Fixed DHCP packet input filter. Added numerous comments. Code cleanup.

This commit is contained in:
likewise 2003-01-30 10:18:40 +00:00
parent b0c1e37364
commit 8560f6ef2b

View File

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