mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-25 18:14:53 +00:00
Fixed DHCP packet input filter. Added numerous comments. Code cleanup.
This commit is contained in:
parent
b0c1e37364
commit
8560f6ef2b
@ -87,7 +87,7 @@ ip_lookup(void *header, struct netif *inp)
|
||||
|
||||
iphdr = header;
|
||||
|
||||
/* Refuse anything that isn't IPv4. */
|
||||
/* not IP v4? */
|
||||
if(IPH_V(iphdr) != 4) {
|
||||
return 0;
|
||||
}
|
||||
@ -137,13 +137,16 @@ struct netif *
|
||||
ip_route(struct ip_addr *dest)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
|
||||
/* iterate through netifs */
|
||||
for(netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
/* network mask matches? */
|
||||
if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
|
||||
/* return netif on which to forward IP packet */
|
||||
return netif;
|
||||
}
|
||||
}
|
||||
|
||||
/* no matching netif found, use default netif */
|
||||
return netif_default;
|
||||
}
|
||||
#if IP_FORWARD
|
||||
@ -161,31 +164,29 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
struct netif *netif;
|
||||
|
||||
PERF_START;
|
||||
|
||||
if((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
|
||||
|
||||
/* Find network interface where to forward this IP packet to. */
|
||||
netif = ip_route((struct ip_addr *)&(iphdr->dest));
|
||||
if(netif == NULL) {
|
||||
DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
|
||||
iphdr->dest.addr));
|
||||
|
||||
#if LWIP_SNMP > 0
|
||||
snmp_inc_ipnoroutes();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't forward packets onto the same network interface on which
|
||||
/* Do not forward packets onto the same network interface on which
|
||||
they arrived. */
|
||||
if(netif == inp) {
|
||||
DEBUGF(IP_DEBUG, ("ip_forward: not forward packets back on incoming interface.\n"));
|
||||
|
||||
DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
|
||||
#if LWIP_SNMP > 0
|
||||
snmp_inc_ipnoroutes();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decrement TTL and send ICMP if ttl == 0. */
|
||||
/* decrement TTL */
|
||||
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
|
||||
/* send ICMP if TTL == 0 */
|
||||
if(IPH_TTL(iphdr) == 0) {
|
||||
/* Don't send ICMP messages in response to ICMP messages */
|
||||
if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
|
||||
@ -197,7 +198,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Incremental update of the IP checksum. */
|
||||
/* Incrementally update the IP checksum. */
|
||||
if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
|
||||
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
|
||||
} else {
|
||||
@ -216,7 +217,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
#endif
|
||||
|
||||
PERF_STOP("ip_forward");
|
||||
|
||||
/* transmit pbuf on chosen interface */
|
||||
netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
|
||||
}
|
||||
#endif /* IP_FORWARD */
|
||||
@ -236,9 +237,7 @@ err_t
|
||||
ip_input(struct pbuf *p, struct netif *inp) {
|
||||
static struct ip_hdr *iphdr;
|
||||
static struct netif *netif;
|
||||
static u8_t hl;
|
||||
|
||||
|
||||
static u16_t iphdrlen;
|
||||
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip.recv;
|
||||
@ -264,12 +263,16 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
#endif
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
hl = IPH_HL(iphdr);
|
||||
|
||||
if(hl * 4 > p->len) {
|
||||
DEBUGF(IP_DEBUG, ("IP packet dropped due to too short packet %d\n", p->len));
|
||||
/* obtain IP header length in number of 32-bit words */
|
||||
iphdrlen = IPH_HL(iphdr);
|
||||
/* calculate IP header length in bytes */
|
||||
iphdrlen *= 4;
|
||||
|
||||
/* header length exceeds first pbuf length? */
|
||||
if(iphdrlen > p->len) {
|
||||
DEBUGF(IP_DEBUG, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
|
||||
iphdrlen, p->len));
|
||||
/* free (drop) packet pbufs */
|
||||
pbuf_free(p);
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip.lenerr;
|
||||
@ -282,9 +285,9 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
}
|
||||
|
||||
/* verify checksum */
|
||||
if(inet_chksum(iphdr, hl * 4) != 0) {
|
||||
if(inet_chksum(iphdr, iphdrlen) != 0) {
|
||||
|
||||
DEBUGF(IP_DEBUG, ("IP packet dropped due to failing checksum 0x%x\n", inet_chksum(iphdr, hl * 4)));
|
||||
DEBUGF(IP_DEBUG, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
|
||||
#if IP_DEBUG
|
||||
ip_debug_print(p);
|
||||
#endif /* IP_DEBUG */
|
||||
@ -317,39 +320,42 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
{
|
||||
/* unicast to this interface address? */
|
||||
if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
|
||||
/* or broadcast on this interface network address ? */
|
||||
/* or broadcast matching this interface network address? */
|
||||
(ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
|
||||
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
|
||||
/* or restricted broadcast? */
|
||||
ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
|
||||
DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
/* break out of for loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if LWIP_DHCP
|
||||
/* Pass DHCP messages in case of an unconfigured (0.0.0.0) interface, regardless
|
||||
of destination address. (DHCP replies are sent to the IP address-to-be. This
|
||||
is according to RFC 1542 section 3.1.1, referred by RFC 2131). */
|
||||
|
||||
/* interface unconfigured (0.0.0.0) */
|
||||
else {
|
||||
/* remote port is DHCP server? */
|
||||
if(IPH_PROTO(iphdr) == IP_PROTO_UDP &&
|
||||
((struct udp_hdr *)((u8_t *)iphdr + IPH_HL(iphdr) * 4))->src == DHCP_SERVER_PORT) {
|
||||
netif = inp;
|
||||
/* break out of for loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_DHCP */
|
||||
}
|
||||
|
||||
|
||||
#if LWIP_DHCP
|
||||
/* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
|
||||
using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
|
||||
According to RFC 1542 section 3.1.1, referred by RFC 2131). */
|
||||
if(netif == NULL) {
|
||||
/* remote port is DHCP server? */
|
||||
if(IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||
DEBUGF(IP_DEBUG, ("ip_input: UDP packet to DHCP client port %u\n",
|
||||
ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
|
||||
if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
|
||||
DEBUGF(IP_DEBUG, ("ip_input: DHCP packet accepted.\n"));
|
||||
netif = inp;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_DHCP */
|
||||
/* packet not for us? */
|
||||
if(netif == NULL) {
|
||||
/* packet not for us, route or discard */
|
||||
DEBUGF(IP_DEBUG, ("ip_input: packet not for us.\n"));
|
||||
#if IP_FORWARD
|
||||
/* non-broadcast packet? */
|
||||
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
|
||||
/* try to forward IP packet on (other) interfaces */
|
||||
ip_forward(p, iphdr, inp);
|
||||
}
|
||||
else
|
||||
@ -374,8 +380,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
#else /* IP_REASSEMBLY */
|
||||
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
||||
pbuf_free(p);
|
||||
DEBUGF(IP_DEBUG, ("IP packet dropped since it was fragmented (0x%x).\n",
|
||||
ntohs(IPH_OFFSET(iphdr))));
|
||||
DEBUGF(IP_DEBUG, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
|
||||
ntohs(IPH_OFFSET(iphdr))));
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip.opterr;
|
||||
++lwip_stats.ip.drop;
|
||||
@ -388,9 +394,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
#endif /* IP_REASSEMBLY */
|
||||
|
||||
#if IP_OPTIONS == 0
|
||||
if(hl * 4 > IP_HLEN) {
|
||||
DEBUGF(IP_DEBUG, ("IP packet dropped since there were IP options.\n"));
|
||||
|
||||
if(iphdrlen > IP_HLEN) {
|
||||
DEBUGF(IP_DEBUG, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
|
||||
pbuf_free(p);
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip.opterr;
|
||||
@ -403,7 +408,6 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
}
|
||||
#endif /* IP_OPTIONS == 0 */
|
||||
|
||||
|
||||
/* send to upper layers */
|
||||
#if IP_DEBUG
|
||||
DEBUGF(IP_DEBUG, ("ip_input: \n"));
|
||||
@ -531,7 +535,7 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
ip_debug_print(p);
|
||||
#endif /* IP_DEBUG */
|
||||
|
||||
DEBUGF(IP_DEBUG, ("netif->output()"));
|
||||
DEBUGF(IP_DEBUG, ("netif->output()"));
|
||||
|
||||
return netif->output(netif, p, dest);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user