Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

icmp6.c File Reference

#include "lwip/opt.h"
#include "lwip/icmp.h"
#include "lwip/inet.h"
#include "lwip/ip.h"
#include "lwip/def.h"
#include "lwip/stats.h"

Include dependency graph for icmp6.c:

Go to the source code of this file.

Functions

void icmp_input (struct pbuf *p, struct netif *inp)
void icmp_dest_unreach (struct pbuf *p, enum icmp_dur_type t)
void icmp_time_exceeded (struct pbuf *p, enum icmp_te_type t)


Function Documentation

void icmp_dest_unreach struct pbuf p,
enum icmp_dur_type  t
 

Definition at line 118 of file icmp6.c.

References ICMP6_DUR, ICMP_DUR, ICMPH_CODE_SET, ICMPH_TYPE_SET, inet_chksum(), IP_HLEN, ip_output(), IP_PROTO_ICMP, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_IP, PBUF_RAM, snmp_inc_icmpoutdestunreachs, and snmp_inc_icmpoutmsgs.

Referenced by ip_input().

00119 {
00120   struct pbuf *q;
00121   struct ip_hdr *iphdr;
00122   struct icmp_dur_hdr *idur;
00123   
00124   q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
00125   /* ICMP header + IP header + 8 bytes of data */
00126 
00127   iphdr = p->payload;
00128   
00129   idur = q->payload;
00130   idur->type = (char)ICMP6_DUR;
00131   idur->icode = (char)t;
00132 
00133   memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8);
00134   
00135   /* calculate checksum */
00136   idur->chksum = 0;
00137   idur->chksum = inet_chksum(idur, q->len);
00138 #ifdef ICMP_STATS
00139   ++lwip_stats.icmp.xmit;
00140 #endif /* ICMP_STATS */
00141 
00142   ip_output(q, NULL,
00143             (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
00144   pbuf_free(q);
00145 }

Here is the call graph for this function:

void icmp_input struct pbuf p,
struct netif inp
 

Definition at line 47 of file icmp6.c.

References ip_addr::addr, DEBUGF, DEMO_DEBUG, htons, ICMP6_ECHO, ICMP6_ER, ICMP_DEBUG, ICMP_ECHO, ICMP_ER, ICMPH_TYPE_SET, inet_chksum_pbuf(), inet_chksum_pseudo(), ip_addr_isbroadcast, ip_addr_ismulticast, ip_addr_set, IP_HDRINCL, IP_HLEN, ip_output_if(), IP_PROTO_ICMP, IPH_HL, IPH_TTL, pbuf::len, netif::netmask, pbuf::payload, pbuf_free(), pbuf_header(), s16_t, snmp_inc_icmpinerrors, snmp_inc_icmpinmsgs, snmp_inc_icmpoutechoreps, snmp_inc_icmpoutmsgs, pbuf::tot_len, u16_t, and u8_t.

Referenced by ip_input().

00048 {
00049   unsigned char type;
00050   struct icmp_echo_hdr *iecho;
00051   struct ip_hdr *iphdr;
00052   struct ip_addr tmpaddr;
00053   
00054  
00055 #ifdef ICMP_STATS
00056   ++lwip_stats.icmp.recv;
00057 #endif /* ICMP_STATS */
00058 
00059   type = ((char *)p->payload)[0];
00060 
00061   switch(type) {
00062   case ICMP6_ECHO:
00063     DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
00064 
00065     if(p->tot_len < sizeof(struct icmp_echo_hdr)) {
00066       DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
00067 
00068       pbuf_free(p);
00069 #ifdef ICMP_STATS
00070       ++lwip_stats.icmp.lenerr;
00071 #endif /* ICMP_STATS */
00072 
00073       return;      
00074     }
00075     iecho = p->payload;
00076     iphdr = (struct ip_hdr *)((char *)p->payload - IP_HLEN);
00077     if(inet_chksum_pbuf(p) != 0) {
00078       DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
00079 
00080 #ifdef ICMP_STATS
00081       ++lwip_stats.icmp.chkerr;
00082 #endif /* ICMP_STATS */
00083     /*      return;*/
00084     }
00085     DEBUGF(ICMP_DEBUG, ("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len));
00086     ip_addr_set(&tmpaddr, &(iphdr->src));
00087     ip_addr_set(&(iphdr->src), &(iphdr->dest));
00088     ip_addr_set(&(iphdr->dest), &tmpaddr);
00089     iecho->type = ICMP6_ER;
00090     /* adjust the checksum */
00091     if(iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {
00092       iecho->chksum += htons(ICMP6_ECHO << 8) + 1;
00093     } else {
00094       iecho->chksum += htons(ICMP6_ECHO << 8);
00095     }
00096     DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
00097 #ifdef ICMP_STATS
00098     ++lwip_stats.icmp.xmit;
00099 #endif /* ICMP_STATS */
00100 
00101     /*    DEBUGF("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len);*/
00102     ip_output_if(p, &(iphdr->src), IP_HDRINCL,
00103                  iphdr->hoplim, IP_PROTO_ICMP, inp);
00104     break; 
00105   default:
00106     DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type not supported.\n"));
00107 
00108 #ifdef ICMP_STATS
00109     ++lwip_stats.icmp.proterr;
00110     ++lwip_stats.icmp.drop;
00111 #endif /* ICMP_STATS */
00112   }
00113 
00114   pbuf_free(p);
00115 }

Here is the call graph for this function:

void icmp_time_exceeded struct pbuf p,
enum icmp_te_type  t
 

Definition at line 148 of file icmp6.c.

References DEBUGF, ICMP6_TE, ICMP_DEBUG, inet_chksum(), IP_HLEN, ip_output(), IP_PROTO_ICMP, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_IP, and PBUF_RAM.

Referenced by ip_forward().

00149 {
00150   struct pbuf *q;
00151   struct ip_hdr *iphdr;
00152   struct icmp_te_hdr *tehdr;
00153 
00154   DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
00155   
00156   q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
00157 
00158   iphdr = p->payload;
00159   
00160   tehdr = q->payload;
00161   tehdr->type = (char)ICMP6_TE;
00162   tehdr->icode = (char)t;
00163 
00164   /* copy fields from original packet */
00165   memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8);
00166   
00167   /* calculate checksum */
00168   tehdr->chksum = 0;
00169   tehdr->chksum = inet_chksum(tehdr, q->len);
00170 #ifdef ICMP_STATS
00171   ++lwip_stats.icmp.xmit;
00172 #endif /* ICMP_STATS */
00173   ip_output(q, NULL, 
00174             (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
00175   pbuf_free(q);
00176 }

Here is the call graph for this function:


Generated on Wed Jan 14 12:59:05 2004 for RTL-lwIP-0.4 by doxygen 1.3.4