Combined IPv4 and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP code so that the code is more readable.

This commit is contained in:
goldsimon 2011-05-25 17:16:35 +00:00
parent 9546e65617
commit 6865806b55
41 changed files with 1392 additions and 2269 deletions

View File

@ -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 :-)

View File

@ -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);

View File

@ -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 */
}

View File

@ -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;

View File

@ -58,15 +58,65 @@
#include <string.h>
/* 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) {

View File

@ -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

View File

@ -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 <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/inet.h"

View File

@ -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(&current_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(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_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(&current_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(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_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(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_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, &current_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(&current_iphdr_dest)) {
if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &current_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(&current_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(&current_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(&current_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(&current_iphdr_src))
if (check_ip_src && !ip_addr_isany(ip_current_src_addr()))
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
{ if ((ip_addr_isbroadcast(&current_iphdr_src, inp)) ||
(ip_addr_ismulticast(&current_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(&current_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, &current_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(&current_iphdr_dest, inp) &&
!ip_addr_ismulticast(&current_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(&current_iphdr_src);
ip_addr_set_any(&current_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;
}

View File

@ -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 <string.h>
#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(&ethhdr->dest, dst, 6);
SMEMCPY(&ethhdr->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(&ethhdr->dest, dst, 6);
SMEMCPY(&ethhdr->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 */

View File

@ -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 */

View File

@ -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(&current_ip6hdr_src);
ip6_addr_set_any(&current_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;
}

View File

@ -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 <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#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 */

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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*

View File

@ -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 */

View File

@ -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 <string.h>
@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -29,8 +29,8 @@
* Author: Adam Dunkels <adam@sics.se>
*
*/
#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() (&current_iphdr_src)
/** Destination IP address of current_header */
#define ip_current_dest_addr() (&current_iphdr_dest)
#if IP_DEBUG
void ip_debug_print(struct pbuf *p);

View File

@ -29,8 +29,8 @@
* Author: Adam Dunkels <adam@sics.se>
*
*/
#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"

View File

@ -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() (&current_ip6hdr_src)
/** Destination IPv6 address of current_header */
#define ip6_current_dest_addr() (&current_ip6hdr_dest)
#if IP6_DEBUG
void ip6_debug_print(struct pbuf *p);
#else

View File

@ -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. */

View File

@ -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 <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#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__ */

View File

@ -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 */

View File

@ -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) */

View File

@ -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

230
src/include/lwip/ip.h Normal file
View File

@ -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 <adam@sics.se>
*
*/
#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__ */

127
src/include/lwip/ip_addr.h Normal file
View File

@ -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 <adam@sics.se>
*
*/
#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__ */

View File

@ -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

View File

@ -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
}

View File

@ -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__ */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */