87 |
iphdr = header; |
iphdr = header; |
88 |
|
|
89 |
/* not IP v4? */ |
/* not IP v4? */ |
90 |
if(IPH_V(iphdr) != 4) { |
if (IPH_V(iphdr) != 4) { |
91 |
return 0; |
return 0; |
92 |
} |
} |
93 |
|
|
94 |
/* Immediately accept/decline packets that are fragments or has |
/* Immediately accept/decline packets that are fragments or has |
95 |
options. */ |
options. */ |
96 |
#if IP_REASSEMBLY == 0 |
#if IP_REASSEMBLY == 0 |
97 |
/* if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { |
/* if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { |
98 |
return 0; |
return 0; |
99 |
}*/ |
}*/ |
100 |
#endif /* IP_REASSEMBLY == 0 */ |
#endif /* IP_REASSEMBLY == 0 */ |
101 |
|
|
102 |
#if IP_OPTIONS == 0 |
#if IP_OPTIONS == 0 |
103 |
if(IPH_HL(iphdr) != 5) { |
if (IPH_HL(iphdr) != 5) { |
104 |
return 0; |
return 0; |
105 |
} |
} |
106 |
#endif /* IP_OPTIONS == 0 */ |
#endif /* IP_OPTIONS == 0 */ |
107 |
|
|
108 |
switch(IPH_PROTO(iphdr)) { |
switch (IPH_PROTO(iphdr)) { |
109 |
#if LWIP_UDP > 0 |
#if LWIP_UDP > 0 |
110 |
case IP_PROTO_UDP: |
case IP_PROTO_UDP: |
111 |
return udp_lookup(iphdr, inp); |
return udp_lookup(iphdr, inp); |
138 |
/* iterate through netifs */ |
/* iterate through netifs */ |
139 |
for(netif = netif_list; netif != NULL; netif = netif->next) { |
for(netif = netif_list; netif != NULL; netif = netif->next) { |
140 |
/* network mask matches? */ |
/* network mask matches? */ |
141 |
if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) { |
if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) { |
142 |
/* return netif on which to forward IP packet */ |
/* return netif on which to forward IP packet */ |
143 |
return netif; |
return netif; |
144 |
} |
} |
163 |
PERF_START; |
PERF_START; |
164 |
/* Find network interface where to forward this IP packet to. */ |
/* Find network interface where to forward this IP packet to. */ |
165 |
netif = ip_route((struct ip_addr *)&(iphdr->dest)); |
netif = ip_route((struct ip_addr *)&(iphdr->dest)); |
166 |
if(netif == NULL) { |
if (netif == NULL) { |
167 |
DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n", |
DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n", |
168 |
iphdr->dest.addr)); |
iphdr->dest.addr)); |
169 |
snmp_inc_ipnoroutes(); |
snmp_inc_ipnoroutes(); |
171 |
} |
} |
172 |
/* Do not forward packets onto the same network interface on which |
/* Do not forward packets onto the same network interface on which |
173 |
they arrived. */ |
they arrived. */ |
174 |
if(netif == inp) { |
if (netif == inp) { |
175 |
DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); |
DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); |
176 |
snmp_inc_ipnoroutes(); |
snmp_inc_ipnoroutes(); |
177 |
return; |
return; |
180 |
/* decrement TTL */ |
/* decrement TTL */ |
181 |
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); |
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); |
182 |
/* send ICMP if TTL == 0 */ |
/* send ICMP if TTL == 0 */ |
183 |
if(IPH_TTL(iphdr) == 0) { |
if (IPH_TTL(iphdr) == 0) { |
184 |
/* Don't send ICMP messages in response to ICMP messages */ |
/* Don't send ICMP messages in response to ICMP messages */ |
185 |
if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) { |
if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { |
186 |
icmp_time_exceeded(p, ICMP_TE_TTL); |
icmp_time_exceeded(p, ICMP_TE_TTL); |
187 |
snmp_inc_icmpouttimeexcds(); |
snmp_inc_icmpouttimeexcds(); |
188 |
} |
} |
190 |
} |
} |
191 |
|
|
192 |
/* Incrementally update the IP checksum. */ |
/* Incrementally update the IP checksum. */ |
193 |
if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) { |
if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) { |
194 |
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1); |
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1); |
195 |
} else { |
} else { |
196 |
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100)); |
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100)); |
235 |
|
|
236 |
/* identify the IP header */ |
/* identify the IP header */ |
237 |
iphdr = p->payload; |
iphdr = p->payload; |
238 |
if(IPH_V(iphdr) != 4) { |
if (IPH_V(iphdr) != 4) { |
239 |
DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr))); |
DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr))); |
240 |
#if IP_DEBUG |
#if IP_DEBUG |
241 |
ip_debug_print(p); |
ip_debug_print(p); |
254 |
iphdrlen *= 4; |
iphdrlen *= 4; |
255 |
|
|
256 |
/* header length exceeds first pbuf length? */ |
/* header length exceeds first pbuf length? */ |
257 |
if(iphdrlen > p->len) { |
if (iphdrlen > p->len) { |
258 |
DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n", |
DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n", |
259 |
iphdrlen, p->len)); |
iphdrlen, p->len)); |
260 |
/* free (drop) packet pbufs */ |
/* free (drop) packet pbufs */ |
268 |
} |
} |
269 |
|
|
270 |
/* verify checksum */ |
/* verify checksum */ |
271 |
if(inet_chksum(iphdr, iphdrlen) != 0) { |
if (inet_chksum(iphdr, iphdrlen) != 0) { |
272 |
|
|
273 |
DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen))); |
DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen))); |
274 |
#if IP_DEBUG |
#if IP_DEBUG |
297 |
iphdr->dest.addr & ~(netif->netmask.addr))); |
iphdr->dest.addr & ~(netif->netmask.addr))); |
298 |
|
|
299 |
/* interface configured? */ |
/* interface configured? */ |
300 |
if(!ip_addr_isany(&(netif->ip_addr))) |
if (!ip_addr_isany(&(netif->ip_addr))) |
301 |
{ |
{ |
302 |
/* unicast to this interface address? */ |
/* unicast to this interface address? */ |
303 |
if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) || |
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) || |
304 |
/* or broadcast matching this interface network address? */ |
/* or broadcast matching this interface network address? */ |
305 |
(ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) && |
(ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) && |
306 |
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) || |
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) || |
317 |
/* Pass DHCP messages regardless of destination address. DHCP traffic is addressed |
/* Pass DHCP messages regardless of destination address. DHCP traffic is addressed |
318 |
using link layer addressing (such as Ethernet MAC) so we must not filter on IP. |
using link layer addressing (such as Ethernet MAC) so we must not filter on IP. |
319 |
According to RFC 1542 section 3.1.1, referred by RFC 2131). */ |
According to RFC 1542 section 3.1.1, referred by RFC 2131). */ |
320 |
if(netif == NULL) { |
if (netif == NULL) { |
321 |
/* remote port is DHCP server? */ |
/* remote port is DHCP server? */ |
322 |
if(IPH_PROTO(iphdr) == IP_PROTO_UDP) { |
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { |
323 |
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n", |
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n", |
324 |
ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest))); |
ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest))); |
325 |
if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) { |
if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) { |
330 |
} |
} |
331 |
#endif /* LWIP_DHCP */ |
#endif /* LWIP_DHCP */ |
332 |
/* packet not for us? */ |
/* packet not for us? */ |
333 |
if(netif == NULL) { |
if (netif == NULL) { |
334 |
/* packet not for us, route or discard */ |
/* packet not for us, route or discard */ |
335 |
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n")); |
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n")); |
336 |
#if IP_FORWARD |
#if IP_FORWARD |
337 |
/* non-broadcast packet? */ |
/* non-broadcast packet? */ |
338 |
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) { |
if (!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) { |
339 |
/* try to forward IP packet on (other) interfaces */ |
/* try to forward IP packet on (other) interfaces */ |
340 |
ip_forward(p, iphdr, inp); |
ip_forward(p, iphdr, inp); |
341 |
} |
} |
349 |
} |
} |
350 |
|
|
351 |
#if IP_REASSEMBLY |
#if IP_REASSEMBLY |
352 |
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { |
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { |
353 |
DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); |
DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); |
354 |
p = ip_reass(p); |
p = ip_reass(p); |
355 |
if(p == NULL) { |
if (p == NULL) { |
356 |
return ERR_OK; |
return ERR_OK; |
357 |
} |
} |
358 |
iphdr = p->payload; |
iphdr = p->payload; |
359 |
} |
} |
360 |
#else /* IP_REASSEMBLY */ |
#else /* IP_REASSEMBLY */ |
361 |
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { |
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { |
362 |
pbuf_free(p); |
pbuf_free(p); |
363 |
DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n", |
DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n", |
364 |
ntohs(IPH_OFFSET(iphdr)))); |
ntohs(IPH_OFFSET(iphdr)))); |
391 |
DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len)); |
DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len)); |
392 |
#endif /* IP_DEBUG */ |
#endif /* IP_DEBUG */ |
393 |
|
|
394 |
switch(IPH_PROTO(iphdr)) { |
switch (IPH_PROTO(iphdr)) { |
395 |
#if LWIP_UDP > 0 |
#if LWIP_UDP > 0 |
396 |
case IP_PROTO_UDP: |
case IP_PROTO_UDP: |
397 |
snmp_inc_ipindelivers(); |
snmp_inc_ipindelivers(); |
410 |
break; |
break; |
411 |
default: |
default: |
412 |
/* send ICMP destination protocol unreachable unless is was a broadcast */ |
/* send ICMP destination protocol unreachable unless is was a broadcast */ |
413 |
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) && |
if (!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) && |
414 |
!ip_addr_ismulticast(&(iphdr->dest))) { |
!ip_addr_ismulticast(&(iphdr->dest))) { |
415 |
p->payload = iphdr; |
p->payload = iphdr; |
416 |
icmp_dest_unreach(p, ICMP_DUR_PROTO); |
icmp_dest_unreach(p, ICMP_DUR_PROTO); |
439 |
*/ |
*/ |
440 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
441 |
err_t |
err_t |
442 |
ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, |
ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, |
443 |
u8_t ttl, |
u8_t ttl, |
444 |
u8_t proto, struct netif *netif) |
u8_t proto, struct netif *netif) |
445 |
{ |
{ |
448 |
|
|
449 |
snmp_inc_ipoutrequests(); |
snmp_inc_ipoutrequests(); |
450 |
|
|
451 |
if(dest != IP_HDRINCL) { |
if (dest != IP_HDRINCL) { |
452 |
if(pbuf_header(p, IP_HLEN)) { |
if (pbuf_header(p, IP_HLEN)) { |
453 |
DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n")); |
DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n")); |
454 |
|
|
455 |
#ifdef IP_STATS |
#ifdef IP_STATS |
472 |
IPH_ID_SET(iphdr, htons(ip_id)); |
IPH_ID_SET(iphdr, htons(ip_id)); |
473 |
++ip_id; |
++ip_id; |
474 |
|
|
475 |
if(ip_addr_isany(src)) { |
if (ip_addr_isany(src)) { |
476 |
ip_addr_set(&(iphdr->src), &(netif->ip_addr)); |
ip_addr_set(&(iphdr->src), &(netif->ip_addr)); |
477 |
} else { |
} else { |
478 |
ip_addr_set(&(iphdr->src), src); |
ip_addr_set(&(iphdr->src), src); |
516 |
{ |
{ |
517 |
struct netif *netif; |
struct netif *netif; |
518 |
|
|
519 |
if((netif = ip_route(dest)) == NULL) { |
if ((netif = ip_route(dest)) == NULL) { |
520 |
DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr)); |
DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr)); |
521 |
|
|
522 |
#ifdef IP_STATS |
#ifdef IP_STATS |
526 |
return ERR_RTE; |
return ERR_RTE; |
527 |
} |
} |
528 |
|
|
529 |
return ip_output_if(p, src, dest, ttl, proto, netif); |
return ip_output_if (p, src, dest, ttl, proto, netif); |
530 |
} |
} |
531 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
532 |
#if IP_DEBUG |
#if IP_DEBUG |