diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 78210d4cc7..7c6b962b6b 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -871,6 +871,48 @@ uint16_t net_chksum(FAR uint16_t *data, uint16_t len); uint16_t net_chksum_iob(uint16_t sum, FAR struct iob_s *iob, uint16_t offset); +#ifdef CONFIG_NET_IPv4 + +/**************************************************************************** + * Name: ipv4_upperlayer_header_chksum + * + * Description: + * Perform the checksum calculation over the IPv4, protocol headers, + * IP source and destination addresses + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * proto - The protocol being supported + * + * Returned Value: + * The calculated checksum with pseudo-header and IP source and + * destination addresses + * + ****************************************************************************/ + +uint16_t ipv4_upperlayer_header_chksum(FAR struct net_driver_s *dev, + uint8_t proto); + +/**************************************************************************** + * Name: ipv4_upperlayer_payload_chksum + * + * Description: + * Perform the checksum calculation over the iob data payload + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * sum - The default checksum + * + * Returned Value: + * The calculated checksum with iob data payload and default checksum + * + ****************************************************************************/ + +uint16_t ipv4_upperlayer_payload_chksum(FAR struct net_driver_s *dev, + uint16_t sum); + /**************************************************************************** * Name: ipv4_upperlayer_chksum * @@ -888,10 +930,57 @@ uint16_t net_chksum_iob(uint16_t sum, FAR struct iob_s *iob, * ****************************************************************************/ -#ifdef CONFIG_NET_IPv4 uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto); #endif /* CONFIG_NET_IPv4 */ +#ifdef CONFIG_NET_IPv6 + +/**************************************************************************** + * Name: ipv6_upperlayer_header_chksum + * + * Description: + * Perform the checksum calculation over the IPv6, protocol headers, + * IP source and destination addresses. + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * proto - The protocol being supported + * iplen - The size of the IPv6 header. This may be larger than + * IPv6_HDRLEN the IPv6 header if IPv6 extension headers are + * present. + * + * Returned Value: + * The calculated checksum + * + ****************************************************************************/ + +uint16_t ipv6_upperlayer_header_chksum(FAR struct net_driver_s *dev, + uint8_t proto, unsigned int iplen); + +/**************************************************************************** + * Name: ipv6_upperlayer_payload_chksum + * + * Description: + * Perform the checksum calculation over the iob data payload and + * default checksum. + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * proto - The protocol being supported + * iplen - The size of the IPv6 header. This may be larger than + * IPv6_HDRLEN the IPv6 header if IPv6 extension headers are + * present. + * + * Returned Value: + * The calculated checksum + * + ****************************************************************************/ + +uint16_t ipv6_upperlayer_payload_chksum(FAR struct net_driver_s *dev, + unsigned int iplen, uint16_t sum); + /**************************************************************************** * Name: ipv6_upperlayer_chksum * @@ -912,7 +1001,6 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto); * ****************************************************************************/ -#ifdef CONFIG_NET_IPv6 uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto, unsigned int iplen); #endif /* CONFIG_NET_IPv6 */ diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c index cced7577ee..19c207b90a 100644 --- a/net/devif/ipv4_input.c +++ b/net/devif/ipv4_input.c @@ -381,6 +381,7 @@ static int ipv4_in(FAR struct net_driver_s *dev) } #endif +#ifdef CONFIG_NET_IPV4_CHECKSUMS if (ipv4_chksum(IPv4BUF) != 0xffff) { /* Compute and check the IP header checksum. */ @@ -392,6 +393,7 @@ static int ipv4_in(FAR struct net_driver_s *dev) nwarn("WARNING: Bad IP checksum\n"); goto drop; } +#endif #ifdef CONFIG_NET_IPFILTER if (ipv4_filter_in(dev) != IPFILTER_TARGET_ACCEPT) diff --git a/net/icmp/Kconfig b/net/icmp/Kconfig index cdbacfd4de..aae4573468 100644 --- a/net/icmp/Kconfig +++ b/net/icmp/Kconfig @@ -43,6 +43,12 @@ config NET_ICMP_SOCKET for application level support for sending ECHO (ping) requests and receiving associated ECHO replies. +config NET_ICMP_CHECKSUMS + bool "ICMP checksums" + default y + ---help--- + Enable/disable ICMP checksum support. + if NET_ICMP_SOCKET config NET_ICMP_PREALLOC_CONNS diff --git a/net/icmp/icmp_input.c b/net/icmp/icmp_input.c index da0435f82c..f88310c030 100644 --- a/net/icmp/icmp_input.c +++ b/net/icmp/icmp_input.c @@ -324,7 +324,7 @@ void icmp_input(FAR struct net_driver_s *dev) /* The quick way -- Since only the type has changed, just adjust the * checksum for the change of type */ - +#ifdef CONFIG_NET_ICMP_CHECKSUMS if (icmp->icmpchksum >= HTONS(0xffff - (ICMP_ECHO_REQUEST << 8))) { icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8) + 1; @@ -333,6 +333,10 @@ void icmp_input(FAR struct net_driver_s *dev) { icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8); } +#else + icmp->icmpchksum = 0; +#endif + #endif ninfo("Outgoing ICMP packet length: %d (%d)\n", diff --git a/net/icmp/icmp_reply.c b/net/icmp/icmp_reply.c index 5a6ca57520..df65e9b651 100644 --- a/net/icmp/icmp_reply.c +++ b/net/icmp/icmp_reply.c @@ -197,11 +197,13 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code) /* Calculate the ICMP checksum. */ icmp->icmpchksum = 0; +#ifdef CONFIG_NET_ICMP_CHECKSUMS icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob); if (icmp->icmpchksum == 0) { icmp->icmpchksum = 0xffff; } +#endif ninfo("Outgoing ICMP packet length: %d\n", dev->d_len); } diff --git a/net/icmp/icmp_sendmsg.c b/net/icmp/icmp_sendmsg.c index d4b5fcac90..22f3836bef 100644 --- a/net/icmp/icmp_sendmsg.c +++ b/net/icmp/icmp_sendmsg.c @@ -132,11 +132,14 @@ static void sendto_request(FAR struct net_driver_s *dev, /* Calculate the ICMP checksum. */ icmp->icmpchksum = 0; + +#ifdef CONFIG_NET_ICMP_CHECKSUMS icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob); if (icmp->icmpchksum == 0) { icmp->icmpchksum = 0xffff; } +#endif ninfo("Outgoing ICMP packet length: %d\n", dev->d_len); diff --git a/net/icmpv6/Kconfig b/net/icmpv6/Kconfig index b9ac220d89..f430081352 100644 --- a/net/icmpv6/Kconfig +++ b/net/icmpv6/Kconfig @@ -45,6 +45,12 @@ config NET_ICMPv6_SOCKET for application level support for sending ICMPv7 ECHO requests and receiving associated ICMPv6 ECHO replies. +config NET_ICMPv6_CHECKSUMS + bool "ICMPv6 checksums" + default y + ---help--- + Enable/disable ICMPv6 checksum support. + config NET_ICMPv6_NEIGHBOR bool "Solicit destination addresses" default n diff --git a/net/icmpv6/icmpv6_advertise.c b/net/icmpv6/icmpv6_advertise.c index 8b27a8f012..5f1401dcef 100644 --- a/net/icmpv6/icmpv6_advertise.c +++ b/net/icmpv6/icmpv6_advertise.c @@ -111,8 +111,9 @@ void icmpv6_advertise(FAR struct net_driver_s *dev, /* Calculate the checksum over both the ICMP header and payload */ adv->chksum = 0; +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); - +#endif /* Set the size to the size of the IPv6 header and the payload size */ dev->d_len = IPv6_HDRLEN + l3size; diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c index 79a31ffd93..41c8a437e6 100644 --- a/net/icmpv6/icmpv6_input.c +++ b/net/icmpv6/icmpv6_input.c @@ -556,7 +556,10 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen) net_ipv6addr_copy(ipv6->srcipaddr, srcaddr); icmpv6->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS icmpv6->chksum = ~icmpv6_chksum(dev, iplen); +#endif } break; diff --git a/net/icmpv6/icmpv6_radvertise.c b/net/icmpv6/icmpv6_radvertise.c index 52cb4864ed..865170a061 100644 --- a/net/icmpv6/icmpv6_radvertise.c +++ b/net/icmpv6/icmpv6_radvertise.c @@ -309,8 +309,10 @@ skip_prefix: /* Calculate the checksum over both the ICMP header and payload */ adv->chksum = 0; - adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS + adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); +#endif /* Set the size to the size of the IPv6 header and the payload size */ dev->d_len = IPv6_HDRLEN + l3size; diff --git a/net/icmpv6/icmpv6_reply.c b/net/icmpv6/icmpv6_reply.c index 3479d24dc5..3513a67aed 100644 --- a/net/icmpv6/icmpv6_reply.c +++ b/net/icmpv6/icmpv6_reply.c @@ -186,11 +186,14 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data) /* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */ icmpv6->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); if (icmpv6->chksum == 0) { icmpv6->chksum = 0xffff; } +#endif ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len); } diff --git a/net/icmpv6/icmpv6_rsolicit.c b/net/icmpv6/icmpv6_rsolicit.c index ea26f4ccc0..70d8d068db 100644 --- a/net/icmpv6/icmpv6_rsolicit.c +++ b/net/icmpv6/icmpv6_rsolicit.c @@ -105,8 +105,10 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev) /* Calculate the checksum over both the ICMP header and payload */ sol->chksum = 0; - sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS + sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); +#endif /* Set the size to the size of the IPv6 header and the payload size */ dev->d_len = IPv6_HDRLEN + l3size; diff --git a/net/icmpv6/icmpv6_sendmsg.c b/net/icmpv6/icmpv6_sendmsg.c index 49b1834644..90c025d663 100644 --- a/net/icmpv6/icmpv6_sendmsg.c +++ b/net/icmpv6/icmpv6_sendmsg.c @@ -129,11 +129,14 @@ static void sendto_request(FAR struct net_driver_s *dev, /* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */ icmpv6->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); if (icmpv6->chksum == 0) { icmpv6->chksum = 0xffff; } +#endif ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len); diff --git a/net/icmpv6/icmpv6_solicit.c b/net/icmpv6/icmpv6_solicit.c index 3c85d443d8..22d3ca3e9a 100644 --- a/net/icmpv6/icmpv6_solicit.c +++ b/net/icmpv6/icmpv6_solicit.c @@ -127,8 +127,10 @@ void icmpv6_solicit(FAR struct net_driver_s *dev, /* Calculate the checksum over both the ICMP header and payload */ sol->chksum = 0; - sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS + sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); +#endif /* Set the size to the size of the IPv6 header and the payload size */ dev->d_len = IPv6_HDRLEN + l3size; diff --git a/net/igmp/Kconfig b/net/igmp/Kconfig index 25cd61bd7f..97368eb4f3 100644 --- a/net/igmp/Kconfig +++ b/net/igmp/Kconfig @@ -12,6 +12,12 @@ config NET_IGMP ---help--- Enable IGMPv2 client support. +config NET_IGMP_CHECKSUMS + bool "IGMP checksums" + default y + ---help--- + Enable/disable IGMP checksum support. + if NET_IGMP endif # NET_IGMP diff --git a/net/igmp/igmp_input.c b/net/igmp/igmp_input.c index bde3a5f5a2..7a55443673 100644 --- a/net/igmp/igmp_input.c +++ b/net/igmp/igmp_input.c @@ -136,6 +136,7 @@ void igmp_input(struct net_driver_s *dev) goto drop; } +#ifdef CONFIG_NET_IGMP_CHECKSUMS /* Calculate and check the IGMP checksum */ if (net_chksum((FAR uint16_t *)igmp, IGMP_HDRLEN) != 0) @@ -144,6 +145,7 @@ void igmp_input(struct net_driver_s *dev) nwarn("WARNING: Checksum error\n"); goto drop; } +#endif /* Find the group (or create a new one) using the incoming IP address. */ diff --git a/net/igmp/igmp_send.c b/net/igmp/igmp_send.c index 8ce28a905f..3abd170412 100644 --- a/net/igmp/igmp_send.c +++ b/net/igmp/igmp_send.c @@ -67,11 +67,13 @@ * Private Functions ****************************************************************************/ +#ifdef CONFIG_NET_IGMP_CHECKSUMS static uint16_t igmp_chksum(FAR uint8_t *buffer, int buflen) { uint16_t sum = net_chksum((FAR uint16_t *)buffer, buflen); return sum ? sum : 0xffff; } +#endif /**************************************************************************** * Public Functions @@ -157,7 +159,10 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group, /* Calculate the IGMP checksum. */ igmp->chksum = 0; + +#ifdef CONFIG_NET_IGMP_CHECKSUMS igmp->chksum = ~igmp_chksum(&igmp->type, IGMP_HDRLEN); +#endif IGMP_STATINCR(g_netstats.igmp.poll_send); IGMP_STATINCR(g_netstats.ipv4.sent); diff --git a/net/inet/Kconfig b/net/inet/Kconfig index f72f3c094c..cffc49ae50 100644 --- a/net/inet/Kconfig +++ b/net/inet/Kconfig @@ -2,3 +2,9 @@ # For a description of the syntax of this configuration file, # see the file kconfig-language.txt in the NuttX tools repository. # + +config NET_IPV4_CHECKSUMS + bool "IPV4 checksums" + default y + ---help--- + Enable/disable IPV4 checksum support. diff --git a/net/inet/ipv4_build_header.c b/net/inet/ipv4_build_header.c index 001cba22bf..28b5dc7e07 100644 --- a/net/inet/ipv4_build_header.c +++ b/net/inet/ipv4_build_header.c @@ -99,7 +99,10 @@ uint16_t ipv4_build_header(FAR struct ipv4_hdr_s *ipv4, uint16_t total_len, /* Calculate IP checksum. */ ipv4->ipchksum = 0; + +#ifdef CONFIG_NET_IPV4_CHECKSUMS ipv4->ipchksum = ~ipv4_chksum(ipv4); +#endif ninfo("IPv4 Packet: ipid:%d, length: %d\n", g_ipid, total_len); diff --git a/net/mld/mld_send.c b/net/mld/mld_send.c index a291b85d1d..a451f70b31 100644 --- a/net/mld/mld_send.c +++ b/net/mld/mld_send.c @@ -285,7 +285,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group, /* Calculate the ICMPv6 checksum. */ query->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS query->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); +#endif MLD_STATINCR(g_netstats.mld.query_sent); @@ -326,7 +329,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group, /* Calculate the ICMPv6 checksum. */ report->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS report->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); +#endif SET_MLD_LASTREPORT(group->flags); /* Remember we were the last to report */ MLD_STATINCR(g_netstats.mld.v1report_sent); @@ -352,7 +358,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group, /* Calculate the ICMPv6 checksum. */ report->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS report->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); +#endif SET_MLD_LASTREPORT(group->flags); /* Remember we were the last to report */ MLD_STATINCR(g_netstats.mld.v2report_sent); @@ -372,7 +381,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group, /* Calculate the ICMPv6 checksum. */ done->chksum = 0; + +#ifdef CONFIG_NET_ICMPv6_CHECKSUMS done->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); +#endif MLD_STATINCR(g_netstats.mld.done_sent); } diff --git a/net/tcp/Kconfig b/net/tcp/Kconfig index 8645ef8a5f..8b4a2f0a90 100644 --- a/net/tcp/Kconfig +++ b/net/tcp/Kconfig @@ -50,6 +50,12 @@ config NET_TCPURGDATA compiled in. Urgent data (out-of-band data) is a rarely used TCP feature that is very seldom would be required. +config NET_TCP_CHECKSUMS + bool "TCP checksums" + default y + ---help--- + Enable/disable TCP checksum support. + config NET_TCP_PREALLOC_CONNS int "Preallocated TCP/IP connections" default 8 diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 5904e2d9fd..d56dfcb9bc 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -722,6 +722,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, tcpiplen = iplen + TCP_HDRLEN; +#ifdef CONFIG_NET_TCP_CHECKSUMS /* Start of TCP input header processing code. */ if (tcp_chksum(dev) != 0xffff) @@ -735,6 +736,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, nwarn("WARNING: Bad TCP checksum\n"); goto drop; } +#endif /* Demultiplex this segment. First check any active connections. */ diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c index 3c4481f01a..08d16b175c 100644 --- a/net/tcp/tcp_send.c +++ b/net/tcp/tcp_send.c @@ -196,7 +196,11 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev, /* Calculate TCP checksum. */ tcp->tcpchksum = 0; + +#ifdef CONFIG_NET_TCP_CHECKSUMS tcp->tcpchksum = ~tcp_ipv6_chksum(dev); +#endif + #ifdef CONFIG_NET_STATISTICS g_netstats.ipv6.sent++; #endif @@ -216,7 +220,11 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev, /* Calculate TCP checksum. */ tcp->tcpchksum = 0; + +#ifdef CONFIG_NET_TCP_CHECKSUMS tcp->tcpchksum = ~tcp_ipv4_chksum(dev); +#endif + #ifdef CONFIG_NET_STATISTICS g_netstats.ipv4.sent++; #endif @@ -491,7 +499,10 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) conn ? conn->sconn.s_ttl : IP_TTL_DEFAULT, conn ? conn->sconn.s_tos : 0); tcp->tcpchksum = 0; + +#ifdef CONFIG_NET_TCP_CHECKSUMS tcp->tcpchksum = ~tcp_ipv6_chksum(dev); +#endif } #endif /* CONFIG_NET_IPv6 */ @@ -508,7 +519,10 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) conn ? conn->sconn.s_tos : 0, NULL); tcp->tcpchksum = 0; + +#ifdef CONFIG_NET_TCP_CHECKSUMS tcp->tcpchksum = ~tcp_ipv4_chksum(dev); +#endif } #endif /* CONFIG_NET_IPv4 */ } diff --git a/net/utils/net_ipchksum.c b/net/utils/net_ipchksum.c index d83c429313..f1cd938a29 100644 --- a/net/utils/net_ipchksum.c +++ b/net/utils/net_ipchksum.c @@ -37,26 +37,29 @@ * Public Functions ****************************************************************************/ +#if !defined(CONFIG_NET_ARCH_CHKSUM) && \ + defined(CONFIG_NET_IPv4) && defined(CONFIG_MM_IOB) + /**************************************************************************** - * Name: ipv4_upperlayer_chksum + * Name: ipv4_upperlayer_header_chksum * * Description: - * Perform the checksum calculation over the IPv4, protocol headers, and - * data payload as necessary. + * Perform the checksum calculation over the IPv4, protocol headers, + * IP source and destination addresses * * Input Parameters: - * dev - The network driver instance. The packet data is in the d_buf + * dev - The network driver instance. The packet data is in the d_buf * of the device. * proto - The protocol being supported * * Returned Value: - * The calculated checksum + * The calculated checksum with pseudo-header and IP source and + * destination addresses * ****************************************************************************/ -#if !defined(CONFIG_NET_ARCH_CHKSUM) && \ - defined(CONFIG_NET_IPv4) && defined(CONFIG_MM_IOB) -uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto) +uint16_t ipv4_upperlayer_header_chksum(FAR struct net_driver_s *dev, + uint8_t proto) { FAR struct ipv4_hdr_s *ipv4 = IPv4BUF; uint16_t upperlen; @@ -83,22 +86,82 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto) /* Sum IP source and destination addresses. */ - sum = chksum(sum, (FAR uint8_t *)&ipv4->srcipaddr, 2 * sizeof(in_addr_t)); + return chksum(sum, (FAR uint8_t *)&ipv4->srcipaddr, 2 * sizeof(in_addr_t)); +} + +/**************************************************************************** + * Name: ipv4_upperlayer_payload_chksum + * + * Description: + * Perform the checksum calculation over the iob data payload + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * sum - The default checksum + * + * Returned Value: + * The calculated checksum with iob data payload and default checksum + * + ****************************************************************************/ + +uint16_t ipv4_upperlayer_payload_chksum(FAR struct net_driver_s *dev, + uint16_t sum) +{ + FAR struct ipv4_hdr_s *ipv4 = IPv4BUF; + uint16_t iphdrlen; + + /* Get the IP header length (accounting for possible options). */ + + iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; /* Sum IP payload data. */ - sum = chksum_iob(sum, dev->d_iob, iphdrlen); + return chksum_iob(sum, dev->d_iob, iphdrlen); +} + +/**************************************************************************** + * Name: ipv4_upperlayer_chksum + * + * Description: + * Perform the checksum calculation over the IPv4, protocol headers, and + * data payload as necessary. + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * proto - The protocol being supported + * + * Returned Value: + * The calculated checksum + * + ****************************************************************************/ + +uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto) +{ + uint16_t sum; + + /* Sum pseudo-header IP source and destination addresses. */ + + sum = ipv4_upperlayer_header_chksum(dev, proto); + + /* Sum IP payload data. */ + + sum = ipv4_upperlayer_payload_chksum(dev, sum); return (sum == 0) ? 0xffff : HTONS(sum); } #endif /* CONFIG_NET_ARCH_CHKSUM */ +#if !defined(CONFIG_NET_ARCH_CHKSUM) && \ + defined(CONFIG_NET_IPv6) && defined(CONFIG_MM_IOB) + /**************************************************************************** - * Name: ipv6_upperlayer_chksum + * Name: ipv6_upperlayer_header_chksum * * Description: - * Perform the checksum calculation over the IPv6, protocol headers, and - * data payload as necessary. + * Perform the checksum calculation over the IPv6, protocol headers, + * IP source and destination addresses. * * Input Parameters: * dev - The network driver instance. The packet data is in the d_buf @@ -113,10 +176,8 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto) * ****************************************************************************/ -#if !defined(CONFIG_NET_ARCH_CHKSUM) && \ - defined(CONFIG_NET_IPv6) && defined(CONFIG_MM_IOB) -uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, - uint8_t proto, unsigned int iplen) +uint16_t ipv6_upperlayer_header_chksum(FAR struct net_driver_s *dev, + uint8_t proto, unsigned int iplen) { FAR struct ipv6_hdr_s *ipv6 = IPv6BUF; uint16_t upperlen; @@ -144,12 +205,70 @@ uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, /* Sum IP source and destination addresses. */ - sum = chksum(sum, (FAR uint8_t *)&ipv6->srcipaddr, - 2 * sizeof(net_ipv6addr_t)); + return chksum(sum, (FAR uint8_t *)&ipv6->srcipaddr, + 2 * sizeof(net_ipv6addr_t)); +} + +/**************************************************************************** + * Name: ipv6_upperlayer_payload_chksum + * + * Description: + * Perform the checksum calculation over the IPv6, protocol headers, + * IP source and destination addresses. + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * proto - The protocol being supported + * iplen - The size of the IPv6 header. This may be larger than + * IPv6_HDRLEN the IPv6 header if IPv6 extension headers are + * present. + * + * Returned Value: + * The calculated checksum + * + ****************************************************************************/ + +uint16_t ipv6_upperlayer_payload_chksum(FAR struct net_driver_s *dev, + unsigned int iplen, uint16_t sum) +{ + /* Sum IP payload data. */ + + return chksum_iob(sum, dev->d_iob, iplen); +} + +/**************************************************************************** + * Name: ipv6_upperlayer_chksum + * + * Description: + * Perform the checksum calculation over the IPv6, protocol headers, and + * data payload as necessary. + * + * Input Parameters: + * dev - The network driver instance. The packet data is in the d_buf + * of the device. + * proto - The protocol being supported + * iplen - The size of the IPv6 header. This may be larger than + * IPv6_HDRLEN the IPv6 header if IPv6 extension headers are + * present. + * + * Returned Value: + * The calculated checksum + * + ****************************************************************************/ + +uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, + uint8_t proto, unsigned int iplen) +{ + uint16_t sum; + + /* Sum IP source and destination addresses. */ + + sum = ipv6_upperlayer_header_chksum(dev, proto, iplen); /* Sum IP payload data. */ - sum = chksum_iob(sum, dev->d_iob, iplen); + sum = ipv6_upperlayer_payload_chksum(dev, iplen, sum); return (sum == 0) ? 0xffff : HTONS(sum); }