From 72743bc4f52a1e4219c7844af44a8be4a31bd66f Mon Sep 17 00:00:00 2001 From: ycyang1229 Date: Thu, 29 Apr 2021 17:23:05 +0800 Subject: [PATCH 1/7] add lwip support. --- CMakeLists.txt | 12 +- fuzzer/pcap2corpus.c | 12 +- usrsctplib/CMakeLists.txt | 6 + usrsctplib/netinet/sctp_bsd_addr.c | 78 ++++++++++ usrsctplib/netinet/sctp_callout.c | 6 + usrsctplib/netinet/sctp_header.h | 10 +- usrsctplib/netinet/sctp_in_port.h | 86 +++++++++++ usrsctplib/netinet/sctp_input.c | 50 +++--- usrsctplib/netinet/sctp_ip_port.h | 91 +++++++++++ usrsctplib/netinet/sctp_os_userspace.h | 24 ++- usrsctplib/netinet/sctp_output.c | 205 ++++++++++++------------- usrsctplib/netinet/sctp_pcb.c | 30 ++-- usrsctplib/netinet/sctp_timer.c | 9 +- usrsctplib/netinet/sctp_udp_port.h | 74 +++++++++ usrsctplib/netinet/sctp_userspace.c | 8 + usrsctplib/netinet/sctp_usrreq.c | 34 ++-- usrsctplib/netinet/sctputil.c | 79 +++++----- usrsctplib/netinet6/sctp6_usrreq.c | 6 +- usrsctplib/user_ip_icmp.h | 4 +- usrsctplib/user_recv_thread.c | 23 +-- usrsctplib/user_socket.c | 47 +++--- usrsctplib/usrsctp.h | 7 +- 22 files changed, 642 insertions(+), 259 deletions(-) create mode 100755 usrsctplib/netinet/sctp_in_port.h create mode 100755 usrsctplib/netinet/sctp_ip_port.h create mode 100755 usrsctplib/netinet/sctp_udp_port.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 37270d1..64c0061 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,12 @@ option(sctp_sanitizer_memory "Compile with memory sanitizer" 0) option(sctp_build_fuzzer "Compile in clang fuzzing mode" 0) +option(sctp_use_lwip "build with lwip" ON) + +if(sctp_use_lwip) + add_definitions(-DSCTP_USE_LWIP) +endif() + if (sctp_sanitizer_address AND sctp_sanitizer_memory) message(FATAL_ERROR "Can not compile with both sanitizer options") endif () @@ -128,7 +134,9 @@ set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/usrsctplib") check_include_file(usrsctp.h have_usrsctp_h) if (NOT have_usrsctp_h) - message(FATAL_ERROR "usrsctp.h not found") + if(NOT sctp_use_lwip) + message(FATAL_ERROR "usrsctp.h not found") + endif() endif () check_struct_has_member("struct sockaddr" "sa_len" "sys/types.h;sys/socket.h" have_sa_len) @@ -150,7 +158,7 @@ if (have_sin6_len) endif () check_struct_has_member("struct sockaddr_conn" "sconn_len" "usrsctp.h" have_sconn_len) -if (have_sconn_len) +if (have_sconn_len OR sctp_use_lwip) message(STATUS "HAVE_SCONN_LEN") add_definitions(-DHAVE_SCONN_LEN) endif () diff --git a/fuzzer/pcap2corpus.c b/fuzzer/pcap2corpus.c index 43dc77c..64dba5f 100644 --- a/fuzzer/pcap2corpus.c +++ b/fuzzer/pcap2corpus.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include @@ -110,7 +110,7 @@ packet_handler(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *byt const u_char *bytes_out; FILE *file; char *filename; - const struct ip *ip4_hdr_in; + const STRUCT_IP_HDR *ip4_hdr_in; const struct ip6_hdr *ip6_hdr_in; size_t offset, length; int null = 0; @@ -124,15 +124,15 @@ packet_handler(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *byt goto out; } if (args->is_ipv4(bytes_in)) { - offset = args->offset + sizeof(struct ip) + sizeof(struct sctphdr); + offset = args->offset + sizeof(STRUCT_IP_HDR) + sizeof(struct sctphdr); if (pkthdr->caplen < offset) { goto out; } - ip4_hdr_in = (const struct ip *)(const void *)(bytes_in + args->offset); - if (ip4_hdr_in->ip_p == IPPROTO_SCTP) { + ip4_hdr_in = (const STRUCT_IP_HDR *)(const void *)(bytes_in + args->offset); + if (GET_IP_PROTO(ip4_hdr_in) == IPPROTO_SCTP) { unsigned int ip4_hdr_len; - ip4_hdr_len = ip4_hdr_in->ip_hl << 2; + ip4_hdr_len = GET_IP_HDR_LEN_VAL(ip4_hdr_in) << 2; offset = args->offset + ip4_hdr_len + sizeof(struct sctphdr); if (pkthdr->caplen < offset) { goto out; diff --git a/usrsctplib/CMakeLists.txt b/usrsctplib/CMakeLists.txt index 899ca8e..6eb0f36 100644 --- a/usrsctplib/CMakeLists.txt +++ b/usrsctplib/CMakeLists.txt @@ -48,6 +48,9 @@ include(CheckCCompilerFlag) add_definitions(-D__Userspace__) add_definitions(-DSCTP_SIMPLE_ALLOCATOR) add_definitions(-DSCTP_PROCESS_LEVEL_LOCKS) +if(NOT sctp_use_lwip) + add_definitions(-D__native_client__) +endif() ################################################# @@ -110,6 +113,7 @@ list(APPEND usrsctp_netinet_headers netinet/sctp_header.h netinet/sctp_indata.h netinet/sctp_input.h + netinet/sctp_ip_port.h netinet/sctp_lock_userspace.h netinet/sctp_os_userspace.h netinet/sctp_os.h @@ -121,6 +125,8 @@ list(APPEND usrsctp_netinet_headers netinet/sctp_structs.h netinet/sctp_sysctl.h netinet/sctp_timer.h + netinet/sctp_udp_port.h + netinet/sctp_in_port.h netinet/sctp_uio.h netinet/sctp_var.h netinet/sctputil.h diff --git a/usrsctplib/netinet/sctp_bsd_addr.c b/usrsctplib/netinet/sctp_bsd_addr.c index 40e308f..76d40b8 100755 --- a/usrsctplib/netinet/sctp_bsd_addr.c +++ b/usrsctplib/netinet/sctp_bsd_addr.c @@ -53,6 +53,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 358080 2020-02-18 19:41:55Z #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif +#if defined(SCTP_USE_LWIP) +#include +#endif /* Declare all of our malloc named types */ MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor"); @@ -415,6 +418,80 @@ sctp_init_ifns_for_vrf(int vrfid) static void sctp_init_ifns_for_vrf(int vrfid) { +#if defined(SCTP_USE_LWIP) + #define LWIP_IF_NUM_MAX 256 + + struct sctp_ifa *sctp_ifa; + uint32_t ifa_flags; + uint32_t if_num; + char if_name[NETIF_NAMESIZE]; + struct sockaddr* in_addr = malloc(sizeof(struct sockaddr)); + + for(if_num=1;if_numip_addr)){ + continue; + } + + if(tmp_if->ip_addr.type == IPADDR_TYPE_V4){ + in_addr->sa_family = AF_INET; + memcpy(&((struct sockaddr_in *)in_addr)->sin_addr, &tmp_if->ip_addr.u_addr, sizeof(uint32_t) ); + }else{ + in_addr->sa_family = AF_INET6; + memcpy(&((struct sockaddr_in6 *)in_addr)->sin6_addr, &tmp_if->ip_addr.u_addr, sizeof(uint32_t)*4); + } +#if !defined(INET) + if (in_addr->sa_family != AF_INET6) { + /* non inet6 skip */ + continue; + } +#elif !defined(INET6) + if (in_addr->sa_family != AF_INET) { + /* non inet skip */ + continue; + } +#else + if ((in_addr->sa_family != AF_INET) && (in_addr->sa_family != AF_INET6)) { + /* non inet/inet6 skip */ + continue; + } +#endif +#if defined(INET6) + if ((in_addr->sa_family == AF_INET6) && + IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)in_addr)->sin6_addr)) { + /* skip unspecifed addresses */ + continue; + } +#endif +#if defined(INET) + if (in_addr->sa_family == AF_INET && + ((struct sockaddr_in *)in_addr)->sin_addr.s_addr == 0) { + continue; + } +#endif + ifa_flags = 0; + sctp_ifa = sctp_add_addr_to_vrf(vrfid, + NULL, + if_num, + 0, + tmp_name, + NULL, + (struct sockaddr*)in_addr, + ifa_flags, + 0); + if (sctp_ifa) { + sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; + } + }else{ + break; + } + } + free(in_addr); +#else #if defined(INET) || defined(INET6) int rc; struct ifaddrs *ifa, *ifas; @@ -474,6 +551,7 @@ sctp_init_ifns_for_vrf(int vrfid) } freeifaddrs(ifas); #endif +#endif } #endif diff --git a/usrsctplib/netinet/sctp_callout.c b/usrsctplib/netinet/sctp_callout.c index 4c9be75..d66da73 100755 --- a/usrsctplib/netinet/sctp_callout.c +++ b/usrsctplib/netinet/sctp_callout.c @@ -45,7 +45,11 @@ #include #include #include +#if !defined(SCTP_USE_LWIP) #include +#else +#include "lwip/errno.h" +#endif #include #include #include @@ -199,6 +203,8 @@ user_sctp_timer_iterate(void *arg) for (;;) { #if defined(_WIN32) Sleep(TIMEOUT_INTERVAL); +#elif defined(SCTP_USE_LWIP) + usleep(TIMEOUT_INTERVAL*1000); #else struct timespec amount, remaining; diff --git a/usrsctplib/netinet/sctp_header.h b/usrsctplib/netinet/sctp_header.h index 602921d..83ce0a1 100755 --- a/usrsctplib/netinet/sctp_header.h +++ b/usrsctplib/netinet/sctp_header.h @@ -581,14 +581,14 @@ struct sctp_auth_chunk { sizeof(struct sctphdr) + \ sizeof(struct sctp_ecne_chunk) + \ sizeof(struct sctp_sack_chunk) + \ - sizeof(struct ip)) + sizeof(STRUCT_IP_HDR)) #define SCTP_MED_OVERHEAD (sizeof(struct sctp_data_chunk) + \ sizeof(struct sctphdr) + \ - sizeof(struct ip)) + sizeof(STRUCT_IP_HDR)) -#define SCTP_MIN_OVERHEAD (sizeof(struct ip) + \ +#define SCTP_MIN_OVERHEAD (sizeof(STRUCT_IP_HDR) + \ sizeof(struct sctphdr)) #endif /* INET6 */ @@ -596,9 +596,9 @@ struct sctp_auth_chunk { #define SCTP_MED_V4_OVERHEAD (sizeof(struct sctp_data_chunk) + \ sizeof(struct sctphdr) + \ - sizeof(struct ip)) + sizeof(STRUCT_IP_HDR)) -#define SCTP_MIN_V4_OVERHEAD (sizeof(struct ip) + \ +#define SCTP_MIN_V4_OVERHEAD (sizeof(STRUCT_IP_HDR) + \ sizeof(struct sctphdr)) #if defined(_WIN32) && !defined(__Userspace__) diff --git a/usrsctplib/netinet/sctp_in_port.h b/usrsctplib/netinet/sctp_in_port.h new file mode 100755 index 0000000..2e2d1f3 --- /dev/null +++ b/usrsctplib/netinet/sctp_in_port.h @@ -0,0 +1,86 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * b) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * c) Neither the name of Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__FreeBSD__) && !defined(__Userspace__) +#include +__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 359195 2020-03-21 16:12:19Z tuexen $"); +#endif + +#ifndef _NETINET_SCTP_IN_PORT_H_ +#define _NETINET_SCTP_IN_PORT_H_ + +#if defined(SCTP_USE_LWIP) +/* Standard well-known ports. */ +enum + { + IPPORT_ECHO = 7, /* Echo service. */ + IPPORT_DISCARD = 9, /* Discard transmissions service. */ + IPPORT_SYSTAT = 11, /* System status service. */ + IPPORT_DAYTIME = 13, /* Time of day service. */ + IPPORT_NETSTAT = 15, /* Network status service. */ + IPPORT_FTP = 21, /* File Transfer Protocol. */ + IPPORT_TELNET = 23, /* Telnet protocol. */ + IPPORT_SMTP = 25, /* Simple Mail Transfer Protocol. */ + IPPORT_TIMESERVER = 37, /* Timeserver service. */ + IPPORT_NAMESERVER = 42, /* Domain Name Service. */ + IPPORT_WHOIS = 43, /* Internet Whois service. */ + IPPORT_MTP = 57, + + IPPORT_TFTP = 69, /* Trivial File Transfer Protocol. */ + IPPORT_RJE = 77, + IPPORT_FINGER = 79, /* Finger service. */ + IPPORT_TTYLINK = 87, + IPPORT_SUPDUP = 95, /* SUPDUP protocol. */ + + + IPPORT_EXECSERVER = 512, /* execd service. */ + IPPORT_LOGINSERVER = 513, /* rlogind service. */ + IPPORT_CMDSERVER = 514, + IPPORT_EFSSERVER = 520, + + /* UDP ports. */ + IPPORT_BIFFUDP = 512, + IPPORT_WHOSERVER = 513, + IPPORT_ROUTESERVER = 520, + + /* Ports less than this value are reserved for privileged processes. */ + IPPORT_RESERVED = 1024, + + /* Ports greater this value are reserved for (non-privileged) servers. */ + IPPORT_USERRESERVED = 5000 + }; + +#define IP_HDRINCL 3 /* int; Header is included with data. */ +#endif +#endif//!< _NETINET_SCTP_IN_PORT_H_ diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c index 7be22d3..2296968 100755 --- a/usrsctplib/netinet/sctp_input.c +++ b/usrsctplib/netinet/sctp_input.c @@ -54,11 +54,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 363194 2020-07-14 20:32:50Z tu #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif -#if defined(INET) || defined(INET6) -#if !defined(_WIN32) -#include -#endif -#endif + +#include + #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif @@ -5790,13 +5788,13 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt (net != NULL) && (net->port != port)) { if (net->port == 0) { /* UDP encapsulation turned on. */ - net->mtu -= sizeof(struct udphdr); + net->mtu -= sizeof(STRUCT_UDP_HDR); if (stcb->asoc.smallest_mtu > net->mtu) { sctp_pathmtu_adjustment(stcb, net->mtu); } } else if (port == 0) { /* UDP encapsulation turned off. */ - net->mtu += sizeof(struct udphdr); + net->mtu += sizeof(STRUCT_UDP_HDR); /* XXX Update smallest_mtu */ } net->port = port; @@ -5832,13 +5830,13 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt (net != NULL) && (net->port != port)) { if (net->port == 0) { /* UDP encapsulation turned on. */ - net->mtu -= sizeof(struct udphdr); + net->mtu -= sizeof(STRUCT_UDP_HDR); if (stcb->asoc.smallest_mtu > net->mtu) { sctp_pathmtu_adjustment(stcb, net->mtu); } } else if (port == 0) { /* UDP encapsulation turned off. */ - net->mtu += sizeof(struct udphdr); + net->mtu += sizeof(STRUCT_UDP_HDR); /* XXX Update smallest_mtu */ } net->port = port; @@ -5956,13 +5954,13 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt (net != NULL) && (net->port != port)) { if (net->port == 0) { /* UDP encapsulation turned on. */ - net->mtu -= sizeof(struct udphdr); + net->mtu -= sizeof(STRUCT_UDP_HDR); if (stcb->asoc.smallest_mtu > net->mtu) { sctp_pathmtu_adjustment(stcb, net->mtu); } } else if (port == 0) { /* UDP encapsulation turned off. */ - net->mtu += sizeof(struct udphdr); + net->mtu += sizeof(STRUCT_UDP_HDR); /* XXX Update smallest_mtu */ } net->port = port; @@ -6209,7 +6207,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) uint32_t vrf_id = 0; uint8_t ecn_bits; struct sockaddr_in src, dst; - struct ip *ip; + STRUCT_IP_HDR *ip + struct sctphdr *sh; struct sctp_chunkhdr *ch; int length, offset; @@ -6277,7 +6276,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) return; } } - ip = mtod(m, struct ip *); + ip = mtod(m, STRUCT_IP_HDR *); + sh = (struct sctphdr *)((caddr_t)ip + iphlen); ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); offset -= sizeof(struct sctp_chunkhdr); @@ -6287,32 +6287,32 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) src.sin_len = sizeof(struct sockaddr_in); #endif src.sin_port = sh->src_port; - src.sin_addr = ip->ip_src; + src.sin_addr = GET_IP_SRC(ip); memset(&dst, 0, sizeof(struct sockaddr_in)); dst.sin_family = AF_INET; #ifdef HAVE_SIN_LEN dst.sin_len = sizeof(struct sockaddr_in); #endif dst.sin_port = sh->dest_port; - dst.sin_addr = ip->ip_dst; + dst.sin_addr = GET_IP_DEST(ip); #if defined(_WIN32) && !defined(__Userspace__) - NTOHS(ip->ip_len); + NTOHS(GET_IP_LEN(ip)); #endif #if defined(__linux__) || (defined(_WIN32) && defined(__Userspace__)) - ip->ip_len = ntohs(ip->ip_len); + GET_IP_LEN(ip) = ntohs(GET_IP_LEN(ip)); #endif #if defined(__Userspace__) #if defined(__linux__) || defined(_WIN32) - length = ip->ip_len; + length = GET_IP_LEN(ip); #else - length = ip->ip_len + iphlen; + length = GET_IP_LEN(ip) + iphlen; #endif #elif defined(__FreeBSD__) - length = ntohs(ip->ip_len); + length = ntohs(GET_IP_LEN(ip)); #elif defined(__APPLE__) - length = ip->ip_len + iphlen; + length = GET_IP_LEN(ip) + iphlen; #else - length = ip->ip_len; + length = GET_IP_LEN(ip); #endif /* Validate mbuf chain length with IP payload length. */ if (SCTP_HEADER_LEN(m) != length) { @@ -6328,7 +6328,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) { goto out; } - ecn_bits = ip->ip_tos; + ecn_bits = GET_IP_TOS(iphdr); #if defined(__FreeBSD__) && !defined(__Userspace__) if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { SCTP_STAT_INCR(sctps_recvhwcrc); @@ -6385,7 +6385,7 @@ sctp_input(struct mbuf *m, int off) #if defined(__FreeBSD__) && !defined(__Userspace__) #if defined(SCTP_MCORE_INPUT) && defined(SMP) if (mp_ncpus > 1) { - struct ip *ip; + STRUCT_IP_HDR *ip; struct sctphdr *sh; int offset; int cpu_to_use; @@ -6404,7 +6404,7 @@ sctp_input(struct mbuf *m, int off) return (IPPROTO_DONE); } } - ip = mtod(m, struct ip *); + ip = mtod(m, STRUCT_IP_HDR *); sh = (struct sctphdr *)((caddr_t)ip + off); tag = htonl(sh->v_tag); flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port); diff --git a/usrsctplib/netinet/sctp_ip_port.h b/usrsctplib/netinet/sctp_ip_port.h new file mode 100755 index 0000000..2e382eb --- /dev/null +++ b/usrsctplib/netinet/sctp_ip_port.h @@ -0,0 +1,91 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * b) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * c) Neither the name of Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__FreeBSD__) && !defined(__Userspace__) +#include +__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 359195 2020-03-21 16:12:19Z tuexen $"); +#endif + +#ifndef _NETINET_SCTP_IP_PORT_H_ +#define _NETINET_SCTP_IP_PORT_H_ + +#if !defined(SCTP_USE_LWIP) +#include +#define STRUCT_IP_HDR struct ip +//#define GET_IP_VERSION(ip) ((struct ip_hdr*)(ip))->ip_v +//#define GET_IP_HDR_LEN(ip) ((struct ip_hdr*)(ip))->ip_hl +#define GET_IP_TOS(ip) ((struct ip*)(ip))->ip_tos +#define GET_IP_LEN(ip) ((struct ip*)ip)->ip_len +#define GET_IP_ID(ip) ((struct ip*)ip)->ip_id +#define GET_IP_OFFSET(ip) ((struct ip*)ip)->ip_off +#define GET_IP_TTL(ip) ((struct ip*)ip)->ip_ttl +#define GET_IP_PROTO(ip) ((struct ip*)ip)->ip_p +#define GET_IP_CHKSUM(ip) ((struct ip*)ip)->ip_sum +#define GET_IP_SRC(ip) ((struct ip*)ip)->ip_src +#define GET_IP_DEST(ip) ((struct ip*)ip)->ip_dst +#define GET_IP_SRC_ADDR(ip) ((struct ip*)ip)->ip_src.s_addr +#define GET_IP_DEST_ADDR(ip) ((struct ip*)ip)->ip_dst.s_addr + +#define GET_IP_VERSION_VAL(ip) ((struct ip_hdr*)(ip))->ip_v +#define GET_IP_HDR_LEN_VAL(ip) ((struct ip_hdr*)(ip))->ip_hl + +#define SET_IP_VHL(hdr, v, hl) do{\ + (hdr)->ip_v = v;\ + (hdr)->ip_hl = hl;\ + }while(0) +#else +#include "lwip/ip.h" +#define STRUCT_IP_HDR struct ip_hdr +//#define GET_IP_VERSION(ip) ((struct ip_hdr*)(ip))->_v_hl +//#define GET_IP_HDR_LEN(ip) ((struct ip_hdr*)(ip))->_v_hl +#define GET_IP_TOS(ip) IPH_TOS(ip)//((struct ip_hdr*)(ip))->_tos +#define GET_IP_LEN(ip) IPH_LEN(ip)//((struct ip_hdr*)ip)->_len +#define GET_IP_ID(ip) IPH_ID(ip)//((struct ip_hdr*)ip)->_id +#define GET_IP_OFFSET(ip) IPH_OFFSET(ip)//((struct ip_hdr*)ip)->_offset +#define GET_IP_TTL(ip) IPH_TTL(ip)//((struct ip_hdr*)ip)->_ttl +#define GET_IP_PROTO(ip) IPH_PROTO(ip)//((struct ip_hdr*)ip)->_proto +#define GET_IP_CHKSUM(ip) IPH_CHKSUM(ip)//((struct ip_hdr*)ip)->_chksum +#define GET_IP_SRC(ip) ((struct ip_hdr*)ip)->src +#define GET_IP_DEST(ip) ((struct ip_hdr*)ip)->dest +#define GET_IP_SRC_ADDR(ip) ((struct ip_hdr*)ip)->src.addr +#define GET_IP_DEST_ADDR(ip) ((struct ip_hdr*)ip)->dest.addr + + +#define GET_IP_VERSION_VAL(ip) IPH_V(ip) +#define GET_IP_HDR_LEN_VAL(ip) IPH_HL(ip) + +#define SET_IP_VHL(hdr, v, hl) IPH_VHL_SET(hdr, v, hl) +#endif + +#endif//!< _NETINET_SCTP_UDP_PORT_H_ diff --git a/usrsctplib/netinet/sctp_os_userspace.h b/usrsctplib/netinet/sctp_os_userspace.h index 3a9407a..87ced8b 100755 --- a/usrsctplib/netinet/sctp_os_userspace.h +++ b/usrsctplib/netinet/sctp_os_userspace.h @@ -41,7 +41,12 @@ * We will place them in userspace stack build directory. */ + +#if !defined(SCTP_USE_LWIP) #include +#else +#include "lwip/errno.h" +#endif #if defined(_WIN32) #include @@ -286,6 +291,13 @@ typedef char* caddr_t; #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__native_client__) || defined(__Fuchsia__) #include #endif + +#if defined(SCTP_USE_LWIP) +#define IPVERSION 4 +#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \ + & (size_t) ~(sizeof (size_t) - 1)) +#endif/* */ + typedef pthread_mutex_t userland_mutex_t; typedef pthread_cond_t userland_cond_t; typedef pthread_t userland_thread_t; @@ -457,8 +469,12 @@ struct sx {int dummy;}; #if !defined(_WIN32) && !defined(__native_client__) #include #include +#if !defined(SCTP_USE_LWIP) #include -#include +#endif + +#include + #endif #if defined(HAVE_NETINET_IP_ICMP_H) #include @@ -472,8 +488,10 @@ struct sx {int dummy;}; #include #if !defined(_WIN32) #if defined(INET) || defined(INET6) +#if !defined(SCTP_USE_LWIP) #include #endif +#endif /* for ioctl */ #include @@ -507,13 +525,17 @@ struct sx {int dummy;}; #include #endif #if !defined(_WIN32) +#if !defined(SCTP_USE_LWIP) #include #endif +#endif #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(_WIN32) #include "user_ip6_var.h" #else +#if !defined(SCTP_USE_LWIP) #include #endif +#endif #if defined(__FreeBSD__) #include #include diff --git a/usrsctplib/netinet/sctp_output.c b/usrsctplib/netinet/sctp_output.c index a494b2c..7004506 100755 --- a/usrsctplib/netinet/sctp_output.c +++ b/usrsctplib/netinet/sctp_output.c @@ -62,11 +62,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 362178 2020-06-14 16:05:08Z t #if defined(__linux__) #define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */ #endif -#if defined(INET) || defined(INET6) -#if !defined(_WIN32) -#include -#endif -#endif + +#include + #if !defined(__Userspace__) #if defined(__APPLE__) #include @@ -4130,7 +4128,7 @@ int so_locked) #if defined(INET) || defined(INET6) struct mbuf *o_pak; sctp_route_t *ro = NULL; - struct udphdr *udp = NULL; + STRUCT_UDP_HDR *udp = NULL; #endif uint8_t tos_value; #if defined(__APPLE__) && !defined(__Userspace__) @@ -4174,13 +4172,14 @@ int so_locked) #ifdef INET case AF_INET: { - struct ip *ip = NULL; + STRUCT_IP_HDR *ip = NULL; + sctp_route_t iproute; int len; len = SCTP_MIN_V4_OVERHEAD; if (port) { - len += sizeof(struct udphdr); + len += sizeof(STRUCT_UDP_HDR); } newm = sctp_get_mbuf_for_msg(len, 1, M_NOWAIT, 1, MT_DATA); if (newm == NULL) { @@ -4202,9 +4201,8 @@ int so_locked) } #endif packet_length = sctp_calculate_len(m); - ip = mtod(m, struct ip *); - ip->ip_v = IPVERSION; - ip->ip_hl = (sizeof(struct ip) >> 2); + ip = mtod(m, STRUCT_IP_HDR *); + SET_IP_VHL(ip, IPVERSION, (sizeof(STRUCT_IP_HDR) >> 2)); if (tos_value == 0) { /* * This means especially, that it is not set at the @@ -4218,47 +4216,47 @@ int so_locked) } if ((nofragment_flag) && (port == 0)) { #if defined(__FreeBSD__) && !defined(__Userspace__) - ip->ip_off = htons(IP_DF); + GET_IP_OFFSET(ip) = htons(IP_DF); #elif defined(WITH_CONVERT_IP_OFF) || defined(__APPLE__) - ip->ip_off = IP_DF; + GET_IP_OFFSET(ip) = IP_DF; #else - ip->ip_off = htons(IP_DF); + GET_IP_OFFSET(ip) = htons(IP_DF); #endif } else { #if defined(__FreeBSD__) && !defined(__Userspace__) - ip->ip_off = htons(0); + GET_IP_OFFSET(ip) = htons(0); #else - ip->ip_off = 0; + GET_IP_OFFSET(ip) = 0; #endif } #if defined(__Userspace__) - ip->ip_id = htons(SCTP_IP_ID(inp)++); + GET_IP_ID(ip) = htons(SCTP_IP_ID(inp)++); #elif defined(__FreeBSD__) - /* FreeBSD has a function for ip_id's */ + /* FreeBSD has a function for _id's */ ip_fillid(ip); #elif defined(__APPLE__) #if RANDOM_IP_ID - ip->ip_id = ip_randomid(); + GET_IP_ID(ip) = ip_randomid(); #else - ip->ip_id = htons(ip_id++); + GET_IP_ID(ip) = htons(ip_id++); #endif #else - ip->ip_id = SCTP_IP_ID(inp)++; + GET_IP_ID(ip) = SCTP_IP_ID(inp)++; #endif - ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl; + GET_IP_TTL(ip) = inp->ip_inp.inp.inp_ip_ttl; #if defined(__FreeBSD__) && !defined(__Userspace__) - ip->ip_len = htons(packet_length); + GET_IP_LEN(ip) = htons(packet_length); #else - ip->ip_len = packet_length; + GET_IP_LEN(ip) = packet_length; #endif - ip->ip_tos = tos_value; + GET_IP_TOS(ip) = tos_value; if (port) { - ip->ip_p = IPPROTO_UDP; + GET_IP_PROTO(ip) = IPPROTO_UDP; } else { - ip->ip_p = IPPROTO_SCTP; + GET_IP_PROTO(ip) = IPPROTO_SCTP; } - ip->ip_sum = 0; + GET_IP_CHKSUM(ip) = 0; if (net == NULL) { ro = &iproute; memset(&iproute, 0, sizeof(iproute)); @@ -4271,7 +4269,7 @@ int so_locked) ro = (sctp_route_t *)&net->ro; } /* Now the address selection part */ - ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; + GET_IP_DEST_ADDR(ip) = ((struct sockaddr_in *)to)->sin_addr.s_addr; /* call the routine to select the src address */ if (net && out_of_asoc_ok == 0) { @@ -4303,7 +4301,7 @@ int so_locked) sctp_m_freem(m); return (EHOSTUNREACH); } - ip->ip_src = net->ro._s_addr->address.sin.sin_addr; + GET_IP_SRC_ADDR(ip) = net->ro._s_addr->address.sin.sin_addr.s_addr; } else { if (over_addr == NULL) { struct sctp_ifa *_lsrc; @@ -4318,10 +4316,10 @@ int so_locked) sctp_m_freem(m); return (EHOSTUNREACH); } - ip->ip_src = _lsrc->address.sin.sin_addr; + GET_IP_SRC_ADDR(ip) = _lsrc->address.sin.sin_addr.s_addr; sctp_free_ifa(_lsrc); } else { - ip->ip_src = over_addr->sin.sin_addr; + GET_IP_SRC_ADDR(ip) = over_addr->sin.sin_addr.s_addr; SCTP_RTALLOC(ro, vrf_id, inp->fibnum); } } @@ -4332,26 +4330,26 @@ int so_locked) sctp_m_freem(m); return (EHOSTUNREACH); } - udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip)); - udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); - udp->uh_dport = port; - udp->uh_ulen = htons((uint16_t)(packet_length - sizeof(struct ip))); + udp = (STRUCT_UDP_HDR *)((caddr_t)ip + sizeof(STRUCT_IP_HDR)); + GET_UDP_SRC(udp) = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); + GET_UDP_DEST(udp) = port; + GET_UDP_LEN(udp) = htons((uint16_t)(packet_length - sizeof(STRUCT_IP_HDR))); #if !defined(__Userspace__) #if defined(__FreeBSD__) if (V_udp_cksum) { - udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP)); + GET_UDP_CHKSUM(ip) = in_pseudo(GET_IP_SRC_ADDR(ip), GET_IP_DEST_ADDR(ip), GET_UDP_LEN(udp) + htons(IPPROTO_UDP)); } else { - udp->uh_sum = 0; + GET_UDP_CHKSUM(ip) = 0; } #else - udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP)); + GET_UDP_CHKSUM(ip) = in_pseudo(GET_IP_SRC_ADDR(ip), GET_IP_DEST_ADDR(ip), GET_UDP_LEN(udp) + htons(IPPROTO_UDP)); #endif #else - udp->uh_sum = 0; + GET_UDP_CHKSUM(ip) = 0; #endif - sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr)); + sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(STRUCT_UDP_HDR)); } else { - sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip)); + sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(STRUCT_IP_HDR)); } sctphdr->src_port = src_port; @@ -4385,9 +4383,9 @@ int so_locked) memcpy(&iproute, ro, sizeof(*ro)); } SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv4 output routine from low level src addr:%x\n", - (uint32_t) (ntohl(ip->ip_src.s_addr))); + (uint32_t) (ntohl(GET_IP_SRC_ADDR(ip)))); SCTPDBG(SCTP_DEBUG_OUTPUT3, "Destination is %x\n", - (uint32_t)(ntohl(ip->ip_dst.s_addr))); + (uint32_t)(ntohl(GET_IP_DEST_ADDR(ip)))); #if defined(__FreeBSD__) && !defined(__Userspace__) SCTPDBG(SCTP_DEBUG_OUTPUT3, "RTP route is %p through\n", (void *)ro->ro_nh); @@ -4404,7 +4402,7 @@ int so_locked) } SCTP_ATTACH_CHAIN(o_pak, m, packet_length); if (port) { - sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr)); + sctphdr->checksum = sctp_calculate_cksum(m, sizeof(STRUCT_IP_HDR) + sizeof(STRUCT_UDP_HDR)); SCTP_STAT_INCR(sctps_sendswcrc); #if !defined(__Userspace__) #if defined(__FreeBSD__) @@ -4423,7 +4421,7 @@ int so_locked) #else if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) && (stcb) && (stcb->asoc.scope.loopback_scope))) { - sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip)); + sctphdr->checksum = sctp_calculate_cksum(m, sizeof(STRUCT_IP_HDR)); SCTP_STAT_INCR(sctps_sendswcrc); } else { SCTP_STAT_INCR(sctps_sendhwcrc); @@ -4491,7 +4489,7 @@ int so_locked) #endif if (mtu > 0) { if (net->port) { - mtu -= sizeof(struct udphdr); + mtu -= sizeof(STRUCT_UDP_HDR); } if (mtu < net->mtu) { if ((stcb != NULL) && (stcb->asoc.smallest_mtu > mtu)) { @@ -4556,7 +4554,7 @@ int so_locked) flowlabel &= 0x000fffff; len = SCTP_MIN_OVERHEAD; if (port) { - len += sizeof(struct udphdr); + len += sizeof(STRUCT_UDP_HDR); } newm = sctp_get_mbuf_for_msg(len, 1, M_NOWAIT, 1, MT_DATA); if (newm == NULL) { @@ -4821,12 +4819,12 @@ int so_locked) sctp_m_freem(m); return (EHOSTUNREACH); } - udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr)); - udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); - udp->uh_dport = port; - udp->uh_ulen = htons((uint16_t)(packet_length - sizeof(struct ip6_hdr))); - udp->uh_sum = 0; - sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr)); + udp = (STRUCT_UDP_HDR *)((caddr_t)ip6h + sizeof(struct ip6_hdr)); + GET_UDP_SRC(udp) = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); + GET_UDP_DEST(udp) = port; + GET_UDP_LEN(udp) = htons((uint16_t)(packet_length - sizeof(struct ip6_hdr))); + GET_UDP_CHKSUM(ip) = 0; + sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(STRUCT_UDP_HDR)); } else { sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr)); } @@ -4871,14 +4869,14 @@ int so_locked) } SCTP_ATTACH_CHAIN(o_pak, m, packet_length); if (port) { - sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr)); + sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(STRUCT_UDP_HDR)); SCTP_STAT_INCR(sctps_sendswcrc); #if !defined(__Userspace__) #if defined(_WIN32) - udp->uh_sum = 0; + GET_UDP_CHKSUM(ip) = 0; #else - if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) { - udp->uh_sum = 0xffff; + if ((GET_UDP_CHKSUM(ip) = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) { + GET_UDP_CHKSUM(ip) = 0xffff; } #endif #endif @@ -4981,7 +4979,7 @@ int so_locked) #endif if (mtu > 0) { if (net->port) { - mtu -= sizeof(struct udphdr); + mtu -= sizeof(STRUCT_UDP_HDR); } if (mtu < net->mtu) { if ((stcb != NULL) && (stcb->asoc.smallest_mtu > mtu)) { @@ -5547,7 +5545,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, #ifdef INET6 SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr)); #else - SCTP_BUF_RESV_UF(op_err, sizeof(struct ip)); + SCTP_BUF_RESV_UF(op_err, sizeof(STRUCT_IP_HDR)); #endif SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr)); SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr)); @@ -5589,7 +5587,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, #ifdef INET6 SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr)); #else - SCTP_BUF_RESV_UF(op_err, sizeof(struct ip)); + SCTP_BUF_RESV_UF(op_err, sizeof(STRUCT_IP_HDR)); #endif SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr)); SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr)); @@ -5681,7 +5679,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, #ifdef INET6 SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr)); #else - SCTP_BUF_RESV_UF(op_err, sizeof(struct ip)); + SCTP_BUF_RESV_UF(op_err, sizeof(STRUCT_IP_HDR)); #endif SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr)); SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr)); @@ -11640,7 +11638,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *shout; struct sctp_chunkhdr *ch; #if defined(INET) || defined(INET6) - struct udphdr *udp; + STRUCT_UDP_HDR *udp; #endif int ret, len, cause_len, padding_len; #ifdef INET @@ -11648,7 +11646,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, sctp_route_t ro; #endif struct sockaddr_in *src_sin, *dst_sin; - struct ip *ip; + STRUCT_IP_HDR *ip; #endif #ifdef INET6 struct sockaddr_in6 *src_sin6, *dst_sin6; @@ -11683,7 +11681,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, switch (dst->sa_family) { #ifdef INET case AF_INET: - len += sizeof(struct ip); + len += sizeof(STRUCT_IP_HDR); break; #endif #ifdef INET6 @@ -11696,7 +11694,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, } #if defined(INET) || defined(INET6) if (port) { - len += sizeof(struct udphdr); + len += sizeof(STRUCT_UDP_HDR); } #endif #if defined(__APPLE__) && !defined(__Userspace__) @@ -11741,40 +11739,39 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, case AF_INET: src_sin = (struct sockaddr_in *)src; dst_sin = (struct sockaddr_in *)dst; - ip = mtod(mout, struct ip *); - ip->ip_v = IPVERSION; - ip->ip_hl = (sizeof(struct ip) >> 2); - ip->ip_tos = 0; + ip = mtod(mout, STRUCT_IP_HDR *); + SET_IP_VHL(ip, IPVERSION, (sizeof(STRUCT_IP_HDR) >> 2)); + GET_IP_TOS(ip) = 0; #if defined(__FreeBSD__) && !defined(__Userspace__) - ip->ip_off = htons(IP_DF); + GET_IP_OFFSET(ip) = htons(IP_DF); #elif defined(WITH_CONVERT_IP_OFF) || defined(__APPLE__) - ip->ip_off = IP_DF; + GET_IP_OFFSET(ip) = IP_DF; #else - ip->ip_off = htons(IP_DF); + GET_IP_OFFSET(ip) = htons(IP_DF); #endif #if defined(__Userspace__) - ip->ip_id = htons(ip_id++); + GET_IP_ID(ip) = htons(ip_id++); #elif defined(__FreeBSD__) ip_fillid(ip); #elif defined(__APPLE__) #if RANDOM_IP_ID - ip->ip_id = ip_randomid(); + GET_IP_ID(ip) = ip_randomid(); #else - ip->ip_id = htons(ip_id++); + GET_IP_ID(ip) = htons(ip_id++); #endif #else - ip->ip_id = ip_id++; + GET_IP_ID(ip) = ip_id++; #endif - ip->ip_ttl = MODULE_GLOBAL(ip_defttl); + GET_IP_TTL(ip) = MODULE_GLOBAL(ip_defttl); if (port) { - ip->ip_p = IPPROTO_UDP; + GET_IP_PROTO(ip) = IPPROTO_UDP; } else { - ip->ip_p = IPPROTO_SCTP; + GET_IP_PROTO(ip) = IPPROTO_SCTP; } - ip->ip_src.s_addr = dst_sin->sin_addr.s_addr; - ip->ip_dst.s_addr = src_sin->sin_addr.s_addr; - ip->ip_sum = 0; - len = sizeof(struct ip); + GET_IP_SRC_ADDR(ip) = dst_sin->sin_addr.s_addr; + GET_IP_DEST_ADDR(ip) = src_sin->sin_addr.s_addr; + GET_IP_CHKSUM(ip) = 0; + len = sizeof(STRUCT_IP_HDR); shout = (struct sctphdr *)((caddr_t)ip + len); break; #endif @@ -11816,16 +11813,16 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, sctp_m_freem(mout); return; } - udp = (struct udphdr *)shout; - udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); - udp->uh_dport = port; - udp->uh_sum = 0; - udp->uh_ulen = htons((uint16_t)(sizeof(struct udphdr) + + udp = (STRUCT_UDP_HDR *)shout; + GET_UDP_SRC(udp) = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); + GET_UDP_DEST(udp) = port; + GET_UDP_CHKSUM(ip) = 0; + GET_UDP_LEN(udp) = htons((uint16_t)(sizeof(STRUCT_UDP_HDR) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + cause_len + padding_len)); - len += sizeof(struct udphdr); - shout = (struct sctphdr *)((caddr_t)shout + sizeof(struct udphdr)); + len += sizeof(STRUCT_UDP_HDR); + shout = (struct sctphdr *)((caddr_t)shout + sizeof(STRUCT_UDP_HDR)); } else { udp = NULL; } @@ -11866,26 +11863,26 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, #if !defined(_WIN32) && !defined(__Userspace__) #if defined(__FreeBSD__) if (V_udp_cksum) { - udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP)); + GET_UDP_CHKSUM(ip) = in_pseudo(GET_IP_SRC_ADDR(ip), GET_IP_DEST_ADDR(ip), GET_UDP_LEN(udp) + htons(IPPROTO_UDP)); } else { - udp->uh_sum = 0; + GET_UDP_CHKSUM(ip) = 0; } #else - udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP)); + GET_UDP_CHKSUM(ip) = in_pseudo(GET_IP_SRC_ADDR(ip), GET_IP_DEST_ADDR(ip), GET_UDP_LEN(udp) + htons(IPPROTO_UDP)); #endif #else - udp->uh_sum = 0; + GET_UDP_CHKSUM(ip) = 0; #endif } #if defined(__FreeBSD__) && !defined(__Userspace__) - ip->ip_len = htons(len); + GET_IP_LEN(ip) = htons(len); #elif defined(__APPLE__) || defined(__Userspace__) - ip->ip_len = len; + GET_IP_LEN(ip) = len; #else - ip->ip_len = htons(len); + GET_IP_LEN(ip) = htons(len); #endif if (port) { - shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip) + sizeof(struct udphdr)); + shout->checksum = sctp_calculate_cksum(mout, sizeof(STRUCT_IP_HDR) + sizeof(STRUCT_UDP_HDR)); SCTP_STAT_INCR(sctps_sendswcrc); #if !defined(_WIN32) && !defined(__Userspace__) #if defined(__FreeBSD__) @@ -11902,7 +11899,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); #else - shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip)); + shout->checksum = sctp_calculate_cksum(mout, sizeof(STRUCT_IP_HDR)); SCTP_STAT_INCR(sctps_sendswcrc); #endif } @@ -11930,14 +11927,14 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, case AF_INET6: ip6->ip6_plen = htons((uint16_t)(len - sizeof(struct ip6_hdr))); if (port) { - shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr)); + shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(STRUCT_UDP_HDR)); SCTP_STAT_INCR(sctps_sendswcrc); #if !defined(__Userspace__) #if defined(_WIN32) - udp->uh_sum = 0; + GET_UDP_CHKSUM(ip) = 0; #else - if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) { - udp->uh_sum = 0xffff; + if ((GET_UDP_CHKSUM(ip) = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) { + GET_UDP_CHKSUM(ip) = 0xffff; } #endif #endif diff --git a/usrsctplib/netinet/sctp_pcb.c b/usrsctplib/netinet/sctp_pcb.c index f640a60..4acf743 100755 --- a/usrsctplib/netinet/sctp_pcb.c +++ b/usrsctplib/netinet/sctp_pcb.c @@ -51,18 +51,18 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 363323 2020-07-19 12:34:19Z tuex #include #include #include -#if defined(INET) || defined(INET6) -#if !defined(_WIN32) -#include -#endif -#endif +#include +#include + #ifdef INET6 #if defined(__Userspace__) #include "user_ip6_var.h" #else +#if !defined(SCTP_USE_LWIP) #include #endif #endif +#endif #if defined(__FreeBSD__) && !defined(__Userspace__) #include #include @@ -612,7 +612,11 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, if (if_name != NULL) { SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", if_name); } else { + #if defined(SCTP_USE_LWIP) + SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", "na"); + #else SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", "unknown"); + #endif } hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))]; LIST_INIT(&sctp_ifnp->ifalist); @@ -4624,7 +4628,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, } #if defined(INET) || defined(INET6) if (net->port) { - net->mtu += (uint32_t)sizeof(struct udphdr); + net->mtu += (uint32_t)sizeof(STRUCT_UDP_HDR); } #endif } else if (net->ro._s_addr != NULL) { @@ -4680,7 +4684,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, } #if defined(INET) || defined(INET6) if (net->port) { - net->mtu += (uint32_t)sizeof(struct udphdr); + net->mtu += (uint32_t)sizeof(STRUCT_UDP_HDR); } #endif } else { @@ -4707,7 +4711,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, } #if defined(INET) || defined(INET6) if (net->port) { - net->mtu -= (uint32_t)sizeof(struct udphdr); + net->mtu -= (uint32_t)sizeof(STRUCT_UDP_HDR); } #endif if (from == SCTP_ALLOC_ASOC) { @@ -6490,7 +6494,7 @@ sctp_startup_mcore_threads(void) static struct mbuf * sctp_netisr_hdlr(struct mbuf *m, uintptr_t source) { - struct ip *ip; + STRUCT_IP_HDR *ip; struct sctphdr *sh; int offset; uint32_t flowid, tag; @@ -6499,16 +6503,16 @@ sctp_netisr_hdlr(struct mbuf *m, uintptr_t source) * No flow id built by lower layers fix it so we * create one. */ - ip = mtod(m, struct ip *); - offset = (ip->ip_hl << 2) + sizeof(struct sctphdr); + ip = mtod(m, STRUCT_IP_HDR *); + offset = GET_IP_HDR_LEN_VAL(ip) + sizeof(struct sctphdr); if (SCTP_BUF_LEN(m) < offset) { if ((m = m_pullup(m, offset)) == NULL) { SCTP_STAT_INCR(sctps_hdrops); return (NULL); } - ip = mtod(m, struct ip *); + ip = mtod(m, STRUCT_IP_HDR *); } - sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2)); + sh = (struct sctphdr *)((caddr_t)ip + (GET_IP_HDR_LEN_VAL(ip) << 2)); tag = htonl(sh->v_tag); flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port); m->m_pkthdr.flowid = flowid; diff --git a/usrsctplib/netinet/sctp_timer.c b/usrsctplib/netinet/sctp_timer.c index ad062b3..04b4cf6 100755 --- a/usrsctplib/netinet/sctp_timer.c +++ b/usrsctplib/netinet/sctp_timer.c @@ -56,11 +56,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 362054 2020-06-11 13:34:09Z tu #include #include #include -#if defined(INET) || defined(INET6) -#if !(defined(_WIN32) && defined(__Userspace__)) -#include -#endif -#endif + +#include void sctp_audit_retranmission_queue(struct sctp_association *asoc) @@ -1541,7 +1538,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp, #endif #if defined(INET) || defined(INET6) if (net->port) { - mtu -= sizeof(struct udphdr); + mtu -= sizeof(STRUCT_UDP_HDR); } #endif if (mtu > next_mtu) { diff --git a/usrsctplib/netinet/sctp_udp_port.h b/usrsctplib/netinet/sctp_udp_port.h new file mode 100755 index 0000000..ec8ddbb --- /dev/null +++ b/usrsctplib/netinet/sctp_udp_port.h @@ -0,0 +1,74 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * b) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * c) Neither the name of Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__FreeBSD__) && !defined(__Userspace__) +#include +__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 359195 2020-03-21 16:12:19Z tuexen $"); +#endif + +#ifndef _NETINET_SCTP_UDP_PORT_H_ +#define _NETINET_SCTP_UDP_PORT_H_ + +#if !defined(_WIN32) +#if defined(INET) || defined(INET6) +#if !defined(SCTP_USE_LWIP) +#include + +#define STRUCT_UDP_HDR struct udphdr +#define GET_UDP_SRC(udp) ((struct udphdr*)udp)->source +#define GET_UDP_DEST(udp) ((struct udphdr*)udp)->dest +#define GET_UDP_LEN(udp) ((struct udphdr*)udp)->len +#define GET_UDP_CHKSUM(udp) ((struct udphdr*)udp)->check + +#else +#include "lwip/udp.h" +#define STRUCT_UDP_HDR struct udp_hdr +#define GET_UDP_SRC(udp) ((struct udp_hdr*)udp)->src +#define GET_UDP_DEST(udp) ((struct udp_hdr*)udp)->dest +#define GET_UDP_LEN(udp) ((struct udp_hdr*)udp)->len +#define GET_UDP_CHKSUM(udp) ((struct udp_hdr*)udp)->chksum + +// #TBD +#define UIO_MAXIOV 1024 +#define ERESTART 85 /* Interrupted system call should be restarted */ + +#endif +#endif +#include +#else +#include +#endif + + +#endif//!< _NETINET_SCTP_UDP_PORT_H_ diff --git a/usrsctplib/netinet/sctp_userspace.c b/usrsctplib/netinet/sctp_userspace.c index 8e2ebf4..8dd386f 100755 --- a/usrsctplib/netinet/sctp_userspace.c +++ b/usrsctplib/netinet/sctp_userspace.c @@ -98,6 +98,13 @@ sctp_userspace_set_threadname(const char *name) int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) { + #if defined(SCTP_USE_LWIP) + struct netif* net_if = netif_get_by_index(if_index); + if(net_if != NULL){ + return net_if->mtu; + } + return 0; + #else struct ifreq ifr; int fd; @@ -115,6 +122,7 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) } else { return (0); } + #endif } #endif diff --git a/usrsctplib/netinet/sctp_usrreq.c b/usrsctplib/netinet/sctp_usrreq.c index bf66b36..ba51455 100755 --- a/usrsctplib/netinet/sctp_usrreq.c +++ b/usrsctplib/netinet/sctp_usrreq.c @@ -59,7 +59,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 363275 2020-07-17 15:09:49Z t #if defined(__Userspace__) #include #else -#include + +#include + #endif #if defined(__FreeBSD__) && !defined(__Userspace__) #include @@ -330,13 +332,13 @@ sctp_notify(struct sctp_inpcb *inp, } /* Update the path MTU. */ if (net->port) { - next_mtu -= sizeof(struct udphdr); + next_mtu -= sizeof(STRUCT_UDP_HDR); } if (net->mtu > next_mtu) { net->mtu = next_mtu; #if defined(__FreeBSD__) && !defined(__Userspace__) if (net->port) { - sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr)); + sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(STRUCT_UDP_HDR)); } else { sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu); } @@ -366,9 +368,9 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip) #endif { #if defined(__FreeBSD__) && !defined(__Userspace__) - struct ip *outer_ip; + STRUCT_IP_HDR *outer_ip; #endif - struct ip *inner_ip; + STRUCT_IP_HDR *inner_ip; struct sctphdr *sh; struct icmp *icmp; struct sctp_inpcb *inp; @@ -389,27 +391,27 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip) return; } if (vip != NULL) { - inner_ip = (struct ip *)vip; + inner_ip = (STRUCT_IP_HDR *)vip; icmp = (struct icmp *)((caddr_t)inner_ip - - (sizeof(struct icmp) - sizeof(struct ip))); + (sizeof(struct icmp) - sizeof(STRUCT_IP_HDR))); #if defined(__FreeBSD__) && !defined(__Userspace__) - outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip)); + outer_ip = (STRUCT_IP_HDR *)((caddr_t)icmp - sizeof(STRUCT_IP_HDR)); #endif - sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2)); + sh = (struct sctphdr *)((caddr_t)inner_ip + (GET_IP_HDR_LEN_VAL(inner_ip) << 2)); memset(&src, 0, sizeof(struct sockaddr_in)); src.sin_family = AF_INET; #ifdef HAVE_SIN_LEN src.sin_len = sizeof(struct sockaddr_in); #endif src.sin_port = sh->src_port; - src.sin_addr = inner_ip->ip_src; + src.sin_addr = GET_IP_SRC(inner_ip); memset(&dst, 0, sizeof(struct sockaddr_in)); dst.sin_family = AF_INET; #ifdef HAVE_SIN_LEN dst.sin_len = sizeof(struct sockaddr_in); #endif dst.sin_port = sh->dest_port; - dst.sin_addr = inner_ip->ip_dst; + dst.sin_addr = GET_IP_DEST(inner_ip); /* * 'dst' holds the dest of the packet that failed to be sent. * 'src' holds our local endpoint address. Thus we reverse @@ -437,9 +439,9 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip) } } else { #if defined(__FreeBSD__) && !defined(__Userspace__) - if (ntohs(outer_ip->ip_len) >= - sizeof(struct ip) + - 8 + (inner_ip->ip_hl << 2) + 20) { + if (ntohs(GET_IP_LEN(outer_ip)) >= + sizeof(STRUCT_IP_HDR) + + 8 + (GET_IP_HDR_LEN_VAL(inner_ip) << 2) + 20) { /* * In this case we can check if we * got an INIT chunk and if the @@ -464,9 +466,9 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip) icmp->icmp_type, icmp->icmp_code, #if defined(__FreeBSD__) && !defined(__Userspace__) - ntohs(inner_ip->ip_len), + ntohs(GET_IP_LEN(inner_ip)), #else - inner_ip->ip_len, + GET_IP_LEN(inner_ip), #endif (uint32_t)ntohs(icmp->icmp_nextmtu)); #if defined(__Userspace__) diff --git a/usrsctplib/netinet/sctputil.c b/usrsctplib/netinet/sctputil.c index 19c17b3..4d6bae1 100755 --- a/usrsctplib/netinet/sctputil.c +++ b/usrsctplib/netinet/sctputil.c @@ -63,7 +63,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 363323 2020-07-19 12:34:19Z tuex #if defined(INET6) || defined(INET) #include #endif -#include +#include + #include #include #ifdef INET6 @@ -8070,12 +8071,12 @@ static void sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED) { - struct ip *iph; + STRUCT_IP_HDR *iph; #ifdef INET6 struct ip6_hdr *ip6; #endif struct mbuf *sp, *last; - struct udphdr *uhdr; + STRUCT_UDP_HDR *uhdr; uint16_t port; if ((m->m_flags & M_PKTHDR) == 0) { @@ -8083,9 +8084,9 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, goto out; } /* Pull the src port */ - iph = mtod(m, struct ip *); - uhdr = (struct udphdr *)((caddr_t)iph + off); - port = uhdr->uh_sport; + iph = mtod(m, STRUCT_IP_HDR *); + uhdr = (STRUCT_UDP_HDR *)((caddr_t)iph + off); + port = GET_UDP_SRC(uhdr); /* Split out the mbuf chain. Leave the * IP header in m, place the * rest in the sp. @@ -8095,19 +8096,19 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, /* Gak, drop packet, we can't do a split */ goto out; } - if (sp->m_pkthdr.len < sizeof(struct udphdr) + sizeof(struct sctphdr)) { + if (sp->m_pkthdr.len < sizeof(STRUCT_UDP_HDR) + sizeof(struct sctphdr)) { /* Gak, packet can't have an SCTP header in it - too small */ m_freem(sp); goto out; } /* Now pull up the UDP header and SCTP header together */ - sp = m_pullup(sp, sizeof(struct udphdr) + sizeof(struct sctphdr)); + sp = m_pullup(sp, sizeof(STRUCT_UDP_HDR) + sizeof(struct sctphdr)); if (sp == NULL) { /* Gak pullup failed */ goto out; } /* Trim out the UDP header */ - m_adj(sp, sizeof(struct udphdr)); + m_adj(sp, sizeof(STRUCT_UDP_HDR)); /* Now reconstruct the mbuf chain */ for (last = m; last->m_next; last = last->m_next); @@ -8125,18 +8126,18 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, if_name(m->m_pkthdr.rcvif), (int)m->m_pkthdr.csum_flags, CSUM_BITS); m->m_pkthdr.csum_flags &= ~CSUM_DATA_VALID; - iph = mtod(m, struct ip *); - switch (iph->ip_v) { + iph = mtod(m, STRUCT_IP_HDR *); + switch (GET_IP_VERSION_VAL(iph)) { #ifdef INET case IPVERSION: - iph->ip_len = htons(ntohs(iph->ip_len) - sizeof(struct udphdr)); + GET_IP_LEN(iph) = htons(ntohs(GET_IP_LEN(iph)) - sizeof(STRUCT_UDP_HDR)); sctp_input_with_port(m, off, port); break; #endif #ifdef INET6 case IPV6_VERSION >> 4: ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr)); + ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(STRUCT_UDP_HDR)); sctp6_input_with_port(&m, &off, port); break; #endif @@ -8153,10 +8154,10 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, static void sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ctx SCTP_UNUSED) { - struct ip *outer_ip, *inner_ip; + STRUCT_IP_HDR *outer_ip, *inner_ip; struct sctphdr *sh; struct icmp *icmp; - struct udphdr *udp; + STRUCT_UDP_HDR *udp; struct sctp_inpcb *inp; struct sctp_tcb *stcb; struct sctp_nets *net; @@ -8164,15 +8165,15 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct struct sockaddr_in src, dst; uint8_t type, code; - inner_ip = (struct ip *)vip; + inner_ip = (STRUCT_IP_HDR *)vip; icmp = (struct icmp *)((caddr_t)inner_ip - - (sizeof(struct icmp) - sizeof(struct ip))); - outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip)); - if (ntohs(outer_ip->ip_len) < - sizeof(struct ip) + 8 + (inner_ip->ip_hl << 2) + sizeof(struct udphdr) + 8) { + (sizeof(struct icmp) - sizeof(STRUCT_IP_HDR))); + outer_ip = (STRUCT_IP_HDR *)((caddr_t)icmp - sizeof(STRUCT_IP_HDR)); + if (ntohs(GET_IP_LEN(outer_ip)) < + sizeof(STRUCT_IP_HDR) + 8 + (GET_IP_HDR_LEN_VAL(inner_ip) << 2) + sizeof(STRUCT_UDP_HDR) + 8) { return; } - udp = (struct udphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2)); + udp = (STRUCT_UDP_HDR *)((caddr_t)inner_ip + (GET_IP_HDR_LEN_VAL(inner_ip) << 2)); sh = (struct sctphdr *)(udp + 1); memset(&src, 0, sizeof(struct sockaddr_in)); src.sin_family = AF_INET; @@ -8180,14 +8181,14 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct src.sin_len = sizeof(struct sockaddr_in); #endif src.sin_port = sh->src_port; - src.sin_addr = inner_ip->ip_src; + src.sin_addr = GET_IP_SRC(inner_ip); memset(&dst, 0, sizeof(struct sockaddr_in)); dst.sin_family = AF_INET; #ifdef HAVE_SIN_LEN dst.sin_len = sizeof(struct sockaddr_in); #endif dst.sin_port = sh->dest_port; - dst.sin_addr = inner_ip->ip_dst; + dst.sin_addr = GET_IP_DEST(inner_ip); /* * 'dst' holds the dest of the packet that failed to be sent. * 'src' holds our local endpoint address. Thus we reverse @@ -8203,8 +8204,8 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct (net != NULL) && (inp != NULL)) { /* Check the UDP port numbers */ - if ((udp->uh_dport != net->port) || - (udp->uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) { + if ((GET_UDP_DEST(udp) != net->port) || + (GET_UDP_SRC(udp) != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) { SCTP_TCB_UNLOCK(stcb); return; } @@ -8221,9 +8222,9 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct return; } } else { - if (ntohs(outer_ip->ip_len) >= - sizeof(struct ip) + - 8 + (inner_ip->ip_hl << 2) + 8 + 20) { + if (ntohs(GET_UDP_LEN(outer_ip)) >= + sizeof(STRUCT_IP_HDR) + + 8 + (GET_IP_HDR_LEN_VAL(inner_ip) << 2) + 8 + 20) { /* * In this case we can check if we * got an INIT chunk and if the @@ -8247,7 +8248,7 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct code = ICMP_UNREACH_PROTOCOL; } sctp_notify(inp, stcb, net, type, code, - ntohs(inner_ip->ip_len), + ntohs(GET_UDP_LEN(inner_ip)), (uint32_t)ntohs(icmp->icmp_nextmtu)); #if defined(__Userspace__) if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) && @@ -8291,7 +8292,7 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx struct sctp_tcb *stcb; struct sctp_nets *net; struct sctphdr sh; - struct udphdr udp; + STRUCT_UDP_HDR udp; struct sockaddr_in6 src, dst; uint8_t type, code; @@ -8307,19 +8308,19 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx * verification tag of the SCTP common header. */ if (ip6cp->ip6c_m->m_pkthdr.len < - ip6cp->ip6c_off + sizeof(struct udphdr)+ offsetof(struct sctphdr, checksum)) { + ip6cp->ip6c_off + sizeof(STRUCT_UDP_HDR)+ offsetof(struct sctphdr, checksum)) { return; } /* Copy out the UDP header. */ - memset(&udp, 0, sizeof(struct udphdr)); + memset(&udp, 0, sizeof(STRUCT_UDP_HDR)); m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off, - sizeof(struct udphdr), + sizeof(STRUCT_UDP_HDR), (caddr_t)&udp); /* Copy out the port numbers and the verification tag. */ memset(&sh, 0, sizeof(struct sctphdr)); m_copydata(ip6cp->ip6c_m, - ip6cp->ip6c_off + sizeof(struct udphdr), + ip6cp->ip6c_off + sizeof(STRUCT_UDP_HDR), sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t), (caddr_t)&sh); memset(&src, 0, sizeof(struct sockaddr_in6)); @@ -8355,8 +8356,8 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx (net != NULL) && (inp != NULL)) { /* Check the UDP port numbers */ - if ((udp.uh_dport != net->port) || - (udp.uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) { + if ((GET_UDP_DEST(udp) != net->port) || + (GET_UDP_SRCudp) != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) { SCTP_TCB_UNLOCK(stcb); return; } @@ -8374,7 +8375,7 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx } else { #if defined(__FreeBSD__) && !defined(__Userspace__) if (ip6cp->ip6c_m->m_pkthdr.len >= - ip6cp->ip6c_off + sizeof(struct udphdr) + + ip6cp->ip6c_off + sizeof(STRUCT_UDP_HDR) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + offsetof(struct sctp_init, a_rwnd)) { @@ -8388,13 +8389,13 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off + - sizeof(struct udphdr) + + sizeof(STRUCT_UDP_HDR) + sizeof(struct sctphdr), sizeof(uint8_t), (caddr_t)&chunk_type); m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off + - sizeof(struct udphdr) + + sizeof(STRUCT_UDP_HDR) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr), sizeof(uint32_t), diff --git a/usrsctplib/netinet6/sctp6_usrreq.c b/usrsctplib/netinet6/sctp6_usrreq.c index 1fc81da..9ef7256 100644 --- a/usrsctplib/netinet6/sctp6_usrreq.c +++ b/usrsctplib/netinet6/sctp6_usrreq.c @@ -60,7 +60,7 @@ __FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 361895 2020-06-07 14:39:20Z #include #if !defined(_WIN32) #include -#include +#include #endif #if defined(__Userspace__) int ip6_v6only=0; @@ -373,13 +373,13 @@ sctp6_notify(struct sctp_inpcb *inp, } /* Update the path MTU. */ if (net->port) { - next_mtu -= sizeof(struct udphdr); + next_mtu -= sizeof(STRUCT_UDP_HDR); } if (net->mtu > next_mtu) { net->mtu = next_mtu; #if defined(__FreeBSD__) if (net->port) { - sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr)); + sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(STRUCT_UDP_HDR)); } else { sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu); } diff --git a/usrsctplib/user_ip_icmp.h b/usrsctplib/user_ip_icmp.h index 049314e..50f22b1 100755 --- a/usrsctplib/user_ip_icmp.h +++ b/usrsctplib/user_ip_icmp.h @@ -122,7 +122,7 @@ struct icmp { uint32_t its_ttime; /* Transmit */ } id_ts; struct id_ip { - struct ip idi_ip; + STRUCT_IP_HDR idi_ip; /* options and then 64 bits of data */ } id_ip; struct icmp_ra_addr id_radv; @@ -149,7 +149,7 @@ struct icmp { #define ICMP_MINLEN 8 /* abs minimum */ #define ICMP_TSLEN (8 + 3 * sizeof (uint32_t)) /* timestamp */ #define ICMP_MASKLEN 12 /* address mask */ -#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ +#define ICMP_ADVLENMIN (8 + sizeof (STRUCT_IP_HDR) + 8) /* min */ #define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) /* N.B.: must separately check that ip_hl >= 5 */ diff --git a/usrsctplib/user_recv_thread.c b/usrsctplib/user_recv_thread.c index 3c1657b..5848e94 100755 --- a/usrsctplib/user_recv_thread.c +++ b/usrsctplib/user_recv_thread.c @@ -45,6 +45,7 @@ #include #include #include +#include #if 0 #if defined(__linux__) #include @@ -266,7 +267,7 @@ static void * recv_function_raw(void *arg) { struct mbuf **recvmbuf; - struct ip *iphdr; + STRUCT_IP_HDR *iphdr; struct sctphdr *sh; uint16_t port; int offset, ecn = 0; @@ -371,27 +372,28 @@ recv_function_raw(void *arg) } while (ncounter > 0); } - iphdr = mtod(recvmbuf[0], struct ip *); - sh = (struct sctphdr *)((caddr_t)iphdr + sizeof(struct ip)); + iphdr = mtod(recvmbuf[0], STRUCT_IP_HDR *); + sh = (struct sctphdr *)((caddr_t)iphdr + sizeof(STRUCT_IP_HDR)); ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); - offset = sizeof(struct ip) + sizeof(struct sctphdr); + offset = sizeof(STRUCT_IP_HDR) + sizeof(struct sctphdr); - if (iphdr->ip_tos != 0) { - ecn = iphdr->ip_tos & 0x02; + + if (GET_IP_TOS(iphdr) != 0) { + ecn = GET_IP_TOS(iphdr) & 0x02; } dst.sin_family = AF_INET; #ifdef HAVE_SIN_LEN dst.sin_len = sizeof(struct sockaddr_in); #endif - dst.sin_addr = iphdr->ip_dst; + dst.sin_addr.s_addr = GET_IP_DEST_ADDR(iphdr); dst.sin_port = sh->dest_port; src.sin_family = AF_INET; #ifdef HAVE_SIN_LEN src.sin_len = sizeof(struct sockaddr_in); #endif - src.sin_addr = iphdr->ip_src; + src.sin_addr.s_addr = GET_IP_SRC_ADDR(iphdr); src.sin_port = sh->src_port; /* SCTP does not allow broadcasts or multicasts */ @@ -417,7 +419,7 @@ recv_function_raw(void *arg) } SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n); SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset); - sctp_common_input_processing(&recvmbuf[0], sizeof(struct ip), offset, n, + sctp_common_input_processing(&recvmbuf[0], sizeof(STRUCT_IP_HDR), offset, n, (struct sockaddr *)&src, (struct sockaddr *)&dst, sh, ch, @@ -1053,6 +1055,9 @@ setSendBufferSize(int sfd, int new_size) SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", WSAGetLastError()); #else SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", errno); +#endif +#if defined(SCTP_USE_LWIP) + SCTP_PRINTF("lwIP does not support this socket option(SO_SNDBUF:%d), so you need to control this by yourself.", new_size); #endif } return; diff --git a/usrsctplib/user_socket.c b/usrsctplib/user_socket.c index b72b05e..84e0160 100755 --- a/usrsctplib/user_socket.c +++ b/usrsctplib/user_socket.c @@ -50,14 +50,9 @@ #if defined(__linux__) #define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */ #endif -#if !defined(_WIN32) -#if defined INET || defined INET6 -#include -#endif -#include -#else -#include -#endif + +#include + userland_mutex_t accept_mtx; userland_cond_t accept_cond; #ifdef _WIN32 @@ -2858,8 +2853,8 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak, int iovcnt; int len; int send_count; - struct ip *ip; - struct udphdr *udp; + STRUCT_IP_HDR *ip; + STRUCT_UDP_HDR *udp; struct sockaddr_in dst; #if defined(_WIN32) WSAMSG win_msg_hdr; @@ -2877,57 +2872,57 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak, m = SCTP_HEADER_TO_CHAIN(o_pak); m_orig = m; - len = sizeof(struct ip); + len = sizeof(STRUCT_IP_HDR); if (SCTP_BUF_LEN(m) < len) { if ((m = m_pullup(m, len)) == 0) { SCTP_PRINTF("Can not get the IP header in the first mbuf.\n"); return; } } - ip = mtod(m, struct ip *); - use_udp_tunneling = (ip->ip_p == IPPROTO_UDP); + ip = mtod(m, STRUCT_IP_HDR *); + use_udp_tunneling = (GET_IP_PROTO(ip) == IPPROTO_UDP); if (use_udp_tunneling) { - len = sizeof(struct ip) + sizeof(struct udphdr); + len = sizeof(STRUCT_IP_HDR) + sizeof(STRUCT_UDP_HDR); if (SCTP_BUF_LEN(m) < len) { if ((m = m_pullup(m, len)) == 0) { SCTP_PRINTF("Can not get the UDP/IP header in the first mbuf.\n"); return; } - ip = mtod(m, struct ip *); + ip = mtod(m, STRUCT_IP_HDR *); } - udp = (struct udphdr *)(ip + 1); + udp = (STRUCT_UDP_HDR *)(ip + 1); } else { udp = NULL; } if (!use_udp_tunneling) { - if (ip->ip_src.s_addr == INADDR_ANY) { + if (GET_IP_SRC_ADDR(ip) == INADDR_ANY) { /* TODO get addr of outgoing interface */ SCTP_PRINTF("Why did the SCTP implementation did not choose a source address?\n"); } /* TODO need to worry about ro->ro_dst as in ip_output? */ #if defined(__linux__) || defined(_WIN32) || (defined(__FreeBSD__) && (__FreeBSD_version >= 1100030)) /* need to put certain fields into network order for Linux */ - ip->ip_len = htons(ip->ip_len); + GET_IP_LEN(ip) = htons(GET_IP_LEN(ip)); #endif } memset((void *)&dst, 0, sizeof(struct sockaddr_in)); dst.sin_family = AF_INET; - dst.sin_addr.s_addr = ip->ip_dst.s_addr; + dst.sin_addr.s_addr = GET_IP_DEST_ADDR(ip); #ifdef HAVE_SIN_LEN dst.sin_len = sizeof(struct sockaddr_in); #endif if (use_udp_tunneling) { - dst.sin_port = udp->uh_dport; + dst.sin_port = GET_UDP_DEST(udp); } else { dst.sin_port = 0; } /* tweak the mbuf chain */ if (use_udp_tunneling) { - m_adj(m, sizeof(struct ip) + sizeof(struct udphdr)); + m_adj(m, sizeof(STRUCT_IP_HDR) + sizeof(STRUCT_UDP_HDR)); } send_count = 0; @@ -3004,7 +2999,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak, int len; int send_count; struct ip6_hdr *ip6; - struct udphdr *udp; + STRUCT_UDP_HDR *udp; struct sockaddr_in6 dst; #if defined(_WIN32) WSAMSG win_msg_hdr; @@ -3035,7 +3030,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak, use_udp_tunneling = (ip6->ip6_nxt == IPPROTO_UDP); if (use_udp_tunneling) { - len = sizeof(struct ip6_hdr) + sizeof(struct udphdr); + len = sizeof(struct ip6_hdr) + sizeof(STRUCT_UDP_HDR); if (SCTP_BUF_LEN(m) < len) { if ((m = m_pullup(m, len)) == 0) { SCTP_PRINTF("Can not get the UDP/IP header in the first mbuf.\n"); @@ -3043,7 +3038,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak, } ip6 = mtod(m, struct ip6_hdr *); } - udp = (struct udphdr *)(ip6 + 1); + udp = (STRUCT_UDP_HDR *)(ip6 + 1); } else { udp = NULL; } @@ -3064,14 +3059,14 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak, #endif if (use_udp_tunneling) { - dst.sin6_port = udp->uh_dport; + dst.sin6_port = GET_UDP_DEST(udp); } else { dst.sin6_port = 0; } /* tweak the mbuf chain */ if (use_udp_tunneling) { - m_adj(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr)); + m_adj(m, sizeof(struct ip6_hdr) + sizeof(STRUCT_UDP_HDR)); } else { m_adj(m, sizeof(struct ip6_hdr)); } diff --git a/usrsctplib/usrsctp.h b/usrsctplib/usrsctp.h index fea2aaf..0e3012f 100644 --- a/usrsctplib/usrsctp.h +++ b/usrsctplib/usrsctp.h @@ -34,8 +34,11 @@ #ifdef __cplusplus extern "C" { #endif - +#if !defined(SCTP_USE_LWIP) #include +#else +#include "lwip/errno.h" +#endif #include #ifdef _WIN32 #ifdef _MSC_VER @@ -120,7 +123,7 @@ struct sctp_common_header { * tune with other sockaddr_* structures. */ #if defined(__APPLE__) || defined(__Bitrig__) || defined(__DragonFly__) || \ - defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(SCTP_USE_LWIP) struct sockaddr_conn { uint8_t sconn_len; uint8_t sconn_family; -- 2.34.1