net: extract l3 header build code into new functions

Signed-off-by: liyi <liyi25@xiaomi.com>
This commit is contained in:
liyi 2022-11-29 11:23:43 +08:00 committed by Xiang Xiao
parent d54a20b393
commit 391b501639
23 changed files with 398 additions and 522 deletions

View File

@ -88,6 +88,7 @@
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
# define IPv4_HDRLEN 20 /* Size of IPv4 header (without options) */ # define IPv4_HDRLEN 20 /* Size of IPv4 header (without options) */
# define IPv4_HLMASK 0x0f /* Isolates headler length in VHL field */ # define IPv4_HLMASK 0x0f /* Isolates headler length in VHL field */
# define IPV4_OPTMAX 40 /* The limit of ip option length */
#endif #endif
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
@ -164,6 +165,14 @@ struct ipv4_hdr_s
uint16_t srcipaddr[2]; /* 32-bit Source IP address */ uint16_t srcipaddr[2]; /* 32-bit Source IP address */
uint16_t destipaddr[2]; /* 32-bit Destination IP address */ uint16_t destipaddr[2]; /* 32-bit Destination IP address */
}; };
/* The IPv4 options */
struct ipv4_opt_s
{
uint8_t len;
uint8_t data[IPV4_OPTMAX];
};
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6

View File

@ -668,27 +668,6 @@ uint16_t net_chksum(FAR uint16_t *data, uint16_t len);
void net_incr32(FAR uint8_t *op32, uint16_t op16); void net_incr32(FAR uint8_t *op32, uint16_t op16);
/****************************************************************************
* Name: ipv4_chksum
*
* Description:
* Calculate the IPv4 header checksum of the packet header in d_buf.
*
* The IPv4 header checksum is the Internet checksum of the 20 bytes of
* the IPv4 header.
*
* If CONFIG_NET_ARCH_CHKSUM is defined, then this function must be
* provided by architecture-specific logic.
*
* Returned Value:
* The IPv4 header checksum of the IPv4 header in the d_buf buffer.
*
****************************************************************************/
#ifdef CONFIG_NET_IPv4
uint16_t ipv4_chksum(FAR struct net_driver_s *dev);
#endif
/**************************************************************************** /****************************************************************************
* Name: netdev_ipv4_hdrlen * Name: netdev_ipv4_hdrlen
* *

View File

@ -105,6 +105,7 @@
#include "ipforward/ipforward.h" #include "ipforward/ipforward.h"
#include "devif/devif.h" #include "devif/devif.h"
#include "nat/nat.h" #include "nat/nat.h"
#include "utils/utils.h"
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -342,7 +343,7 @@ int ipv4_input(FAR struct net_driver_s *dev)
} }
#endif #endif
if (ipv4_chksum(dev) != 0xffff) if (ipv4_chksum(IPv4BUF) != 0xffff)
{ {
/* Compute and check the IP header checksum. */ /* Compute and check the IP header checksum. */

View File

@ -127,27 +127,9 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
memmove(icmp + 1, ipv4, datalen); memmove(icmp + 1, ipv4, datalen);
/* Initialize the IP header. */ ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_ICMP,
&dev->d_ipaddr, (FAR in_addr_t *)ipv4->srcipaddr,
ipv4->vhl = 0x45; IP_TTL_DEFAULT, NULL);
ipv4->tos = 0;
ipv4->len[0] = (dev->d_len >> 8);
ipv4->len[1] = (dev->d_len & 0xff);
++g_ipid;
ipv4->ipid[0] = g_ipid >> 8;
ipv4->ipid[1] = g_ipid & 0xff;
ipv4->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
ipv4->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
ipv4->ttl = IP_TTL_DEFAULT;
ipv4->proto = IP_PROTO_ICMP;
/* Calculate IP checksum. */
ipv4->ipchksum = 0;
ipv4->ipchksum = ~ipv4_chksum(dev);
net_ipv4addr_hdrcopy(ipv4->destipaddr, ipv4->srcipaddr);
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
/* Initialize the ICMP header */ /* Initialize the ICMP header */
@ -165,8 +147,7 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
icmp->icmpchksum = 0xffff; icmp->icmpchksum = 0xffff;
} }
ninfo("Outgoing ICMP packet length: %d (%d)\n", ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);
dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
} }
#endif /* CONFIG_NET_ICMP */ #endif /* CONFIG_NET_ICMP */

View File

@ -97,7 +97,6 @@ struct icmp_sendto_s
static void sendto_request(FAR struct net_driver_s *dev, static void sendto_request(FAR struct net_driver_s *dev,
FAR struct icmp_sendto_s *pstate) FAR struct icmp_sendto_s *pstate)
{ {
FAR struct ipv4_hdr_s *ipv4;
FAR struct icmp_hdr_s *icmp; FAR struct icmp_hdr_s *icmp;
IFF_SET_IPv4(dev->d_flags); IFF_SET_IPv4(dev->d_flags);
@ -112,33 +111,16 @@ static void sendto_request(FAR struct net_driver_s *dev,
dev->d_sndlen += pstate->snd_buflen; dev->d_sndlen += pstate->snd_buflen;
/* Initialize the IP header. */
ipv4 = IPv4BUF;
ipv4->vhl = 0x45;
ipv4->tos = 0;
ipv4->len[0] = (dev->d_len >> 8);
ipv4->len[1] = (dev->d_len & 0xff);
++g_ipid;
ipv4->ipid[0] = g_ipid >> 8;
ipv4->ipid[1] = g_ipid & 0xff;
ipv4->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
ipv4->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
ipv4->ttl = IP_TTL_DEFAULT;
ipv4->proto = IP_PROTO_ICMP;
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
net_ipv4addr_hdrcopy(ipv4->destipaddr, &pstate->snd_toaddr);
/* Copy the ICMP header and payload into place after the IPv4 header */ /* Copy the ICMP header and payload into place after the IPv4 header */
icmp = IPBUF(IPv4_HDRLEN); icmp = IPBUF(IPv4_HDRLEN);
memcpy(icmp, pstate->snd_buf, pstate->snd_buflen); memcpy(icmp, pstate->snd_buf, pstate->snd_buflen);
/* Calculate IP checksum. */ /* Initialize the IP header. */
ipv4->ipchksum = 0; ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_ICMP,
ipv4->ipchksum = ~(ipv4_chksum(dev)); &dev->d_ipaddr, &pstate->snd_toaddr,
IP_TTL_DEFAULT, NULL);
/* Calculate the ICMP checksum. */ /* Calculate the ICMP checksum. */
@ -149,8 +131,7 @@ static void sendto_request(FAR struct net_driver_s *dev,
icmp->icmpchksum = 0xffff; icmp->icmpchksum = 0xffff;
} }
ninfo("Outgoing ICMP packet length: %d (%d)\n", ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);
dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.icmp.sent++; g_netstats.icmp.sent++;

View File

@ -38,6 +38,7 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "icmpv6/icmpv6.h" #include "icmpv6/icmpv6.h"
#include "inet/inet.h"
#ifdef CONFIG_NET_ICMPv6 #ifdef CONFIG_NET_ICMPv6
@ -66,31 +67,17 @@
void icmpv6_advertise(FAR struct net_driver_s *dev, void icmpv6_advertise(FAR struct net_driver_s *dev,
const net_ipv6addr_t destipaddr) const net_ipv6addr_t destipaddr)
{ {
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
FAR struct icmpv6_neighbor_advertise_s *adv; FAR struct icmpv6_neighbor_advertise_s *adv;
uint16_t lladdrsize; uint16_t lladdrsize;
uint16_t l3size; uint16_t l3size;
/* Set up the IPv6 header */
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */ /* Length excludes the IPv6 header */
lladdrsize = netdev_lladdrsize(dev); lladdrsize = netdev_lladdrsize(dev);
l3size = SIZEOF_ICMPV6_NEIGHBOR_ADVERTISE_S(lladdrsize); l3size = SIZEOF_ICMPV6_NEIGHBOR_ADVERTISE_S(lladdrsize);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
ipv6->proto = IP_PROTO_ICMP6; /* Next header */ ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
ipv6->ttl = 255; /* Hop limit */ dev->d_ipv6addr, destipaddr, 255);
/* Swap source for destination IP address, add our source IP address */
net_ipv6addr_copy(ipv6->destipaddr, destipaddr);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Neighbor Advertise response */ /* Set up the ICMPv6 Neighbor Advertise response */
@ -125,8 +112,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;
ninfo("Outgoing ICMPv6 Neighbor Advertise length: %d (%d)\n", ninfo("Outgoing ICMPv6 Neighbor Advertise length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++; g_netstats.icmpv6.sent++;

View File

@ -116,20 +116,14 @@ static inline void ipv6addr_mask(FAR uint16_t *dest, FAR const uint16_t *src,
void icmpv6_radvertise(FAR struct net_driver_s *dev) void icmpv6_radvertise(FAR struct net_driver_s *dev)
{ {
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
FAR struct icmpv6_router_advertise_s *adv; FAR struct icmpv6_router_advertise_s *adv;
FAR struct icmpv6_srclladdr_s *srcaddr; FAR struct icmpv6_srclladdr_s *srcaddr;
FAR struct icmpv6_mtu_s *mtu; FAR struct icmpv6_mtu_s *mtu;
FAR struct icmpv6_prefixinfo_s *prefix; FAR struct icmpv6_prefixinfo_s *prefix;
net_ipv6addr_t srcv6addr;
uint16_t lladdrsize; uint16_t lladdrsize;
uint16_t l3size; uint16_t l3size;
/* Set up the IPv6 header */
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */ /* Length excludes the IPv6 header */
lladdrsize = netdev_lladdrsize(dev); lladdrsize = netdev_lladdrsize(dev);
@ -138,19 +132,12 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
sizeof(struct icmpv6_mtu_s) + sizeof(struct icmpv6_mtu_s) +
sizeof(struct icmpv6_prefixinfo_s); sizeof(struct icmpv6_prefixinfo_s);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
/* Swap source for destination IP address, add our source IP address */
net_ipv6addr_copy(ipv6->destipaddr, g_ipv6_allnodes);
/* Source IP address must be set to link-local IP */ /* Source IP address must be set to link-local IP */
icmpv6_linkipaddr(dev, ipv6->srcipaddr); icmpv6_linkipaddr(dev, srcv6addr);
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
srcv6addr, g_ipv6_allnodes, 255);
/* Set up the ICMPv6 Router Advertise response */ /* Set up the ICMPv6 Router Advertise response */
@ -215,8 +202,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;
ninfo("Outgoing ICMPv6 Router Advertise length: %d (%d)\n", ninfo("Outgoing ICMPv6 Router Advertise length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++; g_netstats.icmpv6.sent++;

View File

@ -88,7 +88,6 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF; FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
FAR struct icmpv6_hdr_s *icmpv6 = (FAR struct icmpv6_hdr_s *)(ipv6 + 1); FAR struct icmpv6_hdr_s *icmpv6 = (FAR struct icmpv6_hdr_s *)(ipv6 + 1);
uint16_t datalen; uint16_t datalen;
uint16_t paylen;
if (net_ipv6addr_cmp(ipv6->destipaddr, g_ipv6_unspecaddr) if (net_ipv6addr_cmp(ipv6->destipaddr, g_ipv6_unspecaddr)
# ifdef CONFIG_NET_BROADCAST # ifdef CONFIG_NET_BROADCAST
@ -112,24 +111,9 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
} }
dev->d_len = ipicmplen + datalen; dev->d_len = ipicmplen + datalen;
paylen = dev->d_len - IPv6_HDRLEN;
/* Copy fields from original packet */ ipv6_build_header(IPv6BUF, dev->d_len - IPv6_HDRLEN, IP_PROTO_ICMP6,
dev->d_ipv6addr, ipv6->srcipaddr, 255);
memmove(icmpv6 + 1, ipv6, datalen);
/* Set up the IPv6 header (most is probably already in place) */
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class(LS)/Flow label(MS) */
ipv6->flow = 0; /* Flow label (LS) */
ipv6->len[0] = (paylen >> 8); /* Length excludes the IPv6 header */
ipv6->len[1] = (paylen & 0xff);
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
net_ipv6addr_hdrcopy(ipv6->destipaddr, ipv6->srcipaddr);
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Initialize the ICMPv6 header */ /* Initialize the ICMPv6 header */
@ -147,8 +131,7 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
icmpv6->chksum = 0xffff; icmpv6->chksum = 0xffff;
} }
ninfo("Outgoing ICMPv6 packet length: %d (%d)\n", ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
} }
#endif /* CONFIG_NET_ICMPv6 */ #endif /* CONFIG_NET_ICMPv6 */

View File

@ -66,37 +66,17 @@
void icmpv6_rsolicit(FAR struct net_driver_s *dev) void icmpv6_rsolicit(FAR struct net_driver_s *dev)
{ {
FAR struct ipv6_hdr_s *ipv6;
FAR struct icmpv6_router_solicit_s *sol; FAR struct icmpv6_router_solicit_s *sol;
uint16_t lladdrsize; uint16_t lladdrsize;
uint16_t l3size; uint16_t l3size;
/* Set up the IPv6 header (most is probably already in place) */
ipv6 = IPv6BUF;
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */ /* Length excludes the IPv6 header */
lladdrsize = netdev_lladdrsize(dev); lladdrsize = netdev_lladdrsize(dev);
l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(lladdrsize); l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(lladdrsize);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
ipv6->proto = IP_PROTO_ICMP6; /* Next header */ ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
ipv6->ttl = 255; /* Hop limit */ dev->d_ipv6addr, g_ipv6_allrouters, 255);
/* Set the multicast destination IP address to the IPv6 all link-
* local routers address: ff02::2
*/
net_ipv6addr_copy(ipv6->destipaddr, g_ipv6_allrouters);
/* Add our link local IPv6 address as the source address */
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Router Solicitation message */ /* Set up the ICMPv6 Router Solicitation message */
@ -126,8 +106,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;
ninfo("Outgoing ICMPv6 Router Solicitation length: %d (%d)\n", ninfo("Outgoing ICMPv6 Router Solicitation length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++; g_netstats.icmpv6.sent++;

View File

@ -96,7 +96,6 @@ struct icmpv6_sendto_s
static void sendto_request(FAR struct net_driver_s *dev, static void sendto_request(FAR struct net_driver_s *dev,
FAR struct icmpv6_sendto_s *pstate) FAR struct icmpv6_sendto_s *pstate)
{ {
FAR struct ipv6_hdr_s *ipv6;
FAR struct icmpv6_echo_request_s *icmpv6; FAR struct icmpv6_echo_request_s *icmpv6;
IFF_SET_IPv6(dev->d_flags); IFF_SET_IPv6(dev->d_flags);
@ -111,19 +110,8 @@ static void sendto_request(FAR struct net_driver_s *dev,
dev->d_sndlen += pstate->snd_buflen; dev->d_sndlen += pstate->snd_buflen;
/* Set up the IPv6 header (most is probably already in place) */ ipv6_build_header(IPv6BUF, pstate->snd_buflen, IP_PROTO_ICMP6,
dev->d_ipv6addr, pstate->snd_toaddr.s6_addr16, 255);
ipv6 = IPv6BUF;
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class(LS)/Flow label(MS) */
ipv6->flow = 0; /* Flow label (LS) */
ipv6->len[0] = (pstate->snd_buflen >> 8); /* Length excludes the IPv6 header */
ipv6->len[1] = (pstate->snd_buflen & 0xff);
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_hdrcopy(ipv6->destipaddr, pstate->snd_toaddr.s6_addr16);
/* Copy the ICMPv6 request and payload into place after the IPv6 header */ /* Copy the ICMPv6 request and payload into place after the IPv6 header */
@ -139,8 +127,7 @@ static void sendto_request(FAR struct net_driver_s *dev,
icmpv6->chksum = 0xffff; icmpv6->chksum = 0xffff;
} }
ninfo("Outgoing ICMPv6 packet length: %d (%d)\n", ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++; g_netstats.icmpv6.sent++;

View File

@ -36,6 +36,7 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "icmpv6/icmpv6.h" #include "icmpv6/icmpv6.h"
#include "inet/inet.h"
#ifdef CONFIG_NET_ICMPv6 #ifdef CONFIG_NET_ICMPv6
@ -77,37 +78,24 @@ static const uint16_t g_icmpv_mcastaddr[6] =
void icmpv6_solicit(FAR struct net_driver_s *dev, void icmpv6_solicit(FAR struct net_driver_s *dev,
FAR const net_ipv6addr_t ipaddr) FAR const net_ipv6addr_t ipaddr)
{ {
FAR struct ipv6_hdr_s *ipv6;
FAR struct icmpv6_neighbor_solicit_s *sol; FAR struct icmpv6_neighbor_solicit_s *sol;
net_ipv6addr_t dstaddr;
uint16_t lladdrsize; uint16_t lladdrsize;
uint16_t l3size; uint16_t l3size;
/* Set up the IPv6 header (most is probably already in place) */
ipv6 = IPv6BUF;
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */ /* Length excludes the IPv6 header */
lladdrsize = netdev_lladdrsize(dev); lladdrsize = netdev_lladdrsize(dev);
l3size = SIZEOF_ICMPV6_NEIGHBOR_SOLICIT_S(lladdrsize); l3size = SIZEOF_ICMPV6_NEIGHBOR_SOLICIT_S(lladdrsize);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
/* Set the multicast destination IP address */ /* Set the multicast destination IP address */
memcpy(ipv6->destipaddr, g_icmpv_mcastaddr, 6*sizeof(uint16_t)); memcpy(dstaddr, g_icmpv_mcastaddr, sizeof(g_icmpv_mcastaddr));
ipv6->destipaddr[6] = ipaddr[6] | HTONS(0xff00); dstaddr[6] = ipaddr[6] | HTONS(0xff00);
ipv6->destipaddr[7] = ipaddr[7]; dstaddr[7] = ipaddr[7];
/* Add out IPv6 address as the source address */ ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
dev->d_ipv6addr, dstaddr, 255);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Neighbor Solicitation message */ /* Set up the ICMPv6 Neighbor Solicitation message */
@ -141,8 +129,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;
ninfo("Outgoing ICMPv6 Neighbor Solicitation length: %d (%d)\n", ninfo("Outgoing ICMPv6 Neighbor Solicitation length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++; g_netstats.icmpv6.sent++;

View File

@ -102,9 +102,10 @@ static uint16_t igmp_chksum(FAR uint8_t *buffer, int buflen)
void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group, void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
FAR const in_addr_t *destipaddr, uint8_t msgid) FAR const in_addr_t *destipaddr, uint8_t msgid)
{ {
FAR struct igmp_iphdr_s *ipv4 = IPBUF(0);
FAR struct igmp_hdr_s *igmp; FAR struct igmp_hdr_s *igmp;
uint16_t iphdrlen; uint16_t iphdrlen;
struct ipv4_opt_s opt;
uint32_t tmp;
ninfo("msgid: %02x destipaddr: %08x\n", msgid, (int)*destipaddr); ninfo("msgid: %02x destipaddr: %08x\n", msgid, (int)*destipaddr);
@ -125,30 +126,12 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
/* Add the router alert option to the IPv4 header (RFC 2113) */ /* Add the router alert option to the IPv4 header (RFC 2113) */
ipv4->ra[0] = HTONS(IPOPT_RA >> 16); tmp = HTONL(IPOPT_RA);
ipv4->ra[1] = HTONS(IPOPT_RA & 0xffff); memcpy(opt.data, &tmp, sizeof(uint32_t));
opt.len = sizeof(uint32_t);
/* Initialize the IPv4 header */ ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_IGMP,
&dev->d_ipaddr, destipaddr, IGMP_TTL, &opt);
ipv4->vhl = 0x46; /* 4->IP; 6->24 bytes */
ipv4->tos = 0;
ipv4->len[0] = (dev->d_len >> 8);
ipv4->len[1] = (dev->d_len & 0xff);
++g_ipid;
ipv4->ipid[0] = g_ipid >> 8;
ipv4->ipid[1] = g_ipid & 0xff;
ipv4->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
ipv4->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
ipv4->ttl = IGMP_TTL;
ipv4->proto = IP_PROTO_IGMP;
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
net_ipv4addr_hdrcopy(ipv4->destipaddr, destipaddr);
/* Calculate IP checksum. */
ipv4->ipchksum = 0;
ipv4->ipchksum = ~igmp_chksum((FAR uint8_t *)igmp, iphdrlen);
/* Set up the IGMP message */ /* Set up the IGMP message */
@ -164,8 +147,7 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
IGMP_STATINCR(g_netstats.igmp.poll_send); IGMP_STATINCR(g_netstats.igmp.poll_send);
IGMP_STATINCR(g_netstats.ipv4.sent); IGMP_STATINCR(g_netstats.ipv4.sent);
ninfo("Outgoing IGMP packet length: %d (%d)\n", ninfo("Outgoing IGMP packet length: %d\n", dev->d_len);
dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
igmp_dumppkt(RA, iphdrlen + IGMP_HDRLEN); igmp_dumppkt(RA, iphdrlen + IGMP_HDRLEN);
} }

View File

@ -31,11 +31,11 @@ SOCK_CSRCS += inet_globals.c
endif endif
ifeq ($(CONFIG_NET_IPv4),y) ifeq ($(CONFIG_NET_IPv4),y)
SOCK_CSRCS += ipv4_setsockopt.c ipv4_getsockname.c ipv4_getpeername.c SOCK_CSRCS += ipv4_setsockopt.c ipv4_getsockname.c ipv4_getpeername.c ipv4_build_header.c
endif endif
ifeq ($(CONFIG_NET_IPv6),y) ifeq ($(CONFIG_NET_IPv6),y)
SOCK_CSRCS += ipv6_setsockopt.c ipv6_getsockname.c ipv6_getpeername.c SOCK_CSRCS += ipv6_setsockopt.c ipv6_getsockname.c ipv6_getpeername.c ipv6_build_header.c
endif endif
# Include inet build support # Include inet build support

View File

@ -67,12 +67,6 @@ extern "C"
#define EXTERN extern #define EXTERN extern
#endif #endif
#ifdef CONFIG_NET_IPv4
/* Increasing number used for the IP ID field. */
EXTERN uint16_t g_ipid;
#endif /* CONFIG_NET_IPv4 */
/* Well-known IPv6 addresses */ /* Well-known IPv6 addresses */
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
@ -261,6 +255,58 @@ int inet_close(FAR struct socket *psock);
int inet_txdrain(FAR struct socket *psock, unsigned int timeout); int inet_txdrain(FAR struct socket *psock, unsigned int timeout);
/****************************************************************************
* Name: ipv4_build_header
*
* Description:
* build IPv4 header
*
* Input Parameters:
* ipv4 Pointer to IPv4 header's buffer
* total_len total length of the IPv4 packet
* prot the next level protocol used in IPv4 packet
* src_ip Source IPv4 address
* dst_ip Destination IPv4 address
* ttl Time to live(IPv4)
* opt IPv4 options
*
* Returned Value:
* length of IPv4 header
*
****************************************************************************/
#ifdef CONFIG_NET_IPv4
uint16_t ipv4_build_header(FAR struct ipv4_hdr_s *ipv4, uint16_t total_len,
uint16_t prot, FAR const in_addr_t *src_ip,
FAR const in_addr_t *dst_ip, uint8_t ttl,
FAR struct ipv4_opt_s *opt);
#endif
/****************************************************************************
* Name: ipv6_build_header
*
* Description:
* build IPv6 header
*
* Input Parameters:
* ipv6 Pointer to IPv6 header's buffer
* payload_len Length of the IPv6 payload(without IPv6 header length)
* prot Type of header immediately following the IPv6 header
* src_ip Source IPv6 address
* dst_ip Destination IPv6 address
* ttl hop limit(IPv6)
*
* Returned Value:
* length of IPv6 header
*
****************************************************************************/
#ifdef CONFIG_NET_IPv6
uint16_t ipv6_build_header(FAR struct ipv6_hdr_s *ipv6, uint16_t payload_len,
uint16_t prot, const net_ipv6addr_t src_ip,
const net_ipv6addr_t dst_ip, uint8_t ttl);
#endif
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View File

@ -38,12 +38,6 @@
* Public Data * Public Data
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET_IPv4
/* Increasing number used for the IP ID field. */
uint16_t g_ipid;
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
/* Unspecified address (all zero). See RFC 4291 (replaces 3513) */ /* Unspecified address (all zero). See RFC 4291 (replaces 3513) */

View File

@ -0,0 +1,109 @@
/****************************************************************************
* net/inet/ipv4_build_header.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/netconfig.h>
#include "inet.h"
#include "utils/utils.h"
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_NET_IPv4
/* Increasing number used for the IP ID field. */
static uint16_t g_ipid;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ipv4_build_header
*
* Description:
* build IPv4 header
*
* Input Parameters:
* ipv4 Pointer to IPv4 header's buffer
* total_len total length of the IPv4 packet
* prot the next level protocol used in IPv4 packet
* src_ip Source IPv4 address
* dst_ip Destination IPv4 address
* ttl Time to live(IPv4)
* opt IPv4 options
*
* Returned Value:
* length of IPv4 header
*
****************************************************************************/
uint16_t ipv4_build_header(FAR struct ipv4_hdr_s *ipv4, uint16_t total_len,
uint16_t prot, FAR const in_addr_t *src_ip,
FAR const in_addr_t *dst_ip, uint8_t ttl,
FAR struct ipv4_opt_s *opt)
{
/* Initialize the IP header. */
ipv4->vhl = 0x45; /* orginal initial value like this */
ipv4->tos = 0;
ipv4->len[0] = (total_len >> 8);
ipv4->len[1] = (total_len & 0xff);
++g_ipid;
ipv4->ipid[0] = g_ipid >> 8;
ipv4->ipid[1] = g_ipid & 0xff;
ipv4->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
ipv4->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
ipv4->ttl = ttl;
ipv4->proto = prot;
/* It's possible to use its own src_ip to initialize its dest_ip */
net_ipv4addr_hdrcopy(ipv4->destipaddr, dst_ip);
net_ipv4addr_hdrcopy(ipv4->srcipaddr, src_ip);
/* if ip has options, build it now */
if (opt != NULL)
{
ipv4->vhl += opt->len >> 2;
memcpy(ipv4 + 1, opt->data, opt->len);
}
/* Calculate IP checksum. */
ipv4->ipchksum = 0;
ipv4->ipchksum = ~ipv4_chksum(ipv4);
ninfo("IPv4 Packet: ipid:%d, length: %d\n", g_ipid, total_len);
return (ipv4->vhl & IPv4_HLMASK) << 2;
}
#endif /* CONFIG_NET_IPv4 */

View File

@ -0,0 +1,81 @@
/****************************************************************************
* net/inet/ipv6_build_header.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/netconfig.h>
#include "inet.h"
#ifdef CONFIG_NET_IPv6
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ipv6_build_header
*
* Description:
* build IPv6 header
*
* Input Parameters:
* ipv6 Pointer to IPv6 header's buffer
* payload_len Length of the IPv6 payload(without IPv6 header length)
* prot Type of header immediately following the IPv6 header
* src_ip Source IPv6 address
* dst_ip Destination IPv6 address
* ttl Time to live(IPv4) hop limit(IPv6)
*
* Returned Value:
* length of IPv6 header
*
****************************************************************************/
uint16_t ipv6_build_header(FAR struct ipv6_hdr_s *ipv6, uint16_t payload_len,
uint16_t prot, const net_ipv6addr_t src_ip,
const net_ipv6addr_t dst_ip, uint8_t ttl)
{
/* Set up the IPv6 header */
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class(LS)/Flow label(MS) */
ipv6->flow = 0; /* Flow label (LS) */
ipv6->len[0] = (payload_len >> 8); /* Length excludes the IPv6 header */
ipv6->len[1] = (payload_len & 0xff);
ipv6->proto = prot; /* Next header */
ipv6->ttl = ttl;
/* It's possible to use srcip to initialize destip */
net_ipv6addr_hdrcopy(ipv6->destipaddr, dst_ip);
net_ipv6addr_hdrcopy(ipv6->srcipaddr, src_ip);
ninfo("IPv6 Payload length: %d\n", payload_len);
return IPv6_HDRLEN;
}
#endif /* CONFIG_NET_IPv6 */

View File

@ -87,7 +87,6 @@
void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group, void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
uint8_t msgtype) uint8_t msgtype)
{ {
FAR struct ipv6_hdr_s *ipv6;
FAR struct ipv6_router_alert_s *ra; FAR struct ipv6_router_alert_s *ra;
FAR const uint16_t *destipaddr; FAR const uint16_t *destipaddr;
unsigned int mldsize; unsigned int mldsize;
@ -160,23 +159,6 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
dev->d_sndlen = RASIZE + mldsize; dev->d_sndlen = RASIZE + mldsize;
/* Set up the IPv6 header */
ipv6 = IPv6BUF;
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class(LS)/Flow label(MS) */
ipv6->flow = 0; /* Flow label (LS) */
ipv6->len[0] = (dev->d_sndlen >> 8); /* Length excludes the IPv6 header */
ipv6->len[1] = (dev->d_sndlen & 0xff); /* but includes the extension headers */
ipv6->proto = NEXT_HOPBYBOT_EH; /* Hop-to-hop extension header */
ipv6->ttl = MLD_TTL; /* MLD Time-to-live */
/* Select the IPv6 source address (the local interface assigned to the
* network device).
*/
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Select the IPv6 destination address. /* Select the IPv6 destination address.
* This varies with the type of message being sent: * This varies with the type of message being sent:
* *
@ -216,7 +198,8 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
destipaddr[0], destipaddr[1], destipaddr[2], destipaddr[3], destipaddr[0], destipaddr[1], destipaddr[2], destipaddr[3],
destipaddr[4], destipaddr[5], destipaddr[6], destipaddr[7]); destipaddr[4], destipaddr[5], destipaddr[6], destipaddr[7]);
net_ipv6addr_hdrcopy(ipv6->destipaddr, destipaddr); ipv6_build_header(IPv6BUF, dev->d_sndlen, NEXT_HOPBYBOT_EH,
dev->d_ipv6addr, destipaddr, MLD_TTL);
/* Add the router alert IP header option. /* Add the router alert IP header option.
* *
@ -379,8 +362,7 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
MLD_STATINCR(g_netstats.icmpv6.sent); MLD_STATINCR(g_netstats.icmpv6.sent);
MLD_STATINCR(g_netstats.ipv6.sent); MLD_STATINCR(g_netstats.ipv6.sent);
mldinfo("Outgoing ICMPv6 MLD packet length: %d (%d)\n", mldinfo("Outgoing ICMPv6 MLD packet length: %d\n", dev->d_len);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
mld_dumppkt((FAR const uint8_t *)IPv6BUF, MLD_HDRLEN + mldsize); mld_dumppkt((FAR const uint8_t *)IPv6BUF, MLD_HDRLEN + mldsize);
} }

View File

@ -101,184 +101,6 @@ static inline FAR struct tcp_hdr_s *tcp_header(FAR struct net_driver_s *dev)
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
} }
/****************************************************************************
* Name: tcp_sendcomplete, tcp_ipv4_sendcomplete, and tcp_ipv6_sendcomplete
*
* Description:
* Complete the final portions of the send operation. This function sets
* up IP header and computes the TCP checksum
*
* Input Parameters:
* dev - The device driver structure to use in the send operation
*
* Returned Value:
* None
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_IPv4
static inline void tcp_ipv4_sendcomplete(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp,
FAR struct ipv4_hdr_s *ipv4)
{
/* Set up some IP header fields that are needed for TCP checksum
* calculation.
*/
ipv4->proto = IP_PROTO_TCP;
ipv4->ttl = IP_TTL_DEFAULT;
ipv4->vhl = 0x45;
/* At this point the TCP header holds the size of the payload, the
* TCP header, and the IP header.
*/
ipv4->len[0] = (dev->d_len >> 8);
ipv4->len[1] = (dev->d_len & 0xff);
/* Calculate TCP checksum. */
tcp->urgp[0] = 0;
tcp->urgp[1] = 0;
tcp->tcpchksum = 0;
tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
/* Finish initializing the IP header and calculate the IP checksum */
ipv4->vhl = 0x45;
ipv4->tos = 0;
ipv4->ipoffset[0] = 0;
ipv4->ipoffset[1] = 0;
++g_ipid;
ipv4->ipid[0] = g_ipid >> 8;
ipv4->ipid[1] = g_ipid & 0xff;
/* Calculate IP checksum. */
ipv4->ipchksum = 0;
ipv4->ipchksum = ~ipv4_chksum(dev);
ninfo("IPv4 length: %d\n", ((int)ipv4->len[0] << 8) + ipv4->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv4.sent++;
#endif
}
#endif /* CONFIG_NET_IPv4 */
/****************************************************************************
* Name: tcp_ipv6_sendcomplete
*
* Description:
* Complete the final portions of the send operation. This function sets
* up IP header and computes the TCP checksum
*
* Input Parameters:
* dev - The device driver structure to use in the send operation
*
* Returned Value:
* None
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_IPv6
static inline void tcp_ipv6_sendcomplete(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp,
FAR struct ipv6_hdr_s *ipv6)
{
uint16_t iplen;
/* Set up some IP header fields that are needed for TCP checksum
* calculation.
*/
ipv6->proto = IP_PROTO_TCP;
ipv6->ttl = IP_TTL_DEFAULT;
/* At this point the TCP header holds the size of the payload, the
* TCP header, and the IP header. For IPv6, the IP length field does
* not include the size of IPv6 IP header length.
*/
iplen = dev->d_len - IPv6_HDRLEN;
ipv6->len[0] = (iplen >> 8);
ipv6->len[1] = (iplen & 0xff);
/* Calculate TCP checksum. */
tcp->urgp[0] = 0;
tcp->urgp[1] = 0;
tcp->tcpchksum = 0;
tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
/* Finish initializing the IP header (no IPv6 checksum) */
ipv6->vtc = 0x60;
ipv6->tcf = 0x00;
ipv6->flow = 0x00;
ninfo("IPv6 length: %d\n", ((int)ipv6->len[0] << 8) + ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.sent++;
#endif
}
#endif /* CONFIG_NET_IPv6 */
/****************************************************************************
* Name: tcp_sendcomplete
*
* Description:
* Complete the final portions of the send operation. This function sets
* up IP header and computes the TCP checksum
*
* Input Parameters:
* dev - The device driver structure to use in the send operation
*
* Returned Value:
* None
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
static void tcp_sendcomplete(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp)
{
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (IFF_IS_IPv6(dev->d_flags))
#endif
{
tcp_ipv6_sendcomplete(dev, tcp, IPv6BUF);
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
tcp_ipv4_sendcomplete(dev, tcp, IPv4BUF);
}
#endif /* CONFIG_NET_IPv4 */
ninfo("Outgoing TCP packet length: %d bytes\n", dev->d_len);
#ifdef CONFIG_NET_STATISTICS
g_netstats.tcp.sent++;
#endif
}
/**************************************************************************** /****************************************************************************
* Name: tcp_sendcommon * Name: tcp_sendcommon
* *
@ -303,32 +125,6 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
FAR struct tcp_conn_s *conn, FAR struct tcp_conn_s *conn,
FAR struct tcp_hdr_s *tcp) FAR struct tcp_hdr_s *tcp)
{ {
/* Copy the IP address into the IPv6 header */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (IFF_IS_IPv6(dev->d_flags))
#endif
{
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_hdrcopy(ipv6->destipaddr, conn->u.ipv6.raddr);
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr);
}
#endif /* CONFIG_NET_IPv4 */
/* Set TCP sequence numbers and port numbers */ /* Set TCP sequence numbers and port numbers */
memcpy(tcp->ackno, conn->rcvseq, 4); memcpy(tcp->ackno, conn->rcvseq, 4);
@ -369,9 +165,55 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
tcp->wnd[1] = recvwndo & 0xff; tcp->wnd[1] = recvwndo & 0xff;
} }
/* Finish the IP portion of the message and calculate checksums */ tcp->urgp[0] = 0;
tcp->urgp[1] = 0;
tcp_sendcomplete(dev, tcp); /* Calculate chk & build L3 header */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (IFF_IS_IPv6(dev->d_flags))
#endif
{
ninfo("do IPv6 IP header build!\n");
ipv6_build_header(IPv6BUF, dev->d_len - IPv6_HDRLEN,
IP_PROTO_TCP, dev->d_ipv6addr, conn->u.ipv6.raddr,
IP_TTL_DEFAULT);
/* Calculate TCP checksum. */
tcp->tcpchksum = 0;
tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.sent++;
#endif
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
else
#endif
{
ninfo("do IPv4 IP header build!\n");
ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_TCP,
&dev->d_ipaddr, &conn->u.ipv4.raddr,
IP_TTL_DEFAULT, NULL);
/* Calculate TCP checksum. */
tcp->tcpchksum = 0;
tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv4.sent++;
#endif
}
#endif /* CONFIG_NET_IPv4 */
ninfo("Outgoing TCP packet length: %d bytes\n", dev->d_len);
#ifdef CONFIG_NET_STATISTICS
g_netstats.tcp.sent++;
#endif
#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS) #if !defined(CONFIG_NET_TCP_WRITE_BUFFERS)
if ((tcp->flags & (TCP_SYN | TCP_FIN)) != 0) if ((tcp->flags & (TCP_SYN | TCP_FIN)) != 0)
@ -524,14 +366,14 @@ void tcp_reset(FAR struct net_driver_s *dev)
tcp->destport = tmp16; tcp->destport = tmp16;
/* Initialize the rest of the tcp header to sane values. /* Initialize the rest of the tcp header to sane values.
*
* Note: urgp is set by tcp_ipv4_sendcomplete/tcp_ipv6_sendcomplete.
*/ */
tcp->wnd[0] = 0; tcp->wnd[0] = 0;
tcp->wnd[1] = 0; tcp->wnd[1] = 0;
tcp->urgp[0] = 0;
tcp->urgp[0] = 0;
/* Set the packet length and swap IP addresses. */ /* Calculate chk & build L3 header */
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
@ -544,10 +386,12 @@ void tcp_reset(FAR struct net_driver_s *dev)
dev->d_len = IPv6TCP_HDRLEN; dev->d_len = IPv6TCP_HDRLEN;
/* Swap IPv6 addresses */ ipv6_build_header(ipv6, dev->d_len - IPv6_HDRLEN,
IP_PROTO_TCP, dev->d_ipv6addr, ipv6->srcipaddr,
IP_TTL_DEFAULT);
net_ipv6addr_hdrcopy(ipv6->destipaddr, ipv6->srcipaddr); tcp->tcpchksum = 0;
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr); tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
} }
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
@ -562,16 +406,14 @@ void tcp_reset(FAR struct net_driver_s *dev)
dev->d_len = IPv4TCP_HDRLEN; dev->d_len = IPv4TCP_HDRLEN;
/* Swap IPv4 addresses */ ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_TCP,
&dev->d_ipaddr, (FAR in_addr_t *)ipv4->srcipaddr,
IP_TTL_DEFAULT, NULL);
net_ipv4addr_hdrcopy(ipv4->destipaddr, ipv4->srcipaddr); tcp->tcpchksum = 0;
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr); tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
} }
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
/* And send out the RST packet */
tcp_sendcomplete(dev, tcp);
} }
/**************************************************************************** /****************************************************************************

View File

@ -86,13 +86,14 @@
void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn) void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
{ {
FAR struct udp_hdr_s *udp; FAR struct udp_hdr_s *udp;
#ifdef CONFIG_NET_IPv4
in_addr_t raddr;
#endif
ninfo("UDP payload: %d (%d) bytes\n", dev->d_sndlen, dev->d_len); ninfo("UDP payload: %d (%d) bytes\n", dev->d_sndlen, dev->d_len);
if (dev->d_sndlen > 0) if (dev->d_sndlen > 0)
{ {
/* Initialize the IP header. */
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
if (conn->domain == PF_INET || if (conn->domain == PF_INET ||
@ -100,39 +101,19 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr))) ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr)))
#endif #endif
{ {
/* Get pointers to the IPv4 header and the offset UDP header */
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
DEBUGASSERT(IFF_IS_IPv4(dev->d_flags)); DEBUGASSERT(IFF_IS_IPv4(dev->d_flags));
udp = UDPIPv4BUF; udp = UDPIPv4BUF;
/* Initialize the IPv4 header. */
ipv4->vhl = 0x45;
ipv4->tos = 0;
++g_ipid;
ipv4->ipid[0] = g_ipid >> 8;
ipv4->ipid[1] = g_ipid & 0xff;
ipv4->ipoffset[0] = 0;
ipv4->ipoffset[1] = 0;
ipv4->ttl = conn->ttl;
ipv4->proto = IP_PROTO_UDP;
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
if (conn->domain == PF_INET6 && if (conn->domain == PF_INET6 &&
ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr)) ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr))
{ {
in_addr_t raddr = raddr =
ip6_get_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr); ip6_get_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr);
net_ipv4addr_hdrcopy(ipv4->destipaddr, &raddr);
} }
else else
#endif #endif
{ {
net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr); raddr = conn->u.ipv4.raddr;
} }
/* The total length to send is the size of the application data /* The total length to send is the size of the application data
@ -142,15 +123,9 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
dev->d_len = dev->d_sndlen + IPv4UDP_HDRLEN; dev->d_len = dev->d_sndlen + IPv4UDP_HDRLEN;
/* The IPv4 length includes the size of the IPv4 header */ ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_UDP,
&dev->d_ipaddr, &raddr, IP_TTL_DEFAULT,
ipv4->len[0] = (dev->d_len >> 8); NULL);
ipv4->len[1] = (dev->d_len & 0xff);
/* Calculate IP checksum. */
ipv4->ipchksum = 0;
ipv4->ipchksum = ~ipv4_chksum(dev);
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.ipv4.sent++; g_netstats.ipv4.sent++;
@ -165,31 +140,17 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
{ {
/* Get pointers to the IPv6 header and the offset UDP header */ /* Get pointers to the IPv6 header and the offset UDP header */
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
DEBUGASSERT(IFF_IS_IPv6(dev->d_flags)); DEBUGASSERT(IFF_IS_IPv6(dev->d_flags));
udp = UDPIPv6BUF; udp = UDPIPv6BUF;
/* Initialize the IPv6 header. Note that the IP length field
* does not include the IPv6 IP header length.
*/
ipv6->vtc = 0x60;
ipv6->tcf = 0x00;
ipv6->flow = 0x00;
ipv6->proto = IP_PROTO_UDP;
ipv6->ttl = conn->ttl;
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_copy(ipv6->destipaddr, conn->u.ipv6.raddr);
/* The IPv6 length, Includes the UDP header size but not the IPv6 /* The IPv6 length, Includes the UDP header size but not the IPv6
* header size * header size
*/ */
dev->d_len = dev->d_sndlen + UDP_HDRLEN; dev->d_len = dev->d_sndlen + UDP_HDRLEN;
ipv6->len[0] = (dev->d_len >> 8);
ipv6->len[1] = (dev->d_len & 0xff); ipv6_build_header(IPv6BUF, dev->d_len, IP_PROTO_UDP,
dev->d_ipv6addr, conn->u.ipv6.raddr, conn->ttl);
/* The total length to send is the size of the application data /* The total length to send is the size of the application data
* plus the IPv6 and UDP headers (and, eventually, the link layer * plus the IPv6 and UDP headers (and, eventually, the link layer

View File

@ -21,6 +21,6 @@ config NET_ARCH_CHKSUM
uint16_t chksum(uint16_t sum, FAR const uint8_t *data, uint16_t len) uint16_t chksum(uint16_t sum, FAR const uint8_t *data, uint16_t len)
uint16_t net_chksum(FAR uint16_t *data, uint16_t len) uint16_t net_chksum(FAR uint16_t *data, uint16_t len)
uint16_t ipv4_chksum(FAR struct net_driver_s *dev) uint16_t ipv4_chksum(FAR struct ipv4_hdr_s *ipv4)
uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto) uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto, unsigned int iplen) uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto, unsigned int iplen)

View File

@ -183,9 +183,8 @@ uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev,
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_NET_IPv4) && !defined(CONFIG_NET_ARCH_CHKSUM) #if defined(CONFIG_NET_IPv4) && !defined(CONFIG_NET_ARCH_CHKSUM)
uint16_t ipv4_chksum(FAR struct net_driver_s *dev) uint16_t ipv4_chksum(FAR struct ipv4_hdr_s *ipv4)
{ {
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
uint16_t iphdrlen; uint16_t iphdrlen;
uint16_t sum; uint16_t sum;
@ -193,7 +192,7 @@ uint16_t ipv4_chksum(FAR struct net_driver_s *dev)
iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2;
sum = chksum(0, IPBUF(0), iphdrlen); sum = chksum(0, (FAR const uint8_t *)ipv4, iphdrlen);
return (sum == 0) ? 0xffff : HTONS(sum); return (sum == 0) ? 0xffff : HTONS(sum);
} }
#endif /* CONFIG_NET_ARCH_CHKSUM */ #endif /* CONFIG_NET_ARCH_CHKSUM */

View File

@ -260,6 +260,27 @@ void net_chksum_adjust(FAR uint16_t *chksum,
FAR const uint16_t *optr, ssize_t olen, FAR const uint16_t *optr, ssize_t olen,
FAR const uint16_t *nptr, ssize_t nlen); FAR const uint16_t *nptr, ssize_t nlen);
/****************************************************************************
* Name: ipv4_chksum
*
* Description:
* Calculate the IPv4 header checksum of the packet header in d_buf.
*
* The IPv4 header checksum is the Internet checksum of the 20 bytes of
* the IPv4 header.
*
* If CONFIG_NET_ARCH_CHKSUM is defined, then this function must be
* provided by architecture-specific logic.
*
* Returned Value:
* The IPv4 header checksum of the IPv4 header in the d_buf buffer.
*
****************************************************************************/
#ifdef CONFIG_NET_IPv4
uint16_t ipv4_chksum(FAR struct ipv4_hdr_s *ipv4);
#endif
/**************************************************************************** /****************************************************************************
* Name: ipv4_upperlayer_chksum * Name: ipv4_upperlayer_chksum
* *