From f7479781c1625b1c7112d7d0b8ac6f44c636e93a Mon Sep 17 00:00:00 2001 From: goldsimon Date: Sat, 22 May 2010 21:11:02 +0000 Subject: [PATCH] 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. --- CHANGELOG | 5 +++ src/api/api_lib.c | 4 +- src/api/api_msg.c | 14 +++--- src/api/netbuf.c | 4 +- src/api/sockets.c | 27 ++++++----- src/core/ipv4/icmp.c | 17 +++---- src/core/ipv4/igmp.c | 17 ++++--- src/core/ipv4/ip.c | 79 +++++++++++++++++++-------------- src/core/ipv4/ip_addr.c | 23 +++++----- src/core/raw.c | 6 +-- src/core/tcp_in.c | 34 +++++++------- src/core/udp.c | 29 ++++++------ src/include/ipv4/lwip/inet.h | 2 + src/include/ipv4/lwip/ip.h | 13 +++++- src/include/ipv4/lwip/ip_addr.h | 14 +++++- src/include/lwip/dhcp.h | 8 ++-- src/include/lwip/netbuf.h | 10 +++-- src/netif/etharp.c | 7 ++- 18 files changed, 178 insertions(+), 135 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6cdc05cf..1087dfdd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,11 @@ HISTORY ++ New features: + 2010-05-22: Simon Goldschmidt + * many many files: 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. + 2010-05-16: Simon Goldschmidt * def.h: task #10391: Add preprocessor-macros for compile-time htonl calculation (and use them throughout the stack where applicable) diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 42a59552..9336a380 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -473,7 +473,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf) buf->p = p; buf->ptr = p; buf->port = 0; - buf->addr = NULL; + ip_addr_set_any(&buf->addr); *new_buf = buf; /* don't set conn->last_err: it's only ERR_OK, anyway */ return ERR_OK; @@ -527,7 +527,7 @@ err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port) { if (buf != NULL) { - buf->addr = addr; + ip_addr_set(&buf->addr, addr); buf->port = port; return netconn_send(conn, buf); } diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 36d25573..df9d934f 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -112,7 +112,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, buf->p = q; buf->ptr = q; - buf->addr = &(((struct ip_hdr*)(q->payload))->src); + ip_addr_copy(buf->addr, *ip_current_src_addr()); buf->port = pcb->protocol; len = q->tot_len; @@ -173,7 +173,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, } else { buf->p = p; buf->ptr = p; - buf->addr = addr; + ip_addr_set(&buf->addr, addr); buf->port = port; #if LWIP_NETBUF_RECVINFO { @@ -183,7 +183,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, #if LWIP_CHECKSUM_ON_COPY buf->flags = NETBUF_FLAG_DESTADDR; #endif /* LWIP_CHECKSUM_ON_COPY */ - buf->toaddr = (ip_addr_t*)&iphdr->dest; + ip_addr_set(&buf->toaddr, ip_current_dest_addr()); buf->toport_chksum = udphdr->dest; } #endif /* LWIP_NETBUF_RECVINFO */ @@ -1085,10 +1085,10 @@ do_send(struct api_msg_msg *msg) switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: - if (msg->msg.b->addr == NULL) { + if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); } else { - msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr); + msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); } break; #endif @@ -1104,10 +1104,10 @@ do_send(struct api_msg_msg *msg) msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } #else /* LWIP_CHECKSUM_ON_COPY */ - if (msg->msg.b->addr == NULL) { + if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); } else { - msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port); + msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); } #endif /* LWIP_CHECKSUM_ON_COPY */ break; diff --git a/src/api/netbuf.c b/src/api/netbuf.c index d2d2e42e..9390c9ee 100644 --- a/src/api/netbuf.c +++ b/src/api/netbuf.c @@ -61,7 +61,7 @@ netbuf *netbuf_new(void) if (buf != NULL) { buf->p = NULL; buf->ptr = NULL; - buf->addr = NULL; + ip_addr_set_any(&buf->addr); buf->port = 0; #if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY @@ -69,7 +69,7 @@ netbuf *netbuf_new(void) #endif /* LWIP_CHECKSUM_ON_COPY */ buf->toport_chksum = 0; #if LWIP_NETBUF_RECVINFO - buf->toaddr = NULL; + ip_addr_set_any(&buf->toaddr); #endif /* LWIP_NETBUF_RECVINFO */ #endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ return buf; diff --git a/src/api/sockets.c b/src/api/sockets.c index 8d9adb34..a7e7ab3b 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -787,7 +787,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) { struct lwip_sock *sock; - ip_addr_t remote_addr; err_t err; u16_t short_size; const struct sockaddr_in *to_in; @@ -821,8 +820,10 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #if LWIP_TCPIP_CORE_LOCKING /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */ - { struct pbuf* p; - + { + struct pbuf* p; + ip_addr_t *remote_addr; + #if LWIP_NETIF_TX_SINGLE_PBUF p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); if (p != NULL) { @@ -838,19 +839,19 @@ lwip_sendto(int s, const void *data, size_t size, int flags, if (p != NULL) { p->payload = (void*)data; #endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - inet_addr_to_ipaddr(&remote_addr, &to_in->sin_addr); - + + inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr); + LOCK_TCPIP_CORE(); if (sock->conn->type == NETCONN_RAW) { - err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, &remote_addr); + err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr); } else { #if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, - &remote_addr, ntohs(to_in->sin_port), 1, chksum); + remote_addr, ntohs(to_in->sin_port), 1, chksum); #else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, - &remote_addr, ntohs(to_in->sin_port)); + remote_addr, ntohs(to_in->sin_port)); #endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ } UNLOCK_TCPIP_CORE(); @@ -867,20 +868,18 @@ lwip_sendto(int s, const void *data, size_t size, int flags, buf.flags = 0; #endif /* LWIP_CHECKSUM_ON_COPY */ if (to) { - inet_addr_to_ipaddr(&remote_addr, &to_in->sin_addr); + inet_addr_to_ipaddr(&buf.addr, &to_in->sin_addr); remote_port = ntohs(to_in->sin_port); - netbuf_fromaddr(&buf) = &remote_addr; netbuf_fromport(&buf) = remote_port; } else { - ip_addr_set_zero(&remote_addr); remote_port = 0; - netbuf_fromaddr(&buf) = NULL; + ip_addr_set_any(&buf.addr); netbuf_fromport(&buf) = 0; } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=", s, data, short_size, flags)); - ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); + ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); /* make the buffer point to the data that should be sent */ diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c index e12a0e17..02e498d7 100644 --- a/src/core/ipv4/icmp.c +++ b/src/core/ipv4/icmp.c @@ -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); } diff --git a/src/core/ipv4/igmp.c b/src/core/ipv4/igmp.c index 1e2427fd..5f09c244 100644 --- a/src/core/ipv4/igmp.c +++ b/src/core/ipv4/igmp.c @@ -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); } } diff --git a/src/core/ipv4/ip.c b/src/core/ipv4/ip.c index 5e434cd1..a95622cc 100644 --- a/src/core/ipv4/ip.c +++ b/src/core/ipv4/ip.c @@ -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 diff --git a/src/core/ipv4/ip_addr.c b/src/core/ipv4/ip_addr.c index 511e42f3..58c92aff 100644 --- a/src/core/ipv4/ip_addr.c +++ b/src/core/ipv4/ip_addr.c @@ -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 */ diff --git a/src/core/raw.c b/src/core/raw.c index fc71ae3f..3c1ee820 100644 --- a/src/core/raw.c +++ b/src/core/raw.c @@ -92,16 +92,16 @@ raw_input(struct pbuf *p, struct netif *inp) while ((eaten == 0) && (pcb != NULL)) { if ((pcb->protocol == proto) && (ip_addr_isany(&pcb->local_ip) || - ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) { + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))) { #if IP_SOF_BROADCAST_RECV /* broadcast filter? */ - if ((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(&(iphdr->dest), inp)) + if ((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) #endif /* IP_SOF_BROADCAST_RECV */ { /* receive callback function available? */ if (pcb->recv != NULL) { /* the receive callback function did not eat the packet? */ - if (pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)) != 0) { + if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) { /* receive function ate the packet */ p = NULL; eaten = 1; diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 446380f2..1812fe36 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -124,8 +124,8 @@ tcp_input(struct pbuf *p, struct netif *inp) } /* Don't even process incoming broadcasts/multicasts. */ - 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)) { TCP_STATS_INC(tcp.proterr); TCP_STATS_INC(tcp.drop); snmp_inc_tcpinerrs(); @@ -135,10 +135,10 @@ tcp_input(struct pbuf *p, struct netif *inp) #if CHECKSUM_CHECK_TCP /* Verify TCP checksum. */ - if (inet_chksum_pseudo(p, &iphdr->src, &iphdr->dest, + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), IP_PROTO_TCP, p->tot_len) != 0) { LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - inet_chksum_pseudo(p, &iphdr->src, &iphdr->dest, + inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), IP_PROTO_TCP, p->tot_len))); #if TCP_DEBUG tcp_debug_print(tcphdr); @@ -185,8 +185,8 @@ tcp_input(struct pbuf *p, struct netif *inp) LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); if (pcb->remote_port == tcphdr->src && pcb->local_port == tcphdr->dest && - ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && - ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { /* Move this PCB to the front of the list so that subsequent lookups will be faster (we exploit locality in TCP segment @@ -210,8 +210,8 @@ tcp_input(struct pbuf *p, struct netif *inp) LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); if (pcb->remote_port == tcphdr->src && pcb->local_port == tcphdr->dest && - ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && - ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { /* We don't really care enough to move this PCB to the front of the list since we are not very likely to receive that many segments for connections in TIME-WAIT. */ @@ -228,7 +228,7 @@ tcp_input(struct pbuf *p, struct netif *inp) for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { if (lpcb->local_port == tcphdr->dest) { #if SO_REUSE - if (ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) { + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest)) { /* found an exact match */ break; } else if(ip_addr_isany(&(lpcb->local_ip))) { @@ -237,7 +237,7 @@ tcp_input(struct pbuf *p, struct netif *inp) lpcb_prev = prev; } #else /* SO_REUSE */ - if (ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest)) || + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || ip_addr_isany(&(lpcb->local_ip))) { /* found a match */ break; @@ -415,7 +415,7 @@ aborted: TCP_STATS_INC(tcp.proterr); TCP_STATS_INC(tcp.drop); tcp_rst(ackno, seqno + tcplen, - &(iphdr->dest), &(iphdr->src), + ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } pbuf_free(p); @@ -450,7 +450,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) RST. */ LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); tcp_rst(ackno + 1, seqno + tcplen, - &(iphdr->dest), &(iphdr->src), + ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } else if (flags & TCP_SYN) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); @@ -473,9 +473,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) pcb->accepts_pending++; #endif /* TCP_LISTEN_BACKLOG */ /* Set up the new PCB. */ - ip_addr_copy(npcb->local_ip, iphdr->dest); + ip_addr_copy(npcb->local_ip, current_iphdr_dest); npcb->local_port = pcb->local_port; - ip_addr_copy(npcb->remote_ip, iphdr->src); + ip_addr_copy(npcb->remote_ip, current_iphdr_src); npcb->remote_port = tcphdr->src; npcb->state = SYN_RCVD; npcb->rcv_nxt = seqno + 1; @@ -538,7 +538,7 @@ tcp_timewait_input(struct tcp_pcb *pcb) should be sent in reply */ if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { /* If the SYN is in the window it is an error, send a reset */ - tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); return ERR_OK; } @@ -672,7 +672,7 @@ tcp_process(struct tcp_pcb *pcb) /* received ACK? possibly a half-open connection */ else if (flags & TCP_ACK) { /* send a RST to bring the other side in a non-synchronized state. */ - tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } break; @@ -715,7 +715,7 @@ tcp_process(struct tcp_pcb *pcb) } } else { /* incorrect ACK number, send RST */ - tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { diff --git a/src/core/udp.c b/src/core/udp.c index ebeb9f44..0b335cda 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -113,7 +113,7 @@ udp_input(struct pbuf *p, struct netif *inp) udphdr = (struct udp_hdr *)p->payload; /* is broadcast packet ? */ - broadcast = ip_addr_isbroadcast(&(iphdr->dest), inp); + broadcast = ip_addr_isbroadcast(¤t_iphdr_dest, inp); LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); @@ -144,7 +144,7 @@ udp_input(struct pbuf *p, struct netif *inp) (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! - inp->dhcp->pcb->remote == ANY or iphdr->src */ if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) || - ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), &(iphdr->src)))) { + ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), ¤t_iphdr_src))) { pcb = inp->dhcp->pcb; } } @@ -173,9 +173,9 @@ udp_input(struct pbuf *p, struct netif *inp) /* compare PCB local addr+port to UDP destination addr+port */ if ((pcb->local_port == dest) && ((!broadcast && ip_addr_isany(&pcb->local_ip)) || - ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)) || + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || #if LWIP_IGMP - ip_addr_ismulticast(&(iphdr->dest)) || + ip_addr_ismulticast(¤t_iphdr_dest) || #endif /* LWIP_IGMP */ #if IP_SOF_BROADCAST_RECV (broadcast && (pcb->so_options & SOF_BROADCAST)))) { @@ -193,7 +193,7 @@ udp_input(struct pbuf *p, struct netif *inp) if ((local_match != 0) && (pcb->remote_port == src) && (ip_addr_isany(&pcb->remote_ip) || - ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) { + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src))) { /* the first fully matching PCB */ if (prev != NULL) { /* move the pcb to the front of udp_pcbs so that is @@ -215,7 +215,7 @@ udp_input(struct pbuf *p, struct netif *inp) } /* Check checksum if this is a match or if it was directed at us. */ - if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest)) { + if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, ¤t_iphdr_dest)) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); #if LWIP_UDPLITE if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) { @@ -237,7 +237,7 @@ udp_input(struct pbuf *p, struct netif *inp) goto end; } } - if (inet_chksum_pseudo_partial(p, &iphdr->src, &iphdr->dest, + if (inet_chksum_pseudo_partial(p, ¤t_iphdr_src, ¤t_iphdr_dest, IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_input: UDP Lite datagram discarded due to failing checksum\n")); @@ -253,7 +253,7 @@ udp_input(struct pbuf *p, struct netif *inp) { #if CHECKSUM_CHECK_UDP if (udphdr->chksum != 0) { - if (inet_chksum_pseudo(p, &iphdr->src, &iphdr->dest, + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), IP_PROTO_UDP, p->tot_len) != 0) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_input: UDP datagram discarded due to failing checksum\n")); @@ -277,7 +277,7 @@ udp_input(struct pbuf *p, struct netif *inp) if (pcb != NULL) { snmp_inc_udpindatagrams(); #if SO_REUSE && SO_REUSE_RXTOALL - if ((broadcast || ip_addr_ismulticast(&iphdr->dest)) && + if ((broadcast || ip_addr_ismulticast(¤t_iphdr_dest)) && ((pcb->so_options & SOF_REUSEADDR) != 0)) { /* pass broadcast- or multicast packets to all multicast pcbs if SOF_REUSEADDR is set on the first match */ @@ -288,9 +288,9 @@ udp_input(struct pbuf *p, struct netif *inp) /* compare PCB local addr+port to UDP destination addr+port */ if ((mpcb->local_port == dest) && ((!broadcast && ip_addr_isany(&mpcb->local_ip)) || - ip_addr_cmp(&(mpcb->local_ip), &(iphdr->dest)) || + ip_addr_cmp(&(mpcb->local_ip), ¤t_iphdr_dest) || #if LWIP_IGMP - ip_addr_ismulticast(&(iphdr->dest)) || + ip_addr_ismulticast(¤t_iphdr_dest) || #endif /* LWIP_IGMP */ #if IP_SOF_BROADCAST_RECV (broadcast && (mpcb->so_options & SOF_BROADCAST)))) { @@ -310,9 +310,8 @@ udp_input(struct pbuf *p, struct netif *inp) err_t err = pbuf_copy(q, p); if (err == ERR_OK) { /* move payload to UDP data */ - struct ip_hdr *q_iphdr = (struct ip_hdr *)q->payload; pbuf_header(q, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); - mpcb->recv(mpcb->recv_arg, mpcb, q, &q_iphdr->src, src); + mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); } } } @@ -328,7 +327,7 @@ udp_input(struct pbuf *p, struct netif *inp) /* callback */ if (pcb->recv != NULL) { /* now the recv function is responsible for freeing p */ - pcb->recv(pcb->recv_arg, pcb, p, &iphdr->src, src); + pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); } else { /* no recv function registered? then we have to free the pbuf! */ pbuf_free(p); @@ -341,7 +340,7 @@ udp_input(struct pbuf *p, struct netif *inp) /* No match was found, send ICMP destination port unreachable unless destination address was broadcast/multicast. */ if (!broadcast && - !ip_addr_ismulticast(&iphdr->dest)) { + !ip_addr_ismulticast(¤t_iphdr_dest)) { /* move payload pointer back to ip header */ pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN); LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr)); diff --git a/src/include/ipv4/lwip/inet.h b/src/include/ipv4/lwip/inet.h index cb33486b..7bff49b5 100644 --- a/src/include/ipv4/lwip/inet.h +++ b/src/include/ipv4/lwip/inet.h @@ -91,6 +91,8 @@ struct in_addr { #define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) #define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ +#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) /* directly map this to the lwip internal functions */ #define inet_addr(cp) ipaddr_addr(cp) diff --git a/src/include/ipv4/lwip/ip.h b/src/include/ipv4/lwip/ip.h index 2e13f350..296e344b 100644 --- a/src/include/ipv4/lwip/ip.h +++ b/src/include/ipv4/lwip/ip.h @@ -133,8 +133,8 @@ struct ip_hdr { /* checksum */ PACK_STRUCT_FIELD(u16_t _chksum); /* source and destination IP addresses */ - PACK_STRUCT_FIELD(ip_addr_t src); - PACK_STRUCT_FIELD(ip_addr_t dest); + PACK_STRUCT_FIELD(ip_addr_p_t src); + PACK_STRUCT_FIELD(ip_addr_p_t dest); } PACK_STRUCT_STRUCT; PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES @@ -163,6 +163,10 @@ PACK_STRUCT_END extern struct netif *current_netif; /** Header of the input packet currently being processed. */ extern const struct ip_hdr *current_header; +/** Source IP address of current_header */ +extern ip_addr_t current_iphdr_src; +/** Destination IP address of current_header */ +extern ip_addr_t current_iphdr_dest; #define ip_init() /* Compatibility define, not init needed. */ struct netif *ip_route(ip_addr_t *dest); @@ -189,6 +193,11 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, * This function must only be called from a receive callback (udp_recv, * raw_recv, tcp_accept). It will return NULL otherwise. */ #define ip_current_header() (current_header) +/** Source IP address of current_header */ +#define ip_current_src_addr() (¤t_iphdr_src) +/** Destination IP address of current_header */ +#define ip_current_dest_addr() (¤t_iphdr_dest) + #if IP_DEBUG void ip_debug_print(struct pbuf *p); #else diff --git a/src/include/ipv4/lwip/ip_addr.h b/src/include/ipv4/lwip/ip_addr.h index 65636f54..f6a773b6 100644 --- a/src/include/ipv4/lwip/ip_addr.h +++ b/src/include/ipv4/lwip/ip_addr.h @@ -39,11 +39,19 @@ extern "C" { #endif +/* This is the aligned version of ip_addr_t, + used as local variable, on the stack, etc. */ +struct _ip_addr { + u32_t addr; +}; + +/* This is the packed version of ip_addr_t, + used in network headers that are itself packed */ #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h" #endif PACK_STRUCT_BEGIN -struct _ip_addr { +struct _ip_addr_packed { PACK_STRUCT_FIELD(u32_t addr); } PACK_STRUCT_STRUCT; PACK_STRUCT_END @@ -52,6 +60,7 @@ PACK_STRUCT_END #endif typedef struct _ip_addr ip_addr_t; +typedef struct _ip_addr_packed ip_addr_p_t; /* * struct ipaddr2 is used in the definition of the ARP packet format in @@ -188,7 +197,8 @@ extern const ip_addr_t ip_addr_broadcast; #define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) -u8_t ip_addr_isbroadcast(const ip_addr_t *, const struct netif *); +#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) +u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); #define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) diff --git a/src/include/lwip/dhcp.h b/src/include/lwip/dhcp.h index 6edc8fa7..8767605c 100644 --- a/src/include/lwip/dhcp.h +++ b/src/include/lwip/dhcp.h @@ -80,10 +80,10 @@ struct dhcp_msg PACK_STRUCT_FIELD(u32_t xid); PACK_STRUCT_FIELD(u16_t secs); PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FIELD(ip_addr_t ciaddr); - PACK_STRUCT_FIELD(ip_addr_t yiaddr); - PACK_STRUCT_FIELD(ip_addr_t siaddr); - PACK_STRUCT_FIELD(ip_addr_t giaddr); + PACK_STRUCT_FIELD(ip_addr_p_t ciaddr); + PACK_STRUCT_FIELD(ip_addr_p_t yiaddr); + PACK_STRUCT_FIELD(ip_addr_p_t siaddr); + PACK_STRUCT_FIELD(ip_addr_p_t giaddr); PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); diff --git a/src/include/lwip/netbuf.h b/src/include/lwip/netbuf.h index d6f2655a..7d247d71 100644 --- a/src/include/lwip/netbuf.h +++ b/src/include/lwip/netbuf.h @@ -47,7 +47,7 @@ extern "C" { struct netbuf { struct pbuf *p, *ptr; - ip_addr_t *addr; + ip_addr_t addr; u16_t port; #if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY @@ -55,7 +55,7 @@ struct netbuf { #endif /* LWIP_CHECKSUM_ON_COPY */ u16_t toport_chksum; #if LWIP_NETBUF_RECVINFO - ip_addr_t *toaddr; + ip_addr_t toaddr; #endif /* LWIP_NETBUF_RECVINFO */ #endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ }; @@ -81,10 +81,12 @@ void netbuf_first (struct netbuf *buf); #define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) #define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) #define netbuf_len(buf) ((buf)->p->tot_len) -#define netbuf_fromaddr(buf) ((buf)->addr) +#define netbuf_fromaddr(buf) (&((buf)->addr)) +#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set((&(buf)->addr), fromaddr) #define netbuf_fromport(buf) ((buf)->port) #if LWIP_NETBUF_RECVINFO -#define netbuf_destaddr(buf) ((buf)->toaddr) +#define netbuf_destaddr(buf) (&((buf)->toaddr)) +#define netbuf_set_destaddr(buf, destaddr) ip_addr_set((&(buf)->addr), destaddr) #define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) #endif /* LWIP_NETBUF_RECVINFO */ #if LWIP_CHECKSUM_ON_COPY diff --git a/src/netif/etharp.c b/src/netif/etharp.c index f690ecd9..edd9958f 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -618,6 +618,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) { struct eth_hdr *ethhdr; struct ip_hdr *iphdr; + ip_addr_t iphdr_src; LWIP_ERROR("netif != NULL", (netif != NULL), return;); /* Only insert an entry if the source IP address of the @@ -630,8 +631,10 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) } #endif /* ETHARP_SUPPORT_VLAN */ + ip_addr_copy(iphdr_src, iphdr->src); + /* source is not on the local network? */ - if (!ip_addr_netcmp(&(iphdr->src), &(netif->ip_addr), &(netif->netmask))) { + if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) { /* do nothing */ return; } @@ -640,7 +643,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) /* update the source IP address in the cache, if present */ /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk * back soon (for example, if the destination IP address is ours. */ - update_arp_entry(netif, &(iphdr->src), &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); + update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); } #endif /* ETHARP_TRUST_IP_MAC */