diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-01-15 15:06:46 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-01-15 15:06:46 -0600 |
commit | 079bdbfc29756407b681107b83dc2a7aa122de86 (patch) | |
tree | f4a290f1a94786c799f0830bda6b80bd2f8b2ab2 | |
parent | fe80c662f25081c8d2c9df8797af2dc89ead2f64 (diff) | |
download | px4-nuttx-079bdbfc29756407b681107b83dc2a7aa122de86.tar.gz px4-nuttx-079bdbfc29756407b681107b83dc2a7aa122de86.tar.bz2 px4-nuttx-079bdbfc29756407b681107b83dc2a7aa122de86.zip |
Networking: Seperate tcp_input() and udp_input() into seprate functions tcp_ipv4_input(), tcp_ipv6_input(), udp_ipv4_input(), and upd_ipv6_input() than can deal will the data offsets caused by the differing sizes of the IP header.
-rw-r--r-- | nuttx/include/nuttx/net/netconfig.h | 20 | ||||
-rw-r--r-- | nuttx/include/nuttx/net/tcp.h | 25 | ||||
-rw-r--r-- | nuttx/include/nuttx/net/udp.h | 21 | ||||
-rw-r--r-- | nuttx/net/devif/ipv4_input.c | 6 | ||||
-rw-r--r-- | nuttx/net/devif/ipv6_input.c | 4 | ||||
-rw-r--r-- | nuttx/net/pkt/pkt_poll.c | 4 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp.h | 107 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_appsend.c | 8 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_conn.c | 62 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_input.c | 188 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_poll.c | 4 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_send.c | 4 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_timer.c | 8 | ||||
-rw-r--r-- | nuttx/net/udp/udp.h | 52 | ||||
-rw-r--r-- | nuttx/net/udp/udp_conn.c | 22 | ||||
-rw-r--r-- | nuttx/net/udp/udp_input.c | 97 | ||||
-rw-r--r-- | nuttx/net/udp/udp_poll.c | 4 | ||||
-rw-r--r-- | nuttx/net/udp/udp_send.c | 2 |
18 files changed, 438 insertions, 200 deletions
diff --git a/nuttx/include/nuttx/net/netconfig.h b/nuttx/include/nuttx/net/netconfig.h index cc582e497..9df3a6f2c 100644 --- a/nuttx/include/nuttx/net/netconfig.h +++ b/nuttx/include/nuttx/net/netconfig.h @@ -211,21 +211,21 @@ #endif /* The UDP maximum packet size. This is should not be to set to more - * than NET_DEV_MTU(d) - NET_LL_HDRLEN(dev) - IPUDP_HDRLEN. + * than NET_DEV_MTU(d) - NET_LL_HDRLEN(dev) - IPv4UDP_HDRLEN. */ -#define UDP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPUDP_HDRLEN) +#define UDP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPv4UDP_HDRLEN) #ifdef CONFIG_NET_ETHERNET -# define MIN_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPUDP_HDRLEN) +# define MIN_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPv4UDP_HDRLEN) #else /* if defined(CONFIG_NET_SLIP) */ -# define MIN_UDP_MSS (CONFIG_NET_SLIP_MTU - IPUDP_HDRLEN) +# define MIN_UDP_MSS (CONFIG_NET_SLIP_MTU - IPv4UDP_HDRLEN) #endif #ifdef CONFIG_NET_SLIP -# define MAX_UDP_MSS (CONFIG_NET_SLIP_MTU - IPUDP_HDRLEN) +# define MAX_UDP_MSS (CONFIG_NET_SLIP_MTU - IPv4UDP_HDRLEN) #else /* if defined(CONFIG_NET_ETHERNET) */ -# define MAX_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPUDP_HDRLEN) +# define MAX_UDP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPv4UDP_HDRLEN) #endif /* TCP configuration options */ @@ -288,7 +288,7 @@ #define TCP_MAXSYNRTX 5 /* The TCP maximum segment size. This is should not be set to more - * than NET_DEV_MTU(dev) - NET_LL_HDRLEN(dev) - IPTCP_HDRLEN. + * than NET_DEV_MTU(dev) - NET_LL_HDRLEN(dev) - IPv4TCP_HDRLEN. * * In the case where there are multiple network devices with different * link layer protocols (CONFIG_NET_MULTILINK), each network device @@ -296,13 +296,13 @@ * the minimum MSS for that case. */ -#define TCP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPTCP_HDRLEN) +#define TCP_MSS(d) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - IPv4TCP_HDRLEN) #ifdef CONFIG_NET_ETHERNET -# define ETH_TCP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPTCP_HDRLEN) +# define ETH_TCP_MSS (CONFIG_NET_ETH_MTU - ETH_HDRLEN - IPv4TCP_HDRLEN) # define MIN_TCP_MSS ETH_TCP_MSS #elif defined(CONFIG_NET_SLIP) -# define SLIP_TCP_MSS (CONFIG_NET_SLIP_MTU - IPTCP_HDRLEN) +# define SLIP_TCP_MSS (CONFIG_NET_SLIP_MTU - IPv4TCP_HDRLEN) # define MIN_TCP_MSS SLIP_TCP_MSS #endif diff --git a/nuttx/include/nuttx/net/tcp.h b/nuttx/include/nuttx/net/tcp.h index 146451ce2..db5ef37da 100644 --- a/nuttx/include/nuttx/net/tcp.h +++ b/nuttx/include/nuttx/net/tcp.h @@ -98,7 +98,14 @@ /* TCP header sizes */ #define TCP_HDRLEN 20 /* Size of TCP header */ -#define IPTCP_HDRLEN (TCP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + TCP header */ + +#ifdef CONFIG_NET_IPv4 +# define IPv4TCP_HDRLEN (TCP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + TCP header */ +#endif + +#ifdef CONFIG_NET_IPv4 +# define IPv6TCP_HDRLEN (TCP_HDRLEN + IPv6_HDRLEN) /* Size of IPv4 + TCP header */ +#endif /* Initial minimum MSS according to RFC 879 * @@ -121,6 +128,22 @@ * Public Type Definitions ****************************************************************************/ +/* TCP header */ + +struct tcp_hdr_s +{ + uint16_t srcport; + uint16_t destport; + uint8_t seqno[4]; + uint8_t ackno[4]; + uint8_t tcpoffset; + uint8_t flags; + uint8_t wnd[2]; + uint16_t tcpchksum; + uint8_t urgp[2]; + uint8_t optdata[4]; +}; + /* The TCP and IP headers */ #ifdef CONFIG_NET_IPv4 diff --git a/nuttx/include/nuttx/net/udp.h b/nuttx/include/nuttx/net/udp.h index 0032034c9..b8c1c9b0e 100644 --- a/nuttx/include/nuttx/net/udp.h +++ b/nuttx/include/nuttx/net/udp.h @@ -62,13 +62,30 @@ /* Header sizes */ -#define UDP_HDRLEN 8 /* Size of UDP header */ -#define IPUDP_HDRLEN (UDP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + UDP header */ +#define UDP_HDRLEN 8 /* Size of UDP header */ + +#ifdef CONFIG_NET_IPv4 +# define IPv4UDP_HDRLEN (UDP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + UDP headers */ +#endif + +#ifdef CONFIG_NET_IPv6 +# define IPv6UDP_HDRLEN (UDP_HDRLEN + IPv4_HDRLEN) /* Size of IPv6 + UDP headers */ +#endif /**************************************************************************** * Public Type Definitions ****************************************************************************/ +/* The UDP header */ + +struct udp_hdr_s +{ + uint16_t srcport; + uint16_t destport; + uint16_t udplen; + uint16_t udpchksum; +}; + /* The UDP and IP headers */ #ifdef CONFIG_NET_IPv4 diff --git a/nuttx/net/devif/ipv4_input.c b/nuttx/net/devif/ipv4_input.c index e7895d003..f10cfc68a 100644 --- a/nuttx/net/devif/ipv4_input.c +++ b/nuttx/net/devif/ipv4_input.c @@ -383,7 +383,7 @@ int ipv4_input(FAR struct net_driver_s *dev) if (pbuf->proto == IP_PROTO_UDP && net_ipv4addr_cmp(net_ip4addr_conv32(pbuf->destipaddr), g_alloneaddr)) { - return udp_input(dev); + return udp_ipv4_input(dev); } /* In most other cases, the device must be assigned a non-zero IP @@ -457,13 +457,13 @@ int ipv4_input(FAR struct net_driver_s *dev) { #ifdef CONFIG_NET_TCP case IP_PROTO_TCP: /* TCP input */ - tcp_input(dev); + tcp_ipv4_input(dev); break; #endif #ifdef CONFIG_NET_UDP case IP_PROTO_UDP: /* UDP input */ - udp_input(dev); + udp_ipv4_input(dev); break; #endif diff --git a/nuttx/net/devif/ipv6_input.c b/nuttx/net/devif/ipv6_input.c index c02db74c1..9f95efffa 100644 --- a/nuttx/net/devif/ipv6_input.c +++ b/nuttx/net/devif/ipv6_input.c @@ -251,13 +251,13 @@ int ipv6_input(FAR struct net_driver_s *dev) { #ifdef CONFIG_NET_TCP case IP_PROTO_TCP: /* TCP input */ - tcp_input(dev); + tcp_ipv6_input(dev); break; #endif #ifdef CONFIG_NET_UDP case IP_PROTO_UDP: /* UDP input */ - udp_input(dev); + udp_ipv6_input(dev); break; #endif diff --git a/nuttx/net/pkt/pkt_poll.c b/nuttx/net/pkt/pkt_poll.c index 7c8384268..e3db35b56 100644 --- a/nuttx/net/pkt/pkt_poll.c +++ b/nuttx/net/pkt/pkt_poll.c @@ -102,8 +102,8 @@ void pkt_poll(FAR struct net_driver_s *dev, FAR struct pkt_conn_s *conn) { /* Setup for the application callback */ - dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; - dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; + dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN]; + dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN]; dev->d_len = 0; dev->d_sndlen = 0; diff --git a/nuttx/net/tcp/tcp.h b/nuttx/net/tcp/tcp.h index f7afc6ff0..863c227cc 100644 --- a/nuttx/net/tcp/tcp.h +++ b/nuttx/net/tcp/tcp.h @@ -103,6 +103,7 @@ struct net_driver_s; /* Forward reference */ struct devif_callback_s; /* Forward reference */ struct tcp_backlog_s; /* Forward reference */ +struct tcp_hdr_s; /* Forward reference */ struct tcp_conn_s { @@ -272,7 +273,7 @@ extern "C" struct tcp_iphdr_s; /* Forward reference */ /**************************************************************************** - * Name: tcp_initialize() + * Name: tcp_initialize * * Description: * Initialize the TCP/IP connection structures. Called only once and only @@ -283,12 +284,12 @@ struct tcp_iphdr_s; /* Forward reference */ void tcp_initialize(void); /**************************************************************************** - * Name: tcp_alloc() + * Name: tcp_alloc * * Description: * Find a free TCP/IP connection structure and allocate it * for use. This is normally something done by the implementation of the - * socket() API but is also called from the interrupt level when a TCP + * socket() API but is also called from the driver level when a TCP * packet is received while "listening" * ****************************************************************************/ @@ -296,7 +297,7 @@ void tcp_initialize(void); FAR struct tcp_conn_s *tcp_alloc(void); /**************************************************************************** - * Name: tcp_free() + * Name: tcp_free * * Description: * Free a connection structure that is no longer in use. This should be @@ -307,51 +308,51 @@ FAR struct tcp_conn_s *tcp_alloc(void); void tcp_free(FAR struct tcp_conn_s *conn); /**************************************************************************** - * Name: tcp_active() + * Name: tcp_active * * Description: * Find a connection structure that is the appropriate * connection to be used with the provided TCP/IP header * * Assumptions: - * This function is called from UIP logic at interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ -FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf); +FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev, + FAR struct tcp_hdr_s *tcp); /**************************************************************************** - * Name: tcp_nextconn() + * Name: tcp_nextconn * * Description: * Traverse the list of active TCP connections * * Assumptions: - * This function is called from UIP logic at interrupt level (or with - * interrupts disabled). + * Called from network stack logic with the network stack locked * ****************************************************************************/ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn); /**************************************************************************** - * Name: tcp_alloc_accept() + * Name: tcp_alloc_accept * * Description: - * Called when driver interrupt processing matches the incoming packet - * with a connection in LISTEN. In that case, this function will create - * a new connection and initialize it to send a SYNACK in return. + * Called when driver processing matches the incoming packet with a + * connection in LISTEN. In that case, this function will create a new + * connection and initialize it to send a SYNACK in return. * * Assumptions: - * This function is called from UIP logic at interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, - FAR struct tcp_iphdr_s *buf); + FAR struct tcp_hdr_s *tcp); /**************************************************************************** - * Name: tcp_bind() + * Name: tcp_bind * * Description: * This function implements the lower level parts of the standard TCP @@ -409,7 +410,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, * Set the TCP/IP sequence number * * Assumptions: - * This function may called from the interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -422,7 +423,7 @@ void tcp_setsequence(FAR uint8_t *seqno, uint32_t value); * Get the TCP/IP sequence number * * Assumptions: - * This function may called from the interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -435,7 +436,7 @@ uint32_t tcp_getsequence(FAR uint8_t *seqno); * Add the length to get the next TCP sequence number. * * Assumptions: - * This function may called from the interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -449,7 +450,7 @@ uint32_t tcp_addsequence(FAR uint8_t *seqno, uint16_t len); * established. * * Assumptions: - * This function may called from the interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -462,7 +463,7 @@ void tcp_initsequence(FAR uint8_t *seqno); * Increment the TCP/IP sequence number * * Assumptions: - * This function is called from the interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -483,7 +484,7 @@ void tcp_nextsequence(void); * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -505,7 +506,7 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn); * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -560,7 +561,7 @@ int tcp_listen(FAR struct tcp_conn_s *conn); * Return true is there is a listener for the specified port * * Assumptions: - * Called at interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -573,7 +574,7 @@ bool tcp_islistener(uint16_t portno); * Accept the new connection for the specified listening port. * * Assumptions: - * Called at interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -597,7 +598,7 @@ int tcp_accept_connection(FAR struct net_driver_s *dev, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -617,7 +618,7 @@ void tcp_send(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -638,7 +639,7 @@ void tcp_reset(FAR struct net_driver_s *dev); * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -663,7 +664,7 @@ void tcp_ack(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -685,7 +686,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -694,10 +695,10 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, /* Defined in tcp_input.c ***************************************************/ /**************************************************************************** - * Name: tcp_input + * Name: tcp_ipv4_input * * Description: - * Handle incoming TCP input + * Handle incoming TCP input with IPv4 header * * Parameters: * dev - The device driver structure containing the received TCP packet. @@ -706,11 +707,34 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from the Ethernet driver with the network stack locked * ****************************************************************************/ -void tcp_input(FAR struct net_driver_s *dev); +#ifdef CONFIG_NET_IPv4 +void tcp_ipv4_input(FAR struct net_driver_s *dev); +#endif + +/**************************************************************************** + * Name: tcp_ipv6_input + * + * Description: + * Handle incoming TCP input with IPv4 header + * + * Parameters: + * dev - The device driver structure containing the received TCP packet. + * + * Return: + * None + * + * Assumptions: + * Called from the Ethernet driver with the network stack locked + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +void tcp_ipv6_input(FAR struct net_driver_s *dev); +#endif /* Defined in tcp_callback.c ************************************************/ /**************************************************************************** @@ -720,7 +744,7 @@ void tcp_input(FAR struct net_driver_s *dev); * Inform the application holding the TCP socket of a change in state. * * Assumptions: - * This function is called at the interrupt level with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -749,7 +773,7 @@ uint16_t tcp_callback(FAR struct net_driver_s *dev, * Assumptions: * - The caller has checked that TCP_NEWDATA is set in flags and that is no * other handler available to process the incoming data. - * - This function is called at the interrupt level with interrupts disabled. + * - Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -788,8 +812,7 @@ int tcp_backlogcreate(FAR struct tcp_conn_s *conn, int nblg); * is freed that has pending connections. * * Assumptions: - * The caller has disabled interrupts so that there can be no conflict - * with ongoing, interrupt driven activity + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -808,7 +831,7 @@ int tcp_backlogdestroy(FAR struct tcp_conn_s *conn); * function adds the new connection to the backlog. * * Assumptions: - * Called from the interrupt level with interrupts disabled + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -864,7 +887,7 @@ FAR struct tcp_conn_s *tcp_backlogremove(FAR struct tcp_conn_s *conn); * to remove the defunct connection from the list. * * Assumptions: - * Called from the interrupt level with interrupts disabled + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -984,7 +1007,7 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void); * buffered data. * * Assumptions: - * Called from interrupt level with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ diff --git a/nuttx/net/tcp/tcp_appsend.c b/nuttx/net/tcp/tcp_appsend.c index 1d1670ca8..339e2f255 100644 --- a/nuttx/net/tcp/tcp_appsend.c +++ b/nuttx/net/tcp/tcp_appsend.c @@ -112,7 +112,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, conn->tcpstateflags = TCP_CLOSED; nllvdbg("TCP state: TCP_CLOSED\n"); - tcp_send(dev, conn, TCP_RST | TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_RST | TCP_ACK, IPv4TCP_HDRLEN); } /* Check for connection closed */ @@ -125,7 +125,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, nllvdbg("TCP state: TCP_FIN_WAIT_1\n"); dev->d_sndlen = 0; - tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPv4TCP_HDRLEN); } /* None of the above */ @@ -204,14 +204,14 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * the IP and TCP headers. */ - tcp_send(dev, conn, TCP_ACK | TCP_PSH, dev->d_sndlen + IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK | TCP_PSH, dev->d_sndlen + IPv4TCP_HDRLEN); } /* If there is no data to send, just send out a pure ACK if one is requested`. */ else if ((result & TCP_SNDACK) != 0) { - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, IPv4TCP_HDRLEN); } /* There is nothing to do -- drop the packet */ diff --git a/nuttx/net/tcp/tcp_conn.c b/nuttx/net/tcp/tcp_conn.c index 5209646b1..f5f46a829 100644 --- a/nuttx/net/tcp/tcp_conn.c +++ b/nuttx/net/tcp/tcp_conn.c @@ -61,6 +61,13 @@ #include "tcp/tcp.h" /**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IPv4 ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) +#define IPv6 ((struct net_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) + +/**************************************************************************** * Private Data ****************************************************************************/ @@ -85,7 +92,7 @@ static uint16_t g_last_tcp_port; ****************************************************************************/ /**************************************************************************** - * Name: tcp_listener() + * Name: tcp_listener * * Description: * Given a local port number (in network byte order), find the TCP @@ -144,7 +151,7 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) } /**************************************************************************** - * Name: tcp_selectport() + * Name: tcp_selectport * * Description: * If the port number is zero; select an unused port for the connection. @@ -230,7 +237,7 @@ static int tcp_selectport(uint16_t portno) ****************************************************************************/ /**************************************************************************** - * Name: tcp_initialize() + * Name: tcp_initialize * * Description: * Initialize the TCP/IP connection structures. Called only once and only @@ -261,7 +268,7 @@ void tcp_initialize(void) } /**************************************************************************** - * Name: tcp_alloc() + * Name: tcp_alloc * * Description: * Find a free TCP/IP connection structure and allocate it @@ -374,7 +381,7 @@ FAR struct tcp_conn_s *tcp_alloc(void) } /**************************************************************************** - * Name: tcp_free() + * Name: tcp_free * * Description: * Free a connection structure that is no longer in use. This should be @@ -466,7 +473,7 @@ void tcp_free(FAR struct tcp_conn_s *conn) } /**************************************************************************** - * Name: tcp_active() + * Name: tcp_active * * Description: * Find a connection structure that is the appropriate @@ -477,12 +484,20 @@ void tcp_free(FAR struct tcp_conn_s *conn) * ****************************************************************************/ -FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf) +FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev, + FAR struct tcp_hdr_s *tcp) { - FAR struct tcp_conn_s *conn = (struct tcp_conn_s *)g_active_tcp_connections.head; - in_addr_t srcipaddr = net_ip4addr_conv32(buf->srcipaddr); + FAR struct net_iphdr_s *ip = IPv4; + FAR struct tcp_conn_s *conn; + in_addr_t srcipaddr; #ifdef CONFIG_NETDEV_MULTINIC - in_addr_t destipaddr = net_ip4addr_conv32(buf->destipaddr); + in_addr_t destipaddr; +#endif + + conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head; + srcipaddr = net_ip4addr_conv32(ip->srcipaddr); +#ifdef CONFIG_NETDEV_MULTINIC + destipaddr = net_ip4addr_conv32(ip->destipaddr); #endif while (conn) @@ -507,8 +522,8 @@ FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf) */ if (conn->tcpstateflags != TCP_CLOSED && - buf->destport == conn->lport && - buf->srcport == conn->rport && + tcp->destport == conn->lport && + tcp->srcport == conn->rport && #ifdef CONFIG_NETDEV_MULTINIC (net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr) || net_ipaddr_cmp(destipaddr, conn->lipaddr)) && @@ -531,7 +546,7 @@ FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf) } /**************************************************************************** - * Name: tcp_nextconn() + * Name: tcp_nextconn * * Description: * Traverse the list of active TCP connections @@ -555,7 +570,7 @@ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn) } /**************************************************************************** - * Name: tcp_alloc_accept() + * Name: tcp_alloc_accept * * Description: * Called when driver interrupt processing matches the incoming packet @@ -568,9 +583,12 @@ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn) ****************************************************************************/ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, - FAR struct tcp_iphdr_s *buf) + FAR struct tcp_hdr_s *tcp) { - FAR struct tcp_conn_s *conn = tcp_alloc(); + FAR struct net_iphdr_s *ip = IPv4; + FAR struct tcp_conn_s *conn; + + conn = tcp_alloc(); if (conn) { /* Fill in the necessary fields for the new connection. */ @@ -580,12 +598,12 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, conn->sa = 0; conn->sv = 4; conn->nrtx = 0; - conn->lport = buf->destport; - conn->rport = buf->srcport; + conn->lport = tcp->destport; + conn->rport = tcp->srcport; conn->mss = TCP_INITIAL_MSS(dev); - net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(buf->srcipaddr)); + net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(ip->srcipaddr)); #ifdef CONFIG_NETDEV_MULTINIC - net_ipaddr_copy(conn->lipaddr, net_ip4addr_conv32(buf->destipaddr)); + net_ipaddr_copy(conn->lipaddr, net_ip4addr_conv32(ip->destipaddr)); #endif conn->tcpstateflags = TCP_SYN_RCVD; @@ -599,7 +617,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, /* rcvseq should be the seqno from the incoming packet + 1. */ - memcpy(conn->rcvseq, buf->seqno, 4); + memcpy(conn->rcvseq, tcp->seqno, 4); #ifdef CONFIG_NET_TCP_READAHEAD /* Initialize the list of TCP read-ahead buffers */ @@ -625,7 +643,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, } /**************************************************************************** - * Name: tcp_bind() + * Name: tcp_bind * * Description: * This function implements the lower level parts of the standard TCP diff --git a/nuttx/net/tcp/tcp_input.c b/nuttx/net/tcp/tcp_input.c index c447045ec..c7c808afd 100644 --- a/nuttx/net/tcp/tcp_input.c +++ b/nuttx/net/tcp/tcp_input.c @@ -64,8 +64,6 @@ * Pre-processor Definitions ****************************************************************************/ -#define BUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) - /**************************************************************************** * Public Variables ****************************************************************************/ @@ -79,17 +77,15 @@ ****************************************************************************/ /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** * Name: tcp_input * * Description: * Handle incoming TCP input * * Parameters: - * dev - The device driver structure containing the received TCP packet. + * dev - The device driver structure containing the received TCP packet. + * tcp - A pointer to the TCP header in the packet + * tcpiplen - Combined length of the IP and TCP headers * * Return: * None @@ -99,10 +95,11 @@ * ****************************************************************************/ -void tcp_input(FAR struct net_driver_s *dev) +static void tcp_input(FAR struct net_driver_s *dev, + FAR struct tcp_hdr_s *tcp, unsigned int tcpiplen) { FAR struct tcp_conn_s *conn = NULL; - FAR struct tcp_iphdr_s *pbuf = BUF; + unsigned int hdrlen; uint16_t tmp16; uint16_t flags; uint8_t opt; @@ -110,13 +107,21 @@ void tcp_input(FAR struct net_driver_s *dev) int len; int i; - dev->d_snddata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)]; - dev->d_appdata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)]; - #ifdef CONFIG_NET_STATISTICS + /* Bump up the count of TCP packets received */ + g_netstats.tcp.recv++; #endif + /* Get the size of the link layer header, the IP header, and the TCP header */ + + hdrlen = tcpiplen + NET_LL_HDRLEN(dev); + + /* Initialize for tcp_send() */ + + dev->d_snddata = &dev->d_buf[hdrlen]; + dev->d_appdata = &dev->d_buf[hdrlen]; + /* Start of TCP input header processing code. */ if (tcp_chksum(dev) != 0xffff) @@ -133,7 +138,7 @@ void tcp_input(FAR struct net_driver_s *dev) /* Demultiplex this segment. First check any active connections. */ - conn = tcp_active(pbuf); + conn = tcp_active(dev, tcp); if (conn) { /* We found an active connection.. Check for the subsequent SYN @@ -143,7 +148,7 @@ void tcp_input(FAR struct net_driver_s *dev) */ if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD && - (BUF->flags & TCP_CTL) == TCP_SYN) + (tcp->flags & TCP_CTL) == TCP_SYN) { goto reset; } @@ -159,13 +164,13 @@ void tcp_input(FAR struct net_driver_s *dev) * it is an old packet and we send a RST. */ - if ((pbuf->flags & TCP_CTL) == TCP_SYN) + if ((tcp->flags & TCP_CTL) == TCP_SYN) { /* This is a SYN packet for a connection. Find the connection * listening on this port. */ - tmp16 = pbuf->destport; + tmp16 = tcp->destport; if (tcp_islistener(tmp16)) { /* We matched the incoming packet with a connection in LISTEN. @@ -177,7 +182,7 @@ void tcp_input(FAR struct net_driver_s *dev) * user application to accept it. */ - conn = tcp_alloc_accept(dev, pbuf); + conn = tcp_alloc_accept(dev, tcp); if (conn) { /* The connection structure was successfully allocated. Now see if @@ -215,11 +220,11 @@ void tcp_input(FAR struct net_driver_s *dev) /* Parse the TCP MSS option, if present. */ - if ((pbuf->tcpoffset & 0xf0) > 0x50) + if ((tcp->tcpoffset & 0xf0) > 0x50) { - for (i = 0; i < ((pbuf->tcpoffset >> 4) - 5) << 2 ;) + for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ;) { - opt = dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + i]; + opt = dev->d_buf[hdrlen + i]; if (opt == TCP_OPT_END) { /* End of options. */ @@ -233,12 +238,12 @@ void tcp_input(FAR struct net_driver_s *dev) ++i; } else if (opt == TCP_OPT_MSS && - dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == TCP_OPT_MSS_LEN) + dev->d_buf[hdrlen + 1 + i] == TCP_OPT_MSS_LEN) { /* An MSS option with the right option length. */ - tmp16 = ((uint16_t)dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 2 + i] << 8) | - (uint16_t)dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 3 + i]; + tmp16 = ((uint16_t)dev->d_buf[hdrlen + 2 + i] << 8) | + (uint16_t)dev->d_buf[hdrlen + 3 + i]; conn->mss = tmp16 > TCP_MSS(dev) ? TCP_MSS(dev) : tmp16; /* And we are done processing options. */ @@ -251,7 +256,7 @@ void tcp_input(FAR struct net_driver_s *dev) * can skip past them. */ - if (dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == 0) + if (dev->d_buf[hdrlen + 1 + i] == 0) { /* If the length field is zero, the options are malformed * and we don't process them further. @@ -259,7 +264,7 @@ void tcp_input(FAR struct net_driver_s *dev) break; } - i += dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i]; + i += dev->d_buf[hdrlen + 1 + i]; } } } @@ -279,7 +284,7 @@ reset: /* We do not send resets in response to resets. */ - if ((pbuf->flags & TCP_RST) != 0) + if ((tcp->flags & TCP_RST) != 0) { goto drop; } @@ -294,7 +299,7 @@ found: /* Update the connection's window size */ - conn->winsize = ((uint16_t)pbuf->wnd[0] << 8) + (uint16_t)pbuf->wnd[1]; + conn->winsize = ((uint16_t)tcp->wnd[0] << 8) + (uint16_t)tcp->wnd[1]; flags = 0; @@ -304,7 +309,7 @@ found: * before we accept the reset. */ - if ((pbuf->flags & TCP_RST) != 0) + if ((tcp->flags & TCP_RST) != 0) { conn->tcpstateflags = TCP_CLOSED; nlldbg("RESET - TCP state: TCP_CLOSED\n"); @@ -317,7 +322,7 @@ found: * any data to us. */ - len = (pbuf->tcpoffset >> 4) << 2; + len = (tcp->tcpoffset >> 4) << 2; /* d_len will contain the length of the actual TCP data. This is * calculated by subtracting the length of the TCP header (in @@ -334,14 +339,14 @@ found: */ if (!((((conn->tcpstateflags & TCP_STATE_MASK) == TCP_SYN_SENT) && - ((pbuf->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || + ((tcp->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || (((conn->tcpstateflags & TCP_STATE_MASK) == TCP_SYN_RCVD) && - ((pbuf->flags & TCP_CTL) == TCP_SYN)))) + ((tcp->flags & TCP_CTL) == TCP_SYN)))) { - if ((dev->d_len > 0 || ((pbuf->flags & (TCP_SYN | TCP_FIN)) != 0)) && - memcmp(pbuf->seqno, conn->rcvseq, 4) != 0) + if ((dev->d_len > 0 || ((tcp->flags & (TCP_SYN | TCP_FIN)) != 0)) && + memcmp(tcp->seqno, conn->rcvseq, 4) != 0) { - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, tcpiplen); return; } } @@ -352,7 +357,7 @@ found: * retransmission timer. */ - if ((pbuf->flags & TCP_ACK) != 0 && conn->unacked > 0) + if ((tcp->flags & TCP_ACK) != 0 && conn->unacked > 0) { uint32_t unackseq; uint32_t ackseq; @@ -372,7 +377,7 @@ found: * incoming packet. */ - ackseq = tcp_getsequence(pbuf->ackno); + ackseq = tcp_getsequence(tcp->ackno); /* Check how many of the outstanding bytes have been acknowledged. For * a most uIP send operation, this should always be true. However, @@ -464,7 +469,7 @@ found: conn->tcpstateflags = TCP_ESTABLISHED; #ifdef CONFIG_NET_TCP_WRITE_BUFFERS - conn->isn = tcp_getsequence(pbuf->ackno); + conn->isn = tcp_getsequence(tcp->ackno); tcp_setsequence(conn->sndseq, conn->isn); conn->sent = 0; #endif @@ -486,7 +491,7 @@ found: /* We need to retransmit the SYNACK */ - if ((pbuf->flags & TCP_CTL) == TCP_SYN) + if ((tcp->flags & TCP_CTL) == TCP_SYN) { tcp_ack(dev, conn, TCP_ACK | TCP_SYN); return; @@ -501,15 +506,15 @@ found: * state. */ - if ((flags & TCP_ACKDATA) != 0 && (pbuf->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) + if ((flags & TCP_ACKDATA) != 0 && (tcp->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { /* Parse the TCP MSS option, if present. */ - if ((pbuf->tcpoffset & 0xf0) > 0x50) + if ((tcp->tcpoffset & 0xf0) > 0x50) { - for (i = 0; i < ((pbuf->tcpoffset >> 4) - 5) << 2 ;) + for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ;) { - opt = dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + i]; + opt = dev->d_buf[hdrlen + i]; if (opt == TCP_OPT_END) { /* End of options. */ @@ -523,13 +528,13 @@ found: ++i; } else if (opt == TCP_OPT_MSS && - dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == TCP_OPT_MSS_LEN) + dev->d_buf[hdrlen + 1 + i] == TCP_OPT_MSS_LEN) { /* An MSS option with the right option length. */ tmp16 = - (dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 2 + i] << 8) | - dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 3 + i]; + (dev->d_buf[hdrlen + 2 + i] << 8) | + dev->d_buf[hdrlen + 3 + i]; conn->mss = tmp16 > TCP_MSS(dev) ? TCP_MSS(dev) : tmp16; /* And we are done processing options. */ @@ -542,7 +547,7 @@ found: * easily can skip past them. */ - if (dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i] == 0) + if (dev->d_buf[hdrlen + 1 + i] == 0) { /* If the length field is zero, the options are * malformed and we don't process them further. @@ -550,19 +555,19 @@ found: break; } - i += dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev) + 1 + i]; + i += dev->d_buf[hdrlen + 1 + i]; } } } conn->tcpstateflags = TCP_ESTABLISHED; - memcpy(conn->rcvseq, pbuf->seqno, 4); + memcpy(conn->rcvseq, tcp->seqno, 4); net_incr32(conn->rcvseq, 1); conn->unacked = 0; #ifdef CONFIG_NET_TCP_WRITE_BUFFERS - conn->isn = tcp_getsequence(pbuf->ackno); + conn->isn = tcp_getsequence(tcp->ackno); tcp_setsequence(conn->sndseq, conn->isn); #endif dev->d_len = 0; @@ -585,7 +590,7 @@ found: /* We do not send resets in response to resets. */ - if ((pbuf->flags & TCP_RST) != 0) + if ((tcp->flags & TCP_RST) != 0) { goto drop; } @@ -606,7 +611,7 @@ found: * sequence numbers will be screwed up. */ - if ((pbuf->flags & TCP_FIN) != 0 && (conn->tcpstateflags & TCP_STOPPED) == 0) + if ((tcp->flags & TCP_FIN) != 0 && (conn->tcpstateflags & TCP_STOPPED) == 0) { /* Needs to be investigated further. * Windows often sends FIN packets together with the last ACK for @@ -639,7 +644,7 @@ found: conn->nrtx = 0; nllvdbg("TCP state: TCP_LAST_ACK\n"); - tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_FIN | TCP_ACK, tcpiplen); return; } @@ -647,10 +652,10 @@ found: * data that we must pass to the application. */ - if ((pbuf->flags & TCP_URG) != 0) + if ((tcp->flags & TCP_URG) != 0) { #ifdef CONFIG_NET_TCPURGDATA - dev->d_urglen = (pbuf->urgp[0] << 8) | pbuf->urgp[1]; + dev->d_urglen = (tcp->urgp[0] << 8) | tcp->urgp[1]; if (dev->d_urglen > dev->d_len) { /* There is more urgent data in the next segment to come. */ @@ -667,8 +672,8 @@ found: { dev->d_urglen = 0; #else /* CONFIG_NET_TCPURGDATA */ - dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((pbuf->urgp[0] << 8) | pbuf->urgp[1]); - dev->d_len -= (pbuf->urgp[0] << 8) | pbuf->urgp[1]; + dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((tcp->urgp[0] << 8) | tcp->urgp[1]); + dev->d_len -= (tcp->urgp[0] << 8) | tcp->urgp[1]; #endif /* CONFIG_NET_TCPURGDATA */ } @@ -692,8 +697,7 @@ found: * When the application is called, the d_len field * contains the length of the incoming data. The application can * access the incoming data through the global pointer - * d_appdata, which usually points IPTCP_HDRLEN + NET_LL_HDRLEN(dev) - * bytes into the d_buf array. + * d_appdata, which usually points hdrlen bytes into the d_buf array. * * If the application wishes to send any data, this data should be * put into the d_appdata and the length of the data should be @@ -761,7 +765,7 @@ found: net_incr32(conn->rcvseq, dev->d_len); } - if ((pbuf->flags & TCP_FIN) != 0) + if ((tcp->flags & TCP_FIN) != 0) { if ((flags & TCP_ACKDATA) != 0) { @@ -778,7 +782,7 @@ found: net_incr32(conn->rcvseq, 1); (void)tcp_callback(dev, conn, TCP_CLOSE); - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, tcpiplen); return; } else if ((flags & TCP_ACKDATA) != 0) @@ -791,7 +795,7 @@ found: if (dev->d_len > 0) { - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, tcpiplen); return; } @@ -803,7 +807,7 @@ found: net_incr32(conn->rcvseq, dev->d_len); } - if ((pbuf->flags & TCP_FIN) != 0) + if ((tcp->flags & TCP_FIN) != 0) { conn->tcpstateflags = TCP_TIME_WAIT; conn->timer = 0; @@ -811,20 +815,20 @@ found: net_incr32(conn->rcvseq, 1); (void)tcp_callback(dev, conn, TCP_CLOSE); - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, tcpiplen); return; } if (dev->d_len > 0) { - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, tcpiplen); return; } goto drop; case TCP_TIME_WAIT: - tcp_send(dev, conn, TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_ACK, tcpiplen); return; case TCP_CLOSING: @@ -843,4 +847,58 @@ drop: dev->d_len = 0; } +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tcp_ipv4_input + * + * Description: + * Handle incoming TCP input with IPv4 header + * + * Parameters: + * dev - The device driver structure containing the received TCP packet. + * + * Return: + * None + * + * Assumptions: + * Called from the Ethernet driver with the network stack locked + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +void tcp_ipv4_input(FAR struct net_driver_s *dev) +{ + unsigned int offset = IPv4_HDRLEN + NET_LL_HDRLEN(dev); + tcp_input(dev, (FAR struct tcp_hdr_s *)&dev->d_buf[offset], IPv4TCP_HDRLEN); +} +#endif + +/**************************************************************************** + * Name: tcp_ipv6_input + * + * Description: + * Handle incoming TCP input with IPv4 header + * + * Parameters: + * dev - The device driver structure containing the received TCP packet. + * + * Return: + * None + * + * Assumptions: + * Called from the Ethernet driver with the network stack locked + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +void tcp_ipv6_input(FAR struct net_driver_s *dev) +{ + unsigned int offset = IPv6_HDRLEN + NET_LL_HDRLEN(dev); + tcp_input(dev, (FAR struct tcp_hdr_s *)&dev->d_buf[offset], IPv6TCP_HDRLEN); +} +#endif + #endif /* CONFIG_NET && CONFIG_NET_TCP */ diff --git a/nuttx/net/tcp/tcp_poll.c b/nuttx/net/tcp/tcp_poll.c index 0c2ea66f5..2d05e452c 100644 --- a/nuttx/net/tcp/tcp_poll.c +++ b/nuttx/net/tcp/tcp_poll.c @@ -103,8 +103,8 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) { /* Set up for the callback */ - dev->d_snddata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)]; - dev->d_appdata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_snddata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; dev->d_len = 0; dev->d_sndlen = 0; diff --git a/nuttx/net/tcp/tcp_send.c b/nuttx/net/tcp/tcp_send.c index 7546b2e2b..bc488b51e 100644 --- a/nuttx/net/tcp/tcp_send.c +++ b/nuttx/net/tcp/tcp_send.c @@ -275,7 +275,7 @@ void tcp_reset(FAR struct net_driver_s *dev) #endif pbuf->flags = TCP_RST | TCP_ACK; - dev->d_len = IPTCP_HDRLEN; + dev->d_len = IPv4TCP_HDRLEN; pbuf->tcpoffset = 5 << 4; /* Flip the seqno and ackno fields in the TCP header. */ @@ -362,7 +362,7 @@ void tcp_ack(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, pbuf->optdata[1] = TCP_OPT_MSS_LEN; pbuf->optdata[2] = TCP_MSS(dev) / 256; pbuf->optdata[3] = TCP_MSS(dev) & 255; - dev->d_len = IPTCP_HDRLEN + TCP_OPT_MSS_LEN; + dev->d_len = IPv4TCP_HDRLEN + TCP_OPT_MSS_LEN; pbuf->tcpoffset = ((TCP_HDRLEN + TCP_OPT_MSS_LEN) / 4) << 4; /* Complete the common portions of the TCP message */ diff --git a/nuttx/net/tcp/tcp_timer.c b/nuttx/net/tcp/tcp_timer.c index c0482380c..5ed9c8d10 100644 --- a/nuttx/net/tcp/tcp_timer.c +++ b/nuttx/net/tcp/tcp_timer.c @@ -100,8 +100,8 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, { uint8_t result; - dev->d_snddata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)]; - dev->d_appdata = &dev->d_buf[IPTCP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_snddata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; /* Increase the TCP sequence number */ @@ -183,7 +183,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, /* We also send a reset packet to the remote host. */ - tcp_send(dev, conn, TCP_RST | TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_RST | TCP_ACK, IPv4TCP_HDRLEN); goto done; } @@ -234,7 +234,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, case TCP_LAST_ACK: /* In all these states we should retransmit a FINACK. */ - tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPTCP_HDRLEN); + tcp_send(dev, conn, TCP_FIN | TCP_ACK, IPv4TCP_HDRLEN); goto done; } } diff --git a/nuttx/net/udp/udp.h b/nuttx/net/udp/udp.h index f13b85517..758f89a96 100644 --- a/nuttx/net/udp/udp.h +++ b/nuttx/net/udp/udp.h @@ -62,6 +62,7 @@ /* Representation of a uIP UDP connection */ struct devif_callback_s; /* Forward reference */ +struct udp_hdr_s; /* Forward reference */ struct udp_conn_s { @@ -96,8 +97,8 @@ extern "C" * Public Function Prototypes ****************************************************************************/ -struct udp_iphdr_s; /* Forward reference */ -struct net_driver_s; /* Forward reference */ +struct net_driver_s; /* Forward reference */ +struct udp_iphdr_s; /* Forward reference */ /* Defined in udp_conn.c ****************************************************/ /**************************************************************************** @@ -141,11 +142,12 @@ void udp_free(FAR struct udp_conn_s *conn); * connection to be used within the provided TCP/IP header * * Assumptions: - * This function is called from UIP logic at interrupt level + * Called from network stack logic with the network stack locked * ****************************************************************************/ -FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf); +FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev, + FAR struct udp_hdr_s *udp); /**************************************************************************** * Name: udp_nextconn() @@ -154,8 +156,7 @@ FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf); * Traverse the list of allocated UDP connections * * Assumptions: - * This function is called from UIP logic at interrupt level (or with - * interrupts disabled). + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -224,7 +225,7 @@ int udp_connect(FAR struct udp_conn_s *conn, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -245,7 +246,7 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn); * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ @@ -253,10 +254,10 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn); /* Defined in udp_input.c ***************************************************/ /**************************************************************************** - * Name: udp_input + * Name: udp_ipv4_input * * Description: - * Handle incoming UDP input + * Handle incoming UDP input in an IPv4 packet * * Parameters: * dev - The device driver structure containing the received UDP packet @@ -267,11 +268,36 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn); * but no receive in place to catch the packet yet. * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ -int udp_input(FAR struct net_driver_s *dev); +#ifdef CONFIG_NET_IPv4 +int udp_ipv4_input(FAR struct net_driver_s *dev); +#endif + +/**************************************************************************** + * Name: udp_ipv6_input + * + * Description: + * Handle incoming UDP input in an IPv6 packet + * + * Parameters: + * dev - The device driver structure containing the received UDP packet + * + * Return: + * OK The packet has been processed and can be deleted + * ERROR Hold the packet and try again later. There is a listening socket + * but no receive in place to catch the packet yet. + * + * Assumptions: + * Called from network stack logic with the network stack locked + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +int udp_ipv6_input(FAR struct net_driver_s *dev); +#endif /* Defined in udp_callback.c ************************************************/ /**************************************************************************** @@ -284,7 +310,7 @@ int udp_input(FAR struct net_driver_s *dev); * OK if packet has been processed, otherwise ERROR. * * Assumptions: - * This function is called at the interrupt level with interrupts disabled. + * Called from network stack logic with the network stack locked * ****************************************************************************/ diff --git a/nuttx/net/udp/udp_conn.c b/nuttx/net/udp/udp_conn.c index 3cdb7ce44..fd73b9a2d 100644 --- a/nuttx/net/udp/udp_conn.c +++ b/nuttx/net/udp/udp_conn.c @@ -63,6 +63,12 @@ #include "udp/udp.h" /**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IPv4 ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) + +/**************************************************************************** * Private Data ****************************************************************************/ @@ -342,11 +348,13 @@ void udp_free(FAR struct udp_conn_s *conn) * ****************************************************************************/ -FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf) +FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev, + FAR struct udp_hdr_s *udp) { - FAR struct udp_conn_s *conn = - (FAR struct udp_conn_s *)g_active_udp_connections.head; + FAR struct net_iphdr_s *ip = IPv4; + FAR struct udp_conn_s *conn; + conn = (FAR struct udp_conn_s *)g_active_udp_connections.head; while (conn) { /* If the local UDP port is non-zero, the connection is considered @@ -370,16 +378,16 @@ FAR struct udp_conn_s *udp_active(FAR struct udp_iphdr_s *buf) * is destined for this UDP connection. */ - if (conn->lport != 0 && buf->destport == conn->lport && - (conn->rport == 0 || buf->srcport == conn->rport) && + if (conn->lport != 0 && udp->destport == conn->lport && + (conn->rport == 0 || udp->srcport == conn->rport) && #ifdef CONFIG_NETDEV_MULTINIC (net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr) || net_ipaddr_cmp(conn->lipaddr, g_alloneaddr) || - net_ipaddr_hdrcmp(buf->destipaddr, &conn->lipaddr)) && + net_ipaddr_hdrcmp(ip->destipaddr, &conn->lipaddr)) && #endif (net_ipaddr_cmp(conn->ripaddr, g_allzeroaddr) || net_ipaddr_cmp(conn->ripaddr, g_alloneaddr) || - net_ipaddr_hdrcmp(buf->srcipaddr, &conn->ripaddr))) + net_ipaddr_hdrcmp(ip->srcipaddr, &conn->ripaddr))) { /* Matching connection found.. return a reference to it */ diff --git a/nuttx/net/udp/udp_input.c b/nuttx/net/udp/udp_input.c index 99b16761f..d53b9185c 100644 --- a/nuttx/net/udp/udp_input.c +++ b/nuttx/net/udp/udp_input.c @@ -60,8 +60,6 @@ * Pre-processor Definitions ****************************************************************************/ -#define UDPBUF ((struct udp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) - /**************************************************************************** * Public Variables ****************************************************************************/ @@ -75,17 +73,15 @@ ****************************************************************************/ /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** * Name: udp_input * * Description: * Handle incoming UDP input * * Parameters: - * dev - The device driver structure containing the received UDP packet + * dev - The device driver structure containing the received UDP packet + * udp - A pointer to the UDP header in the packet + * udpiplen - Length of the IP and UDP headers * * Return: * OK The packet has been processed and can be deleted @@ -97,12 +93,15 @@ * ****************************************************************************/ -int udp_input(FAR struct net_driver_s *dev) +static int udp_input(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp, + unsigned int udpiplen) { FAR struct udp_conn_s *conn; - FAR struct udp_iphdr_s *pbuf = UDPBUF; + unsigned int hdrlen; int ret = OK; + /* Update the count of UDP packets received */ + #ifdef CONFIG_NET_STATISTICS g_netstats.udp.recv++; #endif @@ -112,10 +111,16 @@ int udp_input(FAR struct net_driver_s *dev) * application sets d_sndlen, it has a packet to send. */ - dev->d_len -= IPUDP_HDRLEN; + dev->d_len -= udpiplen; + + /* Get the size of the link layer header, the IP header, and the UDP header */ + + hdrlen = udpiplen + NET_LL_HDRLEN(dev); + #ifdef CONFIG_NET_UDP_CHECKSUMS - dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; - if (pbuf->udpchksum != 0 && udp_chksum(dev) != 0xffff) + dev->d_appdata = &dev->d_buf[hdrlen]; + + if (udp->udpchksum != 0 && udp_chksum(dev) != 0xffff) { #ifdef CONFIG_NET_STATISTICS g_netstats.udp.drop++; @@ -134,7 +139,7 @@ int udp_input(FAR struct net_driver_s *dev) * receiving a UDP datagram (multicast reception). This could be * handled easily by something like: * - * for (conn = NULL; conn = udp_active (pbuf, conn); ) + * for (conn = NULL; conn = udp_active(dev, udp); ) * * If the callback logic that receives a packet responds with an * outgoing packet, then it will over-write the received buffer, @@ -143,15 +148,15 @@ int udp_input(FAR struct net_driver_s *dev) * packet as read-only. */ - conn = udp_active(pbuf); + conn = udp_active(dev, udp); if (conn) { uint16_t flags; /* Set-up for the application callback */ - dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; - dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; + dev->d_appdata = &dev->d_buf[hdrlen]; + dev->d_snddata = &dev->d_buf[hdrlen]; dev->d_sndlen = 0; /* Perform the application callback */ @@ -188,4 +193,64 @@ int udp_input(FAR struct net_driver_s *dev) return ret; } +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: udp_ipv4_input + * + * Description: + * Handle incoming UDP input in an IPv4 packet + * + * Parameters: + * dev - The device driver structure containing the received UDP packet + * + * Return: + * OK The packet has been processed and can be deleted + * ERROR Hold the packet and try again later. There is a listening socket + * but no receive in place to catch the packet yet. + * + * Assumptions: + * Called from network stack logic with the network stack locked + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +int udp_ipv4_input(FAR struct net_driver_s *dev) +{ + unsigned int offset = IPv4_HDRLEN + NET_LL_HDRLEN(dev); + return udp_input(dev, (FAR struct udp_hdr_s *)&dev->d_buf[offset], + IPv4UDP_HDRLEN); +} +#endif + +/**************************************************************************** + * Name: udp_ipv6_input + * + * Description: + * Handle incoming UDP input in an IPv6 packet + * + * Parameters: + * dev - The device driver structure containing the received UDP packet + * + * Return: + * OK The packet has been processed and can be deleted + * ERROR Hold the packet and try again later. There is a listening socket + * but no receive in place to catch the packet yet. + * + * Assumptions: + * Called from network stack logic with the network stack locked + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +int udp_ipv6_input(FAR struct net_driver_s *dev) +{ + unsigned int offset = IPv6_HDRLEN + NET_LL_HDRLEN(dev); + return udp_input(dev, (FAR struct udp_hdr_s *)&dev->d_buf[offset], + IPv6UDP_HDRLEN); +} +#endif + #endif /* CONFIG_NET && CONFIG_NET_UDP */ diff --git a/nuttx/net/udp/udp_poll.c b/nuttx/net/udp/udp_poll.c index e490b88ab..d19f72a76 100644 --- a/nuttx/net/udp/udp_poll.c +++ b/nuttx/net/udp/udp_poll.c @@ -100,8 +100,8 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn) { /* Set-up for the application callback */ - dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; - dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPUDP_HDRLEN]; + dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN]; + dev->d_snddata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN]; dev->d_len = 0; dev->d_sndlen = 0; diff --git a/nuttx/net/udp/udp_send.c b/nuttx/net/udp/udp_send.c index 658e826ba..098d7c4fc 100644 --- a/nuttx/net/udp/udp_send.c +++ b/nuttx/net/udp/udp_send.c @@ -109,7 +109,7 @@ void udp_send(struct net_driver_s *dev, struct udp_conn_s *conn) * the IP and UDP headers (and, eventually, the Ethernet header) */ - dev->d_len = dev->d_sndlen + IPUDP_HDRLEN; + dev->d_len = dev->d_sndlen + IPv4UDP_HDRLEN; /* Initialize the IP header. Note that for IPv6, the IP length field * does not include the IPv6 IP header length. |