You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2017/04/19 18:18:13 UTC
[17/30] incubator-mynewt-core git commit: net/ip/lwip_base;
update to LwIP to tag STABLE-2_0_2_RELEASE
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/icmp.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/icmp.c b/net/ip/lwip_base/src/core/ipv4/icmp.c
index e60e448..5ee24ee 100644
--- a/net/ip/lwip_base/src/core/ipv4/icmp.c
+++ b/net/ip/lwip_base/src/core/ipv4/icmp.c
@@ -51,6 +51,10 @@
#include <string.h>
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
* used to modify and send a response packet (and to 1 if this is not the case,
* e.g. when link header is stripped of when receiving) */
@@ -81,7 +85,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
#endif /* LWIP_DEBUG */
struct icmp_echo_hdr *iecho;
const struct ip_hdr *iphdr_in;
- s16_t hlen;
+ u16_t hlen;
const ip4_addr_t* src;
ICMP_STATS_INC(icmp.recv);
@@ -148,7 +152,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
}
#endif
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
- if (pbuf_header(p, (hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
+ if (pbuf_header(p, (s16_t)(hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
/* p is not big enough to contain link headers
* allocate a new one and copy p into it
*/
@@ -167,7 +171,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
/* copy the ip header */
MEMCPY(r->payload, iphdr_in, hlen);
/* switch r->payload back to icmp header (cannot fail) */
- if (pbuf_header(r, -hlen)) {
+ if (pbuf_header(r, (s16_t)-hlen)) {
LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0);
pbuf_free(r);
goto icmperr;
@@ -194,7 +198,7 @@ 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;
- if (pbuf_header(p, hlen)) {
+ if (pbuf_header(p, (s16_t)hlen)) {
LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet"));
} else {
err_t ret;
@@ -247,7 +251,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
if (type == ICMP_DUR) {
MIB2_STATS_INC(mib2.icmpindestunreachs);
} else if (type == ICMP_TE) {
- MIB2_STATS_INC(mib2.icmpindestunreachs);
+ MIB2_STATS_INC(mib2.icmpintimeexcds);
} else if (type == ICMP_PP) {
MIB2_STATS_INC(mib2.icmpinparmprobs);
} else if (type == ICMP_SQ) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/igmp.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/igmp.c b/net/ip/lwip_base/src/core/ipv4/igmp.c
index f3db591..74a6c37 100644
--- a/net/ip/lwip_base/src/core/ipv4/igmp.c
+++ b/net/ip/lwip_base/src/core/ipv4/igmp.c
@@ -195,10 +195,13 @@ igmp_report_groups(struct netif *netif)
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void*)netif));
+ /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+ if(group != NULL) {
+ group = group->next;
+ }
+
while (group != NULL) {
- if (!(ip4_addr_cmp(&(group->group_address), &allsystems))) {
- igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
- }
+ igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
group = group->next;
}
}
@@ -237,10 +240,11 @@ igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr)
* @return a struct igmp_group*,
* NULL on memory error.
*/
-struct igmp_group *
+static struct igmp_group *
igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
{
struct igmp_group *group;
+ struct igmp_group *list_head = netif_igmp_data(ifp);
/* Search if the group already exists */
group = igmp_lookfor_group(ifp, addr);
@@ -248,7 +252,7 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
/* Group already exists. */
return group;
}
-
+
/* Group doesn't exist yet, create a new one */
group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
if (group != NULL) {
@@ -257,9 +261,21 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
group->group_state = IGMP_GROUP_NON_MEMBER;
group->last_reporter_flag = 0;
group->use = 0;
- group->next = netif_igmp_data(ifp);
- netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
+ /* Ensure allsystems group is always first in list */
+ if (list_head == NULL) {
+ /* this is the first entry in linked list */
+ LWIP_ASSERT("igmp_lookup_group: first group must be allsystems",
+ (ip4_addr_cmp(addr, &allsystems) != 0));
+ group->next = NULL;
+ netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
+ } else {
+ /* append _after_ first entry */
+ LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems",
+ (ip4_addr_cmp(addr, &allsystems) == 0));
+ group->next = list_head->next;
+ list_head->next = group;
+ }
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to ")));
@@ -279,24 +295,19 @@ static err_t
igmp_remove_group(struct netif* netif, struct igmp_group *group)
{
err_t err = ERR_OK;
+ struct igmp_group *tmp_group;
- /* Is it the first group? */
- if (netif_igmp_data(netif) == group) {
- netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group->next);
- } else {
- /* look for group further down the list */
- struct igmp_group *tmpGroup;
- for (tmpGroup = netif_igmp_data(netif); tmpGroup != NULL; tmpGroup = tmpGroup->next) {
- if (tmpGroup->next == group) {
- tmpGroup->next = group->next;
- break;
- }
- }
- /* Group not found in the global igmp_group_list */
- if (tmpGroup == NULL) {
- err = ERR_ARG;
+ /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+ for (tmp_group = netif_igmp_data(netif); tmp_group != NULL; tmp_group = tmp_group->next) {
+ if (tmp_group->next == group) {
+ tmp_group->next = group->next;
+ break;
}
}
+ /* Group not found in the global igmp_group_list */
+ if (tmp_group == NULL) {
+ err = ERR_ARG;
+ }
return err;
}
@@ -368,11 +379,15 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
}
groupref = netif_igmp_data(inp);
+
+ /* Do not send messages on the all systems group address! */
+ /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+ if(groupref != NULL) {
+ groupref = groupref->next;
+ }
+
while (groupref) {
- /* Do not send messages on the all systems group address! */
- if (!(ip4_addr_cmp(&(groupref->group_address), &allsystems))) {
- igmp_delaying_member(groupref, igmp->igmp_maxresp);
- }
+ igmp_delaying_member(groupref, igmp->igmp_maxresp);
groupref = groupref->next;
}
} else {
@@ -658,6 +673,8 @@ igmp_timeout(struct netif *netif, struct igmp_group *group)
ip4_addr_debug_print(IGMP_DEBUG, &(group->group_address));
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)netif));
+ group->group_state = IGMP_GROUP_IDLE_MEMBER;
+
IGMP_STATS_INC(igmp.tx_report);
igmp_send(netif, group, IGMP_V2_MEMB_REPORT);
}
@@ -711,11 +728,9 @@ igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
- * @param ttl the TTL value to be set in the IP header
- * @param proto the PROTOCOL to be set in the IP header
* @param netif the netif on which to send this packet
* @return ERR_OK if the packet was sent OK
* ERR_BUF if p doesn't have enough space for IP/LINK headers
@@ -743,7 +758,7 @@ igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
{
struct pbuf* p = NULL;
struct igmp_msg* igmp = NULL;
- ip4_addr_t src = *IP4_ADDR_ANY;
+ ip4_addr_t src = *IP4_ADDR_ANY4;
ip4_addr_t* dest = NULL;
/* IP header + "router alert" option + IGMP header */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/ip4.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/ip4.c b/net/ip/lwip_base/src/core/ipv4/ip4.c
index 27747ea..4e4eb61 100644
--- a/net/ip/lwip_base/src/core/ipv4/ip4.c
+++ b/net/ip/lwip_base/src/core/ipv4/ip4.c
@@ -59,6 +59,10 @@
#include <string.h>
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
/** Set this to 0 in the rare case of wanting to call an extra function to
* generate the IP checksum (in contrast to calculating it on-the-fly). */
#ifndef LWIP_INLINE_IP_CHKSUM
@@ -177,7 +181,7 @@ ip4_route(const ip4_addr_t *dest)
/* loopif is disabled, looopback traffic is passed through any netif */
if (ip4_addr_isloopback(dest)) {
/* don't check for link on loopback traffic */
- if (netif_is_up(netif_default)) {
+ if (netif_default != NULL && netif_is_up(netif_default)) {
return netif_default;
}
/* default netif is not up, just use any netif for loopback traffic */
@@ -222,13 +226,12 @@ ip4_route(const ip4_addr_t *dest)
* that may not be forwarded, or whether datagrams to that destination
* may be forwarded.
* @param p the packet to forward
- * @param dest the destination IP address
* @return 1: can forward 0: discard
*/
static int
ip4_canforward(struct pbuf *p)
{
- u32_t addr = htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
+ u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
if (p->flags & PBUF_FLAG_LLBCAST) {
/* don't route link-layer broadcasts */
@@ -405,7 +408,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* calculate IP header length in bytes */
iphdr_hlen *= 4;
/* obtain ip length in bytes */
- iphdr_len = ntohs(IPH_LEN(iphdr));
+ iphdr_len = lwip_ntohs(IPH_LEN(iphdr));
/* Trim pbuf. This is especially required for packets < 60 bytes. */
if (iphdr_len < p->tot_len) {
@@ -519,6 +522,15 @@ ip4_input(struct pbuf *p, struct netif *inp)
#endif /* LWIP_AUTOIP */
}
if (first) {
+#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
+ /* Packets sent to the loopback address must not be accepted on an
+ * interface that does not have the loopback address assigned to it,
+ * unless a non-loopback interface is used for loopback traffic. */
+ if (ip4_addr_isloopback(ip4_current_dest_addr())) {
+ netif = NULL;
+ break;
+ }
+#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
first = 0;
netif = netif_list;
} else {
@@ -545,7 +557,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n",
- ntohs(udphdr->dest)));
+ lwip_ntohs(udphdr->dest)));
if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
netif = inp;
@@ -590,6 +602,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
} else
#endif /* IP_FORWARD */
{
+ IP_STATS_INC(ip.drop);
MIB2_STATS_INC(mib2.ipinaddrerrors);
MIB2_STATS_INC(mib2.ipindiscards);
}
@@ -600,7 +613,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
#if IP_REASSEMBLY /* packet fragment reassembly code present? */
LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n",
- ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)));
+ lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)));
/* reassemble the packet*/
p = ip4_reass(p);
/* packet not fully reassembled yet? */
@@ -611,7 +624,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
pbuf_free(p);
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
- ntohs(IPH_OFFSET(iphdr))));
+ lwip_ntohs(IPH_OFFSET(iphdr))));
IP_STATS_INC(ip.opterr);
IP_STATS_INC(ip.drop);
/* unsupported protocol feature */
@@ -724,7 +737,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
* @param ttl the TTL value to be set in the IP header
@@ -854,7 +867,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
IPH_TTL_SET(iphdr, ttl);
IPH_PROTO_SET(iphdr, proto);
#if CHECKSUM_GEN_IP_INLINE
- chk_sum += LWIP_MAKE_U16(proto, ttl);
+ chk_sum += PP_NTOHS(proto | (ttl << 8));
#endif /* CHECKSUM_GEN_IP_INLINE */
/* dest cannot be NULL here */
@@ -867,21 +880,21 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
IPH_TOS_SET(iphdr, tos);
#if CHECKSUM_GEN_IP_INLINE
- chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl);
+ chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
#endif /* CHECKSUM_GEN_IP_INLINE */
- IPH_LEN_SET(iphdr, htons(p->tot_len));
+ IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
#if CHECKSUM_GEN_IP_INLINE
chk_sum += iphdr->_len;
#endif /* CHECKSUM_GEN_IP_INLINE */
IPH_OFFSET_SET(iphdr, 0);
- IPH_ID_SET(iphdr, htons(ip_id));
+ IPH_ID_SET(iphdr, lwip_htons(ip_id));
#if CHECKSUM_GEN_IP_INLINE
chk_sum += iphdr->_id;
#endif /* CHECKSUM_GEN_IP_INLINE */
++ip_id;
if (src == NULL) {
- ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY);
+ ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4);
} else {
/* src cannot be NULL here */
ip4_addr_copy(iphdr->src, *src);
@@ -955,7 +968,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
* @param ttl the TTL value to be set in the IP header
@@ -990,7 +1003,7 @@ ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
* @param ttl the TTL value to be set in the IP header
@@ -1041,19 +1054,19 @@ ip4_debug_print(struct pbuf *p)
(u16_t)IPH_V(iphdr),
(u16_t)IPH_HL(iphdr),
(u16_t)IPH_TOS(iphdr),
- ntohs(IPH_LEN(iphdr))));
+ lwip_ntohs(IPH_LEN(iphdr))));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
- ntohs(IPH_ID(iphdr)),
- (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
- (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
- (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
- (u16_t)(ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
+ lwip_ntohs(IPH_ID(iphdr)),
+ (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
+ (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
+ (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
+ (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
(u16_t)IPH_TTL(iphdr),
(u16_t)IPH_PROTO(iphdr),
- ntohs(IPH_CHKSUM(iphdr))));
+ lwip_ntohs(IPH_CHKSUM(iphdr))));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
ip4_addr1_16(&iphdr->src),
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/ip4_addr.c b/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
index 7fe35c9..2d47992 100644
--- a/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
+++ b/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
@@ -43,7 +43,7 @@
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
-/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
+/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST);
@@ -183,10 +183,10 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
}
for (;;) {
if (isdigit(c)) {
- val = (val * base) + (int)(c - '0');
+ val = (val * base) + (u32_t)(c - '0');
c = *++cp;
} else if (base == 16 && isxdigit(c)) {
- val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
+ val = (val << 4) | (u32_t)(c + 10 - (islower(c) ? 'a' : 'A'));
c = *++cp;
} else {
break;
@@ -260,7 +260,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
break;
}
if (addr) {
- ip4_addr_set_u32(addr, htonl(val));
+ ip4_addr_set_u32(addr, lwip_htonl(val));
}
return 1;
}
@@ -310,7 +310,7 @@ ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
do {
rem = *ap % (u8_t)10;
*ap /= (u8_t)10;
- inv[i++] = '0' + rem;
+ inv[i++] = (char)('0' + rem);
} while (*ap);
while (i--) {
if (len++ >= buflen) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/ip4_frag.c b/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
index 50edd12..57fb44c 100644
--- a/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
+++ b/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
@@ -160,7 +160,7 @@ static int
ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
{
u16_t pbufs_freed = 0;
- u8_t clen;
+ u16_t clen;
struct pbuf *p;
struct ip_reass_helper *iprh;
@@ -331,7 +331,7 @@ ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
* will grow over time as new pbufs are rx.
* Also checks that the datagram passes basic continuity checks (if the last
* fragment was received at least once).
- * @param root_p points to the 'root' pbuf for the current datagram being assembled.
+ * @param ipr points to the reassembly state
* @param new_p points to the pbuf for the current fragment
* @return 0 if invalid, >0 otherwise
*/
@@ -346,8 +346,8 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
/* Extract length and fragment offset from current fragment */
fraghdr = (struct ip_hdr*)new_p->payload;
- len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
- offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
+ len = lwip_ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
+ offset = (lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
/* overwrite the fragment's ip header from the pbuf with our helper struct,
* and setup the embedded helper structure. */
@@ -487,8 +487,7 @@ ip4_reass(struct pbuf *p)
struct ip_hdr *fraghdr;
struct ip_reassdata *ipr;
struct ip_reass_helper *iprh;
- u16_t offset, len;
- u8_t clen;
+ u16_t offset, len, clen;
IPFRAG_STATS_INC(ip_frag.recv);
MIB2_STATS_INC(mib2.ipreasmreqds);
@@ -501,8 +500,8 @@ ip4_reass(struct pbuf *p)
goto nullreturn;
}
- offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
- len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
+ offset = (lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
+ len = lwip_ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
/* Check if we are allowed to enqueue more datagrams. */
clen = pbuf_clen(p);
@@ -530,7 +529,7 @@ ip4_reass(struct pbuf *p)
fragment into the buffer. */
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
- ntohs(IPH_ID(fraghdr))));
+ lwip_ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit);
break;
}
@@ -544,8 +543,8 @@ ip4_reass(struct pbuf *p)
goto nullreturn;
}
} else {
- if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
- ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
+ if (((lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
+ ((lwip_ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
/* ipr->iphdr is not the header from the first fragment, but fraghdr is
* -> copy fraghdr into ipr->iphdr since we want to have the header
* of the first fragment (for ICMP time exceeded and later, for copying
@@ -582,7 +581,7 @@ ip4_reass(struct pbuf *p)
/* copy the original ip header back to the first pbuf */
fraghdr = (struct ip_hdr*)(ipr->p->payload);
SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
- IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
+ IPH_LEN_SET(fraghdr, lwip_htons(ipr->datagram_len));
IPH_OFFSET_SET(fraghdr, 0);
IPH_CHKSUM_SET(fraghdr, 0);
/* @todo: do we need to set/calculate the correct checksum? */
@@ -688,53 +687,41 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
struct pbuf *rambuf;
#if !LWIP_NETIF_TX_SINGLE_PBUF
struct pbuf *newpbuf;
+ u16_t newpbuflen = 0;
+ u16_t left_to_copy;
#endif
struct ip_hdr *original_iphdr;
struct ip_hdr *iphdr;
- u16_t nfb;
- u16_t left, cop;
- u16_t mtu = netif->mtu;
- u16_t ofo, omf;
- u16_t last;
+ const u16_t nfb = (netif->mtu - IP_HLEN) / 8;
+ u16_t left, fragsize;
+ u16_t ofo;
+ int last;
u16_t poff = IP_HLEN;
u16_t tmp;
-#if !LWIP_NETIF_TX_SINGLE_PBUF
- u16_t newpbuflen = 0;
- u16_t left_to_copy;
-#endif
original_iphdr = (struct ip_hdr *)p->payload;
iphdr = original_iphdr;
+ LWIP_ERROR("ip4_frag() does not support IP options", IPH_HL(iphdr) * 4 == IP_HLEN, return ERR_VAL);
/* Save original offset */
- tmp = ntohs(IPH_OFFSET(iphdr));
+ tmp = lwip_ntohs(IPH_OFFSET(iphdr));
ofo = tmp & IP_OFFMASK;
- omf = tmp & IP_MF;
+ LWIP_ERROR("ip_frag(): MF already set", (tmp & IP_MF) == 0, return ERR_VAL);
left = p->tot_len - IP_HLEN;
- nfb = (mtu - IP_HLEN) / 8;
-
while (left) {
- last = (left <= mtu - IP_HLEN);
-
- /* Set new offset and MF flag */
- tmp = omf | (IP_OFFMASK & (ofo));
- if (!last) {
- tmp = tmp | IP_MF;
- }
-
/* Fill this fragment */
- cop = last ? left : nfb * 8;
+ fragsize = LWIP_MIN(left, nfb * 8);
#if LWIP_NETIF_TX_SINGLE_PBUF
- rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM);
+ rambuf = pbuf_alloc(PBUF_IP, fragsize, PBUF_RAM);
if (rambuf == NULL) {
goto memerr;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
- poff += pbuf_copy_partial(p, rambuf->payload, cop, poff);
+ poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff);
/* make room for the IP header */
if (pbuf_header(rambuf, IP_HLEN)) {
pbuf_free(rambuf);
@@ -758,16 +745,14 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr *)rambuf->payload;
- /* Can just adjust p directly for needed offset. */
- p->payload = (u8_t *)p->payload + poff;
- p->len -= poff;
-
- left_to_copy = cop;
+ left_to_copy = fragsize;
while (left_to_copy) {
struct pbuf_custom_ref *pcr;
- newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
+ u16_t plen = p->len - poff;
+ newpbuflen = LWIP_MIN(left_to_copy, plen);
/* Is this pbuf already empty? */
if (!newpbuflen) {
+ poff = 0;
p = p->next;
continue;
}
@@ -777,7 +762,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
goto memerr;
}
/* Mirror this pbuf, although we might not need all of it. */
- newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen);
+ newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc,
+ (u8_t*)p->payload + poff, newpbuflen);
if (newpbuf == NULL) {
ip_frag_free_pbuf_custom_ref(pcr);
pbuf_free(rambuf);
@@ -793,15 +779,23 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
pbuf_cat(rambuf, newpbuf);
left_to_copy -= newpbuflen;
if (left_to_copy) {
+ poff = 0;
p = p->next;
}
}
- poff = newpbuflen;
+ poff += newpbuflen;
#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
/* Correct header */
- IPH_OFFSET_SET(iphdr, htons(tmp));
- IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
+ last = (left <= netif->mtu - IP_HLEN);
+
+ /* Set new offset and MF flag */
+ tmp = (IP_OFFMASK & (ofo));
+ if (!last) {
+ tmp = tmp | IP_MF;
+ }
+ IPH_OFFSET_SET(iphdr, lwip_htons(tmp));
+ IPH_LEN_SET(iphdr, lwip_htons(fragsize + IP_HLEN));
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
@@ -823,7 +817,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
*/
pbuf_free(rambuf);
- left -= cop;
+ left -= fragsize;
ofo += nfb;
}
MIB2_STATS_INC(mib2.ipfragoks);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ethip6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ethip6.c b/net/ip/lwip_base/src/core/ipv6/ethip6.c
index 1ae784f..8f9a91b 100644
--- a/net/ip/lwip_base/src/core/ipv6/ethip6.c
+++ b/net/ip/lwip_base/src/core/ipv6/ethip6.c
@@ -62,7 +62,9 @@
* For IPv6 multicast, corresponding Ethernet addresses
* are selected and the packet is transmitted on the link.
*
- * For unicast addresses, ...
+ * For unicast addresses, ask the ND6 module what to do. It will either let us
+ * send the the packet right away, or queue the packet for later itself, unless
+ * an error occurs.
*
* @todo anycast addresses
*
@@ -71,14 +73,14 @@
* @param ip6addr The IP address of the packet destination.
*
* @return
- * - ERR_RTE No route to destination (no gateway to external networks),
- * or the return type of either etharp_query() or ethernet_output().
+ * - ERR_OK or the return value of @ref nd6_get_next_hop_addr_or_queue.
*/
err_t
ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
{
struct eth_addr dest;
- s8_t i;
+ const u8_t *hwaddr;
+ err_t result;
/* multicast destination IP address? */
if (ip6_addr_ismulticast(ip6addr)) {
@@ -91,36 +93,26 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
/* Send out. */
- return ethernet_output(netif, q, (struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
+ return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
}
/* We have a unicast destination IP address */
/* @todo anycast? */
- /* Get next hop record. */
- i = nd6_get_next_hop_entry(ip6addr, netif);
- if (i < 0) {
- /* failed to get a next hop neighbor record. */
- return ERR_MEM;
- }
- /* Now that we have a destination record, send or queue the packet. */
- if (neighbor_cache[i].state == ND6_STALE) {
- /* Switch to delay state. */
- neighbor_cache[i].state = ND6_DELAY;
- neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+ /* Ask ND6 what to do with the packet. */
+ result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr);
+ if (result != ERR_OK) {
+ return result;
}
- /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */
- if ((neighbor_cache[i].state == ND6_REACHABLE) ||
- (neighbor_cache[i].state == ND6_DELAY) ||
- (neighbor_cache[i].state == ND6_PROBE)) {
- /* Send out. */
- SMEMCPY(dest.addr, neighbor_cache[i].lladdr, 6);
- return ethernet_output(netif, q, (struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
+ /* If no hardware address is returned, nd6 has queued the packet for later. */
+ if (hwaddr == NULL) {
+ return ERR_OK;
}
- /* We should queue packet on this interface. */
- return nd6_queue_packet(i, q);
+ /* Send out the packet using the returned hardware address. */
+ SMEMCPY(dest.addr, hwaddr, 6);
+ return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
}
#endif /* LWIP_IPV6 && LWIP_ETHERNET */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ip6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ip6.c b/net/ip/lwip_base/src/core/ipv6/ip6.c
index 8cc9c01..f14e334 100644
--- a/net/ip/lwip_base/src/core/ipv6/ip6.c
+++ b/net/ip/lwip_base/src/core/ipv6/ip6.c
@@ -60,6 +60,10 @@
#include "lwip/debug.h"
#include "lwip/stats.h"
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
/**
* Finds the appropriate network interface for a given IPv6 address. It tries to select
* a netif following a sequence of heuristics:
@@ -94,7 +98,8 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
if (ip6_addr_islinklocal(dest)) {
if (ip6_addr_isany(src)) {
/* Use default netif, if Up. */
- if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
+ if (netif_default == NULL || !netif_is_up(netif_default) ||
+ !netif_is_link_up(netif_default)) {
return NULL;
}
return netif_default;
@@ -114,7 +119,8 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
}
/* netif not found, use default netif, if up */
- if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
+ if (netif_default == NULL || !netif_is_up(netif_default) ||
+ !netif_is_link_up(netif_default)) {
return NULL;
}
return netif_default;
@@ -142,15 +148,9 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
}
/* Get the netif for a suitable router. */
- i = nd6_select_router(dest, NULL);
- if (i >= 0) {
- if (default_router_list[i].neighbor_entry != NULL) {
- if (default_router_list[i].neighbor_entry->netif != NULL) {
- if (netif_is_up(default_router_list[i].neighbor_entry->netif) && netif_is_link_up(default_router_list[i].neighbor_entry->netif)) {
- return default_router_list[i].neighbor_entry->netif;
- }
- }
- }
+ netif = nd6_find_route(dest);
+ if ((netif != NULL) && netif_is_up(netif) && netif_is_link_up(netif)) {
+ return netif;
}
/* try with the netif that matches the source address. */
@@ -172,7 +172,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
/* loopif is disabled, loopback traffic is passed through any netif */
if (ip6_addr_isloopback(dest)) {
/* don't check for link on loopback traffic */
- if (netif_is_up(netif_default)) {
+ if (netif_default != NULL && netif_is_up(netif_default)) {
return netif_default;
}
/* default netif is not up, just use any netif for loopback traffic */
@@ -290,8 +290,9 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
{
struct netif *netif;
- /* do not forward link-local addresses */
- if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
+ /* do not forward link-local or loopback addresses */
+ if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
+ ip6_addr_isloopback(ip6_current_dest_addr())) {
LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
IP6_STATS_INC(ip6.rterr);
IP6_STATS_INC(ip6.drop);
@@ -446,9 +447,11 @@ ip6_input(struct pbuf *p, struct netif *inp)
ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest);
ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src);
- /* Don't accept virtual IPv6 mapped IPv4 addresses */
- if (ip6_addr_isipv6mappedipv4(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
- ip6_addr_isipv6mappedipv4(ip_2_ip6(&ip_data.current_iphdr_src)) ) {
+ /* Don't accept virtual IPv4 mapped IPv6 addresses.
+ * Don't accept multicast source addresses. */
+ if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
+ ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
+ ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
IP6_STATS_INC(ip6.err);
IP6_STATS_INC(ip6.drop);
return ERR_OK;
@@ -509,12 +512,21 @@ ip6_input(struct pbuf *p, struct netif *inp)
}
}
}
- if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
- /* Do not match link-local addresses to other netifs. */
- netif = NULL;
- break;
- }
if (first) {
+ if (ip6_addr_islinklocal(ip6_current_dest_addr())
+#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
+ || ip6_addr_isloopback(ip6_current_dest_addr())
+#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
+ ) {
+ /* Do not match link-local addresses to other netifs. The loopback
+ * address is to be considered link-local and packets to it should be
+ * dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. This
+ * requirement cannot be implemented in the case that loopback
+ * traffic is sent across a non-loopback interface, however.
+ */
+ netif = NULL;
+ break;
+ }
first = 0;
netif = netif_list;
} else {
@@ -709,7 +721,7 @@ netif_found:
options_done:
/* p points to IPv6 header again. */
- pbuf_header_force(p, ip_data.current_ip_header_tot_len);
+ pbuf_header_force(p, (s16_t)ip_data.current_ip_header_tot_len);
/* send to upper layers */
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
@@ -809,8 +821,8 @@ ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
const ip6_addr_t *src_used = src;
if (dest != LWIP_IP_HDRINCL) {
if (src != NULL && ip6_addr_isany(src)) {
- src = ip_2_ip6(ip6_select_source_address(netif, dest));
- if ((src == NULL) || ip6_addr_isany(src)) {
+ src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
+ if ((src_used == NULL) || ip6_addr_isany(src_used)) {
/* No appropriate source address was found for this packet. */
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
IP6_STATS_INC(ip6.rterr);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ip6_addr.c b/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
index 1792f62..aa06659 100644
--- a/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
+++ b/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
@@ -132,8 +132,8 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
} else if (isxdigit(*s)) {
/* add current digit */
current_block_value = (current_block_value << 4) +
- (isdigit(*s) ? *s - '0' :
- 10 + (islower(*s) ? *s - 'a' : *s - 'A'));
+ (isdigit(*s) ? (u32_t)(*s - '0') :
+ (u32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A')));
} else {
/* unexpected digit, space? CRLF? */
break;
@@ -152,7 +152,7 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
/* convert to network byte order. */
if (addr) {
for (addr_index = 0; addr_index < 4; addr_index++) {
- addr->addr[addr_index] = htonl(addr->addr[addr_index]);
+ addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]);
}
}
@@ -199,7 +199,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
for (current_block_index = 0; current_block_index < 8; current_block_index++) {
/* get the current 16-bit block */
- current_block_value = htonl(addr->addr[current_block_index >> 1]);
+ current_block_value = lwip_htonl(addr->addr[current_block_index >> 1]);
if ((current_block_index & 0x1) == 0) {
current_block_value = current_block_value >> 16;
}
@@ -218,7 +218,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
if (empty_block_flag == 0) {
/* generate empty block "::", but only if more than one contiguous zero block,
* according to current formatting suggestions RFC 5952. */
- next_block_value = htonl(addr->addr[(current_block_index + 1) >> 1]);
+ next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]);
if ((current_block_index & 0x1) == 0x01) {
next_block_value = next_block_value >> 16;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ip6_frag.c b/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
index f41d167..ff07f71 100644
--- a/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
+++ b/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
@@ -147,7 +147,7 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
{
struct ip6_reassdata *prev;
u16_t pbufs_freed = 0;
- u8_t clen;
+ u16_t clen;
struct pbuf *p;
struct ip6_reass_helper *iprh;
@@ -262,7 +262,8 @@ ip6_reass(struct pbuf *p)
struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
struct ip6_frag_hdr *frag_hdr;
u16_t offset, len;
- u8_t clen, valid = 1;
+ u16_t clen;
+ u8_t valid = 1;
struct pbuf *q;
IP6_FRAG_STATS_INC(ip6_frag.recv);
@@ -278,12 +279,12 @@ ip6_reass(struct pbuf *p)
clen = pbuf_clen(p);
- offset = ntohs(frag_hdr->_fragment_offset);
+ offset = lwip_ntohs(frag_hdr->_fragment_offset);
/* Calculate fragment length from IPv6 payload length.
* Adjust for headers before Fragment Header.
* And finally adjust by Fragment Header length. */
- len = ntohs(ip6_current_header()->_plen);
+ len = lwip_ntohs(ip6_current_header()->_plen);
len -= (u16_t)(((u8_t*)p->payload - (const u8_t*)ip6_current_header()) - IP6_HLEN);
len -= IP6_FRAG_HLEN;
@@ -378,6 +379,7 @@ ip6_reass(struct pbuf *p)
/* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4).
This cannot fail since we already checked when receiving this fragment. */
u8_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM);
+ LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
}
#else /* IPV6_FRAG_COPYHEADER */
@@ -529,6 +531,7 @@ ip6_reass(struct pbuf *p)
if (IPV6_FRAG_REQROOM > 0) {
/* hide the extra bytes borrowed from ip6_hdr for struct ip6_reass_helper */
u8_t hdrerr = pbuf_header(next_pbuf, -(s16_t)(IPV6_FRAG_REQROOM));
+ LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
}
#endif
@@ -545,6 +548,7 @@ ip6_reass(struct pbuf *p)
if (IPV6_FRAG_REQROOM > 0) {
/* get back room for struct ip6_reass_helper (only required if sizeof(void*) > 4) */
u8_t hdrerr = pbuf_header(ipr->p, -(s16_t)(IPV6_FRAG_REQROOM));
+ LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
}
iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->p->payload - IP6_HLEN);
@@ -559,7 +563,7 @@ ip6_reass(struct pbuf *p)
- IP6_HLEN);
/* Set payload length in ip header. */
- iphdr_ptr->_plen = htons(ipr->datagram_len);
+ iphdr_ptr->_plen = lwip_htons(ipr->datagram_len);
/* Get the first pbuf. */
p = ipr->p;
@@ -609,6 +613,7 @@ nullreturn:
#if LWIP_IPV6 && LWIP_IPV6_FRAG
+#if !LWIP_NETIF_TX_SINGLE_PBUF
/** Allocate a new struct pbuf_custom_ref */
static struct pbuf_custom_ref*
ip6_frag_alloc_pbuf_custom_ref(void)
@@ -637,6 +642,7 @@ ip6_frag_free_pbuf_custom(struct pbuf *p)
}
ip6_frag_free_pbuf_custom_ref(pcr);
}
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
/**
* Fragment an IPv6 datagram if too large for the netif or path MTU.
@@ -657,7 +663,11 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
struct ip6_hdr *ip6hdr;
struct ip6_frag_hdr *frag_hdr;
struct pbuf *rambuf;
+#if !LWIP_NETIF_TX_SINGLE_PBUF
struct pbuf *newpbuf;
+ u16_t newpbuflen = 0;
+ u16_t left_to_copy;
+#endif
static u32_t identification;
u16_t nfb;
u16_t left, cop;
@@ -665,8 +675,6 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
u16_t fragment_offset = 0;
u16_t last;
u16_t poff = IP6_HLEN;
- u16_t newpbuflen = 0;
- u16_t left_to_copy;
identification++;
@@ -685,6 +693,26 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
/* Fill this fragment */
cop = last ? left : nfb;
+#if LWIP_NETIF_TX_SINGLE_PBUF
+ rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM);
+ if (rambuf == NULL) {
+ IP6_FRAG_STATS_INC(ip6_frag.memerr);
+ return ERR_MEM;
+ }
+ LWIP_ASSERT("this needs a pbuf in one piece!",
+ (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
+ poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff);
+ /* make room for the IP header */
+ if (pbuf_header(rambuf, IP6_HLEN)) {
+ pbuf_free(rambuf);
+ IP6_FRAG_STATS_INC(ip6_frag.memerr);
+ return ERR_MEM;
+ }
+ /* fill in the IP header */
+ SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
+ ip6hdr = (struct ip6_hdr *)rambuf->payload;
+ frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
+#else
/* When not using a static buffer, create a chain of pbufs.
* The first will be a PBUF_RAM holding the link, IPv6, and Fragment header.
* The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
@@ -696,7 +724,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
return ERR_MEM;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
- (p->len >= (IP6_HLEN + IP6_FRAG_HLEN)));
+ (p->len >= (IP6_HLEN)));
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
ip6hdr = (struct ip6_hdr *)rambuf->payload;
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
@@ -743,12 +771,13 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
}
}
poff = newpbuflen;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
/* Set headers */
frag_hdr->_nexth = original_ip6hdr->_nexth;
frag_hdr->reserved = 0;
- frag_hdr->_fragment_offset = htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG));
- frag_hdr->_identification = htonl(identification);
+ frag_hdr->_fragment_offset = lwip_htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG));
+ frag_hdr->_identification = lwip_htonl(identification);
IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT);
IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/mld6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/mld6.c b/net/ip/lwip_base/src/core/ipv6/mld6.c
index 2ebcff3..9acb82f 100644
--- a/net/ip/lwip_base/src/core/ipv6/mld6.c
+++ b/net/ip/lwip_base/src/core/ipv6/mld6.c
@@ -564,7 +564,7 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
#if CHECKSUM_GEN_ICMP6
- IF__NETIF_CHECKSUM_ENABLED(group->netif, NETIF_CHECKSUM_GEN_ICMP6) {
+ IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
src_addr, &(group->group_address));
}
@@ -573,6 +573,11 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
/* Add hop-by-hop headers options: router alert with MLD value. */
ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
+ if (type == ICMP6_TYPE_MLR) {
+ /* Remember we were the last to report */
+ group->last_reporter_flag = 1;
+ }
+
/* Send the packet out. */
MLD6_STATS_INC(mld6.xmit);
ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/nd6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/nd6.c b/net/ip/lwip_base/src/core/ipv6/nd6.c
index 7806f6e..0b36718 100644
--- a/net/ip/lwip_base/src/core/ipv6/nd6.c
+++ b/net/ip/lwip_base/src/core/ipv6/nd6.c
@@ -46,6 +46,7 @@
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/nd6.h"
+#include "lwip/priv/nd6_priv.h"
#include "lwip/prot/nd6.h"
#include "lwip/prot/icmp6.h"
#include "lwip/pbuf.h"
@@ -59,9 +60,14 @@
#include "lwip/mld6.h"
#include "lwip/ip.h"
#include "lwip/stats.h"
+#include "lwip/dns.h"
#include <string.h>
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
#if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
#error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
#endif
@@ -93,10 +99,13 @@ static void nd6_free_neighbor_cache_entry(s8_t i);
static s8_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr);
static s8_t nd6_new_destination_cache_entry(void);
static s8_t nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif);
+static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif);
static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif);
static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif);
static s8_t nd6_get_onlink_prefix(ip6_addr_t *prefix, struct netif *netif);
static s8_t nd6_new_onlink_prefix(ip6_addr_t *prefix, struct netif *netif);
+static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif);
+static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q);
#define ND6_SEND_FLAG_MULTICAST_DEST 0x01
#define ND6_SEND_FLAG_ALLNODES_DEST 0x02
@@ -149,50 +158,27 @@ nd6_input(struct pbuf *p, struct netif *inp)
/* Unsolicited NA?*/
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
+ ip6_addr_t target_address;
+
/* This is an unsolicited NA.
* link-layer changed?
* part of DAD mechanism? */
- /* Check that link-layer address option also fits in packet. */
- if (p->len < (sizeof(struct na_header) + 2)) {
- /* @todo debug message */
- pbuf_free(p);
- ND6_STATS_INC(nd6.lenerr);
- ND6_STATS_INC(nd6.drop);
- return;
- }
-
- lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
-
- if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
- /* @todo debug message */
- pbuf_free(p);
- ND6_STATS_INC(nd6.lenerr);
- ND6_STATS_INC(nd6.drop);
- return;
- }
-
- /* Override ip6_current_dest_addr() so that we have an aligned copy. */
- ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address));
+ /* Create an aligned copy. */
+ ip6_addr_set(&target_address, &(na_hdr->target_address));
#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
/* If the target address matches this netif, it is a DAD response. */
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
- ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
+ ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
/* We are using a duplicate address. */
netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
-#if LWIP_IPV6_MLD
- /* Leave solicited node multicast group. */
- ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(inp, i)->addr[3]);
- mld6_leavegroup(netif_ip6_addr(inp, i), &multicast_address);
-#endif /* LWIP_IPV6_MLD */
-
#if LWIP_IPV6_AUTOCONFIG
/* Check to see if this address was autoconfigured. */
- if (!ip6_addr_islinklocal(ip6_current_dest_addr())) {
- i = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp);
+ if (!ip6_addr_islinklocal(&target_address)) {
+ i = nd6_get_onlink_prefix(&target_address, inp);
if (i >= 0) {
/* Mark this prefix as duplicate, so that we don't use it
* to generate this address again. */
@@ -207,23 +193,44 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */
+ /* Check that link-layer address option also fits in packet. */
+ if (p->len < (sizeof(struct na_header) + 2)) {
+ /* @todo debug message */
+ pbuf_free(p);
+ ND6_STATS_INC(nd6.lenerr);
+ ND6_STATS_INC(nd6.drop);
+ return;
+ }
+
+ lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+
+ if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
+ /* @todo debug message */
+ pbuf_free(p);
+ ND6_STATS_INC(nd6.lenerr);
+ ND6_STATS_INC(nd6.drop);
+ return;
+ }
+
/* This is an unsolicited NA, most likely there was a LLADDR change. */
- i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr());
+ i = nd6_find_neighbor_cache_entry(&target_address);
if (i >= 0) {
if (na_hdr->flags & ND6_FLAG_OVERRIDE) {
MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
}
}
} else {
+ ip6_addr_t target_address;
+
/* This is a solicited NA.
* neighbor address resolution response?
* neighbor unreachability detection response? */
- /* Override ip6_current_dest_addr() so that we have an aligned copy. */
- ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address));
+ /* Create an aligned copy. */
+ ip6_addr_set(&target_address, &(na_hdr->target_address));
/* Find the cache entry corresponding to this na. */
- i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr());
+ i = nd6_find_neighbor_cache_entry(&target_address);
if (i < 0) {
/* We no longer care about this target address. drop it. */
pbuf_free(p);
@@ -231,8 +238,6 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
/* Update cache entry. */
- neighbor_cache[i].netif = inp;
- neighbor_cache[i].counter.reachable_time = reachable_time;
if ((na_hdr->flags & ND6_FLAG_OVERRIDE) ||
(neighbor_cache[i].state == ND6_INCOMPLETE)) {
/* Check that link-layer address option also fits in packet. */
@@ -256,7 +261,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
}
+
+ neighbor_cache[i].netif = inp;
neighbor_cache[i].state = ND6_REACHABLE;
+ neighbor_cache[i].counter.reachable_time = reachable_time;
/* Send queued packets, if any. */
if (neighbor_cache[i].q != NULL) {
@@ -326,6 +334,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
}
} else {
+ ip6_addr_t target_address;
+
/* Sender is trying to resolve our address. */
/* Verify that they included their own link-layer address. */
if (lladdr_opt == NULL) {
@@ -345,7 +355,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
/* Delay probe in case we get confirmation of reachability from upper layer (TCP). */
neighbor_cache[i].state = ND6_DELAY;
- neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+ neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
}
} else {
/* Add their IPv6 address and link-layer address to neighbor cache.
@@ -366,14 +376,14 @@ nd6_input(struct pbuf *p, struct netif *inp)
/* Receiving a message does not prove reachability: only in one direction.
* Delay probe in case we get confirmation of reachability from upper layer (TCP). */
neighbor_cache[i].state = ND6_DELAY;
- neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+ neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
}
- /* Override ip6_current_dest_addr() so that we have an aligned copy. */
- ip6_addr_set(ip6_current_dest_addr(), &(ns_hdr->target_address));
+ /* Create an aligned copy. */
+ ip6_addr_set(&target_address, &(ns_hdr->target_address));
/* Send back a NA for us. Allocate the reply pbuf. */
- nd6_send_na(inp, ip6_current_dest_addr(), ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE);
+ nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE);
}
break; /* ICMP6_TYPE_NS */
@@ -383,6 +393,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
struct ra_header *ra_hdr;
u8_t *buffer; /* Used to copy options. */
u16_t offset;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+ /* There can by multiple RDNSS options per RA */
+ u8_t rdnss_server_idx = 0;
+#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */
/* Check that RA header fits in packet. */
if (p->len < sizeof(struct ra_header)) {
@@ -419,15 +433,15 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
/* Re-set invalidation timer. */
- default_router_list[i].invalidation_timer = htons(ra_hdr->router_lifetime);
+ default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime);
/* Re-set default timer values. */
#if LWIP_ND6_ALLOW_RA_UPDATES
if (ra_hdr->retrans_timer > 0) {
- retrans_timer = htonl(ra_hdr->retrans_timer);
+ retrans_timer = lwip_htonl(ra_hdr->retrans_timer);
}
if (ra_hdr->reachable_time > 0) {
- reachable_time = htonl(ra_hdr->reachable_time);
+ reachable_time = lwip_htonl(ra_hdr->reachable_time);
}
#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
@@ -478,9 +492,9 @@ nd6_input(struct pbuf *p, struct netif *inp)
{
struct mtu_option *mtu_opt;
mtu_opt = (struct mtu_option *)buffer;
- if (htonl(mtu_opt->mtu) >= 1280) {
+ if (lwip_htonl(mtu_opt->mtu) >= 1280) {
#if LWIP_ND6_ALLOW_RA_UPDATES
- inp->mtu = (u16_t)htonl(mtu_opt->mtu);
+ inp->mtu = (u16_t)lwip_htonl(mtu_opt->mtu);
#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
}
break;
@@ -495,18 +509,19 @@ nd6_input(struct pbuf *p, struct netif *inp)
!ip6_addr_islinklocal(&(prefix_opt->prefix))) {
/* Add to on-link prefix list. */
s8_t prefix;
+ ip6_addr_t prefix_addr;
/* Get a memory-aligned copy of the prefix. */
- ip6_addr_set(ip6_current_dest_addr(), &(prefix_opt->prefix));
+ ip6_addr_set(&prefix_addr, &(prefix_opt->prefix));
/* find cache entry for this prefix. */
- prefix = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp);
+ prefix = nd6_get_onlink_prefix(&prefix_addr, inp);
if (prefix < 0) {
/* Create a new cache entry. */
- prefix = nd6_new_onlink_prefix(ip6_current_dest_addr(), inp);
+ prefix = nd6_new_onlink_prefix(&prefix_addr, inp);
}
if (prefix >= 0) {
- prefix_list[prefix].invalidation_timer = htonl(prefix_opt->valid_lifetime);
+ prefix_list[prefix].invalidation_timer = lwip_htonl(prefix_opt->valid_lifetime);
#if LWIP_IPV6_AUTOCONFIG
if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) {
@@ -526,6 +541,37 @@ nd6_input(struct pbuf *p, struct netif *inp)
route_opt = (struct route_option *)buffer;*/
break;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+ case ND6_OPTION_TYPE_RDNSS:
+ {
+ u8_t num, n;
+ struct rdnss_option * rdnss_opt;
+
+ rdnss_opt = (struct rdnss_option *)buffer;
+ num = (rdnss_opt->length - 1) / 2;
+ for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) {
+ ip_addr_t rdnss_address;
+
+ /* Get a memory-aligned copy of the prefix. */
+ ip_addr_copy_from_ip6(rdnss_address, rdnss_opt->rdnss_address[n]);
+
+ if (htonl(rdnss_opt->lifetime) > 0) {
+ /* TODO implement Lifetime > 0 */
+ dns_setserver(rdnss_server_idx++, &rdnss_address);
+ } else {
+ /* TODO implement DNS removal in dns.c */
+ u8_t s;
+ for (s = 0; s < DNS_MAX_SERVERS; s++) {
+ const ip_addr_t *addr = dns_getserver(s);
+ if(ip_addr_cmp(addr, &rdnss_address)) {
+ dns_setserver(s, NULL);
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */
default:
/* Unrecognized option, abort. */
ND6_STATS_INC(nd6.proterr);
@@ -541,6 +587,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
{
struct redirect_header *redir_hdr;
struct lladdr_option *lladdr_opt;
+ ip6_addr_t tmp;
/* Check that Redir header fits in packet. */
if (p->len < sizeof(struct redirect_header)) {
@@ -563,10 +610,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
/* Copy original destination address to current source address, to have an aligned copy. */
- ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->destination_address));
+ ip6_addr_set(&tmp, &(redir_hdr->destination_address));
/* Find dest address in cache */
- i = nd6_find_destination_cache_entry(ip6_current_src_addr());
+ i = nd6_find_destination_cache_entry(&tmp);
if (i < 0) {
/* Destination not in cache, drop packet. */
pbuf_free(p);
@@ -580,20 +627,20 @@ nd6_input(struct pbuf *p, struct netif *inp)
if (lladdr_opt != NULL) {
if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) {
/* Copy target address to current source address, to have an aligned copy. */
- ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->target_address));
+ ip6_addr_set(&tmp, &(redir_hdr->target_address));
- i = nd6_find_neighbor_cache_entry(ip6_current_src_addr());
+ i = nd6_find_neighbor_cache_entry(&tmp);
if (i < 0) {
i = nd6_new_neighbor_cache_entry();
if (i >= 0) {
neighbor_cache[i].netif = inp;
MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
- ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr());
+ ip6_addr_set(&(neighbor_cache[i].next_hop_address), &tmp);
/* Receiving a message does not prove reachability: only in one direction.
* Delay probe in case we get confirmation of reachability from upper layer (TCP). */
neighbor_cache[i].state = ND6_DELAY;
- neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+ neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
}
}
if (i >= 0) {
@@ -602,7 +649,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
/* Receiving a message does not prove reachability: only in one direction.
* Delay probe in case we get confirmation of reachability from upper layer (TCP). */
neighbor_cache[i].state = ND6_DELAY;
- neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+ neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
}
}
}
@@ -614,6 +661,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
struct icmp6_hdr *icmp6hdr; /* Packet too big message */
struct ip6_hdr *ip6hdr; /* IPv6 header of the packet which caused the error */
u32_t pmtu;
+ ip6_addr_t tmp;
/* Check that ICMPv6 header + IPv6 header fit in payload */
if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) {
@@ -628,10 +676,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr));
/* Copy original destination address to current source address, to have an aligned copy. */
- ip6_addr_set(ip6_current_src_addr(), &(ip6hdr->dest));
+ ip6_addr_set(&tmp, &(ip6hdr->dest));
/* Look for entry in destination cache. */
- i = nd6_find_destination_cache_entry(ip6_current_src_addr());
+ i = nd6_find_destination_cache_entry(&tmp);
if (i < 0) {
/* Destination not in cache, drop packet. */
pbuf_free(p);
@@ -639,7 +687,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
/* Change the Path MTU. */
- pmtu = htonl(icmp6hdr->data);
+ pmtu = lwip_htonl(icmp6hdr->data);
destination_cache[i].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF);
break; /* ICMP6_TYPE_PTB */
@@ -698,15 +746,15 @@ nd6_tmr(void)
}
break;
case ND6_STALE:
- neighbor_cache[i].counter.stale_time += ND6_TMR_INTERVAL;
+ neighbor_cache[i].counter.stale_time++;
break;
case ND6_DELAY:
- if (neighbor_cache[i].counter.delay_time <= ND6_TMR_INTERVAL) {
+ if (neighbor_cache[i].counter.delay_time <= 1) {
/* Change to PROBE state. */
neighbor_cache[i].state = ND6_PROBE;
neighbor_cache[i].counter.probes_sent = 0;
} else {
- neighbor_cache[i].counter.delay_time -= ND6_TMR_INTERVAL;
+ neighbor_cache[i].counter.delay_time--;
}
break;
case ND6_PROBE:
@@ -821,13 +869,6 @@ nd6_tmr(void)
netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED);
/* @todo implement preferred and valid lifetimes. */
} else if (netif->flags & NETIF_FLAG_UP) {
-#if LWIP_IPV6_MLD
- if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) == 0) {
- /* Join solicited node multicast group. */
- ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, i)->addr[3]);
- mld6_joingroup(netif_ip6_addr(netif, i), &multicast_address);
- }
-#endif /* LWIP_IPV6_MLD */
/* Send a NS for this address. */
nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST);
/* tentative: set next state by increasing by one */
@@ -1286,6 +1327,22 @@ nd6_new_destination_cache_entry(void)
}
/**
+ * Clear the destination cache.
+ *
+ * This operation may be necessary for consistency in the light of changing
+ * local addresses and/or use of the gateway hook.
+ */
+void
+nd6_clear_destination_cache(void)
+{
+ int i;
+
+ for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+ ip6_addr_set_any(&destination_cache[i].destination_addr);
+ }
+}
+
+/**
* Determine whether an address matches an on-link prefix.
*
* @param ip6addr the IPv6 address to match
@@ -1320,7 +1377,7 @@ nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif)
* @return the default router entry index, or -1 if no suitable
* router is found
*/
-s8_t
+static s8_t
nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
{
s8_t i;
@@ -1373,6 +1430,30 @@ nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
}
/**
+ * Find a router-announced route to the given destination.
+ *
+ * The caller is responsible for checking whether the returned netif, if any,
+ * is in a suitable state (up, link up) to be used for packet transmission.
+ *
+ * @param ip6addr the destination IPv6 address
+ * @return the netif to use for the destination, or NULL if none found
+ */
+struct netif *
+nd6_find_route(const ip6_addr_t *ip6addr)
+{
+ s8_t i;
+
+ i = nd6_select_router(ip6addr, NULL);
+ if (i >= 0) {
+ if (default_router_list[i].neighbor_entry != NULL) {
+ return default_router_list[i].neighbor_entry->netif; /* may be NULL */
+ }
+ }
+
+ return NULL;
+}
+
+/**
* Find an entry for a default router.
*
* @param router_addr the IPv6 address of the router
@@ -1408,6 +1489,7 @@ static s8_t
nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif)
{
s8_t router_index;
+ s8_t free_router_index;
s8_t neighbor_index;
/* Do we have a neighbor entry for this router? */
@@ -1431,12 +1513,22 @@ nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif)
neighbor_cache[neighbor_index].isrouter = 1;
/* Look for empty entry. */
- for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) {
+ free_router_index = LWIP_ND6_NUM_ROUTERS;
+ for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) {
+ /* check if router already exists (this is a special case for 2 netifs on the same subnet
+ - e.g. wifi and cable) */
+ if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){
+ return router_index;
+ }
if (default_router_list[router_index].neighbor_entry == NULL) {
- default_router_list[router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
- return router_index;
+ /* remember lowest free index to create a new entry */
+ free_router_index = router_index;
}
}
+ if (free_router_index < LWIP_ND6_NUM_ROUTERS) {
+ default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
+ return free_router_index;
+ }
/* Could not create a router entry. */
@@ -1513,9 +1605,12 @@ nd6_new_onlink_prefix(ip6_addr_t *prefix, struct netif *netif)
* suitable next hop was found, ERR_MEM if no cache entry
* could be created
*/
-s8_t
+static s8_t
nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
{
+#ifdef LWIP_HOOK_ND6_GET_GW
+ const ip6_addr_t *next_hop_addr;
+#endif /* LWIP_HOOK_ND6_GET_GW */
s8_t i;
#if LWIP_NETIF_HWADDRHINT
@@ -1559,6 +1654,12 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
/* Destination in local link. */
destination_cache[nd6_cached_destination_index].pmtu = netif->mtu;
ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr);
+#ifdef LWIP_HOOK_ND6_GET_GW
+ } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) {
+ /* Next hop for destination provided by hook function. */
+ destination_cache[nd6_cached_destination_index].pmtu = netif->mtu;
+ ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr);
+#endif /* LWIP_HOOK_ND6_GET_GW */
} else {
/* We need to select a router. */
i = nd6_select_router(ip6addr, netif);
@@ -1626,7 +1727,7 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
* @param q packet to be queued
* @return ERR_OK if succeeded, ERR_MEM if out of memory
*/
-err_t
+static err_t
nd6_queue_packet(s8_t neighbor_index, struct pbuf *q)
{
err_t result = ERR_MEM;
@@ -1762,6 +1863,7 @@ static void
nd6_send_q(s8_t i)
{
struct ip6_hdr *ip6hdr;
+ ip6_addr_t dest;
#if LWIP_ND6_QUEUEING
struct nd6_q_entry *q;
#endif /* LWIP_ND6_QUEUEING */
@@ -1778,10 +1880,10 @@ nd6_send_q(s8_t i)
neighbor_cache[i].q = q->next;
/* Get ipv6 header. */
ip6hdr = (struct ip6_hdr *)(q->p->payload);
- /* Override ip6_current_dest_addr() so that we have an aligned copy. */
- ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest));
+ /* Create an aligned copy. */
+ ip6_addr_set(&dest, &(ip6hdr->dest));
/* send the queued IPv6 packet */
- (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, ip6_current_dest_addr());
+ (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, &dest);
/* free the queued IP packet */
pbuf_free(q->p);
/* now queue entry can be freed */
@@ -1791,10 +1893,10 @@ nd6_send_q(s8_t i)
if (neighbor_cache[i].q != NULL) {
/* Get ipv6 header. */
ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload);
- /* Override ip6_current_dest_addr() so that we have an aligned copy. */
- ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest));
+ /* Create an aligned copy. */
+ ip6_addr_set(&dest, &(ip6hdr->dest));
/* send the queued IPv6 packet */
- (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, ip6_current_dest_addr());
+ (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, &dest);
/* free the queued IP packet */
pbuf_free(neighbor_cache[i].q);
neighbor_cache[i].q = NULL;
@@ -1802,6 +1904,61 @@ nd6_send_q(s8_t i)
#endif /* LWIP_ND6_QUEUEING */
}
+/**
+ * A packet is to be transmitted to a specific IPv6 destination on a specific
+ * interface. Check if we can find the hardware address of the next hop to use
+ * for the packet. If so, give the hardware address to the caller, which should
+ * use it to send the packet right away. Otherwise, enqueue the packet for
+ * later transmission while looking up the hardware address, if possible.
+ *
+ * As such, this function returns one of three different possible results:
+ *
+ * - ERR_OK with a non-NULL 'hwaddrp': the caller should send the packet now.
+ * - ERR_OK with a NULL 'hwaddrp': the packet has been enqueued for later.
+ * - not ERR_OK: something went wrong; forward the error upward in the stack.
+ *
+ * @param netif The lwIP network interface on which the IP packet will be sent.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ip6addr The destination IPv6 address of the packet.
+ * @param hwaddrp On success, filled with a pointer to a HW address or NULL (meaning
+ * the packet has been queued).
+ * @return
+ * - ERR_OK on success, ERR_RTE if no route was found for the packet,
+ * or ERR_MEM if low memory conditions prohibit sending the packet at all.
+ */
+err_t
+nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp)
+{
+ s8_t i;
+
+ /* Get next hop record. */
+ i = nd6_get_next_hop_entry(ip6addr, netif);
+ if (i < 0) {
+ /* failed to get a next hop neighbor record. */
+ return i;
+ }
+
+ /* Now that we have a destination record, send or queue the packet. */
+ if (neighbor_cache[i].state == ND6_STALE) {
+ /* Switch to delay state. */
+ neighbor_cache[i].state = ND6_DELAY;
+ neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+ }
+ /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */
+ if ((neighbor_cache[i].state == ND6_REACHABLE) ||
+ (neighbor_cache[i].state == ND6_DELAY) ||
+ (neighbor_cache[i].state == ND6_PROBE)) {
+
+ /* Tell the caller to send out the packet now. */
+ *hwaddrp = neighbor_cache[i].lladdr;
+ return ERR_OK;
+ }
+
+ /* We should queue packet on this interface. */
+ *hwaddrp = NULL;
+ return nd6_queue_packet(i, q);
+}
+
/**
* Get the Path MTU for a destination.
@@ -1908,4 +2065,38 @@ nd6_cleanup_netif(struct netif *netif)
}
}
+#if LWIP_IPV6_MLD
+/**
+ * The state of a local IPv6 address entry is about to change. If needed, join
+ * or leave the solicited-node multicast group for the address.
+ *
+ * @param netif The netif that owns the address.
+ * @param addr_idx The index of the address.
+ * @param new_state The new (IP6_ADDR_) state for the address.
+ */
+void
+nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state)
+{
+ u8_t old_state, old_member, new_member;
+
+ old_state = netif_ip6_addr_state(netif, addr_idx);
+
+ /* Determine whether we were, and should be, a member of the solicited-node
+ * multicast group for this address. For tentative addresses, the group is
+ * not joined until the address enters the TENTATIVE_1 (or VALID) state. */
+ old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_TENTATIVE);
+ new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_TENTATIVE);
+
+ if (old_member != new_member) {
+ ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]);
+
+ if (new_member) {
+ mld6_joingroup_netif(netif, &multicast_address);
+ } else {
+ mld6_leavegroup_netif(netif, &multicast_address);
+ }
+ }
+}
+#endif /* LWIP_IPV6_MLD */
+
#endif /* LWIP_IPV6 */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/mem.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/mem.c b/net/ip/lwip_base/src/core/mem.c
index 40f4cb9..db3b7cc 100644
--- a/net/ip/lwip_base/src/core/mem.c
+++ b/net/ip/lwip_base/src/core/mem.c
@@ -61,9 +61,13 @@
#include "lwip/err.h"
#include <string.h>
-#include <stdlib.h>
+
+#if MEM_LIBC_MALLOC
+#include <stdlib.h> /* for malloc()/free() */
+#endif
#if MEM_LIBC_MALLOC || MEM_USE_POOLS
+
/** mem_init is not used when using pools instead of a heap or using
* C library malloc().
*/
@@ -162,7 +166,7 @@ void *
mem_malloc(mem_size_t size)
{
void *ret;
- struct memp_malloc_helper *element;
+ struct memp_malloc_helper *element = NULL;
memp_t poolnr;
mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/memp.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/memp.c b/net/ip/lwip_base/src/core/memp.c
index 19198eb..58fab1a 100644
--- a/net/ip/lwip_base/src/core/memp.c
+++ b/net/ip/lwip_base/src/core/memp.c
@@ -71,11 +71,10 @@
#include "netif/ppp/ppp_opts.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
-#include "lwip/nd6.h"
+#include "lwip/priv/nd6_priv.h"
#include "lwip/ip6_frag.h"
#include "lwip/mld6.h"
-
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
#include "lwip/priv/memp_std.h"
@@ -84,6 +83,10 @@ const struct memp_desc* const memp_pools[MEMP_MAX] = {
#include "lwip/priv/memp_std.h"
};
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2
#undef MEMP_OVERFLOW_CHECK
/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */
@@ -205,11 +208,11 @@ memp_overflow_check_all(void)
SYS_ARCH_PROTECT(old_level);
for (i = 0; i < MEMP_MAX; ++i) {
- p = (struct memp *)(size_t)(memp_pools[i]->base);
+ p = (struct memp*)LWIP_MEM_ALIGN(memp_pools[i]->base);
for (j = 0; j < memp_pools[i]->num; ++j) {
memp_overflow_check_element_overflow(p, memp_pools[i]);
memp_overflow_check_element_underflow(p, memp_pools[i]);
- p = (struct memp*)(size_t)((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED);
+ p = LWIP_ALIGNMENT_CAST(struct memp*, ((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED));
}
}
SYS_ARCH_UNPROTECT(old_level);
@@ -301,15 +304,15 @@ do_memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int
SYS_ARCH_PROTECT(old_level);
memp = *desc->tab;
-
-#if MEMP_OVERFLOW_CHECK == 1
- memp_overflow_check_element_overflow(memp, desc);
- memp_overflow_check_element_underflow(memp, desc);
-#endif /* MEMP_OVERFLOW_CHECK */
#endif /* MEMP_MEM_MALLOC */
if (memp != NULL) {
#if !MEMP_MEM_MALLOC
+#if MEMP_OVERFLOW_CHECK == 1
+ memp_overflow_check_element_overflow(memp, desc);
+ memp_overflow_check_element_underflow(memp, desc);
+#endif /* MEMP_OVERFLOW_CHECK */
+
*desc->tab = memp->next;
#if MEMP_OVERFLOW_CHECK
memp->next = NULL;
@@ -471,6 +474,10 @@ memp_free(memp_t type, void *mem)
LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;);
+ if (mem == NULL) {
+ return;
+ }
+
#if MEMP_OVERFLOW_CHECK >= 2
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */