diff --git a/CHANGELOG b/CHANGELOG index f23128ed..c47b87a6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,7 +6,13 @@ HISTORY ++ New features: - 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) + 2011-05-25: Simon Goldschmidt + * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, + combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 + and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP + code so that the code is more readable. + + 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to Ivan! (this is work in progress: we're just post release anyway :-) diff --git a/src/api/api_lib.c b/src/api/api_lib.c index bc7507b7..47767512 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -143,7 +143,7 @@ netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) msg.function = do_getaddr; msg.msg.conn = conn; - msg.msg.msg.ad.ipaddr = addr; + msg.msg.msg.ad.ipaddr = ip_2_ipX(addr); msg.msg.msg.ad.port = port; msg.msg.msg.ad.local = local; err = TCPIP_APIMSG(&msg); @@ -481,11 +481,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf) buf->p = p; buf->ptr = p; buf->port = 0; -#if LWIP_IPV6 - ip6_addr_set_any(&buf->addr.ip6); -#else /* LWIP_IPV6 */ - ip_addr_set_any(&buf->addr.ip4); -#endif /* LWIP_IPV6 */ + ipX_addr_set_any(LWIP_IPV6, &buf->addr); *new_buf = buf; /* don't set conn->last_err: it's only ERR_OK, anyway */ return ERR_OK; @@ -544,15 +540,7 @@ err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port) { if (buf != NULL) { -#if LWIP_IPV6 - if (conn->pcb.ip->isipv6) { - ip6_addr_set(&buf->addr.ip6, (ip6_addr_t *)addr); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set(&buf->addr.ip4, addr); - } + ipX_addr_set_ipaddr(conn->pcb.ip->isipv6, &buf->addr, addr); buf->port = port; return netconn_send(conn, buf); } @@ -700,8 +688,8 @@ netconn_join_leave_group(struct netconn *conn, msg.function = do_join_leave_group; msg.msg.conn = conn; - msg.msg.msg.jl.multiaddr = multiaddr; - msg.msg.msg.jl.netif_addr = netif_addr; + msg.msg.msg.jl.multiaddr = ip_2_ipX(multiaddr); + msg.msg.msg.jl.netif_addr = ip_2_ipX(netif_addr); msg.msg.msg.jl.join_or_leave = join_or_leave; err = TCPIP_APIMSG(&msg); diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 6f6ffc4d..de226a5a 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -113,15 +113,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, buf->p = q; buf->ptr = q; -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_copy(buf->addr.ip6, *ip6_current_src_addr()); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_copy(buf->addr.ip4, *ip_current_src_addr()); - } + ipX_addr_copy(pcb->isipv6, buf->addr, *ipX_current_src_addr()); buf->port = pcb->protocol; len = q->tot_len; @@ -184,38 +176,16 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, } else { buf->p = p; buf->ptr = p; -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - ip6_addr_set(&buf->addr.ip6, (ip6_addr_t *)addr); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set(&buf->addr.ip4, addr); - } + ipX_addr_set_ipaddr(ip_current_is_v6(), &buf->addr, addr); buf->port = port; #if LWIP_NETBUF_RECVINFO -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - /* get the UDP header - always in the first pbuf, ensured by udp_input */ - const struct udp_hdr* udphdr = (void*)(((char*)ip6_current_header()) + - ip6_current_header_tot_len()); -#if LWIP_CHECKSUM_ON_COPY - buf->flags = NETBUF_FLAG_DESTADDR; -#endif /* LWIP_CHECKSUM_ON_COPY */ - ip6_addr_set(&buf->toaddr.ip6, ip6_current_dest_addr()); - buf->toport_chksum = udphdr->dest; - } - else -#endif /* LWIP_IPV6 */ { - const struct ip_hdr* iphdr = ip_current_header(); /* get the UDP header - always in the first pbuf, ensured by udp_input */ - const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr)); + const struct udp_hdr* udphdr = ipX_next_header_ptr(); #if LWIP_CHECKSUM_ON_COPY buf->flags = NETBUF_FLAG_DESTADDR; #endif /* LWIP_CHECKSUM_ON_COPY */ - ip_addr_set(&buf->toaddr.ip4, ip_current_dest_addr()); + ipX_addr_set(ip_current_is_v6(), &buf->toaddr, ipX_current_dest_addr()); buf->toport_chksum = udphdr->dest; } #endif /* LWIP_NETBUF_RECVINFO */ @@ -517,71 +487,51 @@ pcb_new(struct api_msg_msg *msg) switch(NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - msg->conn->pcb.raw = raw_new_ip6(msg->msg.n.proto); + msg->conn->pcb.raw = raw_new(msg->msg.n.proto); + if(msg->conn->pcb.raw != NULL) { + raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); } - else -#endif /* LWIP_IPV6 */ - { - msg->conn->pcb.raw = raw_new(msg->msg.n.proto); - } - if(msg->conn->pcb.raw == NULL) { - msg->err = ERR_MEM; - break; - } - raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - msg->conn->pcb.udp = udp_new_ip6(); - } - else -#endif /* LWIP_IPV6 */ - { - msg->conn->pcb.udp = udp_new(); - } - if(msg->conn->pcb.udp == NULL) { - msg->err = ERR_MEM; - break; - } + msg->conn->pcb.udp = udp_new(); + if(msg->conn->pcb.udp != NULL) { #if LWIP_UDPLITE - if (NETCONNTYPE_ISUDPLITE((msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); - } + if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); + } #endif /* LWIP_UDPLITE */ - if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); } - udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - msg->conn->pcb.tcp = tcp_new_ip6(); + msg->conn->pcb.tcp = tcp_new(); + if(msg->conn->pcb.tcp != NULL) { + setup_tcp(msg->conn); } - else -#endif /* LWIP_IPV6 */ - { - msg->conn->pcb.tcp = tcp_new(); - } - if(msg->conn->pcb.tcp == NULL) { - msg->err = ERR_MEM; - break; - } - setup_tcp(msg->conn); break; #endif /* LWIP_TCP */ default: /* Unsupported netconn type, e.g. protocol disabled */ msg->err = ERR_VAL; - break; + return; } + if (msg->conn->pcb.ip == NULL) { + msg->err = ERR_MEM; + } +#if LWIP_IPV6 + else { + if (NETCONNTYPE_ISIPV6(msg->conn->type)) { + ip_set_v6(msg->conn->pcb.ip, 1); + } + } +#endif /* LWIP_IPV6 */ } /** @@ -878,7 +828,8 @@ do_delconn(struct api_msg_msg *msg) (msg->conn->state != NETCONN_LISTEN) && (msg->conn->state != NETCONN_CONNECT)) { /* this only happens for TCP netconns */ - LWIP_ASSERT("msg->conn->type == NETCONN_TCP", NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); + LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP", + NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); msg->err = ERR_INPROGRESS; } else { LWIP_ASSERT("blocking connect in progress", @@ -1167,62 +1118,29 @@ do_send(struct api_msg_msg *msg) switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: -#if LWIP_IPV6 - if (msg->conn->pcb.ip->isipv6) { - if (ip6_addr_isany(&msg->msg.b->addr.ip6)) { - msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); - } else { - msg->err = raw_sendto_ip6(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr.ip6); - } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(&msg->msg.b->addr.ip4)) { + if (ipX_addr_isany(msg->conn->pcb.ip->isipv6, &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.ip4); + msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, ipX_2_ip(&msg->msg.b->addr)); } break; #endif #if LWIP_UDP case NETCONN_UDP: #if LWIP_CHECKSUM_ON_COPY -#if LWIP_IPV6 - if (msg->conn->pcb.ip->isipv6) { - if (ip6_addr_isany(&msg->msg.b->addr.ip6)) { - msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } else { - msg->err = udp_sendto_chksum_ip6(msg->conn->pcb.udp, msg->msg.b->p, - &msg->msg.b->addr.ip6, msg->msg.b->port, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(&msg->msg.b->addr.ip4)) { + if (ipX_addr_isany(msg->conn->pcb.ip->isipv6, &msg->msg.b->addr)) { msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } else { msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, - &msg->msg.b->addr.ip4, msg->msg.b->port, + ipX_2_ip(&msg->msg.b->addr), msg->msg.b->port, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } #else /* LWIP_CHECKSUM_ON_COPY */ -#if LWIP_IPV6 - if (msg->conn->pcb.ip->isipv6) { - if (ip6_addr_isany(&msg->msg.b->addr.ip6)) { - msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); - } else { - msg->err = udp_sendto_ip6(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr.ip6, msg->msg.b->port); - } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(&msg->msg.b->addr.ip4)) { + if (ipX_addr_isany(msg->conn->pcb.ip->isipv6, &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.ip4, msg->msg.b->port); + msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, ipX_2_ip(&msg->msg.b->addr), msg->msg.b->port); } #endif /* LWIP_CHECKSUM_ON_COPY */ break; @@ -1455,21 +1373,13 @@ void do_getaddr(struct api_msg_msg *msg) { if (msg->conn->pcb.ip != NULL) { -#if LWIP_IPV6 - if (msg->conn->pcb.ip->isipv6) { - if (msg->msg.ad.local) { - ip6_addr_set((ip6_addr_t *)msg->msg.ad.ipaddr, &(msg->conn->pcb.ip->local_ip.ip6)); - } else { - ip6_addr_set((ip6_addr_t *)msg->msg.ad.ipaddr, &(msg->conn->pcb.ip->remote_ip.ip6)); - } + if (msg->msg.ad.local) { + ipX_addr_copy(msg->conn->pcb.ip->isipv6, *(msg->msg.ad.ipaddr), + msg->conn->pcb.ip->local_ip); + } else { + ipX_addr_copy(msg->conn->pcb.ip->isipv6, *(msg->msg.ad.ipaddr), + msg->conn->pcb.ip->remote_ip); } - else -#endif /* LWIP_IPV6 */ - { - *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip.ip4 : - msg->conn->pcb.ip->remote_ip.ip4); - } - msg->err = ERR_OK; switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW @@ -1523,7 +1433,8 @@ do_close(struct api_msg_msg *msg) /* @todo: abort running write/connect? */ if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) { /* this only happens for TCP netconns */ - LWIP_ASSERT("msg->conn->type == NETCONN_TCP", NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); + LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP", + NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); msg->err = ERR_INPROGRESS; } else if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)) { if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) { @@ -1569,9 +1480,11 @@ do_join_leave_group(struct api_msg_msg *msg) #if LWIP_IPV6 && LWIP_IPV6_MLD if (msg->conn->pcb.udp->isipv6) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = mld6_joingroup((ip6_addr_t *)msg->msg.jl.netif_addr, (ip6_addr_t *)msg->msg.jl.multiaddr); + msg->err = mld6_joingroup(ipX_2_ip6(msg->msg.jl.netif_addr), + ipX_2_ip6(msg->msg.jl.multiaddr)); } else { - msg->err = mld6_leavegroup((ip6_addr_t *)msg->msg.jl.netif_addr, (ip6_addr_t *)msg->msg.jl.multiaddr); + msg->err = mld6_leavegroup(ipX_2_ip6(msg->msg.jl.netif_addr), + ipX_2_ip6(msg->msg.jl.multiaddr)); } } else @@ -1579,9 +1492,11 @@ do_join_leave_group(struct api_msg_msg *msg) { #if LWIP_IGMP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); + msg->err = igmp_joingroup(ipX_2_ip(msg->msg.jl.netif_addr), + ipX_2_ip(msg->msg.jl.multiaddr)); } else { - msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); + msg->err = igmp_leavegroup(ipX_2_ip(msg->msg.jl.netif_addr), + ipX_2_ip(msg->msg.jl.multiaddr)); } #endif /* LWIP_IGMP */ } diff --git a/src/api/netbuf.c b/src/api/netbuf.c index 0aded3af..0ccd2bce 100644 --- a/src/api/netbuf.c +++ b/src/api/netbuf.c @@ -61,11 +61,7 @@ netbuf *netbuf_new(void) if (buf != NULL) { buf->p = NULL; buf->ptr = NULL; -#if LWIP_IPV6 - ip6_addr_set_any(&buf->addr.ip6); -#else /* LWIP_IPV6 */ - ip_addr_set_any(&buf->addr.ip4); -#endif /* LWIP_IPV6 */ + ipX_addr_set_any(LWIP_IPV6, &buf->addr); buf->port = 0; #if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY @@ -73,11 +69,7 @@ netbuf *netbuf_new(void) #endif /* LWIP_CHECKSUM_ON_COPY */ buf->toport_chksum = 0; #if LWIP_NETBUF_RECVINFO -#if LWIP_IPV6 - ip6_addr_set_any(&buf->toaddr.ip6); -#else /* LWIP_IPV6 */ - ip_addr_set_any(&buf->toaddr.ip4); -#endif /* LWIP_IPV6 */ + ipX_addr_set_any(LWIP_IPV6, &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 ba035de5..d897397b 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -58,15 +58,65 @@ #include -/* Check that the family member of a struct sockaddr matches the socket's IP version */ +#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipXaddr, port) do { \ + (sin)->sin_len = sizeof(struct sockaddr_in); \ + (sin)->sin_family = AF_INET; \ + (sin)->sin_port = htons((port)); \ + inet_addr_from_ipaddr(&(sin)->sin_addr, ipX_2_ip(ipXaddr)); \ + memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) +#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipXaddr, port) do { \ + inet_addr_to_ipaddr(ipX_2_ip(ipXaddr), &((sin)->sin_addr)); \ + (port) = (sin)->sin_port; }while(0) + #if LWIP_IPV6 -#define SOCK_ADDR_MATCH(name, sock) \ +#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ + ((namelen) == sizeof(struct sockaddr_in6))) +#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ + ((name)->sa_family == AF_INET6)) +#define SOCK_ADDR_TYPE_MATCH(name, sock) \ ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) +#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipXaddr, port) do { \ + (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ + (sin6)->sin6_family = AF_INET6; \ + (sin6)->sin6_port = htons((port)); \ + (sin6)->sin6_flowinfo = 0; \ + inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipX_2_ip6(ipXaddr)); }while(0) +#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) do { \ + if (isipv6) { \ + IP6ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in6*)(sockaddr)), ipXaddr, port); \ + } else { \ + IP4ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in*)(sockaddr)), ipXaddr, port); \ + } } while(0) +#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipXaddr, port) do { \ + inet6_addr_to_ip6addr(ipX_2_ip6(ipXaddr), &((sin6)->sin6_addr)); \ + (port) = (sin6)->sin6_port; }while(0) +#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) do { \ + if (isipv6) { \ + SOCKADDR6_TO_IP6ADDR_PORT(((struct sockaddr_in6*)(sockaddr)), ipXaddr, port); \ + } else { \ + SOCKADDR4_TO_IP4ADDR_PORT(((struct sockaddr_in*)(sockaddr)), ipXaddr, port); \ + } } while(0) +#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (((domain) == AF_INET) ? \ + (netconn_type) : ((netconn_type) | NETCONN_TYPE_IPV6)) #else /* LWIP_IPV6 */ -#define SOCK_ADDR_MATCH(name, sock) (((name)->sa_family) == AF_INET) +#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) +#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) +#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 +#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) \ + IP4ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in*)sockaddr), ipXaddr, port) +#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) \ + IP4ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in*)(sockaddr)), ipXaddr, port) +#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) #endif /* LWIP_IPV6 */ +#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ + IS_SOCK_ADDR_TYPE_VALID(name)) +#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ + SOCK_ADDR_TYPE_MATCH(name, sock)) +#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) + + #define NUM_SOCKETS MEMP_NUM_NETCONN @@ -323,19 +373,9 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { struct lwip_sock *sock, *nsock; struct netconn *newconn; - union { - ip_addr_t ip4; -#if LWIP_IPV6 - ip6_addr_t ip6; -#endif /* LWIP_IPV6 */ - } naddr; + ipX_addr_t naddr; u16_t port; int newsock; - struct sockaddr tempaddr; - struct sockaddr_in * sin; -#if LWIP_IPV6 - struct sockaddr_in6 * sin6; -#endif /* LWIP_IPV6 */ err_t err; SYS_ARCH_DECL_PROTECT(lev); @@ -362,47 +402,25 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) /* Prevent automatic window updates, we do this on our own! */ netconn_set_noautorecved(newconn, 1); - /* get the IP address and port of the remote host */ - err = netconn_peer(newconn, &naddr.ip4, &port); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); - netconn_delete(newconn); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - /* Note that POSIX only requires us to check addr is non-NULL. addrlen must * not be NULL if addr is valid. */ - if (NULL != addr) { + if (addr != NULL) { + struct sockaddr tempaddr; + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, ipX_2_ip(&naddr), &port); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + netconn_delete(newconn); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); - memset(&tempaddr, 0, sizeof(tempaddr)); -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(newconn->type)) { - sin6 = (struct sockaddr_in6 *)&tempaddr; - sin6->sin6_len = sizeof(struct sockaddr_in6); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons(port); - sin6->sin6_flowinfo = 0; - inet6_addr_from_ip6addr(&sin6->sin6_addr, &naddr.ip6); - - if (*addrlen > sin6->sin6_len) - *addrlen = sin6->sin6_len; + IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(newconn->type), &tempaddr, &naddr, port); + if (*addrlen > tempaddr.sa_len) { + *addrlen = tempaddr.sa_len; } - else -#endif /* LWIP_IPV6 */ - { - sin = (struct sockaddr_in *)&tempaddr; - sin->sin_len = sizeof(struct sockaddr_in); - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - inet_addr_from_ipaddr(&sin->sin_addr, &naddr.ip4); - - if (*addrlen > sin->sin_len) - *addrlen = sin->sin_len; - } - MEMCPY(addr, &tempaddr, *addrlen); } @@ -426,17 +444,12 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) newconn->socket = newsock; SYS_ARCH_UNPROTECT(lev); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(newconn->type)) { - ip6_addr_debug_print(SOCKETS_DEBUG, &naddr.ip6); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); + if (addr != NULL) { + LWIP_DEBUGF(SOCKETS_DEBUG, (" addr=")); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(newconn->type), SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_debug_print(SOCKETS_DEBUG, &naddr.ip4); - } - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); sock_set_errno(sock, 0); return newsock; @@ -446,53 +459,32 @@ int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) { struct lwip_sock *sock; - union { - ip_addr_t ip4; -#if LWIP_IPV6 - ip6_addr_t ip6; -#endif /* LWIP_IPV6 */ - } local_addr; + ipX_addr_t local_addr; u16_t local_port; err_t err; - const struct sockaddr_in *name_in; -#if LWIP_IPV6 - const struct sockaddr_in6 *name_in6; -#endif /* LWIP_IPV6 */ sock = get_socket(s); if (!sock) { return -1; } + if (SOCK_ADDR_TYPE_MATCH(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + return -1; + } + /* check size, familiy and alignment of 'name' */ - LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) && - SOCK_ADDR_MATCH(name, sock) && - ((((mem_ptr_t)name) % 4) == 0)), + LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &local_addr, local_port); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); -#if LWIP_IPV6 - if ((name->sa_family) == AF_INET6) { - name_in6 = (const struct sockaddr_in6 *)(void*)name; - - inet6_addr_to_ip6addr(&local_addr.ip6, &name_in6->sin6_addr); - ip6_addr_debug_print(SOCKETS_DEBUG, &local_addr.ip6); - - local_port = name_in6->sin6_port; - } - else -#endif /* LWIP_IPV6 */ - { - name_in = (const struct sockaddr_in *)(void*)name; - - inet_addr_to_ipaddr(&local_addr.ip4, &name_in->sin_addr); - ip_addr_debug_print(SOCKETS_DEBUG, &local_addr.ip4); - - local_port = name_in->sin_port; - } + ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &local_addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port))); - err = netconn_bind(sock->conn, &local_addr.ip4, ntohs(local_port)); + err = netconn_bind(sock->conn, ipX_2_ip(&local_addr), ntohs(local_port)); if (err != ERR_OK) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); @@ -542,48 +534,28 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) return -1; } + if (SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + return -1; + } + /* check size, familiy and alignment of 'name' */ - LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) && - SOCK_ADDR_MATCH(name, sock) && - ((((mem_ptr_t)name) % 4) == 0)), + LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); if (name->sa_family == AF_UNSPEC) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); err = netconn_disconnect(sock->conn); - } -#if LWIP_IPV6 - else if (name->sa_family == AF_INET6) { - const struct sockaddr_in6 *name_in6; - ip6_addr_t remote_addr; + } else { + ipX_addr_t remote_addr; u16_t remote_port; - - name_in6 = (const struct sockaddr_in6 *)(void*)name; - - inet6_addr_to_ip6addr(&remote_addr, &name_in6->sin6_addr); - remote_port = name_in6->sin6_port; - + SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &remote_addr, remote_port); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ip6_addr_debug_print(SOCKETS_DEBUG, &remote_addr); + ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &remote_addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); - err = netconn_connect(sock->conn, (ip_addr_t *)&remote_addr, ntohs(remote_port)); - } -#endif /* LWIP_IPV6 */ - else { - const struct sockaddr_in *name_in; - ip_addr_t remote_addr; - u16_t remote_port; - - name_in = (const struct sockaddr_in *)(void*)name; - - inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr); - remote_port = name_in->sin_port; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); - - err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); + err = netconn_connect(sock->conn, ipX_2_ip(&remote_addr), ntohs(remote_port)); } if (err != ERR_OK) { @@ -635,14 +607,13 @@ lwip_listen(int s, int backlog) int lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) + struct sockaddr *from, socklen_t *fromlen) { struct lwip_sock *sock; void *buf = NULL; struct pbuf *p; u16_t buflen, copylen; int off = 0; - u16_t port; u8_t done = 0; err_t err; @@ -747,64 +718,23 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, if (from && fromlen) #endif /* !SOCKETS_DEBUG */ { + u16_t port; + ipX_addr_t tmpaddr; + ipX_addr_t *fromaddr; + struct sockaddr saddr; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn))) { - ip6_addr_t *fromaddr6; - ip6_addr_t tmpaddr6; - struct sockaddr_in6 sin6; - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - /* @todo: implement netconn_getaddr() for IPv6 addresses */ - ip6_addr_set_any(&tmpaddr6); - fromaddr6 = &tmpaddr6; - port = 0; - } else { - fromaddr6 = netbuf_fromaddr_ip6((struct netbuf *)buf); - port = netbuf_fromport((struct netbuf *)buf); - } - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(sin6); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(port); - inet6_addr_from_ip6addr(&sin6.sin6_addr, fromaddr6); - - if (from && fromlen) { - if (*fromlen > sizeof(sin6)) { - *fromlen = sizeof(sin6); - } - MEMCPY(from, &sin6, *fromlen); - } - - ip6_addr_debug_print(SOCKETS_DEBUG, fromaddr6); - } else -#endif /* LWIP_IPV6 */ - { - ip_addr_t *fromaddr4; - ip_addr_t tmpaddr4; - struct sockaddr_in sin; - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - fromaddr4 = &tmpaddr4; - netconn_getaddr(sock->conn, fromaddr4, &port, 0); - } else { - fromaddr4 = netbuf_fromaddr((struct netbuf *)buf); - port = netbuf_fromport((struct netbuf *)buf); - } - - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - inet_addr_from_ipaddr(&sin.sin_addr, fromaddr4); - - if (from && fromlen) { - if (*fromlen > sizeof(sin)) { - *fromlen = sizeof(sin); - } - MEMCPY(from, &sin, *fromlen); - } - - ip_addr_debug_print(SOCKETS_DEBUG, &fromaddr4); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + fromaddr = &tmpaddr; + /* @todo: this does not work for IPv6, yet */ + netconn_getaddr(sock->conn, ipX_2_ip(fromaddr), &port, 0); + } else { + port = netbuf_fromport((struct netbuf *)buf); + fromaddr = netbuf_fromaddr_ipX((struct netbuf *)buf); } + IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + &saddr, fromaddr, port); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + SOCKETS_DEBUG, fromaddr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); } } @@ -866,7 +796,7 @@ lwip_send(int s, const void *data, size_t size, int flags) return -1; } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { #if (LWIP_UDP || LWIP_RAW) return lwip_sendto(s, data, size, flags, NULL, 0); #else /* (LWIP_UDP || LWIP_RAW) */ @@ -910,7 +840,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, return -1; } - if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_TCP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { #if LWIP_TCP return lwip_send(s, data, size, flags); #else /* LWIP_TCP */ @@ -920,13 +850,18 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #endif /* LWIP_TCP */ } + if (SOCK_ADDR_TYPE_MATCH(to, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + return -1; + } + /* @todo: split into multiple sendto's? */ LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); short_size = (u16_t)size; LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || - ((tolen == sizeof(struct sockaddr_in)) && - SOCK_ADDR_MATCH(to, sock) && - ((((mem_ptr_t)to) % 4) == 0))), + (IS_SOCK_ADDR_LEN_VALID(tolen) && + IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))), sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); #if LWIP_TCPIP_CORE_LOCKING @@ -943,7 +878,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, if (p != NULL) { #if LWIP_CHECKSUM_ON_COPY u16_t chksum = 0; - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_RAW) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); } else #endif /* LWIP_CHECKSUM_ON_COPY */ @@ -960,7 +895,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, const struct sockaddr_in6 *to_in6; to_in6 = (const struct sockaddr_in6 *)(void*)to; inet6_addr_to_ip6addr_p(remote_addr6, &to_in6->sin6_addr); - remote_addr = (ip_addr_t *)remote_addr6; + remote_addr = ip6_2_ip(remote_addr6); remote_port = ntohs(to_in6->sin6_port); } else @@ -974,19 +909,23 @@ lwip_sendto(int s, const void *data, size_t size, int flags, } else { remote_addr = IP_ADDR_ANY; #if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(sock->conn->type)) { - remote_addr6 = IP6_ADDR_ANY; - remote_addr = (ip_addr_t *)remote_addr6; + if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn))) { + remote_addr = ip6_2_ip(IP6_ADDR_ANY); } else #endif /* LWIP_IPV6 */ { remote_addr = IP_ADDR_ANY; } + if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_RAW) { + remote_port = 0; + } else { + remote_port = sock->conn->pcb.udp->remote_port; + } } LOCK_TCPIP_CORE(); - if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_RAW) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr); } else { #if LWIP_UDP @@ -1015,48 +954,18 @@ lwip_sendto(int s, const void *data, size_t size, int flags, buf.flags = 0; #endif /* LWIP_CHECKSUM_ON_COPY */ if (to) { -#if LWIP_IPV6 - if ((to->sa_family) == AF_INET6) { - const struct sockaddr_in6 *to_in6; - to_in6 = (const struct sockaddr_in6 *)(void*)to; - inet6_addr_to_ip6addr(&buf.addr.ip6, &to_in6->sin6_addr); - remote_port = ntohs(to_in6->sin6_port); - } - else -#endif /* LWIP_IPV6 */ - { - const struct sockaddr_in *to_in; - to_in = (const struct sockaddr_in *)(void*)to; - inet_addr_to_ipaddr(&buf.addr.ip4, &to_in->sin_addr); - remote_port = ntohs(to_in->sin_port); - } - netbuf_fromport(&buf) = remote_port; + SOCKADDR_TO_IPXADDR_PORT((to->sa_family) == AF_INET6, to, &buf.addr, remote_port); } else { remote_port = 0; -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(sock->conn->type)) { - ip6_addr_set_any(&buf.addr.ip6); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set_any(&buf.addr.ip4); - } - netbuf_fromport(&buf) = 0; + ipX_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); } + netbuf_fromport(&buf) = remote_port; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", s, data, short_size, flags)); -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(sock->conn->type)) { - ip6_addr_debug_print(SOCKETS_DEBUG, &buf.addr.ip6); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr.ip4); - } + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + 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 */ @@ -1066,7 +975,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, err = ERR_MEM; } else { #if LWIP_CHECKSUM_ON_COPY - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_RAW) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); netbuf_set_chksum(&buf, chksum); err = ERR_OK; @@ -1098,40 +1007,26 @@ lwip_socket(int domain, int type, int protocol) int i; #if !LWIP_IPV6 - LWIP_UNUSED_ARG(domain); + LWIP_UNUSED_ARG(domain); /* @todo: check this */ #endif /* LWIP_IPV6 */ /* create a netconn */ switch (type) { case SOCK_RAW: -#if LWIP_IPV6 - conn = netconn_new_with_proto_and_callback((domain == AF_INET) ? NETCONN_RAW : NETCONN_RAW_IPV6, + conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), (u8_t)protocol, event_callback); -#else /* LWIP_IPV6 */ - conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback); -#endif /* LWIP_IPV6 */ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); break; case SOCK_DGRAM: -#if LWIP_IPV6 - conn = netconn_new_with_callback((domain == AF_INET) ? - ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP) : - ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE_IPV6 : NETCONN_UDP_IPV6) , + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, + ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)) , event_callback); -#else /* LWIP_IPV6 */ - conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ? - NETCONN_UDPLITE : NETCONN_UDP, event_callback); -#endif /* LWIP_IPV6 */ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); break; case SOCK_STREAM: -#if LWIP_IPV6 - conn = netconn_new_with_callback((domain == AF_INET) ? NETCONN_TCP : NETCONN_TCP_IPV6, event_callback); -#else /* LWIP_IPV6 */ - conn = netconn_new_with_callback(NETCONN_TCP, event_callback); -#endif /* LWIP_IPV6 */ + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), event_callback); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); if (conn != NULL) { @@ -1399,8 +1294,6 @@ return_copy_fdsets: if (exceptset) { *exceptset = lexceptset; } - - return nready; } @@ -1573,63 +1466,31 @@ static int lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) { struct lwip_sock *sock; + struct sockaddr saddr; + ipX_addr_t naddr; + u16_t port; sock = get_socket(s); if (!sock) { return -1; } -#if LWIP_IPV6 - if (NETCONNTYPE_ISIPV6(sock->conn->type)) { - struct sockaddr_in6 sin6; - ip6_addr_t naddr6; + /* get the IP address and port */ + /* @todo: this does not work for IPv6, yet */ + netconn_getaddr(sock->conn, ipX_2_ip(&naddr), &port, local); + IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + &saddr, &naddr, port); - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(sin6); - sin6.sin6_family = AF_INET6; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); - /* get the IP address and port */ - netconn_getaddr(sock->conn, (ip_addr_t *)&naddr6, &sin6.sin6_port, local); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ip6_addr_debug_print(SOCKETS_DEBUG, &naddr6); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin6.sin6_port)); - - sin6.sin6_port = htons(sin6.sin6_port); - inet6_addr_from_ip6addr(&sin6.sin6_addr, &naddr6); - - if (*namelen > sizeof(sin6)) { - *namelen = sizeof(sin6); - } - - MEMCPY(name, &sin6, *namelen); + if (*namelen > saddr.sa_len) { + *namelen = saddr.sa_len; } - else -#endif /* LWIP_IPV6 */ - { - struct sockaddr_in sin; - ip_addr_t naddr; + MEMCPY(name, &saddr, *namelen); - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - - /* get the IP address and port */ - netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port)); - - sin.sin_port = htons(sin.sin_port); - inet_addr_from_ipaddr(&sin.sin_addr, &naddr); - - if (*namelen > sizeof(sin)) { - *namelen = sizeof(sin); - } - - MEMCPY(name, &sin, *namelen); - } sock_set_errno(sock, 0); return 0; } @@ -1703,12 +1564,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) err = EINVAL; } #if LWIP_UDP - if ( -#if LWIP_IPV6 - ((sock->conn->type != NETCONN_UDP) && (sock->conn->type != NETCONN_UDP_IPV6)) || -#else /* LWIP_IPV6 */ - (sock->conn->type != NETCONN_UDP) || -#endif /* LWIP_IPV6 */ + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP || ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { /* this flag is only available for UDP, not for UDP lite */ err = EAFNOSUPPORT; @@ -1750,7 +1606,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) if (*optlen < sizeof(u8_t)) { err = EINVAL; } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; @@ -1772,7 +1628,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) } /* If this is no TCP socket, ignore any options. */ - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) return 0; switch (optname) { @@ -1801,11 +1657,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) } /* If this is no UDP lite socket, ignore any options. */ -#if LWIP_IPV6 - if ((sock->conn->type != NETCONN_UDPLITE) && (sock->conn->type != NETCONN_UDPLITE_IPV6)) { -#else /* LWIP_IPV6 */ - if (sock->conn->type != NETCONN_UDPLITE) { -#endif /* LWIP_IPV6 */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { return 0; } @@ -1899,7 +1751,7 @@ lwip_getsockopt_internal(void *arg) break; case SO_TYPE: - switch (NETCONNTYPE_GROUP(sock->conn->type)) { + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { case NETCONN_RAW: *(int*)optval = SOCK_RAW; break; @@ -1910,11 +1762,11 @@ lwip_getsockopt_internal(void *arg) *(int*)optval = SOCK_DGRAM; break; default: /* unrecognized socket type */ - *(int*)optval = sock->conn->type; + *(int*)optval = netconn_type(sock->conn); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", s, *(int *)optval)); - } /* switch (sock->conn->type) */ + } /* switch (netconn_type(sock->conn)) */ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", s, *(int *)optval)); break; @@ -2109,12 +1961,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt err = EINVAL; } #if LWIP_UDP - if ( -#if LWIP_IPV6 - ((sock->conn->type != NETCONN_UDP) && (sock->conn->type != NETCONN_UDP_IPV6)) || -#else /* LWIP_IPV6 */ - (sock->conn->type != NETCONN_UDP) || -#endif /* LWIP_IPV6 */ + if (NETCONNTYPE_GROUP((netconn_type(sock->conn) != NETCONN_UDP)) || ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { /* this flag is only available for UDP, not for UDP lite */ err = EAFNOSUPPORT; @@ -2145,7 +1992,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt if (optlen < sizeof(u8_t)) { err = EINVAL; } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; @@ -2153,7 +2000,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt if (optlen < sizeof(struct in_addr)) { err = EINVAL; } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; @@ -2161,7 +2008,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt if (optlen < sizeof(u8_t)) { err = EINVAL; } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; @@ -2170,7 +2017,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt if (optlen < sizeof(struct ip_mreq)) { err = EINVAL; } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { err = EAFNOSUPPORT; } break; @@ -2191,7 +2038,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt } /* If this is no TCP socket, ignore any options. */ - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) return 0; switch (optname) { @@ -2220,11 +2067,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt } /* If this is no UDP lite socket, ignore any options. */ -#if LWIP_IPV6 - if ((sock->conn->type != NETCONN_UDPLITE) && (sock->conn->type != NETCONN_UDPLITE_IPV6)) -#else /* LWIP_IPV6 */ - if (sock->conn->type != NETCONN_UDPLITE) -#endif /* LWIP_IPV6 */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) return 0; switch (optname) { diff --git a/src/core/ipv4/inet_chksum.c b/src/core/inet_chksum.c similarity index 79% rename from src/core/ipv4/inet_chksum.c rename to src/core/inet_chksum.c index b95f7f28..9d295159 100644 --- a/src/core/ipv4/inet_chksum.c +++ b/src/core/inet_chksum.c @@ -257,30 +257,13 @@ lwip_standard_chksum(void *dataptr, int len) } #endif -/* inet_chksum_pseudo: - * - * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo(struct pbuf *p, - ip_addr_t *src, ip_addr_t *dest, - u8_t proto, u16_t proto_len) +/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ +static u16_t +inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc) { - u32_t acc; - u32_t addr; struct pbuf *q; - u8_t swapped; + u8_t swapped = 0; - acc = 0; - swapped = 0; /* iterate through all pbuf in chain */ for(q = p; q != NULL; q = q->next) { LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", @@ -300,12 +283,7 @@ inet_chksum_pseudo(struct pbuf *p, if (swapped) { acc = SWAP_BYTES_IN_WORD(acc); } - addr = ip4_addr_get_u32(src); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = ip4_addr_get_u32(dest); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); acc += (u32_t)htons(proto_len); @@ -330,18 +308,63 @@ inet_chksum_pseudo(struct pbuf *p, * @return checksum (as u16_t) to be saved directly in the protocol header */ u16_t -inet_chksum_pseudo_partial(struct pbuf *p, - ip_addr_t *src, ip_addr_t *dest, - u8_t proto, u16_t proto_len, u16_t chksum_len) +inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip_addr_t *src, ip_addr_t *dest) { u32_t acc; u32_t addr; + + addr = ip4_addr_get_u32(src); + acc = (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + + return inet_cksum_pseudo_base(p, proto, proto_len, acc); +} +#if LWIP_IPV6 +/** + * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. + * IPv6 addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ipv6 address (used for checksum of pseudo header) + * @param dst destination ipv6 address (used for checksum of pseudo header) + * @param proto ipv6 protocol/next header (used for checksum of pseudo header) + * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip6_addr_t *src, ip6_addr_t *dest) +{ + u32_t acc = 0; + u32_t addr; + u8_t addr_part; + + for (addr_part = 0; addr_part < 4; addr_part++) { + addr = src->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = dest->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + } + + return inet_cksum_pseudo_base(p, proto, proto_len, acc); +} +#endif /* LWIP_IPV6 */ + +/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ +static u16_t +inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, u32_t acc) +{ struct pbuf *q; - u8_t swapped; + u8_t swapped = 0; u16_t chklen; - acc = 0; - swapped = 0; /* iterate through all pbuf in chain */ for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", @@ -366,12 +389,7 @@ inet_chksum_pseudo_partial(struct pbuf *p, if (swapped) { acc = SWAP_BYTES_IN_WORD(acc); } - addr = ip4_addr_get_u32(src); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = ip4_addr_get_u32(dest); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); acc += (u32_t)htons(proto_len); @@ -383,6 +401,70 @@ inet_chksum_pseudo_partial(struct pbuf *p, return (u16_t)~(acc & 0xffffUL); } +/* inet_chksum_pseudo_partial: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest) +{ + u32_t acc; + u32_t addr; + + addr = ip4_addr_get_u32(src); + acc = (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + + return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); +} + +#if LWIP_IPV6 +/** + * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. + * IPv6 addresses are expected to be in network byte order. Will only compute for a + * portion of the payload. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ipv6 address (used for checksum of pseudo header) + * @param dst destination ipv6 address (used for checksum of pseudo header) + * @param proto ipv6 protocol/next header (used for checksum of pseudo header) + * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) + * @param chksum_len number of payload bytes used to compute chksum + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest) +{ + u32_t acc = 0; + u32_t addr; + u8_t addr_part; + + for (addr_part = 0; addr_part < 4; addr_part++) { + addr = src->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = dest->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + } + + return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); +} +#endif /* LWIP_IPV6 */ + /* inet_chksum: * * Calculates the Internet checksum over a portion of memory. Used primarily for IP diff --git a/src/core/ipv4/inet.c b/src/core/ipv4/inet.c deleted file mode 100644 index e283a576..00000000 --- a/src/core/ipv4/inet.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file - * Functions common to all TCP/IPv4 modules, such as the byte order functions. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/inet.h" - diff --git a/src/core/ipv4/ip.c b/src/core/ipv4/ip4.c similarity index 93% rename from src/core/ipv4/ip.c rename to src/core/ipv4/ip4.c index 5e9a387d..cd121867 100644 --- a/src/core/ipv4/ip.c +++ b/src/core/ipv4/ip4.c @@ -93,20 +93,8 @@ #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 #endif /* LWIP_DHCP */ -/** - * The interface that provided the packet for the current callback - * invocation. - */ -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; +/** Global data for both IPv4 and IPv6 */ +struct ip_globals ip_data; /** The IP header ID of the next outgoing IP packet */ static u16_t ip_id; @@ -164,19 +152,19 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) PERF_START; /* RFC3927 2.7: do not forward link-local addresses */ - if (ip_addr_islinklocal(¤t_iphdr_dest)) { + if (ip_addr_islinklocal(ip_current_dest_addr())) { LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), - ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), + ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); goto return_noroute; } /* Find network interface where to forward this IP packet to. */ - netif = ip_route(¤t_iphdr_dest); + netif = ip_route(ip_current_dest_addr()); 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(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), - ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), + ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); goto return_noroute; } /* Do not forward packets onto the same network interface on which @@ -208,8 +196,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(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), - ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), + ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); IP_STATS_INC(ip.fw); IP_STATS_INC(ip.xmit); @@ -217,7 +205,7 @@ 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, ¤t_iphdr_dest); + netif->output(netif, p, ip_current_dest_addr()); return; return_noroute: snmp_inc_ipoutnoroutes(); @@ -311,13 +299,13 @@ ip_input(struct pbuf *p, struct netif *inp) 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); + ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_dest), iphdr->dest); + ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_src), iphdr->src); /* match packet against an interface, i.e. is this packet for us? */ #if LWIP_IGMP - if (ip_addr_ismulticast(¤t_iphdr_dest)) { - if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_iphdr_dest))) { + if (ip_addr_ismulticast(ip_current_dest_addr())) { + if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip_current_dest_addr()))) { netif = inp; } else { netif = NULL; @@ -340,9 +328,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(¤t_iphdr_dest, &(netif->ip_addr)) || + if (ip_addr_cmp(ip_current_dest_addr(), &(netif->ip_addr)) || /* or broadcast on this interface network address? */ - ip_addr_isbroadcast(¤t_iphdr_dest, netif)) { + ip_addr_isbroadcast(ip_current_dest_addr(), 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 */ @@ -352,7 +340,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(¤t_iphdr_dest, &(netif->autoip->llipaddr))) { + ip_addr_cmp(ip_current_dest_addr(), &(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 */ @@ -400,10 +388,10 @@ ip_input(struct pbuf *p, struct netif *inp) /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ #if IP_ACCEPT_LINK_LAYER_ADDRESSING /* 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(¤t_iphdr_src)) + if (check_ip_src && !ip_addr_isany(ip_current_src_addr())) #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || - (ip_addr_ismulticast(¤t_iphdr_src))) { + { if ((ip_addr_isbroadcast(ip_current_src_addr(), inp)) || + (ip_addr_ismulticast(ip_current_src_addr()))) { /* 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 */ @@ -421,7 +409,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(¤t_iphdr_dest, inp)) { + if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp)) { /* try to forward IP packet on (other) interfaces */ ip_forward(p, iphdr, inp); } else @@ -480,8 +468,9 @@ ip_input(struct pbuf *p, struct netif *inp) ip_debug_print(p); LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); - current_netif = inp; - current_header = iphdr; + ip_data.current_netif = inp; + ip_data.current_ip4_header = iphdr; + ip_data.current_ip_header_tot_len = IPH_LEN(iphdr); #if LWIP_RAW /* raw input did not eat the packet? */ @@ -517,14 +506,14 @@ ip_input(struct pbuf *p, struct netif *inp) #if LWIP_IGMP case IP_PROTO_IGMP: pbuf_header(p, -iphdr_hlen); /* Move to payload, no check necessary. */ - igmp_input(p, inp, ¤t_iphdr_dest); + igmp_input(p, inp, ip_current_dest_addr()); break; #endif /* LWIP_IGMP */ default: #if LWIP_ICMP /* send ICMP destination protocol unreachable unless is was a broadcast */ - if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && - !ip_addr_ismulticast(¤t_iphdr_dest)) { + if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp) && + !ip_addr_ismulticast(ip_current_dest_addr())) { p->payload = iphdr; icmp_dest_unreach(p, ICMP_DUR_PROTO); } @@ -539,10 +528,12 @@ 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); + /* @todo: this is not really necessary... */ + ip_data.current_netif = NULL; + ip_data.current_ip4_header = NULL; + ip_data.current_ip_header_tot_len = 0; + ip_addr_set_any(ip_current_src_addr()); + ip_addr_set_any(ip_current_dest_addr()); return ERR_OK; } @@ -805,9 +796,9 @@ ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, return ERR_RTE; } - netif->addr_hint = addr_hint; + NETIF_SET_HWADDRHINT(netif, addr_hint); err = ip_output_if(p, src, dest, ttl, tos, proto, netif); - netif->addr_hint = NULL; + NETIF_SET_HWADDRHINT(netif, NULL); return err; } diff --git a/src/core/ipv4/ip_addr.c b/src/core/ipv4/ip4_addr.c similarity index 100% rename from src/core/ipv4/ip_addr.c rename to src/core/ipv4/ip4_addr.c diff --git a/src/core/ipv6/ethip6.c b/src/core/ipv6/ethip6.c index 1a6001e3..99410103 100644 --- a/src/core/ipv6/ethip6.c +++ b/src/core/ipv6/ethip6.c @@ -48,13 +48,13 @@ #include "lwip/pbuf.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #include "lwip/netif.h" #include "lwip/icmp6.h" #include -#define ETHTYPE_IPV6 0x86dd +#define ETHTYPE_IPV6 0x86DD /** The ethernet address */ #ifdef PACK_STRUCT_USE_INCLUDES @@ -89,7 +89,30 @@ PACK_STRUCT_END #define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) -static err_t ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst); +/** + * Send an IPv6 packet on the network using netif->linkoutput + * The ethernet header is filled in before sending. + * + * @params netif the lwIP network interface on which to send the packet + * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header + * @params src the source MAC address to be copied into the ethernet header + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; + + LWIP_ASSERT("netif->hwaddr_len must be 6 for ethip6!", + (netif->hwaddr_len == 6)); + SMEMCPY(ðhdr->dest, dst, 6); + SMEMCPY(ðhdr->src, src, 6); + ethhdr->type = PP_HTONS(ETHTYPE_IPV6); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); +} /** * Resolve and fill-in Ethernet address header for outgoing IPv6 packet. @@ -169,29 +192,4 @@ ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr) return ERR_OK; } -/** - * Send an IPv6 packet on the network using netif->linkoutput - * The ethernet header is filled in before sending. - * - * @params netif the lwIP network interface on which to send the packet - * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header - * @params src the source MAC address to be copied into the ethernet header - * @params dst the destination MAC address to be copied into the ethernet header - * @return ERR_OK if the packet was sent, any other err_t on failure - */ -static err_t -ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) -{ - struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; - - LWIP_ASSERT("netif->hwaddr_len must be 6 for ethip6!", - (netif->hwaddr_len == 6)); - SMEMCPY(ðhdr->dest, dst, 6); - SMEMCPY(ðhdr->src, src, 6); - ethhdr->type = PP_HTONS(ETHTYPE_IPV6); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p)); - /* send the packet */ - return netif->linkoutput(netif, p); -} - #endif /* LWIP_IPV6 && LWIP_ETHERNET */ diff --git a/src/core/ipv6/icmp6.c b/src/core/ipv6/icmp6.c index c92235e1..be725c2d 100644 --- a/src/core/ipv6/icmp6.c +++ b/src/core/ipv6/icmp6.c @@ -46,7 +46,7 @@ #include "lwip/icmp6.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #include "lwip/pbuf.h" #include "lwip/netif.h" #include "lwip/nd6.h" @@ -63,7 +63,7 @@ #endif /* Forward declarations */ -static void icmp6_send_response(struct pbuf *p, u8_t type, u8_t code, u32_t data); +static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); /** @@ -96,8 +96,8 @@ icmp6_input(struct pbuf *p, struct netif *inp) icmp6hdr = (struct icmp6_hdr *)p->payload; #if LWIP_ICMP6_CHECKSUM_CHECK - if (ip6_chksum_pseudo(p, ip6_current_src_addr(), ip6_current_dest_addr(), - IP6_NEXTH_ICMP6, p->tot_len) != 0) { + if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), + ip6_current_dest_addr()) != 0) { /* Checksum failed */ pbuf_free(p); ICMP6_STATS_INC(icmp6.chkerr); @@ -171,8 +171,7 @@ icmp6_input(struct pbuf *p, struct netif *inp) ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r, - reply_src, ip6_current_src_addr(), - IP6_NEXTH_ICMP6, r->tot_len); + IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); /* Send reply. */ ICMP6_STATS_INC(icmp6.xmit); @@ -201,7 +200,7 @@ icmp6_input(struct pbuf *p, struct netif *inp) void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c) { - icmp6_send_response(p, ICMP6_TYPE_DUR, c, 0); + icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR); } /** @@ -214,7 +213,7 @@ icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c) void icmp6_packet_too_big(struct pbuf *p, u32_t mtu) { - icmp6_send_response(p, ICMP6_TYPE_PTB, 0, mtu); + icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB); } /** @@ -227,7 +226,7 @@ icmp6_packet_too_big(struct pbuf *p, u32_t mtu) void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c) { - icmp6_send_response(p, ICMP6_TYPE_TE, c, 0); + icmp6_send_response(p, c, 0, ICMP6_TYPE_TE); } /** @@ -241,7 +240,7 @@ icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c) void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer) { - icmp6_send_response(p, ICMP6_TYPE_PP, c, pointer); + icmp6_send_response(p, c, pointer, ICMP6_TYPE_PP); } /** @@ -249,12 +248,12 @@ icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer) * * @param p the input packet for which the response should be sent, * p->payload pointing to the IPv6 header - * @param type Type of the ICMPv6 header * @param code Code of the ICMPv6 header * @param data Additional 32-bit parameter in the ICMPv6 header + * @param type Type of the ICMPv6 header */ static void -icmp6_send_response(struct pbuf *p, u8_t type, u8_t code, u32_t data) +icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) { struct pbuf *q; struct icmp6_hdr *icmp6hdr; @@ -281,7 +280,7 @@ icmp6_send_response(struct pbuf *p, u8_t type, u8_t code, u32_t data) IP6_HLEN + LWIP_ICMP6_DATASIZE); /* Select an address to use as source. */ - reply_src = ip6_select_source_address(current_netif, ip6_current_src_addr()); + reply_src = ip6_select_source_address(ip_current_netif(), ip6_current_src_addr()); if (reply_src == NULL) { /* drop */ pbuf_free(q); @@ -291,13 +290,12 @@ icmp6_send_response(struct pbuf *p, u8_t type, u8_t code, u32_t data) /* calculate checksum */ icmp6hdr->chksum = 0; - icmp6hdr->chksum = ip6_chksum_pseudo(q, reply_src, ip6_current_src_addr(), - IP6_NEXTH_ICMP6, q->tot_len); + icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, + reply_src, ip6_current_src_addr()); ICMP6_STATS_INC(icmp6.xmit); ip6_output(q, reply_src, ip6_current_src_addr(), LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6); pbuf_free(q); } - #endif /* LWIP_ICMP6 && LWIP_IPV6 */ diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 5c58f05c..79cbc870 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -61,17 +61,6 @@ #include "lwip/stats.h" -/** Header of the input IPv6 packet currently being processed. */ -const struct ip6_hdr *current_ip6_header; -/** Total header length of current_ip6_header (i.e. after this, the UDP/TCP header starts) */ -u16_t current_ip6_header_tot_len; -/** Source IPv6 address of current_header */ -ip6_addr_t current_ip6hdr_src; -/** Destination IPv6 address of current_header */ -ip6_addr_t current_ip6hdr_dest; - - - /** * Finds the appropriate network interface for a given IPv6 address. It tries to select * a netif following a sequence of heuristics: @@ -380,11 +369,11 @@ ip6_input(struct pbuf *p, struct netif *inp) pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr)); /* copy IP addresses to aligned ip6_addr_t */ - ip6_addr_copy(current_ip6hdr_dest, ip6hdr->dest); - ip6_addr_copy(current_ip6hdr_src, ip6hdr->src); + ip6_addr_copy(ip_data.current_iphdr_dest.ip6, ip6hdr->dest); + ip6_addr_copy(ip_data.current_iphdr_src.ip6, ip6hdr->src); /* current header pointer. */ - current_ip6_header = ip6hdr; + ip_data.current_ip6_header = ip6hdr; /* match packet against an interface, i.e. is this packet for us? */ if (ip6_addr_ismulticast(ip6_current_dest_addr())) { @@ -468,13 +457,13 @@ netif_found: } /* current netif pointer. */ - current_netif = inp; + ip_data.current_netif = inp; /* Save next header type. */ nexth = IP6H_NEXTH(ip6hdr); /* Init header length. */ - hlen = current_ip6_header_tot_len = IP6_HLEN; + hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; /* Move to payload. */ pbuf_header(p, -IP6_HLEN); @@ -490,7 +479,7 @@ netif_found: /* Get the header length. */ hlen = 8 * (1 + *((u8_t *)p->payload) + 1); - current_ip6_header_tot_len += hlen; + ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ if (hlen > p->len) { @@ -513,7 +502,7 @@ netif_found: /* Get the header length. */ hlen = 8 * (1 + *((u8_t *)p->payload) + 1); - current_ip6_header_tot_len += hlen; + ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ if (hlen > p->len) { @@ -536,7 +525,7 @@ netif_found: /* Get the header length. */ hlen = 8 * (1 + *((u8_t *)p->payload) + 1); - current_ip6_header_tot_len += hlen; + ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ if (hlen > p->len) { @@ -565,7 +554,7 @@ netif_found: /* Fragment Header length. */ hlen = 8; - current_ip6_header_tot_len += hlen; + ip_data.current_ip_header_tot_len += hlen; /* Make sure this header fits in current pbuf. */ if (hlen > p->len) { @@ -601,7 +590,7 @@ netif_found: * Update all our variables and pointers and continue. */ ip6hdr = (struct ip6_hdr *)p->payload; nexth = IP6H_NEXTH(ip6hdr); - hlen = current_ip6_header_tot_len = IP6_HLEN; + hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; pbuf_header(p, -IP6_HLEN); #else /* LWIP_IPV6_REASS */ @@ -623,7 +612,7 @@ netif_found: options_done: /* p points to IPv6 header again. */ - pbuf_header(p, current_ip6_header_tot_len); + pbuf_header(p, ip_data.current_ip_header_tot_len); /* send to upper layers */ LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n")); @@ -645,21 +634,21 @@ options_done: case IP6_NEXTH_UDPLITE: #endif /* LWIP_UDPLITE */ /* Point to payload. */ - pbuf_header(p, -current_ip6_header_tot_len); + pbuf_header(p, -ip_data.current_ip_header_tot_len); udp_input(p, inp); break; #endif /* LWIP_UDP */ #if LWIP_TCP case IP6_NEXTH_TCP: /* Point to payload. */ - pbuf_header(p, -current_ip6_header_tot_len); + pbuf_header(p, -ip_data.current_ip_header_tot_len); tcp_input(p, inp); break; #endif /* LWIP_TCP */ #if LWIP_ICMP6 case IP6_NEXTH_ICMP6: /* Point to payload. */ - pbuf_header(p, -current_ip6_header_tot_len); + pbuf_header(p, -ip_data.current_ip_header_tot_len); icmp6_input(p, inp); break; #endif /* LWIP_ICMP */ @@ -668,7 +657,7 @@ options_done: /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { - icmp6_param_problem(p, ICMP6_PP_HEADER, current_ip6_header_tot_len - hlen); + icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen); } #endif /* LWIP_ICMP */ LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", IP6H_NEXTH(ip6hdr))); @@ -680,11 +669,11 @@ options_done: } ip6_input_cleanup: - current_netif = NULL; - current_ip6_header = NULL; - current_ip6_header_tot_len = 0; - ip6_addr_set_any(¤t_ip6hdr_src); - ip6_addr_set_any(¤t_ip6hdr_dest); + ip_data.current_netif = NULL; + ip_data.current_ip6_header = NULL; + ip_data.current_ip_header_tot_len = 0; + ip6_addr_set_any(&ip_data.current_iphdr_src.ip6); + ip6_addr_set_any(&ip_data.current_iphdr_dest.ip6); return ERR_OK; } @@ -727,7 +716,7 @@ ip6_output_if(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, LWIP_ASSERT("p->ref == 1", p->ref == 1); /* Should the IPv6 header be generated or is it already included in p? */ - if (dest != IP6_HDRINCL) { + if (dest != IP_HDRINCL) { /* generate IPv6 header */ if (pbuf_header(p, IP6_HLEN)) { LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n")); @@ -883,9 +872,9 @@ ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, return ERR_RTE; } - netif->addr_hint = addr_hint; + NETIF_SET_HWADDRHINT(netif, addr_hint); err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); - netif->addr_hint = NULL; + NETIF_SET_HWADDRHINT(netif, NULL); return err; } diff --git a/src/core/ipv6/ip6_chksum.c b/src/core/ipv6/ip6_chksum.c deleted file mode 100644 index 311a166d..00000000 --- a/src/core/ipv6/ip6_chksum.c +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file - * - * IPv6 Checksum helper functions. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" -#include "lwip/inet_chksum.h" -#include "lwip/def.h" - -#ifndef LWIP_CHKSUM -# define LWIP_CHKSUM lwip_standard_chksum -extern u16_t lwip_standard_chksum(void *dataptr, u16_t len); -#endif - - -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dst destination ipv6 address (used for checksum of pseudo header) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo(struct pbuf *p, - ip6_addr_t *src, ip6_addr_t *dest, - u8_t proto, u16_t proto_len) -{ - u32_t acc; - u32_t addr; - struct pbuf *q; - u8_t swapped; - - acc = 0; - swapped = 0; - /* iterate through all pbuf in chain */ - for(q = p; q != NULL; q = q->next) { - acc += LWIP_CHKSUM(q->payload, q->len); - /* fold the upper bit down */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - } - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - for (swapped = 0; swapped < 4; swapped++) { - addr = src->addr[swapped]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = dest->addr[swapped]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - } - acc += (u32_t)htons((u16_t)proto); - acc += (u32_t)htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is propably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("ip6_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. Will only compute for a - * portion of the payload. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dst destination ipv6 address (used for checksum of pseudo header) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @param chksum_len number of payload bytes used to compute chksum - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo_partial(struct pbuf *p, - ip6_addr_t *src, ip6_addr_t *dest, - u8_t proto, u16_t proto_len, u16_t chksum_len) -{ - u32_t acc; - u32_t addr; - struct pbuf *q; - u8_t swapped; - u16_t chklen; - - acc = 0; - swapped = 0; - /* iterate through all pbuf in chain */ - for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { - chklen = q->len; - if (chklen > chksum_len) { - chklen = chksum_len; - } - acc += LWIP_CHKSUM(q->payload, chklen); - chksum_len -= chklen; - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - } - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - for (swapped = 0; swapped < 4; swapped++) { - addr = src->addr[swapped]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = dest->addr[swapped]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - } - acc += (u32_t)htons((u16_t)proto); - acc += (u32_t)htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is propably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("ip6_chksum_pseudo_partial(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -#endif /* LWIP_IPV6 */ diff --git a/src/core/ipv6/mld6.c b/src/core/ipv6/mld6.c index 2e9213b9..97132273 100644 --- a/src/core/ipv6/mld6.c +++ b/src/core/ipv6/mld6.c @@ -50,7 +50,7 @@ #include "lwip/icmp6.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #include "lwip/pbuf.h" #include "lwip/netif.h" #include "lwip/memp.h" @@ -560,8 +560,8 @@ mld6_send(struct mld_group *group, u8_t type) mld_hdr->reserved = 0; ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address)); - mld_hdr->chksum = ip6_chksum_pseudo(p, src_addr, &(group->group_address), - IP6_NEXTH_ICMP6, p->len); + mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, + src_addr, &(group->group_address)); /* 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); diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 7a80e653..8797a025 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -51,7 +51,7 @@ #include "lwip/memp.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #include "lwip/netif.h" #include "lwip/icmp6.h" #include "lwip/mld6.h" @@ -827,8 +827,8 @@ nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) target_addr = &multicast_address; } - ns_hdr->chksum = ip6_chksum_pseudo(p, src_addr, target_addr, - IP6_NEXTH_ICMP6, p->len); + ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, + target_addr); /* Send the packet out. */ ND6_STATS_INC(nd6.xmit); @@ -897,8 +897,8 @@ nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) dest_addr = ip6_current_src_addr(); } - na_hdr->chksum = ip6_chksum_pseudo(p, src_addr, dest_addr, - IP6_NEXTH_ICMP6, p->len); + na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, + dest_addr); /* Send the packet out. */ ND6_STATS_INC(nd6.xmit); @@ -964,8 +964,8 @@ nd6_send_rs(struct netif * netif) SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); } - rs_hdr->chksum = ip6_chksum_pseudo(p, src_addr, &multicast_address, - IP6_NEXTH_ICMP6, p->len); + rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, + &multicast_address); /* Send the packet out. */ ND6_STATS_INC(nd6.xmit); @@ -1407,12 +1407,11 @@ nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif) s8_t i; #if LWIP_NETIF_HWADDRHINT - /* TODO should addr_hint point to nd6_cached_neighbor_index instead? */ if (netif->addr_hint != NULL) { /* per-pcb cached entry was given */ - i = *(netif->addr_hint); - if ((i >= 0) && (i < LWIP_ND6_NUM_DESTINATIONS)) { - nd6_cached_destination_index = i; + u8_t addr_hint = *(netif->addr_hint); + if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) { + nd6_cached_destination_index = addr_hint; } } #endif /* LWIP_NETIF_HWADDRHINT */ @@ -1425,7 +1424,7 @@ nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif) } else { /* Search destination cache. */ i = nd6_find_destination_cache_entry(ip6addr); - if (i>= 0) { + if (i >= 0) { /* found destination entry. make it our new cached index. */ nd6_cached_destination_index = i; } @@ -1465,7 +1464,6 @@ nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif) } #if LWIP_NETIF_HWADDRHINT - /* TODO should addr_hint point to nd6_cached_neighbor_index instead? */ if (netif->addr_hint != NULL) { /* per-pcb cached entry was given */ *(netif->addr_hint) = nd6_cached_destination_index; diff --git a/src/core/netif.c b/src/core/netif.c index e93762af..f58ba1ab 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -202,9 +202,7 @@ netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, netif->state = state; netif->num = netifnum++; netif->input = input; -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, NULL); #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS netif->loop_cnt_current = 0; #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ @@ -365,10 +363,10 @@ netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) pcb = tcp_active_pcbs; while (pcb != NULL) { /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&(pcb->local_ip.ip4), &(netif->ip_addr)) + if (ip_addr_cmp(ipX_2_ip(&pcb->local_ip), &(netif->ip_addr)) #if LWIP_AUTOIP /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ - && !ip_addr_islinklocal(&(pcb->local_ip.ip4)) + && !ip_addr_islinklocal(ipX_2_ip(&pcb->local_ip)) #endif /* LWIP_AUTOIP */ ) { /* this connection must be aborted */ @@ -382,11 +380,11 @@ netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) } for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { /* PCB bound to current local interface address? */ - if ((!(ip_addr_isany(&(lpcb->local_ip.ip4)))) && - (ip_addr_cmp(&(lpcb->local_ip.ip4), &(netif->ip_addr)))) { + if ((!(ip_addr_isany(ipX_2_ip(&lpcb->local_ip)))) && + (ip_addr_cmp(ipX_2_ip(&lpcb->local_ip), &(netif->ip_addr)))) { /* The PCB is listening to the old ipaddr and * is set to listen to the new one instead */ - ip_addr_set(&(lpcb->local_ip.ip4), ipaddr); + ip_addr_set(ipX_2_ip(&lpcb->local_ip), ipaddr); } } } diff --git a/src/core/pbuf.c b/src/core/pbuf.c index dd9ff64e..4649fb87 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -190,21 +190,21 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); /* determine header offset */ - offset = 0; switch (layer) { case PBUF_TRANSPORT: /* add room for transport (often TCP) layer header */ - offset += PBUF_TRANSPORT_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; case PBUF_IP: /* add room for IP layer header */ - offset += PBUF_IP_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; case PBUF_LINK: /* add room for link layer header */ - offset += PBUF_LINK_HLEN; + offset = PBUF_LINK_HLEN; break; case PBUF_RAW: + offset = 0; break; default: LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); @@ -348,21 +348,21 @@ pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_cust LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); /* determine header offset */ - offset = 0; switch (l) { case PBUF_TRANSPORT: /* add room for transport (often TCP) layer header */ - offset += PBUF_TRANSPORT_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; case PBUF_IP: /* add room for IP layer header */ - offset += PBUF_IP_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; case PBUF_LINK: /* add room for link layer header */ - offset += PBUF_LINK_HLEN; + offset = PBUF_LINK_HLEN; break; case PBUF_RAW: + offset = 0; break; default: LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); diff --git a/src/core/raw.c b/src/core/raw.c index 8a0ce762..3ac3b687 100644 --- a/src/core/raw.c +++ b/src/core/raw.c @@ -105,17 +105,9 @@ raw_input(struct pbuf *p, struct netif *inp) /* loop through all raw pcbs until the packet is eaten by one */ /* this allows multiple pcbs to match against the packet by design */ while ((eaten == 0) && (pcb != NULL)) { - if ((pcb->protocol == proto) && -#if LWIP_IPV6 - ((pcb->isipv6 && - (ip6_addr_isany(&pcb->local_ip.ip6) || - ip6_addr_cmp(&pcb->local_ip.ip6, ip6_current_dest_addr()))) || - (!pcb->isipv6 && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - (ip_addr_isany(&pcb->local_ip.ip4) || - ip_addr_cmp(&(pcb->local_ip.ip4), ip_current_dest_addr()))))) { + if ((pcb->protocol == proto) && IP_PCB_IPVER_INPUT_MATCH(pcb) && + (ipX_addr_isany(pcb->isipv6, &pcb->local_ip) || + ipX_addr_cmp(pcb->isipv6, &(pcb->local_ip), ipX_current_dest_addr()))) { #if IP_SOF_BROADCAST_RECV /* broadcast filter? */ if (((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) @@ -128,15 +120,7 @@ raw_input(struct pbuf *p, struct netif *inp) /* receive callback function available? */ if (pcb->recv.ip4 != NULL) { /* the receive callback function did not eat the packet? */ -#if LWIP_IPV6 - if (pcb->isipv6) { - eaten = pcb->recv.ip6(pcb->recv_arg, pcb, p, ip6_current_src_addr()); - } - else -#endif /* LWIP_IPV6 */ - { - eaten = pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr()); - } + eaten = pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr()); if (eaten != 0) { /* receive function ate the packet */ p = NULL; @@ -177,15 +161,7 @@ raw_input(struct pbuf *p, struct netif *inp) err_t raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr) { -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_set(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set(&pcb->local_ip.ip4, ipaddr); - } + ipX_addr_set_ipaddr(pcb->isipv6, &pcb->local_ip, ipaddr); return ERR_OK; } @@ -205,15 +181,7 @@ raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr) err_t raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr) { -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_set(&pcb->remote_ip.ip6, (ip6_addr_t *)ipaddr); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set(&pcb->remote_ip.ip4, ipaddr); - } + ipX_addr_set_ipaddr(pcb->isipv6, &pcb->remote_ip, ipaddr); return ERR_OK; } @@ -258,38 +226,22 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) struct netif *netif; ip_addr_t *src_ip; struct pbuf *q; /* q will be sent down the stack */ - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); - + s16_t header_size; #if LWIP_IPV6 - /* TODO lots of v4 and v6 code duplication, optimize! Or will compiler optimize? */ - if (pcb->isipv6) { - /* not enough space to add an IPv6 header to first pbuf in given p chain? */ - if (pbuf_header(p, IP6_HLEN)) { - /* allocate header in new pbuf */ - q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); - return ERR_MEM; - } - /* chain header q in front of given pbuf p */ - pbuf_chain(q, p); - /* { first pbuf q points to header pbuf } */ - LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* first pbuf q equals given pbuf */ - q = p; - if(pbuf_header(q, -IP6_HLEN)) { - LWIP_ASSERT("Can't restore header we just removed!", 0); - return ERR_MEM; - } - } - } - else + ip6_addr_t *ip6addr = ip_2_ip6(ipaddr); #endif /* LWIP_IPV6 */ + + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); + + header_size = ( +#if LWIP_IPV6 + pcb->isipv6 ? IP6_HLEN : +#endif /* LWIP_IPV6 */ + IP_HLEN); + /* not enough space to add an IP header to first pbuf in given p chain? */ - if (pbuf_header(p, IP_HLEN)) { + if (pbuf_header(p, header_size)) { /* allocate header in new pbuf */ q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); /* new header pbuf could not be allocated? */ @@ -306,7 +258,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) } else { /* first pbuf q equals given pbuf */ q = p; - if(pbuf_header(q, -IP_HLEN)) { + if(pbuf_header(q, -header_size)) { LWIP_ASSERT("Can't restore header we just removed!", 0); return ERR_MEM; } @@ -314,20 +266,14 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) #if LWIP_IPV6 if (pcb->isipv6) { - if ((netif = ip6_route(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr)) == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to IPv6 destionation\n")); - /* free any temporary header pbuf allocated by pbuf_header() */ - if (q != p) { - pbuf_free(q); - } - return ERR_RTE; - } + netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ip6addr); } else #endif /* LWIP_IPV6 */ - if ((netif = ip_route(ipaddr)) == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); + netif = ip_route(ipaddr); + if (netif == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); + ipX_addr_debug_print(pcb->isipv6, RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ip_2_ipX(ipaddr)); /* free any temporary header pbuf allocated by pbuf_header() */ if (q != p) { pbuf_free(q); @@ -337,8 +283,10 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) #if IP_SOF_BROADCAST #if LWIP_IPV6 - if (!netif->isipv6) { + /* @todo: why does IPv6 not filter broadcast with SOF_BROADCAST enabled? */ + if (!netif->isipv6) #endif /* LWIP_IPV6 */ + { /* broadcast filter? */ if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) { LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); @@ -348,54 +296,48 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) } return ERR_VAL; } -#if LWIP_IPV6 } -#endif /* LWIP_IPV6 */ #endif /* IP_SOF_BROADCAST */ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + #if LWIP_IPV6 if (pcb->isipv6) { - if (ip6_addr_isany(&pcb->local_ip.ip6)) { + ip6_addr_t *src6_ip; + if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { /* select an IPv6 address from the netif as source address */ - src_ip = (ip_addr_t *)ip6_select_source_address(netif, (ip6_addr_t *)ipaddr); - if (src_ip == NULL) { + src6_ip = ip6_select_source_address(netif, ip6addr); + if (src6_ip == NULL) { /* No suitable source address was found. */ + err = ERR_RTE; + NETIF_SET_HWADDRHINT(netif, NULL); + /* did we chain a header earlier? */ if (q != p) { + /* free the header */ pbuf_free(q); } return ERR_RTE; } } else { /* use RAW PCB local IPv6 address as source address */ - src_ip = (ip_addr_t *)&(pcb->local_ip.ip6); + src6_ip = ipX_2_ip6(&pcb->local_ip); } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(&pcb->local_ip.ip4)) { - /* use outgoing network interface IP address as source address */ - src_ip = &(netif->ip_addr); - } else { - /* use RAW PCB local IP address as source address */ - src_ip = &(pcb->local_ip.ip4); - } - -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = &(pcb->addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT*/ -#if LWIP_IPV6 - if (pcb->isipv6) { - err = ip6_output_if(q, (ip6_addr_t *)src_ip, (ip6_addr_t *)ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); + err = ip6_output_if(q, src6_ip, ip6addr, pcb->ttl, pcb->tos, pcb->protocol, netif); } else #endif /* LWIP_IPV6 */ { - err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* use RAW PCB local IP address as source address */ + src_ip = ipX_2_ip(&pcb->local_ip); + } + err = ip_output_if(q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); } -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, NULL); /* did we chain a header earlier? */ if (q != p) { /* free the header */ @@ -414,13 +356,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) err_t raw_send(struct raw_pcb *pcb, struct pbuf *p) { -#if LWIP_IPV6 - if (pcb->isipv6) { - /* TODO is this necessary, or ar ip4 and ip6 pointers the same (think union)? */ - return raw_sendto(pcb, p, (ip_addr_t *)&pcb->remote_ip.ip6); - } -#endif /* LWIP_IPV6 */ - return raw_sendto(pcb, p, &pcb->remote_ip.ip4); + return raw_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip)); } /** @@ -499,9 +435,7 @@ raw_new_ip6(u8_t proto) { struct raw_pcb *pcb; pcb = raw_new(proto); - if (pcb != NULL) { - pcb->isipv6 = 1; - } + ip_set_v6(pcb, 1); return pcb; } #endif /* LWIP_IPV6 */ diff --git a/src/core/snmp/mib2.c b/src/core/snmp/mib2.c index 29decd30..7d587f8c 100644 --- a/src/core/snmp/mib2.c +++ b/src/core/snmp/mib2.c @@ -1797,7 +1797,7 @@ void snmp_insert_udpidx_tree(struct udp_pcb *pcb) u8_t level; LWIP_ASSERT("pcb != NULL", pcb != NULL); - snmp_iptooid(&pcb->local_ip, &udpidx[0]); + snmp_iptooid(ipX_2_ip(&pcb->local_ip), &udpidx[0]); udpidx[4] = pcb->local_port; udp_rn = &udp_root; @@ -1850,7 +1850,7 @@ void snmp_delete_udpidx_tree(struct udp_pcb *pcb) u8_t bindings, fc, level, del_cnt; LWIP_ASSERT("pcb != NULL", pcb != NULL); - snmp_iptooid(&pcb->local_ip, &udpidx[0]); + snmp_iptooid(ipX_2_ip(&pcb->local_ip), &udpidx[0]); udpidx[4] = pcb->local_port; /* count PCBs for a given binding @@ -1859,7 +1859,7 @@ void snmp_delete_udpidx_tree(struct udp_pcb *pcb) npcb = udp_pcbs; while ((npcb != NULL)) { - if (ip_addr_cmp(&npcb->local_ip, &pcb->local_ip) && + if (ipX_addr_cmp(0, &npcb->local_ip, &pcb->local_ip) && (npcb->local_port == udpidx[4])) { bindings++; @@ -3881,17 +3881,17 @@ udpentry_get_value(struct obj_def *od, u16_t len, void *value) { u8_t id; struct udp_pcb *pcb; - ip_addr_t ip; + ipX_addr_t ip; u16_t port; LWIP_UNUSED_ARG(len); - snmp_oidtoip(&od->id_inst_ptr[1], &ip); + snmp_oidtoip(&od->id_inst_ptr[1], (ip_addr_t*)&ip); LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff)); port = (u16_t)od->id_inst_ptr[5]; pcb = udp_pcbs; while ((pcb != NULL) && - !(ip_addr_cmp(&pcb->local_ip, &ip) && + !(ipX_addr_cmp(0, &pcb->local_ip, &ip) && (pcb->local_port == port))) { pcb = pcb->next; @@ -3905,8 +3905,8 @@ udpentry_get_value(struct obj_def *od, u16_t len, void *value) { case 1: /* udpLocalAddress */ { - ip_addr_t *dst = (ip_addr_t*)value; - *dst = pcb->local_ip; + ipX_addr_t *dst = (ipX_addr_t*)value; + ipX_addr_copy(0, *dst, pcb->local_ip); } break; case 2: /* udpLocalPort */ diff --git a/src/core/tcp.c b/src/core/tcp.c index 1d62def6..8aa53a02 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -150,17 +150,8 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) /* don't call tcp_abort here: we must not deallocate the pcb since that might not be expected when calling tcp_close */ -#if LWIP_IPV6 - if (pcb->isipv6) { - tcp_rst_ip6(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, - pcb->local_port, pcb->remote_port); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, - pcb->local_port, pcb->remote_port); - } + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port, pcb->isipv6); tcp_pcb_purge(pcb); @@ -330,8 +321,6 @@ void tcp_abandon(struct tcp_pcb *pcb, int reset) { u32_t seqno, ackno; - /*u16_t remote_port, local_port; - ip_addr_t remote_ip, local_ip; */ #if LWIP_CALLBACK_API tcp_err_fn errf; #endif /* LWIP_CALLBACK_API */ @@ -349,10 +338,6 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) } else { seqno = pcb->snd_nxt; ackno = pcb->rcv_nxt; - /*ip_addr_copy(local_ip, pcb->local_ip.ip4); - ip_addr_copy(remote_ip, pcb->remote_ip.ip4); - local_port = pcb->local_port; - remote_port = pcb->remote_port;*/ #if LWIP_CALLBACK_API errf = pcb->errf; #endif /* LWIP_CALLBACK_API */ @@ -371,15 +356,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) #endif /* TCP_QUEUE_OOSEQ */ if (reset) { LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); -#if LWIP_IPV6 - if (pcb->isipv6) { - tcp_rst_ip6(seqno, ackno, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, pcb->local_port, pcb->remote_port); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(seqno, ackno, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, pcb->local_port, pcb->remote_port); - } + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, pcb->isipv6); } memp_free(MEMP_TCP_PCB, pcb); TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); @@ -452,40 +429,20 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) ((cpcb->so_options & SOF_REUSEADDR) == 0)) #endif /* SO_REUSE */ { - if ( -#if LWIP_IPV6 - !pcb->isipv6 && - !cpcb->isipv6 && -#endif /* LWIP_IPV6 */ - (ip_addr_isany(&(cpcb->local_ip.ip4)) || - ip_addr_isany(ipaddr) || - ip_addr_cmp(&(cpcb->local_ip.ip4), ipaddr))) { + /* @todo: check accept_any_ip_version */ + if (IP_PCB_IPVER_EQ(pcb, cpcb) && + (ipX_addr_isany(PCB_ISIPV6(pcb), &cpcb->local_ip) || + ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr)) || + ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, ip_2_ipX(ipaddr)))) { return ERR_USE; } -#if LWIP_IPV6 - if (pcb->isipv6 && - cpcb->isipv6 && - (ip6_addr_isany(&(cpcb->local_ip.ip6)) || - ip6_addr_isany((ip6_addr_t *)ipaddr) || - ip6_addr_cmp(&(cpcb->local_ip.ip6), (ip6_addr_t *)ipaddr))) { - return ERR_USE; - } -#endif /* LWIP_IPV6 */ } } } } -#if LWIP_IPV6 - if (pcb->isipv6) { - if (!ip6_addr_isany((ip6_addr_t *)ipaddr)) { - ip6_addr_set(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr); - } - } - else -#endif /* LWIP_IPV6 */ - if (!ip_addr_isany(ipaddr)) { - pcb->local_ip.ip4 = *ipaddr; + if (!ipX_addr_isany(pcb->isipv6, ip_2_ipX(ipaddr))) { + ipX_addr_set(pcb->isipv6, &pcb->local_ip, ip_2_ipX(ipaddr)); } pcb->local_port = port; TCP_REG(&tcp_bound_pcbs, pcb); @@ -539,16 +496,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) is declared (listen-/connection-pcb), we have to make sure now that this port is only used once for every local IP. */ for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if (lpcb->local_port == pcb->local_port) { - if (( -#if LWIP_IPV6 - pcb->isipv6 && - lpcb->isipv6 && - ip6_addr_cmp(&lpcb->local_ip.ip6, &pcb->local_ip.ip6)) || - (!pcb->isipv6 && - !lpcb->isipv6 && -#endif /* LWIP_IPV6 */ - ip_addr_cmp(&lpcb->local_ip.ip4, &pcb->local_ip.ip4))) { + if ((lpcb->local_port == pcb->local_port) && + IP_PCB_IPVER_EQ(pcb, lpcb)) { + if (ipX_addr_cmp(pcb->isipv6, &lpcb->local_ip, &pcb->local_ip)) { /* this address/port is already used */ return NULL; } @@ -570,14 +520,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) lpcb->tos = pcb->tos; #if LWIP_IPV6 lpcb->isipv6 = pcb->isipv6; - if (lpcb->isipv6) { - ip6_addr_copy(lpcb->local_ip.ip6, pcb->local_ip.ip6); - } - else + lpcb->accept_any_ip_version = 0; #endif /* LWIP_IPV6 */ - { - ip_addr_copy(lpcb->local_ip.ip4, pcb->local_ip.ip4); - } + ipX_addr_copy(pcb->isipv6, lpcb->local_ip, pcb->local_ip); if (pcb->local_port != 0) { TCP_RMV(&tcp_bound_pcbs, pcb); } @@ -593,7 +538,28 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) return (struct tcp_pcb *)lpcb; } -/** +#if LWIP_IPV6 +/** + * Same as tcp_listen_with_backlog, but allows to accept IPv4 and IPv6 + * connections, if the pcb's local address is set to ANY. + */ +struct tcp_pcb * +tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog) +{ + struct tcp_pcb *lpcb; + + if (!ipX_addr_isany(pcb->isipv6, &pcb->local_ip)) { + return NULL; + } + lpcb = tcp_listen_with_backlog(pcb, backlog); + if (lpcb != NULL) { + ((struct tcp_pcb_listen*)lpcb)->accept_any_ip_version = 1; + } + return lpcb; +} +#endif /* LWIP_IPV6 */ + +/** * Update the state that tracks the available window space to advertise. * * Returns how much extra window would be advertised if we sent an @@ -716,15 +682,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); if (ipaddr != NULL) { -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_set(&pcb->remote_ip.ip6, (ip6_addr_t *)ipaddr); - } - else -#endif /* LWIP_IPV6 */ - { - pcb->remote_ip.ip4 = *ipaddr; - } + ipX_addr_set(PCB_ISIPV6(pcb), &pcb->remote_ip, ip_2_ipX(ipaddr)); } else { return ERR_VAL; } @@ -733,38 +691,38 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, /* check if we have a route to the remote host */ #if LWIP_IPV6 if (pcb->isipv6) { - if (ip6_addr_isany(&(pcb->local_ip.ip6))) { + if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { /* no local IPv6 address set, yet. */ ip6_addr_t * local_addr6; - struct netif *netif = ip6_route(&(pcb->remote_ip.ip6), &(pcb->remote_ip.ip6)); + struct netif *netif = ip6_route(ipX_2_ip6(&pcb->remote_ip), ipX_2_ip6(&pcb->remote_ip)); if (netif == NULL) { /* Don't even try to send a SYN packet if we have no route since that will fail. */ return ERR_RTE; } /* Select and IPv6 address from the netif. */ - local_addr6 = ip6_select_source_address(netif, &(pcb->remote_ip.ip6)); + local_addr6 = ip6_select_source_address(netif, ipX_2_ip6(&pcb->remote_ip)); if (local_addr6 == NULL) { /* Don't even try to send a SYN packet if we have no suitable source address. */ return ERR_RTE; } - ip6_addr_set(&pcb->local_ip.ip6, local_addr6); + ip6_addr_set(ipX_2_ip6(&pcb->local_ip), local_addr6); } } else #endif /* LWIP_IPV6 */ - if (ip_addr_isany(&(pcb->local_ip.ip4))) { + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { /* no local IP address set, yet. */ - struct netif *netif = ip_route(&(pcb->remote_ip.ip4)); + struct netif *netif = ip_route(ipX_2_ip(&pcb->remote_ip)); if (netif == NULL) { /* Don't even try to send a SYN packet if we have no route since that will fail. */ return ERR_RTE; } /* Use the netif's IP address as local address. */ - ip_addr_copy(pcb->local_ip.ip4, netif->ip_addr); + ip_addr_copy(*ipX_2_ip(&pcb->local_ip), netif->ip_addr); } old_local_port = pcb->local_port; @@ -782,18 +740,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { if ((cpcb->local_port == pcb->local_port) && (cpcb->remote_port == port) && -#if LWIP_IPV6 - ((cpcb->isipv6 && - pcb->isipv6 && - ip6_addr_cmp(&cpcb->local_ip.ip6, &pcb->local_ip.ip6) && - ip6_addr_cmp(&cpcb->remote_ip.ip6, (ip6_addr_t *)ipaddr)) || - (!cpcb->isipv6 && - !pcb->isipv6 && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - ip_addr_cmp(&cpcb->local_ip.ip4, &pcb->local_ip.ip4) && - ip_addr_cmp(&cpcb->remote_ip.ip4, ipaddr)))) { + IP_PCB_IPVER_EQ(cpcb, pcb) && + ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, &pcb->local_ip) && + ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->remote_ip, ip_2_ipX(ipaddr))) { /* linux returns EISCONN here, but ERR_USE should be OK for us */ return ERR_USE; } @@ -814,15 +763,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, The send MSS is updated when an MSS option is received. */ pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; #if TCP_CALCULATE_EFF_SEND_MSS -#if LWIP_IPV6 - if (pcb->isipv6) { - pcb->mss = tcp_eff_send_mss_ip6(pcb->mss, &pcb->local_ip.ip6, &pcb->remote_ip.ip6); - } - else -#endif /* LWIP_IPV6 */ - { - pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->remote_ip.ip4); - } + pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, pcb->isipv6); #endif /* TCP_CALCULATE_EFF_SEND_MSS */ pcb->cwnd = 1; pcb->ssthresh = pcb->mss * 10; @@ -962,11 +903,7 @@ tcp_slowtmr(void) #endif /* LWIP_TCP_KEEPALIVE */ { LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to ")); - if (!pcb->isipv6) { - ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip4); - } else { - ip6_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, TCP_DEBUG, &pcb->remote_ip); LWIP_DEBUGF(TCP_DEBUG, ("\n")); ++pcb_remove; @@ -1032,17 +969,8 @@ tcp_slowtmr(void) TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT); if (pcb_reset) { -#if LWIP_IPV6 - if (pcb->isipv6) { - tcp_rst_ip6(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, - pcb->local_port, pcb->remote_port); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, - pcb->local_port, pcb->remote_port); - } + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port, pcb->isipv6); } pcb2 = pcb; @@ -1401,10 +1329,7 @@ tcp_new_ip6(void) { struct tcp_pcb * pcb; pcb = tcp_alloc(TCP_PRIO_NORMAL); - /* could allocate TCP PCB? */ - if (pcb != NULL) { - pcb->isipv6 = 1; - } + ip_set_v6(pcb, 1); return pcb; } #endif /* LWIP_IPV6 */ @@ -1519,18 +1444,9 @@ tcp_pcb_purge(struct tcp_pcb *pcb) tcp_listen_pcbs.listen_pcbs != NULL); for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { if ((lpcb->local_port == pcb->local_port) && -#if LWIP_IPV6 - ((lpcb->isipv6 && - pcb->isipv6 && - (ip6_addr_isany(&lpcb->local_ip.ip6) || - ip6_addr_cmp(&pcb->local_ip.ip6, &lpcb->local_ip.ip6))) || - (!lpcb->isipv6 && - !pcb->isipv6 && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - (ip_addr_isany(&lpcb->local_ip.ip4) || - ip_addr_cmp(&pcb->local_ip.ip4, &lpcb->local_ip.ip4))))) { + IP_PCB_IPVER_EQ(pcb, lpcb) && + (ipX_addr_isany(lpcb->isipv6, &lpcb->local_ip) || + ipX_addr_cmp(lpcb->isipv6, &pcb->local_ip, &lpcb->local_ip))) { /* port and address of the listen pcb match the timed-out pcb */ LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", lpcb->accepts_pending > 0); @@ -1629,14 +1545,35 @@ tcp_next_iss(void) * calculating the minimum of TCP_MSS and that netif's mtu (if set). */ u16_t -tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) +tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest +#if LWIP_IPV6 + , ipX_addr_t *src, u8_t isipv6 +#endif /* LWIP_IPV6 */ + ) { u16_t mss_s; struct netif *outif; + s16_t mtu; + s16_t iphlen = IP_HLEN; - outif = ip_route(addr); - if ((outif != NULL) && (outif->mtu != 0)) { - mss_s = outif->mtu - IP_HLEN - TCP_HLEN; +#if LWIP_IPV6 + if (isipv6) { + /* First look in destination cache, to see if there is a Path MTU. */ + outif = ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)); + mtu = nd6_get_destination_mtu(ipX_2_ip6(dest), outif); + iphlen = IP6_HLEN; + } else +#endif /* LWIP_IPV6 */ + { + outif = ip_route(ipX_2_ip(dest)); + if (outif == NULL) { + return sendmss; + } + mtu = outif->mtu; + } + + if (mtu != 0) { + mss_s = mtu - iphlen - TCP_HLEN; /* RFC 1122, chap 4.2.2.6: * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize * We correct for TCP options in tcp_write(), and don't support IP options. @@ -1645,35 +1582,6 @@ tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) } return sendmss; } - -#if LWIP_IPV6 -/** - * Calculates the effective send mss that can be used for a specific IPv6 - * address by using ip6_route to determine the netif used to send to the - * address and calculating the minimum of TCP_MSS and that netif's mtu (if set). - */ -u16_t -tcp_eff_send_mss_ip6(u16_t sendmss, ip6_addr_t *src, ip6_addr_t *dest) -{ - u16_t mss_s; - struct netif *outif; - s16_t mtu; - - /* First look in destination cache, to see if there is a PAth MTU. */ - outif = ip6_route(src, dest); - mtu = nd6_get_destination_mtu(dest, outif); - - if (mtu != 0) { - mss_s = mtu - IP6_HLEN - TCP_HLEN; - /* RFC 1122, chap 4.2.2.6: - * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize - * We correct for TCP options in tcp_write(). - */ - sendmss = LWIP_MIN(sendmss, mss_s); - } - return sendmss; -} -#endif /* LWIP_IPV6 */ #endif /* TCP_CALCULATE_EFF_SEND_MSS */ const char* diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 86bb93e7..ea4c3c33 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -57,7 +57,7 @@ #include "arch/perf.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #if LWIP_ND6_TCP_REACHABILITY_HINTS #include "lwip/nd6.h" #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ @@ -104,6 +104,7 @@ tcp_input(struct pbuf *p, struct netif *inp) #endif /* SO_REUSE */ u8_t hdrlen; err_t err; + u16_t chksum; PERF_START; @@ -121,62 +122,26 @@ tcp_input(struct pbuf *p, struct netif *inp) /* drop short packets */ LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); TCP_STATS_INC(tcp.lenerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } /* Don't even process incoming broadcasts/multicasts. */ - if (( -#if LWIP_IPV6 - (ip6_current_header() != NULL) && - ip6_addr_ismulticast(ip6_current_dest_addr())) || - ((ip_current_header() != NULL) && -#endif /* LWIP_IPV6 */ - (ip_addr_isbroadcast(ip_current_dest_addr(), inp) || - ip_addr_ismulticast(ip_current_dest_addr())))) { + if ((!ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp)) || + ipX_addr_ismulticast(ip_current_is_v6(), ipX_current_dest_addr())) { TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } #if CHECKSUM_CHECK_TCP -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - if (ip6_chksum_pseudo(p, ip6_current_src_addr(), ip6_current_dest_addr(), - IP6_NEXTH_TCP, p->tot_len) != 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - ip6_chksum_pseudo(p, ip6_current_src_addr(), ip6_current_dest_addr(), - IP6_NEXTH_TCP, p->tot_len))); - #if TCP_DEBUG - tcp_debug_print(tcphdr); - #endif /* TCP_DEBUG */ - TCP_STATS_INC(tcp.chkerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; - } - } - else -#endif /* LWIP_IPV6 */ /* Verify TCP checksum. */ - if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), - IP_PROTO_TCP, p->tot_len) != 0) { + chksum = ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_TCP, p->tot_len, + ipX_current_src_addr(), ipX_current_dest_addr()); + if (chksum != 0) { LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), - IP_PROTO_TCP, p->tot_len))); -#if TCP_DEBUG + chksum)); tcp_debug_print(tcphdr); -#endif /* TCP_DEBUG */ TCP_STATS_INC(tcp.chkerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } #endif /* CHECKSUM_CHECK_TCP */ @@ -187,10 +152,7 @@ tcp_input(struct pbuf *p, struct netif *inp) /* drop short packets */ LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); TCP_STATS_INC(tcp.lenerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } /* Convert fields in TCP header to host byte order. */ @@ -214,18 +176,9 @@ 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 && - (( -#if LWIP_IPV6 - pcb->isipv6 && - (ip6_current_header() != NULL) && - ip6_addr_cmp(&(pcb->remote_ip.ip6), ip6_current_src_addr()) && - ip6_addr_cmp(&(pcb->local_ip.ip6), ip6_current_dest_addr())) || - (!pcb->isipv6 && - (ip_current_header() != NULL) && -#endif /* LWIP_IPV6 */ - ip_addr_cmp(&(pcb->remote_ip.ip4), ip_current_src_addr()) && - ip_addr_cmp(&(pcb->local_ip.ip4), ip_current_dest_addr())))) { - + IP_PCB_IPVER_INPUT_MATCH(pcb) && + ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) && + ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) { /* Move this PCB to the front of the list so that subsequent lookups will be faster (we exploit locality in TCP segment arrivals). */ @@ -248,17 +201,9 @@ 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 && - (( -#if LWIP_IPV6 - pcb->isipv6 && - (ip6_current_header() != NULL) && - ip6_addr_cmp(&(pcb->remote_ip.ip6), ip6_current_src_addr()) && - ip6_addr_cmp(&(pcb->local_ip.ip6), ip6_current_dest_addr())) || - (!pcb->isipv6 && - (ip_current_header() != NULL) && -#endif /* LWIP_IPV6 */ - ip_addr_cmp(&(pcb->remote_ip.ip4), ip_current_src_addr()) && - ip_addr_cmp(&(pcb->local_ip.ip4), ip_current_dest_addr())))) { + IP_PCB_IPVER_INPUT_MATCH(pcb) && + ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) && + ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) { /* 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. */ @@ -274,53 +219,31 @@ tcp_input(struct pbuf *p, struct netif *inp) prev = NULL; for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { if (lpcb->local_port == tcphdr->dest) { +#if LWIP_IPV6 + if (lpcb->accept_any_ip_version) { + /* found an ANY-match */ #if SO_REUSE -#if LWIP_IPV6 - if (lpcb->isipv6 && - (ip6_current_header() != NULL)) { - if (ip6_addr_cmp(&(lpcb->local_ip.ip6), ip6_current_dest_addr())) { - /* found an exact match */ - break; - } else if(ip6_addr_isany(&(lpcb->local_ip.ip6))) { - /* found an ANY-match */ - lpcb_any = lpcb; - lpcb_prev = prev; - } - } - else if (!lpcb->isipv6 && - (ip_current_header() != NULL)) -#endif /* LWIP_IPV6 */ - { - if (ip_addr_cmp(&(lpcb->local_ip.ip4), ip_current_dest_addr())) { - /* found an exact match */ - break; - } else if(ip_addr_isany(&(lpcb->local_ip.ip4))) { - /* found an ANY-match */ - lpcb_any = lpcb; - lpcb_prev = prev; - } - } + lpcb_any = lpcb; + lpcb_prev = prev; #else /* SO_REUSE */ -#if LWIP_IPV6 - if (lpcb->isipv6 && - (ip6_current_header() != NULL)) { - if (ip6_addr_cmp(&(lpcb->local_ip.ip6), ip6_current_dest_addr()) || - ip6_addr_isany(&(lpcb->local_ip.ip6))) { + break; +#endif /* SO_REUSE */ + } else +#endif /* LWIP_IPV6 */ + if (IP_PCB_IPVER_INPUT_MATCH(lpcb)) { + if (ipX_addr_cmp(ip_current_is_v6(), &lpcb->local_ip, ipX_current_dest_addr())) { /* found an exact match */ break; - } - } - else if (!lpcb->isipv6 && - (ip_current_header() != NULL)) -#endif /* LWIP_IPV6 */ - { - if (ip_addr_cmp(&(lpcb->local_ip.ip4), ip_current_dest_addr()) || - ip_addr_isany(&(lpcb->local_ip.ip4))) { - /* found a match */ + } else if (ipX_addr_isany(ip_current_is_v6(), &lpcb->local_ip)) { + /* found an ANY-match */ +#if SO_REUSE + lpcb_any = lpcb; + lpcb_prev = prev; +#else /* SO_REUSE */ break; + #endif /* SO_REUSE */ } } -#endif /* SO_REUSE */ } prev = (struct tcp_pcb *)lpcb; } @@ -387,10 +310,7 @@ tcp_input(struct pbuf *p, struct netif *inp) /* Drop incoming packets because pcb is "full" (only if the incoming segment contains data). */ LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } } tcp_input_pcb = pcb; @@ -493,25 +413,19 @@ aborted: if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { TCP_STATS_INC(tcp.proterr); TCP_STATS_INC(tcp.drop); -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - tcp_rst_ip6(ackno, seqno + tcplen, - ip6_current_dest_addr(), ip6_current_src_addr(), - tcphdr->dest, tcphdr->src); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(ackno, seqno + tcplen, - ip_current_dest_addr(), ip_current_src_addr(), - tcphdr->dest, tcphdr->src); - } + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); } pbuf_free(p); } LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); PERF_STOP("tcp_input"); + return; +dropped: + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); } /** @@ -538,19 +452,8 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) /* For incoming segments with the ACK flag set, respond with a RST. */ LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - tcp_rst_ip6(ackno + 1, seqno + tcplen, - ip6_current_dest_addr(), ip6_current_src_addr(), - tcphdr->dest, tcphdr->src); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(ackno + 1, seqno + tcplen, - ip_current_dest_addr(), ip_current_src_addr(), - tcphdr->dest, tcphdr->src); - } + tcp_rst(ackno + 1, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); } else if (flags & TCP_SYN) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); #if TCP_LISTEN_BACKLOG @@ -573,17 +476,10 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) #endif /* TCP_LISTEN_BACKLOG */ /* Set up the new PCB. */ #if LWIP_IPV6 - npcb->isipv6 = pcb->isipv6; - if (npcb->isipv6) { - ip6_addr_copy(npcb->local_ip.ip6, *ip6_current_dest_addr()); - ip6_addr_copy(npcb->remote_ip.ip6, *ip6_current_src_addr()); - } - else + npcb->isipv6 = ip_current_is_v6(); #endif /* LWIP_IPV6 */ - { - ip_addr_copy(npcb->local_ip.ip4, *ip_current_dest_addr()); - ip_addr_copy(npcb->remote_ip.ip4, *ip_current_src_addr()); - } + ipX_addr_copy(ip_current_is_v6(), npcb->local_ip, *ipX_current_dest_addr()); + ipX_addr_copy(ip_current_is_v6(), npcb->remote_ip, *ipX_current_src_addr()); npcb->local_port = pcb->local_port; npcb->remote_port = tcphdr->src; npcb->state = SYN_RCVD; @@ -605,15 +501,8 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) /* Parse any options in the SYN. */ tcp_parseopt(npcb); #if TCP_CALCULATE_EFF_SEND_MSS -#if LWIP_IPV6 - if (npcb->isipv6) { - npcb->mss = tcp_eff_send_mss_ip6(npcb->mss, &(npcb->local_ip.ip6), &(npcb->remote_ip.ip6)); - } - else -#endif /* LWIP_IPV6 */ - { - npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip.ip4)); - } + npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, + &npcb->remote_ip, npcb->isipv6); #endif /* TCP_CALCULATE_EFF_SEND_MSS */ snmp_inc_tcppassiveopens(); @@ -655,17 +544,8 @@ 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 */ -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - tcp_rst_ip6(ackno, seqno + tcplen, ip6_current_dest_addr(), ip6_current_src_addr(), - tcphdr->dest, tcphdr->src); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), - tcphdr->dest, tcphdr->src); - } + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); return ERR_OK; } } else if (flags & TCP_FIN) { @@ -762,15 +642,8 @@ tcp_process(struct tcp_pcb *pcb) pcb->state = ESTABLISHED; #if TCP_CALCULATE_EFF_SEND_MSS -#if LWIP_IPV6 - if (pcb->isipv6) { - pcb->mss = tcp_eff_send_mss_ip6(pcb->mss, &(pcb->local_ip.ip6), &(pcb->remote_ip.ip6)); - } - else -#endif /* LWIP_IPV6 */ - { - pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip.ip4)); - } + pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, + pcb->isipv6); #endif /* TCP_CALCULATE_EFF_SEND_MSS */ /* Set ssthresh again after changing pcb->mss (already set in tcp_connect @@ -806,17 +679,8 @@ 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. */ -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - tcp_rst_ip6(ackno, seqno + tcplen, ip6_current_dest_addr(), ip6_current_src_addr(), - tcphdr->dest, tcphdr->src); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), - tcphdr->dest, tcphdr->src); - } + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); } break; case SYN_RCVD: @@ -858,17 +722,8 @@ tcp_process(struct tcp_pcb *pcb) } } else { /* incorrect ACK number, send RST */ -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - tcp_rst_ip6(ackno, seqno + tcplen, ip6_current_dest_addr(), ip6_current_src_addr(), - tcphdr->dest, tcphdr->src); - } - else -#endif /* LWIP_IPV6 */ - { - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), - tcphdr->dest, tcphdr->src); - } + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); } } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { /* Looks like another copy of the SYN - retransmit our SYN-ACK */ diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 308b8273..d9ab0a92 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -54,7 +54,7 @@ #include "lwip/snmp.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #include @@ -868,34 +868,17 @@ tcp_send_empty_ack(struct tcp_pcb *pcb) } #endif -#if LWIP_IPV6 - if (pcb->isipv6) { - /* Chksum is mandatory over IPv6 */ - tcphdr->chksum = ip6_chksum_pseudo(p, &(pcb->local_ip.ip6), &(pcb->remote_ip.ip6), - IP6_NEXTH_TCP, p->tot_len); -#if LWIP_NETIF_HWADDRHINT - ip6_output_hinted(p, &(pcb->local_ip.ip6), &(pcb->remote_ip.ip6), pcb->ttl, pcb->tos, - IP6_NEXTH_TCP, &(pcb->addr_hint)); -#else /* LWIP_NETIF_HWADDRHINT*/ - ip6_output(p, &(pcb->local_ip.ip6), &(pcb->remote_ip.ip6), pcb->ttl, pcb->tos, - IP6_NEXTH_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - } - else -#endif /* LWIP_IPV6 */ - { #if CHECKSUM_GEN_TCP - tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip.ip4), &(pcb->remote_ip.ip4), - IP_PROTO_TCP, p->tot_len); + tcphdr->chksum = ipX_chksum_pseudo(pcb->isipv6, p, IP_PROTO_TCP, p->tot_len, + &pcb->local_ip, &pcb->remote_ip); #endif #if LWIP_NETIF_HWADDRHINT - ip_output_hinted(p, &(pcb->local_ip.ip4), &(pcb->remote_ip.ip4), pcb->ttl, pcb->tos, - IP_PROTO_TCP, &(pcb->addr_hint)); + ipX_output_hinted(pcb->isipv6, p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, + IP_PROTO_TCP, &pcb->addr_hint); #else /* LWIP_NETIF_HWADDRHINT*/ - ip_output(p, &(pcb->local_ip.ip4), &(pcb->remote_ip.ip4), pcb->ttl, pcb->tos, - IP_PROTO_TCP); + ipX_output(pcb->isipv6, p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, + IP_PROTO_TCP); #endif /* LWIP_NETIF_HWADDRHINT*/ - } pbuf_free(p); return ERR_OK; @@ -1108,28 +1091,28 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) calling ip_route(). */ #if LWIP_IPV6 if (pcb->isipv6) { - if (ip6_addr_isany(&(pcb->local_ip.ip6))) { + if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { ip6_addr_t * local_addr6; - netif = ip6_route(&(pcb->local_ip.ip6), &(pcb->remote_ip.ip6)); + netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ipX_2_ip6(&pcb->remote_ip)); if (netif == NULL) { return; } /* Select and IPv6 address from the netif. */ - local_addr6 = ip6_select_source_address(netif, &(pcb->remote_ip.ip6)); + local_addr6 = ip6_select_source_address(netif, ipX_2_ip6(&pcb->remote_ip)); if (local_addr6 == NULL) { return; } - ip6_addr_set(&pcb->local_ip.ip6, local_addr6); + ip6_addr_set(ipX_2_ip6(&pcb->local_ip), local_addr6); } } else #endif /* LWIP_IPV6 */ - if (ip_addr_isany(&(pcb->local_ip.ip4))) { - netif = ip_route(&(pcb->remote_ip.ip4)); + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { + netif = ip_route(ipX_2_ip(&pcb->remote_ip)); if (netif == NULL) { return; } - ip_addr_copy(pcb->local_ip.ip4, netif->ip_addr); + ip_addr_copy(*ipX_2_ip(&pcb->local_ip), netif->ip_addr); } if (pcb->rttest == 0) { @@ -1154,20 +1137,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) { u32_t acc; #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - u16_t chksum_slow; -#if LWIP_IPV6 - if (pcb->isipv6) { - chksum_slow = ip6_chksum_pseudo(seg->p, &(pcb->local_ip.ip6), - &(pcb->remote_ip.ip6), - IP6_NEXTH_TCP, seg->p->tot_len); - } - else -#endif /* LWIP_IPV6 */ - { - chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip.ip4), - &(pcb->remote_ip.ip4), - IP_PROTO_TCP, seg->p->tot_len); - } + u16_t chksum_slow = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, + seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { LWIP_ASSERT("data included but not checksummed", @@ -1175,19 +1146,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) } /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ -#if LWIP_IPV6 - if (pcb->isipv6) { - acc = ip6_chksum_pseudo_partial(seg->p, &(pcb->local_ip.ip6), - &(pcb->remote_ip.ip6), - IP6_NEXTH_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4); - } - else -#endif /* LWIP_IPV6 */ - { - acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip.ip4), - &(pcb->remote_ip.ip4), - IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4); - } + acc = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, + seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip); /* add payload checksum */ if (seg->chksum_swapped) { seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); @@ -1205,46 +1165,21 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ } #else /* TCP_CHECKSUM_ON_COPY */ -#if LWIP_IPV6 - if (pcb->isipv6) { - /* Chksum is mandatory in IPv6 */ - seg->tcphdr->chksum = ip6_chksum_pseudo(seg->p, &(pcb->local_ip.ip6), - &(pcb->remote_ip.ip6), - IP6_NEXTH_TCP, seg->p->tot_len); - } - else -#endif /* LWIP_IPV6 */ - { #if CHECKSUM_GEN_TCP - seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip.ip4), - &(pcb->remote_ip.ip4), - IP_PROTO_TCP, seg->p->tot_len); + seg->tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, + seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); #endif /* CHECKSUM_GEN_TCP */ } #endif /* TCP_CHECKSUM_ON_COPY */ TCP_STATS_INC(tcp.xmit); -#if LWIP_IPV6 - if (pcb->isipv6) { #if LWIP_NETIF_HWADDRHINT - ip6_output_hinted(seg->p, &(pcb->local_ip.ip6), &(pcb->remote_ip.ip6), pcb->ttl, pcb->tos, - IP6_NEXTH_TCP, &(pcb->addr_hint)); + ipX_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, + pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint); #else /* LWIP_NETIF_HWADDRHINT*/ - ip6_output(seg->p, &(pcb->local_ip.ip6), &(pcb->remote_ip.ip6), pcb->ttl, pcb->tos, - IP6_NEXTH_TCP); + ipX_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, + pcb->tos, IP_PROTO_TCP); #endif /* LWIP_NETIF_HWADDRHINT*/ - } - else -#endif /* LWIP_IPV6 */ - { -#if LWIP_NETIF_HWADDRHINT - ip_output_hinted(seg->p, &(pcb->local_ip.ip4), &(pcb->remote_ip.ip4), pcb->ttl, pcb->tos, - IP_PROTO_TCP, &(pcb->addr_hint)); -#else /* LWIP_NETIF_HWADDRHINT*/ - ip_output(seg->p, &(pcb->local_ip.ip4), &(pcb->remote_ip.ip4), pcb->ttl, pcb->tos, - IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - } } /** @@ -1268,9 +1203,13 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) * @param remote_port the remote TCP port to send the segment to */ void -tcp_rst(u32_t seqno, u32_t ackno, - ip_addr_t *local_ip, ip_addr_t *remote_ip, - u16_t local_port, u16_t remote_port) +tcp_rst_impl(u32_t seqno, u32_t ackno, + ipX_addr_t *local_ip, ipX_addr_t *remote_ip, + u16_t local_port, u16_t remote_port +#if LWIP_IPV6 + , u8_t isipv6 +#endif /* LWIP_IPV6 */ + ) { struct pbuf *p; struct tcp_hdr *tcphdr; @@ -1292,77 +1231,19 @@ tcp_rst(u32_t seqno, u32_t ackno, tcphdr->chksum = 0; tcphdr->urgp = 0; + TCP_STATS_INC(tcp.xmit); + snmp_inc_tcpoutrsts(); + #if CHECKSUM_GEN_TCP - tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, - IP_PROTO_TCP, p->tot_len); + tcphdr->chksum = ipX_chksum_pseudo(isipv6, p, IP_PROTO_TCP, p->tot_len, + local_ip, remote_ip); #endif - TCP_STATS_INC(tcp.xmit); - snmp_inc_tcpoutrsts(); - /* Send output with hardcoded TTL since we have no access to the pcb */ - ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + /* Send output with hardcoded TTL/HL since we have no access to the pcb */ + ipX_output(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); pbuf_free(p); LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); } -#if LWIP_IPV6 -/** - * Send a TCP RESET packet (empty segment with RST flag set) over IPv6, - * either to abort a connection or to show that there is no matching local - * connection for a received segment. - * - * Called by tcp_abort() (to abort a local connection), tcp_input() (if no - * matching local pcb was found), tcp_listen_input() (if incoming segment - * has ACK flag set) and tcp_process() (received segment in the wrong state) - * - * Since a RST segment is in most cases not sent for an active connection, - * tcp_rst() has a number of arguments that are taken from a tcp_pcb for - * most other segment output functions. - * - * @param seqno the sequence number to use for the outgoing segment - * @param ackno the acknowledge number to use for the outgoing segment - * @param local_ip6 the local IPv6 address to send the segment from - * @param remote_ip6 the remote IPv6 address to send the segment to - * @param local_port the local TCP port to send the segment from - * @param remote_port the remote TCP port to send the segment to - */ -void -tcp_rst_ip6(u32_t seqno, u32_t ackno, - ip6_addr_t *local_ip6, ip6_addr_t *remote_ip6, - u16_t local_port, u16_t remote_port) -{ - struct pbuf *p; - struct tcp_hdr *tcphdr; - p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); - return; - } - LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", - (p->len >= sizeof(struct tcp_hdr))); - - tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->src = htons(local_port); - tcphdr->dest = htons(remote_port); - tcphdr->seqno = htonl(seqno); - tcphdr->ackno = htonl(ackno); - TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); - tcphdr->wnd = PP_HTONS(TCP_WND); - tcphdr->chksum = 0; - tcphdr->urgp = 0; - - /* chksum us mandatory over IPv6. */ - tcphdr->chksum = ip6_chksum_pseudo(p, local_ip6, remote_ip6, - IP6_NEXTH_TCP, p->tot_len); - - TCP_STATS_INC(tcp.xmit); - snmp_inc_tcpoutrsts(); - /* Send output with hardcoded HL since we have no access to the pcb */ - ip6_output(p, local_ip6, remote_ip6, TCP_TTL, 0, IP6_NEXTH_TCP); - pbuf_free(p); - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); -} -#endif /* LWIP_IPV6 */ - /** * Requeue all unacked segments for retransmission * @@ -1495,11 +1376,7 @@ tcp_keepalive(struct tcp_pcb *pcb) struct tcp_hdr *tcphdr; LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); - if (!pcb->isipv6) { - ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip4); - } else { - ip6_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, TCP_DEBUG, &pcb->remote_ip); LWIP_DEBUGF(TCP_DEBUG, ("\n")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", @@ -1513,41 +1390,18 @@ tcp_keepalive(struct tcp_pcb *pcb) } tcphdr = (struct tcp_hdr *)p->payload; -#if LWIP_IPV6 - if (pcb->isipv6) { - tcphdr->chksum = ip6_chksum_pseudo(p, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, - IP6_NEXTH_TCP, p->tot_len); - } - else -#endif /* LWIP_IPV6 */ - { -#if CHECKSUM_GEN_TCP - tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, - IP_PROTO_TCP, p->tot_len); -#endif - } + tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, + &pcb->local_ip, &pcb->remote_ip); TCP_STATS_INC(tcp.xmit); /* Send output to IP */ -#if LWIP_IPV6 - if (pcb->isipv6) { #if LWIP_NETIF_HWADDRHINT - ip6_output_hinted(p, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, pcb->ttl, 0, IP6_NEXTH_TCP, - &(pcb->addr_hint)); + ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, + pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint); #else /* LWIP_NETIF_HWADDRHINT*/ - ip6_output(p, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, pcb->ttl, 0, IP6_NEXTH_TCP); + ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, + 0, IP_PROTO_TCP); #endif /* LWIP_NETIF_HWADDRHINT*/ - } - else -#endif /* LWIP_IPV6 */ - { -#if LWIP_NETIF_HWADDRHINT - ip_output_hinted(p, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, pcb->ttl, 0, IP_PROTO_TCP, - &(pcb->addr_hint)); -#else /* LWIP_NETIF_HWADDRHINT*/ - ip_output(p, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, pcb->ttl, 0, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - } pbuf_free(p); @@ -1574,11 +1428,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) u8_t is_fin; LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); - if (!pcb->isipv6) { - ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip4); - } else { - ip6_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, TCP_DEBUG, &pcb->remote_ip); LWIP_DEBUGF(TCP_DEBUG, ("\n")); LWIP_DEBUGF(TCP_DEBUG, @@ -1616,41 +1466,19 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4); } -#if LWIP_IPV6 - if (pcb->isipv6) { - tcphdr->chksum = ip6_chksum_pseudo(p, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, - IP6_NEXTH_TCP, p->tot_len); - } - else -#endif /* LWIP_IPV6 */ - { #if CHECKSUM_GEN_TCP - tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, - IP_PROTO_TCP, p->tot_len); + tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, + &pcb->local_ip, &pcb->remote_ip); #endif - } TCP_STATS_INC(tcp.xmit); /* Send output to IP */ -#if LWIP_IPV6 - if (pcb->isipv6) { #if LWIP_NETIF_HWADDRHINT - ip6_output_hinted(p, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, pcb->ttl, 0, IP6_NEXTH_TCP, - &(pcb->addr_hint)); + ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, + 0, IP_PROTO_TCP, &pcb->addr_hint); #else /* LWIP_NETIF_HWADDRHINT*/ - ip6_output(p, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, pcb->ttl, 0, IP6_NEXTH_TCP); + ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); #endif /* LWIP_NETIF_HWADDRHINT*/ - } - else -#endif /* LWIP_IPV6 */ - { -#if LWIP_NETIF_HWADDRHINT - ip_output_hinted(p, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, pcb->ttl, 0, IP_PROTO_TCP, - &(pcb->addr_hint)); -#else /* LWIP_NETIF_HWADDRHINT*/ - ip_output(p, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, pcb->ttl, 0, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - } pbuf_free(p); diff --git a/src/core/udp.c b/src/core/udp.c index 2594657c..b983609b 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -57,7 +57,7 @@ #include "lwip/ip_addr.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" -#include "lwip/ip6_chksum.h" +#include "lwip/inet_chksum.h" #include "lwip/netif.h" #include "lwip/icmp.h" #include "lwip/icmp6.h" @@ -93,6 +93,7 @@ udp_input(struct pbuf *p, struct netif *inp) u16_t src, dest; u8_t local_match; u8_t broadcast; + u8_t for_us; PERF_START; @@ -114,7 +115,7 @@ udp_input(struct pbuf *p, struct netif *inp) /* is broadcast packet ? */ #if LWIP_IPV6 - broadcast = (ip_current_header() != NULL) && ip_addr_isbroadcast(ip_current_dest_addr(), inp); + broadcast = !ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp); #else /* LWIP_IPV6 */ broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), inp); #endif /* LWIP_IPV6 */ @@ -129,17 +130,9 @@ udp_input(struct pbuf *p, struct netif *inp) /* print the UDP source and destination */ LWIP_DEBUGF(UDP_DEBUG, ("udp (")); - if (ip_current_header() != NULL) { - ip_addr_debug_print(UDP_DEBUG, ip_current_dest_addr()); - } else { - ip6_addr_debug_print(UDP_DEBUG, ip6_current_dest_addr()); - } + ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_dest_addr()); LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", ntohs(udphdr->dest))); - if (ip_current_header() != NULL) { - ip_addr_debug_print(UDP_DEBUG, ip_current_src_addr()); - } else { - ip6_addr_debug_print(UDP_DEBUG, ip6_current_src_addr()); - } + ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_src_addr()); LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", ntohs(udphdr->src))); #if LWIP_DHCP @@ -152,13 +145,10 @@ udp_input(struct pbuf *p, struct netif *inp) if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) { /* accept the packe if (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! - - inp->dhcp->pcb->remote == ANY or iphdr->src */ - if ( -#if LWIP_IPV6 - !pcb->isipv6 && -#endif /* LWIP_IPV6 */ - ((ip_addr_isany(&inp->dhcp->pcb->remote_ip.ip4) || - ip_addr_cmp(&(inp->dhcp->pcb->remote_ip.ip4), ip_current_src_addr())))) { + - inp->dhcp->pcb->remote == ANY or iphdr->src + (no need to check for IPv6 since the dhcp struct always uses IPv4) */ + if (ipX_addr_isany(0, &inp->dhcp->pcb->remote_ip) || + ip_addr_cmp(ipX_2_ip(&(inp->dhcp->pcb->remote_ip)), ip_current_src_addr())) { pcb = inp->dhcp->pcb; } } @@ -177,36 +167,27 @@ udp_input(struct pbuf *p, struct netif *inp) local_match = 0; /* print the PCB local and remote address */ LWIP_DEBUGF(UDP_DEBUG, ("pcb (")); - if (!pcb->isipv6) { - ip_addr_debug_print(UDP_DEBUG, &pcb->local_ip.ip4); - } else { - ip6_addr_debug_print(UDP_DEBUG, &pcb->local_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG, &pcb->local_ip); LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port)); - if (!pcb->isipv6) { - ip_addr_debug_print(UDP_DEBUG, &pcb->remote_ip.ip4); - } else { - ip6_addr_debug_print(UDP_DEBUG, &pcb->remote_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG, &pcb->remote_ip); LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port)); /* compare PCB local addr+port to UDP destination addr+port */ if ((pcb->local_port == dest) && #if LWIP_IPV6 - ((pcb->isipv6 && - (ip6_current_header() != NULL) && - (ip6_addr_isany(&pcb->local_ip.ip6) || + ((pcb->isipv6 && (ip_current_is_v6()) && + (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip)) || #if LWIP_IPV6_MLD ip6_addr_ismulticast(ip6_current_dest_addr()) || #endif /* LWIP_IPV6_MLD */ - ip6_addr_cmp(&pcb->local_ip.ip6, ip6_current_dest_addr()))) || + ip6_addr_cmp(ipX_2_ip6(&pcb->local_ip), ip6_current_dest_addr()))) || (!pcb->isipv6 && (ip_current_header() != NULL) && #else /* LWIP_IPV6 */ (( #endif /* LWIP_IPV6 */ - ((!broadcast && ip_addr_isany(&pcb->local_ip.ip4)) || - ip_addr_cmp(&(pcb->local_ip.ip4), ip_current_dest_addr()) || + ((!broadcast && ipX_addr_isany(0, &pcb->local_ip)) || + ip_addr_cmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr()) || #if LWIP_IGMP ip_addr_ismulticast(ip_current_dest_addr()) || #endif /* LWIP_IGMP */ @@ -224,19 +205,9 @@ udp_input(struct pbuf *p, struct netif *inp) } /* compare PCB remote addr+port to UDP source addr+port */ if ((local_match != 0) && - (pcb->remote_port == src) && -#if LWIP_IPV6 - ((pcb->isipv6 && - (ip6_current_header() != NULL) && - (ip6_addr_isany(&pcb->remote_ip.ip6) || - ip6_addr_cmp(&pcb->remote_ip.ip6, ip6_current_src_addr()))) || - (!pcb->isipv6 && - (ip_current_header() != NULL) && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - ((ip_addr_isany(&pcb->remote_ip.ip4) || - ip_addr_cmp(&(pcb->remote_ip.ip4), ip_current_src_addr())))))) { + (pcb->remote_port == src) && IP_PCB_IPVER_INPUT_MATCH(pcb) && + (ipX_addr_isany(pcb->isipv6, &pcb->remote_ip) || + ipX_addr_cmp(pcb->isipv6, &pcb->remote_ip, ipX_current_src_addr()))) { /* the first fully matching PCB */ if (prev != NULL) { /* move the pcb to the front of udp_pcbs so that is @@ -258,28 +229,24 @@ 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) || + if (pcb != NULL) { + for_us = 1; + } else { #if LWIP_IPV6 - ((ip6_current_header() != NULL) && - netif_matches_ip6_addr(inp, ip6_current_dest_addr())) || - ((ip_current_header() != NULL) && -#else /* LWIP_IPV6 */ - ( + if (ip_current_is_v6()) { + for_us = netif_matches_ip6_addr(inp, ip6_current_dest_addr()); + } else #endif /* LWIP_IPV6 */ - ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr()))) { + { + for_us = ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr()); + } + } + if (for_us) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); -#if LWIP_UDPLITE - if ( -#if LWIP_IPV6 - ((ip6_current_header() != NULL) && - (IP6H_NEXTH(ip6_current_header()) == IP_PROTO_UDPLITE)) || - ((ip_current_header() != NULL) && -#else /* LWIP_IPV6 */ - ( -#endif /* LWIP_IPV6 */ - (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE))) { - /* Do the UDP Lite checksum */ #if CHECKSUM_CHECK_UDP +#if LWIP_UDPLITE + if (ip_current_header_proto() == IP_PROTO_UDPLITE) { + /* Do the UDP Lite checksum */ u16_t chklen = ntohs(udphdr->len); if (chklen < sizeof(struct udp_hdr)) { if (chklen == 0) { @@ -289,72 +256,26 @@ udp_input(struct pbuf *p, struct netif *inp) } else { /* At least the UDP-Lite header must be covered by the checksum! (Again, see RFC 3828 chap. 3.1) */ - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; + goto chkerr; } } -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - if (ip6_chksum_pseudo_partial(p, ip6_current_src_addr(), ip6_current_dest_addr(), - IP6_NEXTH_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")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; - } + if (ipX_chksum_pseudo_partial(ip_current_is_v6(), p, IP_PROTO_UDPLITE, + p->tot_len, chklen, + ipX_current_src_addr(), ipX_current_dest_addr()) != 0) { + goto chkerr; } - else -#endif /* LWIP_IPV6 */ - if (inet_chksum_pseudo_partial(p, ip_current_src_addr(), ip_current_dest_addr(), - 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")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; - } -#endif /* CHECKSUM_CHECK_UDP */ } else #endif /* LWIP_UDPLITE */ { -#if CHECKSUM_CHECK_UDP if (udphdr->chksum != 0) { -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - if (ip6_chksum_pseudo(p, ip6_current_src_addr(), ip6_current_dest_addr(), - IP6_NEXTH_UDP, p->tot_len) != 0) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_input: UDP datagram discarded due to failing checksum\n")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; - } - } - else -#endif /* LWIP_IPV6 */ - 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")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; + if (ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_UDP, p->tot_len, + ipX_current_src_addr(), + ipX_current_dest_addr()) != 0) { + goto chkerr; } } -#endif /* CHECKSUM_CHECK_UDP */ } +#endif /* CHECKSUM_CHECK_UDP */ if(pbuf_header(p, -UDP_HLEN)) { /* Can we cope with this failing? Just assert for now */ LWIP_ASSERT("pbuf_header failed\n", 0); @@ -376,15 +297,7 @@ udp_input(struct pbuf *p, struct netif *inp) if SOF_REUSEADDR is set on the first match */ struct udp_pcb *mpcb; u8_t p_header_changed = 0; - s16_t hdrs_len; -#if LWIP_IPV6 - if (ip6_current_header() != NULL) { - hdrs_len = (s16_t)(ip6_current_header_tot_len() + UDP_HLEN); - } else -#endif /* LWIP_IPV6 */ - { - hdrs_len = (s16_t)((IPH_HL(ip_current_header()) * 4) + UDP_HLEN); - } + s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN); for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { if (mpcb != pcb) { /* compare PCB local addr+port to UDP destination addr+port */ @@ -392,13 +305,13 @@ udp_input(struct pbuf *p, struct netif *inp) #if LWIP_IPV6 ((mpcb->isipv6 && (ip6_addr_ismulticast(ip6_current_dest_addr()) || - ip6_addr_cmp(&mpcb->local_ip.ip6, ip6_current_dest_addr()))) || + ip6_addr_cmp(ipX_2_ip6(&mpcb->local_ip), ip6_current_dest_addr()))) || (!mpcb->isipv6 && #else /* LWIP_IPV6 */ (( #endif /* LWIP_IPV6 */ - ((!broadcast && ip_addr_isany(&mpcb->local_ip.ip4)) || - ip_addr_cmp(&(mpcb->local_ip.ip4), ip_current_dest_addr()) || + ((!broadcast && ipX_addr_isany(0, &mpcb->local_ip)) || + ip_addr_cmp(ipX_2_ip(&mpcb->local_ip), ip_current_dest_addr()) || #if LWIP_IGMP ip_addr_ismulticast(ip_current_dest_addr()) || #endif /* LWIP_IGMP */ @@ -470,23 +383,9 @@ udp_input(struct pbuf *p, struct netif *inp) !ip6_addr_ismulticast(ip6_current_dest_addr()) && #endif /* LWIP_IPV6 */ !ip_addr_ismulticast(ip_current_dest_addr())) { -#if LWIP_IPV6 && LWIP_ICMP6 - if (ip6_current_header() != NULL) { - /* move payload pointer back to ip header */ - pbuf_header(p, ip6_current_header_tot_len() + UDP_HLEN); - LWIP_ASSERT("p->payload == ip6_current_header()", (p->payload == ip6_current_header())); - icmp6_dest_unreach(p, ICMP6_DUR_PORT); - } - else -#endif /* LWIP_IPV6 && LWIP_ICMP6 */ - { -#if LWIP_ICMP - /* move payload pointer back to ip header */ - pbuf_header(p, (IPH_HL(ip_current_header()) * 4) + UDP_HLEN); - LWIP_ASSERT("p->payload == ip_current_header()", (p->payload == ip_current_header())); - icmp_dest_unreach(p, ICMP_DUR_PORT); -#endif /* LWIP_ICMP */ - } + /* move payload pointer back to ip header */ + pbuf_header(p, ip_current_header_tot_len() + UDP_HLEN); + icmp_port_unreach(ip_current_is_v6(), p); } #endif /* LWIP_ICMP || LWIP_ICMP6 */ UDP_STATS_INC(udp.proterr); @@ -499,6 +398,15 @@ udp_input(struct pbuf *p, struct netif *inp) } end: PERF_STOP("udp_input"); + return; +chkerr: + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + PERF_STOP("udp_input"); } /** @@ -523,7 +431,7 @@ err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) { /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto(pcb, p, &pcb->remote_ip.ip4, pcb->remote_port); + return udp_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port); } #if LWIP_CHECKSUM_ON_COPY @@ -534,7 +442,7 @@ udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, u8_t have_chksum, u16_t chksum) { /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto_chksum(pcb, p, &pcb->remote_ip.ip4, pcb->remote_port, + return udp_sendto_chksum(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port, have_chksum, chksum); } #endif /* LWIP_CHECKSUM_ON_COPY */ @@ -577,12 +485,12 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, /* find the outgoing network interface for this packet */ #if LWIP_IPV6 if (pcb->isipv6) { - if (ip6_addr_ismulticast((ip6_addr_t *)dst_ip)) { + if (ip6_addr_ismulticast(ip_2_ip6(dst_ip))) { /* For multicast, find a netif based on source address. */ - netif = ip6_route(&(pcb->local_ip.ip6), &(pcb->local_ip.ip6)); + netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ipX_2_ip6(&pcb->local_ip)); } else { - netif = ip6_route(&(pcb->local_ip.ip6), (ip6_addr_t *)dst_ip); + netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ip_2_ip6(dst_ip)); } } else @@ -598,11 +506,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, /* no outgoing network interface could be found? */ if (netif == NULL) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to ")); - if (!pcb->isipv6) { - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip); - } else { - ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, (ip6_addr_t *)dst_ip); - } + ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ip_2_ipX(dst_ip)); LWIP_DEBUGF(UDP_DEBUG, ("\n")); UDP_STATS_INC(udp.rterr); return ERR_RTE; @@ -652,6 +556,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, ip_addr_t *src_ip; err_t err; struct pbuf *q; /* q will be sent down the stack */ + u8_t ip_proto; #if IP_SOF_BROADCAST /* broadcast filter? */ @@ -669,7 +574,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, /* if the PCB is not yet bound to a port, bind it here */ if (pcb->local_port == 0) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); - err = udp_bind(pcb, &pcb->local_ip.ip4, pcb->local_port); + err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port); if (err != ERR_OK) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); return err; @@ -714,7 +619,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, ( #if LWIP_IPV6_MLD (pcb->isipv6 && - ip6_addr_ismulticast((ip6_addr_t*)dst_ip)) || + ip6_addr_ismulticast(ip_2_ip6(dst_ip))) || #endif /* LWIP_IPV6_MLD */ (!pcb->isipv6 && #else /* LWIP_IPV6 */ @@ -729,8 +634,8 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, /* PCB local address is IP_ANY_ADDR? */ #if LWIP_IPV6 if (pcb->isipv6) { - if (ip6_addr_isany(&pcb->local_ip.ip6)) { - src_ip =(ip_addr_t *)ip6_select_source_address(netif, (ip6_addr_t *)dst_ip); + if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { + src_ip = ip6_2_ip(ip6_select_source_address(netif, ip_2_ip6(dst_ip))); if (src_ip == NULL) { /* No suitable source address was found. */ if (q != p) { @@ -742,7 +647,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, } } else { /* use UDP PCB local IPv6 address as source address, if still valid. */ - if (netif_matches_ip6_addr(netif, &(pcb->local_ip.ip6)) < 0) { + if (netif_matches_ip6_addr(netif, ipX_2_ip6(&pcb->local_ip)) < 0) { /* Address isn't valid anymore. */ if (q != p) { /* free the header pbuf */ @@ -751,18 +656,18 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, } return ERR_RTE; } - src_ip = (ip_addr_t *)&(pcb->local_ip.ip6); + src_ip = ipX_2_ip(&pcb->local_ip); } } else #endif /* LWIP_IPV6 */ - if (ip_addr_isany(&pcb->local_ip.ip4)) { + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { /* use outgoing network interface IP address as source address */ src_ip = &(netif->ip_addr); } else { /* check if UDP PCB local IP address is correct * this could be an old address if netif->ip_addr has changed */ - if (!ip_addr_cmp(&(pcb->local_ip.ip4), &(netif->ip_addr))) { + if (!ip_addr_cmp(ipX_2_ip(&(pcb->local_ip)), &(netif->ip_addr))) { /* local_ip doesn't match, drop the packet */ if (q != p) { /* free the header pbuf */ @@ -773,7 +678,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, return ERR_VAL; } /* use UDP PCB local IP address as source address */ - src_ip = &(pcb->local_ip.ip4); + src_ip = ipX_2_ip(&(pcb->local_ip)); } LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); @@ -800,88 +705,51 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, } udphdr->len = htons(chklen_hdr); /* calculate checksum */ -#if LWIP_IPV6 - /* Checksum is mandatory for IPv6. */ - if (pcb->isipv6) { - udphdr->chksum = ip6_chksum_pseudo_partial(q, (ip6_addr_t *)src_ip, (ip6_addr_t *)dst_ip, - IP6_NEXTH_UDPLITE, q->tot_len, - #if !LWIP_CHECKSUM_ON_COPY - chklen); - #else /* !LWIP_CHECKSUM_ON_COPY */ - (have_chksum ? UDP_HLEN : chklen)); - if (have_chksum) { - u32_t acc; - acc = udphdr->chksum + (u16_t)~(chksum); - udphdr->chksum = FOLD_U32T(acc); - } - #endif /* !LWIP_CHECKSUM_ON_COPY */ - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udphdr->chksum == 0x0000) { - udphdr->chksum = 0xffff; - } - } - else -#endif /* LWIP_IPV6 */ - { #if CHECKSUM_GEN_UDP - udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, - IP_PROTO_UDPLITE, q->tot_len, - #if !LWIP_CHECKSUM_ON_COPY - chklen); - #else /* !LWIP_CHECKSUM_ON_COPY */ - (have_chksum ? UDP_HLEN : chklen)); - if (have_chksum) { - u32_t acc; - acc = udphdr->chksum + (u16_t)~(chksum); - udphdr->chksum = FOLD_U32T(acc); - } - #endif /* !LWIP_CHECKSUM_ON_COPY */ +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + chklen = UDP_HLEN; + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + udphdr->chksum = ipX_chksum_pseudo_partial(pcb->isipv6, q, IP_PROTO_UDPLITE, + q->tot_len, chklen, ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + u32_t acc; + acc = udphdr->chksum + (u16_t)~(chksum); + udphdr->chksum = FOLD_U32T(acc); + } +#endif /* LWIP_CHECKSUM_ON_COPY */ - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udphdr->chksum == 0x0000) { - udphdr->chksum = 0xffff; - } + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udphdr->chksum == 0x0000) { + udphdr->chksum = 0xffff; + } #endif /* CHECKSUM_GEN_UDP */ - } - /* output to IP */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n")); -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = &(pcb->addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT*/ -#if LWIP_IPV6 - if (pcb->isipv6) { - err = ip6_output_if(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, pcb->ttl, pcb->tos, IP6_NEXTH_UDPLITE, netif); - } - else -#endif /* LWIP_IPV6 */ - { - err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif); - } -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + + ip_proto = IP_PROTO_UDPLITE; } else #endif /* LWIP_UDPLITE */ { /* UDP */ LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); udphdr->len = htons(q->tot_len); /* calculate checksum */ -#if LWIP_IPV6 +#if CHECKSUM_GEN_UDP /* Checksum is mandatory over IPv6. */ - if (pcb->isipv6) { + if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { u16_t udpchksum; #if LWIP_CHECKSUM_ON_COPY if (have_chksum) { u32_t acc; - udpchksum = ip6_chksum_pseudo_partial(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, IP6_NEXTH_UDP, - q->tot_len, UDP_HLEN); + udpchksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, + q->tot_len, UDP_HLEN, ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); acc = udpchksum + (u16_t)~(chksum); udpchksum = FOLD_U32T(acc); } else #endif /* LWIP_CHECKSUM_ON_COPY */ { - udpchksum = ip6_chksum_pseudo(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, IP6_NEXTH_UDP, q->tot_len); + udpchksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, q->tot_len, + ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); } /* chksum zero must become 0xffff, as zero means 'no checksum' */ @@ -890,52 +758,17 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, } udphdr->chksum = udpchksum; } - else -#endif /* LWIP_IPV6 */ - { -#if CHECKSUM_GEN_UDP - if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { - u16_t udpchksum; -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - udpchksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, IP_PROTO_UDP, - q->tot_len, UDP_HLEN); - acc = udpchksum + (u16_t)~(chksum); - udpchksum = FOLD_U32T(acc); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len); - } - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udpchksum == 0x0000) { - udpchksum = 0xffff; - } - udphdr->chksum = udpchksum; - } #endif /* CHECKSUM_GEN_UDP */ - } - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); - /* output to IP */ -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = &(pcb->addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT*/ -#if LWIP_IPV6 - if (pcb->isipv6) { - err = ip6_output_if(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, pcb->ttl, pcb->tos, IP6_NEXTH_UDP, netif); - } - else -#endif /* LWIP_IPV6 */ - { - err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); - } -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + ip_proto = IP_PROTO_UDP; } + + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); + /* output to IP */ + NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint)); + err = ipX_output_if(pcb->isipv6, q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + /* TODO: must this be increased even if error occured? */ snmp_inc_udpoutdatagrams(); @@ -977,11 +810,7 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) u8_t rebind; LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); - if (!pcb->isipv6) { - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr); - } else { - ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, (ip6_addr_t *)ipaddr); - } + ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_TRACE, ip_2_ipX(ipaddr)); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); rebind = 0; @@ -1005,22 +834,11 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) /* port matches that of PCB in list and REUSEADDR not set -> reject */ else { #endif /* SO_REUSE */ - if ((ipcb->local_port == port) && + if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) && /* IP address matches, or one is IP_ADDR_ANY? */ -#if LWIP_IPV6 - ((pcb->isipv6 && - ipcb->isipv6 && - (ip6_addr_isany(&(ipcb->local_ip.ip6)) || - ip6_addr_isany((ip6_addr_t *)ipaddr) || - ip6_addr_cmp(&(ipcb->local_ip.ip6), (ip6_addr_t *)ipaddr))) || - (!pcb->isipv6 && - !ipcb->isipv6 && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - (ip_addr_isany(&(ipcb->local_ip.ip4)) || - ip_addr_isany(ipaddr) || - ip_addr_cmp(&(ipcb->local_ip.ip4), ipaddr))))) { + (ipX_addr_isany(ipcb->isipv6, &(ipcb->local_ip)) || + ipX_addr_isany(ipcb->isipv6, ip_2_ipX(ipaddr)) || + ipX_addr_cmp(ipcb->isipv6, &(ipcb->local_ip), ip_2_ipX(ipaddr)))) { /* other PCB already binds to this local IP and port */ LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); @@ -1029,15 +847,7 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) } } -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_set(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set(&pcb->local_ip.ip4, ipaddr); - } + ipX_addr_set_ipaddr(pcb->isipv6, &pcb->local_ip, ipaddr); /* no port specified? */ if (port == 0) { @@ -1075,14 +885,11 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) udp_pcbs = pcb; } LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to ")); - if (!pcb->isipv6) { - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip.ip4); - } else { - ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port)); return ERR_OK; } + /** * Connect an UDP PCB. * @@ -1106,21 +913,13 @@ udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) struct udp_pcb *ipcb; if (pcb->local_port == 0) { - err_t err = udp_bind(pcb, &pcb->local_ip.ip4, pcb->local_port); + err_t err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port); if (err != ERR_OK) { return err; } } -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_set(&pcb->remote_ip.ip6, (ip6_addr_t *)ipaddr); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set(&pcb->remote_ip.ip4, ipaddr); - } + ipX_addr_set_ipaddr(pcb->isipv6, &pcb->remote_ip, ipaddr); pcb->remote_port = port; pcb->flags |= UDP_FLAGS_CONNECTED; /** TODO: this functionality belongs in upper layers */ @@ -1130,29 +929,27 @@ udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) #endif /* LWIP_IPV6 */ { /* Nail down local IP for netconn_addr()/getsockname() */ - if (ip_addr_isany(&pcb->local_ip.ip4) && !ip_addr_isany(&pcb->remote_ip.ip4)) { + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip)) && !ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) { struct netif *netif; - if ((netif = ip_route(&(pcb->remote_ip.ip4))) == NULL) { - LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.ip4.addr)); + if ((netif = ip_route(ipX_2_ip(&pcb->remote_ip))) == NULL) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", + ip4_addr_get_u32(ipX_2_ip(&pcb->remote_ip)))); UDP_STATS_INC(udp.rterr); return ERR_RTE; } /** TODO: this will bind the udp pcb locally, to the interface which is used to route output packets to the remote address. However, we might want to accept incoming packets on any interface! */ - pcb->local_ip.ip4 = netif->ip_addr; - } else if (ip_addr_isany(&pcb->remote_ip.ip4)) { - pcb->local_ip.ip4.addr = 0; + ipX_addr_copy(0, pcb->local_ip, netif->ip_addr); + } else if (ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) { + ipX_addr_set_any(0, &pcb->local_ip); } } #endif LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to ")); - if (!pcb->isipv6) { - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->remote_ip.ip4); - } else { - ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->remote_ip.ip6); - } + ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + &pcb->remote_ip); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port)); /* Insert UDP PCB into the list of active UDP PCBs. */ @@ -1177,15 +974,7 @@ void udp_disconnect(struct udp_pcb *pcb) { /* reset remote address association */ -#if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_set_any(&pcb->remote_ip.ip6); - } - else -#endif /* LWIP_IPV6 */ - { - ip_addr_set_any(&pcb->remote_ip.ip4); - } + ipX_addr_set_any(pcb->isipv6, &pcb->remote_ip); pcb->remote_port = 0; /* mark PCB as unconnected */ pcb->flags &= ~UDP_FLAGS_CONNECTED; @@ -1278,10 +1067,7 @@ udp_new_ip6(void) { struct udp_pcb *pcb; pcb = udp_new(); - /* could allocate UDP PCB? */ - if (pcb != NULL) { - pcb->isipv6 = 1; - } + ip_set_v6(pcb, 1); return pcb; } #endif /* LWIP_IPV6 */ diff --git a/src/include/ipv4/lwip/icmp.h b/src/include/ipv4/lwip/icmp.h index d47a7d8a..fa893b6b 100644 --- a/src/include/ipv4/lwip/icmp.h +++ b/src/include/ipv4/lwip/icmp.h @@ -37,6 +37,10 @@ #include "lwip/ip_addr.h" #include "lwip/netif.h" +#if LWIP_IPV6 && LWIP_ICMP6 +#include "lwip/icmp6.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -104,6 +108,16 @@ void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); #endif /* LWIP_ICMP */ +#if (LWIP_IPV6 && LWIP_ICMP6) +#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ + icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ + icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) +#elif LWIP_ICMP +#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) +#else /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ +#define icmp_port_unreach(isipv6, pbuf) +#endif /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ + #ifdef __cplusplus } #endif diff --git a/src/include/ipv4/lwip/ip.h b/src/include/ipv4/lwip/ip4.h similarity index 57% rename from src/include/ipv4/lwip/ip.h rename to src/include/ipv4/lwip/ip4.h index 18a2abb8..bfe1153d 100644 --- a/src/include/ipv4/lwip/ip.h +++ b/src/include/ipv4/lwip/ip4.h @@ -29,8 +29,8 @@ * Author: Adam Dunkels * */ -#ifndef __LWIP_IP_H__ -#define __LWIP_IP_H__ +#ifndef __LWIP_IP4_H__ +#define __LWIP_IP4_H__ #include "lwip/opt.h" @@ -56,74 +56,6 @@ extern "C" { #define IP_PROTO_UDPLITE 136 #define IP_PROTO_TCP 6 -/* This is passed as the destination address to ip_output_if (not - to ip_output), meaning that an IP header already is constructed - in the pbuf. This is used when TCP retransmits. */ -#ifdef IP_HDRINCL -#undef IP_HDRINCL -#endif /* IP_HDRINCL */ -#define IP_HDRINCL NULL - -#if LWIP_NETIF_HWADDRHINT -#define IP_PCB_ADDRHINT ;u8_t addr_hint -#else -#define IP_PCB_ADDRHINT -#endif /* LWIP_NETIF_HWADDRHINT */ - -#if LWIP_IPV6 -#define IP_PCB_ISIPV6 u8_t isipv6; -#define IP_PCB_IP6 ip6_addr_t ip6; -#else -#define IP_PCB_ISIPV6 -#define IP_PCB_IP6 -#endif /* LWIP_IPV6 */ - -/* This is the common part of all PCB types. It needs to be at the - beginning of a PCB type definition. It is located here so that - changes to this common part are made in one location instead of - having to change all PCB structs. */ -#define IP_PCB \ - IP_PCB_ISIPV6 \ - /* ip addresses in network byte order */ \ - union { \ - ip_addr_t ip4; \ - IP_PCB_IP6 \ - } local_ip; \ - union { \ - ip_addr_t ip4; \ - IP_PCB_IP6 \ - } remote_ip; \ - /* Socket options */ \ - u8_t so_options; \ - /* Type Of Service */ \ - u8_t tos; \ - /* Time To Live */ \ - u8_t ttl \ - /* link layer address resolution hint */ \ - IP_PCB_ADDRHINT - -struct ip_pcb { -/* Common members of all PCB types */ - IP_PCB; -}; - -/* - * Option flags per-socket. These are the same like SO_XXX. - */ -/*#define SOF_DEBUG (u8_t)0x01U Unimplemented: turn on debugging info recording */ -#define SOF_ACCEPTCONN (u8_t)0x02U /* socket has had listen() */ -#define SOF_REUSEADDR (u8_t)0x04U /* allow local address reuse */ -#define SOF_KEEPALIVE (u8_t)0x08U /* keep connections alive */ -/*#define SOF_DONTROUTE (u8_t)0x10U Unimplemented: just use interface addresses */ -#define SOF_BROADCAST (u8_t)0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -/*#define SOF_USELOOPBACK (u8_t)0x40U Unimplemented: bypass hardware when possible */ -#define SOF_LINGER (u8_t)0x80U /* linger on close if data present */ -/*#define SOF_OOBINLINE (u16_t)0x0100U Unimplemented: leave received OOB data in line */ -/*#define SOF_REUSEPORT (u16_t)0x0200U Unimplemented: allow local address & port reuse */ - -/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ -#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) - #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h" @@ -175,16 +107,8 @@ PACK_STRUCT_END #define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) #define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) -/** The interface that provided the packet for the current callback invocation. */ -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. */ +#define ip_init() /* Compatibility define, no init needed. */ struct netif *ip_route(ip_addr_t *dest); err_t ip_input(struct pbuf *p, struct netif *inp); err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, @@ -201,18 +125,6 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, u16_t optlen); #endif /* IP_OPTIONS_SEND */ -/** Get the interface that received the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_netif() (current_netif) -/** Get the IP header of the current packet. - * 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); diff --git a/src/include/ipv4/lwip/ip_addr.h b/src/include/ipv4/lwip/ip4_addr.h similarity index 99% rename from src/include/ipv4/lwip/ip_addr.h rename to src/include/ipv4/lwip/ip4_addr.h index 77f84e02..b05ae537 100644 --- a/src/include/ipv4/lwip/ip_addr.h +++ b/src/include/ipv4/lwip/ip4_addr.h @@ -29,8 +29,8 @@ * Author: Adam Dunkels * */ -#ifndef __LWIP_IP_ADDR_H__ -#define __LWIP_IP_ADDR_H__ +#ifndef __LWIP_IP4_ADDR_H__ +#define __LWIP_IP4_ADDR_H__ #include "lwip/opt.h" #include "lwip/def.h" diff --git a/src/include/ipv6/lwip/ip6.h b/src/include/ipv6/lwip/ip6.h index b7d53344..f8f7e8eb 100644 --- a/src/include/ipv6/lwip/ip6.h +++ b/src/include/ipv6/lwip/ip6.h @@ -71,15 +71,6 @@ extern "C" { #define IP6_NEXTH_UDPLITE 136 -/* This is passed as the destination address to ip6_output_if (not - to ip6_output), meaning that an IP header already is constructed - in the pbuf. This is used when TCP retransmits. */ -#ifdef IP6_HDRINCL -#undef IP6_HDRINCL -#endif /* IP6_HDRINCL */ -#define IP6_HDRINCL NULL - - /* The IPv6 header. */ #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h" @@ -171,16 +162,6 @@ PACK_STRUCT_END #define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) - -/** Header of the input IPv6 packet currently being processed. */ -extern const struct ip6_hdr *current_ip6_header; -/** Total header length of current_ip6_header (i.e. after this, the UDP/TCP header starts) */ -extern u16_t current_ip6_header_tot_len; -/** Source IPv6 address of current_header */ -extern ip6_addr_t current_ip6hdr_src; -/** Destination IPv6 address of current_header */ -extern ip6_addr_t current_ip6hdr_dest; - #define ip6_init() /* TODO should we init current addresses and header pointer? */ struct netif *ip6_route(struct ip6_addr *src, struct ip6_addr *dest); ip6_addr_t *ip6_select_source_address(struct netif *netif, ip6_addr_t * dest); @@ -198,17 +179,6 @@ err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); #endif /* LWIP_IPV6_MLD */ -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() (current_ip6_header) -/** Total header length of current_ip6_header (i.e. after this, the UDP/TCP header starts) */ -#define ip6_current_header_tot_len() (current_ip6_header_tot_len) -/** Source IPv6 address of current_header */ -#define ip6_current_src_addr() (¤t_ip6hdr_src) -/** Destination IPv6 address of current_header */ -#define ip6_current_dest_addr() (¤t_ip6hdr_dest) - #if IP6_DEBUG void ip6_debug_print(struct pbuf *p); #else diff --git a/src/include/ipv6/lwip/ip6_addr.h b/src/include/ipv6/lwip/ip6_addr.h index f7e9da10..c962c769 100644 --- a/src/include/ipv6/lwip/ip6_addr.h +++ b/src/include/ipv6/lwip/ip6_addr.h @@ -115,35 +115,35 @@ Little-endian version, stored in network order (no htonl). */ #define IP6_ADDR_BLOCK8(ip6addr) ((htonl((ip6addr)->addr[3])) & 0xffff) /** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ -#define ip6_addr_copy(dest, src) {(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3];} +#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ + (dest).addr[1] = (src).addr[1]; \ + (dest).addr[2] = (src).addr[2]; \ + (dest).addr[3] = (src).addr[3];}while(0) /** Safely copy one IPv6 address to another (src may be NULL) */ -#define ip6_addr_set(dest, src) {(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ - (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ - (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ - (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];} +#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ + (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ + (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ + (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) /** Set complete address to zero */ -#define ip6_addr_set_zero(ip6addr) {(ip6addr)->addr[0] = 0; \ +#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ (ip6addr)->addr[1] = 0; \ (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = 0;} + (ip6addr)->addr[3] = 0;}while(0) /** Set address to ipv6 'any' (no need for htonl()) */ #define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) /** Set address to ipv6 loopback address */ -#define ip6_addr_set_loopback(ip6addr) {(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);} +#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) /** Safely copy one IPv6 address to another and change byte order * from host- to network-order. */ -#define ip6_addr_set_hton(dest, src) {(dest)->addr[0] = (src) == NULL ? 0 : htonl((src)->addr[0]); \ - (dest)->addr[1] = (src) == NULL ? 0 : htonl((src)->addr[1]); \ - (dest)->addr[2] = (src) == NULL ? 0 : htonl((src)->addr[2]); \ - (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);} +#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : htonl((src)->addr[0]); \ + (dest)->addr[1] = (src) == NULL ? 0 : htonl((src)->addr[1]); \ + (dest)->addr[2] = (src) == NULL ? 0 : htonl((src)->addr[2]); \ + (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);}while(0) @@ -211,28 +211,28 @@ Little-endian version, stored in network order (no htonl). */ ((ip6addr)->addr[1] == 0UL) && \ ((ip6addr)->addr[2] == 0UL) && \ ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) -#define ip6_addr_set_allnodes_linklocal(ip6addr) {(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ +#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ (ip6addr)->addr[1] = 0; \ (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);} + (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) #define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ ((ip6addr)->addr[1] == 0UL) && \ ((ip6addr)->addr[2] == 0UL) && \ ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) -#define ip6_addr_set_allrouters_linklocal(ip6addr) {(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ +#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ (ip6addr)->addr[1] = 0; \ (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);} + (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0) #define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) -#define ip6_addr_set_solicitednode(ip6addr, if_id) {(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ +#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ (ip6addr)->addr[1] = 0; \ (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ - (ip6addr)->addr[3] = htonl(0xff000000UL | (htonl(if_id) & 0x00ffffffUL));} + (ip6addr)->addr[3] = htonl(0xff000000UL | (htonl(if_id) & 0x00ffffffUL));}while(0) /* IPv6 address states. */ diff --git a/src/include/ipv6/lwip/ip6_chksum.h b/src/include/ipv6/lwip/ip6_chksum.h deleted file mode 100644 index 600257c7..00000000 --- a/src/include/ipv6/lwip/ip6_chksum.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * - * IPv6 Checksum helper functions. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef __LWIP_IP6_CHKSUM_H__ -#define __LWIP_IP6_CHKSUM_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -u16_t ip6_chksum_pseudo(struct pbuf *p, - ip6_addr_t *src, ip6_addr_t *dest, - u8_t proto, u16_t proto_len); -u16_t ip6_chksum_pseudo_partial(struct pbuf *p, - ip6_addr_t *src, ip6_addr_t *dest, - u8_t proto, u16_t proto_len, u16_t chksum_len); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_IP6_CHKSUM_H__ */ diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index f85a2dc9..71988108 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -76,34 +76,39 @@ extern "C" { /* Helpers to process several netconn_types by the same code */ -#define NETCONNTYPE_GROUP(t) ((t)&0xF0) -#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) -#define NETCONNTYPE_ISIPV6(t) ((t)&0x08) -#define NETCONNTYPE_ISUDPLITE(t)(((t)&0xF7) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t)(((t)&0xF7) == NETCONN_UDPNOCHKSUM) +#define NETCONNTYPE_GROUP(t) ((t)&0xF0) +#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) +#if LWIP_IPV6 +#define NETCONN_TYPE_IPV6 0x08 +#define NETCONNTYPE_ISIPV6(t) ((t)&0x08) +#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF7) == NETCONN_UDPLITE) +#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF7) == NETCONN_UDPNOCHKSUM) +#else /* LWIP_IPV6 */ +#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) +#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) +#endif /* LWIP_IPV6 */ /** Protocol family and type of the netconn */ enum netconn_type { - NETCONN_INVALID = 0, + NETCONN_INVALID = 0, /* NETCONN_TCP Group */ - NETCONN_TCP = 0x10, + NETCONN_TCP = 0x10, #if LWIP_IPV6 - NETCONN_TCP_IPV6 = 0x18, + NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, #endif /* LWIP_IPV6 */ /* NETCONN_UDP Group */ - NETCONN_UDP = 0x20, - NETCONN_UDPLITE = 0x21, - NETCONN_UDPNOCHKSUM= 0x22, + NETCONN_UDP = 0x20, + NETCONN_UDPLITE = 0x21, + NETCONN_UDPNOCHKSUM = 0x22, #if LWIP_IPV6 - NETCONN_UDP_IPV6 = 0x28, - NETCONN_UDPLITE_IPV6 = 0x29, - NETCONN_UDPNOCHKSUM_IPV6= 0x2a, + NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, + NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, + NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, #endif /* LWIP_IPV6 */ /* NETCONN_RAW Group */ - NETCONN_RAW = 0x40 + NETCONN_RAW = 0x40, #if LWIP_IPV6 - , - NETCONN_RAW_IPV6 = 0x48 + NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */, #endif /* LWIP_IPV6 */ }; @@ -258,15 +263,17 @@ err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); #endif /* LWIP_DNS */ #if LWIP_IPV6 -#define netconn_bind_ip6(conn, ip6addr, port) \ - netconn_bind(conn, (ip_addr_t*) ip6addr, port) -#define netconn_connect_ip6(conn, ip6addr, port) \ - netconn_connect(conn, (ip_addr_t*) ip6addr, port) -#define netconn_sendto_ip6(conn, buf, ip6addr, port) \ - netconn_sendto(conn, buf, (ip_addr_t*) ip6addr, port) + +#define netconn_bind_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_bind(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) +#define netconn_connect_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_connect(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) +#define netconn_sendto_ip6(conn, buf, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_sendto(conn, buf, ip6_2_ip(ip6addr), port) : ERR_VAL) #if LWIP_IPV6_MLD -#define netconn_join_leave_group_ip6(conn, multiaddr, srcaddr, join_or_leave) \ - netconn_join_leave_group(conn, (ip_addr_t*)multiaddr, (ip_addr_t*)srcaddr, join_or_leave) +#define netconn_join_leave_group_ip6(conn, multiaddr, srcaddr, join_or_leave) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_join_leave_group(conn, ip6_2_ip(multiaddr), ip6_2_ip(srcaddr), join_or_leave) :\ + ERR_VAL) #endif /* LWIP_IPV6_MLD*/ #endif /* LWIP_IPV6 */ diff --git a/src/include/lwip/api_msg.h b/src/include/lwip/api_msg.h index 2541e641..fca361d9 100644 --- a/src/include/lwip/api_msg.h +++ b/src/include/lwip/api_msg.h @@ -80,7 +80,7 @@ struct api_msg_msg { } bc; /** used for do_getaddr */ struct { - ip_addr_t *ipaddr; + ipX_addr_t *ipaddr; u16_t *port; u8_t local; } ad; @@ -101,8 +101,8 @@ struct api_msg_msg { #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) /** used for do_join_leave_group */ struct { - ip_addr_t *multiaddr; - ip_addr_t *netif_addr; + ipX_addr_t *multiaddr; + ipX_addr_t *netif_addr; enum netconn_igmp join_or_leave; } jl; #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ diff --git a/src/include/ipv4/lwip/inet_chksum.h b/src/include/lwip/inet_chksum.h similarity index 70% rename from src/include/ipv4/lwip/inet_chksum.h rename to src/include/lwip/inet_chksum.h index 79a2d90f..e1687888 100644 --- a/src/include/ipv4/lwip/inet_chksum.h +++ b/src/include/lwip/inet_chksum.h @@ -72,16 +72,38 @@ extern "C" { u16_t inet_chksum(void *dataptr, u16_t len); u16_t inet_chksum_pbuf(struct pbuf *p); -u16_t inet_chksum_pseudo(struct pbuf *p, - ip_addr_t *src, ip_addr_t *dest, - u8_t proto, u16_t proto_len); -u16_t inet_chksum_pseudo_partial(struct pbuf *p, - ip_addr_t *src, ip_addr_t *dest, - u8_t proto, u16_t proto_len, u16_t chksum_len); +u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip_addr_t *src, ip_addr_t *dest); +u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, + u16_t proto_len, u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest); #if LWIP_CHKSUM_COPY_ALGORITHM u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); #endif /* LWIP_CHKSUM_COPY_ALGORITHM */ +#if LWIP_IPV6 +u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip6_addr_t *src, ip6_addr_t *dest); +u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest); + +#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ + ((isipv6) ? \ + ip6_chksum_pseudo(p, proto, proto_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ + inet_chksum_pseudo(p, proto, proto_len, ipX_2_ip(src), ipX_2_ip(dest))) +#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ + ((isipv6) ? \ + ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ + inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip(src), ipX_2_ip(dest))) + +#else /* LWIP_IPV6 */ + +#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ + inet_chksum_pseudo(p, proto, proto_len, src, dest) +#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ + inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, src, dest) + +#endif /* LWIP_IPV6 */ + #ifdef __cplusplus } #endif diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h new file mode 100644 index 00000000..4f856271 --- /dev/null +++ b/src/include/lwip/ip.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" +#include "lwip/ip4.h" +#include "lwip/ip6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +#if LWIP_IPV6 +#define IP_PCB_ISIPV6_MEMBER u8_t isipv6; +#define IP_PCB_IPVER_EQ(pcb1, pcb2) ((pcb1)->isipv6 == (pcb2)->isipv6) +#define IP_PCB_IPVER_INPUT_MATCH(pcb) (ip_current_is_v6() ? \ + ((pcb)->isipv6 != 0) : \ + ((pcb)->isipv6 == 0)) +#define PCB_ISIPV6(pcb) ((pcb)->isipv6) +#else +#define IP_PCB_ISIPV6_MEMBER +#define IP_PCB_IPVER_EQ(pcb1, pcb2) 1 +#define IP_PCB_IPVER_INPUT_MATCH(pcb) 1 +#define PCB_ISIPV6(pcb) 0 +#endif /* LWIP_IPV6 */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB \ + IP_PCB_ISIPV6_MEMBER \ + /* ip addresses in network byte order */ \ + ipX_addr_t local_ip; \ + ipX_addr_t remote_ip; \ + /* Socket options */ \ + u8_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + +struct ip_pcb { +/* Common members of all PCB types */ + IP_PCB; +}; + +/* + * Option flags per-socket. These are the same like SO_XXX. + */ +/*#define SOF_DEBUG (u8_t)0x01U Unimplemented: turn on debugging info recording */ +#define SOF_ACCEPTCONN (u8_t)0x02U /* socket has had listen() */ +#define SOF_REUSEADDR (u8_t)0x04U /* allow local address reuse */ +#define SOF_KEEPALIVE (u8_t)0x08U /* keep connections alive */ +/*#define SOF_DONTROUTE (u8_t)0x10U Unimplemented: just use interface addresses */ +#define SOF_BROADCAST (u8_t)0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +/*#define SOF_USELOOPBACK (u8_t)0x40U Unimplemented: bypass hardware when possible */ +#define SOF_LINGER (u8_t)0x80U /* linger on close if data present */ +/*#define SOF_OOBINLINE (u16_t)0x0100U Unimplemented: leave received OOB data in line */ +/*#define SOF_REUSEPORT (u16_t)0x0200U Unimplemented: allow local address & port reuse */ + +/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ +#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) + +/* Global variables of this module, kept in a struct for efficient access using base+index. */ +struct ip_globals +{ + /** The interface that provided the packet for the current callback invocation. */ + struct netif *current_netif; + /** Header of the input packet currently being processed. */ + const struct ip_hdr *current_ip4_header; +#if LWIP_IPV6 + /** Header of the input IPv6 packet currently being processed. */ + const struct ip6_hdr *current_ip6_header; +#endif /* LWIP_IPV6 */ + /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ + u16_t current_ip_header_tot_len; + /** Source IP address of current_header */ + ipX_addr_t current_iphdr_src; + /** Destination IP address of current_header */ + ipX_addr_t current_iphdr_dest; +}; +extern struct ip_globals ip_data; + + +/** Get the interface that received the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_netif() (ip_data.current_netif) +/** Get the IP header of the current packet. + * 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() (ip_data.current_ip4_header) +/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ +#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) +/** Source IP address of current_header */ +#define ipX_current_src_addr() (&ip_data.current_iphdr_src) +/** Destination IP address of current_header */ +#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) + +#if LWIP_IPV6 +/** Get the IPv6 header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip6_current_header() (ip_data.current_ip6_header) +/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ +#define ip_current_is_v6() (ip6_current_header() != NULL) +/** Source IPv6 address of current_header */ +#define ip6_current_src_addr() (ipX_2_ip6(&ip_data.current_iphdr_src)) +/** Destination IPv6 address of current_header */ +#define ip6_current_dest_addr() (ipX_2_ip6(&ip_data.current_iphdr_dest)) +/** Get the transport layer protocol */ +#define ip_current_header_proto() (ip_current_is_v6() ? \ + IP6H_NEXTH(ip6_current_header()) :\ + IPH_PROTO(ip_current_header())) +/** Get the transport layer header */ +#define ipX_next_header_ptr() ((void*)((ip_current_is_v6() ? \ + (u8_t*)ip6_current_header() : (u8_t*)ip_current_header()) + ip_current_header_tot_len())) + +/** Set an IP_PCB to IPv6 (IPv4 is the default) */ +#define ip_set_v6(pcb, val) do{if(pcb != NULL) { pcb->isipv6 = val; }}while(0) + +/** Source IP4 address of current_header */ +#define ip_current_src_addr() (ipX_2_ip(&ip_data.current_iphdr_src)) +/** Destination IP4 address of current_header */ +#define ip_current_dest_addr() (ipX_2_ip(&ip_data.current_iphdr_dest)) + +#else /* LWIP_IPV6 */ + +/** Always returns FALSE when only supporting IPv4 */ +#define ip_current_is_v6() 0 +/** Get the transport layer protocol */ +#define ip_current_header_proto() IPH_PROTO(ip_current_header()) +/** Get the transport layer header */ +#define ipX_next_header_ptr() ((void*)((u8_t*)ip_current_header() + ip_current_header_tot_len())) +/** Source IP4 address of current_header */ +#define ip_current_src_addr() (&ip_data.current_iphdr_src) +/** Destination IP4 address of current_header */ +#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) + +#endif /* LWIP_IPV6 */ + +/** Union source address of current_header */ +#define ipX_current_src_addr() (&ip_data.current_iphdr_src) +/** Union destination address of current_header */ +#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) + +#if LWIP_IPV6 +#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ + ((isipv6) ? \ + ip6_output(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto) : \ + ip_output(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto)) +#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ((isipv6) ? \ + ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ + ip_output_if(p, (src), (dest), ttl, tos, proto, netif)) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ + ((isipv6) ? \ + ip6_output_hinted(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto, addr_hint) : \ + ip_output_hinted(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto, addr_hint)) +#define ipX_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip_debug_print(p)) +#else /* LWIP_IPV6 */ +#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ + ip_output(p, src, dest, ttl, tos, proto) +#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ip_output_if(p, src, dest, ttl, tos, proto, netif) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ + ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) +#define ipX_debug_print(is_ipv6, p) ip_debug_print(p) +#endif /* LWIP_IPV6 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/src/include/lwip/ip_addr.h b/src/include/lwip/ip_addr.h new file mode 100644 index 00000000..04ffa534 --- /dev/null +++ b/src/include/lwip/ip_addr.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" + +#include "lwip/ip4_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_IPV6 +/* A union struct for both IP version's addresses. */ +typedef union { + ip_addr_t ip4; + ip6_addr_t ip6; +} ipX_addr_t; + +/** These functions only exist for type-safe conversion from ip_addr_t to + ip6_addr_t and back */ +#if LWIP_ALLOW_STATIC_FN_IN_HEADER +static ip6_addr_t* ip_2_ip6(ip_addr_t *ipaddr) +{ return (ip6_addr_t*)ipaddr;} +static ip_addr_t* ip6_2_ip(ip6_addr_t *ip6addr) +{ return (ip_addr_t*)ip6addr; } +static ipX_addr_t* ip_2_ipX(ip_addr_t *ipaddr) +{ return (ipX_addr_t*)ipaddr; } +#else /* LWIP_ALLOW_STATIC_FN_IN_HEADER */ +#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) +#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) +#define ip_2_ipX(ip_addr_t *ipaddr) ((ipX_addr_t*)ipaddr) +#endif /* LWIP_ALLOW_STATIC_FN_IN_HEADER*/ +#define ipX_2_ip6(ip6addr) (&((ip6addr)->ip6)) +#define ipX_2_ip(ipaddr) (&((ipaddr)->ip4)) + +#define ipX_addr_copy(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_copy((dest).ip6, (src).ip6); }else{ \ + ip_addr_copy((dest).ip4, (src).ip4); }}while(0) +#define ipX_addr_set(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set(ipX_2_ip6(dest), ipX_2_ip6(src)); }else{ \ + ip_addr_set(ipX_2_ip(dest), ipX_2_ip(src)); }}while(0) +#define ipX_addr_set_ipaddr(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set(ipX_2_ip6(dest), ip_2_ip6(src)); }else{ \ + ip_addr_set(ipX_2_ip(dest), src); }}while(0) +#define ipX_addr_set_zero(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_zero(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_zero(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_any(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_any(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_loopback(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_loopback(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_hton(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set_hton(ipX_2_ip6(ipaddr), (src)) ;}else{ \ + ip_addr_set_hton(ipX_2_ip(ipaddr), (src));}}while(0) +#define ipX_addr_cmp(is_ipv6, addr1, addr2) ((is_ipv6) ? \ + ip6_addr_cmp(ipX_2_ip6(addr1), ipX_2_ip6(addr2)) : \ + ip_addr_cmp(ipX_2_ip(addr1), ipX_2_ip(addr2))) +#define ipX_addr_isany(is_ipv6, ipaddr) ((is_ipv6) ? \ + ip6_addr_isany(ipX_2_ip6(ipaddr)) : \ + ip_addr_isany(ipX_2_ip(ipaddr))) +#define ipX_addr_ismulticast(is_ipv6, ipaddr) ((is_ipv6) ? \ + ip6_addr_ismulticast(ipX_2_ip6(ipaddr)) : \ + ip_addr_ismulticast(ipX_2_ip(ipaddr))) +#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) do { if(is_ipv6) { \ + ip6_addr_debug_print(debug, ipX_2_ip6(ipaddr)); } else { \ + ip_addr_debug_print(debug, ipX_2_ip(ipaddr)); }}while(0) + +#else /* LWIP_IPV6 */ + +typedef ip_addr_t ipX_addr_t; +#define ipX_2_ip(ipaddr) (ipaddr) +#define ip_2_ipX(ipaddr) (ipaddr) + +#define ipX_addr_copy(is_ipv6, dest, src) ip_addr_copy(dest, src) +#define ipX_addr_set(is_ipv6, dest, src) ip_addr_set(dest, src) +#define ipX_addr_set_ipaddr(is_ipv6, dest, src) ip_addr_set(dest, src) +#define ipX_addr_set_zero(is_ipv6, ipaddr) ip_addr_set_zero(ipaddr) +#define ipX_addr_set_any(is_ipv6, ipaddr) ip_addr_set_any(ipaddr) +#define ipX_addr_set_loopback(is_ipv6, ipaddr) ip_addr_set_loopback(ipaddr) +#define ipX_addr_set_hton(is_ipv6, dest, src) ip_addr_set_hton(dest, src) +#define ipX_addr_cmp(is_ipv6, addr1, addr2) ip_addr_cmp(addr1, addr2) +#define ipX_addr_isany(is_ipv6, ipaddr) ip_addr_isany(ipaddr) +#define ipX_addr_ismulticast(is_ipv6, ipaddr) ip_addr_ismulticast(ipaddr) +#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) ip_addr_debug_print(debug, ipaddr) + +#endif /* LWIP_IPV6 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/src/include/lwip/netbuf.h b/src/include/lwip/netbuf.h index 82d3d701..d12fe270 100644 --- a/src/include/lwip/netbuf.h +++ b/src/include/lwip/netbuf.h @@ -46,18 +46,9 @@ extern "C" { /** This netbuf includes a checksum */ #define NETBUF_FLAG_CHKSUM 0x02 -#if LWIP_IPV6 -#define NETBUF_IP6 ip6_addr_t ip6; -#else -#define NETBUF_IP6 -#endif /* LWIP_IPV6 */ - struct netbuf { struct pbuf *p, *ptr; - union { - ip_addr_t ip4; - NETBUF_IP6 - } addr; + ipX_addr_t addr; u16_t port; #if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY @@ -65,10 +56,7 @@ struct netbuf { #endif /* LWIP_CHECKSUM_ON_COPY */ u16_t toport_chksum; #if LWIP_NETBUF_RECVINFO - union { - ip_addr_t ip4; - NETBUF_IP6 - } toaddr; + ipX_addr_t toaddr; #endif /* LWIP_NETBUF_RECVINFO */ #endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ }; @@ -94,12 +82,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.ip4)) -#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set((&(buf)->addr.ip4), fromaddr) +#define netbuf_fromaddr(buf) (ipX_2_ip(&((buf)->addr))) +#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(ipX_2_ip(&((buf)->addr)), fromaddr) #define netbuf_fromport(buf) ((buf)->port) #if LWIP_NETBUF_RECVINFO -#define netbuf_destaddr(buf) (&((buf)->toaddr.ip4)) -#define netbuf_set_destaddr(buf, destaddr) ip_addr_set((&(buf)->toaddr.ip4), destaddr) +#define netbuf_destaddr(buf) (ipX_2_ip(&((buf)->toaddr))) +#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(ipX_2_ip(&((buf)->toaddr)), destaddr) #define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) #endif /* LWIP_NETBUF_RECVINFO */ #if LWIP_CHECKSUM_ON_COPY @@ -108,12 +96,15 @@ void netbuf_first (struct netbuf *buf); #endif /* LWIP_CHECKSUM_ON_COPY */ #if LWIP_IPV6 -#define netbuf_fromaddr_ip6(buf) (&((buf)->addr.ip6)) -#define netbuf_set_fromaddr_ip6(buf, fromaddr) ip6_addr_set((&(buf)->addr.ip6), fromaddr) -#define netbuf_destaddr_ip6(buf) (&((buf)->toaddr.ip6)) -#define netbuf_set_destaddr_ip6(buf, destaddr) ip6_addr_set((&(buf)->toaddr.ip6), destaddr) +#define netbuf_fromaddr_ip6(buf) (ipX_2_ip6(&((buf)->addr))) +#define netbuf_set_fromaddr_ip6(buf, fromaddr) ip6_addr_set(ipX_2_ip6(&((buf)->addr)), fromaddr) +#define netbuf_destaddr_ip6(buf) (ipX_2_ip6(&((buf)->toaddr))) +#define netbuf_set_destaddr_ip6(buf, destaddr) ip6_addr_set(ipX_2_ip6(&((buf)->toaddr)), destaddr) #endif /* LWIP_IPV6 */ +#define netbuf_fromaddr_ipX(buf) (&((buf)->addr)) +#define netbuf_destaddr_ipX(buf) (&((buf)->toaddr)) + #ifdef __cplusplus } #endif diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index a8527f88..c14289b8 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -367,6 +367,11 @@ s8_t netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr); void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); #endif /* LWIP_IPV6 */ +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) +#else /* LWIP_NETIF_HWADDRHINT */ +#define NETIF_SET_HWADDRHINT(netif, hint) +#endif /* LWIP_NETIF_HWADDRHINT */ #ifdef __cplusplus } diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index e5b5eed8..a8243b6a 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -2309,7 +2309,7 @@ * IP6_DEBUG: Enable debugging for IPv6. */ #ifndef IP6_DEBUG -#define IP6_DEBUG LWIP_DBG_ON +#define IP6_DEBUG LWIP_DBG_OFF #endif #endif /* __LWIP_OPT_H__ */ diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h index 59eec8c5..53fdc69b 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -44,6 +44,9 @@ extern "C" { * of IP_FRAG */ #define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) +/* @todo: We need a mechanism to prevent wasting memory in every pbuf + (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ + #define PBUF_TRANSPORT_HLEN 20 #if LWIP_IPV6 #define PBUF_IP_HLEN 40 diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index 09842b67..5ce4a4f9 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -54,7 +54,8 @@ struct sockaddr_in { u8_t sin_family; u16_t sin_port; struct in_addr sin_addr; - char sin_zero[8]; +#define SIN_ZERO_LEN 8 + char sin_zero[SIN_ZERO_LEN]; }; #if LWIP_IPV6 diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index 53bc5320..fdd12567 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -281,7 +281,7 @@ struct tcp_pcb { u8_t keep_cnt_sent; }; -struct tcp_pcb_listen { +struct tcp_pcb_listen { /* Common members of all PCB types */ IP_PCB; /* Protocol specific PCB members */ @@ -291,6 +291,9 @@ struct tcp_pcb_listen { u8_t backlog; u8_t accepts_pending; #endif /* TCP_LISTEN_BACKLOG */ +#if LWIP_IPV6 + u8_t accept_any_ip_version; +#endif /* LWIP_IPV6 */ }; #if LWIP_EVENT_API @@ -372,9 +375,14 @@ const char* tcp_debug_state_str(enum tcp_state s); #if LWIP_IPV6 struct tcp_pcb * tcp_new_ip6 (void); #define tcp_bind_ip6(pcb, ip6addr, port) \ - tcp_bind(pcb, (ip_addr_t *)ip6addr, port) + tcp_bind(pcb, ip6_2_ip(ip6addr), port) #define tcp_connect_ip6(pcb, ip6addr, port, connected) \ - udp_connect(pcb, (ip_addr_t *)ip6addr, port, connected) + udp_connect(pcb, ip6_2_ip(ip6addr), port, connected) +struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) +#else /* LWIP_IPV6 */ +#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog) +#define tcp_listen_dual(pcb) tcp_listen(pcb) #endif /* LWIP_IPV6 */ diff --git a/src/include/lwip/tcp_impl.h b/src/include/lwip/tcp_impl.h index 126e8eb0..f3ae40d2 100644 --- a/src/include/lwip/tcp_impl.h +++ b/src/include/lwip/tcp_impl.h @@ -428,13 +428,19 @@ err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); -void tcp_rst(u32_t seqno, u32_t ackno, - ip_addr_t *local_ip, ip_addr_t *remote_ip, - u16_t local_port, u16_t remote_port); +void tcp_rst_impl(u32_t seqno, u32_t ackno, + ipX_addr_t *local_ip, ipX_addr_t *remote_ip, + u16_t local_port, u16_t remote_port #if LWIP_IPV6 -void tcp_rst_ip6(u32_t seqno, u32_t ackno, - ip6_addr_t *local_ip6, ip6_addr_t *remote_ip6, - u16_t local_port, u16_t remote_port); + , u8_t isipv6 +#endif /* LWIP_IPV6 */ + ); +#if LWIP_IPV6 +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) +#else /* LWIP_IPV6 */ +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port) #endif /* LWIP_IPV6 */ u32_t tcp_next_iss(void); @@ -443,9 +449,15 @@ void tcp_keepalive(struct tcp_pcb *pcb); void tcp_zero_window_probe(struct tcp_pcb *pcb); #if TCP_CALCULATE_EFF_SEND_MSS -u16_t tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr); +u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest #if LWIP_IPV6 -u16_t tcp_eff_send_mss_ip6(u16_t sendmss, ip6_addr_t *src, ip6_addr_t *dest); + , ipX_addr_t *src, u8_t isipv6 +#endif /* LWIP_IPV6 */ + ); +#if LWIP_IPV6 +#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6) +#else /* LWIP_IPV6 */ +#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest) #endif /* LWIP_IPV6 */ #endif /* TCP_CALCULATE_EFF_SEND_MSS */