mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +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;
|
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;
|
||||||
}
|
}
|
||||||
@ -137,13 +137,16 @@ struct netif *
|
|||||||
ip_route(struct ip_addr *dest)
|
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 */
|
||||||
hl = IPH_HL(iphdr);
|
iphdrlen = IPH_HL(iphdr);
|
||||||
|
/* calculate IP header length in bytes */
|
||||||
if(hl * 4 > p->len) {
|
iphdrlen *= 4;
|
||||||
DEBUGF(IP_DEBUG, ("IP packet dropped due to too short packet %d\n", p->len));
|
|
||||||
|
|
||||||
|
/* 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);
|
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
|
|
||||||
/* 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) {
|
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,8 +380,8 @@ 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;
|
||||||
++lwip_stats.ip.drop;
|
++lwip_stats.ip.drop;
|
||||||
@ -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"));
|
||||||
@ -531,7 +535,7 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
ip_debug_print(p);
|
ip_debug_print(p);
|
||||||
#endif /* IP_DEBUG */
|
#endif /* IP_DEBUG */
|
||||||
|
|
||||||
DEBUGF(IP_DEBUG, ("netif->output()"));
|
DEBUGF(IP_DEBUG, ("netif->output()"));
|
||||||
|
|
||||||
return netif->output(netif, p, dest);
|
return netif->output(netif, p, dest);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user