net: extract l3 header build code into new functions
Signed-off-by: liyi <liyi25@xiaomi.com>
This commit is contained in:
parent
d54a20b393
commit
391b501639
@ -88,6 +88,7 @@
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
# define IPv4_HDRLEN 20 /* Size of IPv4 header (without options) */
|
||||
# define IPv4_HLMASK 0x0f /* Isolates headler length in VHL field */
|
||||
# define IPV4_OPTMAX 40 /* The limit of ip option length */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
@ -164,6 +165,14 @@ struct ipv4_hdr_s
|
||||
uint16_t srcipaddr[2]; /* 32-bit Source 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 */
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
@ -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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
|
@ -105,6 +105,7 @@
|
||||
#include "ipforward/ipforward.h"
|
||||
#include "devif/devif.h"
|
||||
#include "nat/nat.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@ -342,7 +343,7 @@ int ipv4_input(FAR struct net_driver_s *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ipv4_chksum(dev) != 0xffff)
|
||||
if (ipv4_chksum(IPv4BUF) != 0xffff)
|
||||
{
|
||||
/* Compute and check the IP header checksum. */
|
||||
|
||||
|
@ -127,27 +127,9 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
|
||||
|
||||
memmove(icmp + 1, ipv4, datalen);
|
||||
|
||||
/* Initialize the IP header. */
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_ICMP,
|
||||
&dev->d_ipaddr, (FAR in_addr_t *)ipv4->srcipaddr,
|
||||
IP_TTL_DEFAULT, NULL);
|
||||
|
||||
/* Initialize the ICMP header */
|
||||
|
||||
@ -165,8 +147,7 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
|
||||
icmp->icmpchksum = 0xffff;
|
||||
}
|
||||
|
||||
ninfo("Outgoing ICMP packet length: %d (%d)\n",
|
||||
dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
|
||||
ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ICMP */
|
||||
|
@ -97,7 +97,6 @@ struct icmp_sendto_s
|
||||
static void sendto_request(FAR struct net_driver_s *dev,
|
||||
FAR struct icmp_sendto_s *pstate)
|
||||
{
|
||||
FAR struct ipv4_hdr_s *ipv4;
|
||||
FAR struct icmp_hdr_s *icmp;
|
||||
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
|
||||
icmp = IPBUF(IPv4_HDRLEN);
|
||||
memcpy(icmp, pstate->snd_buf, pstate->snd_buflen);
|
||||
|
||||
/* Calculate IP checksum. */
|
||||
/* Initialize the IP header. */
|
||||
|
||||
ipv4->ipchksum = 0;
|
||||
ipv4->ipchksum = ~(ipv4_chksum(dev));
|
||||
ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_ICMP,
|
||||
&dev->d_ipaddr, &pstate->snd_toaddr,
|
||||
IP_TTL_DEFAULT, NULL);
|
||||
|
||||
/* Calculate the ICMP checksum. */
|
||||
|
||||
@ -149,8 +131,7 @@ static void sendto_request(FAR struct net_driver_s *dev,
|
||||
icmp->icmpchksum = 0xffff;
|
||||
}
|
||||
|
||||
ninfo("Outgoing ICMP packet length: %d (%d)\n",
|
||||
dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
|
||||
ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmp.sent++;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "netdev/netdev.h"
|
||||
#include "utils/utils.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
#include "inet/inet.h"
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
|
||||
@ -66,31 +67,17 @@
|
||||
void icmpv6_advertise(FAR struct net_driver_s *dev,
|
||||
const net_ipv6addr_t destipaddr)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
||||
FAR struct icmpv6_neighbor_advertise_s *adv;
|
||||
uint16_t lladdrsize;
|
||||
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 */
|
||||
|
||||
lladdrsize = netdev_lladdrsize(dev);
|
||||
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->ttl = 255; /* Hop limit */
|
||||
|
||||
/* 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);
|
||||
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
|
||||
dev->d_ipv6addr, destipaddr, 255);
|
||||
|
||||
/* 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;
|
||||
|
||||
ninfo("Outgoing ICMPv6 Neighbor Advertise length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
ninfo("Outgoing ICMPv6 Neighbor Advertise length: %d\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmpv6.sent++;
|
||||
|
@ -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)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
||||
FAR struct icmpv6_router_advertise_s *adv;
|
||||
FAR struct icmpv6_srclladdr_s *srcaddr;
|
||||
FAR struct icmpv6_mtu_s *mtu;
|
||||
FAR struct icmpv6_prefixinfo_s *prefix;
|
||||
net_ipv6addr_t srcv6addr;
|
||||
uint16_t lladdrsize;
|
||||
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 */
|
||||
|
||||
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_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 */
|
||||
|
||||
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 */
|
||||
|
||||
@ -215,8 +202,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
||||
|
||||
dev->d_len = IPv6_HDRLEN + l3size;
|
||||
|
||||
ninfo("Outgoing ICMPv6 Router Advertise length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
ninfo("Outgoing ICMPv6 Router Advertise length: %d\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmpv6.sent++;
|
||||
|
@ -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 icmpv6_hdr_s *icmpv6 = (FAR struct icmpv6_hdr_s *)(ipv6 + 1);
|
||||
uint16_t datalen;
|
||||
uint16_t paylen;
|
||||
|
||||
if (net_ipv6addr_cmp(ipv6->destipaddr, g_ipv6_unspecaddr)
|
||||
# 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;
|
||||
paylen = dev->d_len - IPv6_HDRLEN;
|
||||
|
||||
/* Copy fields from original packet */
|
||||
|
||||
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);
|
||||
ipv6_build_header(IPv6BUF, dev->d_len - IPv6_HDRLEN, IP_PROTO_ICMP6,
|
||||
dev->d_ipv6addr, ipv6->srcipaddr, 255);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
ninfo("Outgoing ICMPv6 packet length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ICMPv6 */
|
||||
|
@ -66,37 +66,17 @@
|
||||
|
||||
void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6;
|
||||
FAR struct icmpv6_router_solicit_s *sol;
|
||||
uint16_t lladdrsize;
|
||||
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 */
|
||||
|
||||
lladdrsize = netdev_lladdrsize(dev);
|
||||
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->ttl = 255; /* Hop limit */
|
||||
|
||||
/* 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);
|
||||
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
|
||||
dev->d_ipv6addr, g_ipv6_allrouters, 255);
|
||||
|
||||
/* 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;
|
||||
|
||||
ninfo("Outgoing ICMPv6 Router Solicitation length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
ninfo("Outgoing ICMPv6 Router Solicitation length: %d\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmpv6.sent++;
|
||||
|
@ -96,7 +96,6 @@ struct icmpv6_sendto_s
|
||||
static void sendto_request(FAR struct net_driver_s *dev,
|
||||
FAR struct icmpv6_sendto_s *pstate)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6;
|
||||
FAR struct icmpv6_echo_request_s *icmpv6;
|
||||
|
||||
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;
|
||||
|
||||
/* 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) */
|
||||
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);
|
||||
ipv6_build_header(IPv6BUF, pstate->snd_buflen, IP_PROTO_ICMP6,
|
||||
dev->d_ipv6addr, pstate->snd_toaddr.s6_addr16, 255);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
ninfo("Outgoing ICMPv6 packet length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmpv6.sent++;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "netdev/netdev.h"
|
||||
#include "utils/utils.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
#include "inet/inet.h"
|
||||
|
||||
#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,
|
||||
FAR const net_ipv6addr_t ipaddr)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6;
|
||||
FAR struct icmpv6_neighbor_solicit_s *sol;
|
||||
net_ipv6addr_t dstaddr;
|
||||
uint16_t lladdrsize;
|
||||
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 */
|
||||
|
||||
lladdrsize = netdev_lladdrsize(dev);
|
||||
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 */
|
||||
|
||||
memcpy(ipv6->destipaddr, g_icmpv_mcastaddr, 6*sizeof(uint16_t));
|
||||
ipv6->destipaddr[6] = ipaddr[6] | HTONS(0xff00);
|
||||
ipv6->destipaddr[7] = ipaddr[7];
|
||||
memcpy(dstaddr, g_icmpv_mcastaddr, sizeof(g_icmpv_mcastaddr));
|
||||
dstaddr[6] = ipaddr[6] | HTONS(0xff00);
|
||||
dstaddr[7] = ipaddr[7];
|
||||
|
||||
/* Add out IPv6 address as the source address */
|
||||
|
||||
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
|
||||
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
|
||||
dev->d_ipv6addr, dstaddr, 255);
|
||||
|
||||
/* 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;
|
||||
|
||||
ninfo("Outgoing ICMPv6 Neighbor Solicitation length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
ninfo("Outgoing ICMPv6 Neighbor Solicitation length: %d\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.icmpv6.sent++;
|
||||
|
@ -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,
|
||||
FAR const in_addr_t *destipaddr, uint8_t msgid)
|
||||
{
|
||||
FAR struct igmp_iphdr_s *ipv4 = IPBUF(0);
|
||||
FAR struct igmp_hdr_s *igmp;
|
||||
uint16_t iphdrlen;
|
||||
struct ipv4_opt_s opt;
|
||||
uint32_t tmp;
|
||||
|
||||
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) */
|
||||
|
||||
ipv4->ra[0] = HTONS(IPOPT_RA >> 16);
|
||||
ipv4->ra[1] = HTONS(IPOPT_RA & 0xffff);
|
||||
tmp = HTONL(IPOPT_RA);
|
||||
memcpy(opt.data, &tmp, sizeof(uint32_t));
|
||||
opt.len = sizeof(uint32_t);
|
||||
|
||||
/* Initialize the IPv4 header */
|
||||
|
||||
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);
|
||||
ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_IGMP,
|
||||
&dev->d_ipaddr, destipaddr, IGMP_TTL, &opt);
|
||||
|
||||
/* 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.ipv4.sent);
|
||||
|
||||
ninfo("Outgoing IGMP packet length: %d (%d)\n",
|
||||
dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
|
||||
ninfo("Outgoing IGMP packet length: %d\n", dev->d_len);
|
||||
igmp_dumppkt(RA, iphdrlen + IGMP_HDRLEN);
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,11 @@ SOCK_CSRCS += inet_globals.c
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# Include inet build support
|
||||
|
@ -67,12 +67,6 @@ extern "C"
|
||||
#define EXTERN extern
|
||||
#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 */
|
||||
|
||||
#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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -38,12 +38,6 @@
|
||||
* 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
|
||||
|
||||
/* Unspecified address (all zero). See RFC 4291 (replaces 3513) */
|
||||
|
109
net/inet/ipv4_build_header.c
Normal file
109
net/inet/ipv4_build_header.c
Normal 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 */
|
81
net/inet/ipv6_build_header.c
Normal file
81
net/inet/ipv6_build_header.c
Normal 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 */
|
@ -87,7 +87,6 @@
|
||||
void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
|
||||
uint8_t msgtype)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6;
|
||||
FAR struct ipv6_router_alert_s *ra;
|
||||
FAR const uint16_t *destipaddr;
|
||||
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;
|
||||
|
||||
/* 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.
|
||||
* 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[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.
|
||||
*
|
||||
@ -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.ipv6.sent);
|
||||
|
||||
mldinfo("Outgoing ICMPv6 MLD packet length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
mldinfo("Outgoing ICMPv6 MLD packet length: %d\n", dev->d_len);
|
||||
|
||||
mld_dumppkt((FAR const uint8_t *)IPv6BUF, MLD_HDRLEN + mldsize);
|
||||
}
|
||||
|
@ -101,184 +101,6 @@ static inline FAR struct tcp_hdr_s *tcp_header(FAR struct net_driver_s *dev)
|
||||
#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
|
||||
*
|
||||
@ -303,32 +125,6 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
||||
FAR struct tcp_conn_s *conn,
|
||||
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 */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 ((tcp->flags & (TCP_SYN | TCP_FIN)) != 0)
|
||||
@ -524,14 +366,14 @@ void tcp_reset(FAR struct net_driver_s *dev)
|
||||
tcp->destport = tmp16;
|
||||
|
||||
/* 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[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_IPv4
|
||||
@ -544,10 +386,12 @@ void tcp_reset(FAR struct net_driver_s *dev)
|
||||
|
||||
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);
|
||||
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
|
||||
tcp->tcpchksum = 0;
|
||||
tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
|
||||
}
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
@ -562,16 +406,14 @@ void tcp_reset(FAR struct net_driver_s *dev)
|
||||
|
||||
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);
|
||||
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
|
||||
tcp->tcpchksum = 0;
|
||||
tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
|
||||
}
|
||||
#endif /* CONFIG_NET_IPv4 */
|
||||
|
||||
/* And send out the RST packet */
|
||||
|
||||
tcp_sendcomplete(dev, tcp);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -86,13 +86,14 @@
|
||||
void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
|
||||
{
|
||||
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);
|
||||
|
||||
if (dev->d_sndlen > 0)
|
||||
{
|
||||
/* Initialize the IP header. */
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
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)))
|
||||
#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));
|
||||
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
|
||||
if (conn->domain == PF_INET6 &&
|
||||
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);
|
||||
net_ipv4addr_hdrcopy(ipv4->destipaddr, &raddr);
|
||||
}
|
||||
else
|
||||
#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
|
||||
@ -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;
|
||||
|
||||
/* The IPv4 length includes the size of the IPv4 header */
|
||||
|
||||
ipv4->len[0] = (dev->d_len >> 8);
|
||||
ipv4->len[1] = (dev->d_len & 0xff);
|
||||
|
||||
/* Calculate IP checksum. */
|
||||
|
||||
ipv4->ipchksum = 0;
|
||||
ipv4->ipchksum = ~ipv4_chksum(dev);
|
||||
ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_UDP,
|
||||
&dev->d_ipaddr, &raddr, IP_TTL_DEFAULT,
|
||||
NULL);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
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 */
|
||||
|
||||
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
||||
|
||||
DEBUGASSERT(IFF_IS_IPv6(dev->d_flags));
|
||||
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
|
||||
* header size
|
||||
*/
|
||||
|
||||
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
|
||||
* plus the IPv6 and UDP headers (and, eventually, the link layer
|
||||
|
@ -21,6 +21,6 @@ config NET_ARCH_CHKSUM
|
||||
|
||||
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 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 ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto, unsigned int iplen)
|
||||
|
@ -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)
|
||||
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 sum;
|
||||
|
||||
@ -193,7 +192,7 @@ uint16_t ipv4_chksum(FAR struct net_driver_s *dev)
|
||||
|
||||
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);
|
||||
}
|
||||
#endif /* CONFIG_NET_ARCH_CHKSUM */
|
||||
|
@ -260,6 +260,27 @@ void net_chksum_adjust(FAR uint16_t *chksum,
|
||||
FAR const uint16_t *optr, ssize_t olen,
|
||||
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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user