mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-06-30 18:09:02 +00:00
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:
parent
9546e65617
commit
6865806b55
|
@ -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 :-)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
|
|
@ -93,20 +93,8 @@
|
|||
#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
|
||||
#endif /* LWIP_DHCP */
|
||||
|
||||
/**
|
||||
* The interface that provided the packet for the current callback
|
||||
* invocation.
|
||||
*/
|
||||
struct netif *current_netif;
|
||||
|
||||
/**
|
||||
* Header of the input packet currently being processed.
|
||||
*/
|
||||
const struct ip_hdr *current_header;
|
||||
/** Source IP address of current_header */
|
||||
ip_addr_t current_iphdr_src;
|
||||
/** Destination IP address of current_header */
|
||||
ip_addr_t current_iphdr_dest;
|
||||
/** Global data for both IPv4 and IPv6 */
|
||||
struct ip_globals ip_data;
|
||||
|
||||
/** The IP header ID of the next outgoing IP packet */
|
||||
static u16_t ip_id;
|
||||
|
@ -164,19 +152,19 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||
PERF_START;
|
||||
|
||||
/* RFC3927 2.7: do not forward link-local addresses */
|
||||
if (ip_addr_islinklocal(¤t_iphdr_dest)) {
|
||||
if (ip_addr_islinklocal(ip_current_dest_addr())) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
|
||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
|
||||
ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()),
|
||||
ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr())));
|
||||
goto return_noroute;
|
||||
}
|
||||
|
||||
/* Find network interface where to forward this IP packet to. */
|
||||
netif = ip_route(¤t_iphdr_dest);
|
||||
netif = ip_route(ip_current_dest_addr());
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
|
||||
ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
|
||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
|
||||
ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()),
|
||||
ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr())));
|
||||
goto return_noroute;
|
||||
}
|
||||
/* Do not forward packets onto the same network interface on which
|
||||
|
@ -208,8 +196,8 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||
}
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
|
||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
|
||||
ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()),
|
||||
ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr())));
|
||||
|
||||
IP_STATS_INC(ip.fw);
|
||||
IP_STATS_INC(ip.xmit);
|
||||
|
@ -217,7 +205,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||
|
||||
PERF_STOP("ip_forward");
|
||||
/* transmit pbuf on chosen interface */
|
||||
netif->output(netif, p, ¤t_iphdr_dest);
|
||||
netif->output(netif, p, ip_current_dest_addr());
|
||||
return;
|
||||
return_noroute:
|
||||
snmp_inc_ipoutnoroutes();
|
||||
|
@ -311,13 +299,13 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
pbuf_realloc(p, iphdr_len);
|
||||
|
||||
/* copy IP addresses to aligned ip_addr_t */
|
||||
ip_addr_copy(current_iphdr_dest, iphdr->dest);
|
||||
ip_addr_copy(current_iphdr_src, iphdr->src);
|
||||
ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_dest), iphdr->dest);
|
||||
ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_src), iphdr->src);
|
||||
|
||||
/* match packet against an interface, i.e. is this packet for us? */
|
||||
#if LWIP_IGMP
|
||||
if (ip_addr_ismulticast(¤t_iphdr_dest)) {
|
||||
if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_iphdr_dest))) {
|
||||
if (ip_addr_ismulticast(ip_current_dest_addr())) {
|
||||
if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip_current_dest_addr()))) {
|
||||
netif = inp;
|
||||
} else {
|
||||
netif = NULL;
|
||||
|
@ -340,9 +328,9 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
/* interface is up and configured? */
|
||||
if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
|
||||
/* unicast to this interface address? */
|
||||
if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) ||
|
||||
if (ip_addr_cmp(ip_current_dest_addr(), &(netif->ip_addr)) ||
|
||||
/* or broadcast on this interface network address? */
|
||||
ip_addr_isbroadcast(¤t_iphdr_dest, netif)) {
|
||||
ip_addr_isbroadcast(ip_current_dest_addr(), netif)) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
/* break out of for loop */
|
||||
|
@ -352,7 +340,7 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
/* connections to link-local addresses must persist after changing
|
||||
the netif's address (RFC3927 ch. 1.9) */
|
||||
if ((netif->autoip != NULL) &&
|
||||
ip_addr_cmp(¤t_iphdr_dest, &(netif->autoip->llipaddr))) {
|
||||
ip_addr_cmp(ip_current_dest_addr(), &(netif->autoip->llipaddr))) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
/* break out of for loop */
|
||||
|
@ -400,10 +388,10 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
/* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
|
||||
#if IP_ACCEPT_LINK_LAYER_ADDRESSING
|
||||
/* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
|
||||
if (check_ip_src && !ip_addr_isany(¤t_iphdr_src))
|
||||
if (check_ip_src && !ip_addr_isany(ip_current_src_addr()))
|
||||
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
|
||||
{ if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) ||
|
||||
(ip_addr_ismulticast(¤t_iphdr_src))) {
|
||||
{ if ((ip_addr_isbroadcast(ip_current_src_addr(), inp)) ||
|
||||
(ip_addr_ismulticast(ip_current_src_addr()))) {
|
||||
/* packet source is not valid */
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
|
||||
/* free (drop) packet pbufs */
|
||||
|
@ -421,7 +409,7 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
|
||||
#if IP_FORWARD
|
||||
/* non-broadcast packet? */
|
||||
if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp)) {
|
||||
if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp)) {
|
||||
/* try to forward IP packet on (other) interfaces */
|
||||
ip_forward(p, iphdr, inp);
|
||||
} else
|
||||
|
@ -480,8 +468,9 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
ip_debug_print(p);
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
|
||||
|
||||
current_netif = inp;
|
||||
current_header = iphdr;
|
||||
ip_data.current_netif = inp;
|
||||
ip_data.current_ip4_header = iphdr;
|
||||
ip_data.current_ip_header_tot_len = IPH_LEN(iphdr);
|
||||
|
||||
#if LWIP_RAW
|
||||
/* raw input did not eat the packet? */
|
||||
|
@ -517,14 +506,14 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
#if LWIP_IGMP
|
||||
case IP_PROTO_IGMP:
|
||||
pbuf_header(p, -iphdr_hlen); /* Move to payload, no check necessary. */
|
||||
igmp_input(p, inp, ¤t_iphdr_dest);
|
||||
igmp_input(p, inp, ip_current_dest_addr());
|
||||
break;
|
||||
#endif /* LWIP_IGMP */
|
||||
default:
|
||||
#if LWIP_ICMP
|
||||
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
||||
if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) &&
|
||||
!ip_addr_ismulticast(¤t_iphdr_dest)) {
|
||||
if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp) &&
|
||||
!ip_addr_ismulticast(ip_current_dest_addr())) {
|
||||
p->payload = iphdr;
|
||||
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
||||
}
|
||||
|
@ -539,10 +528,12 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
}
|
||||
}
|
||||
|
||||
current_netif = NULL;
|
||||
current_header = NULL;
|
||||
ip_addr_set_any(¤t_iphdr_src);
|
||||
ip_addr_set_any(¤t_iphdr_dest);
|
||||
/* @todo: this is not really necessary... */
|
||||
ip_data.current_netif = NULL;
|
||||
ip_data.current_ip4_header = NULL;
|
||||
ip_data.current_ip_header_tot_len = 0;
|
||||
ip_addr_set_any(ip_current_src_addr());
|
||||
ip_addr_set_any(ip_current_dest_addr());
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
@ -805,9 +796,9 @@ ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
|||
return ERR_RTE;
|
||||
}
|
||||
|
||||
netif->addr_hint = addr_hint;
|
||||
NETIF_SET_HWADDRHINT(netif, addr_hint);
|
||||
err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
|
||||
netif->addr_hint = NULL;
|
||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||
|
||||
return err;
|
||||
}
|
|
@ -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(ðhdr->dest, dst, 6);
|
||||
SMEMCPY(ðhdr->src, src, 6);
|
||||
ethhdr->type = PP_HTONS(ETHTYPE_IPV6);
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p));
|
||||
/* send the packet */
|
||||
return netif->linkoutput(netif, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve and fill-in Ethernet address header for outgoing IPv6 packet.
|
||||
|
@ -169,29 +192,4 @@ ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr)
|
|||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an IPv6 packet on the network using netif->linkoutput
|
||||
* The ethernet header is filled in before sending.
|
||||
*
|
||||
* @params netif the lwIP network interface on which to send the packet
|
||||
* @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header
|
||||
* @params src the source MAC address to be copied into the ethernet header
|
||||
* @params dst the destination MAC address to be copied into the ethernet header
|
||||
* @return ERR_OK if the packet was sent, any other err_t on failure
|
||||
*/
|
||||
static err_t
|
||||
ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
|
||||
{
|
||||
struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
|
||||
|
||||
LWIP_ASSERT("netif->hwaddr_len must be 6 for ethip6!",
|
||||
(netif->hwaddr_len == 6));
|
||||
SMEMCPY(ðhdr->dest, dst, 6);
|
||||
SMEMCPY(ðhdr->src, src, 6);
|
||||
ethhdr->type = PP_HTONS(ETHTYPE_IPV6);
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p));
|
||||
/* send the packet */
|
||||
return netif->linkoutput(netif, p);
|
||||
}
|
||||
|
||||
#endif /* LWIP_IPV6 && LWIP_ETHERNET */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -61,17 +61,6 @@
|
|||
#include "lwip/stats.h"
|
||||
|
||||
|
||||
/** Header of the input IPv6 packet currently being processed. */
|
||||
const struct ip6_hdr *current_ip6_header;
|
||||
/** Total header length of current_ip6_header (i.e. after this, the UDP/TCP header starts) */
|
||||
u16_t current_ip6_header_tot_len;
|
||||
/** Source IPv6 address of current_header */
|
||||
ip6_addr_t current_ip6hdr_src;
|
||||
/** Destination IPv6 address of current_header */
|
||||
ip6_addr_t current_ip6hdr_dest;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Finds the appropriate network interface for a given IPv6 address. It tries to select
|
||||
* a netif following a sequence of heuristics:
|
||||
|
@ -380,11 +369,11 @@ ip6_input(struct pbuf *p, struct netif *inp)
|
|||
pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr));
|
||||
|
||||
/* copy IP addresses to aligned ip6_addr_t */
|
||||
ip6_addr_copy(current_ip6hdr_dest, ip6hdr->dest);
|
||||
ip6_addr_copy(current_ip6hdr_src, ip6hdr->src);
|
||||
ip6_addr_copy(ip_data.current_iphdr_dest.ip6, ip6hdr->dest);
|
||||
ip6_addr_copy(ip_data.current_iphdr_src.ip6, ip6hdr->src);
|
||||
|
||||
/* current header pointer. */
|
||||
current_ip6_header = ip6hdr;
|
||||
ip_data.current_ip6_header = ip6hdr;
|
||||
|
||||
/* match packet against an interface, i.e. is this packet for us? */
|
||||
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
|
||||
|
@ -468,13 +457,13 @@ netif_found:
|
|||
}
|
||||
|
||||
/* current netif pointer. */
|
||||
current_netif = inp;
|
||||
ip_data.current_netif = inp;
|
||||
|
||||
/* Save next header type. */
|
||||
nexth = IP6H_NEXTH(ip6hdr);
|
||||
|
||||
/* Init header length. */
|
||||
hlen = current_ip6_header_tot_len = IP6_HLEN;
|
||||
hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
|
||||
|
||||
/* Move to payload. */
|
||||
pbuf_header(p, -IP6_HLEN);
|
||||
|
@ -490,7 +479,7 @@ netif_found:
|
|||
|
||||
/* Get the header length. */
|
||||
hlen = 8 * (1 + *((u8_t *)p->payload) + 1);
|
||||
current_ip6_header_tot_len += hlen;
|
||||
ip_data.current_ip_header_tot_len += hlen;
|
||||
|
||||
/* Skip over this header. */
|
||||
if (hlen > p->len) {
|
||||
|
@ -513,7 +502,7 @@ netif_found:
|
|||
|
||||
/* Get the header length. */
|
||||
hlen = 8 * (1 + *((u8_t *)p->payload) + 1);
|
||||
current_ip6_header_tot_len += hlen;
|
||||
ip_data.current_ip_header_tot_len += hlen;
|
||||
|
||||
/* Skip over this header. */
|
||||
if (hlen > p->len) {
|
||||
|
@ -536,7 +525,7 @@ netif_found:
|
|||
|
||||
/* Get the header length. */
|
||||
hlen = 8 * (1 + *((u8_t *)p->payload) + 1);
|
||||
current_ip6_header_tot_len += hlen;
|
||||
ip_data.current_ip_header_tot_len += hlen;
|
||||
|
||||
/* Skip over this header. */
|
||||
if (hlen > p->len) {
|
||||
|
@ -565,7 +554,7 @@ netif_found:
|
|||
|
||||
/* Fragment Header length. */
|
||||
hlen = 8;
|
||||
current_ip6_header_tot_len += hlen;
|
||||
ip_data.current_ip_header_tot_len += hlen;
|
||||
|
||||
/* Make sure this header fits in current pbuf. */
|
||||
if (hlen > p->len) {
|
||||
|
@ -601,7 +590,7 @@ netif_found:
|
|||
* Update all our variables and pointers and continue. */
|
||||
ip6hdr = (struct ip6_hdr *)p->payload;
|
||||
nexth = IP6H_NEXTH(ip6hdr);
|
||||
hlen = current_ip6_header_tot_len = IP6_HLEN;
|
||||
hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
|
||||
pbuf_header(p, -IP6_HLEN);
|
||||
|
||||
#else /* LWIP_IPV6_REASS */
|
||||
|
@ -623,7 +612,7 @@ netif_found:
|
|||
options_done:
|
||||
|
||||
/* p points to IPv6 header again. */
|
||||
pbuf_header(p, current_ip6_header_tot_len);
|
||||
pbuf_header(p, ip_data.current_ip_header_tot_len);
|
||||
|
||||
/* send to upper layers */
|
||||
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
|
||||
|
@ -645,21 +634,21 @@ options_done:
|
|||
case IP6_NEXTH_UDPLITE:
|
||||
#endif /* LWIP_UDPLITE */
|
||||
/* Point to payload. */
|
||||
pbuf_header(p, -current_ip6_header_tot_len);
|
||||
pbuf_header(p, -ip_data.current_ip_header_tot_len);
|
||||
udp_input(p, inp);
|
||||
break;
|
||||
#endif /* LWIP_UDP */
|
||||
#if LWIP_TCP
|
||||
case IP6_NEXTH_TCP:
|
||||
/* Point to payload. */
|
||||
pbuf_header(p, -current_ip6_header_tot_len);
|
||||
pbuf_header(p, -ip_data.current_ip_header_tot_len);
|
||||
tcp_input(p, inp);
|
||||
break;
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_ICMP6
|
||||
case IP6_NEXTH_ICMP6:
|
||||
/* Point to payload. */
|
||||
pbuf_header(p, -current_ip6_header_tot_len);
|
||||
pbuf_header(p, -ip_data.current_ip_header_tot_len);
|
||||
icmp6_input(p, inp);
|
||||
break;
|
||||
#endif /* LWIP_ICMP */
|
||||
|
@ -668,7 +657,7 @@ options_done:
|
|||
/* send ICMP parameter problem unless it was a multicast or ICMPv6 */
|
||||
if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
|
||||
(IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
|
||||
icmp6_param_problem(p, ICMP6_PP_HEADER, current_ip6_header_tot_len - hlen);
|
||||
icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen);
|
||||
}
|
||||
#endif /* LWIP_ICMP */
|
||||
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", IP6H_NEXTH(ip6hdr)));
|
||||
|
@ -680,11 +669,11 @@ options_done:
|
|||
}
|
||||
|
||||
ip6_input_cleanup:
|
||||
current_netif = NULL;
|
||||
current_ip6_header = NULL;
|
||||
current_ip6_header_tot_len = 0;
|
||||
ip6_addr_set_any(¤t_ip6hdr_src);
|
||||
ip6_addr_set_any(¤t_ip6hdr_dest);
|
||||
ip_data.current_netif = NULL;
|
||||
ip_data.current_ip6_header = NULL;
|
||||
ip_data.current_ip_header_tot_len = 0;
|
||||
ip6_addr_set_any(&ip_data.current_iphdr_src.ip6);
|
||||
ip6_addr_set_any(&ip_data.current_iphdr_dest.ip6);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
@ -727,7 +716,7 @@ ip6_output_if(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest,
|
|||
LWIP_ASSERT("p->ref == 1", p->ref == 1);
|
||||
|
||||
/* Should the IPv6 header be generated or is it already included in p? */
|
||||
if (dest != IP6_HDRINCL) {
|
||||
if (dest != IP_HDRINCL) {
|
||||
/* generate IPv6 header */
|
||||
if (pbuf_header(p, IP6_HLEN)) {
|
||||
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
|
||||
|
@ -883,9 +872,9 @@ ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest,
|
|||
return ERR_RTE;
|
||||
}
|
||||
|
||||
netif->addr_hint = addr_hint;
|
||||
NETIF_SET_HWADDRHINT(netif, addr_hint);
|
||||
err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
|
||||
netif->addr_hint = NULL;
|
||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
168
src/core/raw.c
168
src/core/raw.c
|
@ -105,17 +105,9 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||
/* loop through all raw pcbs until the packet is eaten by one */
|
||||
/* this allows multiple pcbs to match against the packet by design */
|
||||
while ((eaten == 0) && (pcb != NULL)) {
|
||||
if ((pcb->protocol == proto) &&
|
||||
#if LWIP_IPV6
|
||||
((pcb->isipv6 &&
|
||||
(ip6_addr_isany(&pcb->local_ip.ip6) ||
|
||||
ip6_addr_cmp(&pcb->local_ip.ip6, ip6_current_dest_addr()))) ||
|
||||
(!pcb->isipv6 &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
(ip_addr_isany(&pcb->local_ip.ip4) ||
|
||||
ip_addr_cmp(&(pcb->local_ip.ip4), ip_current_dest_addr()))))) {
|
||||
if ((pcb->protocol == proto) && IP_PCB_IPVER_INPUT_MATCH(pcb) &&
|
||||
(ipX_addr_isany(pcb->isipv6, &pcb->local_ip) ||
|
||||
ipX_addr_cmp(pcb->isipv6, &(pcb->local_ip), ipX_current_dest_addr()))) {
|
||||
#if IP_SOF_BROADCAST_RECV
|
||||
/* broadcast filter? */
|
||||
if (((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp))
|
||||
|
@ -128,15 +120,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||
/* receive callback function available? */
|
||||
if (pcb->recv.ip4 != NULL) {
|
||||
/* the receive callback function did not eat the packet? */
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
eaten = pcb->recv.ip6(pcb->recv_arg, pcb, p, ip6_current_src_addr());
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
eaten = pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr());
|
||||
}
|
||||
eaten = pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr());
|
||||
if (eaten != 0) {
|
||||
/* receive function ate the packet */
|
||||
p = NULL;
|
||||
|
@ -177,15 +161,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||
err_t
|
||||
raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr)
|
||||
{
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
ip6_addr_set(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
ip_addr_set(&pcb->local_ip.ip4, ipaddr);
|
||||
}
|
||||
ipX_addr_set_ipaddr(pcb->isipv6, &pcb->local_ip, ipaddr);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
@ -205,15 +181,7 @@ raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr)
|
|||
err_t
|
||||
raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr)
|
||||
{
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
ip6_addr_set(&pcb->remote_ip.ip6, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
ip_addr_set(&pcb->remote_ip.ip4, ipaddr);
|
||||
}
|
||||
ipX_addr_set_ipaddr(pcb->isipv6, &pcb->remote_ip, ipaddr);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
@ -258,38 +226,22 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
struct netif *netif;
|
||||
ip_addr_t *src_ip;
|
||||
struct pbuf *q; /* q will be sent down the stack */
|
||||
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
|
||||
|
||||
s16_t header_size;
|
||||
#if LWIP_IPV6
|
||||
/* TODO lots of v4 and v6 code duplication, optimize! Or will compiler optimize? */
|
||||
if (pcb->isipv6) {
|
||||
/* not enough space to add an IPv6 header to first pbuf in given p chain? */
|
||||
if (pbuf_header(p, IP6_HLEN)) {
|
||||
/* allocate header in new pbuf */
|
||||
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
|
||||
/* new header pbuf could not be allocated? */
|
||||
if (q == NULL) {
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
/* { first pbuf q points to header pbuf } */
|
||||
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||
} else {
|
||||
/* first pbuf q equals given pbuf */
|
||||
q = p;
|
||||
if(pbuf_header(q, -IP6_HLEN)) {
|
||||
LWIP_ASSERT("Can't restore header we just removed!", 0);
|
||||
return ERR_MEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ip6_addr_t *ip6addr = ip_2_ip6(ipaddr);
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
|
||||
|
||||
header_size = (
|
||||
#if LWIP_IPV6
|
||||
pcb->isipv6 ? IP6_HLEN :
|
||||
#endif /* LWIP_IPV6 */
|
||||
IP_HLEN);
|
||||
|
||||
/* not enough space to add an IP header to first pbuf in given p chain? */
|
||||
if (pbuf_header(p, IP_HLEN)) {
|
||||
if (pbuf_header(p, header_size)) {
|
||||
/* allocate header in new pbuf */
|
||||
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
|
||||
/* new header pbuf could not be allocated? */
|
||||
|
@ -306,7 +258,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
} else {
|
||||
/* first pbuf q equals given pbuf */
|
||||
q = p;
|
||||
if(pbuf_header(q, -IP_HLEN)) {
|
||||
if(pbuf_header(q, -header_size)) {
|
||||
LWIP_ASSERT("Can't restore header we just removed!", 0);
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
@ -314,20 +266,14 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
if ((netif = ip6_route(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr)) == NULL) {
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to IPv6 destionation\n"));
|
||||
/* free any temporary header pbuf allocated by pbuf_header() */
|
||||
if (q != p) {
|
||||
pbuf_free(q);
|
||||
}
|
||||
return ERR_RTE;
|
||||
}
|
||||
netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ip6addr);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if ((netif = ip_route(ipaddr)) == NULL) {
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
|
||||
netif = ip_route(ipaddr);
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
|
||||
ipX_addr_debug_print(pcb->isipv6, RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ip_2_ipX(ipaddr));
|
||||
/* free any temporary header pbuf allocated by pbuf_header() */
|
||||
if (q != p) {
|
||||
pbuf_free(q);
|
||||
|
@ -337,8 +283,10 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
|
||||
#if IP_SOF_BROADCAST
|
||||
#if LWIP_IPV6
|
||||
if (!netif->isipv6) {
|
||||
/* @todo: why does IPv6 not filter broadcast with SOF_BROADCAST enabled? */
|
||||
if (!netif->isipv6)
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
/* broadcast filter? */
|
||||
if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) {
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
|
||||
|
@ -348,54 +296,48 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
}
|
||||
return ERR_VAL;
|
||||
}
|
||||
#if LWIP_IPV6
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
#endif /* IP_SOF_BROADCAST */
|
||||
|
||||
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
|
||||
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
if (ip6_addr_isany(&pcb->local_ip.ip6)) {
|
||||
ip6_addr_t *src6_ip;
|
||||
if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) {
|
||||
/* select an IPv6 address from the netif as source address */
|
||||
src_ip = (ip_addr_t *)ip6_select_source_address(netif, (ip6_addr_t *)ipaddr);
|
||||
if (src_ip == NULL) {
|
||||
src6_ip = ip6_select_source_address(netif, ip6addr);
|
||||
if (src6_ip == NULL) {
|
||||
/* No suitable source address was found. */
|
||||
err = ERR_RTE;
|
||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||
/* did we chain a header earlier? */
|
||||
if (q != p) {
|
||||
/* free the header */
|
||||
pbuf_free(q);
|
||||
}
|
||||
return ERR_RTE;
|
||||
}
|
||||
} else {
|
||||
/* use RAW PCB local IPv6 address as source address */
|
||||
src_ip = (ip_addr_t *)&(pcb->local_ip.ip6);
|
||||
src6_ip = ipX_2_ip6(&pcb->local_ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if (ip_addr_isany(&pcb->local_ip.ip4)) {
|
||||
/* use outgoing network interface IP address as source address */
|
||||
src_ip = &(netif->ip_addr);
|
||||
} else {
|
||||
/* use RAW PCB local IP address as source address */
|
||||
src_ip = &(pcb->local_ip.ip4);
|
||||
}
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
err = ip6_output_if(q, (ip6_addr_t *)src_ip, (ip6_addr_t *)ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
|
||||
err = ip6_output_if(q, src6_ip, ip6addr, pcb->ttl, pcb->tos, pcb->protocol, netif);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
|
||||
if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) {
|
||||
/* use outgoing network interface IP address as source address */
|
||||
src_ip = &(netif->ip_addr);
|
||||
} else {
|
||||
/* use RAW PCB local IP address as source address */
|
||||
src_ip = ipX_2_ip(&pcb->local_ip);
|
||||
}
|
||||
err = ip_output_if(q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
|
||||
}
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
|
||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||
/* did we chain a header earlier? */
|
||||
if (q != p) {
|
||||
/* free the header */
|
||||
|
@ -414,13 +356,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
err_t
|
||||
raw_send(struct raw_pcb *pcb, struct pbuf *p)
|
||||
{
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
/* TODO is this necessary, or ar ip4 and ip6 pointers the same (think union)? */
|
||||
return raw_sendto(pcb, p, (ip_addr_t *)&pcb->remote_ip.ip6);
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
return raw_sendto(pcb, p, &pcb->remote_ip.ip4);
|
||||
return raw_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -499,9 +435,7 @@ raw_new_ip6(u8_t proto)
|
|||
{
|
||||
struct raw_pcb *pcb;
|
||||
pcb = raw_new(proto);
|
||||
if (pcb != NULL) {
|
||||
pcb->isipv6 = 1;
|
||||
}
|
||||
ip_set_v6(pcb, 1);
|
||||
return pcb;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
254
src/core/tcp.c
254
src/core/tcp.c
|
@ -150,17 +150,8 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
|||
|
||||
/* don't call tcp_abort here: we must not deallocate the pcb since
|
||||
that might not be expected when calling tcp_close */
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
tcp_rst_ip6(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip6, &pcb->remote_ip.ip6,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip4, &pcb->remote_ip.ip4,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
|
||||
pcb->local_port, pcb->remote_port, pcb->isipv6);
|
||||
|
||||
tcp_pcb_purge(pcb);
|
||||
|
||||
|
@ -330,8 +321,6 @@ void
|
|||
tcp_abandon(struct tcp_pcb *pcb, int reset)
|
||||
{
|
||||
u32_t seqno, ackno;
|
||||
/*u16_t remote_port, local_port;
|
||||
ip_addr_t remote_ip, local_ip; */
|
||||
#if LWIP_CALLBACK_API
|
||||
tcp_err_fn errf;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
|
@ -349,10 +338,6 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
|||
} else {
|
||||
seqno = pcb->snd_nxt;
|
||||
ackno = pcb->rcv_nxt;
|
||||
/*ip_addr_copy(local_ip, pcb->local_ip.ip4);
|
||||
ip_addr_copy(remote_ip, pcb->remote_ip.ip4);
|
||||
local_port = pcb->local_port;
|
||||
remote_port = pcb->remote_port;*/
|
||||
#if LWIP_CALLBACK_API
|
||||
errf = pcb->errf;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
|
@ -371,15 +356,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
|||
#endif /* TCP_QUEUE_OOSEQ */
|
||||
if (reset) {
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
tcp_rst_ip6(seqno, ackno, &pcb->local_ip.ip6, &pcb->remote_ip.ip6, pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
tcp_rst(seqno, ackno, &pcb->local_ip.ip4, &pcb->remote_ip.ip4, pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, pcb->isipv6);
|
||||
}
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
|
||||
|
@ -452,40 +429,20 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
((cpcb->so_options & SOF_REUSEADDR) == 0))
|
||||
#endif /* SO_REUSE */
|
||||
{
|
||||
if (
|
||||
#if LWIP_IPV6
|
||||
!pcb->isipv6 &&
|
||||
!cpcb->isipv6 &&
|
||||
#endif /* LWIP_IPV6 */
|
||||
(ip_addr_isany(&(cpcb->local_ip.ip4)) ||
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_cmp(&(cpcb->local_ip.ip4), ipaddr))) {
|
||||
/* @todo: check accept_any_ip_version */
|
||||
if (IP_PCB_IPVER_EQ(pcb, cpcb) &&
|
||||
(ipX_addr_isany(PCB_ISIPV6(pcb), &cpcb->local_ip) ||
|
||||
ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr)) ||
|
||||
ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, ip_2_ipX(ipaddr)))) {
|
||||
return ERR_USE;
|
||||
}
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6 &&
|
||||
cpcb->isipv6 &&
|
||||
(ip6_addr_isany(&(cpcb->local_ip.ip6)) ||
|
||||
ip6_addr_isany((ip6_addr_t *)ipaddr) ||
|
||||
ip6_addr_cmp(&(cpcb->local_ip.ip6), (ip6_addr_t *)ipaddr))) {
|
||||
return ERR_USE;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
if (!ip6_addr_isany((ip6_addr_t *)ipaddr)) {
|
||||
ip6_addr_set(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if (!ip_addr_isany(ipaddr)) {
|
||||
pcb->local_ip.ip4 = *ipaddr;
|
||||
if (!ipX_addr_isany(pcb->isipv6, ip_2_ipX(ipaddr))) {
|
||||
ipX_addr_set(pcb->isipv6, &pcb->local_ip, ip_2_ipX(ipaddr));
|
||||
}
|
||||
pcb->local_port = port;
|
||||
TCP_REG(&tcp_bound_pcbs, pcb);
|
||||
|
@ -539,16 +496,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||
is declared (listen-/connection-pcb), we have to make sure now that
|
||||
this port is only used once for every local IP. */
|
||||
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||
if (lpcb->local_port == pcb->local_port) {
|
||||
if ((
|
||||
#if LWIP_IPV6
|
||||
pcb->isipv6 &&
|
||||
lpcb->isipv6 &&
|
||||
ip6_addr_cmp(&lpcb->local_ip.ip6, &pcb->local_ip.ip6)) ||
|
||||
(!pcb->isipv6 &&
|
||||
!lpcb->isipv6 &&
|
||||
#endif /* LWIP_IPV6 */
|
||||
ip_addr_cmp(&lpcb->local_ip.ip4, &pcb->local_ip.ip4))) {
|
||||
if ((lpcb->local_port == pcb->local_port) &&
|
||||
IP_PCB_IPVER_EQ(pcb, lpcb)) {
|
||||
if (ipX_addr_cmp(pcb->isipv6, &lpcb->local_ip, &pcb->local_ip)) {
|
||||
/* this address/port is already used */
|
||||
return NULL;
|
||||
}
|
||||
|
@ -570,14 +520,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||
lpcb->tos = pcb->tos;
|
||||
#if LWIP_IPV6
|
||||
lpcb->isipv6 = pcb->isipv6;
|
||||
if (lpcb->isipv6) {
|
||||
ip6_addr_copy(lpcb->local_ip.ip6, pcb->local_ip.ip6);
|
||||
}
|
||||
else
|
||||
lpcb->accept_any_ip_version = 0;
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
ip_addr_copy(lpcb->local_ip.ip4, pcb->local_ip.ip4);
|
||||
}
|
||||
ipX_addr_copy(pcb->isipv6, lpcb->local_ip, pcb->local_ip);
|
||||
if (pcb->local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
|
@ -593,7 +538,28 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||
return (struct tcp_pcb *)lpcb;
|
||||
}
|
||||
|
||||
/**
|
||||
#if LWIP_IPV6
|
||||
/**
|
||||
* Same as tcp_listen_with_backlog, but allows to accept IPv4 and IPv6
|
||||
* connections, if the pcb's local address is set to ANY.
|
||||
*/
|
||||
struct tcp_pcb *
|
||||
tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
||||
{
|
||||
struct tcp_pcb *lpcb;
|
||||
|
||||
if (!ipX_addr_isany(pcb->isipv6, &pcb->local_ip)) {
|
||||
return NULL;
|
||||
}
|
||||
lpcb = tcp_listen_with_backlog(pcb, backlog);
|
||||
if (lpcb != NULL) {
|
||||
((struct tcp_pcb_listen*)lpcb)->accept_any_ip_version = 1;
|
||||
}
|
||||
return lpcb;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
/**
|
||||
* Update the state that tracks the available window space to advertise.
|
||||
*
|
||||
* Returns how much extra window would be advertised if we sent an
|
||||
|
@ -716,15 +682,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
|
||||
if (ipaddr != NULL) {
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
ip6_addr_set(&pcb->remote_ip.ip6, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
pcb->remote_ip.ip4 = *ipaddr;
|
||||
}
|
||||
ipX_addr_set(PCB_ISIPV6(pcb), &pcb->remote_ip, ip_2_ipX(ipaddr));
|
||||
} else {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
@ -733,38 +691,38 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
/* check if we have a route to the remote host */
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
if (ip6_addr_isany(&(pcb->local_ip.ip6))) {
|
||||
if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) {
|
||||
/* no local IPv6 address set, yet. */
|
||||
ip6_addr_t * local_addr6;
|
||||
struct netif *netif = ip6_route(&(pcb->remote_ip.ip6), &(pcb->remote_ip.ip6));
|
||||
struct netif *netif = ip6_route(ipX_2_ip6(&pcb->remote_ip), ipX_2_ip6(&pcb->remote_ip));
|
||||
if (netif == NULL) {
|
||||
/* Don't even try to send a SYN packet if we have no route
|
||||
since that will fail. */
|
||||
return ERR_RTE;
|
||||
}
|
||||
/* Select and IPv6 address from the netif. */
|
||||
local_addr6 = ip6_select_source_address(netif, &(pcb->remote_ip.ip6));
|
||||
local_addr6 = ip6_select_source_address(netif, ipX_2_ip6(&pcb->remote_ip));
|
||||
if (local_addr6 == NULL) {
|
||||
/* Don't even try to send a SYN packet if we have no suitable
|
||||
source address. */
|
||||
return ERR_RTE;
|
||||
}
|
||||
|
||||
ip6_addr_set(&pcb->local_ip.ip6, local_addr6);
|
||||
ip6_addr_set(ipX_2_ip6(&pcb->local_ip), local_addr6);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if (ip_addr_isany(&(pcb->local_ip.ip4))) {
|
||||
if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) {
|
||||
/* no local IP address set, yet. */
|
||||
struct netif *netif = ip_route(&(pcb->remote_ip.ip4));
|
||||
struct netif *netif = ip_route(ipX_2_ip(&pcb->remote_ip));
|
||||
if (netif == NULL) {
|
||||
/* Don't even try to send a SYN packet if we have no route
|
||||
since that will fail. */
|
||||
return ERR_RTE;
|
||||
}
|
||||
/* Use the netif's IP address as local address. */
|
||||
ip_addr_copy(pcb->local_ip.ip4, netif->ip_addr);
|
||||
ip_addr_copy(*ipX_2_ip(&pcb->local_ip), netif->ip_addr);
|
||||
}
|
||||
|
||||
old_local_port = pcb->local_port;
|
||||
|
@ -782,18 +740,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
|
||||
if ((cpcb->local_port == pcb->local_port) &&
|
||||
(cpcb->remote_port == port) &&
|
||||
#if LWIP_IPV6
|
||||
((cpcb->isipv6 &&
|
||||
pcb->isipv6 &&
|
||||
ip6_addr_cmp(&cpcb->local_ip.ip6, &pcb->local_ip.ip6) &&
|
||||
ip6_addr_cmp(&cpcb->remote_ip.ip6, (ip6_addr_t *)ipaddr)) ||
|
||||
(!cpcb->isipv6 &&
|
||||
!pcb->isipv6 &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
ip_addr_cmp(&cpcb->local_ip.ip4, &pcb->local_ip.ip4) &&
|
||||
ip_addr_cmp(&cpcb->remote_ip.ip4, ipaddr)))) {
|
||||
IP_PCB_IPVER_EQ(cpcb, pcb) &&
|
||||
ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, &pcb->local_ip) &&
|
||||
ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->remote_ip, ip_2_ipX(ipaddr))) {
|
||||
/* linux returns EISCONN here, but ERR_USE should be OK for us */
|
||||
return ERR_USE;
|
||||
}
|
||||
|
@ -814,15 +763,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
The send MSS is updated when an MSS option is received. */
|
||||
pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
|
||||
#if TCP_CALCULATE_EFF_SEND_MSS
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
pcb->mss = tcp_eff_send_mss_ip6(pcb->mss, &pcb->local_ip.ip6, &pcb->remote_ip.ip6);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->remote_ip.ip4);
|
||||
}
|
||||
pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, pcb->isipv6);
|
||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||
pcb->cwnd = 1;
|
||||
pcb->ssthresh = pcb->mss * 10;
|
||||
|
@ -962,11 +903,7 @@ tcp_slowtmr(void)
|
|||
#endif /* LWIP_TCP_KEEPALIVE */
|
||||
{
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to "));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip4);
|
||||
} else {
|
||||
ip6_addr_debug_print(TCP_DEBUG, &pcb->remote_ip.ip6);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, TCP_DEBUG, &pcb->remote_ip);
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("\n"));
|
||||
|
||||
++pcb_remove;
|
||||
|
@ -1032,17 +969,8 @@ tcp_slowtmr(void)
|
|||
|
||||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
|
||||
if (pcb_reset) {
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
tcp_rst_ip6(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip6, &pcb->remote_ip.ip6,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip.ip4, &pcb->remote_ip.ip4,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
|
||||
pcb->local_port, pcb->remote_port, pcb->isipv6);
|
||||
}
|
||||
|
||||
pcb2 = pcb;
|
||||
|
@ -1401,10 +1329,7 @@ tcp_new_ip6(void)
|
|||
{
|
||||
struct tcp_pcb * pcb;
|
||||
pcb = tcp_alloc(TCP_PRIO_NORMAL);
|
||||
/* could allocate TCP PCB? */
|
||||
if (pcb != NULL) {
|
||||
pcb->isipv6 = 1;
|
||||
}
|
||||
ip_set_v6(pcb, 1);
|
||||
return pcb;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
@ -1519,18 +1444,9 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
|
|||
tcp_listen_pcbs.listen_pcbs != NULL);
|
||||
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||
if ((lpcb->local_port == pcb->local_port) &&
|
||||
#if LWIP_IPV6
|
||||
((lpcb->isipv6 &&
|
||||
pcb->isipv6 &&
|
||||
(ip6_addr_isany(&lpcb->local_ip.ip6) ||
|
||||
ip6_addr_cmp(&pcb->local_ip.ip6, &lpcb->local_ip.ip6))) ||
|
||||
(!lpcb->isipv6 &&
|
||||
!pcb->isipv6 &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
(ip_addr_isany(&lpcb->local_ip.ip4) ||
|
||||
ip_addr_cmp(&pcb->local_ip.ip4, &lpcb->local_ip.ip4))))) {
|
||||
IP_PCB_IPVER_EQ(pcb, lpcb) &&
|
||||
(ipX_addr_isany(lpcb->isipv6, &lpcb->local_ip) ||
|
||||
ipX_addr_cmp(lpcb->isipv6, &pcb->local_ip, &lpcb->local_ip))) {
|
||||
/* port and address of the listen pcb match the timed-out pcb */
|
||||
LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
|
||||
lpcb->accepts_pending > 0);
|
||||
|
@ -1629,14 +1545,35 @@ tcp_next_iss(void)
|
|||
* calculating the minimum of TCP_MSS and that netif's mtu (if set).
|
||||
*/
|
||||
u16_t
|
||||
tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
|
||||
tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest
|
||||
#if LWIP_IPV6
|
||||
, ipX_addr_t *src, u8_t isipv6
|
||||
#endif /* LWIP_IPV6 */
|
||||
)
|
||||
{
|
||||
u16_t mss_s;
|
||||
struct netif *outif;
|
||||
s16_t mtu;
|
||||
s16_t iphlen = IP_HLEN;
|
||||
|
||||
outif = ip_route(addr);
|
||||
if ((outif != NULL) && (outif->mtu != 0)) {
|
||||
mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
|
||||
#if LWIP_IPV6
|
||||
if (isipv6) {
|
||||
/* First look in destination cache, to see if there is a Path MTU. */
|
||||
outif = ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest));
|
||||
mtu = nd6_get_destination_mtu(ipX_2_ip6(dest), outif);
|
||||
iphlen = IP6_HLEN;
|
||||
} else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
outif = ip_route(ipX_2_ip(dest));
|
||||
if (outif == NULL) {
|
||||
return sendmss;
|
||||
}
|
||||
mtu = outif->mtu;
|
||||
}
|
||||
|
||||
if (mtu != 0) {
|
||||
mss_s = mtu - iphlen - TCP_HLEN;
|
||||
/* RFC 1122, chap 4.2.2.6:
|
||||
* Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
|
||||
* We correct for TCP options in tcp_write(), and don't support IP options.
|
||||
|
@ -1645,35 +1582,6 @@ tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
|
|||
}
|
||||
return sendmss;
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
/**
|
||||
* Calculates the effective send mss that can be used for a specific IPv6
|
||||
* address by using ip6_route to determine the netif used to send to the
|
||||
* address and calculating the minimum of TCP_MSS and that netif's mtu (if set).
|
||||
*/
|
||||
u16_t
|
||||
tcp_eff_send_mss_ip6(u16_t sendmss, ip6_addr_t *src, ip6_addr_t *dest)
|
||||
{
|
||||
u16_t mss_s;
|
||||
struct netif *outif;
|
||||
s16_t mtu;
|
||||
|
||||
/* First look in destination cache, to see if there is a PAth MTU. */
|
||||
outif = ip6_route(src, dest);
|
||||
mtu = nd6_get_destination_mtu(dest, outif);
|
||||
|
||||
if (mtu != 0) {
|
||||
mss_s = mtu - IP6_HLEN - TCP_HLEN;
|
||||
/* RFC 1122, chap 4.2.2.6:
|
||||
* Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
|
||||
* We correct for TCP options in tcp_write().
|
||||
*/
|
||||
sendmss = LWIP_MIN(sendmss, mss_s);
|
||||
}
|
||||
return sendmss;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||
|
||||
const char*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
476
src/core/udp.c
476
src/core/udp.c
|
@ -57,7 +57,7 @@
|
|||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/ip6.h"
|
||||
#include "lwip/ip6_addr.h"
|
||||
#include "lwip/ip6_chksum.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/icmp.h"
|
||||
#include "lwip/icmp6.h"
|
||||
|
@ -93,6 +93,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
u16_t src, dest;
|
||||
u8_t local_match;
|
||||
u8_t broadcast;
|
||||
u8_t for_us;
|
||||
|
||||
PERF_START;
|
||||
|
||||
|
@ -114,7 +115,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
|
||||
/* is broadcast packet ? */
|
||||
#if LWIP_IPV6
|
||||
broadcast = (ip_current_header() != NULL) && ip_addr_isbroadcast(ip_current_dest_addr(), inp);
|
||||
broadcast = !ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp);
|
||||
#else /* LWIP_IPV6 */
|
||||
broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), inp);
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
@ -129,17 +130,9 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
|
||||
/* print the UDP source and destination */
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp ("));
|
||||
if (ip_current_header() != NULL) {
|
||||
ip_addr_debug_print(UDP_DEBUG, ip_current_dest_addr());
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG, ip6_current_dest_addr());
|
||||
}
|
||||
ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_dest_addr());
|
||||
LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", ntohs(udphdr->dest)));
|
||||
if (ip_current_header() != NULL) {
|
||||
ip_addr_debug_print(UDP_DEBUG, ip_current_src_addr());
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG, ip6_current_src_addr());
|
||||
}
|
||||
ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_src_addr());
|
||||
LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", ntohs(udphdr->src)));
|
||||
|
||||
#if LWIP_DHCP
|
||||
|
@ -152,13 +145,10 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
|
||||
/* accept the packe if
|
||||
(- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY!
|
||||
- inp->dhcp->pcb->remote == ANY or iphdr->src */
|
||||
if (
|
||||
#if LWIP_IPV6
|
||||
!pcb->isipv6 &&
|
||||
#endif /* LWIP_IPV6 */
|
||||
((ip_addr_isany(&inp->dhcp->pcb->remote_ip.ip4) ||
|
||||
ip_addr_cmp(&(inp->dhcp->pcb->remote_ip.ip4), ip_current_src_addr())))) {
|
||||
- inp->dhcp->pcb->remote == ANY or iphdr->src
|
||||
(no need to check for IPv6 since the dhcp struct always uses IPv4) */
|
||||
if (ipX_addr_isany(0, &inp->dhcp->pcb->remote_ip) ||
|
||||
ip_addr_cmp(ipX_2_ip(&(inp->dhcp->pcb->remote_ip)), ip_current_src_addr())) {
|
||||
pcb = inp->dhcp->pcb;
|
||||
}
|
||||
}
|
||||
|
@ -177,36 +167,27 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
local_match = 0;
|
||||
/* print the PCB local and remote address */
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("pcb ("));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(UDP_DEBUG, &pcb->local_ip.ip4);
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG, &pcb->local_ip.ip6);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG, &pcb->local_ip);
|
||||
LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(UDP_DEBUG, &pcb->remote_ip.ip4);
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG, &pcb->remote_ip.ip6);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG, &pcb->remote_ip);
|
||||
LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port));
|
||||
|
||||
/* compare PCB local addr+port to UDP destination addr+port */
|
||||
if ((pcb->local_port == dest) &&
|
||||
#if LWIP_IPV6
|
||||
((pcb->isipv6 &&
|
||||
(ip6_current_header() != NULL) &&
|
||||
(ip6_addr_isany(&pcb->local_ip.ip6) ||
|
||||
((pcb->isipv6 && (ip_current_is_v6()) &&
|
||||
(ip6_addr_isany(ipX_2_ip6(&pcb->local_ip)) ||
|
||||
#if LWIP_IPV6_MLD
|
||||
ip6_addr_ismulticast(ip6_current_dest_addr()) ||
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
ip6_addr_cmp(&pcb->local_ip.ip6, ip6_current_dest_addr()))) ||
|
||||
ip6_addr_cmp(ipX_2_ip6(&pcb->local_ip), ip6_current_dest_addr()))) ||
|
||||
(!pcb->isipv6 &&
|
||||
(ip_current_header() != NULL) &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
((!broadcast && ip_addr_isany(&pcb->local_ip.ip4)) ||
|
||||
ip_addr_cmp(&(pcb->local_ip.ip4), ip_current_dest_addr()) ||
|
||||
((!broadcast && ipX_addr_isany(0, &pcb->local_ip)) ||
|
||||
ip_addr_cmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr()) ||
|
||||
#if LWIP_IGMP
|
||||
ip_addr_ismulticast(ip_current_dest_addr()) ||
|
||||
#endif /* LWIP_IGMP */
|
||||
|
@ -224,19 +205,9 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
}
|
||||
/* compare PCB remote addr+port to UDP source addr+port */
|
||||
if ((local_match != 0) &&
|
||||
(pcb->remote_port == src) &&
|
||||
#if LWIP_IPV6
|
||||
((pcb->isipv6 &&
|
||||
(ip6_current_header() != NULL) &&
|
||||
(ip6_addr_isany(&pcb->remote_ip.ip6) ||
|
||||
ip6_addr_cmp(&pcb->remote_ip.ip6, ip6_current_src_addr()))) ||
|
||||
(!pcb->isipv6 &&
|
||||
(ip_current_header() != NULL) &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
((ip_addr_isany(&pcb->remote_ip.ip4) ||
|
||||
ip_addr_cmp(&(pcb->remote_ip.ip4), ip_current_src_addr())))))) {
|
||||
(pcb->remote_port == src) && IP_PCB_IPVER_INPUT_MATCH(pcb) &&
|
||||
(ipX_addr_isany(pcb->isipv6, &pcb->remote_ip) ||
|
||||
ipX_addr_cmp(pcb->isipv6, &pcb->remote_ip, ipX_current_src_addr()))) {
|
||||
/* the first fully matching PCB */
|
||||
if (prev != NULL) {
|
||||
/* move the pcb to the front of udp_pcbs so that is
|
||||
|
@ -258,28 +229,24 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
}
|
||||
|
||||
/* Check checksum if this is a match or if it was directed at us. */
|
||||
if ((pcb != NULL) ||
|
||||
if (pcb != NULL) {
|
||||
for_us = 1;
|
||||
} else {
|
||||
#if LWIP_IPV6
|
||||
((ip6_current_header() != NULL) &&
|
||||
netif_matches_ip6_addr(inp, ip6_current_dest_addr())) ||
|
||||
((ip_current_header() != NULL) &&
|
||||
#else /* LWIP_IPV6 */
|
||||
(
|
||||
if (ip_current_is_v6()) {
|
||||
for_us = netif_matches_ip6_addr(inp, ip6_current_dest_addr());
|
||||
} else
|
||||
#endif /* LWIP_IPV6 */
|
||||
ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr()))) {
|
||||
{
|
||||
for_us = ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr());
|
||||
}
|
||||
}
|
||||
if (for_us) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
|
||||
#if LWIP_UDPLITE
|
||||
if (
|
||||
#if LWIP_IPV6
|
||||
((ip6_current_header() != NULL) &&
|
||||
(IP6H_NEXTH(ip6_current_header()) == IP_PROTO_UDPLITE)) ||
|
||||
((ip_current_header() != NULL) &&
|
||||
#else /* LWIP_IPV6 */
|
||||
(
|
||||
#endif /* LWIP_IPV6 */
|
||||
(IPH_PROTO(iphdr) == IP_PROTO_UDPLITE))) {
|
||||
/* Do the UDP Lite checksum */
|
||||
#if CHECKSUM_CHECK_UDP
|
||||
#if LWIP_UDPLITE
|
||||
if (ip_current_header_proto() == IP_PROTO_UDPLITE) {
|
||||
/* Do the UDP Lite checksum */
|
||||
u16_t chklen = ntohs(udphdr->len);
|
||||
if (chklen < sizeof(struct udp_hdr)) {
|
||||
if (chklen == 0) {
|
||||
|
@ -289,72 +256,26 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
} else {
|
||||
/* At least the UDP-Lite header must be covered by the
|
||||
checksum! (Again, see RFC 3828 chap. 3.1) */
|
||||
UDP_STATS_INC(udp.chkerr);
|
||||
UDP_STATS_INC(udp.drop);
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
goto chkerr;
|
||||
}
|
||||
}
|
||||
#if LWIP_IPV6
|
||||
if (ip6_current_header() != NULL) {
|
||||
if (ip6_chksum_pseudo_partial(p, ip6_current_src_addr(), ip6_current_dest_addr(),
|
||||
IP6_NEXTH_UDPLITE, p->tot_len, chklen) != 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
|
||||
UDP_STATS_INC(udp.chkerr);
|
||||
UDP_STATS_INC(udp.drop);
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
if (ipX_chksum_pseudo_partial(ip_current_is_v6(), p, IP_PROTO_UDPLITE,
|
||||
p->tot_len, chklen,
|
||||
ipX_current_src_addr(), ipX_current_dest_addr()) != 0) {
|
||||
goto chkerr;
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if (inet_chksum_pseudo_partial(p, ip_current_src_addr(), ip_current_dest_addr(),
|
||||
IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
|
||||
UDP_STATS_INC(udp.chkerr);
|
||||
UDP_STATS_INC(udp.drop);
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
#endif /* CHECKSUM_CHECK_UDP */
|
||||
} else
|
||||
#endif /* LWIP_UDPLITE */
|
||||
{
|
||||
#if CHECKSUM_CHECK_UDP
|
||||
if (udphdr->chksum != 0) {
|
||||
#if LWIP_IPV6
|
||||
if (ip6_current_header() != NULL) {
|
||||
if (ip6_chksum_pseudo(p, ip6_current_src_addr(), ip6_current_dest_addr(),
|
||||
IP6_NEXTH_UDP, p->tot_len) != 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("udp_input: UDP datagram discarded due to failing checksum\n"));
|
||||
UDP_STATS_INC(udp.chkerr);
|
||||
UDP_STATS_INC(udp.drop);
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
|
||||
IP_PROTO_UDP, p->tot_len) != 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("udp_input: UDP datagram discarded due to failing checksum\n"));
|
||||
UDP_STATS_INC(udp.chkerr);
|
||||
UDP_STATS_INC(udp.drop);
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
if (ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_UDP, p->tot_len,
|
||||
ipX_current_src_addr(),
|
||||
ipX_current_dest_addr()) != 0) {
|
||||
goto chkerr;
|
||||
}
|
||||
}
|
||||
#endif /* CHECKSUM_CHECK_UDP */
|
||||
}
|
||||
#endif /* CHECKSUM_CHECK_UDP */
|
||||
if(pbuf_header(p, -UDP_HLEN)) {
|
||||
/* Can we cope with this failing? Just assert for now */
|
||||
LWIP_ASSERT("pbuf_header failed\n", 0);
|
||||
|
@ -376,15 +297,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
if SOF_REUSEADDR is set on the first match */
|
||||
struct udp_pcb *mpcb;
|
||||
u8_t p_header_changed = 0;
|
||||
s16_t hdrs_len;
|
||||
#if LWIP_IPV6
|
||||
if (ip6_current_header() != NULL) {
|
||||
hdrs_len = (s16_t)(ip6_current_header_tot_len() + UDP_HLEN);
|
||||
} else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
hdrs_len = (s16_t)((IPH_HL(ip_current_header()) * 4) + UDP_HLEN);
|
||||
}
|
||||
s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN);
|
||||
for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) {
|
||||
if (mpcb != pcb) {
|
||||
/* compare PCB local addr+port to UDP destination addr+port */
|
||||
|
@ -392,13 +305,13 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
#if LWIP_IPV6
|
||||
((mpcb->isipv6 &&
|
||||
(ip6_addr_ismulticast(ip6_current_dest_addr()) ||
|
||||
ip6_addr_cmp(&mpcb->local_ip.ip6, ip6_current_dest_addr()))) ||
|
||||
ip6_addr_cmp(ipX_2_ip6(&mpcb->local_ip), ip6_current_dest_addr()))) ||
|
||||
(!mpcb->isipv6 &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
((!broadcast && ip_addr_isany(&mpcb->local_ip.ip4)) ||
|
||||
ip_addr_cmp(&(mpcb->local_ip.ip4), ip_current_dest_addr()) ||
|
||||
((!broadcast && ipX_addr_isany(0, &mpcb->local_ip)) ||
|
||||
ip_addr_cmp(ipX_2_ip(&mpcb->local_ip), ip_current_dest_addr()) ||
|
||||
#if LWIP_IGMP
|
||||
ip_addr_ismulticast(ip_current_dest_addr()) ||
|
||||
#endif /* LWIP_IGMP */
|
||||
|
@ -470,23 +383,9 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
!ip6_addr_ismulticast(ip6_current_dest_addr()) &&
|
||||
#endif /* LWIP_IPV6 */
|
||||
!ip_addr_ismulticast(ip_current_dest_addr())) {
|
||||
#if LWIP_IPV6 && LWIP_ICMP6
|
||||
if (ip6_current_header() != NULL) {
|
||||
/* move payload pointer back to ip header */
|
||||
pbuf_header(p, ip6_current_header_tot_len() + UDP_HLEN);
|
||||
LWIP_ASSERT("p->payload == ip6_current_header()", (p->payload == ip6_current_header()));
|
||||
icmp6_dest_unreach(p, ICMP6_DUR_PORT);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 && LWIP_ICMP6 */
|
||||
{
|
||||
#if LWIP_ICMP
|
||||
/* move payload pointer back to ip header */
|
||||
pbuf_header(p, (IPH_HL(ip_current_header()) * 4) + UDP_HLEN);
|
||||
LWIP_ASSERT("p->payload == ip_current_header()", (p->payload == ip_current_header()));
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif /* LWIP_ICMP */
|
||||
}
|
||||
/* move payload pointer back to ip header */
|
||||
pbuf_header(p, ip_current_header_tot_len() + UDP_HLEN);
|
||||
icmp_port_unreach(ip_current_is_v6(), p);
|
||||
}
|
||||
#endif /* LWIP_ICMP || LWIP_ICMP6 */
|
||||
UDP_STATS_INC(udp.proterr);
|
||||
|
@ -499,6 +398,15 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||
}
|
||||
end:
|
||||
PERF_STOP("udp_input");
|
||||
return;
|
||||
chkerr:
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n"));
|
||||
UDP_STATS_INC(udp.chkerr);
|
||||
UDP_STATS_INC(udp.drop);
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
PERF_STOP("udp_input");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -523,7 +431,7 @@ err_t
|
|||
udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
{
|
||||
/* send to the packet using remote ip and port stored in the pcb */
|
||||
return udp_sendto(pcb, p, &pcb->remote_ip.ip4, pcb->remote_port);
|
||||
return udp_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port);
|
||||
}
|
||||
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
|
@ -534,7 +442,7 @@ udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
|
|||
u8_t have_chksum, u16_t chksum)
|
||||
{
|
||||
/* send to the packet using remote ip and port stored in the pcb */
|
||||
return udp_sendto_chksum(pcb, p, &pcb->remote_ip.ip4, pcb->remote_port,
|
||||
return udp_sendto_chksum(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port,
|
||||
have_chksum, chksum);
|
||||
}
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY */
|
||||
|
@ -577,12 +485,12 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
/* find the outgoing network interface for this packet */
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
if (ip6_addr_ismulticast((ip6_addr_t *)dst_ip)) {
|
||||
if (ip6_addr_ismulticast(ip_2_ip6(dst_ip))) {
|
||||
/* For multicast, find a netif based on source address. */
|
||||
netif = ip6_route(&(pcb->local_ip.ip6), &(pcb->local_ip.ip6));
|
||||
netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ipX_2_ip6(&pcb->local_ip));
|
||||
}
|
||||
else {
|
||||
netif = ip6_route(&(pcb->local_ip.ip6), (ip6_addr_t *)dst_ip);
|
||||
netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ip_2_ip6(dst_ip));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -598,11 +506,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
/* no outgoing network interface could be found? */
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to "));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip);
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, (ip6_addr_t *)dst_ip);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ip_2_ipX(dst_ip));
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("\n"));
|
||||
UDP_STATS_INC(udp.rterr);
|
||||
return ERR_RTE;
|
||||
|
@ -652,6 +556,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
ip_addr_t *src_ip;
|
||||
err_t err;
|
||||
struct pbuf *q; /* q will be sent down the stack */
|
||||
u8_t ip_proto;
|
||||
|
||||
#if IP_SOF_BROADCAST
|
||||
/* broadcast filter? */
|
||||
|
@ -669,7 +574,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
/* if the PCB is not yet bound to a port, bind it here */
|
||||
if (pcb->local_port == 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
|
||||
err = udp_bind(pcb, &pcb->local_ip.ip4, pcb->local_port);
|
||||
err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port);
|
||||
if (err != ERR_OK) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
|
||||
return err;
|
||||
|
@ -714,7 +619,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
(
|
||||
#if LWIP_IPV6_MLD
|
||||
(pcb->isipv6 &&
|
||||
ip6_addr_ismulticast((ip6_addr_t*)dst_ip)) ||
|
||||
ip6_addr_ismulticast(ip_2_ip6(dst_ip))) ||
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
(!pcb->isipv6 &&
|
||||
#else /* LWIP_IPV6 */
|
||||
|
@ -729,8 +634,8 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
/* PCB local address is IP_ANY_ADDR? */
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
if (ip6_addr_isany(&pcb->local_ip.ip6)) {
|
||||
src_ip =(ip_addr_t *)ip6_select_source_address(netif, (ip6_addr_t *)dst_ip);
|
||||
if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) {
|
||||
src_ip = ip6_2_ip(ip6_select_source_address(netif, ip_2_ip6(dst_ip)));
|
||||
if (src_ip == NULL) {
|
||||
/* No suitable source address was found. */
|
||||
if (q != p) {
|
||||
|
@ -742,7 +647,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
}
|
||||
} else {
|
||||
/* use UDP PCB local IPv6 address as source address, if still valid. */
|
||||
if (netif_matches_ip6_addr(netif, &(pcb->local_ip.ip6)) < 0) {
|
||||
if (netif_matches_ip6_addr(netif, ipX_2_ip6(&pcb->local_ip)) < 0) {
|
||||
/* Address isn't valid anymore. */
|
||||
if (q != p) {
|
||||
/* free the header pbuf */
|
||||
|
@ -751,18 +656,18 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
}
|
||||
return ERR_RTE;
|
||||
}
|
||||
src_ip = (ip_addr_t *)&(pcb->local_ip.ip6);
|
||||
src_ip = ipX_2_ip(&pcb->local_ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
if (ip_addr_isany(&pcb->local_ip.ip4)) {
|
||||
if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) {
|
||||
/* use outgoing network interface IP address as source address */
|
||||
src_ip = &(netif->ip_addr);
|
||||
} else {
|
||||
/* check if UDP PCB local IP address is correct
|
||||
* this could be an old address if netif->ip_addr has changed */
|
||||
if (!ip_addr_cmp(&(pcb->local_ip.ip4), &(netif->ip_addr))) {
|
||||
if (!ip_addr_cmp(ipX_2_ip(&(pcb->local_ip)), &(netif->ip_addr))) {
|
||||
/* local_ip doesn't match, drop the packet */
|
||||
if (q != p) {
|
||||
/* free the header pbuf */
|
||||
|
@ -773,7 +678,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
return ERR_VAL;
|
||||
}
|
||||
/* use UDP PCB local IP address as source address */
|
||||
src_ip = &(pcb->local_ip.ip4);
|
||||
src_ip = ipX_2_ip(&(pcb->local_ip));
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
|
||||
|
@ -800,88 +705,51 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
}
|
||||
udphdr->len = htons(chklen_hdr);
|
||||
/* calculate checksum */
|
||||
#if LWIP_IPV6
|
||||
/* Checksum is mandatory for IPv6. */
|
||||
if (pcb->isipv6) {
|
||||
udphdr->chksum = ip6_chksum_pseudo_partial(q, (ip6_addr_t *)src_ip, (ip6_addr_t *)dst_ip,
|
||||
IP6_NEXTH_UDPLITE, q->tot_len,
|
||||
#if !LWIP_CHECKSUM_ON_COPY
|
||||
chklen);
|
||||
#else /* !LWIP_CHECKSUM_ON_COPY */
|
||||
(have_chksum ? UDP_HLEN : chklen));
|
||||
if (have_chksum) {
|
||||
u32_t acc;
|
||||
acc = udphdr->chksum + (u16_t)~(chksum);
|
||||
udphdr->chksum = FOLD_U32T(acc);
|
||||
}
|
||||
#endif /* !LWIP_CHECKSUM_ON_COPY */
|
||||
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000) {
|
||||
udphdr->chksum = 0xffff;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
#if CHECKSUM_GEN_UDP
|
||||
udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip,
|
||||
IP_PROTO_UDPLITE, q->tot_len,
|
||||
#if !LWIP_CHECKSUM_ON_COPY
|
||||
chklen);
|
||||
#else /* !LWIP_CHECKSUM_ON_COPY */
|
||||
(have_chksum ? UDP_HLEN : chklen));
|
||||
if (have_chksum) {
|
||||
u32_t acc;
|
||||
acc = udphdr->chksum + (u16_t)~(chksum);
|
||||
udphdr->chksum = FOLD_U32T(acc);
|
||||
}
|
||||
#endif /* !LWIP_CHECKSUM_ON_COPY */
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
if (have_chksum) {
|
||||
chklen = UDP_HLEN;
|
||||
}
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY */
|
||||
udphdr->chksum = ipX_chksum_pseudo_partial(pcb->isipv6, q, IP_PROTO_UDPLITE,
|
||||
q->tot_len, chklen, ip_2_ipX(src_ip), ip_2_ipX(dst_ip));
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
if (have_chksum) {
|
||||
u32_t acc;
|
||||
acc = udphdr->chksum + (u16_t)~(chksum);
|
||||
udphdr->chksum = FOLD_U32T(acc);
|
||||
}
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY */
|
||||
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000) {
|
||||
udphdr->chksum = 0xffff;
|
||||
}
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000) {
|
||||
udphdr->chksum = 0xffff;
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_UDP */
|
||||
}
|
||||
/* output to IP */
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
err = ip6_output_if(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, pcb->ttl, pcb->tos, IP6_NEXTH_UDPLITE, netif);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
||||
}
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
|
||||
ip_proto = IP_PROTO_UDPLITE;
|
||||
} else
|
||||
#endif /* LWIP_UDPLITE */
|
||||
{ /* UDP */
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
|
||||
udphdr->len = htons(q->tot_len);
|
||||
/* calculate checksum */
|
||||
#if LWIP_IPV6
|
||||
#if CHECKSUM_GEN_UDP
|
||||
/* Checksum is mandatory over IPv6. */
|
||||
if (pcb->isipv6) {
|
||||
if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
|
||||
u16_t udpchksum;
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
if (have_chksum) {
|
||||
u32_t acc;
|
||||
udpchksum = ip6_chksum_pseudo_partial(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, IP6_NEXTH_UDP,
|
||||
q->tot_len, UDP_HLEN);
|
||||
udpchksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDP,
|
||||
q->tot_len, UDP_HLEN, ip_2_ipX(src_ip), ip_2_ipX(dst_ip));
|
||||
acc = udpchksum + (u16_t)~(chksum);
|
||||
udpchksum = FOLD_U32T(acc);
|
||||
} else
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY */
|
||||
{
|
||||
udpchksum = ip6_chksum_pseudo(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, IP6_NEXTH_UDP, q->tot_len);
|
||||
udpchksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, q->tot_len,
|
||||
ip_2_ipX(src_ip), ip_2_ipX(dst_ip));
|
||||
}
|
||||
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
|
@ -890,52 +758,17 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
}
|
||||
udphdr->chksum = udpchksum;
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
#if CHECKSUM_GEN_UDP
|
||||
if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
|
||||
u16_t udpchksum;
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
if (have_chksum) {
|
||||
u32_t acc;
|
||||
udpchksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, IP_PROTO_UDP,
|
||||
q->tot_len, UDP_HLEN);
|
||||
acc = udpchksum + (u16_t)~(chksum);
|
||||
udpchksum = FOLD_U32T(acc);
|
||||
} else
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY */
|
||||
{
|
||||
udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len);
|
||||
}
|
||||
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udpchksum == 0x0000) {
|
||||
udpchksum = 0xffff;
|
||||
}
|
||||
udphdr->chksum = udpchksum;
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_UDP */
|
||||
}
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
||||
/* output to IP */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
err = ip6_output_if(q, (ip6_addr_t*)src_ip, (ip6_addr_t*)dst_ip, pcb->ttl, pcb->tos, IP6_NEXTH_UDP, netif);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
||||
}
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
ip_proto = IP_PROTO_UDP;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto));
|
||||
/* output to IP */
|
||||
NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
|
||||
err = ipX_output_if(pcb->isipv6, q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif);
|
||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||
|
||||
/* TODO: must this be increased even if error occured? */
|
||||
snmp_inc_udpoutdatagrams();
|
||||
|
||||
|
@ -977,11 +810,7 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
u8_t rebind;
|
||||
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr);
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_TRACE, ip_2_ipX(ipaddr));
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
|
||||
|
||||
rebind = 0;
|
||||
|
@ -1005,22 +834,11 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
/* port matches that of PCB in list and REUSEADDR not set -> reject */
|
||||
else {
|
||||
#endif /* SO_REUSE */
|
||||
if ((ipcb->local_port == port) &&
|
||||
if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) &&
|
||||
/* IP address matches, or one is IP_ADDR_ANY? */
|
||||
#if LWIP_IPV6
|
||||
((pcb->isipv6 &&
|
||||
ipcb->isipv6 &&
|
||||
(ip6_addr_isany(&(ipcb->local_ip.ip6)) ||
|
||||
ip6_addr_isany((ip6_addr_t *)ipaddr) ||
|
||||
ip6_addr_cmp(&(ipcb->local_ip.ip6), (ip6_addr_t *)ipaddr))) ||
|
||||
(!pcb->isipv6 &&
|
||||
!ipcb->isipv6 &&
|
||||
#else /* LWIP_IPV6 */
|
||||
((
|
||||
#endif /* LWIP_IPV6 */
|
||||
(ip_addr_isany(&(ipcb->local_ip.ip4)) ||
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_cmp(&(ipcb->local_ip.ip4), ipaddr))))) {
|
||||
(ipX_addr_isany(ipcb->isipv6, &(ipcb->local_ip)) ||
|
||||
ipX_addr_isany(ipcb->isipv6, ip_2_ipX(ipaddr)) ||
|
||||
ipX_addr_cmp(ipcb->isipv6, &(ipcb->local_ip), ip_2_ipX(ipaddr)))) {
|
||||
/* other PCB already binds to this local IP and port */
|
||||
LWIP_DEBUGF(UDP_DEBUG,
|
||||
("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
|
||||
|
@ -1029,15 +847,7 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
}
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
ip6_addr_set(&pcb->local_ip.ip6, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
ip_addr_set(&pcb->local_ip.ip4, ipaddr);
|
||||
}
|
||||
ipX_addr_set_ipaddr(pcb->isipv6, &pcb->local_ip, ipaddr);
|
||||
|
||||
/* no port specified? */
|
||||
if (port == 0) {
|
||||
|
@ -1075,14 +885,11 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
udp_pcbs = pcb;
|
||||
}
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to "));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip.ip4);
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip.ip6);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip);
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port));
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect an UDP PCB.
|
||||
*
|
||||
|
@ -1106,21 +913,13 @@ udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
struct udp_pcb *ipcb;
|
||||
|
||||
if (pcb->local_port == 0) {
|
||||
err_t err = udp_bind(pcb, &pcb->local_ip.ip4, pcb->local_port);
|
||||
err_t err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port);
|
||||
if (err != ERR_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
ip6_addr_set(&pcb->remote_ip.ip6, (ip6_addr_t *)ipaddr);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
ip_addr_set(&pcb->remote_ip.ip4, ipaddr);
|
||||
}
|
||||
ipX_addr_set_ipaddr(pcb->isipv6, &pcb->remote_ip, ipaddr);
|
||||
pcb->remote_port = port;
|
||||
pcb->flags |= UDP_FLAGS_CONNECTED;
|
||||
/** TODO: this functionality belongs in upper layers */
|
||||
|
@ -1130,29 +929,27 @@ udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
/* Nail down local IP for netconn_addr()/getsockname() */
|
||||
if (ip_addr_isany(&pcb->local_ip.ip4) && !ip_addr_isany(&pcb->remote_ip.ip4)) {
|
||||
if (ip_addr_isany(ipX_2_ip(&pcb->local_ip)) && !ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) {
|
||||
struct netif *netif;
|
||||
|
||||
if ((netif = ip_route(&(pcb->remote_ip.ip4))) == NULL) {
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.ip4.addr));
|
||||
if ((netif = ip_route(ipX_2_ip(&pcb->remote_ip))) == NULL) {
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n",
|
||||
ip4_addr_get_u32(ipX_2_ip(&pcb->remote_ip))));
|
||||
UDP_STATS_INC(udp.rterr);
|
||||
return ERR_RTE;
|
||||
}
|
||||
/** TODO: this will bind the udp pcb locally, to the interface which
|
||||
is used to route output packets to the remote address. However, we
|
||||
might want to accept incoming packets on any interface! */
|
||||
pcb->local_ip.ip4 = netif->ip_addr;
|
||||
} else if (ip_addr_isany(&pcb->remote_ip.ip4)) {
|
||||
pcb->local_ip.ip4.addr = 0;
|
||||
ipX_addr_copy(0, pcb->local_ip, netif->ip_addr);
|
||||
} else if (ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) {
|
||||
ipX_addr_set_any(0, &pcb->local_ip);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to "));
|
||||
if (!pcb->isipv6) {
|
||||
ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->remote_ip.ip4);
|
||||
} else {
|
||||
ip6_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->remote_ip.ip6);
|
||||
}
|
||||
ipX_addr_debug_print(pcb->isipv6, UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
&pcb->remote_ip);
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port));
|
||||
|
||||
/* Insert UDP PCB into the list of active UDP PCBs. */
|
||||
|
@ -1177,15 +974,7 @@ void
|
|||
udp_disconnect(struct udp_pcb *pcb)
|
||||
{
|
||||
/* reset remote address association */
|
||||
#if LWIP_IPV6
|
||||
if (pcb->isipv6) {
|
||||
ip6_addr_set_any(&pcb->remote_ip.ip6);
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_IPV6 */
|
||||
{
|
||||
ip_addr_set_any(&pcb->remote_ip.ip4);
|
||||
}
|
||||
ipX_addr_set_any(pcb->isipv6, &pcb->remote_ip);
|
||||
pcb->remote_port = 0;
|
||||
/* mark PCB as unconnected */
|
||||
pcb->flags &= ~UDP_FLAGS_CONNECTED;
|
||||
|
@ -1278,10 +1067,7 @@ udp_new_ip6(void)
|
|||
{
|
||||
struct udp_pcb *pcb;
|
||||
pcb = udp_new();
|
||||
/* could allocate UDP PCB? */
|
||||
if (pcb != NULL) {
|
||||
pcb->isipv6 = 1;
|
||||
}
|
||||
ip_set_v6(pcb, 1);
|
||||
return pcb;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() (¤t_iphdr_src)
|
||||
/** Destination IP address of current_header */
|
||||
#define ip_current_dest_addr() (¤t_iphdr_dest)
|
||||
|
||||
#if IP_DEBUG
|
||||
void ip_debug_print(struct pbuf *p);
|
|
@ -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"
|
|
@ -71,15 +71,6 @@ extern "C" {
|
|||
#define IP6_NEXTH_UDPLITE 136
|
||||
|
||||
|
||||
/* This is passed as the destination address to ip6_output_if (not
|
||||
to ip6_output), meaning that an IP header already is constructed
|
||||
in the pbuf. This is used when TCP retransmits. */
|
||||
#ifdef IP6_HDRINCL
|
||||
#undef IP6_HDRINCL
|
||||
#endif /* IP6_HDRINCL */
|
||||
#define IP6_HDRINCL NULL
|
||||
|
||||
|
||||
/* The IPv6 header. */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
|
@ -171,16 +162,6 @@ PACK_STRUCT_END
|
|||
#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl)
|
||||
|
||||
|
||||
|
||||
/** Header of the input IPv6 packet currently being processed. */
|
||||
extern const struct ip6_hdr *current_ip6_header;
|
||||
/** Total header length of current_ip6_header (i.e. after this, the UDP/TCP header starts) */
|
||||
extern u16_t current_ip6_header_tot_len;
|
||||
/** Source IPv6 address of current_header */
|
||||
extern ip6_addr_t current_ip6hdr_src;
|
||||
/** Destination IPv6 address of current_header */
|
||||
extern ip6_addr_t current_ip6hdr_dest;
|
||||
|
||||
#define ip6_init() /* TODO should we init current addresses and header pointer? */
|
||||
struct netif *ip6_route(struct ip6_addr *src, struct ip6_addr *dest);
|
||||
ip6_addr_t *ip6_select_source_address(struct netif *netif, ip6_addr_t * dest);
|
||||
|
@ -198,17 +179,6 @@ err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value);
|
|||
#endif /* LWIP_IPV6_MLD */
|
||||
|
||||
|
||||
/** Get the IPv6 header of the current packet.
|
||||
* This function must only be called from a receive callback (udp_recv,
|
||||
* raw_recv, tcp_accept). It will return NULL otherwise. */
|
||||
#define ip6_current_header() (current_ip6_header)
|
||||
/** Total header length of current_ip6_header (i.e. after this, the UDP/TCP header starts) */
|
||||
#define ip6_current_header_tot_len() (current_ip6_header_tot_len)
|
||||
/** Source IPv6 address of current_header */
|
||||
#define ip6_current_src_addr() (¤t_ip6hdr_src)
|
||||
/** Destination IPv6 address of current_header */
|
||||
#define ip6_current_dest_addr() (¤t_ip6hdr_dest)
|
||||
|
||||
#if IP6_DEBUG
|
||||
void ip6_debug_print(struct pbuf *p);
|
||||
#else
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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__ */
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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
230
src/include/lwip/ip.h
Normal 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
127
src/include/lwip/ip_addr.h
Normal 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__ */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user