mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-08-09 17:13:49 +08:00
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:
@@ -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(¤t_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(¤t_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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(¤t_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(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
|
||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
|
||||
goto return_noroute;
|
||||
}
|
||||
|
||||
/* Find network interface where to forward this IP packet to. */
|
||||
netif = ip_route(&dest);
|
||||
netif = ip_route(¤t_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(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
|
||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_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(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
|
||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_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, ¤t_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(¤t_iphdr_dest)) {
|
||||
if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_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(¤t_iphdr_dest, &(netif->ip_addr)) ||
|
||||
/* or broadcast on this interface network address? */
|
||||
ip_addr_isbroadcast(&(iphdr->dest), netif)) {
|
||||
ip_addr_isbroadcast(¤t_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(¤t_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(¤t_iphdr_src))
|
||||
#endif /* LWIP_DHCP */
|
||||
{ if ((ip_addr_isbroadcast(&(iphdr->src), inp)) ||
|
||||
(ip_addr_ismulticast(&(iphdr->src)))) {
|
||||
{ if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) ||
|
||||
(ip_addr_ismulticast(¤t_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(¤t_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, ¤t_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(¤t_iphdr_dest, inp) &&
|
||||
!ip_addr_ismulticast(¤t_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(¤t_iphdr_src);
|
||||
ip_addr_set_any(¤t_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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user