bug #27352: removed packing from ip_addr_t, the packed version is now only used in protocol headers. Added global storage for current src/dest IP address while in input functions.

This commit is contained in:
goldsimon
2010-05-22 21:11:02 +00:00
parent 9bfeb4e5af
commit f7479781c1
18 changed files with 178 additions and 135 deletions

View File

@@ -82,7 +82,6 @@ icmp_input(struct pbuf *p, struct netif *inp)
#endif /* LWIP_DEBUG */
struct icmp_echo_hdr *iecho;
struct ip_hdr *iphdr;
ip_addr_t tmpaddr;
s16_t hlen;
ICMP_STATS_INC(icmp.recv);
@@ -111,13 +110,13 @@ icmp_input(struct pbuf *p, struct netif *inp)
int accepted = 1;
#if !LWIP_MULTICAST_PING
/* multicast destination address? */
if (ip_addr_ismulticast(&iphdr->dest)) {
if (ip_addr_ismulticast(&current_iphdr_dest)) {
accepted = 0;
}
#endif /* LWIP_MULTICAST_PING */
#if !LWIP_BROADCAST_PING
/* broadcast destination address? */
if (ip_addr_isbroadcast(&iphdr->dest, inp)) {
if (ip_addr_isbroadcast(&current_iphdr_dest, inp)) {
accepted = 0;
}
#endif /* LWIP_BROADCAST_PING */
@@ -188,9 +187,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
/* We generate an answer by switching the dest and src ip addresses,
* setting the icmp type to ECHO_RESPONSE and updating the checksum. */
iecho = (struct icmp_echo_hdr *)p->payload;
ip_addr_copy(tmpaddr, iphdr->src);
ip_addr_copy(iphdr->src, iphdr->dest);
ip_addr_copy(iphdr->dest, tmpaddr);
ip_addr_copy(iphdr->src, *ip_current_dest_addr());
ip_addr_copy(iphdr->dest, *ip_current_src_addr());
ICMPH_TYPE_SET(iecho, ICMP_ER);
/* adjust the checksum */
if (iecho->chksum >= PP_HTONS(0xffff - (ICMP_ECHO << 8))) {
@@ -216,7 +214,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
LWIP_ASSERT("Can't move over header in packet", 0);
} else {
err_t ret;
ret = ip_output_if(p, &(iphdr->src), IP_HDRINCL,
/* send an ICMP packet, src addr is the dest addr of the curren packet */
ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL,
ICMP_TTL, 0, IP_PROTO_ICMP, inp);
if (ret != ERR_OK) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret));
@@ -291,6 +290,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
struct ip_hdr *iphdr;
/* we can use the echo header here */
struct icmp_echo_hdr *icmphdr;
ip_addr_t iphdr_src;
/* ICMP header + IP header + 8 bytes of data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
@@ -327,7 +327,8 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
snmp_inc_icmpoutmsgs();
/* increase number of destination unreachable messages attempted to send */
snmp_inc_icmpouttimeexcds();
ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP);
ip_addr_copy(iphdr_src, iphdr->src);
ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP);
pbuf_free(q);
}

View File

@@ -127,7 +127,7 @@ struct igmp_msg {
PACK_STRUCT_FIELD(u8_t igmp_msgtype);
PACK_STRUCT_FIELD(u8_t igmp_maxresp);
PACK_STRUCT_FIELD(u16_t igmp_checksum);
PACK_STRUCT_FIELD(ip_addr_t igmp_group_address);
PACK_STRUCT_FIELD(ip_addr_p_t igmp_group_address);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
@@ -443,8 +443,7 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
IGMP_STATS_INC(igmp.rx_v1);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
}
else {
} else {
IGMP_STATS_INC(igmp.rx_general);
}
@@ -462,9 +461,11 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address);
if (ip_addr_cmp(dest, &allsystems)) {
ip_addr_t groupaddr;
LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
/* we first need to re-lookfor the group since we used dest last time */
group = igmp_lookfor_group(inp, &igmp->igmp_group_address);
/* we first need to re-look for the group since we used dest last time */
ip_addr_copy(groupaddr, igmp->igmp_group_address);
group = igmp_lookfor_group(inp, &groupaddr);
} else {
LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
}
@@ -472,12 +473,10 @@ igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
if (group != NULL) {
IGMP_STATS_INC(igmp.rx_group);
igmp_delaying_member(group, igmp->igmp_maxresp);
}
else {
} else {
IGMP_STATS_INC(igmp.drop);
}
}
else {
} else {
IGMP_STATS_INC(igmp.proterr);
}
}

View File

@@ -79,6 +79,13 @@ struct netif *current_netif;
* Header of the input packet currently being processed.
*/
const struct ip_hdr *current_header;
/** Source IP address of current_header */
ip_addr_t current_iphdr_src;
/** Destination IP address of current_header */
ip_addr_t current_iphdr_dest;
/** The IP header ID of the next outgoing IP packet */
static u16_t ip_id;
/**
* Finds the appropriate network interface for a given IP address. It
@@ -124,39 +131,35 @@ ip_route(ip_addr_t *dest)
* @param p the packet to forward (p->payload points to IP header)
* @param iphdr the IP header of the input packet
* @param inp the netif on which this packet was received
* @return the netif on which the packet was sent (NULL if it wasn't sent)
*/
static struct netif *
static void
ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
{
struct netif *netif;
ip_addr_t dest;
PERF_START;
dest = iphdr->dest;
/* RFC3927 2.7: do not forward link-local addresses */
if (ip_addr_islinklocal(&dest)) {
if (ip_addr_islinklocal(&current_iphdr_dest)) {
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&dest), ip4_addr2_16(&dest), ip4_addr3_16(&dest), ip4_addr4_16(&dest)));
snmp_inc_ipoutnoroutes();
return (struct netif *)NULL;
ip4_addr1_16(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_iphdr_dest)));
goto return_noroute;
}
/* Find network interface where to forward this IP packet to. */
netif = ip_route(&dest);
netif = ip_route(&current_iphdr_dest);
if (netif == NULL) {
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
ip4_addr1_16(&dest), ip4_addr2_16(&dest), ip4_addr3_16(&dest), ip4_addr4_16(&dest)));
snmp_inc_ipoutnoroutes();
return (struct netif *)NULL;
ip4_addr1_16(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_iphdr_dest)));
goto return_noroute;
}
/* Do not forward packets onto the same network interface on which
* they arrived. */
if (netif == inp) {
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
snmp_inc_ipoutnoroutes();
return (struct netif *)NULL;
goto return_noroute;
}
/* decrement TTL */
@@ -170,7 +173,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
icmp_time_exceeded(p, ICMP_TE_TTL);
}
#endif /* LWIP_ICMP */
return (struct netif *)NULL;
return;
}
/* Incrementally update the IP checksum. */
@@ -181,7 +184,8 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
}
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&dest), ip4_addr2_16(&dest), ip4_addr3_16(&dest), ip4_addr4_16(&dest)));
ip4_addr1_16(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_iphdr_dest)));
IP_STATS_INC(ip.fw);
IP_STATS_INC(ip.xmit);
@@ -189,8 +193,10 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
PERF_STOP("ip_forward");
/* transmit pbuf on chosen interface */
netif->output(netif, p, &dest);
return netif;
netif->output(netif, p, &current_iphdr_dest);
return;
return_noroute:
snmp_inc_ipoutnoroutes();
}
#endif /* IP_FORWARD */
@@ -280,10 +286,14 @@ ip_input(struct pbuf *p, struct netif *inp)
* but we'll do it anyway just to be sure that its done. */
pbuf_realloc(p, iphdr_len);
/* copy IP addresses to aligned ip_addr_t */
ip_addr_copy(current_iphdr_dest, iphdr->dest);
ip_addr_copy(current_iphdr_src, iphdr->src);
/* match packet against an interface, i.e. is this packet for us? */
#if LWIP_IGMP
if (ip_addr_ismulticast(&(iphdr->dest))) {
if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &(iphdr->dest)))) {
if (ip_addr_ismulticast(&current_iphdr_dest)) {
if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &current_iphdr_dest))) {
netif = inp;
} else {
netif = NULL;
@@ -306,9 +316,9 @@ ip_input(struct pbuf *p, struct netif *inp)
/* interface is up and configured? */
if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
/* unicast to this interface address? */
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
if (ip_addr_cmp(&current_iphdr_dest, &(netif->ip_addr)) ||
/* or broadcast on this interface network address? */
ip_addr_isbroadcast(&(iphdr->dest), netif)) {
ip_addr_isbroadcast(&current_iphdr_dest, netif)) {
LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
netif->name[0], netif->name[1]));
/* break out of for loop */
@@ -318,7 +328,7 @@ ip_input(struct pbuf *p, struct netif *inp)
/* connections to link-local addresses must persist after changing
the netif's address (RFC3927 ch. 1.9) */
if ((netif->autoip != NULL) &&
ip_addr_cmp(&(iphdr->dest), &(netif->autoip->llipaddr))) {
ip_addr_cmp(&current_iphdr_dest, &(netif->autoip->llipaddr))) {
LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
netif->name[0], netif->name[1]));
/* break out of for loop */
@@ -361,10 +371,10 @@ ip_input(struct pbuf *p, struct netif *inp)
/* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
#if LWIP_DHCP
/* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
if (check_ip_src && !ip_addr_isany(&iphdr->src))
if (check_ip_src && !ip_addr_isany(&current_iphdr_src))
#endif /* LWIP_DHCP */
{ if ((ip_addr_isbroadcast(&(iphdr->src), inp)) ||
(ip_addr_ismulticast(&(iphdr->src)))) {
{ if ((ip_addr_isbroadcast(&current_iphdr_src, inp)) ||
(ip_addr_ismulticast(&current_iphdr_src))) {
/* packet source is not valid */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
/* free (drop) packet pbufs */
@@ -382,7 +392,7 @@ ip_input(struct pbuf *p, struct netif *inp)
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
#if IP_FORWARD
/* non-broadcast packet? */
if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
if (!ip_addr_isbroadcast(&current_iphdr_dest, inp)) {
/* try to forward IP packet on (other) interfaces */
ip_forward(p, iphdr, inp);
} else
@@ -474,14 +484,14 @@ ip_input(struct pbuf *p, struct netif *inp)
#endif /* LWIP_ICMP */
#if LWIP_IGMP
case IP_PROTO_IGMP:
igmp_input(p,inp,&(iphdr->dest));
igmp_input(p, inp, &current_iphdr_dest);
break;
#endif /* LWIP_IGMP */
default:
#if LWIP_ICMP
/* send ICMP destination protocol unreachable unless is was a broadcast */
if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
!ip_addr_ismulticast(&(iphdr->dest))) {
if (!ip_addr_isbroadcast(&current_iphdr_dest, inp) &&
!ip_addr_ismulticast(&current_iphdr_dest)) {
p->payload = iphdr;
icmp_dest_unreach(p, ICMP_DUR_PROTO);
}
@@ -498,6 +508,8 @@ ip_input(struct pbuf *p, struct netif *inp)
current_netif = NULL;
current_header = NULL;
ip_addr_set_any(&current_iphdr_src);
ip_addr_set_any(&current_iphdr_dest);
return ERR_OK;
}
@@ -548,7 +560,7 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
{
#endif /* IP_OPTIONS_SEND */
struct ip_hdr *iphdr;
static u16_t ip_id = 0;
ip_addr_t dest_addr;
#if CHECKSUM_GEN_IP_INLINE
u32_t chk_sum;
#endif /* CHECKSUM_GEN_IP_INLINE */
@@ -646,7 +658,8 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
} else {
/* IP header already included in p */
iphdr = (struct ip_hdr *)p->payload;
dest = &(iphdr->dest);
ip_addr_copy(dest_addr, iphdr->dest);
dest = &dest_addr;
}
IP_STATS_INC(ip.xmit);
@@ -664,7 +677,7 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
#if IP_FRAG
/* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > netif->mtu)) {
return ip_frag(p,netif,dest);
return ip_frag(p, netif, dest);
}
#endif

View File

@@ -51,32 +51,33 @@ const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST };
* @param netif the network interface against which the address is checked
* @return returns non-zero if the address is a broadcast address
*/
u8_t ip_addr_isbroadcast(const ip_addr_t *addr, const struct netif *netif)
u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif)
{
u32_t addr2test;
ip_addr_t ipaddr;
ip4_addr_set_u32(&ipaddr, addr);
addr2test = ip4_addr_get_u32(addr);
/* all ones (broadcast) or all zeroes (old skool broadcast) */
if ((~addr2test == IPADDR_ANY) ||
(addr2test == IPADDR_ANY))
if ((~addr == IPADDR_ANY) ||
(addr == IPADDR_ANY)) {
return 1;
/* no broadcast support on this network interface? */
else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
} else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
/* the given address cannot be a broadcast address
* nor can we check against any broadcast addresses */
return 0;
/* address matches network interface address exactly? => no broadcast */
else if (addr2test == ip4_addr_get_u32(&netif->ip_addr))
} else if (addr == ip4_addr_get_u32(&netif->ip_addr)) {
return 0;
/* on the same (sub) network... */
else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))
} else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask))
/* ...and host identifier bits are all ones? =>... */
&& ((addr2test & ~ip4_addr_get_u32(&netif->netmask)) ==
(IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask))))
&& ((addr & ~ip4_addr_get_u32(&netif->netmask)) ==
(IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) {
/* => network broadcast address */
return 1;
else
} else {
return 0;
}
}
/* Here for now until needed in other places in lwIP */