diff options
356 files changed, 6597 insertions, 3375 deletions
diff --git a/freebsd-org b/freebsd-org -Subproject e724f51f811a4b2bd29447f8b85ab5c2f9b8826 +Subproject d079ae0442af8fa3cfd6d7ede190d04e64a2c0d diff --git a/freebsd/contrib/tcpdump/addrtoname.c b/freebsd/contrib/tcpdump/addrtoname.c index fb4550cc..a47b3615 100644 --- a/freebsd/contrib/tcpdump/addrtoname.c +++ b/freebsd/contrib/tcpdump/addrtoname.c @@ -156,13 +156,23 @@ struct enamemem { u_short e_addr2; const char *e_name; u_char *e_nsap; /* used only for nsaptable[] */ -#define e_bs e_nsap /* for bytestringtable */ struct enamemem *e_nxt; }; static struct enamemem enametable[HASHNAMESIZE]; static struct enamemem nsaptable[HASHNAMESIZE]; -static struct enamemem bytestringtable[HASHNAMESIZE]; + +struct bsnamemem { + u_short bs_addr0; + u_short bs_addr1; + u_short bs_addr2; + const char *bs_name; + u_char *bs_bytes; + unsigned int bs_nbytes; + struct bsnamemem *bs_nxt; +}; + +static struct bsnamemem bytestringtable[HASHNAMESIZE]; struct protoidmem { uint32_t p_oui; @@ -348,7 +358,7 @@ getname6(netdissect_options *ndo, const u_char *ap) return (p->name); } -static const char hex[] = "0123456789abcdef"; +static const char hex[16] = "0123456789abcdef"; /* Find the hash node that corresponds the ether address 'ep' */ @@ -386,11 +396,11 @@ lookup_emem(netdissect_options *ndo, const u_char *ep) * with length 'nlen' */ -static inline struct enamemem * +static inline struct bsnamemem * lookup_bytestring(netdissect_options *ndo, register const u_char *bs, const unsigned int nlen) { - struct enamemem *tp; + struct bsnamemem *tp; register u_int i, j, k; if (nlen >= 6) { @@ -405,26 +415,28 @@ lookup_bytestring(netdissect_options *ndo, register const u_char *bs, i = j = k = 0; tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)]; - while (tp->e_nxt) - if (tp->e_addr0 == i && - tp->e_addr1 == j && - tp->e_addr2 == k && - memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0) + while (tp->bs_nxt) + if (nlen == tp->bs_nbytes && + tp->bs_addr0 == i && + tp->bs_addr1 == j && + tp->bs_addr2 == k && + memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0) return tp; else - tp = tp->e_nxt; + tp = tp->bs_nxt; - tp->e_addr0 = i; - tp->e_addr1 = j; - tp->e_addr2 = k; + tp->bs_addr0 = i; + tp->bs_addr1 = j; + tp->bs_addr2 = k; - tp->e_bs = (u_char *) calloc(1, nlen + 1); - if (tp->e_bs == NULL) + tp->bs_bytes = (u_char *) calloc(1, nlen); + if (tp->bs_bytes == NULL) (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc"); - memcpy(tp->e_bs, bs, nlen); - tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); - if (tp->e_nxt == NULL) + memcpy(tp->bs_bytes, bs, nlen); + tp->bs_nbytes = nlen; + tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp)); + if (tp->bs_nxt == NULL) (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc"); return tp; @@ -451,11 +463,11 @@ lookup_nsap(netdissect_options *ndo, register const u_char *nsap, tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; while (tp->e_nxt) - if (tp->e_addr0 == i && + if (nsap_length == tp->e_nsap[0] && + tp->e_addr0 == i && tp->e_addr1 == j && tp->e_addr2 == k && - tp->e_nsap[0] == nsap_length && - memcmp((const char *)&(nsap[1]), + memcmp((const char *)nsap, (char *)&(tp->e_nsap[1]), nsap_length) == 0) return tp; else @@ -555,12 +567,12 @@ le64addr_string(netdissect_options *ndo, const u_char *ep) const unsigned int len = 8; register u_int i; register char *cp; - register struct enamemem *tp; + register struct bsnamemem *tp; char buf[BUFSIZE]; tp = lookup_bytestring(ndo, ep, len); - if (tp->e_name) - return (tp->e_name); + if (tp->bs_name) + return (tp->bs_name); cp = buf; for (i = len; i > 0 ; --i) { @@ -572,11 +584,11 @@ le64addr_string(netdissect_options *ndo, const u_char *ep) *cp = '\0'; - tp->e_name = strdup(buf); - if (tp->e_name == NULL) + tp->bs_name = strdup(buf); + if (tp->bs_name == NULL) (*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)"); - return (tp->e_name); + return (tp->bs_name); } const char * @@ -585,7 +597,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep, { register u_int i; register char *cp; - register struct enamemem *tp; + register struct bsnamemem *tp; if (len == 0) return ("<empty>"); @@ -597,11 +609,11 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep, return (q922_string(ndo, ep, len)); tp = lookup_bytestring(ndo, ep, len); - if (tp->e_name) - return (tp->e_name); + if (tp->bs_name) + return (tp->bs_name); - tp->e_name = cp = (char *)malloc(len*3); - if (tp->e_name == NULL) + tp->bs_name = cp = (char *)malloc(len*3); + if (tp->bs_name == NULL) (*ndo->ndo_error)(ndo, "linkaddr_string: malloc"); *cp++ = hex[*ep >> 4]; *cp++ = hex[*ep++ & 0xf]; @@ -611,7 +623,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep, *cp++ = hex[*ep++ & 0xf]; } *cp = '\0'; - return (tp->e_name); + return (tp->bs_name); } const char * diff --git a/freebsd/contrib/tcpdump/addrtoname.h b/freebsd/contrib/tcpdump/addrtoname.h index 72e5ef19..fe8b6bbe 100644 --- a/freebsd/contrib/tcpdump/addrtoname.h +++ b/freebsd/contrib/tcpdump/addrtoname.h @@ -33,7 +33,8 @@ enum { LINKADDR_ETHER, LINKADDR_FRELAY, LINKADDR_IEEE1394, - LINKADDR_ATM + LINKADDR_ATM, + LINKADDR_OTHER }; #define BUFSIZE 128 diff --git a/freebsd/contrib/tcpdump/addrtostr.c b/freebsd/contrib/tcpdump/addrtostr.c index bf829bb4..c5fea233 100644 --- a/freebsd/contrib/tcpdump/addrtostr.c +++ b/freebsd/contrib/tcpdump/addrtostr.c @@ -116,25 +116,24 @@ addrtostr6 (const void *src, char *dst, size_t size) size_t space_left, added_space; int snprintfed; struct { - long base; - long len; + int base; + int len; } best, cur; - u_long words [IN6ADDRSZ / INT16SZ]; + uint16_t words [IN6ADDRSZ / INT16SZ]; int i; /* Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ - memset (words, 0, sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3)); + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + words[i] = (srcaddr[2*i] << 8) | srcaddr[2*i + 1]; best.len = 0; best.base = -1; cur.len = 0; cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { @@ -167,7 +166,7 @@ addrtostr6 (const void *src, char *dst, size_t size) *dp++ = c; \ space_left--; \ } - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ @@ -198,7 +197,7 @@ addrtostr6 (const void *src, char *dst, size_t size) space_left -= added_space; break; } - snprintfed = snprintf (dp, space_left, "%lx", words[i]); + snprintfed = snprintf (dp, space_left, "%x", words[i]); if (snprintfed < 0) return (NULL); if ((size_t) snprintfed >= space_left) diff --git a/freebsd/contrib/tcpdump/af.c b/freebsd/contrib/tcpdump/af.c index dfa02dd5..e4f5416b 100644 --- a/freebsd/contrib/tcpdump/af.c +++ b/freebsd/contrib/tcpdump/af.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/af.h b/freebsd/contrib/tcpdump/af.h index 1bde577e..6365b126 100644 --- a/freebsd/contrib/tcpdump/af.h +++ b/freebsd/contrib/tcpdump/af.h @@ -12,7 +12,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ extern const struct tok af_values[]; diff --git a/freebsd/contrib/tcpdump/checksum.c b/freebsd/contrib/tcpdump/checksum.c index 87448b5b..84ce8a77 100644 --- a/freebsd/contrib/tcpdump/checksum.c +++ b/freebsd/contrib/tcpdump/checksum.c @@ -20,7 +20,7 @@ * * miscellaneous checksumming routines * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/extract.h b/freebsd/contrib/tcpdump/extract.h index 23623c28..5969c225 100644 --- a/freebsd/contrib/tcpdump/extract.h +++ b/freebsd/contrib/tcpdump/extract.h @@ -20,8 +20,48 @@ */ /* - * Macros to extract possibly-unaligned big-endian integral values. + * For 8-bit values; provided for the sake of completeness. Byte order + * isn't relevant, and alignment isn't an issue. */ +#define EXTRACT_8BITS(p) (*(p)) +#define EXTRACT_LE_8BITS(p) (*(p)) + +/* + * Inline functions or macros to extract possibly-unaligned big-endian + * integral values. + */ +#include "funcattrs.h" + +/* + * If we have versions of GCC or Clang that support an __attribute__ + * to say "if we're building with unsigned behavior sanitization, + * don't complain about undefined behavior in this function", we + * label these functions with that attribute - we *know* it's undefined + * in the C standard, but we *also* know it does what we want with + * the ISA we're targeting and the compiler we're using. + * + * For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined)); + * pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether + * GCC or Clang first had __attribute__((no_sanitize(XXX)). + * + * For Clang, we check for __attribute__((no_sanitize(XXX)) with + * __has_attribute, as there are versions of Clang that support + * __attribute__((no_sanitize("undefined")) but don't support + * __attribute__((no_sanitize_undefined)). + * + * We define this here, rather than in funcattrs.h, because we + * only want it used here, we don't want it to be broadly used. + * (Any printer will get this defined, but this should at least + * make it harder for people to find.) + */ +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409) +#define UNALIGNED_OK __attribute__((no_sanitize_undefined)) +#elif __has_attribute(no_sanitize) +#define UNALIGNED_OK __attribute__((no_sanitize("undefined"))) +#else +#define UNALIGNED_OK +#endif + #ifdef LBL_ALIGN /* * The processor doesn't natively handle unaligned loads. @@ -31,7 +71,7 @@ defined(__mips) || defined(__mips__)) /* - * This is a GCC-compatible compiler and we have __attribute__, which +* This is a GCC-compatible compiler and we have __attribute__, which * we assume that mean we have __attribute__((packed)), and this is * MIPS or Alpha, which has instructions that can help when doing * unaligned loads. @@ -88,19 +128,19 @@ typedef struct { uint32_t val; } __attribute__((packed)) unaligned_uint32_t; -static inline uint16_t +UNALIGNED_OK static inline uint16_t EXTRACT_16BITS(const void *p) { return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); } -static inline uint32_t +UNALIGNED_OK static inline uint32_t EXTRACT_32BITS(const void *p) { return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); } -static inline uint64_t +UNALIGNED_OK static inline uint64_t EXTRACT_64BITS(const void *p) { return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | @@ -138,19 +178,19 @@ EXTRACT_64BITS(const void *p) * The processor natively handles unaligned loads, so we can just * cast the pointer and fetch through it. */ -static inline uint16_t +static inline uint16_t UNALIGNED_OK EXTRACT_16BITS(const void *p) { return ((uint16_t)ntohs(*(const uint16_t *)(p))); } -static inline uint32_t +static inline uint32_t UNALIGNED_OK EXTRACT_32BITS(const void *p) { return ((uint32_t)ntohl(*(const uint32_t *)(p))); } -static inline uint64_t +static inline uint64_t UNALIGNED_OK EXTRACT_64BITS(const void *p) { return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | @@ -193,7 +233,6 @@ EXTRACT_64BITS(const void *p) * Macros to extract possibly-unaligned little-endian integral values. * XXX - do loads on little-endian machines that support unaligned loads? */ -#define EXTRACT_LE_8BITS(p) (*(p)) #define EXTRACT_LE_16BITS(p) \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) @@ -242,3 +281,6 @@ EXTRACT_64BITS(const void *p) #define ND_TTEST_64BITS(p) ND_TTEST2(*(p), 8) #define ND_TCHECK_64BITS(p) ND_TCHECK2(*(p), 8) + +#define ND_TTEST_128BITS(p) ND_TTEST2(*(p), 16) +#define ND_TCHECK_128BITS(p) ND_TCHECK2(*(p), 16) diff --git a/freebsd/contrib/tcpdump/funcattrs.h b/freebsd/contrib/tcpdump/funcattrs.h new file mode 100644 index 00000000..63d3f565 --- /dev/null +++ b/freebsd/contrib/tcpdump/funcattrs.h @@ -0,0 +1,122 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#ifndef lib_funcattrs_h +#define lib_funcattrs_h + +/* + * Attributes to apply to functions and their arguments, using various + * compiler-specific extensions. + */ + +/* + * This was introduced by Clang: + * + * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute + * + * in some version (which version?); it has been picked up by GCC 5.0. + */ +#ifndef __has_attribute + /* + * It's a macro, so you can check whether it's defined to check + * whether it's supported. + * + * If it's not, define it to always return 0, so that we move on to + * the fallback checks. + */ + #define __has_attribute(x) 0 +#endif + +/* + * NORETURN, before a function declaration, means "this function + * never returns". (It must go before the function declaration, e.g. + * "extern NORETURN func(...)" rather than after the function + * declaration, as the MSVC version has to go before the declaration.) + */ +#if __has_attribute(noreturn) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * Compiler with support for __attribute((noreturn)), or GCC 2.5 and + * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1 + * and later (do any earlier versions of XL C support this?), or + * HP aCC A.06.10 and later. + */ + #define NORETURN __attribute((noreturn)) +#elif defined(_MSC_VER) + /* + * MSVC. + */ + #define NORETURN __declspec(noreturn) +#else + #define NORETURN +#endif + +/* + * PRINTFLIKE(x,y), after a function declaration, means "this function + * does printf-style formatting, with the xth argument being the format + * string and the yth argument being the first argument for the format + * string". + */ +#if __has_attribute(__format__) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1 + * and later (do any earlier versions of XL C support this?), + * or HP aCC A.06.10 and later. + */ + #define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PRINTFLIKE(x,y) +#endif + +/* + * For flagging arguments as format strings in MSVC. + */ +#if _MSC_VER >= 1400 + #include <sal.h> + #if _MSC_VER > 1400 + #define FORMAT_STRING(p) _Printf_format_string_ p + #else + #define FORMAT_STRING(p) __format_string p + #endif +#else + #define FORMAT_STRING(p) p +#endif + +#endif /* lib_funcattrs_h */ diff --git a/freebsd/contrib/tcpdump/gmpls.c b/freebsd/contrib/tcpdump/gmpls.c index 4b45ba26..e8cb7ff0 100644 --- a/freebsd/contrib/tcpdump/gmpls.c +++ b/freebsd/contrib/tcpdump/gmpls.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/gmpls.h b/freebsd/contrib/tcpdump/gmpls.h index 8b44f949..32fa8114 100644 --- a/freebsd/contrib/tcpdump/gmpls.h +++ b/freebsd/contrib/tcpdump/gmpls.h @@ -10,7 +10,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #define GMPLS_PSC1 1 diff --git a/freebsd/contrib/tcpdump/ip6.h b/freebsd/contrib/tcpdump/ip6.h index 2ea1d0ab..9a24ef14 100644 --- a/freebsd/contrib/tcpdump/ip6.h +++ b/freebsd/contrib/tcpdump/ip6.h @@ -178,14 +178,13 @@ struct ip6_rthdr { /* Type 0 Routing header */ /* Also used for Type 2 */ struct ip6_rthdr0 { - uint8_t ip6r0_nxt; /* next header */ - uint8_t ip6r0_len; /* length in units of 8 octets */ - uint8_t ip6r0_type; /* always zero */ - uint8_t ip6r0_segleft; /* segments left */ - uint8_t ip6r0_reserved; /* reserved field */ - uint8_t ip6r0_slmap[3]; /* strict/loose bit map */ + nd_uint8_t ip6r0_nxt; /* next header */ + nd_uint8_t ip6r0_len; /* length in units of 8 octets */ + nd_uint8_t ip6r0_type; /* always zero */ + nd_uint8_t ip6r0_segleft; /* segments left */ + nd_uint32_t ip6r0_reserved; /* reserved field */ struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */ -} UNALIGNED; +}; /* Fragment header */ struct ip6_frag { diff --git a/freebsd/contrib/tcpdump/ipproto.c b/freebsd/contrib/tcpdump/ipproto.c index 44fae5d6..38c5de80 100644 --- a/freebsd/contrib/tcpdump/ipproto.c +++ b/freebsd/contrib/tcpdump/ipproto.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H @@ -61,6 +61,312 @@ const struct tok ipproto_values[] = { { 0, NULL } }; +/* + * For completeness the number space in the array below comes from IANA: + * https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + * However, the spelling tries to match that of /etc/protocols to achieve as + * much consistency as possible with the previously implemented behaviour, + * which was based on getprotobynumber (3). + */ +static const char *const netdb_protocol_names[256] = { + "hopopt", /* 0 (IPPROTO_HOPOPTS, IPv6 Hop-by-Hop Option) */ + "icmp", /* 1 (IPPROTO_ICMP, Internet Control Message) */ + "igmp", /* 2 (IPPROTO_IGMP, Internet Group Management) */ + "ggp", /* 3 (Gateway-to-Gateway) */ + "ipencap", /* 4 (IPPROTO_IPV4, IPv4 encapsulation) */ + "st", /* 5 (Stream, ST datagram mode) */ + "tcp", /* 6 (IPPROTO_TCP, Transmission Control) */ + "cbt", /* 7 (CBT) */ + "egp", /* 8 (IPPROTO_EGP, Exterior Gateway Protocol) */ + "igp", /* 9 (IPPROTO_PIGP, "any private interior gateway + * (used by Cisco for their IGRP)") + */ + "bbn-rcc-mon", /* 10 (BBN RCC Monitoring) */ + "nvp-ii", /* 11 (Network Voice Protocol) */ + "pup", /* 12 (PARC universal packet protocol) */ + "argus", /* 13 (ARGUS) */ + "emcon", /* 14 (EMCON) */ + "xnet", /* 15 (Cross Net Debugger) */ + "chaos", /* 16 (Chaos) */ + "udp", /* 17 (IPPROTO_UDP, User Datagram) */ + "mux", /* 18 (Multiplexing) */ + "dcn-meas", /* 19 (DCN Measurement Subsystems) */ + "hmp", /* 20 (Host Monitoring) */ + "prm", /* 21 (Packet Radio Measurement) */ + "xns-idp", /* 22 (XEROX NS IDP) */ + "trunk-1", /* 23 (Trunk-1) */ + "trunk-2", /* 24 (Trunk-2) */ + "leaf-1", /* 25 (Leaf-1) */ + "leaf-2", /* 26 (Leaf-2) */ + "rdp", /* 27 (Reliable Data Protocol) */ + "irtp", /* 28 (Internet Reliable Transaction) */ + "iso-tp4", /* 29 (ISO Transport Protocol Class 4) */ + "netblt", /* 30 (Bulk Data Transfer Protocol) */ + "mfe-nsp", /* 31 (MFE Network Services Protocol) */ + "merit-inp", /* 32 (MERIT Internodal Protocol) */ + "dccp", /* 33 (IPPROTO_DCCP, Datagram Congestion + * Control Protocol) + */ + "3pc", /* 34 (Third Party Connect Protocol) */ + "idpr", /* 35 (Inter-Domain Policy Routing Protocol) */ + "xtp", /* 36 (Xpress Transfer Protocol) */ + "ddp", /* 37 (Datagram Delivery Protocol) */ + "idpr-cmtp", /* 38 (IDPR Control Message Transport Proto) */ + "tp++", /* 39 (TP++ Transport Protocol) */ + "il", /* 40 (IL Transport Protocol) */ + "ipv6", /* 41 (IPPROTO_IPV6, IPv6 encapsulation) */ + "sdrp", /* 42 (Source Demand Routing Protocol) */ + "ipv6-route", /* 43 (IPPROTO_ROUTING, Routing Header for IPv6) */ + "ipv6-frag", /* 44 (IPPROTO_FRAGMENT, Fragment Header for + * IPv6) + */ + "idrp", /* 45 (Inter-Domain Routing Protocol) */ + "rsvp", /* 46 (IPPROTO_RSVP, Reservation Protocol) */ + "gre", /* 47 (IPPROTO_GRE, Generic Routing + * Encapsulation) + */ + "dsr", /* 48 (Dynamic Source Routing Protocol) */ + "bna", /* 49 (BNA) */ + "esp", /* 50 (IPPROTO_ESP, Encap Security Payload) */ + "ah", /* 51 (IPPROTO_AH, Authentication Header) */ + "i-nlsp", /* 52 (Integrated Net Layer Security TUBA) */ + "swipe", /* 53 (IP with Encryption) */ + "narp", /* 54 (NBMA Address Resolution Protocol) */ + "mobile", /* 55 (IPPROTO_MOBILE, IP Mobility) */ + "tlsp", /* 56 (Transport Layer Security Protocol using + * Kryptonet key management) + */ + "skip", /* 57 (SKIP) */ + "ipv6-icmp", /* 58 (IPPROTO_ICMPV6, ICMP for IPv6) */ + "ipv6-nonxt", /* 59 (IPPROTO_NONE, No Next Header for IPv6) */ + "ipv6-opts", /* 60 (IPPROTO_DSTOPTS, Destination Options for + * IPv6) + */ + NULL, /* 61 (any host internal protocol) */ + "cftp", /* 62 (IPPROTO_MOBILITY_OLD, CFTP, see the note + * in ipproto.h) + */ + NULL, /* 63 (any local network) */ + "sat-expak", /* 64 (SATNET and Backroom EXPAK) */ + "kryptolan", /* 65 (Kryptolan) */ + "rvd", /* 66 (MIT Remote Virtual Disk Protocol) */ + "ippc", /* 67 (Internet Pluribus Packet Core) */ + NULL, /* 68 (any distributed file system) */ + "sat-mon", /* 69 (SATNET Monitoring) */ + "visa", /* 70 (VISA Protocol) */ + "ipcv", /* 71 (Internet Packet Core Utility) */ + "cpnx", /* 72 (Computer Protocol Network Executive) */ + "rspf", /* 73 (Radio Shortest Path First, CPHB -- Computer + * Protocol Heart Beat -- in IANA) + */ + "wsn", /* 74 (Wang Span Network) */ + "pvp", /* 75 (Packet Video Protocol) */ + "br-sat-mon", /* 76 (Backroom SATNET Monitoring) */ + "sun-nd", /* 77 (IPPROTO_ND, SUN ND PROTOCOL-Temporary) */ + "wb-mon", /* 78 (WIDEBAND Monitoring) */ + "wb-expak", /* 79 (WIDEBAND EXPAK) */ + "iso-ip", /* 80 (ISO Internet Protocol) */ + "vmtp", /* 81 (Versatile Message Transport) */ + "secure-vmtp", /* 82 (Secure VMTP) */ + "vines", /* 83 (VINES) */ + "ttp", /* 84 (Transaction Transport Protocol, also IPTM -- + * Internet Protocol Traffic Manager) + */ + "nsfnet-igp", /* 85 (NSFNET-IGP) */ + "dgp", /* 86 (Dissimilar Gateway Protocol) */ + "tcf", /* 87 (TCF) */ + "eigrp", /* 88 (IPPROTO_EIGRP, Cisco EIGRP) */ + "ospf", /* 89 (IPPROTO_OSPF, Open Shortest Path First + * IGP) + */ + "sprite-rpc", /* 90 (Sprite RPC Protocol) */ + "larp", /* 91 (Locus Address Resolution Protocol) */ + "mtp", /* 92 (Multicast Transport Protocol) */ + "ax.25", /* 93 (AX.25 Frames) */ + "ipip", /* 94 (IP-within-IP Encapsulation Protocol) */ + "micp", /* 95 (Mobile Internetworking Control Pro.) */ + "scc-sp", /* 96 (Semaphore Communications Sec. Pro.) */ + "etherip", /* 97 (Ethernet-within-IP Encapsulation) */ + "encap", /* 98 (Encapsulation Header) */ + NULL, /* 99 (any private encryption scheme) */ + "gmtp", /* 100 (GMTP) */ + "ifmp", /* 101 (Ipsilon Flow Management Protocol) */ + "pnni", /* 102 (PNNI over IP) */ + "pim", /* 103 (IPPROTO_PIM, Protocol Independent + * Multicast) + */ + "aris", /* 104 (ARIS) */ + "scps", /* 105 (SCPS) */ + "qnx", /* 106 (QNX) */ + "a/n", /* 107 (Active Networks) */ + "ipcomp", /* 108 (IPPROTO_IPCOMP, IP Payload Compression + * Protocol) + */ + "snp", /* 109 (Sitara Networks Protocol) */ + "compaq-peer", /* 110 (Compaq Peer Protocol) */ + "ipx-in-ip", /* 111 (IPX in IP) */ + "vrrp", /* 112 (IPPROTO_VRRP, Virtual Router Redundancy + * Protocol) + */ + "pgm", /* 113 (IPPROTO_PGM, PGM Reliable Transport + * Protocol) + */ + NULL, /* 114 (any 0-hop protocol) */ + "l2tp", /* 115 (Layer Two Tunneling Protocol) */ + "ddx", /* 116 (D-II Data Exchange (DDX)) */ + "iatp", /* 117 (Interactive Agent Transfer Protocol) */ + "stp", /* 118 (Schedule Transfer Protocol) */ + "srp", /* 119 (SpectraLink Radio Protocol) */ + "uti", /* 120 (UTI) */ + "smp", /* 121 (Simple Message Protocol) */ + "sm", /* 122 (Simple Multicast Protocol) */ + "ptp", /* 123 (Performance Transparency Protocol) */ + "isis", /* 124 (ISIS over IPv4) */ + "fire", /* 125 (FIRE) */ + "crtp", /* 126 (Combat Radio Transport Protocol) */ + "crudp", /* 127 (Combat Radio User Datagram) */ + "sscopmce", /* 128 (SSCOPMCE) */ + "iplt", /* 129 (IPLT) */ + "sps", /* 130 (Secure Packet Shield) */ + "pipe", /* 131 (Private IP Encapsulation within IP) */ + "sctp", /* 132 (IPPROTO_SCTP, Stream Control Transmission + * Protocol) + */ + "fc", /* 133 (Fibre Channel) */ + "rsvp-e2e-ignore", /* 134 (RSVP-E2E-IGNORE) */ + "mobility-header", /* 135 (IPPROTO_MOBILITY, Mobility Header) */ + "udplite", /* 136 (UDPLite) */ + "mpls-in-ip", /* 137 (MPLS-in-IP) */ + "manet", /* 138 (MANET Protocols) */ + "hip", /* 139 (Host Identity Protocol) */ + "shim6", /* 140 (Shim6 Protocol) */ + "wesp", /* 141 (Wrapped Encapsulating Security Payload) */ + "rohc", /* 142 (Robust Header Compression) */ + NULL, /* 143 (unassigned) */ + NULL, /* 144 (unassigned) */ + NULL, /* 145 (unassigned) */ + NULL, /* 146 (unassigned) */ + NULL, /* 147 (unassigned) */ + NULL, /* 148 (unassigned) */ + NULL, /* 149 (unassigned) */ + NULL, /* 150 (unassigned) */ + NULL, /* 151 (unassigned) */ + NULL, /* 152 (unassigned) */ + NULL, /* 153 (unassigned) */ + NULL, /* 154 (unassigned) */ + NULL, /* 155 (unassigned) */ + NULL, /* 156 (unassigned) */ + NULL, /* 157 (unassigned) */ + NULL, /* 158 (unassigned) */ + NULL, /* 159 (unassigned) */ + NULL, /* 160 (unassigned) */ + NULL, /* 161 (unassigned) */ + NULL, /* 162 (unassigned) */ + NULL, /* 163 (unassigned) */ + NULL, /* 164 (unassigned) */ + NULL, /* 165 (unassigned) */ + NULL, /* 166 (unassigned) */ + NULL, /* 167 (unassigned) */ + NULL, /* 168 (unassigned) */ + NULL, /* 169 (unassigned) */ + NULL, /* 170 (unassigned) */ + NULL, /* 171 (unassigned) */ + NULL, /* 172 (unassigned) */ + NULL, /* 173 (unassigned) */ + NULL, /* 174 (unassigned) */ + NULL, /* 175 (unassigned) */ + NULL, /* 176 (unassigned) */ + NULL, /* 177 (unassigned) */ + NULL, /* 178 (unassigned) */ + NULL, /* 179 (unassigned) */ + NULL, /* 180 (unassigned) */ + NULL, /* 181 (unassigned) */ + NULL, /* 182 (unassigned) */ + NULL, /* 183 (unassigned) */ + NULL, /* 184 (unassigned) */ + NULL, /* 185 (unassigned) */ + NULL, /* 186 (unassigned) */ + NULL, /* 187 (unassigned) */ + NULL, /* 188 (unassigned) */ + NULL, /* 189 (unassigned) */ + NULL, /* 190 (unassigned) */ + NULL, /* 191 (unassigned) */ + NULL, /* 192 (unassigned) */ + NULL, /* 193 (unassigned) */ + NULL, /* 194 (unassigned) */ + NULL, /* 195 (unassigned) */ + NULL, /* 196 (unassigned) */ + NULL, /* 197 (unassigned) */ + NULL, /* 198 (unassigned) */ + NULL, /* 199 (unassigned) */ + NULL, /* 200 (unassigned) */ + NULL, /* 201 (unassigned) */ + NULL, /* 202 (unassigned) */ + NULL, /* 203 (unassigned) */ + NULL, /* 204 (unassigned) */ + NULL, /* 205 (unassigned) */ + NULL, /* 206 (unassigned) */ + NULL, /* 207 (unassigned) */ + NULL, /* 208 (unassigned) */ + NULL, /* 209 (unassigned) */ + NULL, /* 210 (unassigned) */ + NULL, /* 211 (unassigned) */ + NULL, /* 212 (unassigned) */ + NULL, /* 213 (unassigned) */ + NULL, /* 214 (unassigned) */ + NULL, /* 215 (unassigned) */ + NULL, /* 216 (unassigned) */ + NULL, /* 217 (unassigned) */ + NULL, /* 218 (unassigned) */ + NULL, /* 219 (unassigned) */ + NULL, /* 220 (unassigned) */ + NULL, /* 221 (unassigned) */ + NULL, /* 222 (unassigned) */ + NULL, /* 223 (unassigned) */ + NULL, /* 224 (unassigned) */ + NULL, /* 225 (unassigned) */ + NULL, /* 226 (unassigned) */ + NULL, /* 227 (unassigned) */ + NULL, /* 228 (unassigned) */ + NULL, /* 229 (unassigned) */ + NULL, /* 230 (unassigned) */ + NULL, /* 231 (unassigned) */ + NULL, /* 232 (unassigned) */ + NULL, /* 233 (unassigned) */ + NULL, /* 234 (unassigned) */ + NULL, /* 235 (unassigned) */ + NULL, /* 236 (unassigned) */ + NULL, /* 237 (unassigned) */ + NULL, /* 238 (unassigned) */ + NULL, /* 239 (unassigned) */ + NULL, /* 240 (unassigned) */ + NULL, /* 241 (unassigned) */ + NULL, /* 242 (unassigned) */ + NULL, /* 243 (unassigned) */ + NULL, /* 244 (unassigned) */ + NULL, /* 245 (unassigned) */ + NULL, /* 246 (unassigned) */ + NULL, /* 247 (unassigned) */ + NULL, /* 248 (unassigned) */ + NULL, /* 249 (unassigned) */ + NULL, /* 250 (unassigned) */ + NULL, /* 251 (unassigned) */ + NULL, /* 252 (unassigned) */ + "exptest-253", /* 253 (Use for experimentation and testing, + * RFC 3692) + */ + "exptest-254", /* 254 (Use for experimentation and testing, + * RFC 3692) + */ + "reserved", /* 255 (reserved) */ +}; + +/* The function enforces the array index to be 8-bit. */ +const char * +netdb_protoname (const nd_uint8_t protoid) +{ + return netdb_protocol_names[protoid]; +} #ifdef __rtems__ #include "rtems-bsd-tcpdump-ipproto-data.h" #endif /* __rtems__ */ diff --git a/freebsd/contrib/tcpdump/ipproto.h b/freebsd/contrib/tcpdump/ipproto.h index 4719d4d3..aeefc809 100644 --- a/freebsd/contrib/tcpdump/ipproto.h +++ b/freebsd/contrib/tcpdump/ipproto.h @@ -36,6 +36,7 @@ */ extern const struct tok ipproto_values[]; +extern const char *netdb_protoname (const nd_uint8_t); #ifndef IPPROTO_IP #define IPPROTO_IP 0 /* dummy for IP */ @@ -109,7 +110,7 @@ extern const struct tok ipproto_values[]; * It appears that 62 used to be used, even though that's assigned to * a protocol called CFTP; however, the only reference for CFTP is a * Network Message from BBN back in 1982, so, for now, we support 62, - * aas well as 135, as a protocol number for mobility headers. + * as well as 135, as a protocol number for mobility headers. */ #define IPPROTO_MOBILITY_OLD 62 #endif diff --git a/freebsd/contrib/tcpdump/l2vpn.c b/freebsd/contrib/tcpdump/l2vpn.c index 5a77136b..72831bf8 100644 --- a/freebsd/contrib/tcpdump/l2vpn.c +++ b/freebsd/contrib/tcpdump/l2vpn.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/l2vpn.h b/freebsd/contrib/tcpdump/l2vpn.h index d93abf15..98b6fcc8 100644 --- a/freebsd/contrib/tcpdump/l2vpn.h +++ b/freebsd/contrib/tcpdump/l2vpn.h @@ -10,7 +10,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ extern const struct tok l2vpn_encaps_values[]; diff --git a/freebsd/contrib/tcpdump/netdissect-stdinc.h b/freebsd/contrib/tcpdump/netdissect-stdinc.h index c7070f0a..8282c584 100644 --- a/freebsd/contrib/tcpdump/netdissect-stdinc.h +++ b/freebsd/contrib/tcpdump/netdissect-stdinc.h @@ -394,6 +394,11 @@ struct in6_addr { * end of Apple deprecation workaround macros */ +/* + * Function attributes, for various compilers. + */ +#include "funcattrs.h" + #ifndef min #define min(a,b) ((a)>(b)?(b):(a)) #endif diff --git a/freebsd/contrib/tcpdump/netdissect.h b/freebsd/contrib/tcpdump/netdissect.h index 1d28c0b7..105c490a 100644 --- a/freebsd/contrib/tcpdump/netdissect.h +++ b/freebsd/contrib/tcpdump/netdissect.h @@ -82,19 +82,13 @@ extern int32_t thiszone; /* seconds offset from gmt to local time */ extern const char istr[]; #if !defined(HAVE_SNPRINTF) -int snprintf (char *str, size_t sz, const char *format, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 3, 4))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; +int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...) + PRINTFLIKE(3, 4); #endif /* !defined(HAVE_SNPRINTF) */ #if !defined(HAVE_VSNPRINTF) -int vsnprintf (char *str, size_t sz, const char *format, va_list ap) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 3, 0))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; +int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format), + va_list ap) PRINTFLIKE(3, 0); #endif /* !defined(HAVE_VSNPRINTF) */ #ifndef HAVE_STRLCAT @@ -531,7 +525,7 @@ extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int); extern void ipx_print(netdissect_options *, const u_char *, u_int); extern void isakmp_print(netdissect_options *, const u_char *, u_int, const u_char *); extern void isakmp_rfc3948_print(netdissect_options *, const u_char *, u_int, const u_char *); -extern void isoclns_print(netdissect_options *, const u_char *, u_int, u_int); +extern void isoclns_print(netdissect_options *, const u_char *, u_int); extern void krb_print(netdissect_options *, const u_char *); extern void l2tp_print(netdissect_options *, const u_char *, u_int); extern void lane_print(netdissect_options *, const u_char *, u_int, u_int); diff --git a/freebsd/contrib/tcpdump/nlpid.c b/freebsd/contrib/tcpdump/nlpid.c index 5060aae6..6ba92f4e 100644 --- a/freebsd/contrib/tcpdump/nlpid.c +++ b/freebsd/contrib/tcpdump/nlpid.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/nlpid.h b/freebsd/contrib/tcpdump/nlpid.h index 63a2e709..a3a69054 100644 --- a/freebsd/contrib/tcpdump/nlpid.h +++ b/freebsd/contrib/tcpdump/nlpid.h @@ -10,7 +10,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ extern const struct tok nlpid_values[]; diff --git a/freebsd/contrib/tcpdump/oui.c b/freebsd/contrib/tcpdump/oui.c index 9fb86c6f..922c6e9e 100644 --- a/freebsd/contrib/tcpdump/oui.c +++ b/freebsd/contrib/tcpdump/oui.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/oui.h b/freebsd/contrib/tcpdump/oui.h index a85f883d..a9f732a7 100644 --- a/freebsd/contrib/tcpdump/oui.h +++ b/freebsd/contrib/tcpdump/oui.h @@ -10,7 +10,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ extern const struct tok oui_values[]; diff --git a/freebsd/contrib/tcpdump/print-802_11.c b/freebsd/contrib/tcpdump/print-802_11.c index 3310eb16..990b5777 100644 --- a/freebsd/contrib/tcpdump/print-802_11.c +++ b/freebsd/contrib/tcpdump/print-802_11.c @@ -1045,10 +1045,6 @@ parse_elements(netdissect_options *ndo, if (ssid.length != 0) { if (ssid.length > sizeof(ssid.ssid) - 1) return 0; - if (!ND_TTEST2(*(p + offset), ssid.length)) - return 0; - if (length < ssid.length) - return 0; memcpy(&ssid.ssid, p + offset, ssid.length); offset += ssid.length; length -= ssid.length; @@ -1074,10 +1070,6 @@ parse_elements(netdissect_options *ndo, if (challenge.length > sizeof(challenge.text) - 1) return 0; - if (!ND_TTEST2(*(p + offset), challenge.length)) - return 0; - if (length < challenge.length) - return 0; memcpy(&challenge.text, p + offset, challenge.length); offset += challenge.length; @@ -1103,10 +1095,6 @@ parse_elements(netdissect_options *ndo, if (rates.length != 0) { if (rates.length > sizeof rates.rate) return 0; - if (!ND_TTEST2(*(p + offset), rates.length)) - return 0; - if (length < rates.length) - return 0; memcpy(&rates.rate, p + offset, rates.length); offset += rates.length; length -= rates.length; @@ -1195,8 +1183,7 @@ parse_elements(netdissect_options *ndo, offset += 3; length -= 3; - memcpy(tim.bitmap, p + (tim.length - 3), - (tim.length - 3)); + memcpy(tim.bitmap, p + offset, tim.length - 3); offset += tim.length - 3; length -= tim.length - 3; /* diff --git a/freebsd/contrib/tcpdump/print-802_15_4.c b/freebsd/contrib/tcpdump/print-802_15_4.c index e1c8b7b5..2b4a6bb2 100644 --- a/freebsd/contrib/tcpdump/print-802_15_4.c +++ b/freebsd/contrib/tcpdump/print-802_15_4.c @@ -44,146 +44,188 @@ static const char *ftypes[] = { "Data", /* 1 */ "ACK", /* 2 */ "Command", /* 3 */ - "Reserved", /* 4 */ - "Reserved", /* 5 */ - "Reserved", /* 6 */ - "Reserved", /* 7 */ + "Reserved (0x4)", /* 4 */ + "Reserved (0x5)", /* 5 */ + "Reserved (0x6)", /* 6 */ + "Reserved (0x7)", /* 7 */ }; -static int -extract_header_length(uint16_t fc) -{ - int len = 0; - - switch ((fc >> 10) & 0x3) { - case 0x00: - if (fc & (1 << 6)) /* intra-PAN with none dest addr */ - return -1; - break; - case 0x01: - return -1; - case 0x02: - len += 4; - break; - case 0x03: - len += 10; - break; - } - - switch ((fc >> 14) & 0x3) { - case 0x00: - break; - case 0x01: - return -1; - case 0x02: - len += 4; - break; - case 0x03: - len += 10; - break; - } - - if (fc & (1 << 6)) { - if (len < 2) - return -1; - len -= 2; - } - - return len; -} - +/* + * Frame Control subfields. + */ +#define FC_FRAME_TYPE(fc) ((fc) & 0x7) +#define FC_SECURITY_ENABLED 0x0008 +#define FC_FRAME_PENDING 0x0010 +#define FC_ACK_REQUEST 0x0020 +#define FC_PAN_ID_COMPRESSION 0x0040 +#define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3) +#define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3) +#define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3) + +#define FC_ADDRESSING_MODE_NONE 0x00 +#define FC_ADDRESSING_MODE_RESERVED 0x01 +#define FC_ADDRESSING_MODE_SHORT 0x02 +#define FC_ADDRESSING_MODE_LONG 0x03 u_int ieee802_15_4_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; - int hdrlen; + u_int hdrlen; uint16_t fc; uint8_t seq; + uint16_t panid = 0; if (caplen < 3) { - ND_PRINT((ndo, "[|802.15.4] %x", caplen)); + ND_PRINT((ndo, "[|802.15.4]")); return caplen; } + hdrlen = 3; fc = EXTRACT_LE_16BITS(p); - hdrlen = extract_header_length(fc); - seq = EXTRACT_LE_8BITS(p + 2); p += 3; caplen -= 3; - ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7])); + ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)])); if (ndo->ndo_vflag) ND_PRINT((ndo,"seq %02x ", seq)); - if (hdrlen == -1) { - ND_PRINT((ndo,"invalid! ")); - return caplen; - } - - - if (!ndo->ndo_vflag) { - p+= hdrlen; - caplen -= hdrlen; - } else { - uint16_t panid = 0; - switch ((fc >> 10) & 0x3) { - case 0x00: + /* + * Destination address and PAN ID, if present. + */ + switch (FC_DEST_ADDRESSING_MODE(fc)) { + case FC_ADDRESSING_MODE_NONE: + if (fc & FC_PAN_ID_COMPRESSION) { + /* + * PAN ID compression; this requires that both + * the source and destination addresses be present, + * but the destination address is missing. + */ + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; + } + if (ndo->ndo_vflag) ND_PRINT((ndo,"none ")); - break; - case 0x01: + break; + case FC_ADDRESSING_MODE_RESERVED: + if (ndo->ndo_vflag) ND_PRINT((ndo,"reserved destination addressing mode")); - return 0; - case 0x02: - panid = EXTRACT_LE_16BITS(p); - p += 2; + return hdrlen; + case FC_ADDRESSING_MODE_SHORT: + if (caplen < 2) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; + } + panid = EXTRACT_LE_16BITS(p); + p += 2; + caplen -= 2; + hdrlen += 2; + if (caplen < 2) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; + } + if (ndo->ndo_vflag) ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); - p += 2; - break; - case 0x03: - panid = EXTRACT_LE_16BITS(p); - p += 2; - ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); - p += 8; - break; + p += 2; + caplen -= 2; + hdrlen += 2; + break; + case FC_ADDRESSING_MODE_LONG: + if (caplen < 2) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; + } + panid = EXTRACT_LE_16BITS(p); + p += 2; + caplen -= 2; + hdrlen += 2; + if (caplen < 8) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; } + if (ndo->ndo_vflag) + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); + p += 8; + caplen -= 8; + hdrlen += 8; + break; + } + if (ndo->ndo_vflag) ND_PRINT((ndo,"< ")); - switch ((fc >> 14) & 0x3) { - case 0x00: + /* + * Source address and PAN ID, if present. + */ + switch (FC_SRC_ADDRESSING_MODE(fc)) { + case FC_ADDRESSING_MODE_NONE: + if (ndo->ndo_vflag) ND_PRINT((ndo,"none ")); - break; - case 0x01: + break; + case FC_ADDRESSING_MODE_RESERVED: + if (ndo->ndo_vflag) ND_PRINT((ndo,"reserved source addressing mode")); - return 0; - case 0x02: - if (!(fc & (1 << 6))) { - panid = EXTRACT_LE_16BITS(p); - p += 2; + return 0; + case FC_ADDRESSING_MODE_SHORT: + if (!(fc & FC_PAN_ID_COMPRESSION)) { + /* + * The source PAN ID is not compressed out, so + * fetch it. (Otherwise, we'll use the destination + * PAN ID, fetched above.) + */ + if (caplen < 2) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; } - ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + panid = EXTRACT_LE_16BITS(p); p += 2; - break; - case 0x03: - if (!(fc & (1 << 6))) { - panid = EXTRACT_LE_16BITS(p); - p += 2; + caplen -= 2; + hdrlen += 2; + } + if (caplen < 2) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; + } + if (ndo->ndo_vflag) + ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + p += 2; + caplen -= 2; + hdrlen += 2; + break; + case FC_ADDRESSING_MODE_LONG: + if (!(fc & FC_PAN_ID_COMPRESSION)) { + /* + * The source PAN ID is not compressed out, so + * fetch it. (Otherwise, we'll use the destination + * PAN ID, fetched above.) + */ + if (caplen < 2) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; } - ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); - p += 8; - break; + panid = EXTRACT_LE_16BITS(p); + p += 2; + caplen -= 2; + hdrlen += 2; } - - caplen -= hdrlen; + if (caplen < 8) { + ND_PRINT((ndo, "[|802.15.4]")); + return hdrlen; + } + if (ndo->ndo_vflag) + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p))); + p += 8; + caplen -= 8; + hdrlen += 8; + break; } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); - return 0; + return hdrlen; } #ifdef __rtems__ #include "rtems-bsd-tcpdump-print-802_15_4-data.h" diff --git a/freebsd/contrib/tcpdump/print-aodv.c b/freebsd/contrib/tcpdump/print-aodv.c index b1a977c1..98677d5b 100644 --- a/freebsd/contrib/tcpdump/print-aodv.c +++ b/freebsd/contrib/tcpdump/print-aodv.c @@ -48,7 +48,9 @@ #include "addrtoname.h" #include "extract.h" - +/* + * RFC 3561 + */ struct aodv_rreq { uint8_t rreq_type; /* AODV message type (1) */ uint8_t rreq_flags; /* various flags */ @@ -184,12 +186,17 @@ aodv_extension(netdissect_options *ndo, { const struct aodv_hello *ah; + ND_TCHECK(*ep); switch (ep->type) { case AODV_EXT_HELLO: ah = (const struct aodv_hello *)(const void *)ep; ND_TCHECK(*ah); if (length < sizeof(struct aodv_hello)) goto trunc; + if (ep->length < 4) { + ND_PRINT((ndo, "\n\text HELLO - bad length %u", ep->length)); + break; + } ND_PRINT((ndo, "\n\text HELLO %ld ms", (unsigned long)EXTRACT_32BITS(&ah->interval))); break; diff --git a/freebsd/contrib/tcpdump/print-arp.c b/freebsd/contrib/tcpdump/print-arp.c index 86da2bcc..b19e1036 100644 --- a/freebsd/contrib/tcpdump/print-arp.c +++ b/freebsd/contrib/tcpdump/print-arp.c @@ -84,7 +84,7 @@ struct arp_pkthdr { u_char ar_tha[]; /* target hardware address */ u_char ar_tpa[]; /* target protocol address */ #endif -#define ar_sha(ap) (((const u_char *)((ap)+1))+0) +#define ar_sha(ap) (((const u_char *)((ap)+1))+ 0) #define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln) #define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln) #define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln) @@ -196,6 +196,30 @@ isnonzero(const u_char *a, size_t len) } static void +tpaddr_print_ip(netdissect_options *ndo, + const struct arp_pkthdr *ap, u_short pro) +{ + if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) + ND_PRINT((ndo, "<wrong proto type>")); + else if (PROTO_LEN(ap) != 4) + ND_PRINT((ndo, "<wrong len>")); + else + ND_PRINT((ndo, "%s", ipaddr_string(ndo, TPA(ap)))); +} + +static void +spaddr_print_ip(netdissect_options *ndo, + const struct arp_pkthdr *ap, u_short pro) +{ + if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) + ND_PRINT((ndo, "<wrong proto type>")); + else if (PROTO_LEN(ap) != 4) + ND_PRINT((ndo, "<wrong len>")); + else + ND_PRINT((ndo, "%s", ipaddr_string(ndo, SPA(ap)))); +} + +static void atmarp_addr_print(netdissect_options *ndo, const u_char *ha, u_int ha_len, const u_char *srca, u_int srca_len) @@ -211,6 +235,30 @@ atmarp_addr_print(netdissect_options *ndo, } static void +atmarp_tpaddr_print(netdissect_options *ndo, + const struct atmarp_pkthdr *ap, u_short pro) +{ + if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) + ND_PRINT((ndo, "<wrong proto type>")); + else if (ATMTPROTO_LEN(ap) != 4) + ND_PRINT((ndo, "<wrong tplen>")); + else + ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMTPA(ap)))); +} + +static void +atmarp_spaddr_print(netdissect_options *ndo, + const struct atmarp_pkthdr *ap, u_short pro) +{ + if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) + ND_PRINT((ndo, "<wrong proto type>")); + else if (ATMSPROTO_LEN(ap) != 4) + ND_PRINT((ndo, "<wrong splen>")); + else + ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMSPA(ap)))); +} + +static void atmarp_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { @@ -258,18 +306,21 @@ atmarp_print(netdissect_options *ndo, switch (op) { case ARPOP_REQUEST: - ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, ATMTPA(ap)))); + ND_PRINT((ndo, "who-has ")); + atmarp_tpaddr_print(ndo, ap, pro); if (ATMTHRD_LEN(ap) != 0) { ND_PRINT((ndo, " (")); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); ND_PRINT((ndo, ")")); } - ND_PRINT((ndo, "tell %s", ipaddr_string(ndo, ATMSPA(ap)))); + ND_PRINT((ndo, " tell ")); + atmarp_spaddr_print(ndo, ap, pro); break; case ARPOP_REPLY: - ND_PRINT((ndo, "%s is-at ", ipaddr_string(ndo, ATMSPA(ap)))); + atmarp_spaddr_print(ndo, ap, pro); + ND_PRINT((ndo, " is-at ")); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; @@ -286,11 +337,13 @@ atmarp_print(netdissect_options *ndo, case ARPOP_INVREPLY: atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); - ND_PRINT((ndo, "at %s", ipaddr_string(ndo, ATMSPA(ap)))); + ND_PRINT((ndo, "at ")); + atmarp_spaddr_print(ndo, ap, pro); break; case ARPOP_NAK: - ND_PRINT((ndo, "for %s", ipaddr_string(ndo, ATMSPA(ap)))); + ND_PRINT((ndo, "for ")); + atmarp_spaddr_print(ndo, ap, pro); break; default: @@ -338,7 +391,7 @@ arp_print(netdissect_options *ndo, break; } - if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) { + if (!ND_TTEST2(*TPA(ap), PROTO_LEN(ap))) { ND_PRINT((ndo, "%s", tstr)); ND_DEFAULTPRINT((const u_char *)ap, length); return; @@ -373,16 +426,18 @@ arp_print(netdissect_options *ndo, switch (op) { case ARPOP_REQUEST: - ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, TPA(ap)))); + ND_PRINT((ndo, "who-has ")); + tpaddr_print_ip(ndo, ap, pro); if (isnonzero((const u_char *)THA(ap), HRD_LEN(ap))) ND_PRINT((ndo, " (%s)", linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)))); - ND_PRINT((ndo, " tell %s", ipaddr_string(ndo, SPA(ap)))); + ND_PRINT((ndo, " tell ")); + spaddr_print_ip(ndo, ap, pro); break; case ARPOP_REPLY: - ND_PRINT((ndo, "%s is-at %s", - ipaddr_string(ndo, SPA(ap)), + spaddr_print_ip(ndo, ap, pro); + ND_PRINT((ndo, " is-at %s", linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)))); break; @@ -393,9 +448,9 @@ arp_print(netdissect_options *ndo, break; case ARPOP_REVREPLY: - ND_PRINT((ndo, "%s at %s", - linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)), - ipaddr_string(ndo, TPA(ap)))); + ND_PRINT((ndo, "%s at ", + linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)))); + tpaddr_print_ip(ndo, ap, pro); break; case ARPOP_INVREQUEST: @@ -405,9 +460,9 @@ arp_print(netdissect_options *ndo, break; case ARPOP_INVREPLY: - ND_PRINT((ndo,"%s at %s", - linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)), - ipaddr_string(ndo, SPA(ap)))); + ND_PRINT((ndo,"%s at ", + linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)))); + spaddr_print_ip(ndo, ap, pro); break; default: diff --git a/freebsd/contrib/tcpdump/print-atm.c b/freebsd/contrib/tcpdump/print-atm.c index 1d1578f6..a846c83b 100644 --- a/freebsd/contrib/tcpdump/print-atm.c +++ b/freebsd/contrib/tcpdump/print-atm.c @@ -268,7 +268,7 @@ atm_if_print(netdissect_options *ndo, if (*p == LLC_UI) { if (ndo->ndo_eflag) ND_PRINT((ndo, "CNLPID ")); - isoclns_print(ndo, p + 1, length - 1, caplen - 1); + isoclns_print(ndo, p + 1, length - 1); return hdrlen; } diff --git a/freebsd/contrib/tcpdump/print-beep.c b/freebsd/contrib/tcpdump/print-beep.c index 9a95fbb7..e3a21f51 100644 --- a/freebsd/contrib/tcpdump/print-beep.c +++ b/freebsd/contrib/tcpdump/print-beep.c @@ -34,9 +34,17 @@ */ static int -l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2) +l_strnstart(netdissect_options *ndo, const char *tstr1, u_int tl1, + const char *str2, u_int l2) { - + if (!ND_TTEST2(*str2, tl1)) { + /* + * We don't have tl1 bytes worth of captured data + * for the string, so we can't check for this + * string. + */ + return 0; + } if (tl1 > l2) return 0; @@ -47,19 +55,19 @@ void beep_print(netdissect_options *ndo, const u_char *bp, u_int length) { - if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */ + if (l_strnstart(ndo, "MSG", 4, (const char *)bp, length)) /* A REQuest */ ND_PRINT((ndo, " BEEP MSG")); - else if (l_strnstart("RPY ", 4, (const char *)bp, length)) + else if (l_strnstart(ndo, "RPY ", 4, (const char *)bp, length)) ND_PRINT((ndo, " BEEP RPY")); - else if (l_strnstart("ERR ", 4, (const char *)bp, length)) + else if (l_strnstart(ndo, "ERR ", 4, (const char *)bp, length)) ND_PRINT((ndo, " BEEP ERR")); - else if (l_strnstart("ANS ", 4, (const char *)bp, length)) + else if (l_strnstart(ndo, "ANS ", 4, (const char *)bp, length)) ND_PRINT((ndo, " BEEP ANS")); - else if (l_strnstart("NUL ", 4, (const char *)bp, length)) + else if (l_strnstart(ndo, "NUL ", 4, (const char *)bp, length)) ND_PRINT((ndo, " BEEP NUL")); - else if (l_strnstart("SEQ ", 4, (const char *)bp, length)) + else if (l_strnstart(ndo, "SEQ ", 4, (const char *)bp, length)) ND_PRINT((ndo, " BEEP SEQ")); - else if (l_strnstart("END", 4, (const char *)bp, length)) + else if (l_strnstart(ndo, "END", 4, (const char *)bp, length)) ND_PRINT((ndo, " BEEP END")); else ND_PRINT((ndo, " BEEP (payload or undecoded)")); diff --git a/freebsd/contrib/tcpdump/print-bfd.c b/freebsd/contrib/tcpdump/print-bfd.c index 5eb8d174..bec521c1 100644 --- a/freebsd/contrib/tcpdump/print-bfd.c +++ b/freebsd/contrib/tcpdump/print-bfd.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: Bidirectional Forwarding Detection (BFD) printer */ diff --git a/freebsd/contrib/tcpdump/print-bgp.c b/freebsd/contrib/tcpdump/print-bgp.c index ae80d6b7..3d1e2f4d 100644 --- a/freebsd/contrib/tcpdump/print-bgp.c +++ b/freebsd/contrib/tcpdump/print-bgp.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Extensively modified by Hannes Gredler (hannes@juniper.net) for more + * Extensively modified by Hannes Gredler (hannes@gredler.at) for more * complete BGP support. */ @@ -762,11 +762,18 @@ decode_rt_routing_info(netdissect_options *ndo, { uint8_t route_target[8]; u_int plen; + char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */ + /* NLRI "prefix length" from RFC 2858 Section 4. */ ND_TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ + /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits. + * RFC 4684 Section 4 defines the layout of "origin AS" and "route + * target" fields inside the "prefix" depending on its length. + */ if (0 == plen) { + /* Without "origin AS", without "route target". */ snprintf(buf, buflen, "default route target"); return 1; } @@ -774,20 +781,29 @@ decode_rt_routing_info(netdissect_options *ndo, if (32 > plen) return -1; + /* With at least "origin AS", possibly with "route target". */ + ND_TCHECK_32BITS(pptr + 1); + as_printf(ndo, asbuf, sizeof(asbuf), EXTRACT_32BITS(pptr + 1)); + plen-=32; /* adjust prefix length */ if (64 < plen) return -1; + /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 } + * and gives the number of octets in the variable-length "route + * target" field inside this NLRI "prefix". Look for it. + */ memset(&route_target, 0, sizeof(route_target)); - ND_TCHECK2(pptr[1], (plen + 7) / 8); - memcpy(&route_target, &pptr[1], (plen + 7) / 8); + ND_TCHECK2(pptr[5], (plen + 7) / 8); + memcpy(&route_target, &pptr[5], (plen + 7) / 8); + /* Which specification says to do this? */ if (plen % 8) { ((u_char *)&route_target)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "origin AS: %s, route target %s", - as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)), + asbuf, bgp_vpn_rd_print(ndo, (u_char *)&route_target)); return 5 + (plen + 7) / 8; @@ -901,6 +917,7 @@ static const struct tok bgp_multicast_vpn_route_type_values[] = { { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"}, + { 0, NULL} }; static int @@ -965,13 +982,13 @@ decode_multicast_vpn(netdissect_options *ndo, case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: - ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); + ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", bgp_vpn_rd_print(ndo, pptr), as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); - pptr += BGP_VPN_RD_LEN; + pptr += BGP_VPN_RD_LEN + 4; bgp_vpn_sg_print(ndo, pptr, buf, buflen); break; @@ -1406,6 +1423,7 @@ bgp_attr_print(netdissect_options *ndo, ND_TCHECK(tptr[0]); ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values, "?", tptr[0]))); + ND_TCHECK(tptr[1]); for (i = 0; i < tptr[1] * as_size; i += as_size) { ND_TCHECK2(tptr[2 + i], as_size); ND_PRINT((ndo, "%s ", @@ -1725,7 +1743,7 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT((ndo, ", no SNPA")); } - while (len - (tptr - pptr) > 0) { + while (tptr < pptr + len) { switch (af<<8 | safi) { case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): @@ -1893,7 +1911,7 @@ bgp_attr_print(netdissect_options *ndo, tptr += 3; - while (len - (tptr - pptr) > 0) { + while (tptr < pptr + len) { switch (af<<8 | safi) { case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): @@ -2122,11 +2140,11 @@ bgp_attr_print(netdissect_options *ndo, { uint8_t tunnel_type, flags; + ND_TCHECK2(tptr[0], 5); tunnel_type = *(tptr+1); flags = *tptr; tlen = len; - ND_TCHECK2(tptr[0], 5); ND_PRINT((ndo, "\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), tunnel_type, @@ -2181,35 +2199,42 @@ bgp_attr_print(netdissect_options *ndo, uint8_t type; uint16_t length; - ND_TCHECK2(tptr[0], 3); - tlen = len; while (tlen >= 3) { + ND_TCHECK2(tptr[0], 3); + type = *tptr; length = EXTRACT_16BITS(tptr+1); + tptr += 3; + tlen -= 3; ND_PRINT((ndo, "\n\t %s TLV (%u), length %u", tok2str(bgp_aigp_values, "Unknown", type), type, length)); + if (length < 3) + goto trunc; + length -= 3; + /* * Check if we can read the TLV data. */ - ND_TCHECK2(tptr[3], length - 3); + ND_TCHECK2(tptr[3], length); switch (type) { case BGP_AIGP_TLV: - ND_TCHECK2(tptr[3], 8); + if (length < 8) + goto trunc; ND_PRINT((ndo, ", metric %" PRIu64, - EXTRACT_64BITS(tptr+3))); + EXTRACT_64BITS(tptr))); break; default: if (ndo->ndo_vflag <= 1) { - print_unknown_data(ndo, tptr+3,"\n\t ", length-3); + print_unknown_data(ndo, tptr,"\n\t ", length); } } diff --git a/freebsd/contrib/tcpdump/print-bootp.c b/freebsd/contrib/tcpdump/print-bootp.c index 3f061769..c9f687ff 100644 --- a/freebsd/contrib/tcpdump/print-bootp.c +++ b/freebsd/contrib/tcpdump/print-bootp.c @@ -328,6 +328,7 @@ bootp_print(netdissect_options *ndo, if (EXTRACT_16BITS(&bp->bp_secs)) ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs))); + ND_TCHECK(bp->bp_flags); ND_PRINT((ndo, ", Flags [%s]", bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags)))); if (ndo->ndo_vflag > 1) diff --git a/freebsd/contrib/tcpdump/print-cfm.c b/freebsd/contrib/tcpdump/print-cfm.c index ddb91e06..897dc032 100644 --- a/freebsd/contrib/tcpdump/print-cfm.c +++ b/freebsd/contrib/tcpdump/print-cfm.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */ @@ -223,7 +223,7 @@ static const struct tok cfm_tlv_senderid_chassisid_values[] = { static int cfm_network_addr_print(netdissect_options *ndo, - register const u_char *tptr) + register const u_char *tptr, const u_int length) { u_int network_addr_type; u_int hexdump = FALSE; @@ -233,6 +233,11 @@ cfm_network_addr_print(netdissect_options *ndo, * 802.1ab specifies that this field width * is only once octet */ + if (length < 1) { + ND_PRINT((ndo, "\n\t Network Address Type (invalid, no data")); + return hexdump; + } + /* The calling function must make any due ND_TCHECK calls. */ network_addr_type = *tptr; ND_PRINT((ndo, "\n\t Network Address Type %s (%u)", tok2str(af_values, "Unknown", network_addr_type), @@ -243,10 +248,20 @@ cfm_network_addr_print(netdissect_options *ndo, */ switch(network_addr_type) { case AFNUM_INET: + if (length != 1 + 4) { + ND_PRINT((ndo, "(invalid IPv4 address length %u)", length - 1)); + hexdump = TRUE; + break; + } ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1))); break; case AFNUM_INET6: + if (length != 1 + 16) { + ND_PRINT((ndo, "(invalid IPv6 address length %u)", length - 1)); + hexdump = TRUE; + break; + } ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1))); break; @@ -374,8 +389,11 @@ cfm_print(netdissect_options *ndo, md_nameformat, md_namelength)); - /* -2 for the MA short name format and length */ - if (md_namelength > names_data_remaining - 2) { + /* + * -3 for the MA short name format and length and one byte + * of MA short name. + */ + if (md_namelength > names_data_remaining - 3) { ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2)); return; } @@ -587,11 +605,12 @@ cfm_print(netdissect_options *ndo, if (cfm_tlv_len < 1) { ND_PRINT((ndo, " (too short, must be >= 1)")); - return; + goto next_tlv; } /* * Get the Chassis ID length and check it. + * IEEE 802.1Q-2014 Section 21.5.3.1 */ chassis_id_length = *tptr; tptr++; @@ -599,9 +618,14 @@ cfm_print(netdissect_options *ndo, cfm_tlv_len--; if (chassis_id_length) { + /* + * IEEE 802.1Q-2014 Section 21.5.3.2: Chassis ID Subtype, references + * IEEE 802.1AB-2005 Section 9.5.2.2, subsequently + * IEEE 802.1AB-2016 Section 8.5.2.2: chassis ID subtype + */ if (cfm_tlv_len < 1) { ND_PRINT((ndo, "\n\t (TLV too short)")); - return; + goto next_tlv; } chassis_id_type = *tptr; cfm_tlv_len--; @@ -614,16 +638,22 @@ cfm_print(netdissect_options *ndo, if (cfm_tlv_len < chassis_id_length) { ND_PRINT((ndo, "\n\t (TLV too short)")); - return; + goto next_tlv; } + /* IEEE 802.1Q-2014 Section 21.5.3.3: Chassis ID */ switch (chassis_id_type) { case CFM_CHASSIS_ID_MAC_ADDRESS: + if (chassis_id_length != ETHER_ADDR_LEN) { + ND_PRINT((ndo, " (invalid MAC address length)")); + hexdump = TRUE; + break; + } ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, tptr + 1))); break; case CFM_CHASSIS_ID_NETWORK_ADDRESS: - hexdump |= cfm_network_addr_print(ndo, tptr); + hexdump |= cfm_network_addr_print(ndo, tptr + 1, chassis_id_length); break; case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */ @@ -646,38 +676,53 @@ cfm_print(netdissect_options *ndo, /* * Check if there is a Management Address. + * IEEE 802.1Q-2014 Section 21.5.3.4: Management Address Domain Length + * This and all subsequent fields are not present if the TLV length + * allows only the above fields. */ if (cfm_tlv_len == 0) { /* No, there isn't; we're done. */ - return; + break; } + /* Here mgmt_addr_length stands for the management domain length. */ mgmt_addr_length = *tptr; tptr++; tlen--; cfm_tlv_len--; + ND_PRINT((ndo, "\n\t Management Address Domain Length %u", mgmt_addr_length)); if (mgmt_addr_length) { + /* IEEE 802.1Q-2014 Section 21.5.3.5: Management Address Domain */ if (cfm_tlv_len < mgmt_addr_length) { ND_PRINT((ndo, "\n\t (TLV too short)")); - return; + goto next_tlv; } cfm_tlv_len -= mgmt_addr_length; /* * XXX - this is an OID; print it as such. */ + hex_print(ndo, "\n\t Management Address Domain: ", tptr, mgmt_addr_length); tptr += mgmt_addr_length; tlen -= mgmt_addr_length; + /* + * IEEE 802.1Q-2014 Section 21.5.3.6: Management Address Length + * This field is present if Management Address Domain Length is not 0. + */ if (cfm_tlv_len < 1) { - ND_PRINT((ndo, "\n\t (TLV too short)")); - return; + ND_PRINT((ndo, " (Management Address Length is missing)")); + hexdump = TRUE; + break; } - + + /* Here mgmt_addr_length stands for the management address length. */ mgmt_addr_length = *tptr; tptr++; tlen--; cfm_tlv_len--; + ND_PRINT((ndo, "\n\t Management Address Length %u", mgmt_addr_length)); if (mgmt_addr_length) { + /* IEEE 802.1Q-2014 Section 21.5.3.7: Management Address */ if (cfm_tlv_len < mgmt_addr_length) { ND_PRINT((ndo, "\n\t (TLV too short)")); return; @@ -686,6 +731,7 @@ cfm_print(netdissect_options *ndo, /* * XXX - this is a TransportDomain; print it as such. */ + hex_print(ndo, "\n\t Management Address: ", tptr, mgmt_addr_length); tptr += mgmt_addr_length; tlen -= mgmt_addr_length; } @@ -709,6 +755,7 @@ cfm_print(netdissect_options *ndo, if (hexdump || ndo->ndo_vflag > 1) print_unknown_data(ndo, tlv_ptr, "\n\t ", cfm_tlv_len); +next_tlv: tptr+=cfm_tlv_len; tlen-=cfm_tlv_len; } diff --git a/freebsd/contrib/tcpdump/print-chdlc.c b/freebsd/contrib/tcpdump/print-chdlc.c index 5ccb849f..03ae73f6 100644 --- a/freebsd/contrib/tcpdump/print-chdlc.c +++ b/freebsd/contrib/tcpdump/print-chdlc.c @@ -52,21 +52,18 @@ static const struct tok chdlc_cast_values[] = { u_int chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; - - if (caplen < CHDLC_HDRLEN) { - ND_PRINT((ndo, "[|chdlc]")); - return (caplen); - } - return (chdlc_print(ndo, p,length)); + return chdlc_print(ndo, p, h->len); } u_int chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) { u_int proto; + const u_char *bp = p; + if (length < CHDLC_HDRLEN) + goto trunc; + ND_TCHECK2(*p, CHDLC_HDRLEN); proto = EXTRACT_16BITS(&p[2]); if (ndo->ndo_eflag) { ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ", @@ -100,12 +97,15 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) break; case ETHERTYPE_ISO: /* is the fudge byte set ? lets verify by spotting ISO headers */ + if (length < 2) + goto trunc; + ND_TCHECK_16BITS(p); if (*(p+1) == 0x81 || *(p+1) == 0x82 || *(p+1) == 0x83) - isoclns_print(ndo, p + 1, length - 1, ndo->ndo_snapend - p - 1); + isoclns_print(ndo, p + 1, length - 1); else - isoclns_print(ndo, p, length, ndo->ndo_snapend - p); + isoclns_print(ndo, p, length); break; default: if (!ndo->ndo_eflag) @@ -114,6 +114,10 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) } return (CHDLC_HDRLEN); + +trunc: + ND_PRINT((ndo, "[|chdlc]")); + return ndo->ndo_snapend - bp; } /* diff --git a/freebsd/contrib/tcpdump/print-cnfp.c b/freebsd/contrib/tcpdump/print-cnfp.c index b590afae..9e946f6e 100644 --- a/freebsd/contrib/tcpdump/print-cnfp.c +++ b/freebsd/contrib/tcpdump/print-cnfp.c @@ -165,7 +165,7 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp) { register const struct nfhdr_v1 *nh; register const struct nfrec_v1 *nr; - struct protoent *pent; + const char *p_name; int nrecs, ver; #if 0 time_t t; @@ -217,14 +217,13 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp) ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr))); - pent = getprotobynumber(nr->proto); - if (!pent || ndo->ndo_nflag) - ND_PRINT((ndo, "%u ", nr->proto)); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL) + ND_PRINT((ndo, "%s ", p_name)); else - ND_PRINT((ndo, "%s ", pent->p_name)); + ND_PRINT((ndo, "%u ", nr->proto)); /* tcp flags for tcp only */ - if (pent && pent->p_proto == IPPROTO_TCP) { + if (nr->proto == IPPROTO_TCP) { int flags; flags = nr->tcp_flags; ND_PRINT((ndo, "%s%s%s%s%s%s%s", @@ -255,7 +254,7 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp) { register const struct nfhdr_v5 *nh; register const struct nfrec_v5 *nr; - struct protoent *pent; + const char *p_name; int nrecs, ver; #if 0 time_t t; @@ -314,14 +313,13 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp) ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr))); - pent = getprotobynumber(nr->proto); - if (!pent || ndo->ndo_nflag) - ND_PRINT((ndo, "%u ", nr->proto)); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL) + ND_PRINT((ndo, "%s ", p_name)); else - ND_PRINT((ndo, "%s ", pent->p_name)); + ND_PRINT((ndo, "%u ", nr->proto)); /* tcp flags for tcp only */ - if (pent && pent->p_proto == IPPROTO_TCP) { + if (nr->proto == IPPROTO_TCP) { int flags; flags = nr->tcp_flags; ND_PRINT((ndo, "%s%s%s%s%s%s%s", @@ -352,7 +350,7 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp) { register const struct nfhdr_v6 *nh; register const struct nfrec_v6 *nr; - struct protoent *pent; + const char *p_name; int nrecs, ver; #if 0 time_t t; @@ -411,14 +409,13 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp) ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr))); - pent = getprotobynumber(nr->proto); - if (!pent || ndo->ndo_nflag) - ND_PRINT((ndo, "%u ", nr->proto)); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL) + ND_PRINT((ndo, "%s ", p_name)); else - ND_PRINT((ndo, "%s ", pent->p_name)); + ND_PRINT((ndo, "%u ", nr->proto)); /* tcp flags for tcp only */ - if (pent && pent->p_proto == IPPROTO_TCP) { + if (nr->proto == IPPROTO_TCP) { int flags; flags = nr->tcp_flags; ND_PRINT((ndo, "%s%s%s%s%s%s%s", diff --git a/freebsd/contrib/tcpdump/print-decnet.c b/freebsd/contrib/tcpdump/print-decnet.c index 4d052626..af50492b 100644 --- a/freebsd/contrib/tcpdump/print-decnet.c +++ b/freebsd/contrib/tcpdump/print-decnet.c @@ -548,6 +548,7 @@ decnet_print(netdissect_options *ndo, length -= padlen; caplen -= padlen; rhp = (const union routehdr *)&(ap[sizeof(short)]); + ND_TCHECK(rhp->rh_short.sh_flags); mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); } @@ -619,6 +620,7 @@ print_decnet_ctlmsg(netdissect_options *ndo, register const union routehdr *rhp, u_int length, u_int caplen) { + /* Our caller has already checked for mflags */ int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); register const union controlmsg *cmp = (const union controlmsg *)rhp; int src, dst, info, blksize, eco, ueco, hello, other, vers; diff --git a/freebsd/contrib/tcpdump/print-dhcp6.c b/freebsd/contrib/tcpdump/print-dhcp6.c index 8c7a0974..9815a167 100644 --- a/freebsd/contrib/tcpdump/print-dhcp6.c +++ b/freebsd/contrib/tcpdump/print-dhcp6.c @@ -524,6 +524,10 @@ dhcp6opt_print(netdissect_options *ndo, ND_PRINT((ndo, "...)")); break; case DH6OPT_RECONF_MSG: + if (optlen != 1) { + ND_PRINT((ndo, " ?)")); + break; + } tp = (const u_char *)(dh6o + 1); switch (*tp) { case DH6_RENEW: diff --git a/freebsd/contrib/tcpdump/print-domain.c b/freebsd/contrib/tcpdump/print-domain.c index 904468c4..52348a17 100644 --- a/freebsd/contrib/tcpdump/print-domain.c +++ b/freebsd/contrib/tcpdump/print-domain.c @@ -157,15 +157,14 @@ ns_nprint(netdissect_options *ndo, register u_int i, l; register const u_char *rp = NULL; register int compress = 0; - int chars_processed; int elt; - int data_size = ndo->ndo_snapend - bp; + u_int offset, max_offset; if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); if (!ND_TTEST2(*cp, 1)) return(NULL); - chars_processed = 1; + max_offset = (u_int)(cp - bp); if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { compress = 0; rp = cp + l; @@ -180,24 +179,28 @@ ns_nprint(netdissect_options *ndo, } if (!ND_TTEST2(*cp, 1)) return(NULL); - cp = bp + (((i << 8) | *cp) & 0x3fff); + offset = (((i << 8) | *cp) & 0x3fff); + /* + * This must move backwards in the packet. + * No RFC explicitly says that, but BIND's + * name decompression code requires it, + * as a way of preventing infinite loops + * and other bad behavior, and it's probably + * what was intended (compress by pointing + * to domain name suffixes already seen in + * the packet). + */ + if (offset >= max_offset) { + ND_PRINT((ndo, "<BAD PTR>")); + return(NULL); + } + max_offset = offset; + cp = bp + offset; if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); if (!ND_TTEST2(*cp, 1)) return(NULL); i = *cp++; - chars_processed++; - - /* - * If we've looked at every character in - * the message, this pointer will make - * us look at some character again, - * which means we're looping. - */ - if (chars_processed >= data_size) { - ND_PRINT((ndo, "<LOOP>")); - return (NULL); - } continue; } if ((i & INDIR_MASK) == EDNS0_MASK) { @@ -218,14 +221,12 @@ ns_nprint(netdissect_options *ndo, } cp += l; - chars_processed += l; ND_PRINT((ndo, ".")); if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); if (!ND_TTEST2(*cp, 1)) return(NULL); i = *cp++; - chars_processed++; if (!compress) rp += l + 1; } diff --git a/freebsd/contrib/tcpdump/print-eap.c b/freebsd/contrib/tcpdump/print-eap.c index 78fbef43..1de61b79 100644 --- a/freebsd/contrib/tcpdump/print-eap.c +++ b/freebsd/contrib/tcpdump/print-eap.c @@ -188,7 +188,9 @@ eap_print(netdissect_options *ndo, switch (eap->type) { case EAP_FRAME_TYPE_PACKET: + ND_TCHECK_8BITS(tptr); type = *(tptr); + ND_TCHECK_16BITS(tptr+2); len = EXTRACT_16BITS(tptr+2); ND_PRINT((ndo, ", %s (%u), id %u, len %u", tok2str(eap_code_values, "unknown", type), @@ -199,10 +201,11 @@ eap_print(netdissect_options *ndo, ND_TCHECK2(*tptr, len); if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ + ND_TCHECK_8BITS(tptr+4); subtype = *(tptr+4); ND_PRINT((ndo, "\n\t\t Type %s (%u)", - tok2str(eap_type_values, "unknown", *(tptr+4)), - *(tptr + 4))); + tok2str(eap_type_values, "unknown", subtype), + subtype)); switch (subtype) { case EAP_TYPE_IDENTITY: @@ -228,6 +231,7 @@ eap_print(netdissect_options *ndo, * type one octet per type */ while (count < len) { + ND_TCHECK_8BITS(tptr+count); ND_PRINT((ndo, " %s (%u),", tok2str(eap_type_values, "unknown", *(tptr+count)), *(tptr + count))); @@ -236,19 +240,23 @@ eap_print(netdissect_options *ndo, break; case EAP_TYPE_TTLS: - ND_PRINT((ndo, " TTLSv%u", - EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */ case EAP_TYPE_TLS: + ND_TCHECK_8BITS(tptr + 5); + if (subtype == EAP_TYPE_TTLS) + ND_PRINT((ndo, " TTLSv%u", + EAP_TTLS_VERSION(*(tptr + 5)))); ND_PRINT((ndo, " flags [%s] 0x%02x,", bittok2str(eap_tls_flags_values, "none", *(tptr+5)), *(tptr + 5))); if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + ND_TCHECK_32BITS(tptr + 6); ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); } break; case EAP_TYPE_FAST: + ND_TCHECK_8BITS(tptr + 5); ND_PRINT((ndo, " FASTv%u", EAP_TTLS_VERSION(*(tptr + 5)))); ND_PRINT((ndo, " flags [%s] 0x%02x,", @@ -256,6 +264,7 @@ eap_print(netdissect_options *ndo, *(tptr + 5))); if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + ND_TCHECK_32BITS(tptr + 6); ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); } @@ -264,6 +273,7 @@ eap_print(netdissect_options *ndo, case EAP_TYPE_AKA: case EAP_TYPE_SIM: + ND_TCHECK_8BITS(tptr + 5); ND_PRINT((ndo, " subtype [%s] 0x%02x,", tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), *(tptr + 5))); diff --git a/freebsd/contrib/tcpdump/print-eigrp.c b/freebsd/contrib/tcpdump/print-eigrp.c index 14a14b8f..2b1ea588 100644 --- a/freebsd/contrib/tcpdump/print-eigrp.c +++ b/freebsd/contrib/tcpdump/print-eigrp.c @@ -5,7 +5,7 @@ #include "rtems-bsd-tcpdump-namespace.h" #endif /* __rtems__ */ /* - * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org> + * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at> * The TCPDUMP project * * Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ /* * packet format documented at * http://www.rhyshaden.com/eigrp.htm + * RFC 7868 */ struct eigrp_common_header { @@ -252,6 +253,12 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int /* ok they seem to want to know everything - lets fully decode it */ + if (len < sizeof(struct eigrp_common_header)) { + ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)", + tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), + len, (u_int) sizeof(struct eigrp_common_header))); + return; + } tlen=len-sizeof(struct eigrp_common_header); /* FIXME print other header info */ @@ -292,6 +299,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int eigrp_tlv_type, eigrp_tlv_len)); + if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) sizeof(struct eigrp_tlv_header))); + break; + } tlv_tptr=tptr+sizeof(struct eigrp_tlv_header); tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header); @@ -302,6 +314,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_GENERAL_PARM: tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm)))); + break; + } ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime), @@ -314,6 +331,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_SW_VERSION: tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version)))); + break; + } ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u", tlv_ptr.eigrp_tlv_sw_version->ios_major, @@ -324,6 +346,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_IP_INT: tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int)))); + break; + } bit_length = tlv_ptr.eigrp_tlv_ip_int->plen; if (bit_length > 32) { @@ -353,6 +380,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_IP_EXT: tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext)))); + break; + } bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen; if (bit_length > 32) { @@ -390,6 +422,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_AT_CABLE_SETUP: tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)))); + break; + } ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), @@ -399,6 +436,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_AT_INT: tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int)))); + break; + } ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start), @@ -422,6 +464,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int case EIGRP_TLV_AT_EXT: tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr; + if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) { + ND_PRINT((ndo, " (too short, < %u)", + (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext)))); + break; + } ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start), diff --git a/freebsd/contrib/tcpdump/print-esp.c b/freebsd/contrib/tcpdump/print-esp.c index bab7cb52..c92d6fbe 100644 --- a/freebsd/contrib/tcpdump/print-esp.c +++ b/freebsd/contrib/tcpdump/print-esp.c @@ -151,6 +151,39 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) } #endif +#ifdef HAVE_EVP_CIPHERINIT_EX +/* + * Initialize the cipher by calling EVP_CipherInit_ex(), because + * calling EVP_CipherInit() will reset the cipher context, clearing + * the cipher, so calling it twice, with the second call having a + * null cipher, will clear the already-set cipher. EVP_CipherInit_ex(), + * however, won't reset the cipher context, so you can use it to specify + * the IV oin a second call after a first call to EVP_CipherInit_ex() + * to set the cipher and the key. + * + * XXX - is there some reason why we need to make two calls? + */ +static int +set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} +#else +/* + * Initialize the cipher by calling EVP_CipherInit(), because we don't + * have EVP_CipherInit_ex(); we rely on it not trashing the context. + */ +static int +set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return EVP_CipherInit(ctx, cipher, key, iv, enc); +} +#endif + /* * this will adjust ndo_packetp and ndo_snapend to new buffer! */ @@ -162,8 +195,10 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, { struct sa_list *sa; const u_char *iv; - int len; + unsigned int len; EVP_CIPHER_CTX *ctx; + unsigned int block_size, output_buffer_size; + u_char *output_buffer; /* initiator arg is any non-zero value */ if(initiator) initiator=1; @@ -194,17 +229,36 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return 0; - if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0) + if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0) (*ndo->ndo_warning)(ndo, "espkey init failed"); - EVP_CipherInit(ctx, NULL, NULL, iv, 0); - EVP_Cipher(ctx, __DECONST(u_char *, buf), buf, len); + set_cipher_parameters(ctx, NULL, NULL, iv, 0); + /* + * Allocate a buffer for the decrypted data. + * The output buffer must be separate from the input buffer, and + * its size must be a multiple of the cipher block size. + */ + block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx); + output_buffer_size = len + (block_size - len % block_size); + output_buffer = (u_char *)malloc(output_buffer_size); + if (output_buffer == NULL) { + (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer"); + EVP_CIPHER_CTX_free(ctx); + return 0; + } + EVP_Cipher(ctx, output_buffer, buf, len); EVP_CIPHER_CTX_free(ctx); + /* + * XXX - of course this is wrong, because buf is a const buffer, + * but changing this would require a more complicated fix. + */ + memcpy(__DECONST(u_char *, buf), output_buffer, len); + free(output_buffer); + ndo->ndo_packetp = buf; ndo->ndo_snapend = end; return 1; - } USES_APPLE_RST @@ -612,6 +666,8 @@ esp_print(netdissect_options *ndo, const u_char *ivoff; const u_char *p; EVP_CIPHER_CTX *ctx; + unsigned int block_size, output_buffer_size; + u_char *output_buffer; #endif esp = (const struct newesp *)bp; @@ -709,7 +765,9 @@ esp_print(netdissect_options *ndo, ep = bp2 + len; } + /* pointer to the IV, if there is one */ ivoff = (const u_char *)(esp + 1) + 0; + /* length of the IV, if there is one; 0, if there isn't */ ivlen = sa->ivlen; secret = sa->secret; ep = ep - sa->authlen; @@ -717,14 +775,37 @@ esp_print(netdissect_options *ndo, if (sa->evp) { ctx = EVP_CIPHER_CTX_new(); if (ctx != NULL) { - if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0) + if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0) (*ndo->ndo_warning)(ndo, "espkey init failed"); p = ivoff; - EVP_CipherInit(ctx, NULL, NULL, p, 0); - EVP_Cipher(ctx, __DECONST(u_char *, p + ivlen), - p + ivlen, ep - (p + ivlen)); + set_cipher_parameters(ctx, NULL, NULL, p, 0); + len = ep - (p + ivlen); + + /* + * Allocate a buffer for the decrypted data. + * The output buffer must be separate from the + * input buffer, and its size must be a multiple + * of the cipher block size. + */ + block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx); + output_buffer_size = len + (block_size - len % block_size); + output_buffer = (u_char *)malloc(output_buffer_size); + if (output_buffer == NULL) { + (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer"); + EVP_CIPHER_CTX_free(ctx); + return -1; + } + + EVP_Cipher(ctx, output_buffer, p + ivlen, len); EVP_CIPHER_CTX_free(ctx); + /* + * XXX - of course this is wrong, because buf is a + * const buffer, but changing this would require a + * more complicated fix. + */ + memcpy(__DECONST(u_char *, p + ivlen), output_buffer, len); + free(output_buffer); advance = ivoff - (const u_char *)esp + ivlen; } else advance = sizeof(struct newesp); diff --git a/freebsd/contrib/tcpdump/print-ether.c b/freebsd/contrib/tcpdump/print-ether.c index 2a72830c..cf996cd3 100644 --- a/freebsd/contrib/tcpdump/print-ether.c +++ b/freebsd/contrib/tcpdump/print-ether.c @@ -372,7 +372,7 @@ ethertype_print(netdissect_options *ndo, ND_PRINT((ndo, " [|osi]")); return (1); } - isoclns_print(ndo, p + 1, length - 1, caplen - 1); + isoclns_print(ndo, p + 1, length - 1); return(1); case ETHERTYPE_PPPOED: diff --git a/freebsd/contrib/tcpdump/print-fr.c b/freebsd/contrib/tcpdump/print-fr.c index 11457ab0..25e0219a 100644 --- a/freebsd/contrib/tcpdump/print-fr.c +++ b/freebsd/contrib/tcpdump/print-fr.c @@ -335,7 +335,7 @@ fr_print(netdissect_options *ndo, case NLPID_CLNP: case NLPID_ESIS: case NLPID_ISIS: - isoclns_print(ndo, p - 1, length + 1, ndo->ndo_snapend - p + 1); /* OSI printers need the NLPID field */ + isoclns_print(ndo, p - 1, length + 1); /* OSI printers need the NLPID field */ break; case NLPID_SNAP: diff --git a/freebsd/contrib/tcpdump/print-frag6.c b/freebsd/contrib/tcpdump/print-frag6.c index 11f97ad2..fb364c4d 100644 --- a/freebsd/contrib/tcpdump/print-frag6.c +++ b/freebsd/contrib/tcpdump/print-frag6.c @@ -33,10 +33,11 @@ #include <netdissect-stdinc.h> -#include "ip6.h" #include "netdissect.h" #include "extract.h" +#include "ip6.h" + int frag6_print(netdissect_options *ndo, register const u_char *bp, register const u_char *bp2) { @@ -46,7 +47,7 @@ frag6_print(netdissect_options *ndo, register const u_char *bp, register const u dp = (const struct ip6_frag *)bp; ip6 = (const struct ip6_hdr *)bp2; - ND_TCHECK(dp->ip6f_offlg); + ND_TCHECK(*dp); if (ndo->ndo_vflag) { ND_PRINT((ndo, "frag (0x%08x:%d|%ld)", diff --git a/freebsd/contrib/tcpdump/print-gre.c b/freebsd/contrib/tcpdump/print-gre.c index 2a13d435..04ad5d2a 100644 --- a/freebsd/contrib/tcpdump/print-gre.c +++ b/freebsd/contrib/tcpdump/print-gre.c @@ -232,7 +232,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) atalk_print(ndo, bp, len); break; case ETHERTYPE_GRE_ISO: - isoclns_print(ndo, bp, len, ndo->ndo_snapend - bp); + isoclns_print(ndo, bp, len); break; case ETHERTYPE_TEB: ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL); diff --git a/freebsd/contrib/tcpdump/print-hncp.c b/freebsd/contrib/tcpdump/print-hncp.c index 83ee2fd9..34297772 100644 --- a/freebsd/contrib/tcpdump/print-hncp.c +++ b/freebsd/contrib/tcpdump/print-hncp.c @@ -276,6 +276,8 @@ dhcpv4_print(netdissect_options *ndo, i = 0; while (i < length) { + if (i + 2 > length) + return -1; tlv = cp + i; type = (uint8_t)tlv[0]; optlen = (uint8_t)tlv[1]; @@ -287,6 +289,8 @@ dhcpv4_print(netdissect_options *ndo, ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type))); ND_PRINT((ndo," (%u)", optlen + 2 )); + if (i + 2 + optlen > length) + return -1; switch (type) { case DH4OPT_DNS_SERVERS: @@ -324,6 +328,8 @@ dhcpv6_print(netdissect_options *ndo, i = 0; while (i < length) { + if (i + 4 > length) + return -1; tlv = cp + i; type = EXTRACT_16BITS(tlv); optlen = EXTRACT_16BITS(tlv + 2); @@ -335,6 +341,8 @@ dhcpv6_print(netdissect_options *ndo, ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type))); ND_PRINT((ndo," (%u)", optlen + 4 )); + if (i + 4 + optlen > length) + return -1; switch (type) { case DH6OPT_DNS_SERVERS: diff --git a/freebsd/contrib/tcpdump/print-icmp.c b/freebsd/contrib/tcpdump/print-icmp.c index fc4906eb..ce22ce81 100644 --- a/freebsd/contrib/tcpdump/print-icmp.c +++ b/freebsd/contrib/tcpdump/print-icmp.c @@ -588,6 +588,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * ip = (const struct ip *)bp; ndo->ndo_snaplen = ndo->ndo_snapend - bp; snapend_save = ndo->ndo_snapend; + ND_TCHECK_16BITS(&ip->ip_len); ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len)); ndo->ndo_snapend = snapend_save; } @@ -605,7 +606,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * * to check if an extension header is present. This is expedient, * however not all implementations set the length field proper. */ - if (!ext_dp->icmp_length) { + if (!ext_dp->icmp_length && + ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) { vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; vec[0].len = plen - ICMP_EXTD_MINLEN; if (in_cksum(vec, 1)) { @@ -626,12 +628,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * } hlen = plen - ICMP_EXTD_MINLEN; - vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; - vec[0].len = hlen; - ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u", - EXTRACT_16BITS(ext_dp->icmp_ext_checksum), - in_cksum(vec, 1) ? "in" : "", - hlen)); + if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) { + vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; + vec[0].len = hlen; + ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u", + EXTRACT_16BITS(ext_dp->icmp_ext_checksum), + in_cksum(vec, 1) ? "in" : "", + hlen)); + } hlen -= 4; /* subtract common header size */ obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data; diff --git a/freebsd/contrib/tcpdump/print-icmp6.c b/freebsd/contrib/tcpdump/print-icmp6.c index 2e6756cf..e2d44dfb 100644 --- a/freebsd/contrib/tcpdump/print-icmp6.c +++ b/freebsd/contrib/tcpdump/print-icmp6.c @@ -1137,6 +1137,7 @@ icmp6_print(netdissect_options *ndo, if (ndo->ndo_vflag) { ND_TCHECK(dp->icmp6_data16[0]); ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]))); + ND_TCHECK(dp->icmp6_data16[1]); if (dp->icmp6_data16[1] & 0xc0) ND_PRINT((ndo," ")); if (dp->icmp6_data16[1] & 0x80) @@ -1704,6 +1705,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, needcomma = 0; + ND_TCHECK2(*dp, sizeof(*ni6)); ni6 = (const struct icmp6_nodeinfo *)dp; ND_PRINT((ndo," node information reply")); ND_PRINT((ndo," (")); /*)*/ @@ -1758,6 +1760,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, ND_PRINT((ndo,", ")); ND_PRINT((ndo,"DNS name")); cp = (const u_char *)(ni6 + 1) + 4; + ND_TCHECK(cp[0]); if (cp[0] == ep - cp - 1) { /* icmp-name-lookup-03, pascal string */ if (ndo->ndo_vflag) diff --git a/freebsd/contrib/tcpdump/print-ip.c b/freebsd/contrib/tcpdump/print-ip.c index 6aa5692e..677ed942 100644 --- a/freebsd/contrib/tcpdump/print-ip.c +++ b/freebsd/contrib/tcpdump/print-ip.c @@ -60,7 +60,7 @@ static const struct tok ip_option_values[] = { /* * print the recorded route in an IP RR, LSRR or SSRR option. */ -static void +static int ip_printroute(netdissect_options *ndo, register const u_char *cp, u_int length) { @@ -69,19 +69,25 @@ ip_printroute(netdissect_options *ndo, if (length < 3) { ND_PRINT((ndo, " [bad length %u]", length)); - return; + return (0); } if ((length + 1) & 3) ND_PRINT((ndo, " [bad length %u]", length)); + ND_TCHECK(cp[2]); ptr = cp[2] - 1; if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) ND_PRINT((ndo, " [bad ptr %u]", cp[2])); for (len = 3; len < length; len += 4) { + ND_TCHECK2(cp[len], 4); ND_PRINT((ndo, " %s", ipaddr_string(ndo, &cp[len]))); if (ptr > len) ND_PRINT((ndo, ",")); } + return (0); + +trunc: + return (-1); } /* @@ -168,7 +174,7 @@ nextproto4_cksum(netdissect_options *ndo, return (in_cksum(vec, 2)); } -static void +static int ip_printts(netdissect_options *ndo, register const u_char *cp, u_int length) { @@ -179,16 +185,18 @@ ip_printts(netdissect_options *ndo, if (length < 4) { ND_PRINT((ndo, "[bad length %u]", length)); - return; + return (0); } ND_PRINT((ndo, " TS{")); hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; if ((length - 4) & (hoplen-1)) ND_PRINT((ndo, "[bad length %u]", length)); + ND_TCHECK(cp[2]); ptr = cp[2] - 1; len = 0; if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) ND_PRINT((ndo, "[bad ptr %u]", cp[2])); + ND_TCHECK(cp[3]); switch (cp[3]&0xF) { case IPOPT_TS_TSONLY: ND_PRINT((ndo, "TSONLY")); @@ -217,6 +225,7 @@ ip_printts(netdissect_options *ndo, for (len = 4; len < length; len += hoplen) { if (ptr == len) type = " ^ "; + ND_TCHECK2(cp[len], hoplen); ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), hoplen!=8 ? "" : ipaddr_string(ndo, &cp[len]))); type = " "; @@ -229,6 +238,10 @@ done: ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4)); else ND_PRINT((ndo, "}")); + return (0); + +trunc: + return (-1); } /* @@ -278,13 +291,15 @@ ip_optprint(netdissect_options *ndo, return; case IPOPT_TS: - ip_printts(ndo, cp, option_len); + if (ip_printts(ndo, cp, option_len) == -1) + goto trunc; break; case IPOPT_RR: /* fall through */ case IPOPT_SSRR: case IPOPT_LSRR: - ip_printroute(ndo, cp, option_len); + if (ip_printroute(ndo, cp, option_len) == -1) + goto trunc; break; case IPOPT_RA: @@ -330,7 +345,7 @@ static void ip_print_demux(netdissect_options *ndo, struct ip_print_demux_state *ipds) { - struct protoent *proto; + const char *p_name; again: switch (ipds->nh) { @@ -496,8 +511,8 @@ again: #endif default: - if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL) - ND_PRINT((ndo, " %s", proto->p_name)); + if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(ipds->nh)) != NULL) + ND_PRINT((ndo, " %s", p_name)); else ND_PRINT((ndo, " ip-proto-%d", ipds->nh)); ND_PRINT((ndo, " %d", ipds->len)); @@ -538,7 +553,7 @@ ip_print(netdissect_options *ndo, u_int hlen; struct cksum_vec vec[1]; uint16_t sum, ip_sum; - struct protoent *proto; + const char *p_name; ipds->ip = (const struct ip *)bp; ND_TCHECK(ipds->ip->ip_vhl); @@ -683,8 +698,8 @@ ip_print(netdissect_options *ndo, */ ND_PRINT((ndo, "%s > %s:", ipaddr_string(ndo, &ipds->ip->ip_src), ipaddr_string(ndo, &ipds->ip->ip_dst))); - if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL) - ND_PRINT((ndo, " %s", proto->p_name)); + if (!ndo->ndo_nflag && (p_name = netdb_protoname(ipds->ip->ip_p)) != NULL) + ND_PRINT((ndo, " %s", p_name)); else ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p)); } diff --git a/freebsd/contrib/tcpdump/print-ip6.c b/freebsd/contrib/tcpdump/print-ip6.c index c82ead12..047ddfc0 100644 --- a/freebsd/contrib/tcpdump/print-ip6.c +++ b/freebsd/contrib/tcpdump/print-ip6.c @@ -286,6 +286,8 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) advance = sizeof(struct ip6_hdr); nh = ip6->ip6_nxt; while (cp < ndo->ndo_snapend && advance > 0) { + if (len < (u_int)advance) + goto trunc; cp += advance; len -= advance; @@ -328,10 +330,15 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) * mobility header. */ advance = mobility_print(ndo, cp, (const u_char *)ip6); + if (advance < 0) + return; nh = *cp; return; case IPPROTO_ROUTING: + ND_TCHECK(*cp); advance = rt6_print(ndo, cp, (const u_char *)ip6); + if (advance < 0) + return; nh = *cp; break; case IPPROTO_SCTP: @@ -351,12 +358,16 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) return; case IPPROTO_AH: advance = ah_print(ndo, cp); + if (advance < 0) + return; nh = *cp; break; case IPPROTO_ESP: { int enh, padlen; advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen); + if (advance < 0) + return; nh = enh & 0xff; len -= padlen; break; diff --git a/freebsd/contrib/tcpdump/print-ip6opts.c b/freebsd/contrib/tcpdump/print-ip6opts.c index 782ac550..a35111fa 100644 --- a/freebsd/contrib/tcpdump/print-ip6opts.c +++ b/freebsd/contrib/tcpdump/print-ip6opts.c @@ -41,12 +41,12 @@ #include <netdissect-stdinc.h> -#include "ip6.h" - #include "netdissect.h" #include "addrtoname.h" #include "extract.h" +#include "ip6.h" + static void ip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len) { diff --git a/freebsd/contrib/tcpdump/print-isakmp.c b/freebsd/contrib/tcpdump/print-isakmp.c index c004eea9..fd78bf86 100644 --- a/freebsd/contrib/tcpdump/print-isakmp.c +++ b/freebsd/contrib/tcpdump/print-isakmp.c @@ -57,6 +57,7 @@ #include "ip.h" #include "ip6.h" +#include "ipproto.h" /* refer to RFC 2408 */ @@ -433,7 +434,7 @@ struct notify_messages { char *msg; }; -/* 3.8 Notification Payload */ +/* 3.8 Authentication Payload */ struct ikev2_auth { struct isakmp_gen h; uint8_t auth_method; /* Protocol-ID */ @@ -921,21 +922,25 @@ struct attrmap { static const u_char * ikev1_attrmap_print(netdissect_options *ndo, - const u_char *p, const u_char *ep, + const u_char *p, const u_char *ep2, const struct attrmap *map, size_t nmap) { int totlen; uint32_t t, v; + ND_TCHECK(p[0]); if (p[0] & 0x80) totlen = 4; - else + else { + ND_TCHECK_16BITS(&p[2]); totlen = 4 + EXTRACT_16BITS(&p[2]); - if (ep < p + totlen) { + } + if (ep2 < p + totlen) { ND_PRINT((ndo,"[|attr]")); - return ep + 1; + return ep2 + 1; } + ND_TCHECK_16BITS(&p[0]); ND_PRINT((ndo,"(")); t = EXTRACT_16BITS(&p[0]) & 0x7fff; if (map && t < nmap && map[t].type) @@ -944,47 +949,71 @@ ikev1_attrmap_print(netdissect_options *ndo, ND_PRINT((ndo,"type=#%d ", t)); if (p[0] & 0x80) { ND_PRINT((ndo,"value=")); + ND_TCHECK_16BITS(&p[2]); v = EXTRACT_16BITS(&p[2]); if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) ND_PRINT((ndo,"%s", map[t].value[v])); - else - rawprint(ndo, (const uint8_t *)&p[2], 2); + else { + if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) { + ND_PRINT((ndo,")")); + goto trunc; + } + } } else { - ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2]))); - rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2])); + ND_PRINT((ndo,"len=%d value=", totlen - 4)); + if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) { + ND_PRINT((ndo,")")); + goto trunc; + } } ND_PRINT((ndo,")")); return p + totlen; + +trunc: + return NULL; } static const u_char * -ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep) +ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2) { int totlen; uint32_t t; + ND_TCHECK(p[0]); if (p[0] & 0x80) totlen = 4; - else + else { + ND_TCHECK_16BITS(&p[2]); totlen = 4 + EXTRACT_16BITS(&p[2]); - if (ep < p + totlen) { + } + if (ep2 < p + totlen) { ND_PRINT((ndo,"[|attr]")); - return ep + 1; + return ep2 + 1; } + ND_TCHECK_16BITS(&p[0]); ND_PRINT((ndo,"(")); t = EXTRACT_16BITS(&p[0]) & 0x7fff; ND_PRINT((ndo,"type=#%d ", t)); if (p[0] & 0x80) { ND_PRINT((ndo,"value=")); t = p[2]; - rawprint(ndo, (const uint8_t *)&p[2], 2); + if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) { + ND_PRINT((ndo,")")); + goto trunc; + } } else { - ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2]))); - rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2])); + ND_PRINT((ndo,"len=%d value=", totlen - 4)); + if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) { + ND_PRINT((ndo,")")); + goto trunc; + } } ND_PRINT((ndo,")")); return p + totlen; + +trunc: + return NULL; } static const u_char * @@ -1265,11 +1294,12 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, cp = (const u_char *)(p + 1); ep2 = (const u_char *)p + item_len; while (cp < ep && cp < ep2) { - if (map && nmap) { - cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, - map, nmap); - } else - cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); + if (map && nmap) + cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap); + else + cp = ikev1_attr_print(ndo, cp, ep2); + if (cp == NULL) + goto trunc; } if (ep < ep2) ND_PRINT((ndo,"...")); @@ -1293,6 +1323,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, UNALIGNED_MEMCPY(&e, ext, sizeof(e)); ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; @@ -1356,16 +1387,15 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, { const struct ipsecdoi_id *doi_p; struct ipsecdoi_id doi_id; - struct protoent *pe; + const char *p_name; doi_p = (const struct ipsecdoi_id *)ext; ND_TCHECK(*doi_p); UNALIGNED_MEMCPY(&doi_id, ext, sizeof(doi_id)); ND_PRINT((ndo," idtype=%s", STR_OR_ID(doi_id.type, ipsecidtypestr))); /* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */ - pe = doi_id.proto_id ? getprotobynumber(doi_id.proto_id) : NULL; - if (pe) - ND_PRINT((ndo," protoid=%s", pe->p_name)); + if (!ndo->ndo_nflag && doi_id.proto_id && (p_name = netdb_protoname(doi_id.proto_id)) != NULL) + ND_PRINT((ndo," protoid=%s", p_name)); else ND_PRINT((ndo," protoid=%u", doi_id.proto_id)); ND_PRINT((ndo," port=%d", ntohs(doi_id.port))); @@ -1416,8 +1446,8 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, case IPSECDOI_ID_IPV6_ADDR_SUBNET: { const u_char *mask; - if (len < 20) - ND_PRINT((ndo," len=%d [bad: < 20]", len)); + if (len < 32) + ND_PRINT((ndo," len=%d [bad: < 32]", len)); else { mask = (const u_char *)(data + sizeof(struct in6_addr)); /*XXX*/ @@ -1496,6 +1526,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," len=%d", item_len - 4)); ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); if (2 < ndo->ndo_vflag && 4 < item_len) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; @@ -1528,6 +1559,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, ND_PRINT((ndo," len=%d", item_len - 4)); ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); if (2 < ndo->ndo_vflag && 4 < item_len) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4)) goto trunc; @@ -1552,6 +1584,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, UNALIGNED_MEMCPY(&e, ext, sizeof(e)); ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; @@ -1576,6 +1609,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, UNALIGNED_MEMCPY(&e, ext, sizeof(e)); ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; @@ -1600,15 +1634,20 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, ND_TCHECK(*ext); UNALIGNED_MEMCPY(&e, ext, sizeof(e)); - ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4)); - if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { - ND_PRINT((ndo," ")); - if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) - goto trunc; - } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { - ND_PRINT((ndo," ")); - if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep)) - goto trunc; + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT((ndo," n len=%u", ntohs(e.len) - 4)); + if (ntohs(e.len) > 4) { + if (ndo->ndo_vflag > 2) { + ND_PRINT((ndo, " ")); + if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } else if (ndo->ndo_vflag > 1) { + ND_PRINT((ndo, " ")); + if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep)) + goto trunc; + } } return (const u_char *)ext + ntohs(e.len); trunc: @@ -1619,8 +1658,8 @@ trunc: static const u_char * ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, const struct isakmp_gen *ext, u_int item_len, - const u_char *ep, uint32_t phase, uint32_t doi0 _U_, - uint32_t proto0 _U_, int depth) + const u_char *ep, uint32_t phase _U_, uint32_t doi0 _U_, + uint32_t proto0 _U_, int depth _U_) { const struct ikev1_pl_n *p; struct ikev1_pl_n n; @@ -1722,35 +1761,44 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, ep2 = (const u_char *)p + item_len; if (cp < ep) { - ND_PRINT((ndo," orig=(")); switch (ntohs(n.type)) { case IPSECDOI_NTYPE_RESPONDER_LIFETIME: { const struct attrmap *map = oakley_t_map; size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); + ND_PRINT((ndo," attrs=(")); while (cp < ep && cp < ep2) { - cp = ikev1_attrmap_print(ndo, cp, - (ep < ep2) ? ep : ep2, map, nmap); + cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap); + if (cp == NULL) { + ND_PRINT((ndo,")")); + goto trunc; + } } + ND_PRINT((ndo,")")); break; } case IPSECDOI_NTYPE_REPLAY_STATUS: + ND_PRINT((ndo," status=(")); ND_PRINT((ndo,"replay detection %sabled", EXTRACT_32BITS(cp) ? "en" : "dis")); - break; - case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: - if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA, - (const struct isakmp_gen *)cp, ep, phase, doi, proto, - depth) == NULL) - return NULL; + ND_PRINT((ndo,")")); break; default: - /* NULL is dummy */ - isakmp_print(ndo, cp, - item_len - sizeof(*p) - n.spi_size, - NULL); + /* + * XXX - fill in more types here; see, for example, + * draft-ietf-ipsec-notifymsg-04. + */ + if (ndo->ndo_vflag > 3) { + ND_PRINT((ndo," data=(")); + if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp)) + goto trunc; + ND_PRINT((ndo,")")); + } else { + if (!ike_show_somedata(ndo, cp, ep)) + goto trunc; + } + break; } - ND_PRINT((ndo,")")); } return (const u_char *)ext + item_len; trunc: @@ -1817,6 +1865,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, UNALIGNED_MEMCPY(&e, ext, sizeof(e)); ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; @@ -1851,6 +1900,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay, ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; @@ -1925,10 +1975,11 @@ ikev2_t_print(netdissect_options *ndo, int tcount, ep2 = (const u_char *)p + item_len; while (cp < ep && cp < ep2) { if (map && nmap) { - cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, - map, nmap); + cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap); } else - cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); + cp = ikev1_attr_print(ndo, cp, ep2); + if (cp == NULL) + goto trunc; } if (ep < ep2) ND_PRINT((ndo,"...")); @@ -1988,7 +2039,6 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, if (prop_length < sizeof(*ext)) goto toolong; ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); /* @@ -2075,7 +2125,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay, if (sa_length < sizeof(*ext)) goto toolong; ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); /* @@ -2136,7 +2185,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay, const struct ikev2_ke *k; k = (const struct ikev2_ke *)ext; - ND_TCHECK(*ext); + ND_TCHECK(*k); UNALIGNED_MEMCPY(&ke, ext, sizeof(ke)); ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); @@ -2161,12 +2210,14 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay, uint32_t phase _U_, uint32_t doi _U_, uint32_t proto _U_, int depth _U_) { + const struct ikev2_id *idp; struct ikev2_id id; int id_len, idtype_len, i; unsigned int dumpascii, dumphex; const unsigned char *typedata; - ND_TCHECK(*ext); + idp = (const struct ikev2_id *)ext; + ND_TCHECK(*idp); UNALIGNED_MEMCPY(&id, ext, sizeof(id)); ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical); @@ -2174,6 +2225,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay, ND_PRINT((ndo," len=%d", id_len - 4)); if (2 < ndo->ndo_vflag && 4 < id_len) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4)) goto trunc; @@ -2269,21 +2321,26 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay, const u_char *authdata = (const u_char*)ext + sizeof(a); unsigned int len; - ND_TCHECK(*ext); + ND_TCHECK2(*ext, sizeof(a)); UNALIGNED_MEMCPY(&a, ext, sizeof(a)); ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical); len = ntohs(a.h.len); - ND_PRINT((ndo," len=%d method=%s", len-4, + /* + * Our caller has ensured that the length is >= 4. + */ + ND_PRINT((ndo," len=%u method=%s", len-4, STR_OR_ID(a.auth_method, v2_auth))); - - if (1 < ndo->ndo_vflag && 4 < len) { - ND_PRINT((ndo," authdata=(")); - if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a))) - goto trunc; - ND_PRINT((ndo,") ")); - } else if(ndo->ndo_vflag && 4 < len) { - if(!ike_show_somedata(ndo, authdata, ep)) goto trunc; + if (len > 4) { + if (ndo->ndo_vflag > 1) { + ND_PRINT((ndo, " authdata=(")); + if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a))) + goto trunc; + ND_PRINT((ndo, ") ")); + } else if (ndo->ndo_vflag) { + if (!ike_show_somedata(ndo, authdata, ep)) + goto trunc; + } } return (const u_char *)ext + len; @@ -2332,7 +2389,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, const struct ikev2_n *p; struct ikev2_n n; const u_char *cp; - u_char showspi, showdata, showsomedata; + u_char showspi, showsomedata; const char *notify_name; uint32_t type; @@ -2342,7 +2399,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical); showspi = 1; - showdata = 0; showsomedata=0; notify_name=NULL; @@ -2456,7 +2512,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, notify_name = "cookie"; showspi = 1; showsomedata= 1; - showdata= 0; break; case IV2_NOTIFY_USE_TRANSPORT_MODE: @@ -2509,19 +2564,17 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, cp = (const u_char *)(p + 1) + n.spi_size; - if(3 < ndo->ndo_vflag) { - showdata = 1; - } - - if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) { - ND_PRINT((ndo," data=(")); - if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp)) - goto trunc; - - ND_PRINT((ndo,")")); + if (cp < ep) { + if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) { + ND_PRINT((ndo," data=(")); + if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp)) + goto trunc; - } else if(showsomedata && cp < ep) { - if(!ike_show_somedata(ndo, cp, ep)) goto trunc; + ND_PRINT((ndo,")")); + } else if (showsomedata) { + if (!ike_show_somedata(ndo, cp, ep)) + goto trunc; + } } return (const u_char *)ext + item_len; @@ -2564,6 +2617,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay, else ND_PRINT((ndo, ".")); } if (2 < ndo->ndo_vflag && 4 < len) { + /* Print the entire payload in hex */ ND_PRINT((ndo," ")); if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4)) goto trunc; @@ -2729,7 +2783,6 @@ ikev1_sub_print(netdissect_options *ndo, while (np) { ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); ND_TCHECK2(*ext, ntohs(e.len)); @@ -2897,7 +2950,6 @@ ikev2_sub_print(netdissect_options *ndo, cp = (const u_char *)ext; while (np) { ND_TCHECK(*ext); - UNALIGNED_MEMCPY(&e, ext, sizeof(e)); ND_TCHECK2(*ext, ntohs(e.len)); @@ -3051,7 +3103,7 @@ isakmp_rfc3948_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2) { - + ND_TCHECK(bp[0]); if(length == 1 && bp[0]==0xff) { ND_PRINT((ndo, "isakmp-nat-keep-alive")); return; @@ -3060,6 +3112,7 @@ isakmp_rfc3948_print(netdissect_options *ndo, if(length < 4) { goto trunc; } + ND_TCHECK(bp[3]); /* * see if this is an IKE packet @@ -3100,10 +3153,6 @@ trunc: * c-basic-offset: 8 * End: */ - - - - #ifdef __rtems__ #include "rtems-bsd-tcpdump-print-isakmp-data.h" #endif /* __rtems__ */ diff --git a/freebsd/contrib/tcpdump/print-isoclns.c b/freebsd/contrib/tcpdump/print-isoclns.c index 7fec66e0..480e5f19 100644 --- a/freebsd/contrib/tcpdump/print-isoclns.c +++ b/freebsd/contrib/tcpdump/print-isoclns.c @@ -26,7 +26,7 @@ * * Original code by Matt Thomas, Digital Equipment Corporation * - * Extensively modified by Hannes Gredler (hannes@juniper.net) for more + * Extensively modified by Hannes Gredler (hannes@gredler.at) for more * complete IS-IS & CLNP support. */ @@ -570,8 +570,8 @@ struct isis_tlv_ptp_adj { uint8_t neighbor_extd_local_circuit_id[4]; }; -static int osi_print_cksum(netdissect_options *, const uint8_t *pptr, - uint16_t checksum, int checksum_offset, int length); +static void osi_print_cksum(netdissect_options *, const uint8_t *pptr, + uint16_t checksum, int checksum_offset, u_int length); static int clnp_print(netdissect_options *, const uint8_t *, u_int); static void esis_print(netdissect_options *, const uint8_t *, u_int); static int isis_print(netdissect_options *, const uint8_t *, u_int); @@ -676,10 +676,9 @@ struct isis_tlv_lsp { #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) void -isoclns_print(netdissect_options *ndo, - const uint8_t *p, u_int length, u_int caplen) +isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length) { - if (caplen <= 1) { /* enough bytes on the wire ? */ + if (!ND_TTEST(*p)) { /* enough bytes on the wire ? */ ND_PRINT((ndo, "|OSI")); return; } @@ -691,7 +690,7 @@ isoclns_print(netdissect_options *ndo, case NLPID_CLNP: if (!clnp_print(ndo, p, length)) - print_unknown_data(ndo, p, "\n\t", caplen); + print_unknown_data(ndo, p, "\n\t", length); break; case NLPID_ESIS: @@ -700,7 +699,7 @@ isoclns_print(netdissect_options *ndo, case NLPID_ISIS: if (!isis_print(ndo, p, length)) - print_unknown_data(ndo, p, "\n\t", caplen); + print_unknown_data(ndo, p, "\n\t", length); break; case NLPID_NULLNS: @@ -727,8 +726,8 @@ isoclns_print(netdissect_options *ndo, if (!ndo->ndo_eflag) ND_PRINT((ndo, "OSI NLPID 0x%02x unknown", *p)); ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length)); - if (caplen > 1) - print_unknown_data(ndo, p, "\n\t", caplen); + if (length > 1) + print_unknown_data(ndo, p, "\n\t", length); break; } } @@ -871,9 +870,8 @@ clnp_print(netdissect_options *ndo, EXTRACT_16BITS(clnp_header->segment_length), EXTRACT_16BITS(clnp_header->cksum))); - if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7, - clnp_header->length_indicator) == 0) - goto trunc; + osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7, + clnp_header->length_indicator); ND_PRINT((ndo, "\n\tFlags [%s]", bittok2str(clnp_flag_values, "none", clnp_flags))); @@ -1159,8 +1157,7 @@ esis_print(netdissect_options *ndo, ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" )); ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum))); - if (osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li) == 0) - goto trunc; + osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li); ND_PRINT((ndo, ", holding time: %us, length indicator: %u", EXTRACT_16BITS(esis_header->holdtime), li)); @@ -1226,10 +1223,18 @@ esis_print(netdissect_options *ndo, pptr += netal; li -= netal; - if (netal == 0) - ND_PRINT((ndo, "\n\t %s", etheraddr_string(ndo, snpa))); + if (snpal == 6) + ND_PRINT((ndo, "\n\t SNPA (length: %u): %s", + snpal, + etheraddr_string(ndo, snpa))); else - ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, neta, netal))); + ND_PRINT((ndo, "\n\t SNPA (length: %u): %s", + snpal, + linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal))); + if (netal != 0) + ND_PRINT((ndo, "\n\t NET (length: %u) %s", + netal, + isonsap_string(ndo, neta, netal))); break; } @@ -1335,7 +1340,7 @@ esis_print(netdissect_options *ndo, case ESIS_OPTION_PROTOCOLS: while (opli>0) { - ND_TCHECK(*pptr); + ND_TCHECK(*tptr); ND_PRINT((ndo, "%s (0x%02x)", tok2str(nlpid_values, "unknown", @@ -1368,7 +1373,7 @@ esis_print(netdissect_options *ndo, pptr += opli; } trunc: - return; + ND_PRINT((ndo, "[|esis]")); } static void @@ -1404,6 +1409,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, while (len > 2) { + ND_TCHECK2(*tptr, 2); stlv_type = *(tptr++); stlv_len = *(tptr++); @@ -1416,11 +1422,18 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, /*len -= TLV_TYPE_LEN_OFFSET;*/ len = len -2; + /* Make sure the subTLV fits within the space left */ + if (len < stlv_len) + goto trunc; + /* Make sure the entire subTLV is in the captured data */ + ND_TCHECK2(*(tptr), stlv_len); + switch (stlv_type) { case ISIS_SUBTLV_SPB_MCID: { - ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN); + if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN) + goto trunc; subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr; @@ -1435,15 +1448,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, /*tptr += SPB_MCID_MIN_LEN; len -= SPB_MCID_MIN_LEN; */ - tptr = tptr + sizeof(struct isis_subtlv_spb_mcid); - len = len - sizeof(struct isis_subtlv_spb_mcid); + tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN; + len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN; + stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN; break; } case ISIS_SUBTLV_SPB_DIGEST: { - ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN); + if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN) + goto trunc; ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d", (*(tptr) >> 5), (((*tptr)>> 4) & 0x01), @@ -1462,18 +1477,15 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, } len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; + stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; break; } case ISIS_SUBTLV_SPB_BVID: { - ND_TCHECK2(*(tptr), stlv_len); - - while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN) + while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN) { - ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN); - ND_PRINT((ndo, "\n\t ECT: %08x", EXTRACT_32BITS(tptr))); @@ -1486,14 +1498,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo, tptr = tptr + 2; len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN; + stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN; } break; } default: - break; + break; } + tptr += stlv_len; + len -= stlv_len; } return 0; @@ -1512,6 +1527,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, while (len > 2) { + ND_TCHECK2(*tptr, 2); stlv_type = *(tptr++); stlv_len = *(tptr++); @@ -1523,11 +1539,17 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, len = len - 2; + /* Make sure the subTLV fits within the space left */ + if (len < stlv_len) + goto trunc; + /* Make sure the entire subTLV is in the captured data */ + ND_TCHECK2(*(tptr), stlv_len); + switch (stlv_type) { case ISIS_SUBTLV_SPB_INSTANCE: - - ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN); + if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN) + goto trunc; ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr))); tptr = tptr+4; @@ -1549,10 +1571,12 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, tmp = *(tptr++); len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; + stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; while (tmp) { - ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN); + if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN) + goto trunc; ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d", *(tptr) >> 7, (*(tptr) >> 6) & 0x01, @@ -1570,14 +1594,15 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, tptr = tptr + 3; len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; + stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; tmp--; } break; case ISIS_SUBTLV_SPBM_SI: - - ND_TCHECK2(*tptr, 8); + if (stlv_len < 8) + goto trunc; ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr))); tptr = tptr+4; @@ -1609,6 +1634,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo, default: break; } + tptr += stlv_len; + len -= stlv_len; } return 0; @@ -1625,8 +1652,12 @@ isis_print_id(const uint8_t *cp, int id_len) int i; static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; char *pos = id; + int sysid_len; - for (i = 1; i <= SYSTEM_ID_LEN; i++) { + sysid_len = SYSTEM_ID_LEN; + if (sysid_len > id_len) + sysid_len = id_len; + for (i = 1; i <= sysid_len; i++) { snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); pos += strlen(pos); if (i == 2 || i == 4) @@ -1836,6 +1867,8 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, break; case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: + if (subl == 0) + break; ND_PRINT((ndo, "%sBandwidth Constraints Model ID: %s (%u)", ident, tok2str(diffserv_te_bc_values, "unknown", *tptr), @@ -1843,7 +1876,6 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, tptr++; /* decode BCs until the subTLV ends */ for (te_class = 0; te_class < (subl-1)/4; te_class++) { - ND_TCHECK2(*tptr, 4); bw.i = EXTRACT_32BITS(tptr); ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps", ident, @@ -1905,13 +1937,15 @@ isis_print_is_reach_subtlv(netdissect_options *ndo, case GMPLS_PSC2: case GMPLS_PSC3: case GMPLS_PSC4: - ND_TCHECK2(*tptr, 6); + if (subl < 6) + break; bw.i = EXTRACT_32BITS(tptr); ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000)); ND_PRINT((ndo, "%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr + 4))); break; case GMPLS_TSC: - ND_TCHECK2(*tptr, 8); + if (subl < 8) + break; bw.i = EXTRACT_32BITS(tptr); ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000)); ND_PRINT((ndo, "%s Indication %s", ident, @@ -2047,7 +2081,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo, } processed++; } else if (afi == AF_INET6) { - if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ + if (!ND_TTEST2(*tptr, 2)) /* fetch status & prefix_len byte */ return (0); status_byte=*(tptr++); bit_length=*(tptr++); @@ -2170,6 +2204,8 @@ isis_print(netdissect_options *ndo, TLV verification */ isis_header = (const struct isis_common_header *)p; ND_TCHECK(*isis_header); + if (length < ISIS_COMMON_HEADER_SIZE) + goto trunc; pptr = p+(ISIS_COMMON_HEADER_SIZE); header_iih_lan = (const struct isis_iih_lan_header *)pptr; header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; @@ -2200,6 +2236,16 @@ isis_print(netdissect_options *ndo, return (0); } + if (length < isis_header->fixed_len) { + ND_PRINT((ndo, "fixed header length %u > packet length %u", isis_header->fixed_len, length)); + return (0); + } + + if (isis_header->fixed_len < ISIS_COMMON_HEADER_SIZE) { + ND_PRINT((ndo, "fixed header length %u < minimum header size %u", isis_header->fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE)); + return (0); + } + max_area = isis_header->max_area; switch(max_area) { case 0: @@ -2242,254 +2288,255 @@ isis_print(netdissect_options *ndo, pdu_type=isis_header->pdu_type; /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ - if (ndo->ndo_vflag < 1) { + if (ndo->ndo_vflag == 0) { ND_PRINT((ndo, "%s%s", ndo->ndo_eflag ? "" : ", ", tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type))); + } else { + /* ok they seem to want to know everything - lets fully decode it */ + ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length)); - switch (pdu_type) { - - case ISIS_PDU_L1_LAN_IIH: - case ISIS_PDU_L2_LAN_IIH: - ND_TCHECK(*header_iih_lan); - ND_PRINT((ndo, ", src-id %s", - isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN))); - ND_PRINT((ndo, ", lan-id %s, prio %u", - isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), - header_iih_lan->priority)); - break; - case ISIS_PDU_PTP_IIH: - ND_TCHECK(*header_iih_ptp); - ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN))); - break; - case ISIS_PDU_L1_LSP: - case ISIS_PDU_L2_LSP: - ND_TCHECK(*header_lsp); - ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us", - isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), - EXTRACT_32BITS(header_lsp->sequence_number), - EXTRACT_16BITS(header_lsp->remaining_lifetime))); - break; - case ISIS_PDU_L1_CSNP: - case ISIS_PDU_L2_CSNP: - ND_TCHECK(*header_csnp); - ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN))); - break; - case ISIS_PDU_L1_PSNP: - case ISIS_PDU_L2_PSNP: - ND_TCHECK(*header_psnp); - ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN))); - break; - - } - ND_PRINT((ndo, ", length %u", length)); - - return(1); - } - - /* ok they seem to want to know everything - lets fully decode it */ - ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length)); - - ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", - tok2str(isis_pdu_values, - "unknown, type %u", - pdu_type), - isis_header->fixed_len, - isis_header->version, - isis_header->pdu_version, - id_length, - isis_header->id_length, - max_area, - isis_header->max_area)); - - if (ndo->ndo_vflag > 1) { - if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */ - return(0); /* for optionally debugging the common header */ + ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", + tok2str(isis_pdu_values, + "unknown, type %u", + pdu_type), + isis_header->fixed_len, + isis_header->version, + isis_header->pdu_version, + id_length, + isis_header->id_length, + max_area, + isis_header->max_area)); + + if (ndo->ndo_vflag > 1) { + if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */ + return (0); /* for optionally debugging the common header */ + } } switch (pdu_type) { case ISIS_PDU_L1_LAN_IIH: case ISIS_PDU_L2_LAN_IIH: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE)); - return (0); - } - - ND_TCHECK(*header_iih_lan); - pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); - if (packet_len>pdu_len) { - packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ - length=pdu_len; - } + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { + ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE))); + return (0); + } + ND_TCHECK(*header_iih_lan); + if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE) + goto trunc; + if (ndo->ndo_vflag == 0) { + ND_PRINT((ndo, ", src-id %s", + isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN))); + ND_PRINT((ndo, ", lan-id %s, prio %u", + isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), + header_iih_lan->priority)); + ND_PRINT((ndo, ", length %u", length)); + return (1); + } + pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } - ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]", - isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), - EXTRACT_16BITS(header_iih_lan->holding_time), - tok2str(isis_iih_circuit_type_values, - "unknown circuit type 0x%02x", - header_iih_lan->circuit_type))); + ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_lan->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_lan->circuit_type))); - ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u", - isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), - (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, - pdu_len)); + ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u", + isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), + (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, + pdu_len)); - if (ndo->ndo_vflag > 1) { - if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE)) - return(0); - } + if (ndo->ndo_vflag > 1) { + if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE)) + return (0); + } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); - pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); - break; + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + break; case ISIS_PDU_PTP_IIH: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE)); - return (0); - } - - ND_TCHECK(*header_iih_ptp); - pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); - if (packet_len>pdu_len) { + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { + ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE))); + return (0); + } + ND_TCHECK(*header_iih_ptp); + if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE) + goto trunc; + if (ndo->ndo_vflag == 0) { + ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN))); + ND_PRINT((ndo, ", length %u", length)); + return (1); + } + pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); + if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; - } + } - ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]", - isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), - EXTRACT_16BITS(header_iih_ptp->holding_time), - tok2str(isis_iih_circuit_type_values, - "unknown circuit type 0x%02x", - header_iih_ptp->circuit_type))); + ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_ptp->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_ptp->circuit_type))); - ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u", - header_iih_ptp->circuit_id, - pdu_len)); + ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u", + header_iih_ptp->circuit_id, + pdu_len)); - if (ndo->ndo_vflag > 1) { - if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE)) - return(0); - } + if (ndo->ndo_vflag > 1) { + if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE)) + return (0); + } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); - pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); - break; + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + break; case ISIS_PDU_L1_LSP: case ISIS_PDU_L2_LSP: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE)); - return (0); - } - - ND_TCHECK(*header_lsp); - pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); - if (packet_len>pdu_len) { + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { + ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE)); + return (0); + } + ND_TCHECK(*header_lsp); + if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE) + goto trunc; + if (ndo->ndo_vflag == 0) { + ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime))); + ND_PRINT((ndo, ", length %u", length)); + return (1); + } + pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); + if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; - } + } - ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", + ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), EXTRACT_32BITS(header_lsp->sequence_number), EXTRACT_16BITS(header_lsp->remaining_lifetime), EXTRACT_16BITS(header_lsp->checksum))); - if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id, - EXTRACT_16BITS(header_lsp->checksum), - 12, length-12) == 0) - goto trunc; + osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id, + EXTRACT_16BITS(header_lsp->checksum), + 12, length-12); - ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s", + ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s", pdu_len, ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "")); - if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "")); - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "")); - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "")); - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "")); - ND_PRINT((ndo, "ATT bit set, ")); - } - ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "")); - ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)", - ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)))); + if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { + ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "")); + ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "")); + ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "")); + ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "")); + ND_PRINT((ndo, "ATT bit set, ")); + } + ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "")); + ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)", + ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)))); - if (ndo->ndo_vflag > 1) { - if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE)) - return(0); - } + if (ndo->ndo_vflag > 1) { + if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE)) + return (0); + } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); - pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); - break; + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + break; case ISIS_PDU_L1_CSNP: case ISIS_PDU_L2_CSNP: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { - ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE)); - return (0); - } - - ND_TCHECK(*header_csnp); - pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); - if (packet_len>pdu_len) { + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { + ND_PRINT((ndo, ", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE))); + return (0); + } + ND_TCHECK(*header_csnp); + if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE) + goto trunc; + if (ndo->ndo_vflag == 0) { + ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN))); + ND_PRINT((ndo, ", length %u", length)); + return (1); + } + pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); + if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; - } + } - ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", + ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", isis_print_id(header_csnp->source_id, NODE_ID_LEN), pdu_len)); - ND_PRINT((ndo, "\n\t start lsp-id: %s", + ND_PRINT((ndo, "\n\t start lsp-id: %s", isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN))); - ND_PRINT((ndo, "\n\t end lsp-id: %s", + ND_PRINT((ndo, "\n\t end lsp-id: %s", isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN))); - if (ndo->ndo_vflag > 1) { - if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE)) - return(0); - } + if (ndo->ndo_vflag > 1) { + if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE)) + return (0); + } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); - pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); break; case ISIS_PDU_L1_PSNP: case ISIS_PDU_L2_PSNP: - if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { - ND_PRINT((ndo, "- bogus fixed header length %u should be %lu", - isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE)); - return (0); - } - - ND_TCHECK(*header_psnp); - pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); - if (packet_len>pdu_len) { + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { + ND_PRINT((ndo, "- bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE))); + return (0); + } + ND_TCHECK(*header_psnp); + if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE) + goto trunc; + if (ndo->ndo_vflag == 0) { + ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN))); + ND_PRINT((ndo, ", length %u", length)); + return (1); + } + pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); + if (packet_len>pdu_len) { packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ length=pdu_len; - } + } - ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", + ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u", isis_print_id(header_psnp->source_id, NODE_ID_LEN), pdu_len)); - if (ndo->ndo_vflag > 1) { - if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE)) - return(0); - } + if (ndo->ndo_vflag > 1) { + if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE)) + return (0); + } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); - pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); - break; + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + break; default: + if (ndo->ndo_vflag == 0) { + ND_PRINT((ndo, ", length %u", length)); + return (1); + } (void)print_unknown_data(ndo, pptr, "\n\t ", length); return (0); } @@ -2498,20 +2545,15 @@ isis_print(netdissect_options *ndo, * Now print the TLV's. */ - while (packet_len >= 2) { - if (pptr == ndo->ndo_snapend) { - return (1); - } - + while (packet_len > 0) { ND_TCHECK2(*pptr, 2); + if (packet_len < 2) + goto trunc; tlv_type = *pptr++; tlv_len = *pptr++; tmp =tlv_len; /* copy temporary len & pointer to packet data */ tptr = pptr; packet_len -= 2; - if (tlv_len > packet_len) { - break; - } /* first lets see if we know the TLVs name*/ ND_PRINT((ndo, "\n\t %s TLV #%u, length: %u", @@ -2524,12 +2566,16 @@ isis_print(netdissect_options *ndo, if (tlv_len == 0) /* something is invalid */ continue; + if (packet_len < tlv_len) + goto trunc; + /* now check if we have a decoder otherwise do a hexdump at the end*/ switch (tlv_type) { case ISIS_TLV_AREA_ADDR: ND_TCHECK2(*tptr, 1); alen = *tptr++; while (tmp && alen < tmp) { + ND_TCHECK2(*tptr, alen); ND_PRINT((ndo, "\n\t Area address (length: %u): %s", alen, isonsap_string(ndo, tptr, alen))); @@ -2912,9 +2958,8 @@ isis_print(netdissect_options *ndo, * to avoid conflicts the checksum TLV is zeroed. * see rfc3358 for details */ - if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr, - length) == 0) - goto trunc; + osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr, + length); break; case ISIS_TLV_POI: @@ -3108,40 +3153,33 @@ isis_print(netdissect_options *ndo, return(1); } -static int +static void osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr, - uint16_t checksum, int checksum_offset, int length) + uint16_t checksum, int checksum_offset, u_int length) { uint16_t calculated_checksum; /* do not attempt to verify the checksum if it is zero, - * if the total length is nonsense, * if the offset is nonsense, * or the base pointer is not sane */ if (!checksum - || length < 0 || checksum_offset < 0 - || length > ndo->ndo_snaplen - || checksum_offset > ndo->ndo_snaplen - || checksum_offset > length) { + || !ND_TTEST2(*(pptr + checksum_offset), 2) + || (u_int)checksum_offset > length + || !ND_TTEST2(*pptr, length)) { ND_PRINT((ndo, " (unverified)")); - return 1; } else { #if 0 - printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen); + printf("\nosi_print_cksum: %p %u %u\n", pptr, checksum_offset, length); #endif - ND_TCHECK2(*pptr, length); calculated_checksum = create_osi_cksum(pptr, checksum_offset, length); if (checksum == calculated_checksum) { ND_PRINT((ndo, " (correct)")); } else { ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum)); } - return 1; } -trunc: - return 0; } /* diff --git a/freebsd/contrib/tcpdump/print-juniper.c b/freebsd/contrib/tcpdump/print-juniper.c index 647110ef..db252a9d 100644 --- a/freebsd/contrib/tcpdump/print-juniper.c +++ b/freebsd/contrib/tcpdump/print-juniper.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: DLT_JUNIPER_* printers */ @@ -478,6 +478,7 @@ juniper_ggsn_print(netdissect_options *ndo, p+=l2info.header_len; gh = (struct juniper_ggsn_header *)&l2info.cookie; + ND_TCHECK(*gh); if (ndo->ndo_eflag) { ND_PRINT((ndo, "proto %s (%u), vlan %u: ", tok2str(juniper_protocol_values,"Unknown",gh->proto), @@ -498,6 +499,10 @@ juniper_ggsn_print(netdissect_options *ndo, } return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_services]")); + return l2info.header_len; } #endif @@ -525,6 +530,7 @@ juniper_es_print(netdissect_options *ndo, p+=l2info.header_len; ih = (const struct juniper_ipsec_header *)p; + ND_TCHECK(*ih); switch (ih->type) { case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE: case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE: @@ -570,6 +576,10 @@ juniper_es_print(netdissect_options *ndo, ip_print(ndo, p, l2info.length); return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_services]")); + return l2info.header_len; } #endif @@ -594,6 +604,7 @@ juniper_monitor_print(netdissect_options *ndo, p+=l2info.header_len; mh = (const struct juniper_monitor_header *)p; + ND_TCHECK(*mh); if (ndo->ndo_eflag) ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ", EXTRACT_32BITS(&mh->service_id), @@ -604,6 +615,10 @@ juniper_monitor_print(netdissect_options *ndo, ip_heuristic_guess (ndo, p, l2info.length); return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_services]")); + return l2info.header_len; } #endif @@ -628,6 +643,7 @@ juniper_services_print(netdissect_options *ndo, p+=l2info.header_len; sh = (const struct juniper_services_header *)p; + ND_TCHECK(*sh); if (ndo->ndo_eflag) ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", sh->svc_id, @@ -639,6 +655,10 @@ juniper_services_print(netdissect_options *ndo, ip_heuristic_guess (ndo, p, l2info.length); return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_services]")); + return l2info.header_len; } #endif @@ -746,6 +766,7 @@ juniper_pppoe_atm_print(netdissect_options *ndo, p+=l2info.header_len; + ND_TCHECK2(p[0], 2); extracted_ethertype = EXTRACT_16BITS(p); /* this DLT contains nothing but raw PPPoE frames, * prepended with a type field*/ @@ -758,6 +779,10 @@ juniper_pppoe_atm_print(netdissect_options *ndo, ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype)); return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_pppoe_atm]")); + return l2info.header_len; } #endif @@ -799,7 +824,7 @@ juniper_mlppp_print(netdissect_options *ndo, mpls_print(ndo, p, l2info.length); return l2info.header_len; case JUNIPER_LSQ_L3_PROTO_ISO: - isoclns_print(ndo, p, l2info.length, l2info.caplen); + isoclns_print(ndo, p, l2info.length); return l2info.header_len; default: break; @@ -854,7 +879,7 @@ juniper_mfr_print(netdissect_options *ndo, mpls_print(ndo, p, l2info.length); return l2info.header_len; case JUNIPER_LSQ_L3_PROTO_ISO: - isoclns_print(ndo, p, l2info.length, l2info.caplen); + isoclns_print(ndo, p, l2info.length); return l2info.header_len; default: break; @@ -867,13 +892,13 @@ juniper_mfr_print(netdissect_options *ndo, ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle)); switch (l2info.proto) { case (LLCSAP_ISONS<<8 | LLCSAP_ISONS): - isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1); + isoclns_print(ndo, p + 1, l2info.length - 1); break; case (LLC_UI<<8 | NLPID_Q933): case (LLC_UI<<8 | NLPID_IP): case (LLC_UI<<8 | NLPID_IP6): /* pass IP{4,6} to the OSI layer for proper link-layer printing */ - isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1); + isoclns_print(ndo, p - 1, l2info.length + 1); break; default: ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length)); @@ -902,13 +927,13 @@ juniper_mlfr_print(netdissect_options *ndo, switch (l2info.proto) { case (LLC_UI): case (LLC_UI<<8): - isoclns_print(ndo, p, l2info.length, l2info.caplen); + isoclns_print(ndo, p, l2info.length); break; case (LLC_UI<<8 | NLPID_Q933): case (LLC_UI<<8 | NLPID_IP): case (LLC_UI<<8 | NLPID_IP6): /* pass IP{4,6} to the OSI layer for proper link-layer printing */ - isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1); + isoclns_print(ndo, p - 1, l2info.length + 1); break; default: ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length)); @@ -946,6 +971,7 @@ juniper_atm1_print(netdissect_options *ndo, return l2info.header_len; } + ND_TCHECK2(p[0], 3); if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ @@ -955,7 +981,7 @@ juniper_atm1_print(netdissect_options *ndo, } if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ - isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1); + isoclns_print(ndo, p + 1, l2info.length - 1); /* FIXME check if frame was recognized */ return l2info.header_len; } @@ -964,6 +990,10 @@ juniper_atm1_print(netdissect_options *ndo, return l2info.header_len; return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_atm1]")); + return l2info.header_len; } #endif @@ -995,6 +1025,7 @@ juniper_atm2_print(netdissect_options *ndo, return l2info.header_len; } + ND_TCHECK2(p[0], 3); if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ @@ -1010,7 +1041,7 @@ juniper_atm2_print(netdissect_options *ndo, } if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ - isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1); + isoclns_print(ndo, p + 1, l2info.length - 1); /* FIXME check if frame was recognized */ return l2info.header_len; } @@ -1022,6 +1053,10 @@ juniper_atm2_print(netdissect_options *ndo, return l2info.header_len; return l2info.header_len; + +trunc: + ND_PRINT((ndo, "[|juniper_atm2]")); + return l2info.header_len; } #endif @@ -1286,6 +1321,7 @@ juniper_parse_header(netdissect_options *ndo, l2info->caplen -= l2info->header_len; /* search through the cookie table and copy values matching for our PIC type */ + ND_TCHECK(p[0]); while (lp->s != NULL) { if (lp->pictype == l2info->pictype) { @@ -1337,6 +1373,7 @@ juniper_parse_header(netdissect_options *ndo, if (ndo->ndo_eflag) ND_PRINT((ndo, ": ")); /* print demarc b/w L2/L3*/ + ND_TCHECK_16BITS(p+l2info->cookie_len); l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); break; } @@ -1366,6 +1403,7 @@ juniper_parse_header(netdissect_options *ndo, case DLT_JUNIPER_MLFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: + ND_TCHECK2(p[0], 2); l2info->bundle = l2info->cookie[1]; l2info->proto = EXTRACT_16BITS(p); l2info->header_len += 2; @@ -1389,6 +1427,7 @@ juniper_parse_header(netdissect_options *ndo, case DLT_JUNIPER_MFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: + ND_TCHECK2(p[0], 2); l2info->bundle = l2info->cookie[1]; l2info->proto = EXTRACT_16BITS(p); l2info->header_len += 2; diff --git a/freebsd/contrib/tcpdump/print-l2tp.c b/freebsd/contrib/tcpdump/print-l2tp.c index a4ea2061..f2100fa7 100644 --- a/freebsd/contrib/tcpdump/print-l2tp.c +++ b/freebsd/contrib/tcpdump/print-l2tp.c @@ -303,10 +303,14 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat) /* AVP-specific print out routines */ /***********************************/ static void -l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat) +l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint16_t *ptr = (const uint16_t *)dat; + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; + } ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u", EXTRACT_16BITS(ptr)))); } @@ -316,28 +320,53 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint16_t *ptr = (const uint16_t *)dat; - ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); ptr++; /* Result Code */ - if (length > 2) { /* Error Code (opt) */ - ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); ptr++; + /* Result Code */ + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; } - if (length > 4) { /* Error Message (opt) */ - ND_PRINT((ndo, " ")); - print_string(ndo, (const u_char *)ptr, length - 4); + ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); + ptr++; + length -= 2; + + /* Error Code (opt) */ + if (length == 0) + return; + if (length < 2) { + ND_PRINT((ndo, " AVP too short")); + return; } + ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); + ptr++; + length -= 2; + + /* Error Message (opt) */ + if (length == 0) + return; + ND_PRINT((ndo, " ")); + print_string(ndo, (const u_char *)ptr, length); } static void -l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat) +l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length) { + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; + } ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8), (EXTRACT_16BITS(dat) & 0xff))); } static void -l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat) +l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint32_t *ptr = (const uint32_t *)dat; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { ND_PRINT((ndo, "A")); } @@ -347,10 +376,14 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat) } static void -l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat) +l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint32_t *ptr = (const uint32_t *)dat; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { ND_PRINT((ndo, "A")); } @@ -362,19 +395,29 @@ l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat) static void l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) { + if (length < 3) { + ND_PRINT((ndo, "AVP too short")); + return; + } print_16bits_val(ndo, (const uint16_t *)dat); ND_PRINT((ndo, ", %02x", dat[2])); - if (length > 3) { + dat += 3; + length -= 3; + if (length != 0) { ND_PRINT((ndo, " ")); - print_string(ndo, dat+3, length-3); + print_string(ndo, dat, length); } } static void -l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat) +l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint32_t *ptr = (const uint32_t *)dat; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { ND_PRINT((ndo, "A")); } @@ -384,10 +427,14 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat) } static void -l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat) +l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint32_t *ptr = (const uint32_t *)dat; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { ND_PRINT((ndo, "A")); } @@ -403,67 +450,117 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo) } static void -l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat) +l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint16_t *ptr = (const uint16_t *)dat; + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; + } ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str, "AuthType-#%u", EXTRACT_16BITS(ptr)))); } static void -l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat) +l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint16_t *ptr = (const uint16_t *)dat; + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; + } ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK)); } static void -l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat) +l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint16_t *ptr = (const uint16_t *)dat; uint16_t val_h, val_l; + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; + } ptr++; /* skip "Reserved" */ + length -= 2; - val_h = EXTRACT_16BITS(ptr); ptr++; - val_l = EXTRACT_16BITS(ptr); ptr++; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } + val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; + val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l)); - val_h = EXTRACT_16BITS(ptr); ptr++; - val_l = EXTRACT_16BITS(ptr); ptr++; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } + val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; + val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l)); - val_h = EXTRACT_16BITS(ptr); ptr++; - val_l = EXTRACT_16BITS(ptr); ptr++; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } + val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; + val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l)); - val_h = EXTRACT_16BITS(ptr); ptr++; - val_l = EXTRACT_16BITS(ptr); ptr++; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } + val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; + val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l)); - val_h = EXTRACT_16BITS(ptr); ptr++; - val_l = EXTRACT_16BITS(ptr); ptr++; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } + val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; + val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l)); + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } val_h = EXTRACT_16BITS(ptr); ptr++; val_l = EXTRACT_16BITS(ptr); ptr++; ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l)); } static void -l2tp_accm_print(netdissect_options *ndo, const u_char *dat) +l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length) { const uint16_t *ptr = (const uint16_t *)dat; uint16_t val_h, val_l; + if (length < 2) { + ND_PRINT((ndo, "AVP too short")); + return; + } ptr++; /* skip "Reserved" */ + length -= 2; - val_h = EXTRACT_16BITS(ptr); ptr++; - val_l = EXTRACT_16BITS(ptr); ptr++; + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } + val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; + val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l)); + if (length < 4) { + ND_PRINT((ndo, "AVP too short")); + return; + } val_h = EXTRACT_16BITS(ptr); ptr++; val_l = EXTRACT_16BITS(ptr); ptr++; ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l)); @@ -474,14 +571,27 @@ l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int lengt { const uint16_t *ptr = (const uint16_t *)dat; - ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(ptr))); ptr++; /* Disconnect Code */ - ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(ptr))); ptr++; /* Control Protocol Number */ + if (length < 5) { + ND_PRINT((ndo, "AVP too short")); + return; + } + /* Disconnect Code */ + ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat))); + dat += 2; + length -= 2; + /* Control Protocol Number */ + ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(dat))); + dat += 2; + length -= 2; + /* Direction */ ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str, - "Direction-#%u", *((const u_char *)ptr++)))); + "Direction-#%u", EXTRACT_8BITS(ptr)))); + ptr++; + length--; - if (length > 5) { + if (length != 0) { ND_PRINT((ndo, " ")); - print_string(ndo, (const u_char *)ptr, length-5); + print_string(ndo, (const u_char *)ptr, length); } } @@ -514,7 +624,12 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) /* If it goes past the end of the remaining length of the captured data, we'll give up. */ ND_TCHECK2(*ptr, len); - /* After this point, no need to worry about truncation */ + + /* + * After this point, we don't need to check whether we go past + * the length of the captured data; however, we *do* need to + * check whether we go past the end of the AVP. + */ if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) { ND_PRINT((ndo, "*")); @@ -543,27 +658,35 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) } else { switch (attr_type) { case L2TP_AVP_MSGTYPE: - l2tp_msgtype_print(ndo, (const u_char *)ptr); + l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_RESULT_CODE: l2tp_result_code_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_PROTO_VER: - l2tp_proto_ver_print(ndo, ptr); + l2tp_proto_ver_print(ndo, ptr, len-6); break; case L2TP_AVP_FRAMING_CAP: - l2tp_framing_cap_print(ndo, (const u_char *)ptr); + l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_BEARER_CAP: - l2tp_bearer_cap_print(ndo, (const u_char *)ptr); + l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_TIE_BREAKER: + if (len-6 < 8) { + ND_PRINT((ndo, "AVP too short")); + break; + } print_octets(ndo, (const u_char *)ptr, 8); break; case L2TP_AVP_FIRM_VER: case L2TP_AVP_ASSND_TUN_ID: case L2TP_AVP_RECV_WIN_SIZE: case L2TP_AVP_ASSND_SESS_ID: + if (len-6 < 2) { + ND_PRINT((ndo, "AVP too short")); + break; + } print_16bits_val(ndo, ptr); break; case L2TP_AVP_HOST_NAME: @@ -588,6 +711,10 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_CHALLENGE_RESP: + if (len-6 < 16) { + ND_PRINT((ndo, "AVP too short")); + break; + } print_octets(ndo, (const u_char *)ptr, 16); break; case L2TP_AVP_CALL_SER_NUM: @@ -596,28 +723,32 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) case L2TP_AVP_TX_CONN_SPEED: case L2TP_AVP_PHY_CHANNEL_ID: case L2TP_AVP_RX_CONN_SPEED: + if (len-6 < 4) { + ND_PRINT((ndo, "AVP too short")); + break; + } print_32bits_val(ndo, (const uint32_t *)ptr); break; case L2TP_AVP_BEARER_TYPE: - l2tp_bearer_type_print(ndo, (const u_char *)ptr); + l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_FRAMING_TYPE: - l2tp_framing_type_print(ndo, (const u_char *)ptr); + l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_PACKET_PROC_DELAY: l2tp_packet_proc_delay_print(ndo); break; case L2TP_AVP_PROXY_AUTH_TYPE: - l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr); + l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_PROXY_AUTH_ID: - l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr); + l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_CALL_ERRORS: - l2tp_call_errors_print(ndo, (const u_char *)ptr); + l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_ACCM: - l2tp_accm_print(ndo, (const u_char *)ptr); + l2tp_accm_print(ndo, (const u_char *)ptr, len-6); break; case L2TP_AVP_SEQ_REQUIRED: break; /* No Attribute Value */ diff --git a/freebsd/contrib/tcpdump/print-ldp.c b/freebsd/contrib/tcpdump/print-ldp.c index 6fe626f8..b0975868 100644 --- a/freebsd/contrib/tcpdump/print-ldp.c +++ b/freebsd/contrib/tcpdump/print-ldp.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) * and Steinar Haug (sthaug@nethelp.no) */ diff --git a/freebsd/contrib/tcpdump/print-llc.c b/freebsd/contrib/tcpdump/print-llc.c index 210bc908..f243f468 100644 --- a/freebsd/contrib/tcpdump/print-llc.c +++ b/freebsd/contrib/tcpdump/print-llc.c @@ -330,7 +330,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, #endif if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS && control == LLC_UI) { - isoclns_print(ndo, p, length, caplen); + isoclns_print(ndo, p, length); return (hdrlen); } diff --git a/freebsd/contrib/tcpdump/print-lldp.c b/freebsd/contrib/tcpdump/print-lldp.c index b48cb3cc..213fd57e 100644 --- a/freebsd/contrib/tcpdump/print-lldp.c +++ b/freebsd/contrib/tcpdump/print-lldp.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com> * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net> */ @@ -596,6 +596,7 @@ static const struct tok lldp_evb_mode_values[]={ { LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"}, { LLDP_EVB_MODE_EVB_STATION, "EVB Staion"}, { LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"}, + { 0, NULL}, }; #define NO_OF_BITS 8 @@ -656,7 +657,7 @@ lldp_private_8021_print(netdissect_options *ndo, int subtype, hexdump = FALSE; u_int sublen; u_int tval; - uint8_t i; + u_int i; if (tlv_len < 4) { return hexdump; @@ -792,9 +793,9 @@ lldp_private_8021_print(netdissect_options *ndo, ND_PRINT((ndo, "\n\t Application Priority Table")); while(i<sublen) { tval=*(tptr+i+5); - ND_PRINT((ndo, "\n\t Priority: %d, RES: %d, Sel: %d", - tval >> 5, (tval >> 3) & 0x03, (tval & 0x07))); - ND_PRINT((ndo, "Protocol ID: %d", EXTRACT_16BITS(tptr + i + 5))); + ND_PRINT((ndo, "\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u", + tval >> 5, (tval >> 3) & 0x03, (tval & 0x07), + EXTRACT_16BITS(tptr + i + 5))); i=i+3; } break; @@ -903,6 +904,9 @@ lldp_private_8023_print(netdissect_options *ndo, break; case LLDP_PRIVATE_8023_SUBTYPE_MTU: + if (tlv_len < 6) { + return hexdump; + } ND_PRINT((ndo, "\n\t MTU size %u", EXTRACT_16BITS(tptr + 4))); break; @@ -932,7 +936,7 @@ lldp_extract_latlon(const u_char *tptr) * (right now there is only one) */ - + static int lldp_private_iana_print(netdissect_options *ndo, const u_char *tptr, u_int tlv_len) @@ -956,12 +960,12 @@ lldp_private_iana_print(netdissect_options *ndo, default: hexdump=TRUE; } - + return hexdump; } - + /* * Print private TIA extensions. */ @@ -1406,7 +1410,7 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo, if (tlen) { oid_len = *tptr; - if (tlen < oid_len) { + if (tlen < 1U + oid_len) { return 0; } if (oid_len) { diff --git a/freebsd/contrib/tcpdump/print-lmp.c b/freebsd/contrib/tcpdump/print-lmp.c index 1ea898ee..031fdb96 100644 --- a/freebsd/contrib/tcpdump/print-lmp.c +++ b/freebsd/contrib/tcpdump/print-lmp.c @@ -16,14 +16,15 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) - * Support for LMP service discovery extensions (defined by UNI 1.0) added - * by Manu Pathak (mapathak@cisco.com), May 2005 + * Original code by Hannes Gredler (hannes@gredler.at) + * Support for LMP service discovery extensions (defined by OIF UNI 1.0) + * added by Manu Pathak (mapathak@cisco.com), May 2005 */ /* \summary: Link Management Protocol (LMP) printer */ /* specification: RFC 4204 */ +/* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -359,6 +360,73 @@ static const struct tok lmp_ctype_values[] = { { 0, NULL} }; +static int +lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr, + int total_subobj_len, int offset) +{ + int hexdump = FALSE; + int subobj_type, subobj_len; + + union { /* int to float conversion buffer */ + float f; + uint32_t i; + } bw; + + while (total_subobj_len > 0 && hexdump == FALSE ) { + subobj_type = EXTRACT_8BITS(obj_tptr+offset); + subobj_len = EXTRACT_8BITS(obj_tptr+offset+1); + ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u", + tok2str(lmp_data_link_subobj, + "Unknown", + subobj_type), + subobj_type, + subobj_len)); + if (subobj_len < 4) { + ND_PRINT((ndo, " (too short)")); + break; + } + if ((subobj_len % 4) != 0) { + ND_PRINT((ndo, " (not a multiple of 4)")); + break; + } + if (total_subobj_len < subobj_len) { + ND_PRINT((ndo, " (goes past the end of the object)")); + break; + } + switch(subobj_type) { + case INT_SWITCHING_TYPE_SUBOBJ: + ND_PRINT((ndo, "\n\t Switching Type: %s (%u)", + tok2str(gmpls_switch_cap_values, + "Unknown", + EXTRACT_8BITS(obj_tptr+offset+2)), + EXTRACT_8BITS(obj_tptr+offset+2))); + ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)", + tok2str(gmpls_encoding_values, + "Unknown", + EXTRACT_8BITS(obj_tptr+offset+3)), + EXTRACT_8BITS(obj_tptr+offset+3))); + bw.i = EXTRACT_32BITS(obj_tptr+offset+4); + ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000)); + bw.i = EXTRACT_32BITS(obj_tptr+offset+8); + ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000)); + break; + case WAVELENGTH_SUBOBJ: + ND_PRINT((ndo, "\n\t Wavelength: %u", + EXTRACT_32BITS(obj_tptr+offset+4))); + break; + default: + /* Any Unknown Subobject ==> Exit loop */ + hexdump=TRUE; + break; + } + total_subobj_len-=subobj_len; + offset+=subobj_len; + } + return (hexdump); +} + void lmp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) @@ -366,10 +434,10 @@ lmp_print(netdissect_options *ndo, const struct lmp_common_header *lmp_com_header; const struct lmp_object_header *lmp_obj_header; const u_char *tptr,*obj_tptr; - int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; + u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; int hexdump; - int offset,subobj_type,subobj_len,total_subobj_len; - int link_type; + u_int offset; + u_int link_type; union { /* int to float conversion buffer */ float f; @@ -407,6 +475,14 @@ lmp_print(netdissect_options *ndo, tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type), bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags), tlen)); + if (tlen < sizeof(const struct lmp_common_header)) { + ND_PRINT((ndo, " (too short)")); + return; + } + if (tlen > len) { + ND_PRINT((ndo, " (too long)")); + tlen = len; + } tptr+=sizeof(const struct lmp_common_header); tlen-=sizeof(const struct lmp_common_header); @@ -419,9 +495,6 @@ lmp_print(netdissect_options *ndo, lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length); lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f; - if(lmp_obj_len % 4 || lmp_obj_len < 4) - return; - ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", tok2str(lmp_obj_values, "Unknown", @@ -434,6 +507,15 @@ lmp_print(netdissect_options *ndo, (lmp_obj_header->ctype)&0x80 ? "" : "non-", lmp_obj_len)); + if (lmp_obj_len < 4) { + ND_PRINT((ndo, " (too short)")); + return; + } + if ((lmp_obj_len % 4) != 0) { + ND_PRINT((ndo, " (not a multiple of 4)")); + return; + } + obj_tptr=tptr+sizeof(struct lmp_object_header); obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header); @@ -447,6 +529,10 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_LOC: case LMP_CTYPE_RMT: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Control Channel ID: %u (0x%08x)", EXTRACT_32BITS(obj_tptr), EXTRACT_32BITS(obj_tptr))); @@ -462,18 +548,30 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_IPV4_LOC: case LMP_CTYPE_IPV4_RMT: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t IPv4 Link ID: %s (0x%08x)", ipaddr_string(ndo, obj_tptr), EXTRACT_32BITS(obj_tptr))); break; case LMP_CTYPE_IPV6_LOC: case LMP_CTYPE_IPV6_RMT: + if (obj_tlen != 16) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)", ip6addr_string(ndo, obj_tptr), EXTRACT_32BITS(obj_tptr))); break; case LMP_CTYPE_UNMD_LOC: case LMP_CTYPE_UNMD_RMT: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)", EXTRACT_32BITS(obj_tptr), EXTRACT_32BITS(obj_tptr))); @@ -486,11 +584,19 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_MESSAGE_ID: switch(lmp_obj_ctype) { case LMP_CTYPE_1: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Message ID: %u (0x%08x)", EXTRACT_32BITS(obj_tptr), EXTRACT_32BITS(obj_tptr))); break; case LMP_CTYPE_2: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Message ID Ack: %u (0x%08x)", EXTRACT_32BITS(obj_tptr), EXTRACT_32BITS(obj_tptr))); @@ -504,6 +610,10 @@ lmp_print(netdissect_options *ndo, switch(lmp_obj_ctype) { case LMP_CTYPE_LOC: case LMP_CTYPE_RMT: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Node ID: %s (0x%08x)", ipaddr_string(ndo, obj_tptr), EXTRACT_32BITS(obj_tptr))); @@ -517,6 +627,10 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_CONFIG: switch(lmp_obj_ctype) { case LMP_CTYPE_HELLO_CONFIG: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", EXTRACT_16BITS(obj_tptr), EXTRACT_16BITS(obj_tptr+2))); @@ -530,6 +644,10 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_HELLO: switch(lmp_obj_ctype) { case LMP_CTYPE_HELLO: + if (obj_tlen != 8) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Tx Seq: %u, Rx Seq: %u", EXTRACT_32BITS(obj_tptr), EXTRACT_32BITS(obj_tptr+4))); @@ -541,13 +659,17 @@ lmp_print(netdissect_options *ndo, break; case LMP_OBJ_TE_LINK: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + if (obj_tlen != 12) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Flags: [%s]", - bittok2str(lmp_obj_te_link_flag_values, + bittok2str(lmp_obj_te_link_flag_values, "none", - EXTRACT_16BITS(obj_tptr)>>8))); + EXTRACT_8BITS(obj_tptr)))); - switch(lmp_obj_ctype) { - case LMP_CTYPE_IPV4: ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)" "\n\t Remote Link-ID: %s (0x%08x)", ipaddr_string(ndo, obj_tptr+4), @@ -557,21 +679,57 @@ lmp_print(netdissect_options *ndo, break; case LMP_CTYPE_IPV6: + if (obj_tlen != 36) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } + ND_PRINT((ndo, "\n\t Flags: [%s]", + bittok2str(lmp_obj_te_link_flag_values, + "none", + EXTRACT_8BITS(obj_tptr)))); + + ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)" + "\n\t Remote Link-ID: %s (0x%08x)", + ip6addr_string(ndo, obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + ip6addr_string(ndo, obj_tptr+20), + EXTRACT_32BITS(obj_tptr+20))); + break; + case LMP_CTYPE_UNMD: + if (obj_tlen != 12) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } + ND_PRINT((ndo, "\n\t Flags: [%s]", + bittok2str(lmp_obj_te_link_flag_values, + "none", + EXTRACT_8BITS(obj_tptr)))); + + ND_PRINT((ndo, "\n\t Local Link-ID: %u (0x%08x)" + "\n\t Remote Link-ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+8))); + break; + default: hexdump=TRUE; } break; case LMP_OBJ_DATA_LINK: - ND_PRINT((ndo, "\n\t Flags: [%s]", - bittok2str(lmp_obj_data_link_flag_values, - "none", - EXTRACT_16BITS(obj_tptr)>>8))); - switch(lmp_obj_ctype) { case LMP_CTYPE_IPV4: - case LMP_CTYPE_UNMD: + if (obj_tlen < 12) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } + ND_PRINT((ndo, "\n\t Flags: [%s]", + bittok2str(lmp_obj_data_link_flag_values, + "none", + EXTRACT_8BITS(obj_tptr)))); ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)" "\n\t Remote Interface ID: %s (0x%08x)", ipaddr_string(ndo, obj_tptr+4), @@ -579,51 +737,50 @@ lmp_print(netdissect_options *ndo, ipaddr_string(ndo, obj_tptr+8), EXTRACT_32BITS(obj_tptr+8))); - total_subobj_len = lmp_obj_len - 16; - offset = 12; - while (total_subobj_len > 0 && hexdump == FALSE ) { - subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8; - subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF; - ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u", - tok2str(lmp_data_link_subobj, - "Unknown", - subobj_type), - subobj_type, - subobj_len)); - switch(subobj_type) { - case INT_SWITCHING_TYPE_SUBOBJ: - ND_PRINT((ndo, "\n\t Switching Type: %s (%u)", - tok2str(gmpls_switch_cap_values, - "Unknown", - EXTRACT_16BITS(obj_tptr+offset+2)>>8), - EXTRACT_16BITS(obj_tptr+offset+2)>>8)); - ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)", - tok2str(gmpls_encoding_values, - "Unknown", - EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF), - EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF)); - bw.i = EXTRACT_32BITS(obj_tptr+offset+4); - ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps", - bw.f*8/1000000)); - bw.i = EXTRACT_32BITS(obj_tptr+offset+8); - ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps", - bw.f*8/1000000)); - break; - case WAVELENGTH_SUBOBJ: - ND_PRINT((ndo, "\n\t Wavelength: %u", - EXTRACT_32BITS(obj_tptr+offset+4))); - break; - default: - /* Any Unknown Subobject ==> Exit loop */ - hexdump=TRUE; - break; - } - total_subobj_len-=subobj_len; - offset+=subobj_len; - } - + if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12)) + hexdump=TRUE; break; + case LMP_CTYPE_IPV6: + if (obj_tlen < 36) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } + ND_PRINT((ndo, "\n\t Flags: [%s]", + bittok2str(lmp_obj_data_link_flag_values, + "none", + EXTRACT_8BITS(obj_tptr)))); + ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)" + "\n\t Remote Interface ID: %s (0x%08x)", + ip6addr_string(ndo, obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + ip6addr_string(ndo, obj_tptr+20), + EXTRACT_32BITS(obj_tptr+20))); + + if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36)) + hexdump=TRUE; + break; + + case LMP_CTYPE_UNMD: + if (obj_tlen < 12) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } + ND_PRINT((ndo, "\n\t Flags: [%s]", + bittok2str(lmp_obj_data_link_flag_values, + "none", + EXTRACT_8BITS(obj_tptr)))); + ND_PRINT((ndo, "\n\t Local Interface ID: %u (0x%08x)" + "\n\t Remote Interface ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+8))); + + if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12)) + hexdump=TRUE; + break; + default: hexdump=TRUE; } @@ -632,6 +789,10 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_VERIFY_BEGIN: switch(lmp_obj_ctype) { case LMP_CTYPE_1: + if (obj_tlen != 20) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Flags: %s", bittok2str(lmp_obj_begin_verify_flag_values, "none", @@ -660,6 +821,10 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_VERIFY_BEGIN_ACK: switch(lmp_obj_ctype) { case LMP_CTYPE_1: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Verify Dead Interval: %u" "\n\t Verify Transport Response: %u", EXTRACT_16BITS(obj_tptr), @@ -674,6 +839,10 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_VERIFY_ID: switch(lmp_obj_ctype) { case LMP_CTYPE_1: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Verify ID: %u", EXTRACT_32BITS(obj_tptr))); break; @@ -686,19 +855,20 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_CHANNEL_STATUS: switch(lmp_obj_ctype) { case LMP_CTYPE_IPV4: - case LMP_CTYPE_UNMD: offset = 0; /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */ - while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { + while (offset+8 <= obj_tlen) { ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", ipaddr_string(ndo, obj_tptr+offset), EXTRACT_32BITS(obj_tptr+offset))); - ND_PRINT((ndo, "\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? + ND_PRINT((ndo, "\n\t\t Active: %s (%u)", + (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? "Allocated" : "Non-allocated", (EXTRACT_32BITS(obj_tptr+offset+4)>>31))); - ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? + ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", + (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? "Transmit" : "Receive", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1)); @@ -710,7 +880,61 @@ lmp_print(netdissect_options *ndo, offset+=8; } break; + case LMP_CTYPE_IPV6: + offset = 0; + /* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */ + while (offset+20 <= obj_tlen) { + ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", + ip6addr_string(ndo, obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset))); + + ND_PRINT((ndo, "\n\t\t Active: %s (%u)", + (EXTRACT_32BITS(obj_tptr+offset+16)>>31) ? + "Allocated" : "Non-allocated", + (EXTRACT_32BITS(obj_tptr+offset+16)>>31))); + + ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", + (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ? + "Transmit" : "Receive", + (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1)); + + ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", + tok2str(lmp_obj_channel_status_values, + "Unknown", + EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF), + EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF)); + offset+=20; + } + break; + + case LMP_CTYPE_UNMD: + offset = 0; + /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */ + while (offset+8 <= obj_tlen) { + ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset))); + + ND_PRINT((ndo, "\n\t\t Active: %s (%u)", + (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? + "Allocated" : "Non-allocated", + (EXTRACT_32BITS(obj_tptr+offset+4)>>31))); + + ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", + (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? + "Transmit" : "Receive", + (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1)); + + ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", + tok2str(lmp_obj_channel_status_values, + "Unknown", + EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), + EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF)); + offset+=8; + } + break; + default: hexdump=TRUE; } @@ -719,16 +943,35 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_CHANNEL_STATUS_REQ: switch(lmp_obj_ctype) { case LMP_CTYPE_IPV4: - case LMP_CTYPE_UNMD: offset = 0; - while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { + while (offset+4 <= obj_tlen) { ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", ipaddr_string(ndo, obj_tptr+offset), EXTRACT_32BITS(obj_tptr+offset))); offset+=4; } break; + case LMP_CTYPE_IPV6: + offset = 0; + while (offset+16 <= obj_tlen) { + ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", + ip6addr_string(ndo, obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset))); + offset+=16; + } + break; + + case LMP_CTYPE_UNMD: + offset = 0; + while (offset+4 <= obj_tlen) { + ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset))); + offset+=4; + } + break; + default: hexdump=TRUE; } @@ -737,6 +980,10 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_ERROR_CODE: switch(lmp_obj_ctype) { case LMP_CTYPE_BEGIN_VERIFY_ERROR: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Error Code: %s", bittok2str(lmp_obj_begin_verify_error_values, "none", @@ -744,6 +991,10 @@ lmp_print(netdissect_options *ndo, break; case LMP_CTYPE_LINK_SUMMARY_ERROR: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Error Code: %s", bittok2str(lmp_obj_link_summary_error_values, "none", @@ -757,51 +1008,60 @@ lmp_print(netdissect_options *ndo, case LMP_OBJ_SERVICE_CONFIG: switch (lmp_obj_ctype) { case LMP_CTYPE_SERVICE_CONFIG_SP: - + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Flags: %s", bittok2str(lmp_obj_service_config_sp_flag_values, "none", - EXTRACT_16BITS(obj_tptr)>>8))); + EXTRACT_8BITS(obj_tptr)))); ND_PRINT((ndo, "\n\t UNI Version: %u", - EXTRACT_16BITS(obj_tptr) & 0x00FF)); + EXTRACT_8BITS(obj_tptr+1))); break; case LMP_CTYPE_SERVICE_CONFIG_CPSA: + if (obj_tlen != 16) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } - link_type = EXTRACT_16BITS(obj_tptr)>>8; + link_type = EXTRACT_8BITS(obj_tptr); ND_PRINT((ndo, "\n\t Link Type: %s (%u)", tok2str(lmp_sd_service_config_cpsa_link_type_values, "Unknown", link_type), link_type)); - if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) { + switch (link_type) { + case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH: ND_PRINT((ndo, "\n\t Signal Type: %s (%u)", tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values, "Unknown", - EXTRACT_16BITS(obj_tptr) & 0x00FF), - EXTRACT_16BITS(obj_tptr) & 0x00FF)); - } + EXTRACT_8BITS(obj_tptr+1)), + EXTRACT_8BITS(obj_tptr+1))); + break; - if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) { + case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET: ND_PRINT((ndo, "\n\t Signal Type: %s (%u)", tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values, "Unknown", - EXTRACT_16BITS(obj_tptr) & 0x00FF), - EXTRACT_16BITS(obj_tptr) & 0x00FF)); + EXTRACT_8BITS(obj_tptr+1)), + EXTRACT_8BITS(obj_tptr+1))); + break; } ND_PRINT((ndo, "\n\t Transparency: %s", bittok2str(lmp_obj_service_config_cpsa_tp_flag_values, "none", - EXTRACT_16BITS(obj_tptr+2)>>8))); + EXTRACT_8BITS(obj_tptr+2)))); ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s", bittok2str(lmp_obj_service_config_cpsa_cct_flag_values, "none", - EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF))); + EXTRACT_8BITS(obj_tptr+3)))); ND_PRINT((ndo, "\n\t Minimum NCC: %u", EXTRACT_16BITS(obj_tptr+4))); @@ -822,6 +1082,10 @@ lmp_print(netdissect_options *ndo, break; case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM: + if (obj_tlen != 8) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Transparency Flags: %s", bittok2str( @@ -833,17 +1097,21 @@ lmp_print(netdissect_options *ndo, bittok2str( lmp_obj_service_config_nsa_tcm_flag_values, "none", - EXTRACT_16BITS(obj_tptr+6) & 0x00FF))); + EXTRACT_8BITS(obj_tptr+7)))); break; case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY: + if (obj_tlen != 4) { + ND_PRINT((ndo, " (not correct for object)")); + break; + } ND_PRINT((ndo, "\n\t Diversity: Flags: %s", bittok2str( lmp_obj_service_config_nsa_network_diversity_flag_values, "none", - EXTRACT_16BITS(obj_tptr+2) & 0x00FF))); + EXTRACT_8BITS(obj_tptr+3)))); break; default: diff --git a/freebsd/contrib/tcpdump/print-lspping.c b/freebsd/contrib/tcpdump/print-lspping.c index eb1cc77d..2972df2a 100644 --- a/freebsd/contrib/tcpdump/print-lspping.c +++ b/freebsd/contrib/tcpdump/print-lspping.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: MPLS LSP PING printer */ @@ -110,6 +110,7 @@ static const struct tok lspping_return_code_values[] = { { 11, "No label entry at stack-depth"}, { 12, "Protocol not associated with interface at FEC stack depth"}, { 13, "Premature termination of ping due to label stack shrinking to a single label"}, + { 0, NULL}, }; diff --git a/freebsd/contrib/tcpdump/print-m3ua.c b/freebsd/contrib/tcpdump/print-m3ua.c index e7d7b300..9e363779 100644 --- a/freebsd/contrib/tcpdump/print-m3ua.c +++ b/freebsd/contrib/tcpdump/print-m3ua.c @@ -73,7 +73,7 @@ static const struct tok MessageClasses[] = { { M3UA_MSGC_SSNM, "SS7" }, { M3UA_MSGC_ASPSM, "ASP" }, { M3UA_MSGC_ASPTM, "ASP" }, - { M3UA_MSGC_RKM, "Routing Key Managment" }, + { M3UA_MSGC_RKM, "Routing Key Management"}, { 0, NULL } }; diff --git a/freebsd/contrib/tcpdump/print-mobility.c b/freebsd/contrib/tcpdump/print-mobility.c index e43dc3f0..57435041 100644 --- a/freebsd/contrib/tcpdump/print-mobility.c +++ b/freebsd/contrib/tcpdump/print-mobility.c @@ -34,6 +34,7 @@ */ /* \summary: IPv6 mobility printer */ +/* RFC 3775 */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -41,11 +42,12 @@ #include <netdissect-stdinc.h> -#include "ip6.h" #include "netdissect.h" #include "addrtoname.h" #include "extract.h" +#include "ip6.h" + static const char tstr[] = "[|MOBILITY]"; /* Mobility header */ @@ -154,6 +156,7 @@ mobility_opt_print(netdissect_options *ndo, goto trunc; } /* units of 4 secs */ + ND_TCHECK_16BITS(&bp[i+2]); ND_PRINT((ndo, "(refresh: %u)", EXTRACT_16BITS(&bp[i+2]) << 2)); break; @@ -162,6 +165,7 @@ mobility_opt_print(netdissect_options *ndo, ND_PRINT((ndo, "(altcoa: trunc)")); goto trunc; } + ND_TCHECK_128BITS(&bp[i+2]); ND_PRINT((ndo, "(alt-CoA: %s)", ip6addr_string(ndo, &bp[i+2]))); break; case IP6MOPT_NONCEID: @@ -169,6 +173,8 @@ mobility_opt_print(netdissect_options *ndo, ND_PRINT((ndo, "(ni: trunc)")); goto trunc; } + ND_TCHECK_16BITS(&bp[i+2]); + ND_TCHECK_16BITS(&bp[i+4]); ND_PRINT((ndo, "(ni: ho=0x%04x co=0x%04x)", EXTRACT_16BITS(&bp[i+2]), EXTRACT_16BITS(&bp[i+4]))); @@ -247,7 +253,7 @@ mobility_print(netdissect_options *ndo, case IP6M_CAREOF_TEST_INIT: hlen = IP6M_MINLEN; if (ndo->ndo_vflag) { - ND_TCHECK2(*mh, hlen + 8); + ND_TCHECK_32BITS(&bp[hlen + 4]); ND_PRINT((ndo, " %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of", EXTRACT_32BITS(&bp[hlen]), @@ -261,7 +267,7 @@ mobility_print(netdissect_options *ndo, ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0]))); hlen = IP6M_MINLEN; if (ndo->ndo_vflag) { - ND_TCHECK2(*mh, hlen + 8); + ND_TCHECK_32BITS(&bp[hlen + 4]); ND_PRINT((ndo, " %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", EXTRACT_32BITS(&bp[hlen]), @@ -269,7 +275,7 @@ mobility_print(netdissect_options *ndo, } hlen += 8; if (ndo->ndo_vflag) { - ND_TCHECK2(*mh, hlen + 8); + ND_TCHECK_32BITS(&bp[hlen + 4]); ND_PRINT((ndo, " %s Keygen Token=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", EXTRACT_32BITS(&bp[hlen]), @@ -281,22 +287,23 @@ mobility_print(netdissect_options *ndo, ND_TCHECK(mh->ip6m_data16[0]); ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0]))); hlen = IP6M_MINLEN; - ND_TCHECK2(*mh, hlen + 1); - if (bp[hlen] & 0xf0) + ND_TCHECK_16BITS(&bp[hlen]); + if (bp[hlen] & 0xf0) { ND_PRINT((ndo, " ")); - if (bp[hlen] & 0x80) - ND_PRINT((ndo, "A")); - if (bp[hlen] & 0x40) - ND_PRINT((ndo, "H")); - if (bp[hlen] & 0x20) - ND_PRINT((ndo, "L")); - if (bp[hlen] & 0x10) - ND_PRINT((ndo, "K")); + if (bp[hlen] & 0x80) + ND_PRINT((ndo, "A")); + if (bp[hlen] & 0x40) + ND_PRINT((ndo, "H")); + if (bp[hlen] & 0x20) + ND_PRINT((ndo, "L")); + if (bp[hlen] & 0x10) + ND_PRINT((ndo, "K")); + } /* Reserved (4bits) */ hlen += 1; /* Reserved (8bits) */ hlen += 1; - ND_TCHECK2(*mh, hlen + 2); + ND_TCHECK_16BITS(&bp[hlen]); /* units of 4 secs */ ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2)); hlen += 2; @@ -304,14 +311,15 @@ mobility_print(netdissect_options *ndo, case IP6M_BINDING_ACK: ND_TCHECK(mh->ip6m_data8[0]); ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); + ND_TCHECK(mh->ip6m_data8[1]); if (mh->ip6m_data8[1] & 0x80) ND_PRINT((ndo, " K")); /* Reserved (7bits) */ hlen = IP6M_MINLEN; - ND_TCHECK2(*mh, hlen + 2); + ND_TCHECK_16BITS(&bp[hlen]); ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&bp[hlen]))); hlen += 2; - ND_TCHECK2(*mh, hlen + 2); + ND_TCHECK_16BITS(&bp[hlen]); /* units of 4 secs */ ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2)); hlen += 2; @@ -321,7 +329,7 @@ mobility_print(netdissect_options *ndo, ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0])); /* Reserved */ hlen = IP6M_MINLEN; - ND_TCHECK2(*mh, hlen + 16); + ND_TCHECK2(bp[hlen], 16); ND_PRINT((ndo, " homeaddr %s", ip6addr_string(ndo, &bp[hlen]))); hlen += 16; break; @@ -338,7 +346,7 @@ mobility_print(netdissect_options *ndo, trunc: ND_PRINT((ndo, "%s", tstr)); - return(mhlen); + return(-1); } #ifdef __rtems__ #include "rtems-bsd-tcpdump-print-mobility-data.h" diff --git a/freebsd/contrib/tcpdump/print-mpcp.c b/freebsd/contrib/tcpdump/print-mpcp.c index 55d1fc63..45b36767 100644 --- a/freebsd/contrib/tcpdump/print-mpcp.c +++ b/freebsd/contrib/tcpdump/print-mpcp.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */ diff --git a/freebsd/contrib/tcpdump/print-mpls.c b/freebsd/contrib/tcpdump/print-mpls.c index a3dadfff..f20f7599 100644 --- a/freebsd/contrib/tcpdump/print-mpls.c +++ b/freebsd/contrib/tcpdump/print-mpls.c @@ -207,7 +207,7 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length) break; case PT_OSI: - isoclns_print(ndo, p, length, length); + isoclns_print(ndo, p, length); break; default: diff --git a/freebsd/contrib/tcpdump/print-mptcp.c b/freebsd/contrib/tcpdump/print-mptcp.c index 54669708..4dcf8129 100644 --- a/freebsd/contrib/tcpdump/print-mptcp.c +++ b/freebsd/contrib/tcpdump/print-mptcp.c @@ -184,7 +184,7 @@ mp_capable_print(netdissect_options *ndo, { const struct mp_capable *mpc = (const struct mp_capable *) opt; - if (!(opt_len == 12 && flags & TH_SYN) && + if (!(opt_len == 12 && (flags & TH_SYN)) && !(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK)) return 0; @@ -208,9 +208,9 @@ mp_join_print(netdissect_options *ndo, { const struct mp_join *mpj = (const struct mp_join *) opt; - if (!(opt_len == 12 && flags & TH_SYN) && + if (!(opt_len == 12 && (flags & TH_SYN)) && !(opt_len == 16 && (flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) && - !(opt_len == 24 && flags & TH_ACK)) + !(opt_len == 24 && (flags & TH_ACK))) return 0; if (opt_len != 24) { @@ -242,76 +242,92 @@ mp_join_print(netdissect_options *ndo, return 1; } -static u_int mp_dss_len(const struct mp_dss *m, int csum) -{ - u_int len; - - len = 4; - if (m->flags & MP_DSS_A) { - /* Ack present - 4 or 8 octets */ - len += (m->flags & MP_DSS_a) ? 8 : 4; - } - if (m->flags & MP_DSS_M) { - /* - * Data Sequence Number (DSN), Subflow Sequence Number (SSN), - * Data-Level Length present, and Checksum possibly present. - * All but the Checksum are 10 bytes if the m flag is - * clear (4-byte DSN) and 14 bytes if the m flag is set - * (8-byte DSN). - */ - len += (m->flags & MP_DSS_m) ? 14 : 10; - - /* - * The Checksum is present only if negotiated. - */ - if (csum) - len += 2; - } - return len; -} - static int mp_dss_print(netdissect_options *ndo, const u_char *opt, u_int opt_len, u_char flags) { const struct mp_dss *mdss = (const struct mp_dss *) opt; - if ((opt_len != mp_dss_len(mdss, 1) && - opt_len != mp_dss_len(mdss, 0)) || flags & TH_SYN) + /* We need the flags, at a minimum. */ + if (opt_len < 4) + return 0; + + if (flags & TH_SYN) return 0; if (mdss->flags & MP_DSS_F) ND_PRINT((ndo, " fin")); opt += 4; + opt_len -= 4; if (mdss->flags & MP_DSS_A) { + /* Ack present */ ND_PRINT((ndo, " ack ")); + /* + * If the a flag is set, we have an 8-byte ack; if it's + * clear, we have a 4-byte ack. + */ if (mdss->flags & MP_DSS_a) { + if (opt_len < 8) + return 0; ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt))); opt += 8; + opt_len -= 8; } else { + if (opt_len < 4) + return 0; ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt))); opt += 4; + opt_len -= 4; } } if (mdss->flags & MP_DSS_M) { + /* + * Data Sequence Number (DSN), Subflow Sequence Number (SSN), + * Data-Level Length present, and Checksum possibly present. + */ ND_PRINT((ndo, " seq ")); + /* + * If the m flag is set, we have an 8-byte NDS; if it's clear, + * we have a 4-byte DSN. + */ if (mdss->flags & MP_DSS_m) { + if (opt_len < 8) + return 0; ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt))); opt += 8; + opt_len -= 8; } else { + if (opt_len < 4) + return 0; ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt))); opt += 4; + opt_len -= 4; } + if (opt_len < 4) + return 0; ND_PRINT((ndo, " subseq %u", EXTRACT_32BITS(opt))); opt += 4; + opt_len -= 4; + if (opt_len < 2) + return 0; ND_PRINT((ndo, " len %u", EXTRACT_16BITS(opt))); opt += 2; + opt_len -= 2; - if (opt_len == mp_dss_len(mdss, 1)) + /* + * The Checksum is present only if negotiated. + * If there are at least 2 bytes left, process the next 2 + * bytes as the Checksum. + */ + if (opt_len >= 2) { ND_PRINT((ndo, " csum 0x%x", EXTRACT_16BITS(opt))); + opt_len -= 2; + } } + if (opt_len != 0) + return 0; return 1; } diff --git a/freebsd/contrib/tcpdump/print-nfs.c b/freebsd/contrib/tcpdump/print-nfs.c index 10de4358..97748dce 100644 --- a/freebsd/contrib/tcpdump/print-nfs.c +++ b/freebsd/contrib/tcpdump/print-nfs.c @@ -634,17 +634,15 @@ nfsreq_print_noaddr(netdissect_options *ndo, if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { - ND_TCHECK(dp[2]); + ND_TCHECK(dp[4]); ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64, EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0]))); if (ndo->ndo_vflag) { - dp += 3; - ND_TCHECK(dp[0]); ND_PRINT((ndo, " <%s>", tok2str(nfsv3_writemodes, - NULL, EXTRACT_32BITS(dp)))); + NULL, EXTRACT_32BITS(&dp[3])))); } } else { ND_TCHECK(dp[3]); @@ -815,11 +813,15 @@ nfs_printfh(netdissect_options *ndo, if (sfsname) { /* file system ID is ASCII, not numeric, for this server OS */ - static char temp[NFSX_V3FHMAX+1]; + char temp[NFSX_V3FHMAX+1]; + u_int stringlen; /* Make sure string is null-terminated */ - strncpy(temp, sfsname, NFSX_V3FHMAX); - temp[sizeof(temp) - 1] = '\0'; + stringlen = len; + if (stringlen > NFSX_V3FHMAX) + stringlen = NFSX_V3FHMAX; + strncpy(temp, sfsname, stringlen); + temp[stringlen] = '\0'; /* Remove trailing spaces */ spacep = strchr(temp, ' '); if (spacep) @@ -874,7 +876,7 @@ xid_map_enter(netdissect_options *ndo, const struct ip6_hdr *ip6 = NULL; struct xid_map_entry *xmep; - if (!ND_TTEST(rp->rm_call.cb_vers)) + if (!ND_TTEST(rp->rm_call.cb_proc)) return (0); switch (IP_V((const struct ip *)bp)) { case 4: @@ -1008,11 +1010,11 @@ parserep(netdissect_options *ndo, * skip past the ar_verf credentials. */ dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t); - ND_TCHECK2(dp[0], 0); /* * now we can check the ar_stat field */ + ND_TCHECK(dp[0]); astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp); if (astat != SUNRPC_SUCCESS) { ND_PRINT((ndo, " %s", tok2str(sunrpc_str, "ar_stat %d", astat))); @@ -1249,6 +1251,7 @@ static const uint32_t * parse_wcc_attr(netdissect_options *ndo, const uint32_t *dp) { + /* Our caller has already checked this */ ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS(&dp[0]))); ND_PRINT((ndo, " mtime %u.%06u ctime %u.%06u", EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]), @@ -1517,8 +1520,10 @@ interp_reply(netdissect_options *ndo, ND_PRINT((ndo, " attr:")); if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) break; - if (!er) + if (!er) { + ND_TCHECK(dp[0]); ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0]))); + } return; case NFSPROC_READLINK: diff --git a/freebsd/contrib/tcpdump/print-null.c b/freebsd/contrib/tcpdump/print-null.c index 9287709d..53aa294f 100644 --- a/freebsd/contrib/tcpdump/print-null.c +++ b/freebsd/contrib/tcpdump/print-null.c @@ -123,7 +123,7 @@ null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char break; case BSD_AFNUM_ISO: - isoclns_print(ndo, p, length, caplen); + isoclns_print(ndo, p, length); break; case BSD_AFNUM_APPLETALK: diff --git a/freebsd/contrib/tcpdump/print-olsr.c b/freebsd/contrib/tcpdump/print-olsr.c index de757a8e..ab53a632 100644 --- a/freebsd/contrib/tcpdump/print-olsr.c +++ b/freebsd/contrib/tcpdump/print-olsr.c @@ -19,7 +19,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler <hannes@juniper.net> + * Original code by Hannes Gredler <hannes@gredler.at> * IPv6 additions by Florian Forster <octo at verplant.org> */ @@ -365,10 +365,9 @@ olsr_print(netdissect_options *ndo, } msgptr; int msg_len_valid = 0; - ND_TCHECK2(*tptr, sizeof(struct olsr_msg4)); - if (is_ipv6) { + ND_TCHECK2(*tptr, sizeof(struct olsr_msg6)); msgptr.v6 = (const struct olsr_msg6 *) tptr; msg_type = msgptr.v6->msg_type; msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); @@ -399,6 +398,7 @@ olsr_print(netdissect_options *ndo, } else /* (!is_ipv6) */ { + ND_TCHECK2(*tptr, sizeof(struct olsr_msg4)); msgptr.v4 = (const struct olsr_msg4 *) tptr; msg_type = msgptr.v4->msg_type; msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); @@ -622,22 +622,25 @@ olsr_print(netdissect_options *ndo, case OLSR_NAMESERVICE_MSG: { - u_int name_entries = EXTRACT_16BITS(msg_data+2); - u_int addr_size = 4; - int name_entries_valid = 0; + u_int name_entries; + u_int addr_size; + int name_entries_valid; u_int i; + if (msg_tlen < 4) + goto trunc; + ND_TCHECK2(*msg_data, 4); + + name_entries = EXTRACT_16BITS(msg_data+2); + addr_size = 4; if (is_ipv6) addr_size = 16; + name_entries_valid = 0; if ((name_entries > 0) && ((name_entries * (4 + addr_size)) <= msg_tlen)) name_entries_valid = 1; - if (msg_tlen < 4) - goto trunc; - ND_TCHECK2(*msg_data, 4); - ND_PRINT((ndo, "\n\t Version %u, Entries %u%s", EXTRACT_16BITS(msg_data), name_entries, (name_entries_valid == 0) ? " (invalid)" : "")); diff --git a/freebsd/contrib/tcpdump/print-ospf6.c b/freebsd/contrib/tcpdump/print-ospf6.c index bd3efe9a..333ac774 100644 --- a/freebsd/contrib/tcpdump/print-ospf6.c +++ b/freebsd/contrib/tcpdump/print-ospf6.c @@ -654,6 +654,7 @@ ospf6_print_lsa(netdissect_options *ndo, if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) return (1); lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); + ND_TCHECK(llsap->llsa_nprefix); prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:", llsap->llsa_priority, @@ -741,6 +742,7 @@ ospf6_decode_v3(netdissect_options *ndo, case OSPF_TYPE_HELLO: { register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); + ND_TCHECK_32BITS(&hellop->hello_options); ND_PRINT((ndo, "\n\tOptions [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&hellop->hello_options)))); @@ -939,10 +941,12 @@ ospf6_decode_v3_trailer(netdissect_options *ndo, if (op->ospf6_type == OSPF_TYPE_HELLO) { const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); + ND_TCHECK(hellop->hello_options); if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L) lls_hello = 1; } else if (op->ospf6_type == OSPF_TYPE_DD) { const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); + ND_TCHECK(ddp->db_options); if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L) lls_dd = 1; } diff --git a/freebsd/contrib/tcpdump/print-pgm.c b/freebsd/contrib/tcpdump/print-pgm.c index e6c2a18f..b9ace2c0 100644 --- a/freebsd/contrib/tcpdump/print-pgm.c +++ b/freebsd/contrib/tcpdump/print-pgm.c @@ -175,13 +175,12 @@ pgm_print(netdissect_options *ndo, ND_PRINT((ndo, "%s > %s: [|pgm]", ip6addr_string(ndo, &ip6->ip6_src), ip6addr_string(ndo, &ip6->ip6_dst))); - return; } else { ND_PRINT((ndo, "%s > %s: [|pgm]", ipaddr_string(ndo, &ip->ip_src), ipaddr_string(ndo, &ip->ip_dst))); - return; } + return; } sport = EXTRACT_16BITS(&pgm->pgm_sport); @@ -368,6 +367,7 @@ pgm_print(netdissect_options *ndo, * and stopping if we don't have enough. */ bp += (2 * sizeof(uint16_t)); + ND_TCHECK_16BITS(bp); switch (EXTRACT_16BITS(bp)) { case AFNUM_INET: ND_TCHECK2(*bp, sizeof(struct in_addr)); @@ -463,6 +463,10 @@ pgm_print(netdissect_options *ndo, ND_PRINT((ndo, "[Total option length leaves no room for final option]")); return; } + if (!ND_TTEST2(*bp, 2)) { + ND_PRINT((ndo, " [|OPT]")); + return; + } opt_type = *bp++; opt_len = *bp++; if (opt_len < PGM_MIN_OPT_LEN) { @@ -481,112 +485,130 @@ pgm_print(netdissect_options *ndo, switch (opt_type & PGM_OPT_MASK) { case PGM_OPT_LENGTH: - if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len)); +#define PGM_OPT_LENGTH_LEN (2+2) + if (opt_len != PGM_OPT_LENGTH_LEN) { + ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != %u]", + opt_len, PGM_OPT_LENGTH_LEN)); return; } ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp))); - bp += sizeof(uint16_t); - opts_len -= 4; + bp += 2; + opts_len -= PGM_OPT_LENGTH_LEN; break; case PGM_OPT_FRAGMENT: - if (opt_len != 16) { - ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len)); +#define PGM_OPT_FRAGMENT_LEN (2+2+4+4+4) + if (opt_len != PGM_OPT_FRAGMENT_LEN) { + ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != %u]", + opt_len, PGM_OPT_FRAGMENT_LEN)); return; } bp += 2; seq = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; offset = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; len = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len)); - opts_len -= 16; + opts_len -= PGM_OPT_FRAGMENT_LEN; break; case PGM_OPT_NAK_LIST: bp += 2; - opt_len -= sizeof(uint32_t); /* option header */ + opt_len -= 4; /* option header */ ND_PRINT((ndo, " NAK LIST")); while (opt_len) { - if (opt_len < sizeof(uint32_t)) { + if (opt_len < 4) { ND_PRINT((ndo, "[Option length not a multiple of 4]")); return; } - ND_TCHECK2(*bp, sizeof(uint32_t)); + ND_TCHECK2(*bp, 4); ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp))); - bp += sizeof(uint32_t); - opt_len -= sizeof(uint32_t); - opts_len -= sizeof(uint32_t); + bp += 4; + opt_len -= 4; + opts_len -= 4; } break; case PGM_OPT_JOIN: - if (opt_len != 8) { - ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len)); +#define PGM_OPT_JOIN_LEN (2+2+4) + if (opt_len != PGM_OPT_JOIN_LEN) { + ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != %u]", + opt_len, PGM_OPT_JOIN_LEN)); return; } bp += 2; seq = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " JOIN %u", seq)); - opts_len -= 8; + opts_len -= PGM_OPT_JOIN_LEN; break; case PGM_OPT_NAK_BO_IVL: - if (opt_len != 12) { - ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len)); +#define PGM_OPT_NAK_BO_IVL_LEN (2+2+4+4) + if (opt_len != PGM_OPT_NAK_BO_IVL_LEN) { + ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != %u]", + opt_len, PGM_OPT_NAK_BO_IVL_LEN)); return; } bp += 2; offset = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; seq = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq)); - opts_len -= 12; + opts_len -= PGM_OPT_NAK_BO_IVL_LEN; break; case PGM_OPT_NAK_BO_RNG: - if (opt_len != 12) { - ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len)); +#define PGM_OPT_NAK_BO_RNG_LEN (2+2+4+4) + if (opt_len != PGM_OPT_NAK_BO_RNG_LEN) { + ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != %u]", + opt_len, PGM_OPT_NAK_BO_RNG_LEN)); return; } bp += 2; offset = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; seq = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq)); - opts_len -= 12; + opts_len -= PGM_OPT_NAK_BO_RNG_LEN; break; case PGM_OPT_REDIRECT: +#define PGM_OPT_REDIRECT_FIXED_LEN (2+2+2+2) + if (opt_len < PGM_OPT_REDIRECT_FIXED_LEN) { + ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u < %u]", + opt_len, PGM_OPT_REDIRECT_FIXED_LEN)); + return; + } bp += 2; nla_afnum = EXTRACT_16BITS(bp); - bp += (2 * sizeof(uint16_t)); + bp += 2+2; switch (nla_afnum) { case AFNUM_INET: - if (opt_len != 4 + sizeof(struct in_addr)) { - ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); + if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr)) { + ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]", + opt_len, PGM_OPT_REDIRECT_FIXED_LEN)); return; } ND_TCHECK2(*bp, sizeof(struct in_addr)); addrtostr(bp, nla_buf, sizeof(nla_buf)); bp += sizeof(struct in_addr); - opts_len -= 4 + sizeof(struct in_addr); + opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr); break; case AFNUM_INET6: - if (opt_len != 4 + sizeof(struct in6_addr)) { - ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); + if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr)) { + ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]", + PGM_OPT_REDIRECT_FIXED_LEN, opt_len)); return; } ND_TCHECK2(*bp, sizeof(struct in6_addr)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); bp += sizeof(struct in6_addr); - opts_len -= 4 + sizeof(struct in6_addr); + opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr); break; default: goto trunc; @@ -597,49 +619,57 @@ pgm_print(netdissect_options *ndo, break; case PGM_OPT_PARITY_PRM: - if (opt_len != 8) { - ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len)); +#define PGM_OPT_PARITY_PRM_LEN (2+2+4) + if (opt_len != PGM_OPT_PARITY_PRM_LEN) { + ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != %u]", + opt_len, PGM_OPT_PARITY_PRM_LEN)); return; } bp += 2; len = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " PARITY MAXTGS %u", len)); - opts_len -= 8; + opts_len -= PGM_OPT_PARITY_PRM_LEN; break; case PGM_OPT_PARITY_GRP: - if (opt_len != 8) { - ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len)); +#define PGM_OPT_PARITY_GRP_LEN (2+2+4) + if (opt_len != PGM_OPT_PARITY_GRP_LEN) { + ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != %u]", + opt_len, PGM_OPT_PARITY_GRP_LEN)); return; } bp += 2; seq = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " PARITY GROUP %u", seq)); - opts_len -= 8; + opts_len -= PGM_OPT_PARITY_GRP_LEN; break; case PGM_OPT_CURR_TGSIZE: - if (opt_len != 8) { - ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len)); +#define PGM_OPT_CURR_TGSIZE_LEN (2+2+4) + if (opt_len != PGM_OPT_CURR_TGSIZE_LEN) { + ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != %u]", + opt_len, PGM_OPT_CURR_TGSIZE_LEN)); return; } bp += 2; len = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; ND_PRINT((ndo, " PARITY ATGS %u", len)); - opts_len -= 8; + opts_len -= PGM_OPT_CURR_TGSIZE_LEN; break; case PGM_OPT_NBR_UNREACH: - if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len)); +#define PGM_OPT_NBR_UNREACH_LEN (2+2) + if (opt_len != PGM_OPT_NBR_UNREACH_LEN) { + ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != %u]", + opt_len, PGM_OPT_NBR_UNREACH_LEN)); return; } bp += 2; ND_PRINT((ndo, " NBR_UNREACH")); - opts_len -= 4; + opts_len -= PGM_OPT_NBR_UNREACH_LEN; break; case PGM_OPT_PATH_NLA: @@ -649,33 +679,39 @@ pgm_print(netdissect_options *ndo, break; case PGM_OPT_SYN: - if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len)); +#define PGM_OPT_SYN_LEN (2+2) + if (opt_len != PGM_OPT_SYN_LEN) { + ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != %u]", + opt_len, PGM_OPT_SYN_LEN)); return; } bp += 2; ND_PRINT((ndo, " SYN")); - opts_len -= 4; + opts_len -= PGM_OPT_SYN_LEN; break; case PGM_OPT_FIN: - if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len)); +#define PGM_OPT_FIN_LEN (2+2) + if (opt_len != PGM_OPT_FIN_LEN) { + ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != %u]", + opt_len, PGM_OPT_FIN_LEN)); return; } bp += 2; ND_PRINT((ndo, " FIN")); - opts_len -= 4; + opts_len -= PGM_OPT_FIN_LEN; break; case PGM_OPT_RST: - if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len)); +#define PGM_OPT_RST_LEN (2+2) + if (opt_len != PGM_OPT_RST_LEN) { + ND_PRINT((ndo, "[Bad OPT_RST option, length %u != %u]", + opt_len, PGM_OPT_RST_LEN)); return; } bp += 2; ND_PRINT((ndo, " RST")); - opts_len -= 4; + opts_len -= PGM_OPT_RST_LEN; break; case PGM_OPT_CR: @@ -685,41 +721,51 @@ pgm_print(netdissect_options *ndo, break; case PGM_OPT_CRQST: - if (opt_len != 4) { - ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len)); +#define PGM_OPT_CRQST_LEN (2+2) + if (opt_len != PGM_OPT_CRQST_LEN) { + ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != %u]", + opt_len, PGM_OPT_CRQST_LEN)); return; } bp += 2; ND_PRINT((ndo, " CRQST")); - opts_len -= 4; + opts_len -= PGM_OPT_CRQST_LEN; break; case PGM_OPT_PGMCC_DATA: +#define PGM_OPT_PGMCC_DATA_FIXED_LEN (2+2+4+2+2) + if (opt_len < PGM_OPT_PGMCC_DATA_FIXED_LEN) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u < %u]", + opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); + return; + } bp += 2; offset = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; nla_afnum = EXTRACT_16BITS(bp); - bp += (2 * sizeof(uint16_t)); + bp += 2+2; switch (nla_afnum) { case AFNUM_INET: - if (opt_len != 12 + sizeof(struct in_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); return; } ND_TCHECK2(*bp, sizeof(struct in_addr)); addrtostr(bp, nla_buf, sizeof(nla_buf)); bp += sizeof(struct in_addr); - opts_len -= 12 + sizeof(struct in_addr); + opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr); break; case AFNUM_INET6: - if (opt_len != 12 + sizeof(struct in6_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); return; } ND_TCHECK2(*bp, sizeof(struct in6_addr)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); bp += sizeof(struct in6_addr); - opts_len -= 12 + sizeof(struct in6_addr); + opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr); break; default: goto trunc; @@ -730,31 +776,39 @@ pgm_print(netdissect_options *ndo, break; case PGM_OPT_PGMCC_FEEDBACK: +#define PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN (2+2+4+2+2) + if (opt_len < PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN) { + ND_PRINT((ndo, "[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]", + opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); + return; + } bp += 2; offset = EXTRACT_32BITS(bp); - bp += sizeof(uint32_t); + bp += 4; nla_afnum = EXTRACT_16BITS(bp); - bp += (2 * sizeof(uint16_t)); + bp += 2+2; switch (nla_afnum) { case AFNUM_INET: - if (opt_len != 12 + sizeof(struct in_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); return; } ND_TCHECK2(*bp, sizeof(struct in_addr)); addrtostr(bp, nla_buf, sizeof(nla_buf)); bp += sizeof(struct in_addr); - opts_len -= 12 + sizeof(struct in_addr); + opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr); break; case AFNUM_INET6: - if (opt_len != 12 + sizeof(struct in6_addr)) { - ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); + if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr)) { + ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", + opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); return; } ND_TCHECK2(*bp, sizeof(struct in6_addr)); addrtostr6(bp, nla_buf, sizeof(nla_buf)); bp += sizeof(struct in6_addr); - opts_len -= 12 + sizeof(struct in6_addr); + opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr); break; default: goto trunc; diff --git a/freebsd/contrib/tcpdump/print-pim.c b/freebsd/contrib/tcpdump/print-pim.c index 1762436a..2fa38842 100644 --- a/freebsd/contrib/tcpdump/print-pim.c +++ b/freebsd/contrib/tcpdump/print-pim.c @@ -175,20 +175,28 @@ pimv1_join_prune_print(netdissect_options *ndo, return; } + if (len < sizeof(struct in_addr)) + goto trunc; ND_TCHECK2(bp[0], sizeof(struct in_addr)); if (ndo->ndo_vflag > 1) ND_PRINT((ndo, "\n")); ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp))); - ND_TCHECK2(bp[6], 2); + bp += 4; + len -= 4; + if (len < 4) + goto trunc; + ND_TCHECK2(bp[2], 2); if (ndo->ndo_vflag > 1) ND_PRINT((ndo, "\n")); ND_PRINT((ndo, " Hold time: ")); - unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[6])); + unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); if (ndo->ndo_vflag < 2) return; - bp += 8; - len -= 8; + bp += 4; + len -= 4; + if (len < 4) + goto trunc; ND_TCHECK2(bp[0], 4); ngroups = bp[3]; bp += 4; @@ -198,17 +206,27 @@ pimv1_join_prune_print(netdissect_options *ndo, * XXX - does the address have length "addrlen" and the * mask length "maddrlen"? */ + if (len < 4) + goto trunc; ND_TCHECK2(bp[0], sizeof(struct in_addr)); ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp))); - ND_TCHECK2(bp[4], sizeof(struct in_addr)); - if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) - ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[4]))); - ND_TCHECK2(bp[8], 4); - njoin = EXTRACT_16BITS(&bp[8]); - nprune = EXTRACT_16BITS(&bp[10]); + bp += 4; + len -= 4; + if (len < 4) + goto trunc; + ND_TCHECK2(bp[0], sizeof(struct in_addr)); + if (EXTRACT_32BITS(&bp[0]) != 0xffffffff) + ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[0]))); + bp += 4; + len -= 4; + if (len < 4) + goto trunc; + ND_TCHECK2(bp[0], 4); + njoin = EXTRACT_16BITS(&bp[0]); + nprune = EXTRACT_16BITS(&bp[2]); ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune)); - bp += 12; - len -= 12; + bp += 4; + len -= 4; for (njp = 0; njp < (njoin + nprune); njp++) { const char *type; @@ -216,12 +234,15 @@ pimv1_join_prune_print(netdissect_options *ndo, type = "Join "; else type = "Prune"; + if (len < 6) + goto trunc; ND_TCHECK2(bp[0], 6); ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type, (bp[0] & 0x01) ? "Sparse " : "Dense ", (bp[1] & 0x80) ? "WC " : "", (bp[1] & 0x40) ? "RP " : "SPT ", - ipaddr_string(ndo, &bp[2]), bp[1] & 0x3f)); + ipaddr_string(ndo, &bp[2]), + bp[1] & 0x3f)); bp += 6; len -= 6; } @@ -236,13 +257,8 @@ void pimv1_print(netdissect_options *ndo, register const u_char *bp, register u_int len) { - register const u_char *ep; register u_char type; - ep = (const u_char *)ndo->ndo_snapend; - if (bp >= ep) - return; - ND_TCHECK(bp[1]); type = bp[1]; @@ -308,10 +324,14 @@ pimv1_print(netdissect_options *ndo, case PIMV1_TYPE_JOIN_PRUNE: case PIMV1_TYPE_GRAFT: case PIMV1_TYPE_GRAFT_ACK: - if (ndo->ndo_vflag) + if (ndo->ndo_vflag) { + if (len < 8) + goto trunc; pimv1_join_prune_print(ndo, &bp[8], len - 8); + } break; } + ND_TCHECK(bp[4]); if ((bp[4] >> 4) != 1) ND_PRINT((ndo, " [v%d]", bp[4] >> 4)); return; @@ -335,6 +355,8 @@ cisco_autorp_print(netdissect_options *ndo, int numrps; int hold; + if (len < 8) + goto trunc; ND_TCHECK(bp[0]); ND_PRINT((ndo, " auto-rp ")); type = bp[0]; @@ -382,10 +404,16 @@ cisco_autorp_print(netdissect_options *ndo, int nentries; char s; + if (len < 4) + goto trunc; ND_TCHECK2(bp[0], 4); ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp))); - ND_TCHECK(bp[4]); - switch (bp[4] & 0x3) { + bp += 4; + len -= 4; + if (len < 1) + goto trunc; + ND_TCHECK(bp[0]); + switch (bp[0] & 0x3) { case 0: ND_PRINT((ndo, " PIMv?")); break; case 1: ND_PRINT((ndo, " PIMv1")); @@ -395,13 +423,20 @@ cisco_autorp_print(netdissect_options *ndo, case 3: ND_PRINT((ndo, " PIMv1+2")); break; } - if (bp[4] & 0xfc) - ND_PRINT((ndo, " [rsvd=0x%02x]", bp[4] & 0xfc)); - ND_TCHECK(bp[5]); - nentries = bp[5]; - bp += 6; len -= 6; + if (bp[0] & 0xfc) + ND_PRINT((ndo, " [rsvd=0x%02x]", bp[0] & 0xfc)); + bp += 1; + len -= 1; + if (len < 1) + goto trunc; + ND_TCHECK(bp[0]); + nentries = bp[0]; + bp += 1; + len -= 1; s = ' '; for (; nentries; nentries--) { + if (len < 6) + goto trunc; ND_TCHECK2(bp[0], 6); ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "", ipaddr_string(ndo, &bp[2]), bp[1])); @@ -426,16 +461,13 @@ void pim_print(netdissect_options *ndo, register const u_char *bp, register u_int len, const u_char *bp2) { - register const u_char *ep; register const struct pim *pim = (const struct pim *)bp; - ep = (const u_char *)ndo->ndo_snapend; - if (bp >= ep) - return; #ifdef notyet /* currently we see only version and type */ ND_TCHECK(pim->pim_rsv); #endif + ND_TCHECK(pim->pim_typever); switch (PIM_VER(pim->pim_typever)) { case 2: if (!ndo->ndo_vflag) { @@ -459,6 +491,10 @@ pim_print(netdissect_options *ndo, break; } return; + +trunc: + ND_PRINT((ndo, "[|pim]")); + return; } /* @@ -501,8 +537,6 @@ pim_print(netdissect_options *ndo, * */ -static int pimv2_addr_len; - enum pimv2_addrtype { pimv2_unicast, pimv2_group, pimv2_source }; @@ -529,23 +563,24 @@ enum pimv2_addrtype { */ static int pimv2_addr_print(netdissect_options *ndo, - const u_char *bp, enum pimv2_addrtype at, int silent) + const u_char *bp, u_int len, enum pimv2_addrtype at, + u_int addr_len, int silent) { int af; - int len, hdrlen; - - ND_TCHECK(bp[0]); + int hdrlen; - if (pimv2_addr_len == 0) { + if (addr_len == 0) { + if (len < 2) + goto trunc; ND_TCHECK(bp[1]); switch (bp[0]) { case 1: af = AF_INET; - len = sizeof(struct in_addr); + addr_len = (u_int)sizeof(struct in_addr); break; case 2: af = AF_INET6; - len = sizeof(struct in6_addr); + addr_len = (u_int)sizeof(struct in6_addr); break; default: return -1; @@ -554,7 +589,7 @@ pimv2_addr_print(netdissect_options *ndo, return -1; hdrlen = 2; } else { - switch (pimv2_addr_len) { + switch (addr_len) { case sizeof(struct in_addr): af = AF_INET; break; @@ -565,14 +600,16 @@ pimv2_addr_print(netdissect_options *ndo, return -1; break; } - len = pimv2_addr_len; hdrlen = 0; } bp += hdrlen; + len -= hdrlen; switch (at) { case pimv2_unicast: - ND_TCHECK2(bp[0], len); + if (len < addr_len) + goto trunc; + ND_TCHECK2(bp[0], addr_len); if (af == AF_INET) { if (!silent) ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp))); @@ -581,10 +618,12 @@ pimv2_addr_print(netdissect_options *ndo, if (!silent) ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp))); } - return hdrlen + len; + return hdrlen + addr_len; case pimv2_group: case pimv2_source: - ND_TCHECK2(bp[0], len + 2); + if (len < addr_len + 2) + goto trunc; + ND_TCHECK2(bp[0], addr_len + 2); if (af == AF_INET) { if (!silent) { ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2))); @@ -613,7 +652,7 @@ pimv2_addr_print(netdissect_options *ndo, ND_PRINT((ndo, ")")); } } - return hdrlen + 2 + len; + return hdrlen + 2 + addr_len; default: return -1; } @@ -661,21 +700,21 @@ static void pimv2_print(netdissect_options *ndo, register const u_char *bp, register u_int len, const u_char *bp2) { - register const u_char *ep; register const struct pim *pim = (const struct pim *)bp; int advance; enum checksum_status cksum_status; + int pimv2_addr_len; - ep = (const u_char *)ndo->ndo_snapend; - if (bp >= ep) - return; - if (ep > bp + len) - ep = bp + len; + if (len < 2) + goto trunc; ND_TCHECK(pim->pim_rsv); pimv2_addr_len = pim->pim_rsv; if (pimv2_addr_len != 0) ND_PRINT((ndo, ", RFC2117-encoding")); + if (len < 4) + goto trunc; + ND_TCHECK(pim->pim_cksum); ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum))); if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { ND_PRINT((ndo, "(unverified)")); @@ -716,26 +755,36 @@ pimv2_print(netdissect_options *ndo, break; } } + bp += 4; + len -= 4; switch (PIM_TYPE(pim->pim_typever)) { case PIMV2_TYPE_HELLO: { uint16_t otype, olen; - bp += 4; - while (bp < ep) { + while (len > 0) { + if (len < 4) + goto trunc; ND_TCHECK2(bp[0], 4); otype = EXTRACT_16BITS(&bp[0]); olen = EXTRACT_16BITS(&bp[2]); - ND_TCHECK2(bp[0], 4 + olen); ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ", tok2str(pimv2_hello_option_values, "Unknown", otype), otype, olen)); bp += 4; + len -= 4; + if (len < olen) + goto trunc; + ND_TCHECK2(bp[0], olen); switch (otype) { case PIMV2_HELLO_OPTION_HOLDTIME: - unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); + if (olen != 2) { + ND_PRINT((ndo, "ERROR: Option Length != 2 Bytes (%u)", olen)); + } else { + unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); + } break; case PIMV2_HELLO_OPTION_LANPRUNEDELAY: @@ -769,17 +818,25 @@ pimv2_print(netdissect_options *ndo, break; case PIMV2_HELLO_OPTION_GENID: - ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp))); + if (olen != 4) { + ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); + } else { + ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp))); + } break; case PIMV2_HELLO_OPTION_REFRESH_CAP: - ND_PRINT((ndo, "v%d", *bp)); - if (*(bp+1) != 0) { - ND_PRINT((ndo, ", interval ")); - unsigned_relts_print(ndo, *(bp+1)); - } - if (EXTRACT_16BITS(bp+2) != 0) { - ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2))); + if (olen != 4) { + ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); + } else { + ND_PRINT((ndo, "v%d", *bp)); + if (*(bp+1) != 0) { + ND_PRINT((ndo, ", interval ")); + unsigned_relts_print(ndo, *(bp+1)); + } + if (EXTRACT_16BITS(bp+2) != 0) { + ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2))); + } } break; @@ -790,14 +847,14 @@ pimv2_print(netdissect_options *ndo, case PIMV2_HELLO_OPTION_ADDRESS_LIST: if (ndo->ndo_vflag > 1) { const u_char *ptr = bp; + u_int plen = len; while (ptr < (bp+olen)) { ND_PRINT((ndo, "\n\t ")); - advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0); - if (advance < 0) { - ND_PRINT((ndo, "...")); - break; - } + advance = pimv2_addr_print(ndo, ptr, plen, pimv2_unicast, pimv2_addr_len, 0); + if (advance < 0) + goto trunc; ptr += advance; + plen -= advance; } } break; @@ -810,6 +867,7 @@ pimv2_print(netdissect_options *ndo, if (ndo->ndo_vflag> 1) print_unknown_data(ndo, bp, "\n\t ", olen); bp += olen; + len -= olen; } break; } @@ -818,18 +876,24 @@ pimv2_print(netdissect_options *ndo, { const struct ip *ip; - ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN); + if (len < 4) + goto trunc; + ND_TCHECK2(*bp, PIMV2_REGISTER_FLAG_LEN); ND_PRINT((ndo, ", Flags [ %s ]\n\t", tok2str(pimv2_register_flag_values, "none", - EXTRACT_32BITS(bp+4)))); + EXTRACT_32BITS(bp)))); - bp += 8; len -= 8; + bp += 4; len -= 4; /* encapsulated multicast packet */ + if (len == 0) + goto trunc; ip = (const struct ip *)bp; + ND_TCHECK(ip->ip_vhl); switch (IP_V(ip)) { case 0: /* Null header */ + ND_TCHECK(ip->ip_dst); ND_PRINT((ndo, "IP-Null-header %s > %s", ipaddr_string(ndo, &ip->ip_src), ipaddr_string(ndo, &ip->ip_dst))); @@ -851,22 +915,13 @@ pimv2_print(netdissect_options *ndo, } case PIMV2_TYPE_REGISTER_STOP: - bp += 4; len -= 4; - if (bp >= ep) - break; ND_PRINT((ndo, " group=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; - if (bp >= ep) - break; ND_PRINT((ndo, " source=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; break; @@ -917,19 +972,15 @@ pimv2_print(netdissect_options *ndo, uint16_t nprune; int i, j; - bp += 4; len -= 4; if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ - if (bp >= ep) - break; ND_PRINT((ndo, ", upstream-neighbor: ")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; } - if (bp + 4 > ep) - break; + if (len < 4) + goto trunc; + ND_TCHECK2(*bp, 4); ngroup = bp[1]; holdtime = EXTRACT_16BITS(&bp[2]); ND_PRINT((ndo, "\n\t %u group(s)", ngroup)); @@ -942,139 +993,125 @@ pimv2_print(netdissect_options *ndo, } bp += 4; len -= 4; for (i = 0; i < ngroup; i++) { - if (bp >= ep) - goto jp_done; ND_PRINT((ndo, "\n\t group #%u: ", i+1)); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { - ND_PRINT((ndo, "...)")); - goto jp_done; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; - if (bp + 4 > ep) { - ND_PRINT((ndo, "...)")); - goto jp_done; - } + if (len < 4) + goto trunc; + ND_TCHECK2(*bp, 4); njoin = EXTRACT_16BITS(&bp[0]); nprune = EXTRACT_16BITS(&bp[2]); ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune)); bp += 4; len -= 4; for (j = 0; j < njoin; j++) { ND_PRINT((ndo, "\n\t joined source #%u: ", j+1)); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) { - ND_PRINT((ndo, "...)")); - goto jp_done; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; } for (j = 0; j < nprune; j++) { ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1)); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) { - ND_PRINT((ndo, "...)")); - goto jp_done; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; } } - jp_done: break; } case PIMV2_TYPE_BOOTSTRAP: { int i, j, frpcnt; - bp += 4; /* Fragment Tag, Hash Mask len, and BSR-priority */ - if (bp + sizeof(uint16_t) >= ep) break; + if (len < 2) + goto trunc; + ND_TCHECK_16BITS(bp); ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp))); - bp += sizeof(uint16_t); - if (bp >= ep) break; + bp += 2; + len -= 2; + if (len < 1) + goto trunc; + ND_TCHECK(bp[0]); ND_PRINT((ndo, " hashmlen=%d", bp[0])); - if (bp + 1 >= ep) break; + if (len < 2) + goto trunc; + ND_TCHECK(bp[2]); ND_PRINT((ndo, " BSRprio=%d", bp[1])); bp += 2; + len -= 2; /* Encoded-Unicast-BSR-Address */ - if (bp >= ep) break; ND_PRINT((ndo, " BSR=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; + len -= advance; - for (i = 0; bp < ep; i++) { + for (i = 0; len > 0; i++) { /* Encoded-Group Address */ ND_PRINT((ndo, " (group%d: ", i)); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) - < 0) { - ND_PRINT((ndo, "...)")); - goto bs_done; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; + len -= advance; /* RP-Count, Frag RP-Cnt, and rsvd */ - if (bp >= ep) { - ND_PRINT((ndo, "...)")); - goto bs_done; - } + if (len < 1) + goto trunc; + ND_TCHECK(bp[0]); ND_PRINT((ndo, " RPcnt=%d", bp[0])); - if (bp + 1 >= ep) { - ND_PRINT((ndo, "...)")); - goto bs_done; - } + if (len < 2) + goto trunc; + ND_TCHECK(bp[1]); ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1])); + if (len < 4) + goto trunc; bp += 4; + len -= 4; - for (j = 0; j < frpcnt && bp < ep; j++) { + for (j = 0; j < frpcnt && len > 0; j++) { /* each RP info */ ND_PRINT((ndo, " RP%d=", j)); - if ((advance = pimv2_addr_print(ndo, bp, + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, - 0)) < 0) { - ND_PRINT((ndo, "...)")); - goto bs_done; - } + pimv2_addr_len, + 0)) < 0) + goto trunc; bp += advance; + len -= advance; - if (bp + 1 >= ep) { - ND_PRINT((ndo, "...)")); - goto bs_done; - } + if (len < 2) + goto trunc; + ND_TCHECK_16BITS(bp); ND_PRINT((ndo, ",holdtime=")); unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); - if (bp + 2 >= ep) { - ND_PRINT((ndo, "...)")); - goto bs_done; - } + if (len < 3) + goto trunc; + ND_TCHECK(bp[2]); ND_PRINT((ndo, ",prio=%d", bp[2])); + if (len < 4) + goto trunc; bp += 4; + len -= 4; } ND_PRINT((ndo, ")")); } - bs_done: break; } case PIMV2_TYPE_ASSERT: - bp += 4; len -= 4; - if (bp >= ep) - break; ND_PRINT((ndo, " group=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; - if (bp >= ep) - break; ND_PRINT((ndo, " src=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; len -= advance; - if (bp + 8 > ep) - break; + if (len < 8) + goto trunc; + ND_TCHECK2(*bp, 8); if (bp[0] & 0x80) ND_PRINT((ndo, " RPT")); ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff)); @@ -1084,61 +1121,62 @@ pimv2_print(netdissect_options *ndo, case PIMV2_TYPE_CANDIDATE_RP: { int i, pfxcnt; - bp += 4; /* Prefix-Cnt, Priority, and Holdtime */ - if (bp >= ep) break; + if (len < 1) + goto trunc; + ND_TCHECK(bp[0]); ND_PRINT((ndo, " prefix-cnt=%d", bp[0])); pfxcnt = bp[0]; - if (bp + 1 >= ep) break; + if (len < 2) + goto trunc; + ND_TCHECK(bp[1]); ND_PRINT((ndo, " prio=%d", bp[1])); - if (bp + 3 >= ep) break; + if (len < 4) + goto trunc; + ND_TCHECK_16BITS(&bp[2]); ND_PRINT((ndo, " holdtime=")); unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); bp += 4; + len -= 4; /* Encoded-Unicast-RP-Address */ - if (bp >= ep) break; ND_PRINT((ndo, " RP=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; + len -= advance; /* Encoded-Group Addresses */ - for (i = 0; i < pfxcnt && bp < ep; i++) { + for (i = 0; i < pfxcnt && len > 0; i++) { ND_PRINT((ndo, " Group%d=", i)); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) - < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; + len -= advance; } break; } case PIMV2_TYPE_PRUNE_REFRESH: ND_PRINT((ndo, " src=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; + len -= advance; ND_PRINT((ndo, " grp=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; + len -= advance; ND_PRINT((ndo, " forwarder=")); - if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { - ND_PRINT((ndo, "...")); - break; - } + if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) + goto trunc; bp += advance; - ND_TCHECK2(bp[0], 2); + len -= advance; + if (len < 2) + goto trunc; + ND_TCHECK_16BITS(bp); ND_PRINT((ndo, " TUNR ")); unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); break; diff --git a/freebsd/contrib/tcpdump/print-pktap.c b/freebsd/contrib/tcpdump/print-pktap.c index 3bccd567..a0d69769 100644 --- a/freebsd/contrib/tcpdump/print-pktap.c +++ b/freebsd/contrib/tcpdump/print-pktap.c @@ -110,6 +110,7 @@ pktap_if_print(netdissect_options *ndo, u_int length = h->len; if_printer printer; const pktap_header_t *hdr; + struct pcap_pkthdr nhdr; if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) { ND_PRINT((ndo, "[|pktap]")); @@ -150,7 +151,10 @@ pktap_if_print(netdissect_options *ndo, case PKT_REC_PACKET: if ((printer = lookup_printer(dlt)) != NULL) { - hdrlen += printer(ndo, h, p); + nhdr = *h; + nhdr.caplen = caplen; + nhdr.len = length; + hdrlen += printer(ndo, &nhdr, p); } else { if (!ndo->ndo_eflag) pktap_header_print(ndo, (const u_char *)hdr, diff --git a/freebsd/contrib/tcpdump/print-ppp.c b/freebsd/contrib/tcpdump/print-ppp.c index ab88944d..724cf72b 100644 --- a/freebsd/contrib/tcpdump/print-ppp.c +++ b/freebsd/contrib/tcpdump/print-ppp.c @@ -617,7 +617,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 6)")); return len; } - ND_TCHECK2(*(p + 2), 3); + ND_TCHECK_24BITS(p + 2); ND_PRINT((ndo, ": Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), EXTRACT_24BITS(p + 2))); @@ -636,7 +636,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return len; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); break; case LCPOPT_ACCM: @@ -644,7 +644,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_32BITS(p + 2); ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); break; case LCPOPT_AP: @@ -652,7 +652,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2)))); switch (EXTRACT_16BITS(p+2)) { @@ -674,7 +674,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p+2); if (EXTRACT_16BITS(p+2) == PPP_LQM) ND_PRINT((ndo, ": LQR")); else @@ -685,7 +685,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return 0; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_32BITS(p + 2); ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); break; case LCPOPT_PFC: @@ -697,7 +697,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2))); break; case LCPOPT_CBACK: @@ -716,7 +716,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); break; case LCPOPT_MLED: @@ -817,6 +817,15 @@ handle_mlppp(netdissect_options *ndo, if (!ndo->ndo_eflag) ND_PRINT((ndo, "MLPPP, ")); + if (length < 2) { + ND_PRINT((ndo, "[|mlppp]")); + return; + } + if (!ND_TTEST_16BITS(p)) { + ND_PRINT((ndo, "[|mlppp]")); + return; + } + ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u", (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */ bittok2str(ppp_ml_flag_values, "none", *p & 0xc0), @@ -1061,7 +1070,7 @@ print_ipcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p+2); compproto = EXTRACT_16BITS(p+2); ND_PRINT((ndo, ": %s (0x%02x):", @@ -1247,7 +1256,7 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 3)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK(p[2]); ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u", p[2] >> 5, p[2] & 0x1f)); break; @@ -1256,7 +1265,7 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK(p[3]); ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u", (p[2] & 0xc0) >> 6, (p[2] & 0x20) ? "Enabled" : "Disabled", @@ -1267,10 +1276,10 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK(p[3]); ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u", (p[2] & 0xf0) >> 4, - ((p[2] & 0x0f) == 8) ? "zlib" : "unkown", + ((p[2] & 0x0f) == 8) ? "zlib" : "unknown", p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03)); break; @@ -1342,7 +1351,7 @@ print_bacp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_32BITS(p + 2); ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2))); break; default: @@ -1490,7 +1499,7 @@ handle_ppp(netdissect_options *ndo, ipx_print(ndo, p, length); break; case PPP_OSI: - isoclns_print(ndo, p, length, length); + isoclns_print(ndo, p, length); break; case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: diff --git a/freebsd/contrib/tcpdump/print-radius.c b/freebsd/contrib/tcpdump/print-radius.c index 56b692ec..2efbfab4 100644 --- a/freebsd/contrib/tcpdump/print-radius.c +++ b/freebsd/contrib/tcpdump/print-radius.c @@ -502,10 +502,7 @@ print_attr_string(netdissect_options *ndo, { case TUNNEL_PASS: if (length < 3) - { - ND_PRINT((ndo, "%s", tstr)); - return; - } + goto trunc; if (*data && (*data <=0x1F) ) ND_PRINT((ndo, "Tag[%u] ", *data)); else @@ -525,10 +522,7 @@ print_attr_string(netdissect_options *ndo, if (*data <= 0x1F) { if (length < 1) - { - ND_PRINT((ndo, "%s", tstr)); - return; - } + goto trunc; if (*data) ND_PRINT((ndo, "Tag[%u] ", *data)); else @@ -538,6 +532,8 @@ print_attr_string(netdissect_options *ndo, } break; case EGRESS_VLAN_NAME: + if (length < 1) + goto trunc; ND_PRINT((ndo, "%s (0x%02x) ", tok2str(rfc4675_tagged,"Unknown tag",*data), *data)); @@ -546,7 +542,7 @@ print_attr_string(netdissect_options *ndo, break; } - for (i=0; *data && i < length ; i++, data++) + for (i=0; i < length && *data; i++, data++) ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); return; diff --git a/freebsd/contrib/tcpdump/print-resp.c b/freebsd/contrib/tcpdump/print-resp.c index bb89e13f..96e80b20 100644 --- a/freebsd/contrib/tcpdump/print-resp.c +++ b/freebsd/contrib/tcpdump/print-resp.c @@ -487,8 +487,10 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con ND_TCHECK(*bp); c = *bp; if (!(c >= '0' && c <= '9')) { - if (!saw_digit) + if (!saw_digit) { + bp++; goto invalid; + } break; } c -= '0'; @@ -497,7 +499,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con too_large = 1; } else { result *= 10; - if (result == INT_MAX && c > (INT_MAX % 10)) { + if (result == ((INT_MAX / 10) * 10) && c > (INT_MAX % 10)) { /* This will overflow an int when we add c */ too_large = 1; } else @@ -507,24 +509,24 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con len--; saw_digit = 1; } - if (!saw_digit) - goto invalid; /* - * OK, the next thing should be \r\n. + * OK, we found a non-digit character. It should be a \r, followed + * by a \n. */ - if (len == 0) - goto trunc; - ND_TCHECK(*bp); - if (*bp != '\r') + if (*bp != '\r') { + bp++; goto invalid; + } bp++; len--; if (len == 0) goto trunc; ND_TCHECK(*bp); - if (*bp != '\n') + if (*bp != '\n') { + bp++; goto invalid; + } bp++; len--; *endp = bp; @@ -537,9 +539,11 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con return (too_large ? -3 : result); trunc: + *endp = bp; return (-2); invalid: + *endp = bp; return (-5); } #ifdef __rtems__ diff --git a/freebsd/contrib/tcpdump/print-ripng.c b/freebsd/contrib/tcpdump/print-ripng.c index 95ec8322..87996c4f 100644 --- a/freebsd/contrib/tcpdump/print-ripng.c +++ b/freebsd/contrib/tcpdump/print-ripng.c @@ -116,67 +116,76 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length) { register const struct rip6 *rp = (const struct rip6 *)dat; register const struct netinfo6 *ni; - register u_int amt; - register u_int i; - int j; - int trunc; - - if (ndo->ndo_snapend < dat) - return; - amt = ndo->ndo_snapend - dat; - i = min(length, amt); - if (i < (sizeof(struct rip6) - sizeof(struct netinfo6))) - return; - i -= (sizeof(struct rip6) - sizeof(struct netinfo6)); + unsigned int length_left; + u_int j; + ND_TCHECK(rp->rip6_cmd); switch (rp->rip6_cmd) { case RIP6_REQUEST: - j = length / sizeof(*ni); - if (j == 1 - && rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6 - && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { - ND_PRINT((ndo, " ripng-req dump")); - break; + length_left = length; + if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6))) + goto trunc; + length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6)); + j = length_left / sizeof(*ni); + if (j == 1) { + ND_TCHECK(rp->rip6_nets); + if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6 + && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { + ND_PRINT((ndo, " ripng-req dump")); + break; + } } - if (j * sizeof(*ni) != length - 4) - ND_PRINT((ndo, " ripng-req %d[%u]:", j, length)); + if (j * sizeof(*ni) != length_left) + ND_PRINT((ndo, " ripng-req %u[%u]:", j, length)); else - ND_PRINT((ndo, " ripng-req %d:", j)); - trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); - for (ni = rp->rip6_nets; i >= sizeof(*ni); - i -= sizeof(*ni), ++ni) { + ND_PRINT((ndo, " ripng-req %u:", j)); + for (ni = rp->rip6_nets; length_left >= sizeof(*ni); + length_left -= sizeof(*ni), ++ni) { + ND_TCHECK(*ni); if (ndo->ndo_vflag > 1) ND_PRINT((ndo, "\n\t")); else ND_PRINT((ndo, " ")); rip6_entry_print(ndo, ni, 0); } + if (length_left != 0) + goto trunc; break; case RIP6_RESPONSE: - j = length / sizeof(*ni); - if (j * sizeof(*ni) != length - 4) + length_left = length; + if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6))) + goto trunc; + length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6)); + j = length_left / sizeof(*ni); + if (j * sizeof(*ni) != length_left) ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length)); else ND_PRINT((ndo, " ripng-resp %d:", j)); - trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); - for (ni = rp->rip6_nets; i >= sizeof(*ni); - i -= sizeof(*ni), ++ni) { + for (ni = rp->rip6_nets; length_left >= sizeof(*ni); + length_left -= sizeof(*ni), ++ni) { + ND_TCHECK(*ni); if (ndo->ndo_vflag > 1) ND_PRINT((ndo, "\n\t")); else ND_PRINT((ndo, " ")); rip6_entry_print(ndo, ni, ni->rip6_metric); } - if (trunc) - ND_PRINT((ndo, "[|ripng]")); + if (length_left != 0) + goto trunc; break; default: ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length)); break; } + ND_TCHECK(rp->rip6_vers); if (rp->rip6_vers != RIP6_VERSION) ND_PRINT((ndo, " [vers %d]", rp->rip6_vers)); + return; + +trunc: + ND_PRINT((ndo, "[|ripng]")); + return; } #ifdef __rtems__ #include "rtems-bsd-tcpdump-print-ripng-data.h" diff --git a/freebsd/contrib/tcpdump/print-rpki-rtr.c b/freebsd/contrib/tcpdump/print-rpki-rtr.c index 17a9a566..e21f67dc 100644 --- a/freebsd/contrib/tcpdump/print-rpki-rtr.c +++ b/freebsd/contrib/tcpdump/print-rpki-rtr.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: Resource Public Key Infrastructure (RPKI) to Router Protocol printer */ @@ -88,6 +88,9 @@ typedef struct rpki_rtr_pdu_ipv6_prefix_ { typedef struct rpki_rtr_pdu_error_report_ { rpki_rtr_pdu pdu_header; u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */ + /* Copy of Erroneous PDU (variable, optional) */ + /* Length of Error Text (4 octets in network byte order) */ + /* Arbitrary Text of Error Diagnostic Message (variable, optional) */ } rpki_rtr_pdu_error_report; /* @@ -177,17 +180,38 @@ indent_string (u_int indent) /* * Print a single PDU. */ -static int -rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) +static u_int +rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len, + const u_char recurse, const u_int indent) { const rpki_rtr_pdu *pdu_header; u_int pdu_type, pdu_len, hexdump; const u_char *msg; + /* Protocol Version */ + ND_TCHECK_8BITS(tptr); + if (*tptr != 0) { + /* Skip the rest of the input buffer because even if this is + * a well-formed PDU of a future RPKI-Router protocol version + * followed by a well-formed PDU of RPKI-Router protocol + * version 0, there is no way to know exactly how to skip the + * current PDU. + */ + ND_PRINT((ndo, "%sRPKI-RTRv%u (unknown)", indent_string(8), *tptr)); + return len; + } + if (len < sizeof(rpki_rtr_pdu)) { + ND_PRINT((ndo, "(%u bytes is too few to decode)", len)); + goto invalid; + } + ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu)); pdu_header = (const rpki_rtr_pdu *)tptr; pdu_type = pdu_header->pdu_type; pdu_len = EXTRACT_32BITS(pdu_header->length); - ND_TCHECK2(*tptr, pdu_len); + /* Do not check bounds with pdu_len yet, do it in the case blocks + * below to make it possible to decode at least the beginning of + * a truncated Error Report PDU or a truncated encapsulated PDU. + */ hexdump = FALSE; ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u", @@ -195,6 +219,8 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) pdu_header->version, tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type), pdu_type, pdu_len)); + if (pdu_len < sizeof(rpki_rtr_pdu) || pdu_len > len) + goto invalid; switch (pdu_type) { @@ -204,6 +230,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) case RPKI_RTR_SERIAL_NOTIFY_PDU: case RPKI_RTR_SERIAL_QUERY_PDU: case RPKI_RTR_END_OF_DATA_PDU: + if (pdu_len != sizeof(rpki_rtr_pdu) + 4) + goto invalid; + ND_TCHECK2(*tptr, pdu_len); msg = (const u_char *)(pdu_header + 1); ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u", indent_string(indent+2), @@ -216,6 +245,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) */ case RPKI_RTR_RESET_QUERY_PDU: case RPKI_RTR_CACHE_RESET_PDU: + if (pdu_len != sizeof(rpki_rtr_pdu)) + goto invalid; + /* no additional boundary to check */ /* * Zero payload PDUs. @@ -223,6 +255,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) break; case RPKI_RTR_CACHE_RESPONSE_PDU: + if (pdu_len != sizeof(rpki_rtr_pdu)) + goto invalid; + /* no additional boundary to check */ ND_PRINT((ndo, "%sSession ID: 0x%04x", indent_string(indent+2), EXTRACT_16BITS(pdu_header->u.session_id))); @@ -232,6 +267,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) { const rpki_rtr_pdu_ipv4_prefix *pdu; + if (pdu_len != sizeof(rpki_rtr_pdu) + 12) + goto invalid; + ND_TCHECK2(*tptr, pdu_len); pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr; ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", indent_string(indent+2), @@ -245,6 +283,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) { const rpki_rtr_pdu_ipv6_prefix *pdu; + if (pdu_len != sizeof(rpki_rtr_pdu) + 24) + goto invalid; + ND_TCHECK2(*tptr, pdu_len); pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr; ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", indent_string(indent+2), @@ -259,10 +300,17 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) const rpki_rtr_pdu_error_report *pdu; u_int encapsulated_pdu_length, text_length, tlen, error_code; + tlen = sizeof(rpki_rtr_pdu); + /* Do not test for the "Length of Error Text" data element yet. */ + if (pdu_len < tlen + 4) + goto invalid; + ND_TCHECK2(*tptr, tlen + 4); + /* Safe up to and including the "Length of Encapsulated PDU" + * data element, more data elements may be present. + */ pdu = (const rpki_rtr_pdu_error_report *)tptr; encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length); - ND_TCHECK2(*tptr, encapsulated_pdu_length); - tlen = pdu_len; + tlen += 4; error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code); ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u", @@ -270,41 +318,58 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) tok2str(rpki_rtr_error_codes, "Unknown", error_code), error_code, encapsulated_pdu_length)); - tptr += sizeof(*pdu); - tlen -= sizeof(*pdu); - - /* - * Recurse if there is an encapsulated PDU. - */ - if (encapsulated_pdu_length && - (encapsulated_pdu_length <= tlen)) { - ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4))); - if (rpki_rtr_pdu_print(ndo, tptr, indent+2)) - goto trunc; + if (encapsulated_pdu_length) { + /* Section 5.10 of RFC 6810 says: + * "An Error Report PDU MUST NOT be sent for an Error Report PDU." + * + * However, as far as the protocol encoding goes Error Report PDUs can + * happen to be nested in each other, however many times, in which case + * the decoder should still print such semantically incorrect PDUs. + * + * That said, "the Erroneous PDU field MAY be truncated" (ibid), thus + * to keep things simple this implementation decodes only the two + * outermost layers of PDUs and makes bounds checks in the outer and + * the inner PDU independently. + */ + if (pdu_len < tlen + encapsulated_pdu_length) + goto invalid; + if (! recurse) { + ND_TCHECK2(*tptr, tlen + encapsulated_pdu_length); + } + else { + ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4))); + rpki_rtr_pdu_print(ndo, tptr + tlen, + encapsulated_pdu_length, 0, indent + 2); + } + tlen += encapsulated_pdu_length; } - tptr += encapsulated_pdu_length; - tlen -= encapsulated_pdu_length; + if (pdu_len < tlen + 4) + goto invalid; + ND_TCHECK2(*tptr, tlen + 4); + /* Safe up to and including the "Length of Error Text" data element, + * one more data element may be present. + */ /* * Extract, trail-zero and print the Error message. */ - text_length = 0; - if (tlen > 4) { - text_length = EXTRACT_32BITS(tptr); - tptr += 4; - tlen -= 4; - } - ND_TCHECK2(*tptr, text_length); - if (text_length && (text_length <= tlen )) { + text_length = EXTRACT_32BITS(tptr + tlen); + tlen += 4; + + if (text_length) { + if (pdu_len < tlen + text_length) + goto invalid; + /* fn_printn() makes the bounds check */ ND_PRINT((ndo, "%sError text: ", indent_string(indent+2))); - if (fn_printn(ndo, tptr, text_length, ndo->ndo_snapend)) + if (fn_printn(ndo, tptr + tlen, text_length, ndo->ndo_snapend)) goto trunc; } } break; default: + ND_TCHECK2(*tptr, pdu_len); /* * Unknown data, please hexdump. @@ -316,57 +381,29 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent) if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) { print_unknown_data(ndo,tptr,"\n\t ", pdu_len); } - return 0; + return pdu_len; +invalid: + ND_PRINT((ndo, "%s", istr)); + ND_TCHECK2(*tptr, len); + return len; trunc: - return 1; + ND_PRINT((ndo, "\n\t%s", tstr)); + return len; } void rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) { - u_int tlen, pdu_type, pdu_len; - const u_char *tptr; - const rpki_rtr_pdu *pdu_header; - - tptr = pptr; - tlen = len; - if (!ndo->ndo_vflag) { ND_PRINT((ndo, ", RPKI-RTR")); return; } - - while (tlen >= sizeof(rpki_rtr_pdu)) { - - ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu)); - - pdu_header = (const rpki_rtr_pdu *)tptr; - pdu_type = pdu_header->pdu_type; - pdu_len = EXTRACT_32BITS(pdu_header->length); - ND_TCHECK2(*tptr, pdu_len); - - /* infinite loop check */ - if (!pdu_type || !pdu_len) { - break; - } - - if (tlen < pdu_len) { - goto trunc; - } - - /* - * Print the PDU. - */ - if (rpki_rtr_pdu_print(ndo, tptr, 8)) - goto trunc; - - tlen -= pdu_len; - tptr += pdu_len; + while (len) { + u_int pdu_len = rpki_rtr_pdu_print(ndo, pptr, len, 1, 8); + len -= pdu_len; + pptr += pdu_len; } - return; -trunc: - ND_PRINT((ndo, "\n\t%s", tstr)); } /* diff --git a/freebsd/contrib/tcpdump/print-rsvp.c b/freebsd/contrib/tcpdump/print-rsvp.c index 727f2db1..102757d0 100644 --- a/freebsd/contrib/tcpdump/print-rsvp.c +++ b/freebsd/contrib/tcpdump/print-rsvp.c @@ -18,7 +18,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: Resource ReSerVation Protocol (RSVP) printer */ @@ -1211,6 +1211,17 @@ rsvp_obj_print(netdissect_options *ndo, /* read variable length subobjects */ total_subobj_len = obj_tlen; while(total_subobj_len > 0) { + /* If RFC 3476 Section 3.1 defined that a sub-object of the + * GENERALIZED_UNI RSVP object must have the Length field as + * a multiple of 4, instead of the check below it would be + * better to test total_subobj_len only once before the loop. + * So long as it does not define it and this while loop does + * not implement such a requirement, let's accept that within + * each iteration subobj_len may happen to be a multiple of 1 + * and test it and total_subobj_len respectively. + */ + if (total_subobj_len < 4) + goto invalid; subobj_len = EXTRACT_16BITS(obj_tptr); subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8; af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF; @@ -1222,7 +1233,13 @@ rsvp_obj_print(netdissect_options *ndo, tok2str(af_values, "Unknown", af), af, subobj_len)); - if(subobj_len == 0) + /* In addition to what is explained above, the same spec does not + * explicitly say that the same Length field includes the 4-octet + * sub-object header, but as long as this while loop implements it + * as it does include, let's keep the check below consistent with + * the rest of the code. + */ + if(subobj_len < 4 || subobj_len > total_subobj_len) goto invalid; switch(subobj_type) { @@ -1478,12 +1495,12 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_OBJ_FASTREROUTE: /* the differences between c-type 1 and 7 are minor */ obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr; - bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); switch(rsvp_obj_ctype) { case RSVP_CTYPE_1: /* new style */ if (obj_tlen < sizeof(struct rsvp_obj_frr_t)) return-1; + bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", ident, (int)obj_ptr.rsvp_obj_frr->setup_prio, @@ -1502,6 +1519,7 @@ rsvp_obj_print(netdissect_options *ndo, case RSVP_CTYPE_TUNNEL_IPV4: /* old style */ if (obj_tlen < 16) return-1; + bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", ident, (int)obj_ptr.rsvp_obj_frr->setup_prio, diff --git a/freebsd/contrib/tcpdump/print-rt6.c b/freebsd/contrib/tcpdump/print-rt6.c index 5ab86c6c..09784ab9 100644 --- a/freebsd/contrib/tcpdump/print-rt6.c +++ b/freebsd/contrib/tcpdump/print-rt6.c @@ -35,12 +35,12 @@ #include <string.h> -#include "ip6.h" - #include "netdissect.h" #include "addrtoname.h" #include "extract.h" +#include "ip6.h" + int rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 _U_) { @@ -51,13 +51,13 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 register const struct in6_addr *addr; dp = (const struct ip6_rthdr *)bp; - len = dp->ip6r_len; /* 'ep' points to the end of available data. */ ep = ndo->ndo_snapend; ND_TCHECK(dp->ip6r_segleft); + len = dp->ip6r_len; ND_PRINT((ndo, "srcrt (len=%d", dp->ip6r_len)); /*)*/ ND_PRINT((ndo, ", type=%d", dp->ip6r_type)); ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft)); @@ -68,7 +68,7 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 dp0 = (const struct ip6_rthdr0 *)dp; ND_TCHECK(dp0->ip6r0_reserved); - if (dp0->ip6r0_reserved || ndo->ndo_vflag) { + if (EXTRACT_32BITS(dp0->ip6r0_reserved) || ndo->ndo_vflag) { ND_PRINT((ndo, ", rsv=0x%0x", EXTRACT_32BITS(&dp0->ip6r0_reserved))); } diff --git a/freebsd/contrib/tcpdump/print-rx.c b/freebsd/contrib/tcpdump/print-rx.c index 46342c2e..e7e369bf 100644 --- a/freebsd/contrib/tcpdump/print-rx.c +++ b/freebsd/contrib/tcpdump/print-rx.c @@ -81,12 +81,12 @@ #define PRSFS_ADMINISTER 64 /* Change ACL's */ struct rx_header { - uint32_t epoch; - uint32_t cid; - uint32_t callNumber; - uint32_t seq; - uint32_t serial; - uint8_t type; + nd_uint32_t epoch; + nd_uint32_t cid; + nd_uint32_t callNumber; + nd_uint32_t seq; + nd_uint32_t serial; + nd_uint8_t type; #define RX_PACKET_TYPE_DATA 1 #define RX_PACKET_TYPE_ACK 2 #define RX_PACKET_TYPE_BUSY 3 @@ -97,7 +97,7 @@ struct rx_header { #define RX_PACKET_TYPE_DEBUG 8 #define RX_PACKET_TYPE_PARAMS 9 #define RX_PACKET_TYPE_VERSION 13 - uint8_t flags; + nd_uint8_t flags; #define RX_CLIENT_INITIATED 1 #define RX_REQUEST_ACK 2 #define RX_LAST_PACKET 4 @@ -105,10 +105,10 @@ struct rx_header { #define RX_FREE_PACKET 16 #define RX_SLOW_START_OK 32 #define RX_JUMBO_PACKET 32 - uint8_t userStatus; - uint8_t securityIndex; - uint16_t spare; /* How clever: even though the AFS */ - uint16_t serviceId; /* header files indicate that the */ + nd_uint8_t userStatus; + nd_uint8_t securityIndex; + nd_uint16_t spare; /* How clever: even though the AFS */ + nd_uint16_t serviceId; /* header files indicate that the */ }; /* serviceId is first, it's really */ /* encoded _after_ the spare field */ /* I wasted a day figuring that out! */ @@ -696,11 +696,11 @@ rx_cache_insert(netdissect_options *ndo, if (++rx_cache_next >= RX_CACHE_SIZE) rx_cache_next = 0; - rxent->callnum = rxh->callNumber; + rxent->callnum = EXTRACT_32BITS(&rxh->callNumber); UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t)); UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t)); rxent->dport = dport; - rxent->serviceId = rxh->serviceId; + rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId); rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); } @@ -728,10 +728,10 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, i = rx_cache_hint; do { rxent = &rx_cache[i]; - if (rxent->callnum == rxh->callNumber && + if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) && rxent->client.s_addr == clip && rxent->server.s_addr == sip && - rxent->serviceId == rxh->serviceId && + rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) && rxent->dport == sport) { /* We got a match! */ @@ -1268,6 +1268,7 @@ cb_print(netdissect_options *ndo, if (j == 0) ND_PRINT((ndo, " <none!>")); + ND_TCHECK_32BITS(bp); j = EXTRACT_32BITS(bp); bp += sizeof(int32_t); @@ -2539,6 +2540,10 @@ ubik_print(netdissect_options *ndo, * gleaned from ubik/ubik_int.xg */ + /* Every function that calls this function first makes a bounds check + * for (sizeof(rx_header) + 4) bytes, so long as it remains this way + * the line below will not over-read. + */ ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op))); @@ -2583,6 +2588,7 @@ ubik_print(netdissect_options *ndo, INTOUT(); ND_PRINT((ndo, " length")); INTOUT(); + ND_TCHECK_32BITS(bp); temp = EXTRACT_32BITS(bp); bp += sizeof(int32_t); tok2str(ubik_lock_types, "type %d", temp); diff --git a/freebsd/contrib/tcpdump/print-sip.c b/freebsd/contrib/tcpdump/print-sip.c index 6f968bca..a922d87a 100644 --- a/freebsd/contrib/tcpdump/print-sip.c +++ b/freebsd/contrib/tcpdump/print-sip.c @@ -16,7 +16,7 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) * Turned into common "text protocol" code, which this uses, by * Guy Harris. */ diff --git a/freebsd/contrib/tcpdump/print-sl.c b/freebsd/contrib/tcpdump/print-sl.c index b318f322..faaa5ba7 100644 --- a/freebsd/contrib/tcpdump/print-sl.c +++ b/freebsd/contrib/tcpdump/print-sl.c @@ -137,8 +137,21 @@ sliplink_print(netdissect_options *ndo, u_int hlen; dir = p[SLX_DIR]; - ND_PRINT((ndo, dir == SLIPDIR_IN ? "I " : "O ")); + switch (dir) { + case SLIPDIR_IN: + ND_PRINT((ndo, "I ")); + break; + + case SLIPDIR_OUT: + ND_PRINT((ndo, "O ")); + break; + + default: + ND_PRINT((ndo, "Invalid direction %d ", dir)); + dir = -1; + break; + } if (ndo->ndo_nflag) { /* XXX just dump the header */ register int i; @@ -161,13 +174,21 @@ sliplink_print(netdissect_options *ndo, * has restored the IP header copy to IPPROTO_TCP. */ lastconn = ((const struct ip *)&p[SLX_CHDR])->ip_p; + ND_PRINT((ndo, "utcp %d: ", lastconn)); + if (dir == -1) { + /* Direction is bogus, don't use it */ + return; + } hlen = IP_HL(ip); hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]); lastlen[dir][lastconn] = length - (hlen << 2); - ND_PRINT((ndo, "utcp %d: ", lastconn)); break; default: + if (dir == -1) { + /* Direction is bogus, don't use it */ + return; + } if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { compressed_sl_print(ndo, &p[SLX_CHDR], ip, length, dir); diff --git a/freebsd/contrib/tcpdump/print-slow.c b/freebsd/contrib/tcpdump/print-slow.c index fe54052f..a5417c0b 100644 --- a/freebsd/contrib/tcpdump/print-slow.c +++ b/freebsd/contrib/tcpdump/print-slow.c @@ -21,7 +21,7 @@ * support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad * OAM as per 802.3ah * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* \summary: IEEE "slow protocols" (802.3ad/802.3ah) printer */ diff --git a/freebsd/contrib/tcpdump/print-stp.c b/freebsd/contrib/tcpdump/print-stp.c index e816cf98..ef7f36c8 100644 --- a/freebsd/contrib/tcpdump/print-stp.c +++ b/freebsd/contrib/tcpdump/print-stp.c @@ -262,6 +262,7 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu, return 1; } + ND_TCHECK(stp_bpdu->flags); ND_PRINT((ndo, "\n\tport-role %s, ", tok2str(rstp_obj_port_role_values, "Unknown", RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)))); @@ -481,6 +482,7 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length) if (stp_bpdu->protocol_version == STP_PROTO_SPB) { /* Validate v4 length */ + ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len); spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len); spb_len += 2; if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) || diff --git a/freebsd/contrib/tcpdump/print-syslog.c b/freebsd/contrib/tcpdump/print-syslog.c index a79a1660..81140339 100644 --- a/freebsd/contrib/tcpdump/print-syslog.c +++ b/freebsd/contrib/tcpdump/print-syslog.c @@ -5,7 +5,7 @@ #include "rtems-bsd-tcpdump-namespace.h" #endif /* __rtems__ */ /* - * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org> + * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at> * The TCPDUMP project * * Redistribution and use in source and binary forms, with or without diff --git a/freebsd/contrib/tcpdump/print-telnet.c b/freebsd/contrib/tcpdump/print-telnet.c index 4d5ab780..5d1e52cd 100644 --- a/freebsd/contrib/tcpdump/print-telnet.c +++ b/freebsd/contrib/tcpdump/print-telnet.c @@ -448,6 +448,7 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print) break; p++; } + ND_TCHECK(*p); if (*p != IAC) goto pktend; diff --git a/freebsd/contrib/tcpdump/print-tftp.c b/freebsd/contrib/tcpdump/print-tftp.c index a2577e3f..bf4ac34e 100644 --- a/freebsd/contrib/tcpdump/print-tftp.c +++ b/freebsd/contrib/tcpdump/print-tftp.c @@ -52,21 +52,6 @@ #define TFTP_ERROR 05 /* error code */ #define OACK 06 /* option acknowledgement */ -struct tftphdr { - unsigned short th_opcode; /* packet type */ - union { - unsigned short tu_block; /* block # */ - unsigned short tu_code; /* error code */ - char tu_stuff[1]; /* request packet stuff */ - } th_u; - char th_data[1]; /* data or error string */ -}; - -#define th_block th_u.tu_block -#define th_code th_u.tu_code -#define th_stuff th_u.tu_stuff -#define th_msg th_data - /* * Error codes. */ @@ -112,80 +97,75 @@ void tftp_print(netdissect_options *ndo, register const u_char *bp, u_int length) { - register const struct tftphdr *tp; register const char *cp; - register const u_char *p; register int opcode; u_int ui; - tp = (const struct tftphdr *)bp; - /* Print length */ ND_PRINT((ndo, " %d", length)); /* Print tftp request type */ if (length < 2) goto trunc; - ND_TCHECK(tp->th_opcode); - opcode = EXTRACT_16BITS(&tp->th_opcode); + ND_TCHECK_16BITS(bp); + opcode = EXTRACT_16BITS(bp); cp = tok2str(op2str, "tftp-#%d", opcode); - length -= 2; ND_PRINT((ndo, " %s", cp)); /* Bail if bogus opcode */ if (*cp == 't') return; + bp += 2; + length -= 2; switch (opcode) { case RRQ: case WRQ: - p = (const u_char *)tp->th_stuff; if (length == 0) goto trunc; ND_PRINT((ndo, " ")); /* Print filename */ ND_PRINT((ndo, "\"")); - ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); ND_PRINT((ndo, "\"")); if (ui == 0) goto trunc; - p += ui; + bp += ui; length -= ui; /* Print the mode - RRQ and WRQ only */ if (length == 0) goto trunc; /* no mode */ ND_PRINT((ndo, " ")); - ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); if (ui == 0) goto trunc; - p += ui; + bp += ui; length -= ui; /* Print options, if any */ while (length != 0) { - ND_TCHECK(*p); - if (*p != '\0') + ND_TCHECK(*bp); + if (*bp != '\0') ND_PRINT((ndo, " ")); - ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); if (ui == 0) goto trunc; - p += ui; + bp += ui; length -= ui; } break; case OACK: - p = (const u_char *)tp->th_stuff; /* Print options */ while (length != 0) { - ND_TCHECK(*p); - if (*p != '\0') + ND_TCHECK(*bp); + if (*bp != '\0') ND_PRINT((ndo, " ")); - ui = fn_printztn(ndo, p, length, ndo->ndo_snapend); + ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); if (ui == 0) goto trunc; - p += ui; + bp += ui; length -= ui; } break; @@ -194,23 +174,24 @@ tftp_print(netdissect_options *ndo, case DATA: if (length < 2) goto trunc; /* no block number */ - ND_TCHECK(tp->th_block); - ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block))); + ND_TCHECK_16BITS(bp); + ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp))); break; case TFTP_ERROR: /* Print error code string */ if (length < 2) goto trunc; /* no error code */ - ND_TCHECK(tp->th_code); + ND_TCHECK_16BITS(bp); ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"", - EXTRACT_16BITS(&tp->th_code)))); + EXTRACT_16BITS(bp)))); + bp += 2; length -= 2; /* Print error message string */ if (length == 0) goto trunc; /* no error message */ ND_PRINT((ndo, " \"")); - ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend); + ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend); ND_PRINT((ndo, "\"")); if (ui == 0) goto trunc; diff --git a/freebsd/contrib/tcpdump/print-vqp.c b/freebsd/contrib/tcpdump/print-vqp.c index 7c4e40da..5a7ca2d1 100644 --- a/freebsd/contrib/tcpdump/print-vqp.c +++ b/freebsd/contrib/tcpdump/print-vqp.c @@ -32,6 +32,7 @@ #include "netdissect.h" #include "extract.h" #include "addrtoname.h" +#include "ether.h" #define VQP_VERSION 1 #define VQP_EXTRACT_VERSION(x) ((x)&0xFF) @@ -111,13 +112,15 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l const u_char *tptr; uint16_t vqp_obj_len; uint32_t vqp_obj_type; - int tlen; + u_int tlen; uint8_t nitems; tptr=pptr; tlen = len; vqp_common_header = (const struct vqp_common_header_t *)pptr; ND_TCHECK(*vqp_common_header); + if (sizeof(struct vqp_common_header_t) > tlen) + goto trunc; /* * Sanity checking of the header. @@ -157,6 +160,9 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l while (nitems > 0 && tlen > 0) { vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr; + ND_TCHECK(*vqp_obj_tlv); + if (sizeof(struct vqp_obj_tlv_t) > tlen) + goto trunc; vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type); vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length); tptr+=sizeof(struct vqp_obj_tlv_t); @@ -173,9 +179,13 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l /* did we capture enough for fully decoding the object ? */ ND_TCHECK2(*tptr, vqp_obj_len); + if (vqp_obj_len > tlen) + goto trunc; switch(vqp_obj_type) { case VQP_OBJ_IP_ADDRESS: + if (vqp_obj_len != 4) + goto trunc; ND_PRINT((ndo, "%s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr))); break; /* those objects have similar semantics - fall through */ @@ -188,6 +198,8 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l /* those objects have similar semantics - fall through */ case VQP_OBJ_MAC_ADDRESS: case VQP_OBJ_MAC_NULL: + if (vqp_obj_len != ETHER_ADDR_LEN) + goto trunc; ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr))); break; default: diff --git a/freebsd/contrib/tcpdump/print-vtp.c b/freebsd/contrib/tcpdump/print-vtp.c index 18e2d925..8f8d236b 100644 --- a/freebsd/contrib/tcpdump/print-vtp.c +++ b/freebsd/contrib/tcpdump/print-vtp.c @@ -19,9 +19,8 @@ * FOR A PARTICULAR PURPOSE. * * Reference documentation: - * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml - * http://www.cisco.com/warp/public/473/21.html - * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * http://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html + * http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm * * Original code ode by Carles Kishimoto <carles.kishimoto@gmail.com> */ @@ -42,7 +41,7 @@ #define VTP_DOMAIN_NAME_LEN 32 #define VTP_MD5_DIGEST_LEN 16 #define VTP_UPDATE_TIMESTAMP_LEN 12 -#define VTP_VLAN_INFO_OFFSET 12 +#define VTP_VLAN_INFO_FIXED_PART_LEN 12 /* length of VLAN info before VLAN name */ #define VTP_SUMMARY_ADV 0x01 #define VTP_SUBSET_ADV 0x02 @@ -229,6 +228,7 @@ vtp_print (netdissect_options *ndo, * */ + ND_TCHECK_32BITS(tptr); ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr))); /* @@ -249,6 +249,7 @@ vtp_print (netdissect_options *ndo, tptr += 4; while (tptr < (pptr+length)) { + ND_TCHECK_8BITS(tptr); len = *tptr; if (len == 0) break; @@ -256,6 +257,8 @@ vtp_print (netdissect_options *ndo, ND_TCHECK2(*tptr, len); vtp_vlan = (const struct vtp_vlan_*)tptr; + if (len < VTP_VLAN_INFO_FIXED_PART_LEN) + goto trunc; ND_TCHECK(*vtp_vlan); ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ", tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status), @@ -263,22 +266,33 @@ vtp_print (netdissect_options *ndo, EXTRACT_16BITS(&vtp_vlan->vlanid), EXTRACT_16BITS(&vtp_vlan->mtu), EXTRACT_32BITS(&vtp_vlan->index))); - fn_printzp(ndo, tptr + VTP_VLAN_INFO_OFFSET, vtp_vlan->name_len, NULL); - - /* - * Vlan names are aligned to 32-bit boundaries. - */ - len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); - tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); + len -= VTP_VLAN_INFO_FIXED_PART_LEN; + tptr += VTP_VLAN_INFO_FIXED_PART_LEN; + if (len < 4*((vtp_vlan->name_len + 3)/4)) + goto trunc; + ND_TCHECK2(*tptr, vtp_vlan->name_len); + fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL); + + /* + * Vlan names are aligned to 32-bit boundaries. + */ + len -= 4*((vtp_vlan->name_len + 3)/4); + tptr += 4*((vtp_vlan->name_len + 3)/4); /* TLV information follows */ while (len > 0) { /* - * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1 - * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * Cisco specs say 2 bytes for type + 2 bytes for length; + * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * However, actual packets on the wire appear to use 1 + * byte for the type and 1 byte for the length, so that's + * what we do. */ + if (len < 2) + goto trunc; + ND_TCHECK2(*tptr, 2); type = *tptr; tlv_len = *(tptr+1); @@ -286,59 +300,65 @@ vtp_print (netdissect_options *ndo, tok2str(vtp_vlan_tlv_values, "Unknown", type), type)); - /* - * infinite loop check - */ - if (type == 0 || tlv_len == 0) { + if (len < tlv_len * 2 + 2) { + ND_PRINT((ndo, " (TLV goes past the end of the packet)")); return; } - ND_TCHECK2(*tptr, tlv_len * 2 +2); - tlv_value = EXTRACT_16BITS(tptr+2); - - switch (type) { - case VTP_VLAN_STE_HOP_COUNT: - ND_PRINT((ndo, ", %u", tlv_value)); - break; - - case VTP_VLAN_PRUNING: - ND_PRINT((ndo, ", %s (%u)", - tlv_value == 1 ? "Enabled" : "Disabled", - tlv_value)); - break; - - case VTP_VLAN_STP_TYPE: - ND_PRINT((ndo, ", %s (%u)", - tok2str(vtp_stp_type_values, "Unknown", tlv_value), - tlv_value)); - break; - - case VTP_VLAN_BRIDGE_TYPE: - ND_PRINT((ndo, ", %s (%u)", - tlv_value == 1 ? "SRB" : "SRT", - tlv_value)); - break; - - case VTP_VLAN_BACKUP_CRF_MODE: - ND_PRINT((ndo, ", %s (%u)", - tlv_value == 1 ? "Backup" : "Not backup", - tlv_value)); - break; - - /* - * FIXME those are the defined TLVs that lack a decoder - * you are welcome to contribute code ;-) - */ - - case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER: - case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER: - case VTP_VLAN_PARENT_VLAN: - case VTP_VLAN_TRANS_BRIDGED_VLAN: - case VTP_VLAN_ARP_HOP_COUNT: - default: - print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2); - break; + /* + * We assume the value is a 2-byte integer; the length is + * in units of 16-bit words. + */ + if (tlv_len != 1) { + ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len)); + return; + } else { + tlv_value = EXTRACT_16BITS(tptr+2); + + switch (type) { + case VTP_VLAN_STE_HOP_COUNT: + ND_PRINT((ndo, ", %u", tlv_value)); + break; + + case VTP_VLAN_PRUNING: + ND_PRINT((ndo, ", %s (%u)", + tlv_value == 1 ? "Enabled" : "Disabled", + tlv_value)); + break; + + case VTP_VLAN_STP_TYPE: + ND_PRINT((ndo, ", %s (%u)", + tok2str(vtp_stp_type_values, "Unknown", tlv_value), + tlv_value)); + break; + + case VTP_VLAN_BRIDGE_TYPE: + ND_PRINT((ndo, ", %s (%u)", + tlv_value == 1 ? "SRB" : "SRT", + tlv_value)); + break; + + case VTP_VLAN_BACKUP_CRF_MODE: + ND_PRINT((ndo, ", %s (%u)", + tlv_value == 1 ? "Backup" : "Not backup", + tlv_value)); + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER: + case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER: + case VTP_VLAN_PARENT_VLAN: + case VTP_VLAN_TRANS_BRIDGED_VLAN: + case VTP_VLAN_ARP_HOP_COUNT: + default: + print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2); + break; + } } len -= 2 + tlv_len*2; tptr += 2 + tlv_len*2; diff --git a/freebsd/contrib/tcpdump/print-wb.c b/freebsd/contrib/tcpdump/print-wb.c index 60892bbd..aeab01c3 100644 --- a/freebsd/contrib/tcpdump/print-wb.c +++ b/freebsd/contrib/tcpdump/print-wb.c @@ -269,9 +269,8 @@ wb_prep(netdissect_options *ndo, const u_char *ep = ndo->ndo_snapend; ND_PRINT((ndo, " wb-prep:")); - if (len < sizeof(*prep)) { + if (len < sizeof(*prep) || !ND_TTEST(*prep)) return (-1); - } n = EXTRACT_32BITS(&prep->pp_n); ps = (const struct pgstate *)(prep + 1); while (--n >= 0 && ND_TTEST(*ps)) { @@ -425,31 +424,37 @@ wb_print(netdissect_options *ndo, case PT_ID: if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0) return; + ND_PRINT((ndo, "%s", tstr)); break; case PT_RREQ: if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0) return; + ND_PRINT((ndo, "%s", tstr)); break; case PT_RREP: if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0) return; + ND_PRINT((ndo, "%s", tstr)); break; case PT_DRAWOP: if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0) return; + ND_PRINT((ndo, "%s", tstr)); break; case PT_PREQ: if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0) return; + ND_PRINT((ndo, "%s", tstr)); break; case PT_PREP: if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0) return; + ND_PRINT((ndo, "%s", tstr)); break; default: diff --git a/freebsd/contrib/tcpdump/print-zephyr.c b/freebsd/contrib/tcpdump/print-zephyr.c index f44c3057..630c7095 100644 --- a/freebsd/contrib/tcpdump/print-zephyr.c +++ b/freebsd/contrib/tcpdump/print-zephyr.c @@ -82,30 +82,41 @@ static const struct tok z_types[] = { { Z_PACKET_SERVACK, "serv-ack" }, { Z_PACKET_SERVNAK, "serv-nak" }, { Z_PACKET_CLIENTACK, "client-ack" }, - { Z_PACKET_STAT, "stat" } + { Z_PACKET_STAT, "stat" }, + { 0, NULL } }; static char z_buf[256]; static const char * -parse_field(netdissect_options *ndo, const char **pptr, int *len) +parse_field(netdissect_options *ndo, const char **pptr, int *len, int *truncated) { const char *s; - if (*len <= 0 || !pptr || !*pptr) - return NULL; - if (*pptr > (const char *) ndo->ndo_snapend) - return NULL; - + /* Start of string */ s = *pptr; - while (*pptr <= (const char *) ndo->ndo_snapend && *len >= 0 && **pptr) { + /* Scan for the NUL terminator */ + for (;;) { + if (*len == 0) { + /* Ran out of packet data without finding it */ + return NULL; + } + if (!ND_TTEST(**pptr)) { + /* Ran out of captured data without finding it */ + *truncated = 1; + return NULL; + } + if (**pptr == '\0') { + /* Found it */ + break; + } + /* Keep scanning */ (*pptr)++; (*len)--; } + /* Skip the NUL terminator */ (*pptr)++; (*len)--; - if (*len < 0 || *pptr > (const char *) ndo->ndo_snapend) - return NULL; return s; } @@ -144,6 +155,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) int parselen = length; const char *s; int lose = 0; + int truncated = 0; /* squelch compiler warnings */ @@ -154,8 +166,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) z.sender = 0; z.recipient = 0; -#define PARSE_STRING \ - s = parse_field(ndo, &parse, &parselen); \ +#define PARSE_STRING \ + s = parse_field(ndo, &parse, &parselen, &truncated); \ + if (truncated) goto trunc; \ if (!s) lose = 1; #define PARSE_FIELD_INT(field) \ @@ -188,10 +201,8 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) PARSE_FIELD_INT(z.multi); PARSE_FIELD_STR(z.multi_uid); - if (lose) { - ND_PRINT((ndo, " [|zephyr] (%d)", length)); - return; - } + if (lose) + goto trunc; ND_PRINT((ndo, " zephyr")); if (strncmp(z.version+4, "0.2", 3)) { @@ -323,6 +334,11 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length) ND_PRINT((ndo, " to %s", z_triple(z.class, z.inst, z.recipient))); if (*z.opcode) ND_PRINT((ndo, " op %s", z.opcode)); + return; + +trunc: + ND_PRINT((ndo, " [|zephyr] (%d)", length)); + return; } #ifdef __rtems__ #include "rtems-bsd-tcpdump-print-zephyr-data.h" diff --git a/freebsd/contrib/tcpdump/print.c b/freebsd/contrib/tcpdump/print.c index 767a235e..2bbfc04b 100644 --- a/freebsd/contrib/tcpdump/print.c +++ b/freebsd/contrib/tcpdump/print.c @@ -232,23 +232,16 @@ static const struct printer printers[] = { static void ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length); -static void ndo_error(netdissect_options *ndo, const char *fmt, ...) - __attribute__((noreturn)) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void ndo_warning(netdissect_options *ndo, const char *fmt, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; - -static int ndo_printf(netdissect_options *ndo, const char *fmt, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute ((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; +static void ndo_error(netdissect_options *ndo, + FORMAT_STRING(const char *fmt), ...) + NORETURN PRINTFLIKE(2, 3); +static void ndo_warning(netdissect_options *ndo, + FORMAT_STRING(const char *fmt), ...) + PRINTFLIKE(2, 3); + +static int ndo_printf(netdissect_options *ndo, + FORMAT_STRING(const char *fmt), ...) + PRINTFLIKE(2, 3); void init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask, diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h index 19986243..9b6b1d8c 100644 --- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h +++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-addrtoname-data.h @@ -2,7 +2,7 @@ #include <rtems/linkersets.h> #include "rtems-bsd-tcpdump-data.h" /* addrtoname.c */ -RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct enamemem bytestringtable[]); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct bsnamemem bytestringtable[]); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct enamemem enametable[]); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct enamemem nsaptable[]); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static struct h6namemem h6nametable[]); diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h index b0ed4329..bb4ed207 100644 --- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h +++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h @@ -46,6 +46,7 @@ #define in_cksum _bsd_tcpdump_in_cksum #define in_cksum_shouldbe _bsd_tcpdump_in_cksum_shouldbe /* ipproto.c */ +#define netdb_protoname _bsd_tcpdump_netdb_protoname /* l2vpn.c */ /* machdep.c */ #define abort_on_misalignment _bsd_tcpdump_abort_on_misalignment diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h index 17b75076..126e0f46 100644 --- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h +++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-tcpdump-data.h @@ -4,7 +4,6 @@ /* tcpdump.c */ RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static char *zflag); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Bflag); -RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Cflag); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Cflag_count); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Dflag); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int Gflag); @@ -23,6 +22,7 @@ RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int infoprint); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int jflag); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int pflag); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int supports_monitor_mode); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static long int Cflag); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static pcap_t *pd); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static time_t Gflag_time); RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static u_int packets_captured); diff --git a/freebsd/contrib/tcpdump/signature.c b/freebsd/contrib/tcpdump/signature.c index 2e654aea..861f59cd 100644 --- a/freebsd/contrib/tcpdump/signature.c +++ b/freebsd/contrib/tcpdump/signature.c @@ -18,7 +18,7 @@ * * Functions for signature and digest verification. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ #ifdef HAVE_CONFIG_H diff --git a/freebsd/contrib/tcpdump/signature.h b/freebsd/contrib/tcpdump/signature.h index 239ee3e8..bbb63edf 100644 --- a/freebsd/contrib/tcpdump/signature.h +++ b/freebsd/contrib/tcpdump/signature.h @@ -12,7 +12,7 @@ * * Functions for signature and digest verification. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ /* for netdissect_options */ diff --git a/freebsd/contrib/tcpdump/smbutil.c b/freebsd/contrib/tcpdump/smbutil.c index b1f9b098..5ed188b6 100644 --- a/freebsd/contrib/tcpdump/smbutil.c +++ b/freebsd/contrib/tcpdump/smbutil.c @@ -243,6 +243,7 @@ name_len(netdissect_options *ndo, return(-1); /* name goes past the end of the buffer */ ND_TCHECK2(*s, 1); s += (*s) + 1; + ND_TCHECK2(*s, 1); } return(PTR_DIFF(s, s0) + 1); diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c index 52fd2260..26761ad7 100644 --- a/freebsd/contrib/tcpdump/tcpdump.c +++ b/freebsd/contrib/tcpdump/tcpdump.c @@ -156,7 +156,7 @@ The Regents of the University of California. All rights reserved.\n"; #endif static int Bflag; /* buffer size */ -static int Cflag; /* rotate dump files after this many bytes */ +static long Cflag; /* rotate dump files after this many bytes */ static int Cflag_count; /* Keep track of which file number we're writing */ static int Dflag; /* list available devices and exit */ /* @@ -204,26 +204,17 @@ cap_channel_t *capdns; #endif /* Forwards */ -static void error(const char *, ...) - __attribute__((noreturn)) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 1, 2))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void warning(const char *, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 1, 2))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void exit_tcpdump(int) __attribute__((noreturn)); +static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2); +static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2); +static void exit_tcpdump(int) NORETURN; static RETSIGTYPE cleanup(int); static RETSIGTYPE child_cleanup(int); static void print_version(void); static void print_usage(void); -static void show_tstamp_types_and_exit(pcap_t *, const char *device) __attribute__((noreturn)); -static void show_dlts_and_exit(pcap_t *, const char *device) __attribute__((noreturn)); +static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN; +static void show_dlts_and_exit(pcap_t *, const char *device) NORETURN; #ifdef HAVE_PCAP_FINDALLDEVS -static void show_devices_and_exit (void) __attribute__((noreturn)); +static void show_devices_and_exit (void) NORETURN; #endif static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); @@ -2063,10 +2054,10 @@ main(int argc, char **argv) /* * The various libpcap devices use a combination of - * read (bpf), ioctl (bpf, netmap), poll (netmap). - * Grant the relevant access rights, sorted by name. + * read (bpf), ioctl (bpf, netmap), poll (netmap) + * so we add the relevant access rights. */ - cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ); + cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT); if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 && errno != ENOSYS) { error("unable to limit pcap descriptor"); @@ -2819,6 +2810,14 @@ print_version(void) smi_version_string = nd_smi_version_string(); if (smi_version_string != NULL) (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string); + +#if defined(__SANITIZE_ADDRESS__) + (void)fprintf (stderr, "Compiled with AddressSanitizer/GCC.\n"); +#elif defined(__has_feature) +# if __has_feature(address_sanitizer) + (void)fprintf (stderr, "Compiled with AddressSanitizer/CLang.\n"); +# endif +#endif /* __SANITIZE_ADDRESS__ or __has_feature */ } USES_APPLE_RST diff --git a/freebsd/contrib/tcpdump/util-print.c b/freebsd/contrib/tcpdump/util-print.c index a4b482ff..7a5269dd 100644 --- a/freebsd/contrib/tcpdump/util-print.c +++ b/freebsd/contrib/tcpdump/util-print.c @@ -27,7 +27,7 @@ /* * txtproto_print() derived from original code by Hannes Gredler - * (hannes@juniper.net): + * (hannes@gredler.at): * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code @@ -527,8 +527,9 @@ static char * bittok2str_internal(register const struct tok *lp, register const char *fmt, register u_int v, const char *sep) { - static char buf[256]; /* our stringbuffer */ - int buflen=0; + static char buf[1024+1]; /* our string buffer */ + char *bufp = buf; + size_t space_left = sizeof(buf), string_size; register u_int rotbit; /* this is the bit we rotate through all bitpositions */ register u_int tokval; const char * sepstr = ""; @@ -543,8 +544,20 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, */ if (tokval == (v&rotbit)) { /* ok we have found something */ - buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", - sepstr, lp->s); + if (space_left <= 1) + return (buf); /* only enough room left for NUL, if that */ + string_size = strlcpy(bufp, sepstr, space_left); + if (string_size >= space_left) + return (buf); /* we ran out of room */ + bufp += string_size; + space_left -= string_size; + if (space_left <= 1) + return (buf); /* only enough room left for NUL, if that */ + string_size = strlcpy(bufp, lp->s, space_left); + if (string_size >= space_left) + return (buf); /* we ran out of room */ + bufp += string_size; + space_left -= string_size; sepstr = sep; break; } @@ -553,7 +566,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, lp++; } - if (buflen == 0) + if (bufp == buf) /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v); return (buf); @@ -908,7 +921,7 @@ safeputs(netdissect_options *ndo, { u_int idx = 0; - while (*s && idx < maxlen) { + while (idx < maxlen && *s) { safeputchar(ndo, *s); idx++; s++; diff --git a/freebsd/crypto/openssl/crypto/asn1/a_i2d_fp.c b/freebsd/crypto/openssl/crypto/asn1/a_i2d_fp.c index a1bc4b6e..8877481a 100644 --- a/freebsd/crypto/openssl/crypto/asn1/a_i2d_fp.c +++ b/freebsd/crypto/openssl/crypto/asn1/a_i2d_fp.c @@ -89,6 +89,9 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) int i, j = 0, n, ret = 1; n = i2d(x, NULL); + if (n <= 0) + return 0; + b = (char *)OPENSSL_malloc(n); if (b == NULL) { ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); diff --git a/freebsd/crypto/openssl/crypto/bio/b_print.c b/freebsd/crypto/openssl/crypto/bio/b_print.c index 0cb09514..738904bc 100644 --- a/freebsd/crypto/openssl/crypto/bio/b_print.c +++ b/freebsd/crypto/openssl/crypto/bio/b_print.c @@ -387,7 +387,7 @@ _dopr(char **sbuffer, if (cflags == DP_C_SHORT) { short int *num; num = va_arg(args, short int *); - *num = currlen; + *num = (short int)currlen; } else if (cflags == DP_C_LONG) { /* XXX */ long int *num; num = va_arg(args, long int *); @@ -504,7 +504,7 @@ fmtint(char **sbuffer, if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; - uvalue = -(unsigned LLONG)value; + uvalue = 0 - (unsigned LLONG)value; } else if (flags & DP_F_PLUS) signvalue = '+'; else if (flags & DP_F_SPACE) diff --git a/freebsd/crypto/openssl/crypto/bn/bn_exp.c b/freebsd/crypto/openssl/crypto/bn/bn_exp.c index 7c1ea0a4..7261c8db 100644 --- a/freebsd/crypto/openssl/crypto/bn/bn_exp.c +++ b/freebsd/crypto/openssl/crypto/bn/bn_exp.c @@ -151,7 +151,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; + return 0; } BN_CTX_start(ctx); @@ -287,7 +287,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; + return 0; } bits = BN_num_bits(p); @@ -1230,7 +1230,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; + return 0; } bn_check_top(p); @@ -1363,7 +1363,7 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; + return 0; } bits = BN_num_bits(p); diff --git a/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c b/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c index 3da90130..5244a252 100644 --- a/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c +++ b/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c @@ -135,6 +135,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) unsigned char *penc = NULL; int penclen; ASN1_STRING *str = NULL; + ASN1_OBJECT *aobj; dsa = pkey->pkey.dsa; if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { @@ -161,8 +162,11 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) goto err; } - if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), - ptype, str, penc, penclen)) + aobj = OBJ_nid2obj(EVP_PKEY_DSA); + if (aobj == NULL) + goto err; + + if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen)) return 1; err: diff --git a/freebsd/crypto/openssl/crypto/engine/eng_fat.c b/freebsd/crypto/openssl/crypto/engine/eng_fat.c index faabb9b7..16b2dacc 100644 --- a/freebsd/crypto/openssl/crypto/engine/eng_fat.c +++ b/freebsd/crypto/openssl/crypto/engine/eng_fat.c @@ -169,6 +169,7 @@ int ENGINE_register_complete(ENGINE *e) #endif ENGINE_register_RAND(e); ENGINE_register_pkey_meths(e); + ENGINE_register_pkey_asn1_meths(e); return 1; } diff --git a/freebsd/crypto/openssl/crypto/lhash/lhash.c b/freebsd/crypto/openssl/crypto/lhash/lhash.c index 1e7194e3..babc7a0d 100644 --- a/freebsd/crypto/openssl/crypto/lhash/lhash.c +++ b/freebsd/crypto/openssl/crypto/lhash/lhash.c @@ -109,7 +109,7 @@ * https://en.wikipedia.org/wiki/Linear_hashing * * Litwin, Witold (1980), "Linear hashing: A new tool for file and table - * addressing", Proc. 6th Conference on Very Large Databases: 212–223 + * addressing", Proc. 6th Conference on Very Large Databases: 212-223 * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf * * From the wikipedia article "Linear hashing is used in the BDB Berkeley diff --git a/freebsd/crypto/openssl/crypto/opensslv.h b/freebsd/crypto/openssl/crypto/opensslv.h index 83867763..d5835040 100644 --- a/freebsd/crypto/openssl/crypto/opensslv.h +++ b/freebsd/crypto/openssl/crypto/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x100020dfL +# define OPENSSL_VERSION_NUMBER 0x100020efL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-fips 2 Nov 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2n-fips 7 Dec 2017" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-freebsd 2 Nov 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2n-freebsd 7 Dec 2017" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/freebsd/crypto/openssl/crypto/rsa/rsa_gen.c b/freebsd/crypto/openssl/crypto/rsa/rsa_gen.c index 759ec219..e12803a8 100644 --- a/freebsd/crypto/openssl/crypto/rsa/rsa_gen.c +++ b/freebsd/crypto/openssl/crypto/rsa/rsa_gen.c @@ -112,6 +112,16 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, int bitsp, bitsq, ok = -1, n = 0; BN_CTX *ctx = NULL; + /* + * When generating ridiculously small keys, we can get stuck + * continually regenerating the same prime values. + */ + if (bits < 16) { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -163,21 +173,10 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, if (!BN_GENCB_call(cb, 3, 0)) goto err; for (;;) { - /* - * When generating ridiculously small keys, we can get stuck - * continually regenerating the same prime values. Check for this and - * bail if it happens 3 times. - */ - unsigned int degenerate = 0; do { if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) goto err; - } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); - if (degenerate == 3) { - ok = 0; /* we set our own err */ - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); - goto err; - } + } while (BN_cmp(rsa->p, rsa->q) == 0); if (!BN_sub(r2, rsa->q, BN_value_one())) goto err; if (!BN_gcd(r1, r2, rsa->e, ctx)) diff --git a/freebsd/crypto/openssl/crypto/symhacks.h b/freebsd/crypto/openssl/crypto/symhacks.h index 239fa4fb..30019579 100644 --- a/freebsd/crypto/openssl/crypto/symhacks.h +++ b/freebsd/crypto/openssl/crypto/symhacks.h @@ -280,6 +280,8 @@ # define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf # undef EVP_PKEY_meth_set_verify_recover # define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover +# undef EVP_PKEY_meth_get_verify_recover +# define EVP_PKEY_meth_get_verify_recover EVP_PKEY_meth_get_vrfy_recover /* Hack some long EC names */ # undef EC_GROUP_set_point_conversion_form diff --git a/freebsd/crypto/openssl/crypto/x509v3/v3_lib.c b/freebsd/crypto/openssl/crypto/x509v3/v3_lib.c index 7d2e16fb..9fd34e9d 100644 --- a/freebsd/crypto/openssl/crypto/x509v3/v3_lib.c +++ b/freebsd/crypto/openssl/crypto/x509v3/v3_lib.c @@ -288,9 +288,9 @@ void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags) { - int extidx = -1; - int errcode; - X509_EXTENSION *ext, *extmp; + int errcode, extidx = -1; + X509_EXTENSION *ext = NULL, *extmp; + STACK_OF(X509_EXTENSION) *ret = NULL; unsigned long ext_op = flags & X509V3_ADD_OP_MASK; /* @@ -349,13 +349,21 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, return 1; } - if (!*x && !(*x = sk_X509_EXTENSION_new_null())) - return -1; - if (!sk_X509_EXTENSION_push(*x, ext)) - return -1; + if ((ret = *x) == NULL + && (ret = sk_X509_EXTENSION_new_null()) == NULL) + goto m_fail; + if (!sk_X509_EXTENSION_push(ret, ext)) + goto m_fail; + *x = ret; return 1; + m_fail: + if (ret != *x) + sk_X509_EXTENSION_free(ret); + X509_EXTENSION_free(ext); + return -1; + err: if (!(flags & X509V3_ADD_SILENT)) X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); diff --git a/freebsd/crypto/openssl/crypto/x509v3/v3_scts.c b/freebsd/crypto/openssl/crypto/x509v3/v3_scts.c index 0503b832..afc84b95 100644 --- a/freebsd/crypto/openssl/crypto/x509v3/v3_scts.c +++ b/freebsd/crypto/openssl/crypto/x509v3/v3_scts.c @@ -158,7 +158,7 @@ static void timestamp_print(BIO *out, SCT_TIMESTAMP timestamp) gen = ASN1_GENERALIZEDTIME_new(); ASN1_GENERALIZEDTIME_adj(gen, (time_t)0, (int)(timestamp / 86400000), - (timestamp % 86400000) / 1000); + (int)(timestamp % 86400000) / 1000); /* * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 * characters long with a final Z. Update it with fractional seconds. diff --git a/freebsd/crypto/openssl/ssl/bad_dtls_test.c b/freebsd/crypto/openssl/ssl/bad_dtls_test.c index ab81cf1f..0a432a4a 100644 --- a/freebsd/crypto/openssl/ssl/bad_dtls_test.c +++ b/freebsd/crypto/openssl/ssl/bad_dtls_test.c @@ -592,13 +592,13 @@ static int send_record(BIO *rbio, unsigned char type, unsigned long seqnr, unsigned char *enc; #ifdef SIXTY_FOUR_BIT_LONG - seq[0] = (seqnr >> 40) & 0xff; - seq[1] = (seqnr >> 32) & 0xff; + seq[0] = (unsigned char)(seqnr >> 40); + seq[1] = (unsigned char)(seqnr >> 32); #endif - seq[2] = (seqnr >> 24) & 0xff; - seq[3] = (seqnr >> 16) & 0xff; - seq[4] = (seqnr >> 8) & 0xff; - seq[5] = seqnr & 0xff; + seq[2] = (unsigned char)(seqnr >> 24); + seq[3] = (unsigned char)(seqnr >> 16); + seq[4] = (unsigned char)(seqnr >> 8); + seq[5] = (unsigned char)(seqnr); pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16); enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad); @@ -614,8 +614,8 @@ static int send_record(BIO *rbio, unsigned char type, unsigned long seqnr, HMAC_Update(&ctx, seq, 6); HMAC_Update(&ctx, &type, 1); HMAC_Update(&ctx, ver, 2); /* Version */ - lenbytes[0] = len >> 8; - lenbytes[1] = len & 0xff; + lenbytes[0] = (unsigned char)(len >> 8); + lenbytes[1] = (unsigned char)(len); HMAC_Update(&ctx, lenbytes, 2); /* Length */ HMAC_Update(&ctx, enc, len); /* Finally the data itself */ HMAC_Final(&ctx, enc + len, NULL); @@ -639,8 +639,8 @@ static int send_record(BIO *rbio, unsigned char type, unsigned long seqnr, BIO_write(rbio, ver, 2); BIO_write(rbio, epoch, 2); BIO_write(rbio, seq, 6); - lenbytes[0] = (len + sizeof(iv)) >> 8; - lenbytes[1] = (len + sizeof(iv)) & 0xff; + lenbytes[0] = (unsigned char)((len + sizeof(iv)) >> 8); + lenbytes[1] = (unsigned char)(len + sizeof(iv)); BIO_write(rbio, lenbytes, 2); BIO_write(rbio, iv, sizeof(iv)); diff --git a/freebsd/crypto/openssl/ssl/s23_clnt.c b/freebsd/crypto/openssl/ssl/s23_clnt.c index 197ae215..840c0ddb 100644 --- a/freebsd/crypto/openssl/ssl/s23_clnt.c +++ b/freebsd/crypto/openssl/ssl/s23_clnt.c @@ -759,10 +759,12 @@ static int ssl23_get_server_hello(SSL *s) s->version = TLS1_VERSION; s->method = TLSv1_client_method(); break; +#ifndef OPENSSL_NO_SSL3 case SSL3_VERSION: s->version = SSL3_VERSION; s->method = SSLv3_client_method(); break; +#endif } SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); diff --git a/freebsd/crypto/openssl/ssl/s3_pkt.c b/freebsd/crypto/openssl/ssl/s3_pkt.c index 679517f2..c2194d18 100644 --- a/freebsd/crypto/openssl/ssl/s3_pkt.c +++ b/freebsd/crypto/openssl/ssl/s3_pkt.c @@ -1326,10 +1326,16 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } #ifndef OPENSSL_NO_HEARTBEATS else if (rr->type == TLS1_RT_HEARTBEAT) { - tls1_process_heartbeat(s); + i = tls1_process_heartbeat(s); + + if (i < 0) + return i; - /* Exit and notify application to read again */ rr->length = 0; + if (s->mode & SSL_MODE_AUTO_RETRY) + goto start; + + /* Exit and notify application to read again */ s->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); diff --git a/freebsd/crypto/openssl/ssl/srtp.h b/freebsd/crypto/openssl/ssl/srtp.h index 512edabc..2279c32b 100644 --- a/freebsd/crypto/openssl/ssl/srtp.h +++ b/freebsd/crypto/openssl/ssl/srtp.h @@ -136,6 +136,7 @@ int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); # endif diff --git a/freebsd/crypto/openssl/ssl/ssl.h b/freebsd/crypto/openssl/ssl/ssl.h index 90aeb0ce..3cf96a23 100644 --- a/freebsd/crypto/openssl/ssl/ssl.h +++ b/freebsd/crypto/openssl/ssl/ssl.h @@ -1727,7 +1727,7 @@ extern "C" { # define SSL_ST_BEFORE 0x4000 # define SSL_ST_OK 0x03 # define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) -# define SSL_ST_ERR 0x05 +# define SSL_ST_ERR (0x05|SSL_ST_INIT) # define SSL_CB_LOOP 0x01 # define SSL_CB_EXIT 0x02 diff --git a/freebsd/crypto/openssl/ssl/ssltest.c b/freebsd/crypto/openssl/ssl/ssltest.c index 5eafe9e3..f6da7d32 100644 --- a/freebsd/crypto/openssl/ssl/ssltest.c +++ b/freebsd/crypto/openssl/ssl/ssltest.c @@ -425,13 +425,13 @@ static unsigned char *next_protos_parse(unsigned short *outlen, OPENSSL_free(out); return NULL; } - out[start] = i - start; + out[start] = (unsigned char)(i - start); start = i + 1; } else out[i + 1] = in[i]; } - *outlen = len + 1; + *outlen = (unsigned char)(len + 1); return out; } @@ -556,6 +556,7 @@ static int cb_ticket2(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CI { fprintf(stderr, "ticket callback for SNI context should never be called\n"); EXIT(1); + return 0; } #endif diff --git a/freebsd/crypto/openssl/ssl/t1_lib.c b/freebsd/crypto/openssl/ssl/t1_lib.c index 984c9c88..5e86a780 100644 --- a/freebsd/crypto/openssl/ssl/t1_lib.c +++ b/freebsd/crypto/openssl/ssl/t1_lib.c @@ -1918,7 +1918,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); s2n(3 + len, ret); s2n(1 + len, ret); - *ret++ = len; + *ret++ = (unsigned char)len; memcpy(ret, selected, len); ret += len; } diff --git a/freebsd/include/arpa/nameser.h b/freebsd/include/arpa/nameser.h index f0e3482a..5dcc4f3b 100644 --- a/freebsd/include/arpa/nameser.h +++ b/freebsd/include/arpa/nameser.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: (ISC AND BSD-3-Clause) + * * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2003 Internet Software Consortium. * @@ -16,8 +18,6 @@ */ /*- - * SPDX-License-Identifier: BSD-3-Clause - * * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. * diff --git a/freebsd/include/err.h b/freebsd/include/err.h index 636185e2..beb536cf 100644 --- a/freebsd/include/err.h +++ b/freebsd/include/err.h @@ -60,7 +60,7 @@ void vwarn(const char *, __va_list) __printf0like(1, 0); void warnc(int, const char *, ...) __printf0like(2, 3); void vwarnc(int, const char *, __va_list) __printf0like(2, 0); void warnx(const char *, ...) __printflike(1, 2); -void vwarnx(const char *, __va_list) __printflike(1, 0); +void vwarnx(const char *, __va_list) __printf0like(1, 0); #ifndef __rtems__ void err_set_file(void *); void err_set_exit(void (* _Nullable)(int)); diff --git a/freebsd/include/ifaddrs.h b/freebsd/include/ifaddrs.h index e768d50c..5e195363 100644 --- a/freebsd/include/ifaddrs.h +++ b/freebsd/include/ifaddrs.h @@ -1,6 +1,8 @@ /* $FreeBSD$ */ -/* +/*- + * SPDX-License-Identifier: BSD-1-Clause + * * Copyright (c) 1995, 1999 * Berkeley Software Design, Inc. All rights reserved. * diff --git a/freebsd/include/netdb.h b/freebsd/include/netdb.h index f46f5a3c..a106338a 100644 --- a/freebsd/include/netdb.h +++ b/freebsd/include/netdb.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (BSD-3-Clause AND ISC) * * Copyright (c) 1980, 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. diff --git a/freebsd/include/res_update.h b/freebsd/include/res_update.h index 06f3b3a5..32d363ba 100644 --- a/freebsd/include/res_update.h +++ b/freebsd/include/res_update.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999 by Internet Software Consortium, Inc. * diff --git a/freebsd/include/resolv.h b/freebsd/include/resolv.h index 1f4a9bc8..2226c481 100644 --- a/freebsd/include/resolv.h +++ b/freebsd/include/resolv.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (ISC AND BSD-3-Clause) * * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1995-2003 Internet Software Consortium. diff --git a/freebsd/lib/libc/include/isc/eventlib.h b/freebsd/lib/libc/include/isc/eventlib.h index a4cfdf90..7e10063a 100644 --- a/freebsd/lib/libc/include/isc/eventlib.h +++ b/freebsd/lib/libc/include/isc/eventlib.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1995-1999, 2001, 2003 Internet Software Consortium. * diff --git a/freebsd/lib/libc/include/isc/list.h b/freebsd/lib/libc/include/isc/list.h index ffd0c511..cdc98a84 100644 --- a/freebsd/lib/libc/include/isc/list.h +++ b/freebsd/lib/libc/include/isc/list.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1997,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/include/isc/platform.h b/freebsd/lib/libc/include/isc/platform.h index a0513be8..b514cb42 100644 --- a/freebsd/lib/libc/include/isc/platform.h +++ b/freebsd/lib/libc/include/isc/platform.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/freebsd/lib/libc/include/reentrant.h b/freebsd/lib/libc/include/reentrant.h index dd197ada..69132d0e 100644 --- a/freebsd/lib/libc/include/reentrant.h +++ b/freebsd/lib/libc/include/reentrant.h @@ -67,7 +67,7 @@ * Implementation Details: * * The mutex primitives used by the library (mutex_t, mutex_lock, etc.) - * are macros which expand to the cooresponding primitives provided by + * are macros which expand to the corresponding primitives provided by * the thread engine or to nothing. The latter is used so that code is * not unreasonably cluttered with #ifdefs when all thread safe support * is removed. diff --git a/freebsd/lib/libc/inet/inet_addr.c b/freebsd/lib/libc/inet/inet_addr.c index 3dedd7fa..5d8f5f1a 100644 --- a/freebsd/lib/libc/inet/inet_addr.c +++ b/freebsd/lib/libc/inet/inet_addr.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (BSD-3-Clause AND ISC) * * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. diff --git a/freebsd/lib/libc/inet/inet_cidr_ntop.c b/freebsd/lib/libc/inet/inet_cidr_ntop.c index 1fccb9a4..771e3331 100644 --- a/freebsd/lib/libc/inet/inet_cidr_ntop.c +++ b/freebsd/lib/libc/inet/inet_cidr_ntop.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1998,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/inet_cidr_pton.c b/freebsd/lib/libc/inet/inet_cidr_pton.c index 2165b898..d19894ae 100644 --- a/freebsd/lib/libc/inet/inet_cidr_pton.c +++ b/freebsd/lib/libc/inet/inet_cidr_pton.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1998,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/inet_net_ntop.c b/freebsd/lib/libc/inet/inet_net_ntop.c index 48b1fd07..2932d269 100644 --- a/freebsd/lib/libc/inet/inet_net_ntop.c +++ b/freebsd/lib/libc/inet/inet_net_ntop.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/inet_net_pton.c b/freebsd/lib/libc/inet/inet_net_pton.c index ba59726f..7fbf5da6 100644 --- a/freebsd/lib/libc/inet/inet_net_pton.c +++ b/freebsd/lib/libc/inet/inet_net_pton.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996, 1998, 1999, 2001, 2003 Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/inet_neta.c b/freebsd/lib/libc/inet/inet_neta.c index aa02ec59..498f5e20 100644 --- a/freebsd/lib/libc/inet/inet_neta.c +++ b/freebsd/lib/libc/inet/inet_neta.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/inet_ntop.c b/freebsd/lib/libc/inet/inet_ntop.c index be2aabe2..cbc59f1e 100644 --- a/freebsd/lib/libc/inet/inet_ntop.c +++ b/freebsd/lib/libc/inet/inet_ntop.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/inet_pton.c b/freebsd/lib/libc/inet/inet_pton.c index 18bcd32b..ddaa6c28 100644 --- a/freebsd/lib/libc/inet/inet_pton.c +++ b/freebsd/lib/libc/inet/inet_pton.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/inet/nsap_addr.c b/freebsd/lib/libc/inet/nsap_addr.c index 27449b42..f6bda82e 100644 --- a/freebsd/lib/libc/inet/nsap_addr.c +++ b/freebsd/lib/libc/inet/nsap_addr.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/isc/ev_streams.c b/freebsd/lib/libc/isc/ev_streams.c index 92af0c87..65ca8039 100644 --- a/freebsd/lib/libc/isc/ev_streams.c +++ b/freebsd/lib/libc/isc/ev_streams.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium * diff --git a/freebsd/lib/libc/isc/ev_timers.c b/freebsd/lib/libc/isc/ev_timers.c index 56efe06f..380b5686 100644 --- a/freebsd/lib/libc/isc/ev_timers.c +++ b/freebsd/lib/libc/isc/ev_timers.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium * diff --git a/freebsd/lib/libc/isc/eventlib_p.h b/freebsd/lib/libc/isc/eventlib_p.h index 07db816f..a56334f0 100644 --- a/freebsd/lib/libc/isc/eventlib_p.h +++ b/freebsd/lib/libc/isc/eventlib_p.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium * diff --git a/freebsd/lib/libc/nameser/ns_name.c b/freebsd/lib/libc/nameser/ns_name.c index 224f9512..50946fab 100644 --- a/freebsd/lib/libc/nameser/ns_name.c +++ b/freebsd/lib/libc/nameser/ns_name.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/nameser/ns_netint.c b/freebsd/lib/libc/nameser/ns_netint.c index 887bdc44..08927f3d 100644 --- a/freebsd/lib/libc/nameser/ns_netint.c +++ b/freebsd/lib/libc/nameser/ns_netint.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/nameser/ns_parse.c b/freebsd/lib/libc/nameser/ns_parse.c index 6b3f68c6..06854350 100644 --- a/freebsd/lib/libc/nameser/ns_parse.c +++ b/freebsd/lib/libc/nameser/ns_parse.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/nameser/ns_print.c b/freebsd/lib/libc/nameser/ns_print.c index 99427348..da620aa0 100644 --- a/freebsd/lib/libc/nameser/ns_print.c +++ b/freebsd/lib/libc/nameser/ns_print.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/nameser/ns_samedomain.c b/freebsd/lib/libc/nameser/ns_samedomain.c index 754e23b9..281bfb74 100644 --- a/freebsd/lib/libc/nameser/ns_samedomain.c +++ b/freebsd/lib/libc/nameser/ns_samedomain.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/nameser/ns_ttl.c b/freebsd/lib/libc/nameser/ns_ttl.c index 5a5aa169..f4e2f9f9 100644 --- a/freebsd/lib/libc/nameser/ns_ttl.c +++ b/freebsd/lib/libc/nameser/ns_ttl.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/net/getaddrinfo.c b/freebsd/lib/libc/net/getaddrinfo.c index c9dab725..8ad66043 100644 --- a/freebsd/lib/libc/net/getaddrinfo.c +++ b/freebsd/lib/libc/net/getaddrinfo.c @@ -1279,7 +1279,8 @@ explore_numeric(const struct addrinfo *pai, const char *hostname, * does not accept. So we need to separate the case for * AF_INET. */ - if (inet_aton(hostname, (struct in_addr *)pton) != 1) + if (inet_aton(hostname, (struct in_addr *)pton) != 1 || + hostname[strspn(hostname, "0123456789.xabcdefXABCDEF")] != '\0') return 0; p = pton; break; diff --git a/freebsd/lib/libc/net/getifaddrs.c b/freebsd/lib/libc/net/getifaddrs.c index 7e111a68..f8bbaf5c 100644 --- a/freebsd/lib/libc/net/getifaddrs.c +++ b/freebsd/lib/libc/net/getifaddrs.c @@ -2,7 +2,9 @@ /* $KAME: getifaddrs.c,v 1.9 2001/08/20 02:31:20 itojun Exp $ */ -/* +/*- + * SPDX-License-Identifier: BSD-1-Clause + * * Copyright (c) 1995, 1999 * Berkeley Software Design, Inc. All rights reserved. * diff --git a/freebsd/lib/libc/net/if_indextoname.c b/freebsd/lib/libc/net/if_indextoname.c index 236ccbda..9299286c 100644 --- a/freebsd/lib/libc/net/if_indextoname.c +++ b/freebsd/lib/libc/net/if_indextoname.c @@ -3,6 +3,8 @@ /* $KAME: if_indextoname.c,v 1.7 2000/11/08 03:09:30 itojun Exp $ */ /*- + * SPDX-License-Identifier: BSD-1-Clause + * * Copyright (c) 1997, 2000 * Berkeley Software Design, Inc. All rights reserved. * diff --git a/freebsd/lib/libc/net/if_nameindex.c b/freebsd/lib/libc/net/if_nameindex.c index 6d2573e8..b2ef9d7f 100644 --- a/freebsd/lib/libc/net/if_nameindex.c +++ b/freebsd/lib/libc/net/if_nameindex.c @@ -3,6 +3,8 @@ /* $KAME: if_nameindex.c,v 1.8 2000/11/24 08:20:01 itojun Exp $ */ /*- + * SPDX-License-Identifier: BSD-1-Clause + * * Copyright (c) 1997, 2000 * Berkeley Software Design, Inc. All rights reserved. * diff --git a/freebsd/lib/libc/net/if_nametoindex.c b/freebsd/lib/libc/net/if_nametoindex.c index 92a2abed..01d3a573 100644 --- a/freebsd/lib/libc/net/if_nametoindex.c +++ b/freebsd/lib/libc/net/if_nametoindex.c @@ -3,6 +3,8 @@ /* $KAME: if_nametoindex.c,v 1.6 2000/11/24 08:18:54 itojun Exp $ */ /*- + * SPDX-License-Identifier: BSD-1-Clause + * * Copyright (c) 1997, 2000 * Berkeley Software Design, Inc. All rights reserved. * diff --git a/freebsd/lib/libc/net/rcmd.c b/freebsd/lib/libc/net/rcmd.c index 24bd7a0c..bc6a583d 100644 --- a/freebsd/lib/libc/net/rcmd.c +++ b/freebsd/lib/libc/net/rcmd.c @@ -459,8 +459,8 @@ again: first = 0; if ((pwd = getpwnam(luser)) == NULL) return (-1); - (void)strcpy(pbuf, pwd->pw_dir); - (void)strcat(pbuf, "/.rhosts"); + (void)strlcpy(pbuf, pwd->pw_dir, sizeof(pbuf)); + (void)strlcat(pbuf, "/.rhosts", sizeof(pbuf)); /* * Change effective uid while opening .rhosts. If root and diff --git a/freebsd/lib/libc/resolv/herror.c b/freebsd/lib/libc/resolv/herror.c index 29da9ca3..013d1619 100644 --- a/freebsd/lib/libc/resolv/herror.c +++ b/freebsd/lib/libc/resolv/herror.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (BSD-3-Clause AND ISC) * * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. diff --git a/freebsd/lib/libc/resolv/res_comp.c b/freebsd/lib/libc/resolv/res_comp.c index 4999327b..f3db9b95 100644 --- a/freebsd/lib/libc/resolv/res_comp.c +++ b/freebsd/lib/libc/resolv/res_comp.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (BSD-3-Clause AND ISC) * * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. diff --git a/freebsd/lib/libc/resolv/res_data.c b/freebsd/lib/libc/resolv/res_data.c index d17412de..12f66f39 100644 --- a/freebsd/lib/libc/resolv/res_data.c +++ b/freebsd/lib/libc/resolv/res_data.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/resolv/res_debug.c b/freebsd/lib/libc/resolv/res_debug.c index 004a7db0..12cb6e7f 100644 --- a/freebsd/lib/libc/resolv/res_debug.c +++ b/freebsd/lib/libc/resolv/res_debug.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: (ISC AND BSD-3-Clause) + * * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2003 Internet Software Consortium. * @@ -18,8 +20,6 @@ */ /*- - * SPDX-License-Identifier: BSD-3-Clause - * * Copyright (c) 1985 * The Regents of the University of California. All rights reserved. * diff --git a/freebsd/lib/libc/resolv/res_debug.h b/freebsd/lib/libc/resolv/res_debug.h index c28171d7..088046ad 100644 --- a/freebsd/lib/libc/resolv/res_debug.h +++ b/freebsd/lib/libc/resolv/res_debug.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999 by Internet Software Consortium. * @@ -13,6 +15,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ */ #ifndef _RES_DEBUG_H_ diff --git a/freebsd/lib/libc/resolv/res_findzonecut.c b/freebsd/lib/libc/resolv/res_findzonecut.c index acb3186f..8cf8c554 100644 --- a/freebsd/lib/libc/resolv/res_findzonecut.c +++ b/freebsd/lib/libc/resolv/res_findzonecut.c @@ -4,7 +4,9 @@ static const char rcsid[] = "$Id: res_findzonecut.c,v 1.10 2005/10/11 00:10:16 marka Exp $"; #endif /* not lint */ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/resolv/res_init.c b/freebsd/lib/libc/resolv/res_init.c index ce4b4267..815313c0 100644 --- a/freebsd/lib/libc/resolv/res_init.c +++ b/freebsd/lib/libc/resolv/res_init.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (BSD-3-Clause AND ISC) * * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. All rights reserved. diff --git a/freebsd/lib/libc/resolv/res_mkquery.c b/freebsd/lib/libc/resolv/res_mkquery.c index 564eb5a2..dd2e94b2 100644 --- a/freebsd/lib/libc/resolv/res_mkquery.c +++ b/freebsd/lib/libc/resolv/res_mkquery.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: (ISC AND BSD-3-Clause) + * * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003 Internet Software Consortium. * @@ -18,8 +20,6 @@ */ /*- - * SPDX-License-Identifier: BSD-3-Clause - * * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * diff --git a/freebsd/lib/libc/resolv/res_mkupdate.c b/freebsd/lib/libc/resolv/res_mkupdate.c index c737bc87..69a77f64 100644 --- a/freebsd/lib/libc/resolv/res_mkupdate.c +++ b/freebsd/lib/libc/resolv/res_mkupdate.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-user-space.h> -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libc/resolv/res_query.c b/freebsd/lib/libc/resolv/res_query.c index 2010d647..2071970d 100644 --- a/freebsd/lib/libc/resolv/res_query.c +++ b/freebsd/lib/libc/resolv/res_query.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (ISC AND BSD-3-Clause) * * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001, 2003 Internet Software Consortium. diff --git a/freebsd/lib/libc/resolv/res_send.c b/freebsd/lib/libc/resolv/res_send.c index 06d11327..b635c558 100644 --- a/freebsd/lib/libc/resolv/res_send.c +++ b/freebsd/lib/libc/resolv/res_send.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: (ISC AND BSD-3-Clause) * * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2003 Internet Software Consortium. diff --git a/freebsd/lib/libc/resolv/res_update.c b/freebsd/lib/libc/resolv/res_update.c index d4df045c..55a761f3 100644 --- a/freebsd/lib/libc/resolv/res_update.c +++ b/freebsd/lib/libc/resolv/res_update.c @@ -4,7 +4,9 @@ static const char rcsid[] = "$Id: res_update.c,v 1.13 2005/04/27 04:56:43 sra Exp $"; #endif /* not lint */ -/* +/*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * diff --git a/freebsd/lib/libcasper/libcasper/libcasper.h b/freebsd/lib/libcasper/libcasper/libcasper.h index 8ad15bc6..6e1bfdba 100644 --- a/freebsd/lib/libcasper/libcasper/libcasper.h +++ b/freebsd/lib/libcasper/libcasper/libcasper.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2012-2013 The FreeBSD Foundation * Copyright (c) 2015-2017 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. @@ -122,7 +124,15 @@ cap_wrap(int sock) #ifdef WITH_CASPER int cap_unwrap(cap_channel_t *chan); #else -#define cap_unwrap(chan) (chan->cch_fd) +static inline int +cap_unwrap(cap_channel_t *chan) +{ + int fd; + + fd = chan->cch_fd; + free(chan); + return (fd); +} #endif /* @@ -222,7 +232,7 @@ int cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl); #ifdef WITH_CASPER nvlist_t *cap_recv_nvlist(const cap_channel_t *chan, int flags); #else -#define cap_recv_nvlist(chan, flags) (0) +#define cap_recv_nvlist(chan, flags) (nvlist_create(flags)) #endif /* diff --git a/freebsd/lib/libmemstat/memstat_uma.c b/freebsd/lib/libmemstat/memstat_uma.c index 533a5af7..249335b3 100644 --- a/freebsd/lib/libmemstat/memstat_uma.c +++ b/freebsd/lib/libmemstat/memstat_uma.c @@ -57,6 +57,8 @@ static struct nlist namelist[] = { { .n_name = "_mp_maxid" }, #define X_ALL_CPUS 2 { .n_name = "_all_cpus" }, +#define X_VM_NDOMAINS 3 + { .n_name = "_vm_ndomains" }, { .n_name = "" }, }; @@ -300,11 +302,12 @@ memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle) { LIST_HEAD(, uma_keg) uma_kegs; struct memory_type *mtp; + struct uma_zone_domain uzd; struct uma_bucket *ubp, ub; struct uma_cache *ucp, *ucp_array; struct uma_zone *uzp, uz; struct uma_keg *kzp, kz; - int hint_dontsearch, i, mp_maxid, ret; + int hint_dontsearch, i, mp_maxid, ndomains, ret; char name[MEMTYPE_MAXNAME]; cpuset_t all_cpus; long cpusetsize; @@ -326,6 +329,12 @@ memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle) list->mtl_error = ret; return (-1); } + ret = kread_symbol(kvm, X_VM_NDOMAINS, &ndomains, + sizeof(ndomains), 0); + if (ret != 0) { + list->mtl_error = ret; + return (-1); + } ret = kread_symbol(kvm, X_UMA_KEGS, &uma_kegs, sizeof(uma_kegs), 0); if (ret != 0) { list->mtl_error = ret; @@ -450,10 +459,17 @@ skip_percpu: kz.uk_ipers; mtp->mt_byteslimit = mtp->mt_countlimit * mtp->mt_size; mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees; - for (ubp = LIST_FIRST(&uz.uz_buckets); ubp != - NULL; ubp = LIST_NEXT(&ub, ub_link)) { - ret = kread(kvm, ubp, &ub, sizeof(ub), 0); - mtp->mt_zonefree += ub.ub_cnt; + for (i = 0; i < ndomains; i++) { + ret = kread(kvm, &uz.uz_domain[i], &uzd, + sizeof(uzd), 0); + for (ubp = + LIST_FIRST(&uzd.uzd_buckets); + ubp != NULL; + ubp = LIST_NEXT(&ub, ub_link)) { + ret = kread(kvm, ubp, &ub, + sizeof(ub), 0); + mtp->mt_zonefree += ub.ub_cnt; + } } if (!((kz.uk_flags & UMA_ZONE_SECONDARY) && LIST_FIRST(&kz.uk_zones) != uzp)) { diff --git a/freebsd/lib/libutil/humanize_number.c b/freebsd/lib/libutil/humanize_number.c index 40668aa9..109b4f6a 100644 --- a/freebsd/lib/libutil/humanize_number.c +++ b/freebsd/lib/libutil/humanize_number.c @@ -147,7 +147,8 @@ humanize_number(char *buf, size_t len, int64_t quotient, */ for (i = 0; (quotient >= max || (quotient == max - 1 && - remainder >= divisordeccut)) && i < maxscale; i++) { + (remainder >= divisordeccut || remainder >= + divisor / 2))) && i < maxscale; i++) { remainder = quotient % divisor; quotient /= divisor; } diff --git a/freebsd/sbin/dhclient/clparse.c b/freebsd/sbin/dhclient/clparse.c index f35c9402..3466d90a 100644 --- a/freebsd/sbin/dhclient/clparse.c +++ b/freebsd/sbin/dhclient/clparse.c @@ -298,12 +298,12 @@ parse_client_statement(FILE *cfile, struct interface_info *ip, } } -int -parse_X(FILE *cfile, u_int8_t *buf, int max) +unsigned +parse_X(FILE *cfile, u_int8_t *buf, unsigned max) { int token; char *val; - int len; + unsigned len; token = peek_token(&val, cfile); if (token == NUMBER_OR_NAME || token == NUMBER) { @@ -687,14 +687,14 @@ parse_option_decl(FILE *cfile, struct option_data *options) int token; u_int8_t buf[4]; u_int8_t hunkbuf[1024]; - int hunkix = 0; + unsigned hunkix = 0; char *vendor; char *fmt; struct universe *universe; struct option *option; struct iaddr ip_addr; u_int8_t *dp; - int len; + unsigned len; int nul_term = 0; token = next_token(&val, cfile); diff --git a/freebsd/sbin/dhclient/conflex.c b/freebsd/sbin/dhclient/conflex.c index fce0458c..73b95d85 100644 --- a/freebsd/sbin/dhclient/conflex.c +++ b/freebsd/sbin/dhclient/conflex.c @@ -62,8 +62,8 @@ int eol_token; static char line1[81]; static char line2[81]; -static int lpos; -static int line; +static unsigned lpos; +static unsigned line; static int tlpos; static int tline; static int token; @@ -230,7 +230,8 @@ skip_to_eol(FILE *cfile) static int read_string(FILE *cfile) { - int i, c, bs = 0; + int c, bs = 0; + unsigned i; for (i = 0; i < sizeof(tokbuf); i++) { c = get_char(cfile); @@ -265,7 +266,8 @@ read_string(FILE *cfile) static int read_number(int c, FILE *cfile) { - int seenx = 0, i = 0, token = NUMBER; + int seenx = 0, token = NUMBER; + unsigned i = 0; tokbuf[i++] = c; for (; i < sizeof(tokbuf); i++) { @@ -292,7 +294,7 @@ read_number(int c, FILE *cfile) static int read_num_or_name(int c, FILE *cfile) { - int i = 0; + unsigned i = 0; int rv = NUMBER_OR_NAME; tokbuf[i++] = c; diff --git a/freebsd/sbin/dhclient/dhclient.c b/freebsd/sbin/dhclient/dhclient.c index b0dabdb8..51fa6081 100644 --- a/freebsd/sbin/dhclient/dhclient.c +++ b/freebsd/sbin/dhclient/dhclient.c @@ -152,7 +152,7 @@ int findproto(char *cp, int n) { struct sockaddr *sa; - int i; + unsigned i; if (n == 0) return -1; @@ -182,7 +182,7 @@ struct sockaddr * get_ifa(char *cp, int n) { struct sockaddr *sa; - int i; + unsigned i; if (n == 0) return (NULL); @@ -197,7 +197,7 @@ get_ifa(char *cp, int n) return (NULL); } -struct iaddr defaddr = { 4 }; +struct iaddr defaddr = { .len = 4 }; uint8_t curbssid[6]; static void @@ -239,7 +239,8 @@ routehandler(struct protocol *p) n = read(routefd, &msg, sizeof(msg)); rtm = (struct rt_msghdr *)msg; - if (n < sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen || + if (n < (ssize_t)sizeof(rtm->rtm_msglen) || + n < (ssize_t)rtm->rtm_msglen || rtm->rtm_version != RTM_VERSION) return; @@ -2061,7 +2062,8 @@ priv_script_write_params(char *prefix, struct client_lease *lease) { struct interface_info *ip = ifi; u_int8_t dbuf[1500], *dp = NULL; - int i, len; + int i; + size_t len; char tbuf[128]; script_set_env(ip->client, prefix, "ip_address", @@ -2211,12 +2213,14 @@ script_write_params(char *prefix, struct client_lease *lease) pr_len = strlen(prefix); hdr.code = IMSG_SCRIPT_WRITE_PARAMS; - hdr.len = sizeof(hdr) + sizeof(struct client_lease) + - sizeof(size_t) + fn_len + sizeof(size_t) + sn_len + - sizeof(size_t) + pr_len; + hdr.len = sizeof(hdr) + sizeof(*lease) + + sizeof(fn_len) + fn_len + sizeof(sn_len) + sn_len + + sizeof(pr_len) + pr_len; - for (i = 0; i < 256; i++) - hdr.len += sizeof(int) + lease->options[i].len; + for (i = 0; i < 256; i++) { + hdr.len += sizeof(lease->options[i].len); + hdr.len += lease->options[i].len; + } scripttime = time(NULL); @@ -2225,7 +2229,7 @@ script_write_params(char *prefix, struct client_lease *lease) errs = 0; errs += buf_add(buf, &hdr, sizeof(hdr)); - errs += buf_add(buf, lease, sizeof(struct client_lease)); + errs += buf_add(buf, lease, sizeof(*lease)); errs += buf_add(buf, &fn_len, sizeof(fn_len)); errs += buf_add(buf, lease->filename, fn_len); errs += buf_add(buf, &sn_len, sizeof(sn_len)); @@ -2330,7 +2334,8 @@ void script_set_env(struct client_state *client, const char *prefix, const char *name, const char *value) { - int i, j, namelen; + int i, namelen; + size_t j; /* No `` or $() command substitution allowed in environment values! */ for (j=0; j < strlen(value); j++) @@ -2398,7 +2403,7 @@ script_flush_env(struct client_state *client) int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option) { - int i; + size_t i; for (i = 0; option->name[i]; i++) { if (i + 1 == buflen) diff --git a/freebsd/sbin/dhclient/dhcpd.h b/freebsd/sbin/dhclient/dhcpd.h index 3fd51ee3..ad64a441 100644 --- a/freebsd/sbin/dhclient/dhcpd.h +++ b/freebsd/sbin/dhclient/dhcpd.h @@ -85,7 +85,7 @@ #define REMOTE_PORT 67 struct option_data { - int len; + size_t len; u_int8_t *data; }; @@ -95,7 +95,7 @@ struct string_list { }; struct iaddr { - int len; + size_t len; unsigned char iabuf[16]; }; @@ -288,9 +288,9 @@ char *parse_string(FILE *); int parse_ip_addr(FILE *, struct iaddr *); void parse_hardware_param(FILE *, struct hardware *); void parse_lease_time(FILE *, time_t *); -unsigned char *parse_numeric_aggregate(FILE *, unsigned char *, int *, - int, int, int); -void convert_num(unsigned char *, char *, int, int); +unsigned char *parse_numeric_aggregate(FILE *, unsigned char *, size_t *, + int, unsigned, int); +void convert_num(unsigned char *, char *, unsigned, int); time_t parse_date(FILE *); /* tree.c */ @@ -427,7 +427,7 @@ int read_client_conf(void); void read_client_leases(void); void parse_client_statement(FILE *, struct interface_info *, struct client_config *); -int parse_X(FILE *, u_int8_t *, int); +unsigned parse_X(FILE *, u_int8_t *, unsigned); int parse_option_list(FILE *, u_int8_t *); void parse_interface_declaration(FILE *, struct client_config *); struct interface_info *interface_or_dummy(char *); diff --git a/freebsd/sbin/dhclient/inet.c b/freebsd/sbin/dhclient/inet.c index 8ed88886..4992ffcb 100644 --- a/freebsd/sbin/dhclient/inet.c +++ b/freebsd/sbin/dhclient/inet.c @@ -58,7 +58,7 @@ struct iaddr subnet_number(struct iaddr addr, struct iaddr mask) { struct iaddr rv; - int i; + unsigned i; rv.len = 0; @@ -81,7 +81,7 @@ struct iaddr broadcast_addr(struct iaddr subnet, struct iaddr mask) { struct iaddr rv; - int i; + unsigned i; if (subnet.len != mask.len) { rv.len = 0; diff --git a/freebsd/sbin/dhclient/options.c b/freebsd/sbin/dhclient/options.c index c08c5c53..fad7dacd 100644 --- a/freebsd/sbin/dhclient/options.c +++ b/freebsd/sbin/dhclient/options.c @@ -57,11 +57,11 @@ int bad_options_max = 5; void parse_options(struct packet *); void parse_option_buffer(struct packet *, unsigned char *, int); -int store_options(unsigned char *, int, struct tree_cache **, +unsigned store_options(unsigned char *, int, struct tree_cache **, unsigned char *, int, int, int, int); void expand_domain_search(struct packet *packet); -int find_search_domain_name_len(struct option_data *option, int *offset); -void expand_search_domain_name(struct option_data *option, int *offset, +int find_search_domain_name_len(struct option_data *option, size_t *offset); +void expand_search_domain_name(struct option_data *option, size_t *offset, unsigned char **domain_search); @@ -215,7 +215,8 @@ parse_option_buffer(struct packet *packet, void expand_domain_search(struct packet *packet) { - int offset, expanded_len, next_domain_len; + size_t offset; + int expanded_len, next_domain_len; struct option_data *option; unsigned char *domain_search, *cursor; @@ -259,9 +260,10 @@ expand_domain_search(struct packet *packet) } int -find_search_domain_name_len(struct option_data *option, int *offset) +find_search_domain_name_len(struct option_data *option, size_t *offset) { - int domain_name_len, i, label_len, pointer, pointed_len; + int domain_name_len, label_len, pointed_len; + size_t i, pointer; domain_name_len = 0; @@ -326,10 +328,11 @@ find_search_domain_name_len(struct option_data *option, int *offset) } void -expand_search_domain_name(struct option_data *option, int *offset, +expand_search_domain_name(struct option_data *option, size_t *offset, unsigned char **domain_search) { - int i, label_len, pointer; + int label_len; + size_t i, pointer; unsigned char *cursor; /* @@ -383,8 +386,10 @@ cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, int terminate, int bootpp, u_int8_t *prl, int prl_len) { unsigned char priority_list[300], buffer[4096]; - int priority_len, main_buffer_size, mainbufix, bufix; - int option_size, length; + unsigned priority_len; + size_t main_buffer_size; + unsigned option_size, bufix, mainbufix; + int length; /* * If the client has provided a maximum DHCP message size, use @@ -426,7 +431,7 @@ cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, */ if (inpacket && inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data) { - int prlen = + unsigned prlen = inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].len; if (prlen + priority_len > sizeof(priority_list)) prlen = sizeof(priority_list) - priority_len; @@ -520,7 +525,7 @@ cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, /* * Store all the requested options into the requested buffer. */ -int +unsigned store_options(unsigned char *buffer, int buflen, struct tree_cache **options, unsigned char *priority_list, int priority_len, int first_cutoff, int second_cutoff, int terminate) diff --git a/freebsd/sbin/dhclient/packet.c b/freebsd/sbin/dhclient/packet.c index 40e969ae..b3c719b2 100644 --- a/freebsd/sbin/dhclient/packet.c +++ b/freebsd/sbin/dhclient/packet.c @@ -62,7 +62,7 @@ u_int32_t wrapsum(u_int32_t); u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum) { - int i; + unsigned i; /* Checksum all the pairs of bytes first... */ for (i = 0; i < (nbytes & ~1U); i += 2) { diff --git a/freebsd/sbin/dhclient/parse.c b/freebsd/sbin/dhclient/parse.c index 45234e58..a46f6311 100644 --- a/freebsd/sbin/dhclient/parse.c +++ b/freebsd/sbin/dhclient/parse.c @@ -47,6 +47,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <stdbool.h> + #include "dhcpd.h" #include "dhctoken.h" @@ -160,7 +162,8 @@ void parse_hardware_param(FILE *cfile, struct hardware *hardware) { unsigned char *t; - int token, hlen; + int token; + size_t hlen; char *val; token = next_token(&val, cfile); @@ -244,13 +247,13 @@ parse_lease_time(FILE *cfile, time_t *timep) * tokenized. */ unsigned char * -parse_numeric_aggregate(FILE *cfile, unsigned char *buf, int *max, - int separator, int base, int size) +parse_numeric_aggregate(FILE *cfile, unsigned char *buf, size_t *max, + int separator, unsigned base, int size) { unsigned char *bufp = buf, *s = NULL; - int token, count = 0; + int token; char *val, *t; - size_t valsize; + size_t valsize, count = 0; pair c = NULL; unsigned char *lbufp = NULL; @@ -331,14 +334,15 @@ parse_numeric_aggregate(FILE *cfile, unsigned char *buf, int *max, } void -convert_num(unsigned char *buf, char *str, int base, int size) +convert_num(unsigned char *buf, char *str, unsigned base, int size) { - int negative = 0, tval, max; + bool negative = false; + unsigned tval, max; u_int32_t val = 0; char *ptr = str; if (*ptr == '-') { - negative = 1; + negative = true; ptr++; } diff --git a/freebsd/sbin/dhclient/privsep.c b/freebsd/sbin/dhclient/privsep.c index b1cf5106..0b0d8771 100644 --- a/freebsd/sbin/dhclient/privsep.c +++ b/freebsd/sbin/dhclient/privsep.c @@ -78,7 +78,8 @@ buf_close(int sock, struct buf *buf) ssize_t buf_read(int sock, void *buf, size_t nbytes) { - ssize_t n, r = 0; + ssize_t n; + size_t r = 0; char *p = buf; do { @@ -86,7 +87,7 @@ buf_read(int sock, void *buf, size_t nbytes) if (n == 0) error("connection closed"); if (n != -1) { - r += n; + r += (size_t)n; p += n; nbytes -= n; } @@ -109,9 +110,9 @@ dispatch_imsg(struct interface_info *ifi, int fd) char *medium, *reason, *filename, *servername, *prefix; size_t medium_len, reason_len, filename_len, - servername_len, prefix_len, totlen; + servername_len, optlen, prefix_len, totlen; struct client_lease lease; - int ret, i, optlen; + int ret, i; struct buf *buf; u_int16_t mtu; diff --git a/freebsd/sbin/dhclient/tree.c b/freebsd/sbin/dhclient/tree.c index bc94e2aa..526dd80f 100644 --- a/freebsd/sbin/dhclient/tree.c +++ b/freebsd/sbin/dhclient/tree.c @@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$"); #include "dhcpd.h" -extern int h_errno; - pair cons(caddr_t car, pair cdr) { diff --git a/freebsd/sbin/ifconfig/sfp.c b/freebsd/sbin/ifconfig/sfp.c index b061927e..0aa3300d 100644 --- a/freebsd/sbin/ifconfig/sfp.c +++ b/freebsd/sbin/ifconfig/sfp.c @@ -88,7 +88,7 @@ struct _nv { const char *find_value(struct _nv *x, int value); const char *find_zero_bit(struct _nv *x, int value, int sz); -/* SFF-8472 Rev. 11.4 table 3.4: Connector values */ +/* SFF-8024 Rev. 4.1 Table 4-3: Connector Types */ static struct _nv conn[] = { { 0x00, "Unknown" }, { 0x01, "SC" }, @@ -106,7 +106,8 @@ static struct _nv conn[] = { { 0x20, "HSSDC II" }, { 0x21, "Copper pigtail" }, { 0x22, "RJ45" }, - { 0x23, "No separate connector" }, /* SFF-8436 */ + { 0x23, "No separable connector" }, + { 0x24, "MXC 2x16" }, { 0, NULL } }; @@ -202,10 +203,17 @@ static struct _nv eth_1040g[] = { }; #define SFF_8636_EXT_COMPLIANCE 0x80 -/* SFF-8024 Rev. 3.4 table 4.4: Extended Specification Compliance */ +/* SFF-8024 Rev. 4.2 table 4-4: Extended Specification Compliance */ static struct _nv eth_extended_comp[] = { { 0xFF, "Reserved" }, - { 0x1A, "2 lambda DWDM 100G" }, + { 0x21, "100G PAM4 BiDi" }, + { 0x20, "100G SWDM4" }, + { 0x1F, "40G SWDM4" }, + { 0x1E, "2.5GBASE-T" }, + { 0x1D, "5GBASE-T" }, + { 0x1C, "10GBASE-T Short Reach" }, + { 0x1B, "100G 1550nm WDM" }, + { 0x1A, "100GE-DWDM2" }, { 0x19, "100G ACC or 25GAUI C2M ACC" }, { 0x18, "100G AOC or 25GAUI C2M AOC" }, { 0x17, "100G CLR4" }, @@ -217,23 +225,24 @@ static struct _nv eth_extended_comp[] = { { 0x11, "4 x 10GBASE-SR" }, { 0x10, "40GBASE-ER4" }, { 0x0F, "Reserved" }, + { 0x0E, "Reserved" }, { 0x0D, "25GBASE-CR CA-N" }, { 0x0C, "25GBASE-CR CA-S" }, { 0x0B, "100GBASE-CR4 or 25GBASE-CR CA-L" }, { 0x0A, "Reserved" }, - { 0x09, "100G CWDM4 MSA without FEC" }, - { 0x08, "100G ACC (Active Copper Cable)" }, + { 0x09, "Obsolete" }, + { 0x08, "100G ACC (Active Copper Cable) or 25GAUI C2M ACC" }, { 0x07, "100G PSM4 Parallel SMF" }, - { 0x06, "100G CWDM4 MSA with FEC" }, + { 0x06, "100G CWDM4" }, { 0x05, "100GBASE-SR10" }, - { 0x04, "100GBASE-ER4" }, - { 0x03, "100GBASE-LR4" }, - { 0x02, "100GBASE-SR4" }, - { 0x01, "100G AOC (Active Optical Cable) or 25GAUI C2M ACC" }, + { 0x04, "100GBASE-ER4 or 25GBASE-ER" }, + { 0x03, "100GBASE-LR4 or 25GBASE-LR" }, + { 0x02, "100GBASE-SR4 or 25GBASE-SR" }, + { 0x01, "100G AOC (Active Optical Cable) or 25GAUI C2M AOC" }, { 0x00, "Unspecified" } }; -/* SFF-8636 Rev. 2.5 table 6.3: Revision compliance */ +/* SFF-8636 Rev. 2.9 table 6.3: Revision compliance */ static struct _nv rev_compl[] = { { 0x1, "SFF-8436 rev <=4.8" }, { 0x2, "SFF-8436 rev <=4.8" }, @@ -241,7 +250,8 @@ static struct _nv rev_compl[] = { { 0x4, "SFF-8636 rev <=1.4" }, { 0x5, "SFF-8636 rev <=1.5" }, { 0x6, "SFF-8636 rev <=2.0" }, - { 0x7, "SFF-8636 rev <=2.5" }, + { 0x7, "SFF-8636 rev <=2.7" }, + { 0x8, "SFF-8636 rev >=2.8" }, { 0x0, "Unspecified" } }; @@ -397,17 +407,20 @@ get_sfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size) const char *tech_class; uint8_t code; - unsigned char qbuf[8]; - read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, (uint8_t *)qbuf); - - /* Check 10G Ethernet/IB first */ - read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, &code); - tech_class = find_zero_bit(eth_10g, code, 1); - if (tech_class == NULL) { - /* No match. Try Ethernet 1G */ - read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3, - 1, (caddr_t)&code); - tech_class = find_zero_bit(eth_compat, code, 1); + /* Use extended compliance code if it's valid */ + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS, 1, &code); + if (code != 0) + tech_class = find_value(eth_extended_comp, code); + else { + /* Next, check 10G Ethernet/IB CCs */ + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, &code); + tech_class = find_zero_bit(eth_10g, code, 1); + if (tech_class == NULL) { + /* No match. Try Ethernet 1G */ + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3, + 1, (caddr_t)&code); + tech_class = find_zero_bit(eth_compat, code, 1); + } } if (tech_class == NULL) diff --git a/freebsd/sbin/pfctl/pfctl.c b/freebsd/sbin/pfctl/pfctl.c index f0b963df..c814a816 100644 --- a/freebsd/sbin/pfctl/pfctl.c +++ b/freebsd/sbin/pfctl/pfctl.c @@ -1536,6 +1536,7 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, if (pfctl_trans(dev, t, DIOCXCOMMIT, osize)) ERR("DIOCXCOMMIT"); } + free(path); return (0); _error: @@ -1545,6 +1546,7 @@ _error: err(1, "DIOCXROLLBACK"); exit(1); } else { /* sub ruleset */ + free(path); return (-1); } diff --git a/freebsd/sbin/pfctl/pfctl_optimize.c b/freebsd/sbin/pfctl/pfctl_optimize.c index 89cebe91..cbf94e80 100644 --- a/freebsd/sbin/pfctl/pfctl_optimize.c +++ b/freebsd/sbin/pfctl/pfctl_optimize.c @@ -1115,7 +1115,7 @@ skip_cmp_dst_addr(struct pf_rule *a, struct pf_rule *b) return (0); case PF_ADDR_DYNIFTL: if (strcmp(a->dst.addr.v.ifname, b->dst.addr.v.ifname) != 0 || - a->dst.addr.iflags != a->dst.addr.iflags || + a->dst.addr.iflags != b->dst.addr.iflags || memcmp(&a->dst.addr.v.a.mask, &b->dst.addr.v.a.mask, sizeof(a->dst.addr.v.a.mask))) return (1); @@ -1187,7 +1187,7 @@ skip_cmp_src_addr(struct pf_rule *a, struct pf_rule *b) return (0); case PF_ADDR_DYNIFTL: if (strcmp(a->src.addr.v.ifname, b->src.addr.v.ifname) != 0 || - a->src.addr.iflags != a->src.addr.iflags || + a->src.addr.iflags != b->src.addr.iflags || memcmp(&a->src.addr.v.a.mask, &b->src.addr.v.a.mask, sizeof(a->src.addr.v.a.mask))) return (1); diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h index 8e88b4a3..642e7862 100644 --- a/freebsd/sys/cam/cam_ccb.h +++ b/freebsd/sys/cam/cam_ccb.h @@ -519,7 +519,6 @@ struct device_match_result { struct scsi_inquiry_data inq_data; struct ata_params ident_data; dev_result_flags flags; - struct mmc_params mmc_ident_data; }; struct bus_match_result { @@ -646,6 +645,11 @@ struct ccb_pathinq_settings_sas { struct ccb_pathinq_settings_nvme { uint32_t nsid; /* Namespace ID for this path */ + uint32_t domain; + uint8_t bus; + uint8_t slot; + uint8_t function; + uint8_t extra; }; #define PATHINQ_SETTINGS_SIZE 128 @@ -1296,6 +1300,7 @@ struct ccb_dev_advinfo { #define CDAI_TYPE_EXT_INQ 5 #define CDAI_TYPE_NVME_CNTRL 6 /* NVMe Identify Controller data */ #define CDAI_TYPE_NVME_NS 7 /* NVMe Identify Namespace data */ +#define CDAI_TYPE_MMC_PARAMS 8 /* MMC/SD ident */ off_t bufsiz; /* IN: Size of external buffer */ #define CAM_SCSI_DEVID_MAXLEN 65536 /* length in buffer is an uint16_t */ off_t provsiz; /* OUT: Size required/used */ diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h index b7f0618e..ee9a5fc0 100644 --- a/freebsd/sys/cam/cam_periph.h +++ b/freebsd/sys/cam/cam_periph.h @@ -197,12 +197,15 @@ void cam_periph_freeze_after_event(struct cam_periph *periph, struct timeval* event_time, u_int duration_ms); int cam_periph_error(union ccb *ccb, cam_flags camflags, - u_int32_t sense_flags, union ccb *save_ccb); + u_int32_t sense_flags); static __inline struct mtx * cam_periph_mtx(struct cam_periph *periph) { - return (xpt_path_mtx(periph->path)); + if (periph != NULL) + return (xpt_path_mtx(periph->path)); + else + return (NULL); } #define cam_periph_owned(periph) \ @@ -257,5 +260,8 @@ cam_periph_acquire_next(struct cam_periph *pperiph) (periph) != NULL; \ (periph) = cam_periph_acquire_next(periph)) +#define CAM_PERIPH_PRINT(p, msg, args...) \ + printf("%s%d:" msg, (periph)->periph_name, (periph)->unit_number, ##args) + #endif /* _KERNEL */ #endif /* _CAM_CAM_PERIPH_H */ diff --git a/freebsd/sys/cam/cam_xpt.h b/freebsd/sys/cam/cam_xpt.h index 8baec294..fb49c893 100644 --- a/freebsd/sys/cam/cam_xpt.h +++ b/freebsd/sys/cam/cam_xpt.h @@ -36,8 +36,10 @@ #ifdef _KERNEL #include <sys/cdefs.h> +#include <cam/cam_ccb.h> #endif + /* Forward Declarations */ union ccb; struct cam_periph; @@ -144,6 +146,22 @@ void xpt_copy_path(struct cam_path *new_path, void xpt_release_path(struct cam_path *path); const char * xpt_action_name(uint32_t action); +void xpt_pollwait(union ccb *start_ccb, uint32_t timeout); +uint32_t xpt_poll_setup(union ccb *start_ccb); + +/* + * Perform a path inquiry at the request priority. The bzero may be + * unnecessary. + */ +static inline void +xpt_path_inq(struct ccb_pathinq *cpi, struct cam_path *path) +{ + + bzero(cpi, sizeof(*cpi)); + xpt_setup_ccb(&cpi->ccb_h, path, CAM_PRIORITY_NORMAL); + cpi->ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)cpi); +} #endif /* _KERNEL */ diff --git a/freebsd/sys/cam/mmc/mmc.h b/freebsd/sys/cam/mmc/mmc.h index 2e31f029..9b9659fe 100644 --- a/freebsd/sys/cam/mmc/mmc.h +++ b/freebsd/sys/cam/mmc/mmc.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2014-2016 Ilya Bakulin. All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/freebsd/sys/cam/mmc/mmc_all.h b/freebsd/sys/cam/mmc/mmc_all.h index c2494894..cbc32c0d 100644 --- a/freebsd/sys/cam/mmc/mmc_all.h +++ b/freebsd/sys/cam/mmc/mmc_all.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2014-2016 Ilya Bakulin. All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/freebsd/sys/cam/nvme/nvme_all.h b/freebsd/sys/cam/nvme/nvme_all.h index b2db4833..fa229846 100644 --- a/freebsd/sys/cam/nvme/nvme_all.h +++ b/freebsd/sys/cam/nvme/nvme_all.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2015 Netflix, Inc * All rights reserved. * diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c index d344cc14..1a469f32 100644 --- a/freebsd/sys/cam/scsi/scsi_all.c +++ b/freebsd/sys/cam/scsi/scsi_all.c @@ -1,10 +1,10 @@ #include <machine/rtems-bsd-kernel-space.h> /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * * Implementation of Utility functions for all SCSI device types. * + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry. * All rights reserved. diff --git a/freebsd/sys/dev/cadence/if_cgem.c b/freebsd/sys/dev/cadence/if_cgem.c index 42fd4213..191362c4 100644 --- a/freebsd/sys/dev/cadence/if_cgem.c +++ b/freebsd/sys/dev/cadence/if_cgem.c @@ -895,7 +895,7 @@ cgem_start_locked(if_t ifp) WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow | CGEM_NET_CTRL_START_TX); - /* If there is a BPF listener, bounce a copy to to him. */ + /* If there is a BPF listener, bounce a copy to him. */ ETHER_BPF_MTAP(ifp, m); } } diff --git a/freebsd/sys/dev/e1000/e1000_82543.c b/freebsd/sys/dev/e1000/e1000_82543.c index dbaa4a6e..0bd0c6d5 100644 --- a/freebsd/sys/dev/e1000/e1000_82543.c +++ b/freebsd/sys/dev/e1000/e1000_82543.c @@ -1312,7 +1312,7 @@ static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) * turn it on. For compatibility with a TBI link * partner, we will store bad packets. Some * frames have an additional byte on the end and - * will look like CRC errors to to the hardware. + * will look like CRC errors to the hardware. */ if (!e1000_tbi_sbp_enabled_82543(hw)) { e1000_set_tbi_sbp_82543(hw, TRUE); diff --git a/freebsd/sys/dev/e1000/e1000_82575.h b/freebsd/sys/dev/e1000/e1000_82575.h index 7e127ed7..a96b25f4 100644 --- a/freebsd/sys/dev/e1000/e1000_82575.h +++ b/freebsd/sys/dev/e1000/e1000_82575.h @@ -385,7 +385,7 @@ struct e1000_adv_tx_context_desc { #define E1000_ETQF_FILTER_ENABLE (1 << 26) #define E1000_ETQF_IMM_INT (1 << 29) #define E1000_ETQF_1588 (1 << 30) -#define E1000_ETQF_QUEUE_ENABLE (1 << 31) +#define E1000_ETQF_QUEUE_ENABLE (1U << 31) /* * ETQF filter list: one static filter per filter consumer. This is * to avoid filter collisions later. Add new filters @@ -412,7 +412,7 @@ struct e1000_adv_tx_context_desc { #define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */ #define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8 #define E1000_DTXSWC_LLE_SHIFT 16 -#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ +#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1U << 31) /* global VF LB enable */ /* Easy defines for setting default pool, would normally be left a zero */ #define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7 diff --git a/freebsd/sys/dev/e1000/e1000_api.c b/freebsd/sys/dev/e1000/e1000_api.c index 393a22e2..c351901c 100644 --- a/freebsd/sys/dev/e1000/e1000_api.c +++ b/freebsd/sys/dev/e1000/e1000_api.c @@ -313,6 +313,16 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_PCH_SPT_I219_V5: mac->type = e1000_pch_spt; break; + case E1000_DEV_ID_PCH_CNP_I219_LM6: + case E1000_DEV_ID_PCH_CNP_I219_V6: + case E1000_DEV_ID_PCH_CNP_I219_LM7: + case E1000_DEV_ID_PCH_CNP_I219_V7: + case E1000_DEV_ID_PCH_ICP_I219_LM8: + case E1000_DEV_ID_PCH_ICP_I219_V8: + case E1000_DEV_ID_PCH_ICP_I219_LM9: + case E1000_DEV_ID_PCH_ICP_I219_V9: + mac->type = e1000_pch_cnp; + break; case E1000_DEV_ID_82575EB_COPPER: case E1000_DEV_ID_82575EB_FIBER_SERDES: case E1000_DEV_ID_82575GB_QUAD_COPPER: @@ -464,6 +474,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: e1000_init_function_pointers_ich8lan(hw); break; case e1000_82575: diff --git a/freebsd/sys/dev/e1000/e1000_hw.h b/freebsd/sys/dev/e1000/e1000_hw.h index 82e783fe..2c17a022 100644 --- a/freebsd/sys/dev/e1000/e1000_hw.h +++ b/freebsd/sys/dev/e1000/e1000_hw.h @@ -147,6 +147,14 @@ struct e1000_hw; #define E1000_DEV_ID_PCH_SPT_I219_V4 0x15D8 #define E1000_DEV_ID_PCH_SPT_I219_LM5 0x15E3 #define E1000_DEV_ID_PCH_SPT_I219_V5 0x15D6 +#define E1000_DEV_ID_PCH_CNP_I219_LM6 0x15BD +#define E1000_DEV_ID_PCH_CNP_I219_V6 0x15BE +#define E1000_DEV_ID_PCH_CNP_I219_LM7 0x15BB +#define E1000_DEV_ID_PCH_CNP_I219_V7 0x15BC +#define E1000_DEV_ID_PCH_ICP_I219_LM8 0x15DF +#define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0 +#define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1 +#define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2 #define E1000_DEV_ID_82576 0x10C9 #define E1000_DEV_ID_82576_FIBER 0x10E6 #define E1000_DEV_ID_82576_SERDES 0x10E7 @@ -233,6 +241,7 @@ enum e1000_mac_type { e1000_pch2lan, e1000_pch_lpt, e1000_pch_spt, + e1000_pch_cnp, e1000_82575, e1000_82576, e1000_82580, diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.c b/freebsd/sys/dev/e1000/e1000_ich8lan.c index b78b7283..bcd82c47 100644 --- a/freebsd/sys/dev/e1000/e1000_ich8lan.c +++ b/freebsd/sys/dev/e1000/e1000_ich8lan.c @@ -347,6 +347,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: if (e1000_phy_is_accessible_pchlan(hw)) break; @@ -495,6 +496,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: /* In case the PHY needs to be in mdio slow mode, * set slow mode and try to get the PHY id again. */ @@ -796,6 +798,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) /* fall-through */ case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: /* multicast address update for pch2 */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_pch2lan; @@ -1833,6 +1836,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: hw->phy.ops.init_params = e1000_init_phy_params_pchlan; break; default: @@ -2297,6 +2301,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; break; default: @@ -2657,6 +2662,8 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) e1000_phy_sw_reset_generic(hw); ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, 0x3140); + if (ret_val) + return ret_val; } } @@ -3414,6 +3421,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) switch (hw->mac.type) { case e1000_pch_spt: + case e1000_pch_cnp: bank1_offset = nvm->flash_bank_size; act_offset = E1000_ICH_NVM_SIG_WORD; @@ -4389,6 +4397,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: word = NVM_COMPAT; valid_csum_mask = NVM_COMPAT_VALID_CSUM; break; @@ -5195,7 +5204,7 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) /* Device Status */ if (hw->mac.type == e1000_ich8lan) { reg = E1000_READ_REG(hw, E1000_STATUS); - reg &= ~(1 << 31); + reg &= ~(1U << 31); E1000_WRITE_REG(hw, E1000_STATUS, reg); } diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.h b/freebsd/sys/dev/e1000/e1000_ich8lan.h index d61f4df8..db37aab7 100644 --- a/freebsd/sys/dev/e1000/e1000_ich8lan.h +++ b/freebsd/sys/dev/e1000/e1000_ich8lan.h @@ -124,7 +124,8 @@ #define NVM_SIZE_MULTIPLIER 4096 /*multiplier for NVMS field*/ #define E1000_FLASH_BASE_ADDR 0xE000 /*offset of NVM access regs*/ #define E1000_CTRL_EXT_NVMVS 0x3 /*NVM valid sector */ -#define E1000_TARC0_CB_MULTIQ_3_REQ (1 << 28 | 1 << 29) +#define E1000_TARC0_CB_MULTIQ_3_REQ 0x30000000 +#define E1000_TARC0_CB_MULTIQ_2_REQ 0x20000000 #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL #define E1000_ICH_RAR_ENTRIES 7 diff --git a/freebsd/sys/dev/e1000/e1000_regs.h b/freebsd/sys/dev/e1000/e1000_regs.h index d9949817..246968e9 100644 --- a/freebsd/sys/dev/e1000/e1000_regs.h +++ b/freebsd/sys/dev/e1000/e1000_regs.h @@ -215,7 +215,7 @@ /* QAV Tx mode control register bitfields masks */ #define E1000_TQAVCC_IDLE_SLOPE 0xFFFF /* Idle slope */ #define E1000_TQAVCC_KEEP_CREDITS (1 << 30) /* Keep credits opt enable */ -#define E1000_TQAVCC_QUEUE_MODE (1 << 31) /* SP vs. SR Tx mode */ +#define E1000_TQAVCC_QUEUE_MODE (1U << 31) /* SP vs. SR Tx mode */ /* Good transmitted packets counter registers */ #define E1000_PQGPTC(_n) (0x010014 + (0x100 * (_n))) diff --git a/freebsd/sys/dev/e1000/em_txrx.c b/freebsd/sys/dev/e1000/em_txrx.c index 2183a8bd..9286f0ea 100644 --- a/freebsd/sys/dev/e1000/em_txrx.c +++ b/freebsd/sys/dev/e1000/em_txrx.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-kernel-space.h> /*- - * Copyright (c) 2016-2017 Matt Macy <mmacy@nextbsd.org> + * Copyright (c) 2016-2017 Matthew Macy <mmacy@mattmacy.io> * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c index 07acaad9..94159e31 100644 --- a/freebsd/sys/dev/e1000/if_em.c +++ b/freebsd/sys/dev/e1000/if_em.c @@ -3,7 +3,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org> + * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -168,6 +168,14 @@ static pci_vendor_info_t em_vendor_info_array[] = PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V4, "Intel(R) PRO/1000 Network Connection"), PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM5, "Intel(R) PRO/1000 Network Connection"), PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V5, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_LM6, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_V6, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_LM7, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_CNP_I219_V7, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_LM8, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V8, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_LM9, "Intel(R) PRO/1000 Network Connection"), + PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V9, "Intel(R) PRO/1000 Network Connection"), /* required last entry */ PVID_END }; @@ -864,7 +872,7 @@ em_if_attach_pre(if_ctx_t ctx) ** so use the same tag and an offset handle for the ** FLASH read/write macros in the shared code. */ - else if (hw->mac.type == e1000_pch_spt) { + else if (hw->mac.type >= e1000_pch_spt) { adapter->osdep.flash_bus_space_tag = adapter->osdep.mem_bus_space_tag; adapter->osdep.flash_bus_space_handle = @@ -1134,6 +1142,7 @@ em_if_mtu_set(if_ctx_t ctx, uint32_t mtu) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: case e1000_82574: case e1000_82583: case e1000_80003es2lan: @@ -2418,6 +2427,7 @@ em_reset(if_ctx_t ctx) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: pba = E1000_PBA_26K; break; case e1000_82575: @@ -2526,6 +2536,7 @@ em_reset(if_ctx_t ctx) case e1000_pch2lan: case e1000_pch_lpt: case e1000_pch_spt: + case e1000_pch_cnp: hw->fc.high_water = 0x5C20; hw->fc.low_water = 0x5048; hw->fc.pause_time = 0x0650; @@ -3056,13 +3067,16 @@ em_initialize_transmit_unit(if_ctx_t ctx) /* This write will effectively turn on the transmit unit. */ E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl); + /* SPT and KBL errata workarounds */ if (hw->mac.type == e1000_pch_spt) { u32 reg; reg = E1000_READ_REG(hw, E1000_IOSFPC); reg |= E1000_RCTL_RDMTS_HEX; E1000_WRITE_REG(hw, E1000_IOSFPC, reg); + /* i218-i219 Specification Update 1.5.4.5 */ reg = E1000_READ_REG(hw, E1000_TARC(0)); - reg |= E1000_TARC0_CB_MULTIQ_3_REQ; + reg &= ~E1000_TARC0_CB_MULTIQ_3_REQ; + reg |= E1000_TARC0_CB_MULTIQ_2_REQ; E1000_WRITE_REG(hw, E1000_TARC(0), reg); } } diff --git a/freebsd/sys/dev/e1000/if_em.h b/freebsd/sys/dev/e1000/if_em.h index 4f9d34b8..0a6a09ca 100644 --- a/freebsd/sys/dev/e1000/if_em.h +++ b/freebsd/sys/dev/e1000/if_em.h @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org> + * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io> * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/freebsd/sys/dev/e1000/igb_txrx.c b/freebsd/sys/dev/e1000/igb_txrx.c index 2ed24e2d..05b2fff2 100644 --- a/freebsd/sys/dev/e1000/igb_txrx.c +++ b/freebsd/sys/dev/e1000/igb_txrx.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-kernel-space.h> /*- - * Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org> + * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -239,7 +239,7 @@ igb_isc_txd_encap(void *arg, if_pkt_info_t pi) int nsegs = pi->ipi_nsegs; bus_dma_segment_t *segs = pi->ipi_segs; union e1000_adv_tx_desc *txd = NULL; - int i, j, first, pidx_last; + int i, j, pidx_last; u32 olinfo_status, cmd_type_len, txd_flags; qidx_t ntxd; @@ -251,7 +251,7 @@ igb_isc_txd_encap(void *arg, if_pkt_info_t pi) if (pi->ipi_mflags & M_VLANTAG) cmd_type_len |= E1000_ADVTXD_DCMD_VLE; - first = i = pi->ipi_pidx; + i = pi->ipi_pidx; ntxd = scctx->isc_ntxd[0]; txd_flags = pi->ipi_flags & IPI_TX_INTR ? E1000_ADVTXD_DCMD_RS : 0; /* Consume the first descriptor */ diff --git a/freebsd/sys/dev/fdt/fdt_common.c b/freebsd/sys/dev/fdt/fdt_common.c index 26f73bc3..daa45832 100644 --- a/freebsd/sys/dev/fdt/fdt_common.c +++ b/freebsd/sys/dev/fdt/fdt_common.c @@ -157,7 +157,7 @@ fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size) pcell_t ranges[FDT_RANGES_SIZE], *rangesptr; pcell_t addr_cells, size_cells, par_addr_cells; u_long par_bus_addr, pbase, psize; - int err, len, tuple_size, tuples; + int err, len; if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) return (ENXIO); @@ -183,10 +183,6 @@ fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size) if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0) return (EINVAL); - tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells + - size_cells); - tuples = len / tuple_size; - if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2) return (ERANGE); @@ -602,11 +598,9 @@ fdt_get_reserved_regions(struct mem_region *mr, int *mrcnt) pcell_t reserve[FDT_REG_CELLS * FDT_MEM_REGIONS]; pcell_t *reservep; phandle_t memory, root; - uint32_t memory_size; int addr_cells, size_cells; - int i, max_size, res_len, rv, tuple_size, tuples; + int i, res_len, rv, tuple_size, tuples; - max_size = sizeof(reserve); root = OF_finddevice("/"); memory = OF_finddevice("/memory"); if (memory == -1) { @@ -636,7 +630,6 @@ fdt_get_reserved_regions(struct mem_region *mr, int *mrcnt) goto out; } - memory_size = 0; tuples = res_len / tuple_size; reservep = (pcell_t *)&reserve; for (i = 0; i < tuples; i++) { @@ -664,9 +657,8 @@ fdt_get_mem_regions(struct mem_region *mr, int *mrcnt, uint64_t *memsize) phandle_t memory; uint64_t memory_size; int addr_cells, size_cells; - int i, max_size, reg_len, rv, tuple_size, tuples; + int i, reg_len, rv, tuple_size, tuples; - max_size = sizeof(reg); memory = OF_finddevice("/memory"); if (memory == -1) { rv = ENXIO; diff --git a/freebsd/sys/dev/mmc/mmc.c b/freebsd/sys/dev/mmc/mmc.c index 32599383..2c3cba3d 100644 --- a/freebsd/sys/dev/mmc/mmc.c +++ b/freebsd/sys/dev/mmc/mmc.c @@ -1573,17 +1573,14 @@ mmc_host_timing(device_t dev, enum mmc_bus_timing timing) static void mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard) { - enum mmc_bus_timing max_timing, timing; + enum mmc_bus_timing timing; device_printf(dev, "Card at relative address 0x%04x%s:\n", ivar->rca, newcard ? " added" : ""); device_printf(dev, " card: %s\n", ivar->card_id_string); - max_timing = bus_timing_normal; for (timing = bus_timing_max; timing > bus_timing_normal; timing--) { - if (isset(&ivar->timings, timing)) { - max_timing = timing; + if (isset(&ivar->timings, timing)) break; - } } device_printf(dev, " quirks: %b\n", ivar->quirks, MMC_QUIRKS_FMT); device_printf(dev, " bus: %ubit, %uMHz (%s timing)\n", @@ -1885,7 +1882,7 @@ mmc_discover_cards(struct mmc_softc *sc) * units of 10 ms), defaulting to 500 ms. */ ivar->cmd6_time = 500 * 1000; - if (ivar->csd.spec_vers >= 6) + if (ivar->raw_ext_csd[EXT_CSD_REV] >= 6) ivar->cmd6_time = 10 * ivar->raw_ext_csd[EXT_CSD_GEN_CMD6_TIME]; /* Handle HC erase sector size. */ diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c index df29b544..94e6e73f 100644 --- a/freebsd/sys/dev/mmc/mmcsd.c +++ b/freebsd/sys/dev/mmc/mmcsd.c @@ -1005,11 +1005,9 @@ mmcsd_close(struct disk *dp __unused) static void mmcsd_strategy(struct bio *bp) { - struct mmcsd_softc *sc; struct mmcsd_part *part; part = bp->bio_disk->d_drv1; - sc = part->sc; MMCSD_DISK_LOCK(part); if (part->running > 0 || part->suspend > 0) { bioq_disksort(&part->bio_queue, bp); @@ -1169,6 +1167,16 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag) default: break; } + /* + * No partition switching in userland; it's almost impossible + * to recover from that, especially if things go wrong. + */ + if (cmd.opcode == MMC_SWITCH_FUNC && dp != NULL && + (((uint8_t *)dp)[EXT_CSD_PART_CONFIG] & + EXT_CSD_PART_CONFIG_ACC_MASK) != part->type) { + err = EINVAL; + goto out; + } } dev = sc->dev; mmcbus = sc->mmcbus; @@ -1189,7 +1197,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag) if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) { /* * If the request went to the RPMB partition, try to ensure - * that the command actually has completed ... + * that the command actually has completed. */ retries = MMCSD_CMD_RETRIES; do { @@ -1201,13 +1209,6 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag) break; DELAY(1000); } while (retries-- > 0); - -switch_back: - /* ... and always switch back to the default partition. */ - err = mmcsd_switch_part(mmcbus, dev, rca, - EXT_CSD_PART_CONFIG_ACC_DEFAULT); - if (err != MMC_ERR_NONE) - goto release; } /* * If EXT_CSD was changed, our copy is outdated now. Specifically, @@ -1219,6 +1220,17 @@ switch_back: if (err != MMC_ERR_NONE) goto release; } +switch_back: + if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) { + /* + * If the request went to the RPMB partition, always switch + * back to the default partition (see mmcsd_switch_part()). + */ + err = mmcsd_switch_part(mmcbus, dev, rca, + EXT_CSD_PART_CONFIG_ACC_DEFAULT); + if (err != MMC_ERR_NONE) + goto release; + } MMCBUS_RELEASE_BUS(mmcbus, dev); if (cmd.error != MMC_ERR_NONE) { switch (cmd.error) { diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c index c655e668..8406988f 100644 --- a/freebsd/sys/dev/ofw/ofw_bus_subr.c +++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c @@ -92,6 +92,7 @@ ofw_bus_gen_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, size_t buflen) { + *buf = '\0'; if (ofw_bus_get_name(child) != NULL) { strlcat(buf, "name=", buflen); strlcat(buf, ofw_bus_get_name(child), buflen); @@ -388,9 +389,8 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz, uint8_t *mptr; pcell_t paddrsz; pcell_t pintrsz; - int i, rsz, tsz; + int i, tsz; - rsz = -1; if (imapmsk != NULL) { for (i = 0; i < physsz; i++) ref[i] = uiregs[i] & uiimapmsk[i]; @@ -447,7 +447,7 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent, { pcell_t *map, mask, msi_base, rid_base, rid_length; ssize_t len; - uint32_t masked_rid, rid; + uint32_t masked_rid; int err, i; /* TODO: This should be OF_searchprop_alloc if we had it */ @@ -464,7 +464,6 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent, } err = ENOENT; - rid = 0; mask = 0xffffffff; OF_getencprop(node, "msi-map-mask", &mask, sizeof(mask)); diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c index 7bdf447b..b9266eb5 100644 --- a/freebsd/sys/dev/ofw/ofw_fdt.c +++ b/freebsd/sys/dev/ofw/ofw_fdt.c @@ -256,7 +256,7 @@ ofw_fdt_instance_to_package(ofw_t ofw, ihandle_t instance) static ssize_t ofw_fdt_getproplen(ofw_t ofw, phandle_t package, const char *propname) { - const struct fdt_property *prop; + const void *prop; int offset, len; offset = fdt_phandle_offset(package); @@ -264,7 +264,7 @@ ofw_fdt_getproplen(ofw_t ofw, phandle_t package, const char *propname) return (-1); len = -1; - prop = fdt_get_property(fdtp, offset, propname, &len); + prop = fdt_getprop(fdtp, offset, propname, &len); if (prop == NULL && strcmp(propname, "name") == 0) { /* Emulate the 'name' property */ @@ -341,7 +341,7 @@ static int ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf, size_t size) { - const struct fdt_property *prop; + const void *prop; const char *name; int offset; @@ -356,7 +356,7 @@ ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf, if (previous != NULL) { while (offset >= 0) { - prop = fdt_get_property_by_offset(fdtp, offset, NULL); + prop = fdt_getprop_by_offset(fdtp, offset, &name, NULL); if (prop == NULL) return (-1); /* Internal error */ @@ -365,17 +365,16 @@ ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf, return (0); /* No more properties */ /* Check if the last one was the one we wanted */ - name = fdt_string(fdtp, fdt32_to_cpu(prop->nameoff)); if (strcmp(name, previous) == 0) break; } } - prop = fdt_get_property_by_offset(fdtp, offset, &offset); + prop = fdt_getprop_by_offset(fdtp, offset, &name, &offset); if (prop == NULL) return (-1); /* Internal error */ - strncpy(buf, fdt_string(fdtp, fdt32_to_cpu(prop->nameoff)), size); + strncpy(buf, name, size); return (1); } @@ -439,8 +438,7 @@ ofw_fdt_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len) return (-1); } -#ifndef __rtems__ -#if defined(FDT_MARVELL) || defined(__powerpc__) +#if defined(FDT_MARVELL) static int ofw_fdt_fixup(ofw_t ofw) { @@ -483,13 +481,11 @@ ofw_fdt_fixup(ofw_t ofw) return (0); } #endif -#endif /* __rtems__ */ static int ofw_fdt_interpret(ofw_t ofw, const char *cmd, int nret, cell_t *retvals) { -#if defined(FDT_MARVELL) || defined(__powerpc__) -#ifndef __rtems__ +#if defined(FDT_MARVELL) int rv; /* @@ -508,9 +504,6 @@ ofw_fdt_interpret(ofw_t ofw, const char *cmd, int nret, cell_t *retvals) retvals[0] = rv; return (rv); -#else /* __rtems__ */ - return (0); -#endif /* __rtems__ */ #else return (0); #endif diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c index e492846d..7fbdc693 100644 --- a/freebsd/sys/dev/pci/pci.c +++ b/freebsd/sys/dev/pci/pci.c @@ -125,6 +125,8 @@ static void pci_resume_msi(device_t dev); static void pci_resume_msix(device_t dev); static int pci_remap_intr_method(device_t bus, device_t dev, u_int irq); +static void pci_hint_device_unit(device_t acdev, device_t child, + const char *name, int *unitp); static int pci_get_id_method(device_t dev, device_t child, enum pci_id_type type, uintptr_t *rid); @@ -164,6 +166,7 @@ static device_method_t pci_methods[] = { DEVMETHOD(bus_child_detached, pci_child_detached), DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method), DEVMETHOD(bus_child_location_str, pci_child_location_str_method), + DEVMETHOD(bus_hint_device_unit, pci_hint_device_unit), DEVMETHOD(bus_remap_intr, pci_remap_intr_method), DEVMETHOD(bus_suspend_child, pci_suspend_child), DEVMETHOD(bus_resume_child, pci_resume_child), @@ -3987,7 +3990,6 @@ pci_rescan_method(device_t dev) { #define REG(n, w) PCIB_READ_CONFIG(pcib, busno, s, f, n, w) device_t pcib = device_get_parent(dev); - struct pci_softc *sc; device_t child, *devlist, *unchanged; int devcount, error, i, j, maxslots, oldcount; int busno, domain, s, f, pcifunchigh; @@ -4007,7 +4009,6 @@ pci_rescan_method(device_t dev) } else unchanged = NULL; - sc = device_get_softc(dev); domain = pcib_get_domain(dev); busno = pcib_get_bus(dev); maxslots = PCIB_MAXSLOTS(pcib); @@ -4084,12 +4085,10 @@ device_t pci_add_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid, uint16_t did) { - struct pci_devinfo *pf_dinfo, *vf_dinfo; + struct pci_devinfo *vf_dinfo; device_t pcib; int busno, slot, func; - pf_dinfo = device_get_ivars(pf); - pcib = device_get_parent(bus); PCIB_DECODE_RID(pcib, rid, &busno, &slot, &func); @@ -4231,6 +4230,31 @@ pci_detach(device_t dev) } static void +pci_hint_device_unit(device_t dev, device_t child, const char *name, int *unitp) +{ + int line, unit; + const char *at; + char me1[24], me2[32]; + uint8_t b, s, f; + uint32_t d; + + d = pci_get_domain(child); + b = pci_get_bus(child); + s = pci_get_slot(child); + f = pci_get_function(child); + snprintf(me1, sizeof(me1), "pci%u:%u:%u", b, s, f); + snprintf(me2, sizeof(me2), "pci%u:%u:%u:%u", d, b, s, f); + line = 0; + while (resource_find_dev(&line, name, &unit, "at", NULL) == 0) { + resource_string_value(name, unit, "at", &at); + if (strcmp(at, me1) != 0 && strcmp(at, me2) != 0) + continue; /* No match, try next candidate */ + *unitp = unit; + return; + } +} + +static void pci_set_power_child(device_t dev, device_t child, int state) { device_t pcib; diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c index 5585bd32..20364cf9 100644 --- a/freebsd/sys/dev/pci/pci_pci.c +++ b/freebsd/sys/dev/pci/pci_pci.c @@ -1243,10 +1243,8 @@ static void pcib_pcie_ab_timeout(void *arg) { struct pcib_softc *sc; - device_t dev; sc = arg; - dev = sc->dev; mtx_assert(&Giant, MA_OWNED); if (sc->flags & PCIB_DETACH_PENDING) { sc->flags |= PCIB_DETACHING; @@ -1486,16 +1484,14 @@ pcib_cfg_save(struct pcib_softc *sc) static void pcib_cfg_restore(struct pcib_softc *sc) { - device_t dev; #ifndef NEW_PCIB uint16_t command; #endif - dev = sc->dev; #ifdef NEW_PCIB pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM); #else - command = pci_read_config(dev, PCIR_COMMAND, 2); + command = pci_read_config(sc->dev, PCIR_COMMAND, 2); if (command & PCIM_CMD_PORTEN) pcib_set_io_decode(sc); if (command & PCIM_CMD_MEMEN) diff --git a/freebsd/sys/dev/rtwn/if_rtwn.c b/freebsd/sys/dev/rtwn/if_rtwn.c index 1f057dad..79868dc0 100644 --- a/freebsd/sys/dev/rtwn/if_rtwn.c +++ b/freebsd/sys/dev/rtwn/if_rtwn.c @@ -1576,17 +1576,19 @@ rtwn_set_channel(struct ieee80211com *ic) static int rtwn_wme_update(struct ieee80211com *ic) { + struct chanAccParams chp; struct ieee80211_channel *c = ic->ic_curchan; struct rtwn_softc *sc = ic->ic_softc; struct wmeParams *wmep = sc->cap_wmeParams; uint8_t aifs, acm, slottime; int ac; + ieee80211_wme_ic_getparams(ic, &chp); + /* Prevent possible races. */ IEEE80211_LOCK(ic); /* XXX */ RTWN_LOCK(sc); - memcpy(wmep, ic->ic_wme.wme_chanParams.cap_wmeParams, - sizeof(sc->cap_wmeParams)); + memcpy(wmep, chp.cap_wmeParams, sizeof(sc->cap_wmeParams)); RTWN_UNLOCK(sc); IEEE80211_UNLOCK(ic); diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h index 6bbdf5bc..e30ae6be 100644 --- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h +++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h @@ -134,6 +134,7 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = { RTWN_RTL8812AU_DEV(MELCO, WIU3866D), RTWN_RTL8812AU_DEV(NEC, WL900U), RTWN_RTL8812AU_DEV(PLANEX2, GW900D), + RTWN_RTL8812AU_DEV(REALTEK, RTL8812AU), RTWN_RTL8812AU_DEV(SENAO, EUB1200AC), RTWN_RTL8812AU_DEV(SITECOMEU, WLA7100), RTWN_RTL8812AU_DEV(TPLINK, T4U), diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c index 496e8fac..39b9dc91 100644 --- a/freebsd/sys/dev/sdhci/sdhci.c +++ b/freebsd/sys/dev/sdhci/sdhci.c @@ -275,7 +275,7 @@ sdhci_tuning_intmask(struct sdhci_slot *slot) uint32_t intmask; intmask = 0; - if (slot->opt & SDHCI_TUNING_SUPPORTED) { + if (slot->opt & SDHCI_TUNING_ENABLED) { intmask |= SDHCI_INT_TUNEERR; if (slot->retune_mode == SDHCI_RETUNE_MODE_2 || slot->retune_mode == SDHCI_RETUNE_MODE_3) @@ -303,7 +303,7 @@ sdhci_init(struct sdhci_slot *slot) slot->intmask |= SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT; } - WR4(slot, SDHCI_INT_ENABLE, slot->intmask | sdhci_tuning_intmask(slot)); + WR4(slot, SDHCI_INT_ENABLE, slot->intmask); WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); } @@ -656,6 +656,7 @@ sdhci_card_task(void *arg, int pending __unused) xpt_rescan(ccb); #else slot->intmask &= ~sdhci_tuning_intmask(slot); + WR4(slot, SDHCI_INT_ENABLE, slot->intmask); WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); slot->opt &= ~SDHCI_TUNING_ENABLED; SDHCI_UNLOCK(slot); @@ -1340,6 +1341,7 @@ sdhci_generic_tune(device_t brdev __unused, device_t reqdev, bool hs400) if (err == 0) { slot->opt |= SDHCI_TUNING_ENABLED; slot->intmask |= sdhci_tuning_intmask(slot); + WR4(slot, SDHCI_INT_ENABLE, slot->intmask); WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); if (slot->retune_ticks) { callout_reset(&slot->retune_callout, slot->retune_ticks, @@ -1408,6 +1410,7 @@ sdhci_exec_tuning(struct sdhci_slot *slot, bool reset) */ intmask = slot->intmask; slot->intmask = SDHCI_INT_DATA_AVAIL; + WR4(slot, SDHCI_INT_ENABLE, SDHCI_INT_DATA_AVAIL); WR4(slot, SDHCI_SIGNAL_ENABLE, SDHCI_INT_DATA_AVAIL); hostctrl2 = RD2(slot, SDHCI_HOST_CONTROL2); @@ -1447,8 +1450,17 @@ sdhci_exec_tuning(struct sdhci_slot *slot, bool reset) DELAY(1000); } + /* + * Restore DMA usage and interrupts. + * Note that the interrupt aggregation code might have cleared + * SDHCI_INT_DMA_END and/or SDHCI_INT_RESPONSE in slot->intmask + * and SDHCI_SIGNAL_ENABLE respectively so ensure SDHCI_INT_ENABLE + * doesn't lose these. + */ slot->opt = opt; slot->intmask = intmask; + WR4(slot, SDHCI_INT_ENABLE, intmask | SDHCI_INT_DMA_END | + SDHCI_INT_RESPONSE); WR4(slot, SDHCI_SIGNAL_ENABLE, intmask); if ((hostctrl2 & (SDHCI_CTRL2_EXEC_TUNING | diff --git a/freebsd/sys/dev/smc/if_smc.c b/freebsd/sys/dev/smc/if_smc.c index 6b087a85..ac2fdf88 100644 --- a/freebsd/sys/dev/smc/if_smc.c +++ b/freebsd/sys/dev/smc/if_smc.c @@ -1224,7 +1224,6 @@ smc_stop(struct smc_softc *sc) #ifdef DEVICE_POLLING ether_poll_deregister(sc->smc_ifp); sc->smc_ifp->if_capenable &= ~IFCAP_POLLING; - sc->smc_ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT; #endif /* @@ -1284,7 +1283,6 @@ smc_init_locked(struct smc_softc *sc) ether_poll_register(smc_poll, ifp); SMC_LOCK(sc); ifp->if_capenable |= IFCAP_POLLING; - ifp->if_capenable |= IFCAP_POLLING_NOCOUNT; #endif } diff --git a/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c b/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c index 1cf96f4c..a7110887 100644 --- a/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c +++ b/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c @@ -175,7 +175,6 @@ int dwc_otg_detach(device_t dev) { struct dwc_otg_fdt_softc *sc = device_get_softc(dev); - int err; /* during module unload there are lots of children leftover */ device_delete_children(dev); @@ -186,7 +185,7 @@ dwc_otg_detach(device_t dev) */ dwc_otg_uninit(&sc->sc_otg); - err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, + bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, sc->sc_otg.sc_intr_hdl); sc->sc_otg.sc_intr_hdl = NULL; } diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c index 557698f6..6e7c05f4 100644 --- a/freebsd/sys/dev/usb/controller/ehci.c +++ b/freebsd/sys/dev/usb/controller/ehci.c @@ -1204,9 +1204,7 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer) static void ehci_non_isoc_done(struct usb_xfer *xfer) { - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); ehci_qh_t *qh; - uint32_t status; usb_error_t err = 0; DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n", @@ -1226,8 +1224,6 @@ ehci_non_isoc_done(struct usb_xfer *xfer) usb_pc_cpu_invalidate(qh->page_cache); - status = hc32toh(sc, qh->qh_qtd.qtd_status); - /* reset scanner */ xfer->td_transfer_cache = xfer->td_transfer_first; diff --git a/freebsd/sys/dev/usb/controller/ohci.c b/freebsd/sys/dev/usb/controller/ohci.c index df1981cc..48db76f0 100644 --- a/freebsd/sys/dev/usb/controller/ohci.c +++ b/freebsd/sys/dev/usb/controller/ohci.c @@ -2387,7 +2387,6 @@ ohci_xfer_setup(struct usb_setup_params *parm) { struct usb_page_search page_info; struct usb_page_cache *pc; - ohci_softc_t *sc; struct usb_xfer *xfer; void *last_obj; uint32_t ntd; @@ -2395,7 +2394,6 @@ ohci_xfer_setup(struct usb_setup_params *parm) uint32_t nqh; uint32_t n; - sc = OHCI_BUS2SC(parm->udev->bus); xfer = parm->curr_xfer; parm->hc_max_packet_size = 0x500; diff --git a/freebsd/sys/dev/usb/net/if_cdce.c b/freebsd/sys/dev/usb/net/if_cdce.c index ececc5b3..9a15da69 100644 --- a/freebsd/sys/dev/usb/net/if_cdce.c +++ b/freebsd/sys/dev/usb/net/if_cdce.c @@ -288,6 +288,9 @@ static const STRUCT_USB_HOST_ID cdce_host_devs[] = { {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x76), USB_DRIVER_INFO(0)}, + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x03), USB_IFACE_PROTOCOL(0x16), + USB_DRIVER_INFO(0)}, }; static const STRUCT_USB_DUAL_ID cdce_dual_devs[] = { diff --git a/freebsd/sys/dev/usb/net/if_mos.c b/freebsd/sys/dev/usb/net/if_mos.c index a25e9df6..ad7bfcce 100644 --- a/freebsd/sys/dev/usb/net/if_mos.c +++ b/freebsd/sys/dev/usb/net/if_mos.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-kernel-space.h> /*- - * SPDX-License-Identifier: 0BSD AND BSD-4-Clause + * SPDX-License-Identifier: (BSD-1-Clause AND BSD-4-Clause) * * Copyright (c) 2011 Rick van der Zwet <info@rickvanderzwet.nl> * diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c index 8c9e91cb..3ae4a557 100644 --- a/freebsd/sys/dev/usb/quirk/usb_quirk.c +++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c @@ -246,6 +246,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */ + USB_QUIRK(JMICRON, JMS567, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN), USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE), diff --git a/freebsd/sys/dev/usb/serial/u3g.c b/freebsd/sys/dev/usb/serial/u3g.c index 0f3933e6..6f1cfdb1 100644 --- a/freebsd/sys/dev/usb/serial/u3g.c +++ b/freebsd/sys/dev/usb/serial/u3g.c @@ -202,6 +202,7 @@ static driver_t u3g_driver = { static const STRUCT_USB_HOST_ID u3g_devs[] = { #define U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } + U3G_DEV(ABIT, AK_020, 0), U3G_DEV(ACERP, H10, 0), U3G_DEV(AIRPLUS, MCD650, 0), U3G_DEV(AIRPRIME, PC5220, 0), @@ -310,7 +311,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = { U3G_DEV(HUAWEI, E173, 0), U3G_DEV(HUAWEI, E173_INIT, U3GINIT_HUAWEISCSI), U3G_DEV(HUAWEI, E3131, 0), - U3G_DEV(HUAWEI, E3131_INIT, U3GINIT_HUAWEISCSI), + U3G_DEV(HUAWEI, E3131_INIT, U3GINIT_HUAWEISCSI2), U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI), @@ -331,6 +332,8 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = { U3G_DEV(HUAWEI, K4505, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, K4505_INIT, U3GINIT_HUAWEISCSI), U3G_DEV(HUAWEI, ETS2055, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E3272_INIT, U3GINIT_HUAWEISCSI2), + U3G_DEV(HUAWEI, E3272, 0), U3G_DEV(KYOCERA2, CDMA_MSM_K, 0), U3G_DEV(KYOCERA2, KPC680, 0), U3G_DEV(LONGCHEER, WM66, U3GINIT_HUAWEI), @@ -493,6 +496,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = { U3G_DEV(QUANTA, GLX, 0), U3G_DEV(QUANTA, Q101, 0), U3G_DEV(QUANTA, Q111, 0), + U3G_DEV(QUECTEL, EC25, 0), U3G_DEV(SIERRA, AC402, 0), U3G_DEV(SIERRA, AC595U, 0), U3G_DEV(SIERRA, AC313U, 0), @@ -632,6 +636,45 @@ u3g_huawei_init(struct usb_device *udev) return (0); } +static int +u3g_huawei_is_cdce(uint16_t idVendor, uint8_t bInterfaceSubClass, + uint8_t bInterfaceProtocol) +{ + /* + * This function returns non-zero if the interface being + * probed is of type CDC ethernet, which the U3G driver should + * not attach to. See sys/dev/usb/net/if_cdce.c for matching + * entries. + */ + if (idVendor != USB_VENDOR_HUAWEI) + goto done; + + switch (bInterfaceSubClass) { + case 0x02: + switch (bInterfaceProtocol) { + case 0x16: + case 0x46: + case 0x76: + return (1); + default: + break; + } + break; + case 0x03: + switch (bInterfaceProtocol) { + case 0x16: + return (1); + default: + break; + } + break; + default: + break; + } +done: + return (0); +} + static void u3g_sael_m460_init(struct usb_device *udev) { @@ -845,6 +888,10 @@ u3g_probe(device_t self) if (uaa->info.bInterfaceClass != UICLASS_VENDOR) { return (ENXIO); } + if (u3g_huawei_is_cdce(uaa->info.idVendor, uaa->info.bInterfaceSubClass, + uaa->info.bInterfaceProtocol)) { + return (ENXIO); + } return (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)); } @@ -888,6 +935,9 @@ u3g_attach(device_t dev) id = usbd_get_interface_descriptor(iface); if (id == NULL || id->bInterfaceClass != UICLASS_VENDOR) continue; + if (u3g_huawei_is_cdce(uaa->info.idVendor, + id->bInterfaceSubClass, id->bInterfaceProtocol)) + continue; usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex); iface_valid |= (1<<i); } diff --git a/freebsd/sys/dev/usb/serial/umodem.c b/freebsd/sys/dev/usb/serial/umodem.c index c64600c8..ac1e35c8 100644 --- a/freebsd/sys/dev/usb/serial/umodem.c +++ b/freebsd/sys/dev/usb/serial/umodem.c @@ -133,6 +133,18 @@ static const STRUCT_USB_DUAL_ID umodem_dual_devs[] = { static const STRUCT_USB_HOST_ID umodem_host_devs[] = { /* Huawei Modem class match */ + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x01)}, + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x02)}, + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x10)}, + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x12)}, + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x61)}, + {USB_VENDOR(USB_VENDOR_HUAWEI), USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(0x02), USB_IFACE_PROTOCOL(0x62)}, {USB_VENDOR(USB_VENDOR_HUAWEI),USB_IFACE_CLASS(UICLASS_CDC), USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), USB_IFACE_PROTOCOL(0xFF)}, diff --git a/freebsd/sys/dev/usb/storage/umass.c b/freebsd/sys/dev/usb/storage/umass.c index 6b488cf7..c74a8403 100644 --- a/freebsd/sys/dev/usb/storage/umass.c +++ b/freebsd/sys/dev/usb/storage/umass.c @@ -1097,7 +1097,6 @@ static void umass_init_shuttle(struct umass_softc *sc) { struct usb_device_request req; - usb_error_t err; uint8_t status[2] = {0, 0}; /* @@ -1110,7 +1109,7 @@ umass_init_shuttle(struct umass_softc *sc) req.wIndex[0] = sc->sc_iface_no; req.wIndex[1] = 0; USETW(req.wLength, sizeof(status)); - err = usbd_do_request(sc->sc_udev, NULL, &req, &status); + usbd_do_request(sc->sc_udev, NULL, &req, &status); DPRINTF(sc, UDMASS_GEN, "Shuttle init returned 0x%02x%02x\n", status[0], status[1]); diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c index 2b244d80..94f306d4 100644 --- a/freebsd/sys/dev/usb/usb_dev.c +++ b/freebsd/sys/dev/usb/usb_dev.c @@ -882,7 +882,7 @@ usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td) struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1; struct usb_cdev_refdata refs; struct usb_cdev_privdata *cpd; - int err, ep; + int err; DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags); @@ -894,7 +894,6 @@ usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td) } cpd = malloc(sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO); - ep = cpd->ep_addr = pd->ep_addr; usb_loc_fill(pd, cpd); err = usb_ref_device(cpd, &refs, 1); @@ -1422,8 +1421,6 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag) struct usb_cdev_privdata* cpd; struct usb_fifo *f; struct usb_mbuf *m; - int fflags; - int resid; int io_len; int err; uint8_t tr_data = 0; @@ -1436,8 +1433,6 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag) if (err) return (ENXIO); - fflags = cpd->fflags; - f = refs.rxfifo; if (f == NULL) { /* should not happen */ @@ -1445,8 +1440,6 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag) return (EPERM); } - resid = uio->uio_resid; - mtx_lock(f->priv_mtx); /* check for permanent read error */ @@ -1546,8 +1539,6 @@ usb_write(struct cdev *dev, struct uio *uio, int ioflag) struct usb_fifo *f; struct usb_mbuf *m; uint8_t *pdata; - int fflags; - int resid; int io_len; int err; uint8_t tr_data = 0; @@ -1562,15 +1553,12 @@ usb_write(struct cdev *dev, struct uio *uio, int ioflag) if (err) return (ENXIO); - fflags = cpd->fflags; - f = refs.txfifo; if (f == NULL) { /* should not happen */ usb_unref_device(cpd, &refs); return (EPERM); } - resid = uio->uio_resid; mtx_lock(f->priv_mtx); diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c index 861f6029..5f1cf409 100644 --- a/freebsd/sys/dev/usb/usb_device.c +++ b/freebsd/sys/dev/usb/usb_device.c @@ -89,6 +89,7 @@ /* function prototypes */ +static int sysctl_hw_usb_template(SYSCTL_HANDLER_ARGS); static void usb_init_endpoint(struct usb_device *, uint8_t, struct usb_endpoint_descriptor *, struct usb_endpoint_ss_comp_descriptor *, @@ -123,8 +124,137 @@ int usb_template; #endif #ifndef __rtems__ -SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RWTUN, - &usb_template, 0, "Selected USB device side template"); +SYSCTL_PROC(_hw_usb, OID_AUTO, template, + CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, + NULL, 0, sysctl_hw_usb_template, + "I", "Selected USB device side template"); + +/*------------------------------------------------------------------------* + * usb_trigger_reprobe_on_off + * + * This function sets the pull up resistors for all ports currently + * operating in device mode either on (when on_not_off is 1), or off + * (when it's 0). + *------------------------------------------------------------------------*/ +static void +usb_trigger_reprobe_on_off(int on_not_off) +{ + struct usb_port_status ps; + struct usb_bus *bus; + struct usb_device *udev; + usb_error_t err; + int do_unlock, max; + + max = devclass_get_maxunit(usb_devclass_ptr); + while (max >= 0) { + mtx_lock(&usb_ref_lock); + bus = devclass_get_softc(usb_devclass_ptr, max); + max--; + + if (bus == NULL || bus->devices == NULL || + bus->devices[USB_ROOT_HUB_ADDR] == NULL) { + mtx_unlock(&usb_ref_lock); + continue; + } + + udev = bus->devices[USB_ROOT_HUB_ADDR]; + + if (udev->refcount == USB_DEV_REF_MAX) { + mtx_unlock(&usb_ref_lock); + continue; + } + + udev->refcount++; + mtx_unlock(&usb_ref_lock); + + do_unlock = usbd_enum_lock(udev); + if (do_unlock > 1) { + do_unlock = 0; + goto next; + } + + err = usbd_req_get_port_status(udev, NULL, &ps, 1); + if (err != 0) { + DPRINTF("usbd_req_get_port_status() " + "failed: %s\n", usbd_errstr(err)); + goto next; + } + + if ((UGETW(ps.wPortStatus) & UPS_PORT_MODE_DEVICE) == 0) + goto next; + + if (on_not_off) { + err = usbd_req_set_port_feature(udev, NULL, 1, + UHF_PORT_POWER); + if (err != 0) { + DPRINTF("usbd_req_set_port_feature() " + "failed: %s\n", usbd_errstr(err)); + } + } else { + err = usbd_req_clear_port_feature(udev, NULL, 1, + UHF_PORT_POWER); + if (err != 0) { + DPRINTF("usbd_req_clear_port_feature() " + "failed: %s\n", usbd_errstr(err)); + } + } + +next: + mtx_lock(&usb_ref_lock); + if (do_unlock) + usbd_enum_unlock(udev); + if (--(udev->refcount) == 0) + cv_broadcast(&udev->ref_cv); + mtx_unlock(&usb_ref_lock); + } +} + +/*------------------------------------------------------------------------* + * usb_trigger_reprobe_all + * + * This function toggles the pull up resistors for all ports currently + * operating in device mode, causing the host machine to reenumerate them. + *------------------------------------------------------------------------*/ +static void +usb_trigger_reprobe_all(void) +{ + + /* + * Set the pull up resistors off for all ports in device mode. + */ + usb_trigger_reprobe_on_off(0); + + /* + * According to the DWC OTG spec this must be at least 3ms. + */ + usb_pause_mtx(NULL, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME)); + + /* + * Set the pull up resistors back on. + */ + usb_trigger_reprobe_on_off(1); +} + +static int +sysctl_hw_usb_template(SYSCTL_HANDLER_ARGS) +{ + int error, val; + + val = usb_template; + error = sysctl_handle_int(oidp, &val, 0, req); + if (error != 0 || req->newptr == NULL || usb_template == val) + return (error); + + usb_template = val; + + if (usb_template < 0) { + usb_trigger_reprobe_on_off(0); + } else { + usb_trigger_reprobe_all(); + } + + return (0); +} #endif /* __rtems__ */ /* English is default language */ diff --git a/freebsd/sys/dev/usb/wlan/if_rum.c b/freebsd/sys/dev/usb/wlan/if_rum.c index 9996576e..dbb12335 100644 --- a/freebsd/sys/dev/usb/wlan/if_rum.c +++ b/freebsd/sys/dev/usb/wlan/if_rum.c @@ -2303,11 +2303,14 @@ rum_update_slot(struct ieee80211com *ic) static int rum_wme_update(struct ieee80211com *ic) { - const struct wmeParams *chanp = - ic->ic_wme.wme_chanParams.cap_wmeParams; + struct chanAccParams chp; + const struct wmeParams *chanp; struct rum_softc *sc = ic->ic_softc; int error = 0; + ieee80211_wme_ic_getparams(ic, &chp); + chanp = chp.cap_wmeParams; + RUM_LOCK(sc); error = rum_write(sc, RT2573_AIFSN_CSR, chanp[WME_AC_VO].wmep_aifsn << 12 | diff --git a/freebsd/sys/dev/usb/wlan/if_run.c b/freebsd/sys/dev/usb/wlan/if_run.c index d9bda8c8..71f53dd3 100644 --- a/freebsd/sys/dev/usb/wlan/if_run.c +++ b/freebsd/sys/dev/usb/wlan/if_run.c @@ -2219,11 +2219,14 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) static int run_wme_update(struct ieee80211com *ic) { + struct chanAccParams chp; struct run_softc *sc = ic->ic_softc; - const struct wmeParams *ac = - ic->ic_wme.wme_chanParams.cap_wmeParams; + const struct wmeParams *ac; int aci, error = 0; + ieee80211_wme_ic_getparams(ic, &chp); + ac = chp.cap_wmeParams; + /* update MAC TX configuration registers */ RUN_LOCK(sc); for (aci = 0; aci < WME_NUM_AC; aci++) { diff --git a/freebsd/sys/dev/usb/wlan/if_uath.c b/freebsd/sys/dev/usb/wlan/if_uath.c index e1aa5ec0..e001d9ed 100644 --- a/freebsd/sys/dev/usb/wlan/if_uath.c +++ b/freebsd/sys/dev/usb/wlan/if_uath.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-kernel-space.h> /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND 0BSD + * SPDX-License-Identifier: (BSD-2-Clause-FreeBSD AND BSD-1-Clause) * * Copyright (c) 2006 Sam Leffler, Errno Consulting * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c index 4a1c0675..dfa8413b 100644 --- a/freebsd/sys/fs/devfs/devfs_vnops.c +++ b/freebsd/sys/fs/devfs/devfs_vnops.c @@ -911,6 +911,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) struct devfs_dirent *de, *dd; struct devfs_dirent **dde; struct devfs_mount *dmp; + struct mount *mp; struct cdev *cdev; int error, flags, nameiop, dvplocked; char specname[SPECNAMELEN + 1], *pname; @@ -922,7 +923,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) td = cnp->cn_thread; flags = cnp->cn_flags; nameiop = cnp->cn_nameiop; - dmp = VFSTODEVFS(dvp->v_mount); + mp = dvp->v_mount; + dmp = VFSTODEVFS(mp); dd = dvp->v_data; *vpp = NULLVP; @@ -955,8 +957,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) return (ENOENT); dvplocked = VOP_ISLOCKED(dvp); VOP_UNLOCK(dvp, 0); - error = devfs_allocv(de, dvp->v_mount, - cnp->cn_lkflags & LK_TYPE_MASK, vpp); + error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, + vpp); *dm_unlock = 0; vn_lock(dvp, dvplocked | LK_RETRY); return (error); @@ -1041,8 +1043,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) return (0); } } - error = devfs_allocv(de, dvp->v_mount, cnp->cn_lkflags & LK_TYPE_MASK, - vpp); + error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, vpp); *dm_unlock = 0; return (error); } @@ -1195,6 +1196,18 @@ devfs_pathconf(struct vop_pathconf_args *ap) { switch (ap->a_name) { + case _PC_FILESIZEBITS: + *ap->a_retval = 64; + return (0); + case _PC_NAME_MAX: + *ap->a_retval = NAME_MAX; + return (0); + case _PC_LINK_MAX: + *ap->a_retval = INT_MAX; + return (0); + case _PC_SYMLINK_MAX: + *ap->a_retval = MAXPATHLEN; + return (0); case _PC_MAX_CANON: if (ap->a_vp->v_vflag & VV_ISTTY) { *ap->a_retval = MAX_CANON; @@ -1224,6 +1237,9 @@ devfs_pathconf(struct vop_pathconf_args *ap) *ap->a_retval = 0; #endif return (0); + case _PC_CHOWN_RESTRICTED: + *ap->a_retval = 1; + return (0); default: return (vop_stdpathconf(ap)); } diff --git a/freebsd/sys/isa/isavar.h b/freebsd/sys/isa/isavar.h index 28d13505..30fd1f8d 100644 --- a/freebsd/sys/isa/isavar.h +++ b/freebsd/sys/isa/isavar.h @@ -142,6 +142,10 @@ enum isa_device_ivars { #define ISACFGATTR_DYNAMIC (1 << 1) /* dynamic configuration */ #define ISACFGATTR_HINTS (1 << 3) /* source of config is hints */ +#define ISA_PNP_DESCR "E:pnpid;D:#" +#define ISA_PNP_INFO(t) \ + MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, sizeof(t[0]), nitems(t) - 1); \ + /* * Simplified accessors for isa devices */ diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c index b8961ab6..ea827ebe 100644 --- a/freebsd/sys/kern/init_main.c +++ b/freebsd/sys/kern/init_main.c @@ -91,7 +91,6 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_param.h> #include <vm/pmap.h> #include <vm/vm_map.h> -#include <vm/vm_domain.h> #include <sys/copyright.h> #include <ddb/ddb.h> @@ -235,6 +234,8 @@ mi_startup(void) int verbose; #endif + TSENTER(); + #ifndef __rtems__ if (boothowto & RB_VERBOSE) bootverbose++; @@ -334,6 +335,8 @@ restart: #endif /* __rtems__ */ } + TSEXIT(); /* Here so we don't overlap with start_init. */ + mtx_assert(&Giant, MA_OWNED | MA_NOTRECURSED); mtx_unlock(&Giant); @@ -517,10 +520,7 @@ proc0_init(void *dummy __unused) td->td_flags = TDF_INMEM; td->td_pflags = TDP_KTHREAD; td->td_cpuset = cpuset_thread0(); - vm_domain_policy_init(&td->td_vm_dom_policy); - vm_domain_policy_set(&td->td_vm_dom_policy, VM_POLICY_NONE, -1); - vm_domain_policy_init(&p->p_vm_dom_policy); - vm_domain_policy_set(&p->p_vm_dom_policy, VM_POLICY_NONE, -1); + td->td_domain.dr_policy = td->td_cpuset->cs_domain; prison0_init(); p->p_peers = 0; p->p_leader = p; @@ -730,6 +730,8 @@ start_init(void *dummy) GIANT_REQUIRED; + TSENTER(); /* Here so we don't overlap with mi_startup. */ + td = curthread; p = td->td_proc; @@ -823,6 +825,7 @@ start_init(void *dummy) */ if ((error = sys_execve(td, &args)) == EJUSTRETURN) { mtx_unlock(&Giant); + TSEXIT(); return; } if (error != ENOENT) diff --git a/freebsd/sys/kern/kern_mbuf.c b/freebsd/sys/kern/kern_mbuf.c index 0f46259a..78e3528f 100644 --- a/freebsd/sys/kern/kern_mbuf.c +++ b/freebsd/sys/kern/kern_mbuf.c @@ -295,7 +295,7 @@ static void mb_dtor_pack(void *, int, void *); static int mb_zinit_pack(void *, int, int); static void mb_zfini_pack(void *, int); static void mb_reclaim(uma_zone_t, int); -static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, uint8_t *, int); +static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int); /* Ensure that MSIZE is a power of 2. */ CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE); @@ -400,13 +400,14 @@ SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL); * pages. */ static void * -mbuf_jumbo_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait) +mbuf_jumbo_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *flags, + int wait) { /* Inform UMA that this allocator uses kernel_map/object. */ *flags = UMA_SLAB_KERNEL; #ifndef __rtems__ - return ((void *)kmem_alloc_contig(kernel_arena, bytes, wait, + return ((void *)kmem_alloc_contig_domain(domain, bytes, wait, (vm_paddr_t)0, ~(vm_paddr_t)0, 1, 0, VM_MEMATTR_DEFAULT)); #else /* __rtems__ */ return ((void *)malloc(bytes, M_TEMP, wait)); diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c index d96954c7..f6485a86 100644 --- a/freebsd/sys/kern/kern_synch.c +++ b/freebsd/sys/kern/kern_synch.c @@ -139,18 +139,12 @@ _sleep(void *ident, struct lock_object *lock, int priority, const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) { struct thread *td; -#ifndef __rtems__ - struct proc *p; -#endif /* __rtems__ */ struct lock_class *class; uintptr_t lock_state; int catch, pri, rval, sleepq_flags; WITNESS_SAVE_DECL(lock_witness); td = curthread; -#ifndef __rtems__ - p = td->td_proc; -#endif /* __rtems__ */ #ifdef KTRACE if (KTRPOINT(td, KTR_CSW)) ktrcsw(1, 0, wmesg); @@ -198,7 +192,7 @@ _sleep(void *ident, struct lock_object *lock, int priority, sleepq_lock(ident); CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)", - td->td_tid, p->p_pid, td->td_name, wmesg, ident); + td->td_tid, td->td_proc->p_pid, td->td_name, wmesg, ident); if (lock == &Giant.lock_object) mtx_assert(&Giant, MA_OWNED); @@ -263,12 +257,10 @@ msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) { struct thread *td; - struct proc *p; int rval; WITNESS_SAVE_DECL(mtx); td = curthread; - p = td->td_proc; KASSERT(mtx != NULL, ("sleeping without a mutex")); KASSERT(ident != NULL, ("msleep_spin_sbt: NULL ident")); KASSERT(TD_IS_RUNNING(td), ("msleep_spin_sbt: curthread not running")); @@ -278,7 +270,7 @@ msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg, sleepq_lock(ident); CTR5(KTR_PROC, "msleep_spin: thread %ld (pid %ld, %s) on %s (%p)", - td->td_tid, p->p_pid, td->td_name, wmesg, ident); + td->td_tid, td->td_proc->p_pid, td->td_name, wmesg, ident); DROP_GIANT(); mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED); diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c index 09a459aa..8076e7e3 100644 --- a/freebsd/sys/kern/subr_bus.c +++ b/freebsd/sys/kern/subr_bus.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/conf.h> +#include <sys/eventhandler.h> #include <sys/filio.h> #include <sys/lock.h> #include <sys/kernel.h> @@ -149,6 +150,10 @@ static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures"); static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc"); #ifndef __rtems__ +EVENTHANDLER_LIST_DEFINE(device_attach); +EVENTHANDLER_LIST_DEFINE(device_detach); +EVENTHANDLER_LIST_DEFINE(dev_lookup); + static void devctl2_init(void); #endif /* __rtems__ */ @@ -2981,6 +2986,7 @@ device_attach(device_t dev) dev->flags &= ~DF_DONENOMATCH; #ifndef __rtems__ EVENTHANDLER_INVOKE(device_attach, dev); + EVENTHANDLER_DIRECT_INVOKE(device_attach, dev); #endif /* __rtems__ */ devadded(dev); return (0); @@ -3016,16 +3022,18 @@ device_detach(device_t dev) return (0); #ifndef __rtems__ - EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN); + EVENTHANDLER_DIRECT_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN); #endif /* __rtems__ */ if ((error = DEVICE_DETACH(dev)) != 0) { #ifndef __rtems__ - EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_FAILED); + EVENTHANDLER_DIRECT_INVOKE(device_detach, dev, + EVHDEV_DETACH_FAILED); #endif /* __rtems__ */ return (error); } else { #ifndef __rtems__ - EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_COMPLETE); + EVENTHANDLER_DIRECT_INVOKE(device_detach, dev, + EVHDEV_DETACH_COMPLETE); #endif /* __rtems__ */ } devremoved(dev); @@ -5099,7 +5107,7 @@ print_device_short(device_t dev, int indent) if (!dev) return; - indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n", + indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n", dev->unit, dev->desc, (dev->parent? "":"no "), (TAILQ_EMPTY(&dev->children)? "no ":""), @@ -5108,6 +5116,7 @@ print_device_short(device_t dev, int indent) (dev->flags&DF_WILDCARD? "wildcard,":""), (dev->flags&DF_DESCMALLOCED? "descmalloced,":""), (dev->flags&DF_REBID? "rebiddable,":""), + (dev->flags&DF_SUSPENDED? "suspended,":""), (dev->ivars? "":"no "), (dev->softc? "":"no "), dev->busy)); @@ -5388,7 +5397,7 @@ find_device(struct devreq *req, device_t *devp) /* Finally, give device enumerators a chance. */ dev = NULL; - EVENTHANDLER_INVOKE(dev_lookup, req->dr_name, &dev); + EVENTHANDLER_DIRECT_INVOKE(dev_lookup, req->dr_name, &dev); if (dev == NULL) return (ENOENT); *devp = dev; @@ -5655,6 +5664,56 @@ devctl2_init(void) UID_ROOT, GID_WHEEL, 0600, "devctl2"); } +/* + * APIs to manage deprecation and obsolescence. + */ +static int obsolete_panic = 0; +SYSCTL_INT(_debug, OID_AUTO, obsolete_panic, CTLFLAG_RWTUN, &obsolete_panic, 0, + "Bus debug level"); +/* 0 - don't panic, 1 - panic if already obsolete, 2 - panic if deprecated */ +static void +gone_panic(int major, int running, const char *msg) +{ + + switch (obsolete_panic) + { + case 0: + return; + case 1: + if (running < major) + return; + /* FALLTHROUGH */ + default: + panic("%s", msg); + } +} + +void +_gone_in(int major, const char *msg) +{ + + gone_panic(major, P_OSREL_MAJOR(__FreeBSD_version), msg); + if (P_OSREL_MAJOR(__FreeBSD_version) >= major) + printf("Obsolete code will removed soon: %s\n", msg); + else if (P_OSREL_MAJOR(__FreeBSD_version) + 1 == major) + printf("Deprecated code (to be removed in FreeBSD %d): %s\n", + major, msg); +} + +void +_gone_in_dev(device_t dev, int major, const char *msg) +{ + + gone_panic(major, P_OSREL_MAJOR(__FreeBSD_version), msg); + if (P_OSREL_MAJOR(__FreeBSD_version) >= major) + device_printf(dev, + "Obsolete code will removed soon: %s\n", msg); + else if (P_OSREL_MAJOR(__FreeBSD_version) + 1 == major) + device_printf(dev, + "Deprecated code (to be removed in FreeBSD %d): %s\n", + major, msg); +} + #ifdef DDB DB_SHOW_COMMAND(device, db_show_device) { diff --git a/freebsd/sys/kern/subr_hash.c b/freebsd/sys/kern/subr_hash.c index 488d8bcd..dd442931 100644 --- a/freebsd/sys/kern/subr_hash.c +++ b/freebsd/sys/kern/subr_hash.c @@ -59,9 +59,8 @@ void * hashinit_flags(int elements, struct malloc_type *type, u_long *hashmask, int flags) { - long hashsize; + long hashsize, i; LIST_HEAD(generic, generic) *hashtbl; - int i; KASSERT(elements > 0, ("%s: bad elements", __func__)); /* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */ @@ -116,9 +115,8 @@ static const int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531, void * phashinit_flags(int elements, struct malloc_type *type, u_long *nentries, int flags) { - long hashsize; + long hashsize, i; LIST_HEAD(generic, generic) *hashtbl; - int i; KASSERT(elements > 0, ("%s: bad elements", __func__)); /* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */ diff --git a/freebsd/sys/kern/subr_prf.c b/freebsd/sys/kern/subr_prf.c index 0405b369..12a0825d 100644 --- a/freebsd/sys/kern/subr_prf.c +++ b/freebsd/sys/kern/subr_prf.c @@ -137,6 +137,7 @@ static void snprintf_func(int ch, void *arg); #ifndef __rtems__ static int msgbufmapped; /* Set when safe to use msgbuf */ int msgbuftrigger; +struct msgbuf *msgbufp; static int log_console_output = 1; SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RWTUN, @@ -290,6 +291,7 @@ _vprintf(int level, int flags, const char *fmt, va_list ap) char bufr[PRINTF_BUFR_SIZE]; #endif + TSENTER(); pca.tty = NULL; pca.pri = level; pca.flags = flags; @@ -317,6 +319,7 @@ _vprintf(int level, int flags, const char *fmt, va_list ap) } #endif + TSEXIT(); return (retval); } #else /* __rtems__ */ diff --git a/freebsd/sys/kern/subr_sleepqueue.c b/freebsd/sys/kern/subr_sleepqueue.c index fa33af86..6ecefc70 100644 --- a/freebsd/sys/kern/subr_sleepqueue.c +++ b/freebsd/sys/kern/subr_sleepqueue.c @@ -1441,11 +1441,10 @@ sleepq_sbuf_print_stacks(struct sbuf *sb, void *wchan, int queue, struct stack **st; struct sbuf **td_infos; int i, stack_idx, error, stacks_to_allocate; - bool finished, partial_print; + bool finished; error = 0; finished = false; - partial_print = false; KASSERT(wchan != NULL, ("%s: invalid NULL wait channel", __func__)); MPASS((queue >= 0) && (queue < NR_SLEEPQS)); diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c index 118b4c77..1c46bd29 100644 --- a/freebsd/sys/kern/sys_generic.c +++ b/freebsd/sys/kern/sys_generic.c @@ -2004,6 +2004,8 @@ seltdfini(struct thread *td) if (stp->st_free2) uma_zfree(selfd_zone, stp->st_free2); td->td_sel = NULL; + cv_destroy(&stp->st_wait); + mtx_destroy(&stp->st_mtx); free(stp, M_SELECT); } diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c index 974f7eec..4f4ce99e 100644 --- a/freebsd/sys/kern/sys_socket.c +++ b/freebsd/sys/kern/sys_socket.c @@ -585,6 +585,7 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) kif->kf_type = KF_TYPE_SOCKET; so = fp->f_data; + CURVNET_SET(so->so_vnet); kif->kf_un.kf_sock.kf_sock_domain0 = so->so_proto->pr_domain->dom_family; kif->kf_un.kf_sock.kf_sock_type0 = so->so_type; @@ -637,6 +638,7 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) } strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name, sizeof(kif->kf_path)); + CURVNET_RESTORE(); return (0); } diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c index 9f7e545f..7849be9d 100644 --- a/freebsd/sys/kern/uipc_usrreq.c +++ b/freebsd/sys/kern/uipc_usrreq.c @@ -1724,13 +1724,13 @@ unp_disconnect(struct unpcb *unp, struct unpcb *unp2) static int unp_pcblist(SYSCTL_HANDLER_ARGS) { - int error, i, n; - int freeunp; struct unpcb *unp, **unp_list; unp_gen_t gencnt; struct xunpgen *xug; struct unp_head *head; struct xunpcb *xu; + u_int i; + int error, freeunp, n; switch ((intptr_t)arg1) { case SOCK_STREAM: diff --git a/freebsd/sys/net/altq/altq_hfsc.h b/freebsd/sys/net/altq/altq_hfsc.h index de5e89b8..0a9fcf95 100644 --- a/freebsd/sys/net/altq/altq_hfsc.h +++ b/freebsd/sys/net/altq/altq_hfsc.h @@ -192,7 +192,7 @@ struct hfsc_class_stats { * representation. * the slope values are scaled to avoid overflow. * the inverse slope values as well as the y-projection of the 1st - * segment are kept in order to to avoid 64-bit divide operations + * segment are kept in order to avoid 64-bit divide operations * that are expensive on 32-bit architectures. * * note: Intel Pentium TSC never wraps around in several thousands of years. diff --git a/freebsd/sys/net/bpf.c b/freebsd/sys/net/bpf.c index 6fc6b435..e6ad9e25 100644 --- a/freebsd/sys/net/bpf.c +++ b/freebsd/sys/net/bpf.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sockio.h> #include <sys/ttycom.h> #include <sys/uio.h> +#include <sys/sysent.h> #include <sys/event.h> #include <sys/file.h> @@ -728,7 +729,7 @@ bpf_check_upgrade(u_long cmd, struct bpf_d *d, struct bpf_insn *fcode, int flen) * Check if cmd looks like snaplen setting from * pcap_bpf.c:pcap_open_live(). * Note we're not checking .k value here: - * while pcap_open_live() definitely sets to to non-zero value, + * while pcap_open_live() definitely sets to non-zero value, * we'd prefer to treat k=0 (deny ALL) case the same way: e.g. * do not consider upgrading immediately */ @@ -1396,9 +1397,11 @@ bpfioctl(struct bpf_d *d, u_long cmd, caddr_t addr, int flags, case BIOCGDLTLIST32: case BIOCGRTIMEOUT32: case BIOCSRTIMEOUT32: - BPFD_LOCK(d); - d->bd_compat32 = 1; - BPFD_UNLOCK(d); + if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { + BPFD_LOCK(d); + d->bd_compat32 = 1; + BPFD_UNLOCK(d); + } } #endif diff --git a/freebsd/sys/net/ieee8023ad_lacp.c b/freebsd/sys/net/ieee8023ad_lacp.c index 1778193d..2a30f4a3 100644 --- a/freebsd/sys/net/ieee8023ad_lacp.c +++ b/freebsd/sys/net/ieee8023ad_lacp.c @@ -203,8 +203,8 @@ SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, debug, CTLFLAG_RWTUN | CTLFLAG_VNET, &VNET_NAME(lacp_debug), 0, "Enable LACP debug logging (1=debug, 2=trace)"); static VNET_DEFINE(int, lacp_default_strict_mode) = 1; -SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, default_strict_mode, CTLFLAG_RWTUN, - &VNET_NAME(lacp_default_strict_mode), 0, +SYSCTL_INT(_net_link_lagg_lacp, OID_AUTO, default_strict_mode, + CTLFLAG_RWTUN | CTLFLAG_VNET, &VNET_NAME(lacp_default_strict_mode), 0, "LACP strict protocol compliance default"); #define LACP_DPRINTF(a) if (V_lacp_debug & 0x01) { lacp_dprintf a ; } diff --git a/freebsd/sys/net/if_clone.c b/freebsd/sys/net/if_clone.c index 99faa05f..295bddf4 100644 --- a/freebsd/sys/net/if_clone.c +++ b/freebsd/sys/net/if_clone.c @@ -357,7 +357,7 @@ if_clone_alloc(const char *name, int maxunit) return (ifc); } - + static int if_clone_attach(struct if_clone *ifc) { @@ -389,10 +389,8 @@ if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match, ifc->ifc_create = create; ifc->ifc_destroy = destroy; - if (if_clone_attach(ifc) != 0) { - if_clone_free(ifc); + if (if_clone_attach(ifc) != 0) return (NULL); - } EVENTHANDLER_INVOKE(if_clone_event, ifc); @@ -412,10 +410,8 @@ if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy, ifc->ifcs_destroy = destroy; ifc->ifcs_minifs = minifs; - if (if_clone_attach(ifc) != 0) { - if_clone_free(ifc); + if (if_clone_attach(ifc) != 0) return (NULL); - } for (unit = 0; unit < minifs; unit++) { char name[IFNAMSIZ]; @@ -452,7 +448,7 @@ if_clone_detach(struct if_clone *ifc) /* destroy all interfaces for this cloner */ while (!LIST_EMPTY(&ifc->ifc_iflist)) if_clone_destroyif(ifc, LIST_FIRST(&ifc->ifc_iflist)); - + IF_CLONE_REMREF(ifc); } @@ -514,7 +510,7 @@ if_clone_list(struct if_clonereq *ifcr) done: IF_CLONERS_UNLOCK(); - if (err == 0) + if (err == 0 && dst != NULL) err = copyout(outbuf, dst, buf_count*IFNAMSIZ); if (outbuf != NULL) free(outbuf, M_CLONE); diff --git a/freebsd/sys/net/if_ethersubr.c b/freebsd/sys/net/if_ethersubr.c index 9b927511..24f11436 100644 --- a/freebsd/sys/net/if_ethersubr.c +++ b/freebsd/sys/net/if_ethersubr.c @@ -292,7 +292,6 @@ ether_output(struct ifnet *ifp, struct mbuf *m, int hlen; /* link layer header length */ uint32_t pflags; struct llentry *lle = NULL; - struct rtentry *rt0 = NULL; int addref = 0; phdr = NULL; @@ -322,7 +321,6 @@ ether_output(struct ifnet *ifp, struct mbuf *m, pflags = lle->r_flags; } } - rt0 = ro->ro_rt; } #ifdef MAC diff --git a/freebsd/sys/net/if_gif.c b/freebsd/sys/net/if_gif.c index fdbccbb6..bd33ab75 100644 --- a/freebsd/sys/net/if_gif.c +++ b/freebsd/sys/net/if_gif.c @@ -526,7 +526,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn) struct ip6_hdr *ip6; uint32_t t; #endif - struct gif_softc *sc; struct ether_header *eh; struct ifnet *oldifp; int isr, n, af; @@ -536,7 +535,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn) m_freem(m); return; } - sc = ifp->if_softc; m->m_pkthdr.rcvif = ifp; m_clrprotoflags(m); switch (proto) { diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c index ce696fb2..36c8095a 100644 --- a/freebsd/sys/net/if_lagg.c +++ b/freebsd/sys/net/if_lagg.c @@ -246,7 +246,7 @@ SYSCTL_INT(_net_link_lagg, OID_AUTO, failover_rx_all, CTLFLAG_RW | CTLFLAG_VNET, "Accept input from any interface in a failover lagg"); /* Default value for using flowid */ -static VNET_DEFINE(int, def_use_flowid) = 1; +static VNET_DEFINE(int, def_use_flowid) = 0; #define V_def_use_flowid VNET(def_use_flowid) SYSCTL_INT(_net_link_lagg, OID_AUTO, default_use_flowid, CTLFLAG_RWTUN, &VNET_NAME(def_use_flowid), 0, diff --git a/freebsd/sys/net/iflib.h b/freebsd/sys/net/iflib.h index 70992fdd..3730f0ea 100644 --- a/freebsd/sys/net/iflib.h +++ b/freebsd/sys/net/iflib.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2017, Matthew Macy (mmacy@nextbsd.org) + * Copyright (c) 2014-2017, Matthew Macy (mmacy@mattmacy.io) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -174,9 +174,9 @@ typedef struct pci_vendor_info { #define PVID_END {0, 0, 0, 0, 0, 0, NULL} #define IFLIB_PNP_DESCR "U32:vendor;U32:device;U32:subvendor;U32:subdevice;" \ - "U32:revision;U32:class;D:human" + "U32:revision;U32:class;D:#" #define IFLIB_PNP_INFO(b, u, t) \ - MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t)) + MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t) - 1) typedef struct if_txrx { int (*ift_txd_encap) (void *, if_pkt_info_t); @@ -217,6 +217,8 @@ typedef struct if_softc_ctx { iflib_intr_mode_t isc_intr; uint16_t isc_max_frame_size; /* set at init time by driver */ + uint16_t isc_min_frame_size; /* set at init time by driver, only used if + IFLIB_NEED_ETHER_PAD is set. */ uint32_t isc_pause_frames; /* set by driver for iflib_timer to detect */ pci_vendor_info_t isc_vendor_info; /* set by iflib prior to attach_pre */ int isc_disable_msix; @@ -314,6 +316,10 @@ typedef enum { * Driver needs csum zeroed for offloading */ #define IFLIB_NEED_ZERO_CSUM 0x80 +/* + * Driver needs frames padded to some minimum length + */ +#define IFLIB_NEED_ETHER_PAD 0x100 diff --git a/freebsd/sys/net/pfvar.h b/freebsd/sys/net/pfvar.h index 4bc84d94..c9b1d1db 100644 --- a/freebsd/sys/net/pfvar.h +++ b/freebsd/sys/net/pfvar.h @@ -1619,6 +1619,7 @@ int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *, u_int32_t pf_state_expires(const struct pf_state *); void pf_purge_expired_fragments(void); +void pf_purge_fragments(uint32_t); int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *, int); int pf_socket_lookup(int, struct pf_pdesc *, struct mbuf *); diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c index 1be39753..ade738a2 100644 --- a/freebsd/sys/net/route.c +++ b/freebsd/sys/net/route.c @@ -1765,6 +1765,8 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info, int family, mtu; struct if_mtuinfo ifmtu; + RIB_WLOCK_ASSERT(rnh); + rt = (struct rtentry *)rnh->rnh_lookup(info->rti_info[RTAX_DST], info->rti_info[RTAX_NETMASK], &rnh->head); @@ -1813,8 +1815,9 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info, /* Check if outgoing interface has changed */ if (info->rti_ifa != NULL && info->rti_ifa != rt->rt_ifa && - rt->rt_ifa != NULL && rt->rt_ifa->ifa_rtrequest != NULL) { - rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, info); + rt->rt_ifa != NULL) { + if (rt->rt_ifa->ifa_rtrequest != NULL) + rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, info); ifa_free(rt->rt_ifa); } /* Update gateway address */ @@ -1854,6 +1857,13 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info, } } + /* + * This route change may have modified the route's gateway. In that + * case, any inpcbs that have cached this route need to invalidate their + * llentry cache. + */ + rnh->rnh_gen++; + if (ret_nrt) { *ret_nrt = rt; RT_ADDREF(rt); diff --git a/freebsd/sys/net/route.h b/freebsd/sys/net/route.h index 8835433e..28f1db01 100644 --- a/freebsd/sys/net/route.h +++ b/freebsd/sys/net/route.h @@ -416,6 +416,14 @@ struct rt_addrinfo { } \ } while (0) +#define RO_INVALIDATE_CACHE(ro) do { \ + RO_RTFREE(ro); \ + if ((ro)->ro_lle != NULL) { \ + LLE_FREE((ro)->ro_lle); \ + (ro)->ro_lle = NULL; \ + } \ + } while (0) + /* * Validate a cached route based on a supplied cookie. If there is an * out-of-date cache, simply free it. Update the generation number @@ -424,10 +432,7 @@ struct rt_addrinfo { #define RT_VALIDATE(ro, cookiep, fibnum) do { \ rt_gen_t cookie = RT_GEN(fibnum, (ro)->ro_dst.sa_family); \ if (*(cookiep) != cookie) { \ - if ((ro)->ro_rt != NULL) { \ - RTFREE((ro)->ro_rt); \ - (ro)->ro_rt = NULL; \ - } \ + RO_INVALIDATE_CACHE(ro); \ *(cookiep) = cookie; \ } \ } while (0) diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c index fe608d70..851c30c9 100644 --- a/freebsd/sys/net/rtsock.c +++ b/freebsd/sys/net/rtsock.c @@ -114,6 +114,12 @@ struct ifa_msghdrl32 { int32_t ifam_metric; struct if_data ifam_data; }; + +#define SA_SIZE32(sa) \ + ( (((struct sockaddr *)(sa))->sa_len == 0) ? \ + sizeof(int) : \ + 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int) - 1) ) ) + #endif /* COMPAT_FREEBSD32 */ MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables"); @@ -1128,6 +1134,9 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int * struct sockaddr_storage ss; struct sockaddr_in6 *sin6; #endif +#ifdef COMPAT_FREEBSD32 + bool compat32 = false; +#endif switch (type) { @@ -1135,9 +1144,10 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int * case RTM_NEWADDR: if (w != NULL && w->w_op == NET_RT_IFLISTL) { #ifdef COMPAT_FREEBSD32 - if (w->w_req->flags & SCTL_MASK32) + if (w->w_req->flags & SCTL_MASK32) { len = sizeof(struct ifa_msghdrl32); - else + compat32 = true; + } else #endif len = sizeof(struct ifa_msghdrl); } else @@ -1151,6 +1161,7 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int * len = sizeof(struct if_msghdrl32); else len = sizeof(struct if_msghdr32); + compat32 = true; break; } #endif @@ -1181,7 +1192,12 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int * if ((sa = rtinfo->rti_info[i]) == NULL) continue; rtinfo->rti_addrs |= (1 << i); - dlen = SA_SIZE(sa); +#ifdef COMPAT_FREEBSD32 + if (compat32) + dlen = SA_SIZE32(sa); + else +#endif + dlen = SA_SIZE(sa); if (cp != NULL && buflen >= dlen) { #ifdef INET6 if (V_deembed_scopeid && sa->sa_family == AF_INET6) { diff --git a/freebsd/sys/net/sff8472.h b/freebsd/sys/net/sff8472.h index e67aa7f6..d38fcfc0 100644 --- a/freebsd/sys/net/sff8472.h +++ b/freebsd/sys/net/sff8472.h @@ -379,7 +379,7 @@ enum { /* * Table 3.2 Identifier values. - * Identifier constants has taken from SFF-8024 rev 2.9 table 4.1 + * Identifier constants has taken from SFF-8024 rev 4.2 table 4.1 * (as referenced by table 3.2 footer) * */ enum { @@ -400,13 +400,15 @@ enum { SFF_8024_ID_CXP = 0xE, /* CXP */ SFF_8024_ID_HD4X = 0xF, /* Shielded Mini Multilane HD 4X */ SFF_8024_ID_HD8X = 0x10, /* Shielded Mini Multilane HD 8X */ - SFF_8024_ID_QSFP28 = 0x11, /* QSFP28 */ + SFF_8024_ID_QSFP28 = 0x11, /* QSFP28 or later */ SFF_8024_ID_CXP2 = 0x12, /* CXP2 (aka CXP28) */ SFF_8024_ID_CDFP = 0x13, /* CDFP (Style 1/Style 2) */ SFF_8024_ID_SMM4 = 0x14, /* Shielded Mini Multilate HD 4X Fanout */ SFF_8024_ID_SMM8 = 0x15, /* Shielded Mini Multilate HD 8X Fanout */ SFF_8024_ID_CDFP3 = 0x16, /* CDFP (Style3) */ - SFF_8024_ID_LAST = SFF_8024_ID_CDFP3 + SFF_8024_ID_MICROQSFP = 0x17, /* microQSFP */ + SFF_8024_ID_QSFP_DD = 0x18, /* QSFP-DD 8X Pluggable Transceiver */ + SFF_8024_ID_LAST = SFF_8024_ID_QSFP_DD }; static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {"Unknown", @@ -431,7 +433,9 @@ static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {"Unknown", "CDFP", "SMM4", "SMM8", - "CDFP3"}; + "CDFP3", + "microQSFP", + "QSFP-DD"}; /* Keep compatibility with old definitions */ #define SFF_8472_ID_UNKNOWN SFF_8024_ID_UNKNOWN diff --git a/freebsd/sys/net80211/ieee80211_ht.c b/freebsd/sys/net80211/ieee80211_ht.c index 21d85fb3..c6a3a200 100644 --- a/freebsd/sys/net80211/ieee80211_ht.c +++ b/freebsd/sys/net80211/ieee80211_ht.c @@ -3356,7 +3356,7 @@ ieee80211_add_htinfo_body(uint8_t *frm, struct ieee80211_node *ni) } /* - * Add 802.11n HT information information element. + * Add 802.11n HT information element. */ uint8_t * ieee80211_add_htinfo(uint8_t *frm, struct ieee80211_node *ni) diff --git a/freebsd/sys/net80211/ieee80211_node.c b/freebsd/sys/net80211/ieee80211_node.c index 023fb128..45d6fa73 100644 --- a/freebsd/sys/net80211/ieee80211_node.c +++ b/freebsd/sys/net80211/ieee80211_node.c @@ -245,7 +245,12 @@ ieee80211_node_setuptxparms(struct ieee80211_node *ni) struct ieee80211vap *vap = ni->ni_vap; enum ieee80211_phymode mode; - if (ni->ni_flags & IEEE80211_NODE_HT) { + if (ni->ni_flags & IEEE80211_NODE_VHT) { + if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) + mode = IEEE80211_MODE_VHT_5GHZ; + else + mode = IEEE80211_MODE_VHT_2GHZ; + } else if (ni->ni_flags & IEEE80211_NODE_HT) { if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) mode = IEEE80211_MODE_11NA; else diff --git a/freebsd/sys/net80211/ieee80211_output.c b/freebsd/sys/net80211/ieee80211_output.c index 51a75af2..a49c8a16 100644 --- a/freebsd/sys/net80211/ieee80211_output.c +++ b/freebsd/sys/net80211/ieee80211_output.c @@ -553,6 +553,59 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni, return (error); } +static int +ieee80211_validate_frame(struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211_frame *wh; + int type; + + if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_ack)) + return (EINVAL); + + wh = mtod(m, struct ieee80211_frame *); + if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != + IEEE80211_FC0_VERSION_0) + return (EINVAL); + + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + if (type != IEEE80211_FC0_TYPE_DATA) { + if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != + IEEE80211_FC1_DIR_NODS) + return (EINVAL); + + if (type != IEEE80211_FC0_TYPE_MGT && + (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) != 0) + return (EINVAL); + + /* XXX skip other field checks? */ + } + + if ((params && (params->ibp_flags & IEEE80211_BPF_CRYPTO) != 0) || + (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0) { + int subtype; + + subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; + + /* + * See IEEE Std 802.11-2012, + * 8.2.4.1.9 'Protected Frame field' + */ + /* XXX no support for robust management frames yet. */ + if (!(type == IEEE80211_FC0_TYPE_DATA || + (type == IEEE80211_FC0_TYPE_MGT && + subtype == IEEE80211_FC0_SUBTYPE_AUTH))) + return (EINVAL); + + wh->i_fc[1] |= IEEE80211_FC1_PROTECTED; + } + + if (m->m_pkthdr.len < ieee80211_anyhdrsize(wh)) + return (EINVAL); + + return (0); +} + /* * 802.11 output routine. This is (currently) used only to * connect bpf write calls to the 802.11 layer for injecting @@ -563,6 +616,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, struct route *ro) { #define senderr(e) do { error = (e); goto bad;} while (0) + const struct ieee80211_bpf_params *params = NULL; struct ieee80211_node *ni = NULL; struct ieee80211vap *vap; struct ieee80211_frame *wh; @@ -608,14 +662,20 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, senderr(EIO); /* XXX bypass bridge, pfil, carp, etc. */ - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_ack)) - senderr(EIO); /* XXX */ + /* + * NB: DLT_IEEE802_11_RADIO identifies the parameters are + * present by setting the sa_len field of the sockaddr (yes, + * this is a hack). + * NB: we assume sa_data is suitably aligned to cast. + */ + if (dst->sa_len != 0) + params = (const struct ieee80211_bpf_params *)dst->sa_data; + + error = ieee80211_validate_frame(m, params); + if (error != 0) + senderr(error); + wh = mtod(m, struct ieee80211_frame *); - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) - senderr(EIO); /* XXX */ - if (m->m_pkthdr.len < ieee80211_anyhdrsize(wh)) - senderr(EIO); /* XXX */ /* locate destination node */ switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { @@ -628,7 +688,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, ni = ieee80211_find_txnode(vap, wh->i_addr3); break; default: - senderr(EIO); /* XXX */ + senderr(EDOOFUS); } if (ni == NULL) { /* @@ -647,11 +707,18 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, * it marks EAPOL in frames with M_EAPOL. */ m->m_flags &= ~M_80211_TX; + m->m_flags |= M_ENCAP; /* mark encapsulated */ - /* calculate priority so drivers can find the tx queue */ - /* XXX assumes an 802.3 frame */ - if (ieee80211_classify(ni, m)) - senderr(EIO); /* XXX */ + if (IEEE80211_IS_DATA(wh)) { + /* calculate priority so drivers can find the tx queue */ + if (ieee80211_classify(ni, m)) + senderr(EIO); /* XXX */ + + /* NB: ieee80211_encap does not include 802.11 header */ + IEEE80211_NODE_STAT_ADD(ni, tx_bytes, + m->m_pkthdr.len - ieee80211_hdrsize(wh)); + } else + M_WME_SETAC(m, WME_AC_BE); IEEE80211_NODE_STAT(ni, tx_data); if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { @@ -659,20 +726,9 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, m->m_flags |= M_MCAST; } else IEEE80211_NODE_STAT(ni, tx_ucast); - /* NB: ieee80211_encap does not include 802.11 header */ - IEEE80211_NODE_STAT_ADD(ni, tx_bytes, m->m_pkthdr.len); IEEE80211_TX_LOCK(ic); - - /* - * NB: DLT_IEEE802_11_RADIO identifies the parameters are - * present by setting the sa_len field of the sockaddr (yes, - * this is a hack). - * NB: we assume sa_data is suitably aligned to cast. - */ - ret = ieee80211_raw_output(vap, ni, m, - (const struct ieee80211_bpf_params *)(dst->sa_len ? - dst->sa_data : NULL)); + ret = ieee80211_raw_output(vap, ni, m, params); IEEE80211_TX_UNLOCK(ic); return (ret); bad: @@ -1008,13 +1064,44 @@ ieee80211_send_nulldata(struct ieee80211_node *ni) int ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m) { - const struct ether_header *eh = mtod(m, struct ether_header *); + const struct ether_header *eh = NULL; + uint16_t ether_type; int v_wme_ac, d_wme_ac, ac; + if (__predict_false(m->m_flags & M_ENCAP)) { + struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); + struct llc *llc; + int hdrlen, subtype; + + subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; + if (subtype & IEEE80211_FC0_SUBTYPE_NODATA) { + ac = WME_AC_BE; + goto done; + } + + hdrlen = ieee80211_hdrsize(wh); + if (m->m_pkthdr.len < hdrlen + sizeof(*llc)) + return 1; + + llc = (struct llc *)mtodo(m, hdrlen); + if (llc->llc_dsap != LLC_SNAP_LSAP || + llc->llc_ssap != LLC_SNAP_LSAP || + llc->llc_control != LLC_UI || + llc->llc_snap.org_code[0] != 0 || + llc->llc_snap.org_code[1] != 0 || + llc->llc_snap.org_code[2] != 0) + return 1; + + ether_type = llc->llc_snap.ether_type; + } else { + eh = mtod(m, struct ether_header *); + ether_type = eh->ether_type; + } + /* * Always promote PAE/EAPOL frames to high priority. */ - if (eh->ether_type == htons(ETHERTYPE_PAE)) { + if (ether_type == htons(ETHERTYPE_PAE)) { /* NB: mark so others don't need to check header */ m->m_flags |= M_EAPOL; ac = WME_AC_VO; @@ -1049,7 +1136,7 @@ ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m) /* XXX m_copydata may be too slow for fast path */ #ifdef INET - if (eh->ether_type == htons(ETHERTYPE_IP)) { + if (eh && eh->ether_type == htons(ETHERTYPE_IP)) { uint8_t tos; /* * IP frame, map the DSCP bits from the TOS field. @@ -1062,7 +1149,7 @@ ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m) } else { #endif /* INET */ #ifdef INET6 - if (eh->ether_type == htons(ETHERTYPE_IPV6)) { + if (eh && eh->ether_type == htons(ETHERTYPE_IPV6)) { uint32_t flow; uint8_t tos; /* diff --git a/freebsd/sys/net80211/ieee80211_proto.c b/freebsd/sys/net80211/ieee80211_proto.c index 73410d70..129e11e2 100644 --- a/freebsd/sys/net80211/ieee80211_proto.c +++ b/freebsd/sys/net80211/ieee80211_proto.c @@ -1310,6 +1310,12 @@ ieee80211_wme_updateparams(struct ieee80211vap *vap) } } +/* + * Fetch the WME parameters for the given VAP. + * + * When net80211 grows p2p, etc support, this may return different + * parameters for each VAP. + */ void ieee80211_wme_vap_getparams(struct ieee80211vap *vap, struct chanAccParams *wp) { @@ -1317,6 +1323,12 @@ ieee80211_wme_vap_getparams(struct ieee80211vap *vap, struct chanAccParams *wp) memcpy(wp, &vap->iv_ic->ic_wme.wme_chanParams, sizeof(*wp)); } +/* + * For NICs which only support one set of WME paramaters (ie, softmac NICs) + * there may be different VAP WME parameters but only one is "active". + * This returns the "NIC" WME parameters for the currently active + * context. + */ void ieee80211_wme_ic_getparams(struct ieee80211com *ic, struct chanAccParams *wp) { @@ -1324,6 +1336,26 @@ ieee80211_wme_ic_getparams(struct ieee80211com *ic, struct chanAccParams *wp) memcpy(wp, &ic->ic_wme.wme_chanParams, sizeof(*wp)); } +/* + * Return whether to use QoS on a given WME queue. + * + * This is intended to be called from the transmit path of softmac drivers + * which are setting NoAck bits in transmit descriptors. + * + * Ideally this would be set in some transmit field before the packet is + * queued to the driver but net80211 isn't quite there yet. + */ +int +ieee80211_wme_vap_ac_is_noack(struct ieee80211vap *vap, int ac) +{ + /* Bounds/sanity check */ + if (ac < 0 || ac >= WME_NUM_AC) + return (0); + + /* Again, there's only one global context for now */ + return (!! vap->iv_ic->ic_wme.wme_chanParams.cap_wmeParams[ac].wmep_noackPolicy); +} + static void parent_updown(void *arg, int npending) { diff --git a/freebsd/sys/net80211/ieee80211_proto.h b/freebsd/sys/net80211/ieee80211_proto.h index 187f7018..28238ce8 100644 --- a/freebsd/sys/net80211/ieee80211_proto.h +++ b/freebsd/sys/net80211/ieee80211_proto.h @@ -298,6 +298,7 @@ void ieee80211_wme_vap_getparams(struct ieee80211vap *vap, struct chanAccParams *); void ieee80211_wme_ic_getparams(struct ieee80211com *ic, struct chanAccParams *); +int ieee80211_wme_vap_ac_is_noack(struct ieee80211vap *vap, int ac); /* * Return the WME TID from a QoS frame. If no TID diff --git a/freebsd/sys/net80211/ieee80211_scan_sta.c b/freebsd/sys/net80211/ieee80211_scan_sta.c index ed069ed8..a7a1fc29 100644 --- a/freebsd/sys/net80211/ieee80211_scan_sta.c +++ b/freebsd/sys/net80211/ieee80211_scan_sta.c @@ -121,7 +121,7 @@ static void sta_flush_table(struct sta_table *); /* * match_bss returns a bitmask describing if an entry is suitable * for use. If non-zero the entry was deemed not suitable and it's - * contents explains why. The following flags are or'd to to this + * contents explains why. The following flags are or'd to this * mask and can be used to figure out why the entry was rejected. */ #define MATCH_CHANNEL 0x00001 /* channel mismatch */ diff --git a/freebsd/sys/netinet/icmp6.h b/freebsd/sys/netinet/icmp6.h index b0ae67fe..310684b8 100644 --- a/freebsd/sys/netinet/icmp6.h +++ b/freebsd/sys/netinet/icmp6.h @@ -628,7 +628,7 @@ struct icmp6stat { uint64_t icp6s_nd_badopt; /* bad ND options */ uint64_t icp6s_badns; /* bad neighbor solicitation */ uint64_t icp6s_badna; /* bad neighbor advertisement */ - uint64_t icp6s_badrs; /* bad router advertisement */ + uint64_t icp6s_badrs; /* bad router solicitation */ uint64_t icp6s_badra; /* bad router advertisement */ uint64_t icp6s_badredirect; /* bad redirect message */ }; diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c index 2783a276..2803126d 100644 --- a/freebsd/sys/netinet/in_pcb.c +++ b/freebsd/sys/netinet/in_pcb.c @@ -1331,9 +1331,7 @@ in_pcbfree(struct inpcb *inp) if (inp->inp_moptions != NULL) inp_freemoptions(inp->inp_moptions); #endif - RO_RTFREE(&inp->inp_route); - if (inp->inp_route.ro_lle) - LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */ + RO_INVALIDATE_CACHE(&inp->inp_route); inp->inp_vflag = 0; inp->inp_flags2 |= INP_FREED; @@ -2271,9 +2269,7 @@ void in_losing(struct inpcb *inp) { - RO_RTFREE(&inp->inp_route); - if (inp->inp_route.ro_lle) - LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */ + RO_INVALIDATE_CACHE(&inp->inp_route); return; } diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c index eba4af63..3bf4fa91 100644 --- a/freebsd/sys/netinet/ip_mroute.c +++ b/freebsd/sys/netinet/ip_mroute.c @@ -2820,7 +2820,7 @@ static void vnet_mroute_init(const void *unused __unused) { - MALLOC(V_nexpire, u_char *, mfchashsize, M_MRTABLE, M_WAITOK|M_ZERO); + V_nexpire = malloc(mfchashsize, M_MRTABLE, M_WAITOK|M_ZERO); bzero(V_bw_meter_timers, sizeof(V_bw_meter_timers)); callout_init(&V_expire_upcalls_ch, 1); callout_init(&V_bw_upcalls_ch, 1); @@ -2834,7 +2834,7 @@ static void vnet_mroute_uninit(const void *unused __unused) { - FREE(V_nexpire, M_MRTABLE); + free(V_nexpire, M_MRTABLE); V_nexpire = NULL; } diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c index 62110ed1..4944c035 100644 --- a/freebsd/sys/netinet/ip_output.c +++ b/freebsd/sys/netinet/ip_output.c @@ -304,11 +304,8 @@ again: !RT_LINK_IS_UP(rte->rt_ifp) || dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { - RTFREE(rte); - rte = ro->ro_rt = (struct rtentry *)NULL; - if (ro->ro_lle) - LLE_FREE(ro->ro_lle); /* zeros ro_lle */ - ro->ro_lle = (struct llentry *)NULL; + RO_INVALIDATE_CACHE(ro); + rte = NULL; } ia = NULL; have_ia_ref = 0; diff --git a/freebsd/sys/netinet/ip_reass.c b/freebsd/sys/netinet/ip_reass.c index 30cf3ba4..64660228 100644 --- a/freebsd/sys/netinet/ip_reass.c +++ b/freebsd/sys/netinet/ip_reass.c @@ -379,6 +379,7 @@ ip_reass(struct mbuf *m) q->m_nextpkt = NULL; m->m_pkthdr.csum_flags &= q->m_pkthdr.csum_flags; m->m_pkthdr.csum_data += q->m_pkthdr.csum_data; + m_demote_pkthdr(q); m_cat(m, q); } /* diff --git a/freebsd/sys/netinet/libalias/alias_mod.h b/freebsd/sys/netinet/libalias/alias_mod.h index d57798f7..c646f794 100644 --- a/freebsd/sys/netinet/libalias/alias_mod.h +++ b/freebsd/sys/netinet/libalias/alias_mod.h @@ -43,7 +43,7 @@ MALLOC_DECLARE(M_ALIAS); #if defined(_SYS_MALLOC_H_) #ifndef __rtems__ #define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO) -#define calloc(x, n) malloc(x*n) +#define calloc(n, x) mallocarray((n), (x), M_ALIAS, M_NOWAIT|M_ZERO) #define free(x) free(x, M_ALIAS) #else /* __rtems__ */ #undef malloc diff --git a/freebsd/sys/netinet/libalias/alias_sctp.c b/freebsd/sys/netinet/libalias/alias_sctp.c index f7fda7bf..4f7d4940 100644 --- a/freebsd/sys/netinet/libalias/alias_sctp.c +++ b/freebsd/sys/netinet/libalias/alias_sctp.c @@ -29,7 +29,7 @@ */ /* - * Alias_sctp forms part of the libalias kernel module to handle + * Alias_sctp forms part of the libalias kernel module to handle * Network Address Translation (NAT) for the SCTP protocol. * * This software was developed by David A. Hayes and Jason But @@ -41,13 +41,13 @@ * proposed by Jason But and Grenville Armitage: * http://caia.swin.edu.au/urp/sonata/ * - * + * * This project has been made possible in part by a grant from * the Cisco University Research Program Fund at Community * Foundation Silicon Valley. * */ -/** @mainpage +/** @mainpage * Alias_sctp is part of the SONATA (http://caia.swin.edu.au/urp/sonata) project * to develop and release a BSD licensed implementation of a Network Address * Translation (NAT) module that supports the Stream Control Transmission @@ -178,7 +178,7 @@ static void SctpAliasLog(const char *format, ...); * * Calls the higher level ShowAliasStats() in alias_db.c which logs all current * statistics about the libalias instance - including SCTP statistics - * + * * @param la Pointer to the libalias instance */ void SctpShowAliasStats(struct libalias *la); @@ -189,7 +189,7 @@ static MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs"); /* Use kernel allocator. */ #ifdef _SYS_MALLOC_H_ #define sn_malloc(x) malloc(x, M_SCTPNAT, M_NOWAIT|M_ZERO) -#define sn_calloc(n,x) sn_malloc(x * n) +#define sn_calloc(n,x) mallocarray((n), (x), M_SCTPNAT, M_NOWAIT|M_ZERO) #define sn_free(x) free(x, M_SCTPNAT) #endif// #ifdef _SYS_MALLOC_H_ @@ -263,7 +263,7 @@ static MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs"); * Define various log levels and a macro to call specified log functions only if * the current log level (sysctl_log_level) matches the specified level @{ */ -#define SN_LOG_LOW 0 +#define SN_LOG_LOW 0 #define SN_LOG_EVENT 1 #define SN_LOG_INFO 2 #define SN_LOG_DETAIL 3 @@ -424,9 +424,9 @@ int sysctl_chg_loglevel(SYSCTL_HANDLER_ARGS) error = sysctl_handle_int(oidp, &level, 0, req); if (error) return (error); - sysctl_log_level = (level > SN_LOG_DEBUG_MAX)?(SN_LOG_DEBUG_MAX):(level); - sysctl_log_level = (level < SN_LOG_LOW)?(SN_LOG_LOW):(level); - + level = (level > SN_LOG_DEBUG_MAX) ? (SN_LOG_DEBUG_MAX) : (level); + level = (level < SN_LOG_LOW) ? (SN_LOG_LOW) : (level); + sysctl_log_level = level; return (0); } @@ -445,12 +445,11 @@ int sysctl_chg_timer(SYSCTL_HANDLER_ARGS) error = sysctl_handle_int(oidp, &timer, 0, req); if (error) return (error); - timer = (timer > SN_MAX_TIMER)?(SN_MAX_TIMER):(timer); + timer = (timer > SN_MAX_TIMER) ? (SN_MAX_TIMER) : (timer); - if (((u_int *)arg1) != &sysctl_holddown_timer) - { - timer = (timer < SN_MIN_TIMER)?(SN_MIN_TIMER):(timer); - } + if (((u_int *)arg1) != &sysctl_holddown_timer) { + timer = (timer < SN_MIN_TIMER) ? (SN_MIN_TIMER) : (timer); + } *(u_int *)arg1 = timer; @@ -474,11 +473,11 @@ int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS) error = sysctl_handle_int(oidp, &size, 0, req); if (error) return (error); - size = (size < SN_MIN_HASH_SIZE)?(SN_MIN_HASH_SIZE):((size > SN_MAX_HASH_SIZE)?(SN_MAX_HASH_SIZE):(size)); + size = (size < SN_MIN_HASH_SIZE) ? (SN_MIN_HASH_SIZE) : ((size > SN_MAX_HASH_SIZE) ? (SN_MAX_HASH_SIZE) : (size)); size |= 0x00000001; /* make odd */ - for(;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2); + for (;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2); sysctl_hashtable_size = size; return (0); @@ -487,7 +486,7 @@ int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS) /** @ingroup sysctl * @brief sysctl callback for changing net.inet.ip.alias.sctp.error_on_ootb * - * Updates the error_on_clash sysctl variable. + * Updates the error_on_clash sysctl variable. * If set to 0, no ErrorM will be sent if there is a look up table clash * If set to 1, an ErrorM is sent only to the local side * If set to 2, an ErrorM is sent to the local side and global side if there is @@ -542,16 +541,16 @@ int sysctl_chg_initialising_chunk_proc_limit(SYSCTL_HANDLER_ARGS) if (error) return (error); sysctl_initialising_chunk_proc_limit = (proclimit < 1) ? 1: proclimit; - sysctl_chunk_proc_limit = + sysctl_chunk_proc_limit = (sysctl_chunk_proc_limit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : sysctl_chunk_proc_limit; - + return (0); } /** @ingroup sysctl * @brief sysctl callback for changing net.inet.ip.alias.sctp.chunk_proc_limit * - * Updates the chunk_proc_limit sysctl variable. + * Updates the chunk_proc_limit sysctl variable. * Number of chunks that should be processed to find key chunk: * >= initialising_chunk_proc_limit (A high value is a DoS risk) */ @@ -563,7 +562,7 @@ int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS) error = sysctl_handle_int(oidp, &proclimit, 0, req); if (error) return (error); - sysctl_chunk_proc_limit = + sysctl_chunk_proc_limit = (proclimit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : proclimit; return (0); @@ -573,7 +572,7 @@ int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS) /** @ingroup sysctl * @brief sysctl callback for changing net.inet.ip.alias.sctp.param_proc_limit * - * Updates the param_proc_limit sysctl variable. + * Updates the param_proc_limit sysctl variable. * Number of parameters that should be processed to find key parameters: * > 1 (A high value is a DoS risk) */ @@ -585,7 +584,7 @@ int sysctl_chg_param_proc_limit(SYSCTL_HANDLER_ARGS) error = sysctl_handle_int(oidp, &proclimit, 0, req); if (error) return (error); - sysctl_param_proc_limit = + sysctl_param_proc_limit = (proclimit < 2) ? 2 : proclimit; return (0); @@ -616,9 +615,9 @@ int sysctl_chg_track_global_addresses(SYSCTL_HANDLER_ARGS) * CODE BEGINS HERE * ---------------------------------------------------------------------- */ -/** +/** * @brief Initialises the SCTP NAT Implementation - * + * * Creates the look-up tables and the timer queue and initialises all state * variables * @@ -652,7 +651,7 @@ void AliasSctpInit(struct libalias *la) la->sctpLinkCount = 0; } -/** +/** * @brief Cleans-up the SCTP NAT Implementation prior to unloading * * Removes all entries from the timer queue, freeing associations as it goes. @@ -707,7 +706,7 @@ void AliasSctpTerm(struct libalias *la) * @param la Pointer to the relevant libalias instance * @param pip Pointer to IP packet to process * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * + * * @return PKT_ALIAS_OK | PKT_ALIAS_IGNORE | PKT_ALIAS_ERROR */ int @@ -719,10 +718,10 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction) if ((direction != SN_TO_LOCAL) && (direction != SN_TO_GLOBAL)) { SctpAliasLog("ERROR: Invalid direction\n"); - return(PKT_ALIAS_ERROR); + return (PKT_ALIAS_ERROR); } - sctp_CheckTimers(la); /* Check timers */ + sctp_CheckTimers(la); /* Check timers */ /* Parse the packet */ rtnval = sctp_PktParser(la, direction, pip, &msg, &assoc); //using *char (change to mbuf when get code from paolo) @@ -737,24 +736,24 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction) } SN_LOG(SN_LOG_EVENT, logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); - return(PKT_ALIAS_ERROR); + return (PKT_ALIAS_ERROR); case SN_PARSE_ERROR_PARTIALLOOKUP: if (sysctl_error_on_ootb > SN_LOCALandPARTIAL_ERROR_ON_OOTB) { SN_LOG(SN_LOG_EVENT, logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); - return(PKT_ALIAS_ERROR); + return (PKT_ALIAS_ERROR); } case SN_PARSE_ERROR_LOOKUP: if (sysctl_error_on_ootb == SN_ERROR_ON_OOTB || (sysctl_error_on_ootb == SN_LOCALandPARTIAL_ERROR_ON_OOTB && direction == SN_TO_LOCAL) || (sysctl_error_on_ootb == SN_LOCAL_ERROR_ON_OOTB && direction == SN_TO_GLOBAL)) { TxAbortErrorM(la, &msg, assoc, SN_REFLECT_ERROR, direction); /*NB assoc=NULL */ - return(PKT_ALIAS_RESPOND); + return (PKT_ALIAS_RESPOND); } default: SN_LOG(SN_LOG_EVENT, logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); - return(PKT_ALIAS_ERROR); + return (PKT_ALIAS_ERROR); } SN_LOG(SN_LOG_DETAIL, @@ -772,9 +771,9 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction) ); SN_LOG(SN_LOG_DEBUG, logTimerQ(la)); - switch(rtnval){ + switch (rtnval) { case SN_NAT_PKT: - switch(direction) { + switch (direction) { case SN_TO_LOCAL: DifferentialChecksum(&(msg.ip_hdr->ip_sum), &(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2); @@ -796,7 +795,7 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction) break; case SN_REPLY_ABORT: case SN_REPLY_ERROR: - case SN_SEND_ABORT: + case SN_SEND_ABORT: TxAbortErrorM(la, &msg, assoc, rtnval, direction); break; default: @@ -816,22 +815,22 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction) freeGlobalAddressList(assoc); sn_free(assoc); } - switch(rtnval) { + switch (rtnval) { case SN_NAT_PKT: - return(PKT_ALIAS_OK); + return (PKT_ALIAS_OK); case SN_SEND_ABORT: - return(PKT_ALIAS_OK); + return (PKT_ALIAS_OK); case SN_REPLY_ABORT: case SN_REPLY_ERROR: case SN_REFLECT_ERROR: - return(PKT_ALIAS_RESPOND); + return (PKT_ALIAS_RESPOND); case SN_DROP_PKT: default: - return(PKT_ALIAS_ERROR); + return (PKT_ALIAS_ERROR); } } -/** +/** * @brief Send an AbortM or ErrorM * * We construct the new SCTP packet to send in place of the existing packet we @@ -867,7 +866,7 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction) static uint32_t local_sctp_finalize_crc32(uint32_t crc32c) { - /* This routine is duplicated from SCTP + /* This routine is duplicated from SCTP * we need to do that since it MAY be that SCTP * is NOT compiled into the kernel. The CRC32C routines * however are always available in libkern. @@ -926,7 +925,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso ip->ip_hl = 5; /* 5*32 bit words */ ip->ip_tos = 0; ip->ip_len = htons(ip_size); - ip->ip_id = sm->ip_hdr->ip_id; + ip->ip_id = sm->ip_hdr->ip_id; ip->ip_off = 0; ip->ip_ttl = 255; ip->ip_p = IPPROTO_SCTP; @@ -939,7 +938,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR; chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG; if (include_error_cause) { - error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION); + error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION); error_cause->length = htons(sizeof(struct sctp_error_cause)); chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause)); } else { @@ -947,22 +946,22 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso } /* set specific values */ - switch(sndrply) { + switch (sndrply) { case SN_REFLECT_ERROR: chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */ - sctp_hdr->v_tag = sm->sctp_hdr->v_tag; + sctp_hdr->v_tag = sm->sctp_hdr->v_tag; break; case SN_REPLY_ERROR: - sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ; + sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ; break; case SN_SEND_ABORT: - sctp_hdr->v_tag = sm->sctp_hdr->v_tag; + sctp_hdr->v_tag = sm->sctp_hdr->v_tag; break; case SN_REPLY_ABORT: sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag; break; } - + /* Set send/reply values */ if (sndrply == SN_SEND_ABORT) { /*pass through NAT */ ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr; @@ -975,10 +974,10 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso sctp_hdr->src_port = sm->sctp_hdr->dest_port; sctp_hdr->dest_port = sm->sctp_hdr->src_port; } - + /* Calculate IP header checksum */ ip->ip_sum = in_cksum_hdr(ip); - + /* calculate SCTP header CRC32 */ sctp_hdr->checksum = 0; sctp_hdr->checksum = local_sctp_finalize_crc32(calculate_crc32c(0xffffffff, (unsigned char *) sctp_hdr, sctp_size)); @@ -1005,18 +1004,18 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso */ /** @ingroup packet_parser * @brief Parses SCTP packets for the key SCTP chunk that will be processed - * + * * This module parses SCTP packets for the key SCTP chunk that will be processed * The module completes the sctp_nat_msg structure and either retrieves the * relevant (existing) stored association from the Hash Tables or creates a new * association entity with state SN_ID * * @param la Pointer to the relevant libalias instance - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * @param pip + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * @param pip * @param sm Pointer to sctp message information * @param passoc Pointer to the association this SCTP Message belongs to - * + * * @return SN_PARSE_OK | SN_PARSE_ERROR_* */ static int @@ -1051,26 +1050,26 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, /* Check SCTP header length and move to first chunk */ if (bytes_left < sizeof(struct sctphdr)) { sm->sctp_hdr = NULL; - return(SN_PARSE_ERROR_IPSHL); /* packet not long enough*/ + return (SN_PARSE_ERROR_IPSHL); /* packet not long enough*/ } sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip); bytes_left -= sizeof(struct sctphdr); - + /* Check for valid ports (zero valued ports would find partially initialised associations */ if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0) - return(SN_PARSE_ERROR_PORT); + return (SN_PARSE_ERROR_PORT); /* Check length of first chunk */ if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/ - return(SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */ - + return (SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */ + /* First chunk */ chunk_hdr = SN_SCTP_FIRSTCHUNK(sctp_hdr); - + chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could cause endless loop*/ - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) && ((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) || @@ -1093,43 +1092,43 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/ sm->chunk_length = 0; /* only care about length for key chunks */ while (IS_SCTP_CONTROL(chunk_hdr)) { - switch(chunk_hdr->chunk_type) { + switch (chunk_hdr->chunk_type) { case SCTP_INITIATION: if (chunk_length < sizeof(struct sctp_init_chunk)) /* malformed chunk*/ - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); sm->msg = SN_SCTP_INIT; sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); sm->chunk_length = chunk_length; /* if no existing association, create a new one */ if (*passoc == NULL) { - if (sctp_hdr->v_tag == 0){ //Init requires vtag=0 + if (sctp_hdr->v_tag == 0) { //Init requires vtag=0 *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc)); - if (*passoc == NULL) {/* out of resources */ - return(SN_PARSE_ERROR_AS_MALLOC); + if (*passoc == NULL) {/* out of resources */ + return (SN_PARSE_ERROR_AS_MALLOC); } - /* Initialise association - malloc initialises memory to zeros */ + /* Initialize association - sn_malloc initializes memory to zeros */ (*passoc)->state = SN_ID; LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ (*passoc)->TableRegister = SN_NULL_TBL; - return(SN_PARSE_OK); + return (SN_PARSE_OK); } - return(SN_PARSE_ERROR_VTAG); + return (SN_PARSE_ERROR_VTAG); } - return(SN_PARSE_ERROR_LOOKUP); + return (SN_PARSE_ERROR_LOOKUP); case SCTP_INITIATION_ACK: if (chunk_length < sizeof(struct sctp_init_ack_chunk)) /* malformed chunk*/ - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); sm->msg = SN_SCTP_INITACK; sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); sm->chunk_length = chunk_length; - return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK)); + return ((*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP) : (SN_PARSE_OK)); case SCTP_ABORT_ASSOCIATION: /* access only minimum sized chunk */ sm->msg = SN_SCTP_ABORT; sm->chunk_length = chunk_length; - return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP_ABORT):(SN_PARSE_OK)); + return ((*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP_ABORT) : (SN_PARSE_OK)); case SCTP_SHUTDOWN_ACK: if (chunk_length < sizeof(struct sctp_shutdown_ack_chunk)) /* malformed chunk*/ - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); if (sm->msg > SN_SCTP_SHUTACK) { sm->msg = SN_SCTP_SHUTACK; sm->chunk_length = chunk_length; @@ -1140,11 +1139,11 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, sm->msg = SN_SCTP_SHUTCOMP; sm->chunk_length = chunk_length; } - return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK)); + return ((*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP) : (SN_PARSE_OK)); case SCTP_ASCONF: if (sm->msg > SN_SCTP_ASCONF) { if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv4addr_param))) /* malformed chunk*/ - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); //leave parameter searching to later, if required param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_chunk)); /*compulsory IP parameter*/ if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) { @@ -1153,38 +1152,38 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr; *passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match); } - param_hdr = (struct sctp_paramhdr *) + param_hdr = (struct sctp_paramhdr *) ((char *) param_hdr + sizeof(struct sctp_ipv4addr_param)); /*asconf's compulsory address parameter */ sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr_param); /* rest of chunk */ } else { if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv6addr_param))) /* malformed chunk*/ - return(SN_PARSE_ERROR_CHHL); - param_hdr = (struct sctp_paramhdr *) - ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */ + return (SN_PARSE_ERROR_CHHL); + param_hdr = (struct sctp_paramhdr *) + ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */ sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr_param); /* rest of chunk */ } sm->msg = SN_SCTP_ASCONF; sm->sctpchnk.Asconf = param_hdr; - + if (*passoc == NULL) { /* AddIP with no association */ *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc)); - if (*passoc == NULL) {/* out of resources */ - return(SN_PARSE_ERROR_AS_MALLOC); + if (*passoc == NULL) {/* out of resources */ + return (SN_PARSE_ERROR_AS_MALLOC); } - /* Initialise association - malloc initialises memory to zeros */ + /* Initialize association - sn_malloc initializes memory to zeros */ (*passoc)->state = SN_ID; LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ (*passoc)->TableRegister = SN_NULL_TBL; - return(SN_PARSE_OK); + return (SN_PARSE_OK); } } break; case SCTP_ASCONF_ACK: if (sm->msg > SN_SCTP_ASCONFACK) { if (chunk_length < sizeof(struct sctp_asconf_ack_chunk)) /* malformed chunk*/ - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); //leave parameter searching to later, if required - param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_ack_chunk)); sm->msg = SN_SCTP_ASCONFACK; sm->sctpchnk.Asconf = param_hdr; @@ -1197,33 +1196,33 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, /* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_chunk_proc_limit */ if ((*passoc == NULL) && (chunk_count >= sysctl_initialising_chunk_proc_limit)) - return(SN_PARSE_ERROR_LOOKUP); + return (SN_PARSE_ERROR_LOOKUP); /* finished with this chunk, on to the next chunk*/ bytes_left-= chunk_length; /* Is this the end of the packet ? */ if (bytes_left == 0) - return (*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK); + return (*passoc == NULL) ? (SN_PARSE_ERROR_LOOKUP) : (SN_PARSE_OK); /* Are there enough bytes in packet to at least retrieve length of next chunk ? */ if (bytes_left < SN_MIN_CHUNK_SIZE) - return(SN_PARSE_ERROR_CHHL); + return (SN_PARSE_ERROR_CHHL); chunk_hdr = SN_SCTP_NEXTCHUNK(chunk_hdr); /* Is the chunk long enough to not cause endless look and are there enough bytes in packet to read the chunk ? */ chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) - return(SN_PARSE_ERROR_CHHL); - if(++chunk_count > sysctl_chunk_proc_limit) - return(SN_PARSE_OK); /* limit for processing chunks, take what we get */ + return (SN_PARSE_ERROR_CHHL); + if (++chunk_count > sysctl_chunk_proc_limit) + return (SN_PARSE_OK); /* limit for processing chunks, take what we get */ } if (*passoc == NULL) - return (partial_match)?(SN_PARSE_ERROR_PARTIALLOOKUP):(SN_PARSE_ERROR_LOOKUP); + return (partial_match) ? (SN_PARSE_ERROR_PARTIALLOOKUP) : (SN_PARSE_ERROR_LOOKUP); else - return(SN_PARSE_OK); + return (SN_PARSE_OK); } /** @ingroup packet_parser @@ -1231,7 +1230,7 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, * * GetAsconfVtags scans an Asconf Chunk for the vtags parameter, and then * extracts the vtags. - * + * * GetAsconfVtags is not called from within sctp_PktParser. It is called only * from within ID_process when an AddIP has been received. * @@ -1239,9 +1238,9 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip, * @param sm Pointer to sctp message information * @param l_vtag Pointer to the local vtag in the association this SCTP Message belongs to * @param g_vtag Pointer to the local vtag in the association this SCTP Message belongs to - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * - * @return 1 - success | 0 - fail + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * + * @return 1 - success | 0 - fail */ static int GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, uint32_t *g_vtag, int direction) @@ -1253,7 +1252,7 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u uint32_t local_vtag; uint32_t remote_vtag; } __attribute__((packed)); - + struct sctp_vtag_param *vtag_param; struct sctp_paramhdr *param; int bytes_left; @@ -1268,7 +1267,7 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u while((bytes_left >= param_size) && (bytes_left >= SN_VTAG_PARAM_SIZE)) { if (ntohs(param->param_type) == SCTP_VTAG_PARAM) { vtag_param = (struct sctp_vtag_param *) param; - switch(direction) { + switch (direction) { /* The Internet draft is a little ambigious as to order of these vtags. We think it is this way around. If we are wrong, the order will need to be changed. */ @@ -1281,11 +1280,11 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u *l_vtag = vtag_param->local_vtag; break; } - return(1); /* found */ + return (1); /* found */ } bytes_left -= param_size; - if (bytes_left < SN_MIN_PARAM_SIZE) return(0); + if (bytes_left < SN_MIN_PARAM_SIZE) return (0); param = SN_SCTP_NEXTPARAM(param); param_size = SCTP_SIZE32(ntohs(param->param_length)); @@ -1293,22 +1292,22 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u SN_LOG(SN_LOG_EVENT, logsctperror("Parameter parse limit exceeded (GetAsconfVtags)", sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); - return(0); /* not found limit exceeded*/ + return (0); /* not found limit exceeded*/ } } - return(0); /* not found */ + return (0); /* not found */ } /** @ingroup packet_parser * @brief AddGlobalIPAddresses from Init,InitAck,or AddIP packets - * + * * AddGlobalIPAddresses scans an SCTP chunk (in sm) for Global IP addresses, and * adds them. * * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * */ static void AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) @@ -1321,7 +1320,7 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int int param_size; int param_count, addr_param_count = 0; - switch(direction) { + switch (direction) { case SN_TO_GLOBAL: /* does not contain global addresses */ g_addr = sm->ip_hdr->ip_dst; bytes_left = 0; /* force exit */ @@ -1329,7 +1328,7 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int case SN_TO_LOCAL: g_addr = sm->ip_hdr->ip_src; param_count = 1; - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_INIT: bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk); param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init)); @@ -1344,16 +1343,16 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int break; } } - if (bytes_left >= SN_MIN_PARAM_SIZE) + if (bytes_left >= SN_MIN_PARAM_SIZE) param_size = SCTP_SIZE32(ntohs(param->param_length)); else param_size = bytes_left+1; /* force skip loop */ - - if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */ + + if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */ G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); - if (G_Addr == NULL) {/* out of resources */ + if (G_Addr == NULL) {/* out of resources */ SN_LOG(SN_LOG_EVENT, - logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", + logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", sm->sctp_hdr->v_tag, 0, direction)); assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ sysctl_track_global_addresses=0; @@ -1362,7 +1361,7 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int G_Addr->g_addr = g_addr; if (!Add_Global_Address_to_List(assoc, G_Addr)) SN_LOG(SN_LOG_EVENT, - logsctperror("AddGlobalIPAddress: Address already in list", + logsctperror("AddGlobalIPAddress: Address already in list", sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); } @@ -1370,21 +1369,22 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { if (assoc->num_Gaddr >= sysctl_track_global_addresses) { SN_LOG(SN_LOG_EVENT, - logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached", + logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached", sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); return; } - switch(ntohs(param->param_type)) { + switch (ntohs(param->param_type)) { case SCTP_ADD_IP_ADDRESS: /* skip to address parameter - leave param_size so bytes left will be calculated properly*/ param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp; + /* FALLTHROUGH */ case SCTP_IPV4_ADDRESS: ipv4_param = (struct sctp_ipv4addr_param *) param; /* add addresses to association */ G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); - if (G_Addr == NULL) {/* out of resources */ + if (G_Addr == NULL) {/* out of resources */ SN_LOG(SN_LOG_EVENT, - logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", + logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", sm->sctp_hdr->v_tag, 0, direction)); assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ sysctl_track_global_addresses=0; @@ -1396,22 +1396,22 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int G_Addr->g_addr = g_addr; if (!Add_Global_Address_to_List(assoc, G_Addr)) SN_LOG(SN_LOG_EVENT, - logsctperror("AddGlobalIPAddress: Address already in list", + logsctperror("AddGlobalIPAddress: Address already in list", sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); return; /*shouldn't be any other addresses if the zero address is given*/ } else { G_Addr->g_addr.s_addr = ipv4_param->addr; if (!Add_Global_Address_to_List(assoc, G_Addr)) SN_LOG(SN_LOG_EVENT, - logsctperror("AddGlobalIPAddress: Address already in list", + logsctperror("AddGlobalIPAddress: Address already in list", sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); } - } - + } + bytes_left -= param_size; if (bytes_left < SN_MIN_PARAM_SIZE) break; - + param = SN_SCTP_NEXTPARAM(param); param_size = SCTP_SIZE32(ntohs(param->param_length)); if (++param_count > sysctl_param_proc_limit) { @@ -1423,39 +1423,39 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int } if (addr_param_count == 0) { SN_LOG(SN_LOG_DETAIL, - logsctperror("AddGlobalIPAddress: no address parameters to add", + logsctperror("AddGlobalIPAddress: no address parameters to add", sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); } } -/** +/** * @brief Add_Global_Address_to_List * * Adds a global IP address to an associations address list, if it is not * already there. The first address added us usually the packet's address, and * is most likely to be used, so it is added at the beginning. Subsequent * addresses are added after this one. - * + * * @param assoc Pointer to the association this SCTP Message belongs to * @param G_addr Pointer to the global address to add * - * @return 1 - success | 0 - fail + * @return 1 - success | 0 - fail */ static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr) { - struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL; - first_G_Addr = LIST_FIRST(&(assoc->Gaddr)); + struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL; + first_G_Addr = LIST_FIRST(&(assoc->Gaddr)); if (first_G_Addr == NULL) { LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/ } else { LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) { if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr) - return(0); /* already exists, so don't add */ + return (0); /* already exists, so don't add */ } LIST_INSERT_AFTER(first_G_Addr, G_addr, list_Gaddr); /* add address to end of list*/ } - assoc->num_Gaddr++; - return(1); /* success */ + assoc->num_Gaddr++; + return (1); /* success */ } /** @ingroup packet_parser @@ -1468,8 +1468,8 @@ static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sct * * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * */ static void RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) @@ -1482,7 +1482,7 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d int param_size; int param_count; - if(direction == SN_TO_GLOBAL) + if (direction == SN_TO_GLOBAL) g_addr = sm->ip_hdr->ip_dst; else g_addr = sm->ip_hdr->ip_src; @@ -1490,29 +1490,29 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d bytes_left = sm->chunk_length; param_count = 1; param = sm->sctpchnk.Asconf; - if (bytes_left >= SN_MIN_PARAM_SIZE) { + if (bytes_left >= SN_MIN_PARAM_SIZE) { param_size = SCTP_SIZE32(ntohs(param->param_length)); } else { SN_LOG(SN_LOG_EVENT, - logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses", + logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses", sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); return; } - + /* step through Asconf parameters */ while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) { asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param; if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */ LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { - if(G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) { + if (G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) { if (assoc->num_Gaddr > 1) { /* only delete if more than one */ LIST_REMOVE(G_Addr, list_Gaddr); sn_free(G_Addr); assoc->num_Gaddr--; } else { SN_LOG(SN_LOG_EVENT, - logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", + logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); } } @@ -1520,7 +1520,7 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d return; /*shouldn't be any other addresses if the zero address is given*/ } else { LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { - if(G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) { + if (G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) { if (assoc->num_Gaddr > 1) { /* only delete if more than one */ LIST_REMOVE(G_Addr, list_Gaddr); sn_free(G_Addr); @@ -1528,22 +1528,22 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d break; /* Since add only adds new addresses, there should be no double entries */ } else { SN_LOG(SN_LOG_EVENT, - logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", + logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); } } } } - } + } bytes_left -= param_size; if (bytes_left == 0) return; else if (bytes_left < SN_MIN_PARAM_SIZE) { SN_LOG(SN_LOG_EVENT, - logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses", + logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses", sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); return; } - + param = SN_SCTP_NEXTPARAM(param); param_size = SCTP_SIZE32(ntohs(param->param_length)); if (++param_count > sysctl_param_proc_limit) { @@ -1570,11 +1570,11 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d * Since there is currently no connection on this path, there should be no other * ASCONF configuration parameters outstanding, so we presume that if there is * an ACK that it is responding to the AddIP and activate the new association. - * + * * @param la Pointer to the relevant libalias instance * @param sm Pointer to sctp message information - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * * @return 1 - success | 0 - fail */ static int @@ -1589,45 +1589,45 @@ IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction) param = sm->sctpchnk.Asconf; param_size = SCTP_SIZE32(ntohs(param->param_length)); if (param_size == 8) - return(1); /*success - default acknowledgement of everything */ + return (1); /*success - default acknowledgement of everything */ bytes_left = sm->chunk_length; if (bytes_left < param_size) - return(0); /* not found */ + return (0); /* not found */ /* step through Asconf parameters */ while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) { if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT) - return(1); /* success - but can't match correlation IDs - should only be one */ + return (1); /* success - but can't match correlation IDs - should only be one */ /* check others just in case */ bytes_left -= param_size; if (bytes_left >= SN_MIN_PARAM_SIZE) { param = SN_SCTP_NEXTPARAM(param); } else { - return(0); + return (0); } param_size = SCTP_SIZE32(ntohs(param->param_length)); - if (bytes_left < param_size) return(0); + if (bytes_left < param_size) return (0); if (++param_count > sysctl_param_proc_limit) { SN_LOG(SN_LOG_EVENT, - logsctperror("Parameter parse limit exceeded (IsASCONFack)", + logsctperror("Parameter parse limit exceeded (IsASCONFack)", sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); - return(0); /* not found limit exceeded*/ + return (0); /* not found limit exceeded*/ } } - return(0); /* not success */ + return (0); /* not success */ } /** @ingroup packet_parser - * @brief Check to see if ASCONF contains an Add IP or Del IP parameter - * + * @brief Check to see if ASCONF contains an Add IP or Del IP parameter + * * IsADDorDEL scans an ASCONF packet to see if it contains an AddIP or DelIP * parameter * * @param la Pointer to the relevant libalias instance * @param sm Pointer to sctp message information - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL - * + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * * @return SCTP_ADD_IP_ADDRESS | SCTP_DEL_IP_ADDRESS | 0 - fail */ static int @@ -1644,31 +1644,31 @@ IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction) bytes_left = sm->chunk_length; if (bytes_left < param_size) - return(0); /* not found */ + return (0); /* not found */ /* step through Asconf parameters */ while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) { if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS) - return(SCTP_ADD_IP_ADDRESS); - else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) - return(SCTP_DEL_IP_ADDRESS); + return (SCTP_ADD_IP_ADDRESS); + else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) + return (SCTP_DEL_IP_ADDRESS); /* check others just in case */ bytes_left -= param_size; if (bytes_left >= SN_MIN_PARAM_SIZE) { param = SN_SCTP_NEXTPARAM(param); } else { - return(0); /*Neither found */ + return (0); /*Neither found */ } param_size = SCTP_SIZE32(ntohs(param->param_length)); - if (bytes_left < param_size) return(0); + if (bytes_left < param_size) return (0); if (++param_count > sysctl_param_proc_limit) { SN_LOG(SN_LOG_EVENT, - logsctperror("Parameter parse limit exceeded IsADDorDEL)", + logsctperror("Parameter parse limit exceeded IsADDorDEL)", sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); - return(0); /* not found limit exceeded*/ + return (0); /* not found limit exceeded*/ } } - return(0); /*Neither found */ + return (0); /*Neither found */ } /* ---------------------------------------------------------------------- @@ -1691,7 +1691,7 @@ IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction) * each state. * * @param la Pointer to the relevant libalias instance - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to * @@ -1708,17 +1708,17 @@ ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, stru if (rtnval != SN_NAT_PKT) { assoc->state = SN_RM;/* Mark for removal*/ } - return(rtnval); + return (rtnval); case SN_INi: /* Initialising - Init */ - return(INi_process(la, direction, assoc, sm)); + return (INi_process(la, direction, assoc, sm)); case SN_INa: /* Initialising - AddIP */ - return(INa_process(la, direction, assoc, sm)); + return (INa_process(la, direction, assoc, sm)); case SN_UP: /* Association UP */ - return(UP_process(la, direction, assoc, sm)); + return (UP_process(la, direction, assoc, sm)); case SN_CL: /* Association Closing */ - return(CL_process(la, direction, assoc, sm)); + return (CL_process(la, direction, assoc, sm)); } - return(SN_PROCESSING_ERROR); + return (SN_PROCESSING_ERROR); } /** @ingroup state_machine @@ -1738,56 +1738,57 @@ ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, stru static int ID_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) { - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk with ADDIP */ if (!sysctl_accept_global_ootb_addip && (direction == SN_TO_LOCAL)) - return(SN_DROP_PKT); + return (SN_DROP_PKT); /* if this Asconf packet does not contain the Vtag parameters it is of no use in Idle state */ if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction)) - return(SN_DROP_PKT); + return (SN_DROP_PKT); + /* FALLTHROUGH */ case SN_SCTP_INIT: /* a packet containing an INIT chunk or an ASCONF AddIP */ if (sysctl_track_global_addresses) AddGlobalIPAddresses(sm, assoc, direction); - switch(direction){ + switch (direction) { case SN_TO_GLOBAL: assoc->l_addr = sm->ip_hdr->ip_src; assoc->a_addr = FindAliasAddress(la, assoc->l_addr); assoc->l_port = sm->sctp_hdr->src_port; assoc->g_port = sm->sctp_hdr->dest_port; - if(sm->msg == SN_SCTP_INIT) + if (sm->msg == SN_SCTP_INIT) assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; if (AddSctpAssocGlobal(la, assoc)) /* DB clash *///**** need to add dst address - return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); - if(sm->msg == SN_SCTP_ASCONF) { + return ((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); + if (sm->msg == SN_SCTP_ASCONF) { if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */ - return(SN_REPLY_ERROR); + return (SN_REPLY_ERROR); assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */ } break; case SN_TO_LOCAL: assoc->l_addr = FindSctpRedirectAddress(la, sm); - assoc->a_addr = sm->ip_hdr->ip_dst; + assoc->a_addr = sm->ip_hdr->ip_dst; assoc->l_port = sm->sctp_hdr->dest_port; assoc->g_port = sm->sctp_hdr->src_port; - if(sm->msg == SN_SCTP_INIT) + if (sm->msg == SN_SCTP_INIT) assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */ - return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); - if(sm->msg == SN_SCTP_ASCONF) { + return ((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); + if (sm->msg == SN_SCTP_ASCONF) { if (AddSctpAssocGlobal(la, assoc)) /* DB clash */ //**** need to add src address - return(SN_REPLY_ERROR); + return (SN_REPLY_ERROR); assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */ } break; } - assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa; - assoc->exp = SN_I_T(la); - sctp_AddTimeOut(la,assoc); - return(SN_NAT_PKT); + assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa; + assoc->exp = SN_I_T(la); + sctp_AddTimeOut(la,assoc); + return (SN_NAT_PKT); default: /* Any other type of SCTP message is not valid in Idle */ - return(SN_DROP_PKT); + return (SN_DROP_PKT); } -return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ + return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ } /** @ingroup state_machine @@ -1795,30 +1796,30 @@ return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the b * * Only an INIT-ACK, resent INIT, or an ABORT SCTP packet are valid in this * state, all other packets are dropped. - * + * * @param la Pointer to the relevant libalias instance - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to - * - * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT + * + * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT */ static int INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) { - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_INIT: /* a packet containing a retransmitted INIT chunk */ sctp_ResetTimeOut(la, assoc, SN_I_T(la)); - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */ - switch(direction){ + switch (direction) { case SN_TO_LOCAL: if (assoc->num_Gaddr) /*If tracking global addresses for this association */ AddGlobalIPAddresses(sm, assoc, direction); assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */ assoc->state = SN_RM;/* Mark for removal*/ - return(SN_SEND_ABORT); + return (SN_SEND_ABORT); } break; case SN_TO_GLOBAL: @@ -1826,97 +1827,97 @@ INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, st assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; if (AddSctpAssocGlobal(la, assoc)) { /* DB clash */ assoc->state = SN_RM;/* Mark for removal*/ - return(SN_SEND_ABORT); + return (SN_SEND_ABORT); } break; } assoc->state = SN_UP;/* association established for NAT */ sctp_ResetTimeOut(la,assoc, SN_U_T(la)); - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ assoc->state = SN_RM;/* Mark for removal*/ - return(SN_NAT_PKT); + return (SN_NAT_PKT); default: - return(SN_DROP_PKT); + return (SN_DROP_PKT); } - return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ + return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ } /** @ingroup state_machine * @brief Process SCTP message while waiting for an AddIp-ACK message - * + * * Only an AddIP-ACK, resent AddIP, or an ABORT message are valid, all other * SCTP packets are dropped * * @param la Pointer to the relevant libalias instance - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to - * - * @return SN_NAT_PKT | SN_DROP_PKT + * + * @return SN_NAT_PKT | SN_DROP_PKT */ static int INa_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) { - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/ sctp_ResetTimeOut(la,assoc, SN_I_T(la)); - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */ - switch(direction){ + switch (direction) { case SN_TO_LOCAL: if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */ - return(SN_DROP_PKT); + return (SN_DROP_PKT); break; case SN_TO_GLOBAL: if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */ - return(SN_DROP_PKT); + return (SN_DROP_PKT); } if (IsASCONFack(la,sm,direction)) { assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */ assoc->state = SN_UP; /* association established for NAT */ sctp_ResetTimeOut(la,assoc, SN_U_T(la)); - return(SN_NAT_PKT); + return (SN_NAT_PKT); } else { assoc->state = SN_RM;/* Mark for removal*/ - return(SN_NAT_PKT); + return (SN_NAT_PKT); } case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ assoc->state = SN_RM;/* Mark for removal*/ - return(SN_NAT_PKT); + return (SN_NAT_PKT); default: - return(SN_DROP_PKT); + return (SN_DROP_PKT); } - return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ + return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ } /** @ingroup state_machine * @brief Process SCTP messages while association is UP redirecting packets - * + * * While in the SN_UP state, all packets for the particular association * are passed. Only a SHUT-ACK or an ABORT will cause a change of state. * * @param la Pointer to the relevant libalias instance - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to - * - * @return SN_NAT_PKT | SN_DROP_PKT + * + * @return SN_NAT_PKT | SN_DROP_PKT */ static int UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) { - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ assoc->state = SN_CL; sctp_ResetTimeOut(la,assoc, SN_C_T(la)); - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ assoc->state = SN_RM;/* Mark for removal*/ - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/ if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this association & from global side */ - switch(IsADDorDEL(la,sm,direction)) { + switch (IsADDorDEL(la,sm,direction)) { case SCTP_ADD_IP_ADDRESS: AddGlobalIPAddresses(sm, assoc, direction); break; @@ -1926,9 +1927,9 @@ UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, str } /* fall through to default */ default: sctp_ResetTimeOut(la,assoc, SN_U_T(la)); - return(SN_NAT_PKT); /* forward packet */ + return (SN_NAT_PKT); /* forward packet */ } - return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ + return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ } /** @ingroup state_machine @@ -1940,34 +1941,34 @@ UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, str * ABORT packets are permitted in this state. All other packets are dropped. * * @param la Pointer to the relevant libalias instance - * @param direction SN_TO_LOCAL | SN_TO_GLOBAL + * @param direction SN_TO_LOCAL | SN_TO_GLOBAL * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to - * - * @return SN_NAT_PKT | SN_DROP_PKT + * + * @return SN_NAT_PKT | SN_DROP_PKT */ static int CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) { - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */ assoc->state = SN_CL; /* Stay in Close state until timeout */ if (sysctl_holddown_timer > 0) sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/ else assoc->state = SN_RM;/* Mark for removal*/ - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ assoc->state = SN_CL; /* Stay in Close state until timeout */ sctp_ResetTimeOut(la, assoc, SN_C_T(la)); - return(SN_NAT_PKT); + return (SN_NAT_PKT); case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ assoc->state = SN_RM;/* Mark for removal*/ - return(SN_NAT_PKT); + return (SN_NAT_PKT); default: - return(SN_DROP_PKT); + return (SN_DROP_PKT); } - return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ + return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ } /* ---------------------------------------------------------------------- @@ -1981,7 +1982,7 @@ CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, stru */ /** @ingroup Hash * @brief Find the SCTP association given the local address, port and vtag - * + * * Searches the local look-up table for the association entry matching the * provided local <address:ports:vtag> tuple * @@ -1991,7 +1992,7 @@ CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, stru * @param l_vtag local Vtag * @param l_port local Port * @param g_port global Port - * + * * @return pointer to association or NULL */ static struct sctp_nat_assoc* @@ -2000,7 +2001,7 @@ FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, u_int i; struct sctp_nat_assoc *assoc = NULL; struct sctp_GlobalAddress *G_Addr = NULL; - + if (l_vtag != 0) { /* an init packet, vtag==0 */ i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize); LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { @@ -2008,27 +2009,27 @@ FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, && (assoc->l_addr.s_addr == l_addr.s_addr)) { if (assoc->num_Gaddr) { LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { - if(G_Addr->g_addr.s_addr == g_addr.s_addr) - return(assoc); + if (G_Addr->g_addr.s_addr == g_addr.s_addr) + return (assoc); } } else { - return(assoc); + return (assoc); } } } } - return(NULL); + return (NULL); } /** @ingroup Hash * @brief Check for Global Clash - * + * * Searches the global look-up table for the association entry matching the * provided global <(addresses):ports:vtag> tuple * * @param la Pointer to the relevant libalias instance * @param Cassoc association being checked for a clash - * + * * @return pointer to association or NULL */ static struct sctp_nat_assoc* @@ -2038,7 +2039,7 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc) struct sctp_nat_assoc *assoc = NULL; struct sctp_GlobalAddress *G_Addr = NULL; struct sctp_GlobalAddress *G_AddrC = NULL; - + if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */ i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize); LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { @@ -2046,22 +2047,22 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc) if (assoc->num_Gaddr) { LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) { LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { - if(G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr) - return(assoc); + if (G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr) + return (assoc); } } } else { - return(assoc); + return (assoc); } } } } - return(NULL); + return (NULL); } /** @ingroup Hash * @brief Find the SCTP association given the global port and vtag - * + * * Searches the global look-up table for the association entry matching the * provided global <address:ports:vtag> tuple * @@ -2075,7 +2076,7 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc) * @param g_vtag global vtag * @param g_port global port * @param l_port local port - * + * * @return pointer to association or NULL */ static struct sctp_nat_assoc* @@ -2084,7 +2085,7 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint u_int i; struct sctp_nat_assoc *assoc = NULL; struct sctp_GlobalAddress *G_Addr = NULL; - + *partial_match = 0; if (g_vtag != 0) { /* an init packet, vtag==0 */ i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize); @@ -2093,21 +2094,21 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint *partial_match = 1; if (assoc->num_Gaddr) { LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { - if(G_Addr->g_addr.s_addr == g_addr.s_addr) - return(assoc); + if (G_Addr->g_addr.s_addr == g_addr.s_addr) + return (assoc); } } else { - return(assoc); + return (assoc); } } } } - return(NULL); + return (NULL); } /** @ingroup Hash * @brief Find the SCTP association for a T-Flag message (given the global port and local vtag) - * + * * Searches the local look-up table for a unique association entry matching the * provided global port and local vtag information * @@ -2116,40 +2117,40 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint * @param l_vtag local Vtag * @param g_port global Port * @param l_port local Port - * + * * @return pointer to association or NULL */ static struct sctp_nat_assoc* -FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port) +FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port) { u_int i; struct sctp_nat_assoc *assoc = NULL, *lastmatch = NULL; struct sctp_GlobalAddress *G_Addr = NULL; int cnt = 0; - + if (l_vtag != 0) { /* an init packet, vtag==0 */ i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize); LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { if (assoc->num_Gaddr) { LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { - if(G_Addr->g_addr.s_addr == G_Addr->g_addr.s_addr) - return(assoc); /* full match */ + if (G_Addr->g_addr.s_addr == g_addr.s_addr) + return (assoc); /* full match */ } } else { - if (++cnt > 1) return(NULL); + if (++cnt > 1) return (NULL); lastmatch = assoc; } } } } /* If there is more than one match we do not know which local address to send to */ - return( cnt ? lastmatch : NULL ); + return (cnt ? lastmatch : NULL); } /** @ingroup Hash * @brief Find the SCTP association for a T-Flag message (given the local port and global vtag) - * + * * Searches the global look-up table for a unique association entry matching the * provided local port and global vtag information * @@ -2158,7 +2159,7 @@ FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uin * @param g_vtag global vtag * @param l_port local port * @param g_port global port - * + * * @return pointer to association or NULL */ static struct sctp_nat_assoc* @@ -2167,28 +2168,28 @@ FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uin u_int i; struct sctp_nat_assoc *assoc = NULL; struct sctp_GlobalAddress *G_Addr = NULL; - + if (g_vtag != 0) { /* an init packet, vtag==0 */ i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize); LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) { if (assoc->num_Gaddr) { LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { - if(G_Addr->g_addr.s_addr == g_addr.s_addr) - return(assoc); + if (G_Addr->g_addr.s_addr == g_addr.s_addr) + return (assoc); } } else { - return(assoc); + return (assoc); } } } } - return(NULL); + return (NULL); } /** @ingroup Hash * @brief Add the sctp association information to the local look up table - * + * * Searches the local look-up table for an existing association with the same * details. If a match exists and is ONLY in the local look-up table then this * is a repeated INIT packet, we need to remove this association from the @@ -2199,7 +2200,7 @@ FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uin * @param la Pointer to the relevant libalias instance * @param assoc pointer to sctp association * @param g_addr global address - * + * * @return SN_ADD_OK | SN_ADD_CLASH */ static int @@ -2225,9 +2226,9 @@ AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_a freeGlobalAddressList(found); sn_free(found); } else - return(SN_ADD_CLASH); + return (SN_ADD_CLASH); } - + LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableSize)], assoc, list_L); assoc->TableRegister |= SN_LOCAL_TBL; @@ -2241,7 +2242,7 @@ AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_a SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^")); } - return(SN_ADD_OK); + return (SN_ADD_OK); } /** @ingroup Hash @@ -2274,9 +2275,9 @@ AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc) freeGlobalAddressList(found); sn_free(found); } else - return(SN_ADD_CLASH); + return (SN_ADD_CLASH); } - + LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTableSize)], assoc, list_G); assoc->TableRegister |= SN_GLOBAL_TBL; @@ -2290,12 +2291,12 @@ AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc) SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^")); } - return(SN_ADD_OK); + return (SN_ADD_OK); } /** @ingroup Hash * @brief Remove the sctp association information from the look up table - * + * * For each of the two (local/global) look-up tables, remove the association * from that table IF it has been registered in that table. * @@ -2327,7 +2328,7 @@ RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc) la->sctpLinkCount--; //decrement link count LIST_REMOVE(assoc, list_L); } - + if (assoc->TableRegister & SN_GLOBAL_TBL) { assoc->TableRegister ^= SN_GLOBAL_TBL; la->sctpLinkCount--; //decrement link count @@ -2339,20 +2340,20 @@ RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc) SctpShowAliasStats(la); } -/** +/** * @ingroup Hash * @brief free the Global Address List memory - * + * * freeGlobalAddressList deletes all global IP addresses in an associations * global IP address list. * - * @param assoc + * @param assoc */ static void freeGlobalAddressList(struct sctp_nat_assoc *assoc) { struct sctp_GlobalAddress *gaddr1=NULL,*gaddr2=NULL; /*free global address list*/ - gaddr1 = LIST_FIRST(&(assoc->Gaddr)); + gaddr1 = LIST_FIRST(&(assoc->Gaddr)); while (gaddr1 != NULL) { gaddr2 = LIST_NEXT(gaddr1, list_Gaddr); sn_free(gaddr1); @@ -2383,8 +2384,8 @@ static void freeGlobalAddressList(struct sctp_nat_assoc *assoc) * Determine the location in the queue to add the timeout and insert the * association into the list at that queue position * - * @param la - * @param assoc + * @param la + * @param assoc */ static void sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc) @@ -2440,7 +2441,7 @@ sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp) /** @ingroup Timer * @brief Check timer Q against current time - * + * * Loop through each entry in the timer queue since the last time we processed * the timer queue until now (the current time). For each association in the * event list, we remove it from that position in the timer queue and check if @@ -2451,22 +2452,22 @@ sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp) * * If the timer hasn't really expired we place the association into its new * correct position in the timer queue. - * + * * @param la Pointer to the relevant libalias instance */ void sctp_CheckTimers(struct libalias *la) { struct sctp_nat_assoc *assoc; - + LIBALIAS_LOCK_ASSERT(la); while(la->timeStamp >= la->sctpNatTimer.loc_time) { - while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) { + while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) { assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]); //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q); LIST_REMOVE(assoc, timer_Q); if (la->timeStamp >= assoc->exp) { /* state expired */ - SN_LOG(((assoc->state == SN_CL)?(SN_LOG_DEBUG):(SN_LOG_INFO)), + SN_LOG(((assoc->state == SN_CL) ? (SN_LOG_DEBUG) : (SN_LOG_INFO)), logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR)); RmSctpAssoc(la, assoc); freeGlobalAddressList(assoc); @@ -2483,7 +2484,7 @@ sctp_CheckTimers(struct libalias *la) } /* ---------------------------------------------------------------------- - * LOGGING CODE + * LOGGING CODE * ---------------------------------------------------------------------- */ /** @addtogroup Logging @@ -2494,7 +2495,7 @@ sctp_CheckTimers(struct libalias *la) */ /** @ingroup Logging * @brief Log sctp nat errors - * + * * @param errormsg Error message to be logged * @param vtag Current Vtag * @param error Error number @@ -2504,7 +2505,7 @@ static void logsctperror(char* errormsg, uint32_t vtag, int error, int direction) { char dir; - switch(direction) { + switch (direction) { case SN_TO_LOCAL: dir = 'L'; break; @@ -2520,7 +2521,7 @@ logsctperror(char* errormsg, uint32_t vtag, int error, int direction) /** @ingroup Logging * @brief Log what the parser parsed - * + * * @param direction Direction of packet * @param sm Pointer to sctp message information */ @@ -2528,7 +2529,7 @@ static void logsctpparse(int direction, struct sctp_nat_msg *sm) { char *ploc, *pstate; - switch(direction) { + switch (direction) { case SN_TO_LOCAL: ploc = "TO_LOCAL -"; break; @@ -2538,7 +2539,7 @@ logsctpparse(int direction, struct sctp_nat_msg *sm) default: ploc = ""; } - switch(sm->msg) { + switch (sm->msg) { case SN_SCTP_INIT: pstate = "Init"; break; @@ -2572,7 +2573,7 @@ logsctpparse(int direction, struct sctp_nat_msg *sm) /** @ingroup Logging * @brief Log an SCTP association's details - * + * * @param assoc pointer to sctp association * @param s Character that indicates the state of processing for this packet */ @@ -2582,7 +2583,7 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s) char *sp; char addrbuf[INET_ADDRSTRLEN]; - switch(assoc->state) { + switch (assoc->state) { case SN_ID: sp = "ID "; break; @@ -2618,15 +2619,15 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s) } /** @ingroup Logging - * @brief Output Global table to log - * + * @brief Output Global table to log + * * @param la Pointer to the relevant libalias instance */ static void logSctpGlobal(struct libalias *la) { u_int i; struct sctp_nat_assoc *assoc = NULL; - + SctpAliasLog("G->\n"); for (i=0; i < la->sctpNatTableSize; i++) { LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { @@ -2636,15 +2637,15 @@ static void logSctpGlobal(struct libalias *la) } /** @ingroup Logging - * @brief Output Local table to log - * + * @brief Output Local table to log + * * @param la Pointer to the relevant libalias instance */ static void logSctpLocal(struct libalias *la) { u_int i; struct sctp_nat_assoc *assoc = NULL; - + SctpAliasLog("L->\n"); for (i=0; i < la->sctpNatTableSize; i++) { LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { @@ -2655,7 +2656,7 @@ static void logSctpLocal(struct libalias *la) /** @ingroup Logging * @brief Output timer queue to log - * + * * @param la Pointer to the relevant libalias instance */ static void logTimerQ(struct libalias *la) @@ -2674,12 +2675,12 @@ static void logTimerQ(struct libalias *la) } } -/** @ingroup Logging +/** @ingroup Logging * @brief Sctp NAT logging function - * + * * This function is based on a similar function in alias_db.c * - * @param str/stream logging descriptor + * @param str/stream logging descriptor * @param format printf type string */ #ifdef _KERNEL diff --git a/freebsd/sys/netinet/sctp_constants.h b/freebsd/sys/netinet/sctp_constants.h index 94378799..018cd282 100644 --- a/freebsd/sys/netinet/sctp_constants.h +++ b/freebsd/sys/netinet/sctp_constants.h @@ -400,43 +400,34 @@ __FBSDID("$FreeBSD$"); #define SCTP_HOSTNAME_ADDRESS 0x000b #define SCTP_SUPPORTED_ADDRTYPE 0x000c -/* draft-ietf-stewart-tsvwg-strreset-xxx */ +/* RFC 6525 */ #define SCTP_STR_RESET_OUT_REQUEST 0x000d #define SCTP_STR_RESET_IN_REQUEST 0x000e #define SCTP_STR_RESET_TSN_REQUEST 0x000f #define SCTP_STR_RESET_RESPONSE 0x0010 #define SCTP_STR_RESET_ADD_OUT_STREAMS 0x0011 -#define SCTP_STR_RESET_ADD_IN_STREAMS 0x0012 +#define SCTP_STR_RESET_ADD_IN_STREAMS 0x0012 #define SCTP_MAX_RESET_PARAMS 2 -#define SCTP_STREAM_RESET_TSN_DELTA 0x1000 +#define SCTP_STREAM_RESET_TSN_DELTA 0x1000 /*************0x4000 series*************/ /*************0x8000 series*************/ #define SCTP_ECN_CAPABLE 0x8000 -/* draft-ietf-tsvwg-auth-xxx */ +/* RFC 4895 */ #define SCTP_RANDOM 0x8002 #define SCTP_CHUNK_LIST 0x8003 #define SCTP_HMAC_LIST 0x8004 -/* - * draft-ietf-tsvwg-addip-sctp-xx param=0x8008 len=0xNNNN Byte | Byte | Byte - * | Byte Byte | Byte ... - * - * Where each byte is a chunk type extension supported. For example, to support - * all chunks one would have (in hex): - * - * 80 01 00 09 C0 C1 80 81 82 00 00 00 - * - * Has the parameter. C0 = PR-SCTP (RFC3758) C1, 80 = ASCONF (addip draft) 81 - * = Packet Drop 82 = Stream Reset 83 = Authentication - */ -#define SCTP_SUPPORTED_CHUNK_EXT 0x8008 +/* RFC 4820 */ +#define SCTP_PAD 0x8005 +/* RFC 5061 */ +#define SCTP_SUPPORTED_CHUNK_EXT 0x8008 /*************0xC000 series*************/ #define SCTP_PRSCTP_SUPPORTED 0xc000 -/* draft-ietf-tsvwg-addip-sctp */ +/* RFC 5061 */ #define SCTP_ADD_IP_ADDRESS 0xc001 #define SCTP_DEL_IP_ADDRESS 0xc002 #define SCTP_ERROR_CAUSE_IND 0xc003 @@ -444,8 +435,8 @@ __FBSDID("$FreeBSD$"); #define SCTP_SUCCESS_REPORT 0xc005 #define SCTP_ULP_ADAPTATION 0xc006 /* behave-nat-draft */ -#define SCTP_HAS_NAT_SUPPORT 0xc007 -#define SCTP_NAT_VTAGS 0xc008 +#define SCTP_HAS_NAT_SUPPORT 0xc007 +#define SCTP_NAT_VTAGS 0xc008 /* bits for TOS field */ #define SCTP_ECT0_BIT 0x02 @@ -624,7 +615,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */ -#define SCTP_INP_KILL_TIMEOUT 20/* number of ms to retry kill of inpcb */ +#define SCTP_INP_KILL_TIMEOUT 20 /* number of ms to retry kill of inpcb */ #define SCTP_ASOC_KILL_TIMEOUT 10 /* number of ms to retry kill of inpcb */ #define SCTP_DEF_MAX_INIT 8 diff --git a/freebsd/sys/netinet/sctp_crc32.c b/freebsd/sys/netinet/sctp_crc32.c index 82e361e1..e22abeb6 100644 --- a/freebsd/sys/netinet/sctp_crc32.c +++ b/freebsd/sys/netinet/sctp_crc32.c @@ -37,30 +37,36 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <rtems/bsd/local/opt_sctp.h> + +#ifdef SCTP #include <netinet/sctp_os.h> #include <netinet/sctp.h> #include <netinet/sctp_crc32.h> #include <netinet/sctp_pcb.h> +#else +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> - -#if !defined(SCTP_WITH_NO_CSUM) +#include <netinet/sctp_crc32.h> +#endif static uint32_t sctp_finalize_crc32c(uint32_t crc32c) { uint32_t result; - #if BYTE_ORDER == BIG_ENDIAN uint8_t byte0, byte1, byte2, byte3; - #endif + /* Complement the result */ result = ~crc32c; #if BYTE_ORDER == BIG_ENDIAN /* - * For BIG-ENDIAN.. aka Motorola byte order the result is in - * little-endian form. So we must manually swap the bytes. Then we - * can call htonl() which does nothing... + * For BIG-ENDIAN platforms the result is in little-endian form. So + * we must swap the bytes to return the result in network byte + * order. */ byte0 = result & 0x000000ff; byte1 = (result >> 8) & 0x000000ff; @@ -69,65 +75,57 @@ sctp_finalize_crc32c(uint32_t crc32c) crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); #else /* - * For INTEL platforms the result comes out in network order. No - * htonl is required or the swap above. So we optimize out both the - * htonl and the manual swap above. + * For LITTLE ENDIAN platforms the result is in already in network + * byte order. */ crc32c = result; #endif return (crc32c); } +/* + * Compute the SCTP checksum in network byte order for a given mbuf chain m + * which contains an SCTP packet starting at offset. + * Since this function is also called by ipfw, don't assume that + * it is compiled on a kernel with SCTP support. + */ uint32_t sctp_calculate_cksum(struct mbuf *m, uint32_t offset) { - /* - * given a mbuf chain with a packetheader offset by 'offset' - * pointing at a sctphdr (with csum set to 0) go through the chain - * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also - * has a side bonus as it will calculate the total length of the - * mbuf chain. Note: if offset is greater than the total mbuf - * length, checksum=1, pktlen=0 is returned (ie. no real error code) - */ uint32_t base = 0xffffffff; - struct mbuf *at; - at = m; - /* find the correct mbuf and offset into mbuf */ - while ((at != NULL) && (offset > (uint32_t)SCTP_BUF_LEN(at))) { - offset -= SCTP_BUF_LEN(at); /* update remaining offset - * left */ - at = SCTP_BUF_NEXT(at); - } - while (at != NULL) { - if ((SCTP_BUF_LEN(at) - offset) > 0) { - base = calculate_crc32c(base, - (unsigned char *)(SCTP_BUF_AT(at, offset)), - (unsigned int)(SCTP_BUF_LEN(at) - offset)); - } - if (offset) { - /* we only offset once into the first mbuf */ - if (offset < (uint32_t)SCTP_BUF_LEN(at)) - offset = 0; - else - offset -= SCTP_BUF_LEN(at); + while (offset > 0) { + KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain")); + if (offset < (uint32_t)m->m_len) { + break; } - at = SCTP_BUF_NEXT(at); + offset -= m->m_len; + m = m->m_next; + } + if (offset > 0) { + base = calculate_crc32c(base, + (unsigned char *)(m->m_data + offset), + (unsigned int)(m->m_len - offset)); + m = m->m_next; + } + while (m != NULL) { + base = calculate_crc32c(base, + (unsigned char *)m->m_data, + (unsigned int)m->m_len); + m = m->m_next; } base = sctp_finalize_crc32c(base); return (base); } -#endif /* !defined(SCTP_WITH_NO_CSUM) */ - +#ifdef SCTP +/* + * Compute and insert the SCTP checksum in network byte order for a given + * mbuf chain m which contains an SCTP packet starting at offset. + */ void sctp_delayed_cksum(struct mbuf *m, uint32_t offset) { -#if defined(SCTP_WITH_NO_CSUM) -#ifdef INVARIANTS - panic("sctp_delayed_cksum() called when using no SCTP CRC."); -#endif -#else uint32_t checksum; checksum = sctp_calculate_cksum(m, offset); @@ -136,15 +134,15 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset) offset += offsetof(struct sctphdr, checksum); if (offset + sizeof(uint32_t) > (uint32_t)(m->m_len)) { - SCTP_PRINTF("sctp_delayed_cksum(): m->len: %d, off: %d.\n", - (uint32_t)m->m_len, offset); - /* - * XXX this shouldn't happen, but if it does, the correct - * behavior may be to insert the checksum in the appropriate - * next mbuf in the chain. - */ +#ifdef INVARIANTS + panic("sctp_delayed_cksum(): m->m_len: %d, offset: %u.", + m->m_len, offset); +#else + SCTP_PRINTF("sctp_delayed_cksum(): m->m_len: %d, offset: %u.\n", + m->m_len, offset); +#endif return; } *(uint32_t *)(m->m_data + offset) = checksum; -#endif } +#endif diff --git a/freebsd/sys/netinet/sctp_crc32.h b/freebsd/sys/netinet/sctp_crc32.h index adc38afc..4bdf8265 100644 --- a/freebsd/sys/netinet/sctp_crc32.h +++ b/freebsd/sys/netinet/sctp_crc32.h @@ -39,9 +39,9 @@ __FBSDID("$FreeBSD$"); #define _NETINET_SCTP_CRC32_H_ #if defined(_KERNEL) -#if !defined(SCTP_WITH_NO_CSUM) uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t); -#endif +#ifdef SCTP void sctp_delayed_cksum(struct mbuf *, uint32_t offset); +#endif #endif /* _KERNEL */ #endif /* __crc32c_h__ */ diff --git a/freebsd/sys/netinet/sctp_indata.c b/freebsd/sys/netinet/sctp_indata.c index c4522a39..3325dd03 100644 --- a/freebsd/sys/netinet/sctp_indata.c +++ b/freebsd/sys/netinet/sctp_indata.c @@ -3366,7 +3366,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, } } } - if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap)) { + if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap) && + !(accum_moved && asoc->fast_retran_loss_recovery)) { /* we are beyond the tsn in the sack */ break; } @@ -3390,8 +3391,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, * FR using this SACK. */ continue; - } else if (tp1->whoTo && SCTP_TSN_GT(tp1->rec.data.tsn, - tp1->whoTo->this_sack_highest_newack)) { + } else if (tp1->whoTo && + SCTP_TSN_GT(tp1->rec.data.tsn, + tp1->whoTo->this_sack_highest_newack) && + !(accum_moved && asoc->fast_retran_loss_recovery)) { /* * CMT: New acks were receieved for data sent to * this dest. But no new acks were seen for data @@ -3676,7 +3679,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, tp1->whoTo->find_pseudo_cumack = 1; tp1->whoTo->find_rtx_pseudo_cumack = 1; } - } else {/* CMT is OFF */ + } else { /* CMT is OFF */ #ifdef SCTP_FR_TO_ALTERNATE /* Can we find an alternate? */ @@ -4605,6 +4608,13 @@ hopeless_peer: if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) { (*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net); } + /* + * CMT: SFR algo (and HTNA) - this_sack_highest_newack has + * to be greater than the cumack. Also reset saw_newack to 0 + * for all dests. + */ + net->saw_newack = 0; + net->this_sack_highest_newack = last_tsn; } /* process the new consecutive TSN first */ TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { @@ -4732,16 +4742,6 @@ hopeless_peer: if ((num_seg > 0) || (num_nr_seg > 0)) { /* - * CMT: SFR algo (and HTNA) - this_sack_highest_newack has - * to be greater than the cumack. Also reset saw_newack to 0 - * for all dests. - */ - TAILQ_FOREACH(net, &asoc->nets, sctp_next) { - net->saw_newack = 0; - net->this_sack_highest_newack = last_tsn; - } - - /* * thisSackHighestGap will increase while handling NEW * segments this_sack_highest_newack will increase while * handling NEWLY ACKED chunks. this_sack_lowest_newack is diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c index 9c552ff5..9a74ef4b 100644 --- a/freebsd/sys/netinet/sctp_input.c +++ b/freebsd/sys/netinet/sctp_input.c @@ -3209,9 +3209,9 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sct stcb->asoc.ecn_echo_cnt_onq--; TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk, sctp_next); + stcb->asoc.ctrl_queue_cnt--; sctp_m_freem(chk->data); chk->data = NULL; - stcb->asoc.ctrl_queue_cnt--; sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); if (override == 0) { break; @@ -3643,26 +3643,23 @@ static void sctp_clean_up_stream_reset(struct sctp_tcb *stcb) { struct sctp_association *asoc; - struct sctp_tmit_chunk *chk = stcb->asoc.str_reset; + struct sctp_tmit_chunk *chk; - if (stcb->asoc.str_reset == NULL) { + asoc = &stcb->asoc; + chk = asoc->str_reset; + if (chk == NULL) { return; } - asoc = &stcb->asoc; - + asoc->str_reset = NULL; sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_28); - TAILQ_REMOVE(&asoc->control_send_queue, - chk, - sctp_next); + TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); + asoc->ctrl_queue_cnt--; if (chk->data) { sctp_m_freem(chk->data); chk->data = NULL; } - asoc->ctrl_queue_cnt--; sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); - /* sa_ignore NO_NULL_CHK */ - stcb->asoc.str_reset = NULL; } @@ -5509,9 +5506,7 @@ void sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_chunkhdr *ch, -#if !defined(SCTP_WITH_NO_CSUM) uint8_t compute_crc, -#endif uint8_t ecn_bits, uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port) @@ -5531,7 +5526,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt sctp_audit_log(0xE0, 1); sctp_auditing(0, inp, stcb, net); #endif -#if !defined(SCTP_WITH_NO_CSUM) if (compute_crc != 0) { uint32_t check, calc_check; @@ -5576,7 +5570,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt goto out; } } -#endif /* Destination port of 0 is illegal, based on RFC4960. */ if (sh->dest_port == 0) { SCTP_STAT_INCR(sctps_hdrops); @@ -5894,9 +5887,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) struct sctphdr *sh; struct sctp_chunkhdr *ch; int length, offset; -#if !defined(SCTP_WITH_NO_CSUM) uint8_t compute_crc; -#endif uint32_t mflowid; uint8_t mflowtype; uint16_t fibnum; @@ -5966,9 +5957,6 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) goto out; } ecn_bits = ip->ip_tos; -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_recvnocrc); -#else if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { SCTP_STAT_INCR(sctps_recvhwcrc); compute_crc = 0; @@ -5976,14 +5964,11 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) SCTP_STAT_INCR(sctps_recvswcrc); compute_crc = 1; } -#endif sctp_common_input_processing(&m, iphlen, offset, length, (struct sockaddr *)&src, (struct sockaddr *)&dst, sh, ch, -#if !defined(SCTP_WITH_NO_CSUM) compute_crc, -#endif ecn_bits, mflowtype, mflowid, fibnum, vrf_id, port); diff --git a/freebsd/sys/netinet/sctp_input.h b/freebsd/sys/netinet/sctp_input.h index ff0916e7..f393ad89 100644 --- a/freebsd/sys/netinet/sctp_input.h +++ b/freebsd/sys/netinet/sctp_input.h @@ -43,9 +43,7 @@ void sctp_common_input_processing(struct mbuf **, int, int, int, struct sockaddr *, struct sockaddr *, struct sctphdr *, struct sctp_chunkhdr *, -#if !defined(SCTP_WITH_NO_CSUM) uint8_t, -#endif uint8_t, uint8_t, uint32_t, uint16_t, uint32_t, uint16_t); diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c index bc54ee96..9dd2e0fa 100644 --- a/freebsd/sys/netinet/sctp_output.c +++ b/freebsd/sys/netinet/sctp_output.c @@ -4228,23 +4228,15 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, } SCTP_ATTACH_CHAIN(o_pak, m, packet_length); if (port) { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr)); SCTP_STAT_INCR(sctps_sendswcrc); -#endif if (V_udp_cksum) { SCTP_ENABLE_UDP_CSUM(o_pak); } } else { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else m->m_pkthdr.csum_flags = CSUM_SCTP; m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); -#endif } #ifdef SCTP_PACKET_LOGGING if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) @@ -4568,23 +4560,15 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, } SCTP_ATTACH_CHAIN(o_pak, m, packet_length); if (port) { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr)); SCTP_STAT_INCR(sctps_sendswcrc); -#endif 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; } } else { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6; m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); -#endif } /* send it out. table id is taken from stcb */ #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) @@ -6916,11 +6900,11 @@ sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc) TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) { TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); + asoc->ctrl_queue_cnt--; if (chk->data) { sctp_m_freem(chk->data); chk->data = NULL; } - asoc->ctrl_queue_cnt--; sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } } @@ -6945,11 +6929,11 @@ sctp_toss_old_asconf(struct sctp_tcb *stcb) } } TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next); + asoc->ctrl_queue_cnt--; if (chk->data) { sctp_m_freem(chk->data); chk->data = NULL; } - asoc->ctrl_queue_cnt--; sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } } @@ -7073,13 +7057,14 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_l /* Stray chunks must be cleaned up */ clean_up_anyway: TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); + asoc->ctrl_queue_cnt--; if (chk->data) { sctp_m_freem(chk->data); chk->data = NULL; } - asoc->ctrl_queue_cnt--; - if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) + if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) { asoc->fwd_tsn_cnt--; + } sctp_free_a_chunk(stcb, chk, so_locked); } else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) { /* special handling, we must look into the param */ @@ -11229,23 +11214,15 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, } ip->ip_len = htons(len); if (port) { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip) + sizeof(struct udphdr)); SCTP_STAT_INCR(sctps_sendswcrc); -#endif if (V_udp_cksum) { SCTP_ENABLE_UDP_CSUM(o_pak); } } else { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else mout->m_pkthdr.csum_flags = CSUM_SCTP; mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); -#endif } #ifdef SCTP_PACKET_LOGGING if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) { @@ -11259,23 +11236,15 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, case AF_INET6: ip6->ip6_plen = (uint16_t)(len - sizeof(struct ip6_hdr)); if (port) { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr)); SCTP_STAT_INCR(sctps_sendswcrc); -#endif if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) { udp->uh_sum = 0xffff; } } else { -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_sendnocrc); -#else mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6; mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); -#endif } #ifdef SCTP_PACKET_LOGGING if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) { diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c index 8259140f..f1a8d1d5 100644 --- a/freebsd/sys/netinet/sctp_sysctl.c +++ b/freebsd/sys/netinet/sctp_sysctl.c @@ -718,7 +718,6 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS) sb.sctps_recvauthfailed += sarry->sctps_recvauthfailed; sb.sctps_recvexpress += sarry->sctps_recvexpress; sb.sctps_recvexpressm += sarry->sctps_recvexpressm; - sb.sctps_recvnocrc += sarry->sctps_recvnocrc; sb.sctps_recvswcrc += sarry->sctps_recvswcrc; sb.sctps_recvhwcrc += sarry->sctps_recvhwcrc; sb.sctps_sendpackets += sarry->sctps_sendpackets; @@ -731,7 +730,6 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS) sb.sctps_sendecne += sarry->sctps_sendecne; sb.sctps_sendauth += sarry->sctps_sendauth; sb.sctps_senderrors += sarry->sctps_senderrors; - sb.sctps_sendnocrc += sarry->sctps_sendnocrc; sb.sctps_sendswcrc += sarry->sctps_sendswcrc; sb.sctps_sendhwcrc += sarry->sctps_sendhwcrc; sb.sctps_pdrpfmbox += sarry->sctps_pdrpfmbox; diff --git a/freebsd/sys/netinet/sctp_uio.h b/freebsd/sys/netinet/sctp_uio.h index 93274a70..8732219c 100644 --- a/freebsd/sys/netinet/sctp_uio.h +++ b/freebsd/sys/netinet/sctp_uio.h @@ -986,7 +986,7 @@ struct sctpstat { uint32_t sctps_recvexpress; /* total fast path receives all one * chunk */ uint32_t sctps_recvexpressm; /* total fast path multi-part data */ - uint32_t sctps_recvnocrc; + uint32_t sctps_recv_spare; /* formerly sctps_recvnocrc */ uint32_t sctps_recvswcrc; uint32_t sctps_recvhwcrc; @@ -1006,7 +1006,7 @@ struct sctpstat { uint32_t sctps_sendecne;/* total output ECNE chunks */ uint32_t sctps_sendauth;/* total output AUTH chunks FIXME */ uint32_t sctps_senderrors; /* ip_output error counter */ - uint32_t sctps_sendnocrc; + uint32_t sctps_send_spare; /* formerly sctps_sendnocrc */ uint32_t sctps_sendswcrc; uint32_t sctps_sendhwcrc; /* PCKDROPREP statistics: */ diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c index 98c2a708..5511df64 100644 --- a/freebsd/sys/netinet/sctputil.c +++ b/freebsd/sys/netinet/sctputil.c @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/sctp_output.h> #include <netinet/sctp_uio.h> #include <netinet/sctp_timer.h> -#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */ +#include <netinet/sctp_indata.h> #include <netinet/sctp_auth.h> #include <netinet/sctp_asconf.h> #include <netinet/sctp_bsd_addr.h> @@ -6096,7 +6096,7 @@ sctp_m_free(struct mbuf *m) return (m_free(m)); } -void +void sctp_m_freem(struct mbuf *mb) { while (mb != NULL) @@ -6166,6 +6166,7 @@ sctp_soreceive(struct socket *so, struct sockaddr *from; struct sctp_extrcvinfo sinfo; int filling_sinfo = 1; + int flags; struct sctp_inpcb *inp; inp = (struct sctp_inpcb *)so->so_pcb; @@ -6193,15 +6194,24 @@ sctp_soreceive(struct socket *so, if (filling_sinfo) { memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo)); } - error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp, + if (flagsp != NULL) { + flags = *flagsp; + } else { + flags = 0; + } + error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, &flags, (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo); + if (flagsp != NULL) { + *flagsp = flags; + } if (controlp != NULL) { /* copy back the sinfo in a CMSG format */ - if (filling_sinfo) + if (filling_sinfo && ((flags & MSG_NOTIFICATION) == 0)) { *controlp = sctp_build_ctl_nchunk(inp, (struct sctp_sndrcvinfo *)&sinfo); - else + } else { *controlp = NULL; + } } if (psa) { /* copy back the address info */ diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c index 1cb622ac..d0f08e3a 100644 --- a/freebsd/sys/netinet/tcp_output.c +++ b/freebsd/sys/netinet/tcp_output.c @@ -200,7 +200,9 @@ tcp_output(struct tcpcb *tp) int off, flags, error = 0; /* Keep compiler happy */ struct mbuf *m; struct ip *ip = NULL; +#ifdef TCPDEBUG struct ipovly *ipov = NULL; +#endif struct tcphdr *th; u_char opt[TCP_MAXOLEN]; unsigned ipoptlen, optlen, hdrlen; @@ -489,59 +491,7 @@ after_sack_rexmit: /* len will be >= 0 after this point. */ KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); - /* - * Automatic sizing of send socket buffer. Often the send buffer - * size is not optimally adjusted to the actual network conditions - * at hand (delay bandwidth product). Setting the buffer size too - * small limits throughput on links with high bandwidth and high - * delay (eg. trans-continental/oceanic links). Setting the - * buffer size too big consumes too much real kernel memory, - * especially with many connections on busy servers. - * - * The criteria to step up the send buffer one notch are: - * 1. receive window of remote host is larger than send buffer - * (with a fudge factor of 5/4th); - * 2. send buffer is filled to 7/8th with data (so we actually - * have data to make use of it); - * 3. send buffer fill has not hit maximal automatic size; - * 4. our send window (slow start and cogestion controlled) is - * larger than sent but unacknowledged data in send buffer. - * - * The remote host receive window scaling factor may limit the - * growing of the send buffer before it reaches its allowed - * maximum. - * - * It scales directly with slow start or congestion window - * and does at most one step per received ACK. This fast - * scaling has the drawback of growing the send buffer beyond - * what is strictly necessary to make full use of a given - * delay*bandwidth product. However testing has shown this not - * to be much of an problem. At worst we are trading wasting - * of available bandwidth (the non-use of it) for wasting some - * socket buffer memory. - * - * TODO: Shrink send buffer during idle periods together - * with congestion window. Requires another timer. Has to - * wait for upcoming tcp timer rewrite. - * - * XXXGL: should there be used sbused() or sbavail()? - */ - if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { - int lowat; - - lowat = V_tcp_sendbuf_auto_lowat ? so->so_snd.sb_lowat : 0; - if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - lowat && - sbused(&so->so_snd) >= - (so->so_snd.sb_hiwat / 8 * 7) - lowat && - sbused(&so->so_snd) < V_tcp_autosndbuf_max && - sendwin >= (sbused(&so->so_snd) - - (tp->snd_nxt - tp->snd_una))) { - if (!sbreserve_locked(&so->so_snd, - min(so->so_snd.sb_hiwat + V_tcp_autosndbuf_inc, - V_tcp_autosndbuf_max), so, curthread)) - so->so_snd.sb_flags &= ~SB_AUTOSIZE; - } - } + tcp_sndbuf_autoscale(tp, so, sendwin); /* * Decide if we can use TCP Segmentation Offloading (if supported by @@ -1145,7 +1095,9 @@ send: #endif /* INET6 */ { ip = mtod(m, struct ip *); +#ifdef TCPDEBUG ipov = (struct ipovly *)ip; +#endif th = (struct tcphdr *)(ip + 1); tcpip_fillheaders(tp->t_inpcb, ip, th); } @@ -1293,12 +1245,13 @@ send: * NOTE: since TCP options buffer doesn't point into * mbuf's data, calculate offset and use it. */ - if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th, - (u_char *)(th + 1) + (to.to_signature - opt)) != 0) { + if (!TCPMD5_ENABLED() || (error = TCPMD5_OUTPUT(m, th, + (u_char *)(th + 1) + (to.to_signature - opt))) != 0) { /* * Do not send segment if the calculation of MD5 * digest has failed. */ + m_freem(m); goto out; } } @@ -1860,3 +1813,62 @@ tcp_addoptions(struct tcpopt *to, u_char *optp) KASSERT(optlen <= TCP_MAXOLEN, ("%s: TCP options too long", __func__)); return (optlen); } + +void +tcp_sndbuf_autoscale(struct tcpcb *tp, struct socket *so, uint32_t sendwin) +{ + + /* + * Automatic sizing of send socket buffer. Often the send buffer + * size is not optimally adjusted to the actual network conditions + * at hand (delay bandwidth product). Setting the buffer size too + * small limits throughput on links with high bandwidth and high + * delay (eg. trans-continental/oceanic links). Setting the + * buffer size too big consumes too much real kernel memory, + * especially with many connections on busy servers. + * + * The criteria to step up the send buffer one notch are: + * 1. receive window of remote host is larger than send buffer + * (with a fudge factor of 5/4th); + * 2. send buffer is filled to 7/8th with data (so we actually + * have data to make use of it); + * 3. send buffer fill has not hit maximal automatic size; + * 4. our send window (slow start and cogestion controlled) is + * larger than sent but unacknowledged data in send buffer. + * + * The remote host receive window scaling factor may limit the + * growing of the send buffer before it reaches its allowed + * maximum. + * + * It scales directly with slow start or congestion window + * and does at most one step per received ACK. This fast + * scaling has the drawback of growing the send buffer beyond + * what is strictly necessary to make full use of a given + * delay*bandwidth product. However testing has shown this not + * to be much of an problem. At worst we are trading wasting + * of available bandwidth (the non-use of it) for wasting some + * socket buffer memory. + * + * TODO: Shrink send buffer during idle periods together + * with congestion window. Requires another timer. Has to + * wait for upcoming tcp timer rewrite. + * + * XXXGL: should there be used sbused() or sbavail()? + */ + if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { + int lowat; + + lowat = V_tcp_sendbuf_auto_lowat ? so->so_snd.sb_lowat : 0; + if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - lowat && + sbused(&so->so_snd) >= + (so->so_snd.sb_hiwat / 8 * 7) - lowat && + sbused(&so->so_snd) < V_tcp_autosndbuf_max && + sendwin >= (sbused(&so->so_snd) - + (tp->snd_nxt - tp->snd_una))) { + if (!sbreserve_locked(&so->so_snd, + min(so->so_snd.sb_hiwat + V_tcp_autosndbuf_inc, + V_tcp_autosndbuf_max), so, curthread)) + so->so_snd.sb_flags &= ~SB_AUTOSIZE; + } + } +} diff --git a/freebsd/sys/netinet/tcp_timer.c b/freebsd/sys/netinet/tcp_timer.c index a2f854d7..539913f4 100644 --- a/freebsd/sys/netinet/tcp_timer.c +++ b/freebsd/sys/netinet/tcp_timer.c @@ -120,9 +120,9 @@ SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_slop, CTLTYPE_INT|CTLFLAG_RW, &tcp_rexmit_slop, 0, sysctl_msec_to_ticks, "I", "Retransmission Timer Slop"); -static int always_keepalive = 1; +int tcp_always_keepalive = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_RW, - &always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections"); + &tcp_always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections"); int tcp_fast_finwait2_recycle = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, fast_finwait2_recycle, CTLFLAG_RW, @@ -473,7 +473,8 @@ tcp_timer_keep(void *xtp) TCPSTAT_INC(tcps_keeptimeo); if (tp->t_state < TCPS_ESTABLISHED) goto dropit; - if ((always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && + if ((tcp_always_keepalive || + inp->inp_socket->so_options & SO_KEEPALIVE) && tp->t_state <= TCPS_CLOSING) { if (ticks - tp->t_rcvtime >= TP_KEEPIDLE(tp) + TP_MAXIDLE(tp)) goto dropit; diff --git a/freebsd/sys/netinet/tcp_timer.h b/freebsd/sys/netinet/tcp_timer.h index 9a26c95d..b0ff3809 100644 --- a/freebsd/sys/netinet/tcp_timer.h +++ b/freebsd/sys/netinet/tcp_timer.h @@ -197,6 +197,7 @@ extern int tcp_ttl; /* time to live for TCP segs */ extern int tcp_backoff[]; extern int tcp_syn_backoff[]; +extern int tcp_always_keepalive; extern int tcp_finwait2_timeout; extern int tcp_fast_finwait2_recycle; diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h index 0bcb3dc6..35b44410 100644 --- a/freebsd/sys/netinet/tcp_var.h +++ b/freebsd/sys/netinet/tcp_var.h @@ -884,6 +884,7 @@ void tcp_sack_partialack(struct tcpcb *, struct tcphdr *); void tcp_free_sackholes(struct tcpcb *tp); int tcp_newreno(struct tcpcb *, struct tcphdr *); int tcp_compute_pipe(struct tcpcb *); +void tcp_sndbuf_autoscale(struct tcpcb *, struct socket *, uint32_t); static inline void tcp_fields_to_host(struct tcphdr *th) diff --git a/freebsd/sys/netinet6/frag6.c b/freebsd/sys/netinet6/frag6.c index 1224aeaa..5b405ebb 100644 --- a/freebsd/sys/netinet6/frag6.c +++ b/freebsd/sys/netinet6/frag6.c @@ -229,6 +229,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) IP6STAT_INC(ip6s_reassembled); in6_ifstat_inc(dstifp, ifs6_reass_ok); *offp = offset; + m->m_flags |= M_FRAGMENTED; return (ip6f->ip6f_nxt); } @@ -542,6 +543,7 @@ insert: while (t->m_next) t = t->m_next; m_adj(IP6_REASS_MBUF(af6), af6->ip6af_offset); + m_demote_pkthdr(IP6_REASS_MBUF(af6)); m_cat(t, IP6_REASS_MBUF(af6)); free(af6, M_FTABLE); af6 = af6dwn; @@ -829,5 +831,6 @@ ip6_deletefraghdr(struct mbuf *m, int offset, int wait) m_cat(m, t); } + m->m_flags |= M_FRAGMENTED; return (0); } diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c index fb537170..38f14461 100644 --- a/freebsd/sys/netinet6/icmp6.c +++ b/freebsd/sys/netinet6/icmp6.c @@ -2266,6 +2266,10 @@ icmp6_redirect_input(struct mbuf *m, int off) if (!V_icmp6_rediraccept) goto freeit; + /* RFC 6980: Nodes MUST silently ignore fragments */ + if(m->m_flags & M_FRAGMENTED) + goto freeit; + #ifndef PULLDOWN_TEST IP6_EXTHDR_CHECK(m, off, icmp6len,); nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off); diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c index 2046043d..6fc29892 100644 --- a/freebsd/sys/netinet6/in6.c +++ b/freebsd/sys/netinet6/in6.c @@ -1458,7 +1458,7 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags) /* - * find the internet address corresponding to a given address. + * find the interface address corresponding to a given IPv6 address. * ifaddr is returned referenced. */ struct in6_ifaddr * diff --git a/freebsd/sys/netinet6/in6_ifattach.c b/freebsd/sys/netinet6/in6_ifattach.c index d89581e4..26a682ad 100644 --- a/freebsd/sys/netinet6/in6_ifattach.c +++ b/freebsd/sys/netinet6/in6_ifattach.c @@ -700,7 +700,6 @@ void in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) { struct in6_ifaddr *ia; - struct in6_addr in6; if (ifp->if_afdata[AF_INET6] == NULL) return; @@ -733,18 +732,16 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) /* * assign loopback address for loopback interface. - * XXX multiple loopback interface case. */ if ((ifp->if_flags & IFF_LOOPBACK) != 0) { - struct ifaddr *ifa; - - in6 = in6addr_loopback; - ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &in6); - if (ifa == NULL) { - if (in6_ifattach_loopback(ifp) != 0) - return; - } else - ifa_free(ifa); + /* + * check that loopback address doesn't exist yet. + */ + ia = in6ifa_ifwithaddr(&in6addr_loopback, 0); + if (ia == NULL) + in6_ifattach_loopback(ifp); + else + ifa_free(&ia->ia_ifa); } /* @@ -752,18 +749,10 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) */ if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) { - int error; - ia = in6ifa_ifpforlinklocal(ifp, 0); - if (ia == NULL) { - error = in6_ifattach_linklocal(ifp, altifp); -#if 0 - if (error) - log(LOG_NOTICE, "in6_ifattach_linklocal: " - "failed to add a link-local addr to %s\n", - if_name(ifp)); -#endif - } else + if (ia == NULL) + in6_ifattach_linklocal(ifp, altifp); + else ifa_free(&ia->ia_ifa); } diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c index 4119d1d9..a634b18b 100644 --- a/freebsd/sys/netinet6/in6_mcast.c +++ b/freebsd/sys/netinet6/in6_mcast.c @@ -1240,11 +1240,8 @@ out_in6m_release: int in6_mc_leave(struct in6_multi *inm, /*const*/ struct in6_mfilter *imf) { - struct ifnet *ifp; int error; - ifp = inm->in6m_ifp; - IN6_MULTI_LOCK(); error = in6_mc_leave_locked(inm, imf); IN6_MULTI_UNLOCK(); diff --git a/freebsd/sys/netinet6/in6_src.c b/freebsd/sys/netinet6/in6_src.c index a13c1a06..5b110274 100644 --- a/freebsd/sys/netinet6/in6_src.c +++ b/freebsd/sys/netinet6/in6_src.c @@ -162,7 +162,6 @@ static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *); */ #define REPLACE(r) do {\ IP6STAT_INC(ip6s_sources_rule[(r)]); \ - rule = (r); \ /* { \ char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ @@ -178,7 +177,6 @@ static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *); } while(0) #define BREAK(r) do { \ IP6STAT_INC(ip6s_sources_rule[(r)]); \ - rule = (r); \ goto out; /* XXX: we can't use 'break' here */ \ } while(0) @@ -196,7 +194,7 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL; u_int32_t odstzone; int prefer_tempaddr; - int error, rule; + int error; struct ip6_moptions *mopts; KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__)); @@ -312,7 +310,6 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, if (error) return (error); - rule = 0; IN6_IFADDR_RLOCK(&in6_ifa_tracker); TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { int new_scope = -1, new_matchlen = -1; diff --git a/freebsd/sys/netinet6/ip6_id.c b/freebsd/sys/netinet6/ip6_id.c index cf0f3a4c..0905ab3f 100644 --- a/freebsd/sys/netinet6/ip6_id.c +++ b/freebsd/sys/netinet6/ip6_id.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-kernel-space.h> /*- + * SPDX-License-Identifier: (BSD-3-Clause AND BSD-2-Clause) + * * Copyright (C) 2003 WIDE Project. * All rights reserved. * @@ -32,8 +34,6 @@ */ /*- - * SPDX-License-Identifier: BSD-4-Clause AND BSD-3-Clause - * * Copyright 1998 Niels Provos <provos@citi.umich.edu> * All rights reserved. * @@ -50,11 +50,6 @@ * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Niels Provos. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -67,7 +62,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $OpenBSD: ip_id.c,v 1.6 2002/03/15 18:19:52 millert Exp $ + * $OpenBSD: ip6_id.c,v 1.3 2003/12/12 06:57:12 itojun Exp $ */ #include <sys/cdefs.h> @@ -88,7 +83,7 @@ __FBSDID("$FreeBSD$"); * The transaction id is determined by: * id[n] = seed xor (g^X[n] mod n) * - * Effectivly the id is restricted to the lower (bits - 1) bits, thus + * Effectively the id is restricted to the lower (bits - 1) bits, thus * yielding two different cycles by toggling the msb on and off. * This avoids reuse issues caused by reseeding. */ @@ -179,7 +174,7 @@ pmod(u_int32_t gen, u_int32_t expo, u_int32_t mod) } /* - * Initalizes the seed and chooses a suitable generator. Also toggles + * Initializes the seed and chooses a suitable generator. Also toggles * the msb flag. The msb flag is used to generate two distinct * cycles of random numbers and thus avoiding reuse of ids. * @@ -234,15 +229,12 @@ static u_int32_t randomid(struct randomtab *p) { int i, n; - u_int32_t tmp; if (p->ru_counter >= p->ru_max || time_uptime > p->ru_reseed) initid(p); - tmp = arc4random(); - /* Skip a random number of ids */ - n = tmp & 0x3; tmp = tmp >> 2; + n = arc4random() & 0x3; if (p->ru_counter + n >= p->ru_max) initid(p); @@ -253,7 +245,7 @@ randomid(struct randomtab *p) p->ru_counter += i; - return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 ^ p->ru_x, p->ru_n)) | + return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 + p->ru_x, p->ru_n)) | p->ru_msb; } diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c index c22f2015..78d941ae 100644 --- a/freebsd/sys/netinet6/ip6_input.c +++ b/freebsd/sys/netinet6/ip6_input.c @@ -575,10 +575,8 @@ ip6_input(struct mbuf *m) /* * Firewall changed destination to local. */ - m->m_flags &= ~M_FASTFWD_OURS; - ours = 1; ip6 = mtod(m, struct ip6_hdr *); - goto hbhcheck; + goto passin; } /* @@ -739,10 +737,8 @@ ip6_input(struct mbuf *m) if ((m = ip6_tryforward(m)) == NULL) return; if (m->m_flags & M_FASTFWD_OURS) { - m->m_flags &= ~M_FASTFWD_OURS; - ours = 1; ip6 = mtod(m, struct ip6_hdr *); - goto hbhcheck; + goto passin; } } #if defined(IPSEC) || defined(IPSEC_SUPPORT) @@ -773,13 +769,7 @@ ip6_input(struct mbuf *m) return; ip6 = mtod(m, struct ip6_hdr *); srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); - - if (m->m_flags & M_FASTFWD_OURS) { - m->m_flags &= ~M_FASTFWD_OURS; - ours = 1; - goto hbhcheck; - } - if ((m->m_flags & M_IP6_NEXTHOP) && + if ((m->m_flags & (M_IP6_NEXTHOP | M_FASTFWD_OURS)) == M_IP6_NEXTHOP && m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL) { /* * Directly ship the packet on. This allows forwarding @@ -810,6 +800,11 @@ passin: IP6STAT_INC(ip6s_badscope); goto bad; } + if (m->m_flags & M_FASTFWD_OURS) { + m->m_flags &= ~M_FASTFWD_OURS; + ours = 1; + goto hbhcheck; + } /* * Multicast check. Assume packet is for us to avoid * prematurely taking locks. diff --git a/freebsd/sys/netinet6/mld6.c b/freebsd/sys/netinet6/mld6.c index 26fb21f7..c1dff0c3 100644 --- a/freebsd/sys/netinet6/mld6.c +++ b/freebsd/sys/netinet6/mld6.c @@ -2288,7 +2288,7 @@ mld_v2_enqueue_group_record(struct mbufq *mq, struct in6_multi *inm, struct ifnet *ifp; struct ip6_msource *ims, *nims; struct mbuf *m0, *m, *md; - int error, is_filter_list_change; + int is_filter_list_change; int minrec0len, m0srcs, msrcs, nbytes, off; int record_has_sources; int now; @@ -2300,7 +2300,6 @@ mld_v2_enqueue_group_record(struct mbufq *mq, struct in6_multi *inm, IN6_MULTI_LOCK_ASSERT(); - error = 0; ifp = inm->in6m_ifp; is_filter_list_change = 0; m = NULL; diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c index 30672e23..6235b808 100644 --- a/freebsd/sys/netinet6/nd6.c +++ b/freebsd/sys/netinet6/nd6.c @@ -2034,10 +2034,11 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, if (ln_tmp == NULL) { /* No existing lle, mark as new entry (6,7) */ is_newentry = 1; - nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); - if (lladdr != NULL) /* (7) */ + if (lladdr != NULL) { /* (7) */ + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); + } } else { lltable_free_entry(LLTABLE6(ifp), ln); ln = ln_tmp; @@ -2115,7 +2116,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, LLE_RUNLOCK(ln); if (chain != NULL) - nd6_flush_holdchain(ifp, ifp, chain, &sin6); + nd6_flush_holdchain(ifp, chain, &sin6); /* * When the link-layer address of a router changes, select the @@ -2504,23 +2505,18 @@ nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst, } int -nd6_flush_holdchain(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *chain, +nd6_flush_holdchain(struct ifnet *ifp, struct mbuf *chain, struct sockaddr_in6 *dst) { struct mbuf *m, *m_head; - struct ifnet *outifp; int error = 0; m_head = chain; - if ((ifp->if_flags & IFF_LOOPBACK) != 0) - outifp = origifp; - else - outifp = ifp; - + while (m_head) { m = m_head; m_head = m_head->m_nextpkt; - error = nd6_output_ifp(ifp, origifp, m, dst, NULL); + error = nd6_output_ifp(ifp, ifp, m, dst, NULL); } /* @@ -2528,7 +2524,7 @@ nd6_flush_holdchain(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *chain * note that intermediate errors are blindly ignored */ return (error); -} +} static int nd6_need_cache(struct ifnet *ifp) diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h index 30990637..cabfeec0 100644 --- a/freebsd/sys/netinet6/nd6.h +++ b/freebsd/sys/netinet6/nd6.h @@ -448,7 +448,7 @@ void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, char *, int, int, int); void nd6_grab_holdchain(struct llentry *, struct mbuf **, struct sockaddr_in6 *); -int nd6_flush_holdchain(struct ifnet *, struct ifnet *, struct mbuf *, +int nd6_flush_holdchain(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); int nd6_add_ifa_lle(struct in6_ifaddr *); void nd6_rem_ifa_lle(struct in6_ifaddr *, int); diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c index 5e55fc2b..0c875324 100644 --- a/freebsd/sys/netinet6/nd6_nbr.c +++ b/freebsd/sys/netinet6/nd6_nbr.c @@ -139,6 +139,10 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) struct sockaddr_dl proxydl; char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; + /* RFC 6980: Nodes MUST silently ignore fragments */ + if(m->m_flags & M_FRAGMENTED) + goto freeit; + rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0; if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif) rflag = 0; @@ -633,6 +637,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) int lladdr_off; char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; + /* RFC 6980: Nodes MUST silently ignore fragments */ + if(m->m_flags & M_FRAGMENTED) + goto freeit; + if (ip6->ip6_hlim != 255) { nd6log((LOG_ERR, "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n", @@ -888,7 +896,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) LLE_WUNLOCK(ln); if (chain != NULL) - nd6_flush_holdchain(ifp, ifp, chain, &sin6); + nd6_flush_holdchain(ifp, chain, &sin6); if (checklink) pfxlist_onlink_check(); @@ -1301,7 +1309,8 @@ nd6_dad_stop(struct ifaddr *ifa) * we were waiting for it to stop, so re-do the lookup. */ nd6_dad_rele(dp); - if (nd6_dad_find(ifa, NULL) == NULL) + dp = nd6_dad_find(ifa, NULL); + if (dp == NULL) return; nd6_dad_del(dp); @@ -1508,17 +1517,11 @@ nd6_dad_ns_output(struct dadq *dp) static void nd6_dad_ns_input(struct ifaddr *ifa, struct nd_opt_nonce *ndopt_nonce) { - struct in6_ifaddr *ia; - struct ifnet *ifp; - const struct in6_addr *taddr6; struct dadq *dp; if (ifa == NULL) panic("ifa == NULL in nd6_dad_ns_input"); - ia = (struct in6_ifaddr *)ifa; - ifp = ifa->ifa_ifp; - taddr6 = &ia->ia_addr.sin6_addr; /* Ignore Nonce option when Enhanced DAD is disabled. */ if (V_dad_enhanced == 0) ndopt_nonce = NULL; diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c index 47fc497e..2affacbf 100644 --- a/freebsd/sys/netinet6/nd6_rtr.c +++ b/freebsd/sys/netinet6/nd6_rtr.c @@ -141,6 +141,10 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len) if (!V_ip6_forwarding || ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) goto freeit; + /* RFC 6980: Nodes MUST silently ignore fragments */ + if(m->m_flags & M_FRAGMENTED) + goto freeit; + /* Sanity checks */ if (ip6->ip6_hlim != 255) { nd6log((LOG_ERR, @@ -231,6 +235,10 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV)) goto freeit; + /* RFC 6980: Nodes MUST silently ignore fragments */ + if(m->m_flags & M_FRAGMENTED) + goto freeit; + if (ip6->ip6_hlim != 255) { nd6log((LOG_ERR, "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n", diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c index 743fe787..b68077ef 100644 --- a/freebsd/sys/netinet6/raw_ip6.c +++ b/freebsd/sys/netinet6/raw_ip6.c @@ -341,9 +341,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto) void rip6_ctlinput(int cmd, struct sockaddr *sa, void *d) { - struct ip6_hdr *ip6; - struct mbuf *m; - int off = 0; struct ip6ctlparam *ip6cp = NULL; const struct sockaddr_in6 *sa6_src = NULL; void *cmdarg; @@ -367,14 +364,9 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d) */ if (d != NULL) { ip6cp = (struct ip6ctlparam *)d; - m = ip6cp->ip6c_m; - ip6 = ip6cp->ip6c_ip6; - off = ip6cp->ip6c_off; cmdarg = ip6cp->ip6c_cmdarg; sa6_src = ip6cp->ip6c_src; } else { - m = NULL; - ip6 = NULL; cmdarg = NULL; sa6_src = &sa6_any; } @@ -393,7 +385,6 @@ rip6_output(struct mbuf *m, struct socket *so, ...) struct mbuf *control; struct m_tag *mtag; struct sockaddr_in6 *dstsock; - struct in6_addr *dst; struct ip6_hdr *ip6; struct inpcb *in6p; u_int plen = m->m_pkthdr.len; @@ -415,7 +406,6 @@ rip6_output(struct mbuf *m, struct socket *so, ...) in6p = sotoinpcb(so); INP_WLOCK(in6p); - dst = &dstsock->sin6_addr; if (control != NULL) { if ((error = ip6_setpktopts(control, &opt, in6p->in6p_outputopts, so->so_cred, diff --git a/freebsd/sys/netinet6/scope6.c b/freebsd/sys/netinet6/scope6.c index a4c56769..40218287 100644 --- a/freebsd/sys/netinet6/scope6.c +++ b/freebsd/sys/netinet6/scope6.c @@ -413,7 +413,7 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id) if (scope == IPV6_ADDR_SCOPE_INTFACELOCAL || scope == IPV6_ADDR_SCOPE_LINKLOCAL) { /* - * Currently we use interface indeces as the + * Currently we use interface indices as the * zone IDs for interface-local and link-local * scopes. */ diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c index 619a30dc..a79e6f53 100644 --- a/freebsd/sys/netinet6/sctp6_usrreq.c +++ b/freebsd/sys/netinet6/sctp6_usrreq.c @@ -73,9 +73,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) struct sctphdr *sh; struct sctp_chunkhdr *ch; int length, offset; -#if !defined(SCTP_WITH_NO_CSUM) uint8_t compute_crc; -#endif uint32_t mflowid; uint8_t mflowtype; uint16_t fibnum; @@ -146,9 +144,6 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) goto out; } ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); -#if defined(SCTP_WITH_NO_CSUM) - SCTP_STAT_INCR(sctps_recvnocrc); -#else if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { SCTP_STAT_INCR(sctps_recvhwcrc); compute_crc = 0; @@ -156,14 +151,11 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) SCTP_STAT_INCR(sctps_recvswcrc); compute_crc = 1; } -#endif sctp_common_input_processing(&m, iphlen, offset, length, (struct sockaddr *)&src, (struct sockaddr *)&dst, sh, ch, -#if !defined(SCTP_WITH_NO_CSUM) compute_crc, -#endif ecn_bits, mflowtype, mflowid, fibnum, vrf_id, port); diff --git a/freebsd/sys/netinet6/udp6_usrreq.c b/freebsd/sys/netinet6/udp6_usrreq.c index ae57ac79..98d097f7 100644 --- a/freebsd/sys/netinet6/udp6_usrreq.c +++ b/freebsd/sys/netinet6/udp6_usrreq.c @@ -1192,7 +1192,6 @@ udp6_disconnect(struct socket *so) { struct inpcb *inp; struct inpcbinfo *pcbinfo; - int error; pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); inp = sotoinpcb(so); @@ -1214,8 +1213,8 @@ udp6_disconnect(struct socket *so) #endif if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { - error = ENOTCONN; - goto out; + INP_WUNLOCK(inp); + return (ENOTCONN); } INP_HASH_WLOCK(pcbinfo); @@ -1225,7 +1224,6 @@ udp6_disconnect(struct socket *so) SOCK_LOCK(so); so->so_state &= ~SS_ISCONNECTED; /* XXX */ SOCK_UNLOCK(so); -out: INP_WUNLOCK(inp); return (0); } diff --git a/freebsd/sys/netipsec/key.c b/freebsd/sys/netipsec/key.c index 3652524c..31269058 100644 --- a/freebsd/sys/netipsec/key.c +++ b/freebsd/sys/netipsec/key.c @@ -5746,7 +5746,6 @@ static int key_setident(struct secashead *sah, const struct sadb_msghdr *mhp) { const struct sadb_ident *idsrc, *iddst; - int idsrclen, iddstlen; IPSEC_ASSERT(sah != NULL, ("null secashead")); IPSEC_ASSERT(mhp != NULL, ("null msghdr")); @@ -5768,8 +5767,6 @@ key_setident(struct secashead *sah, const struct sadb_msghdr *mhp) idsrc = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_SRC]; iddst = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_DST]; - idsrclen = mhp->extlen[SADB_EXT_IDENTITY_SRC]; - iddstlen = mhp->extlen[SADB_EXT_IDENTITY_DST]; /* validity check */ if (idsrc->sadb_ident_type != iddst->sadb_ident_type) { @@ -7466,7 +7463,6 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) SAHTREE_RLOCK_TRACKER; struct secashead *sah; struct secasvar *sav; - struct sadb_msg *newmsg; struct mbuf *n; uint32_t cnt; uint8_t proto, satype; @@ -7503,7 +7499,6 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) } /* send this to the userland, one at a time. */ - newmsg = NULL; TAILQ_FOREACH(sah, &V_sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) @@ -8149,7 +8144,10 @@ key_destroy(void) TAILQ_CONCAT(&drainq, &V_sptree[i], chain); TAILQ_CONCAT(&drainq, &V_sptree_ifnet[i], chain); } + for (i = 0; i < V_sphash_mask + 1; i++) + LIST_INIT(&V_sphashtbl[i]); SPTREE_WUNLOCK(); + sp = TAILQ_FIRST(&drainq); while (sp != NULL) { nextsp = TAILQ_NEXT(sp, chain); @@ -8200,6 +8198,10 @@ key_destroy(void) free(acq, M_IPSEC_SAQ); acq = nextacq; } + for (i = 0; i < V_acqaddrhash_mask + 1; i++) + LIST_INIT(&V_acqaddrhashtbl[i]); + for (i = 0; i < V_acqseqhash_mask + 1; i++) + LIST_INIT(&V_acqseqhashtbl[i]); ACQ_UNLOCK(); SPACQ_LOCK(); @@ -8215,6 +8217,18 @@ key_destroy(void) hashdestroy(V_acqaddrhashtbl, M_IPSEC_SAQ, V_acqaddrhash_mask); hashdestroy(V_acqseqhashtbl, M_IPSEC_SAQ, V_acqseqhash_mask); uma_zdestroy(V_key_lft_zone); + + if (!IS_DEFAULT_VNET(curvnet)) + return; +#ifndef IPSEC_DEBUG2 + callout_drain(&key_timer); +#endif + XFORMS_LOCK_DESTROY(); + SPTREE_LOCK_DESTROY(); + REGTREE_LOCK_DESTROY(); + SAHTREE_LOCK_DESTROY(); + ACQ_LOCK_DESTROY(); + SPACQ_LOCK_DESTROY(); } #endif diff --git a/freebsd/sys/netipsec/xform_ah.c b/freebsd/sys/netipsec/xform_ah.c index 5667f78f..9125ba40 100644 --- a/freebsd/sys/netipsec/xform_ah.c +++ b/freebsd/sys/netipsec/xform_ah.c @@ -266,7 +266,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) #ifdef INET6 struct ip6_ext *ip6e; struct ip6_hdr ip6; - int alloc, len, ad; + int ad, alloc, nxt, noff; #endif /* INET6 */ switch (proto) { @@ -295,7 +295,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) else ip->ip_off = htons(0); - ptr = mtod(m, unsigned char *) + sizeof(struct ip); + ptr = mtod(m, unsigned char *); /* IPv4 option processing */ for (off = sizeof(struct ip); off < skip;) { @@ -376,7 +376,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) /* Zeroize all other options. */ count = ptr[off + 1]; - bcopy(ipseczeroes, ptr, count); + bcopy(ipseczeroes, ptr + off, count); off += count; break; } @@ -449,61 +449,44 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) } else break; - off = ip6.ip6_nxt & 0xff; /* Next header type. */ + nxt = ip6.ip6_nxt & 0xff; /* Next header type. */ - for (len = 0; len < skip - sizeof(struct ip6_hdr);) - switch (off) { + for (off = 0; off < skip - sizeof(struct ip6_hdr);) + switch (nxt) { case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: - ip6e = (struct ip6_ext *) (ptr + len); + ip6e = (struct ip6_ext *)(ptr + off); + noff = off + ((ip6e->ip6e_len + 1) << 3); + + /* Sanity check. */ + if (noff > skip - sizeof(struct ip6_hdr)) + goto error6; /* - * Process the mutable/immutable - * options -- borrows heavily from the - * KAME code. + * Zero out mutable options. */ - for (count = len + sizeof(struct ip6_ext); - count < len + ((ip6e->ip6e_len + 1) << 3);) { + for (count = off + sizeof(struct ip6_ext); + count < noff;) { if (ptr[count] == IP6OPT_PAD1) { count++; continue; /* Skip padding. */ } - /* Sanity check. */ - if (count > len + - ((ip6e->ip6e_len + 1) << 3)) { - m_freem(m); - - /* Free, if we allocated. */ - if (alloc) - free(ptr, M_XDATA); - return EINVAL; - } - - ad = ptr[count + 1]; + ad = ptr[count + 1] + 2; + if (count + ad > noff) + goto error6; - /* If mutable option, zeroize. */ if (ptr[count] & IP6OPT_MUTABLE) - bcopy(ipseczeroes, ptr + count, - ptr[count + 1]); - + memset(ptr + count, 0, ad); count += ad; - - /* Sanity check. */ - if (count > - skip - sizeof(struct ip6_hdr)) { - m_freem(m); - - /* Free, if we allocated. */ - if (alloc) - free(ptr, M_XDATA); - return EINVAL; - } } + if (count != noff) + goto error6; + /* Advance. */ - len += ((ip6e->ip6e_len + 1) << 3); - off = ip6e->ip6e_nxt; + off += ((ip6e->ip6e_len + 1) << 3); + nxt = ip6e->ip6e_nxt; break; case IPPROTO_ROUTING: @@ -511,14 +494,15 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) * Always include routing headers in * computation. */ - ip6e = (struct ip6_ext *) (ptr + len); - len += ((ip6e->ip6e_len + 1) << 3); - off = ip6e->ip6e_nxt; + ip6e = (struct ip6_ext *) (ptr + off); + off += ((ip6e->ip6e_len + 1) << 3); + nxt = ip6e->ip6e_nxt; break; default: DPRINTF(("%s: unexpected IPv6 header type %d", __func__, off)); +error6: if (alloc) free(ptr, M_XDATA); m_freem(m); @@ -687,9 +671,7 @@ ah_input_cb(struct cryptop *crp) { IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); unsigned char calc[AH_ALEN_MAX]; - const struct auth_hash *ahx; struct mbuf *m; - struct cryptodesc *crd; struct xform_data *xd; struct secasvar *sav; struct secasindex *saidx; @@ -698,7 +680,6 @@ ah_input_cb(struct cryptop *crp) int authsize, rplen, error, skip, protoff; uint8_t nxt; - crd = crp->crp_desc; m = (struct mbuf *) crp->crp_buf; xd = (struct xform_data *) crp->crp_opaque; sav = xd->sav; @@ -711,8 +692,6 @@ ah_input_cb(struct cryptop *crp) saidx->dst.sa.sa_family == AF_INET6, ("unexpected protocol family %u", saidx->dst.sa.sa_family)); - ahx = sav->tdb_authalgxform; - /* Check for crypto errors. */ if (crp->crp_etype) { if (crp->crp_etype == EAGAIN) { diff --git a/freebsd/sys/netipsec/xform_esp.c b/freebsd/sys/netipsec/xform_esp.c index 8af95f7d..f26b8ae7 100644 --- a/freebsd/sys/netipsec/xform_esp.c +++ b/freebsd/sys/netipsec/xform_esp.c @@ -443,7 +443,6 @@ esp_input_cb(struct cryptop *crp) IPSEC_DEBUG_DECLARE(char buf[128]); u_int8_t lastthree[3], aalg[AH_HMAC_MAXHASHLEN]; const struct auth_hash *esph; - const struct enc_xform *espx; struct mbuf *m; struct cryptodesc *crd; struct xform_data *xd; @@ -464,7 +463,6 @@ esp_input_cb(struct cryptop *crp) cryptoid = xd->cryptoid; saidx = &sav->sah->saidx; esph = sav->tdb_authalgxform; - espx = sav->tdb_encalgxform; /* Check for crypto errors */ if (crp->crp_etype) { diff --git a/freebsd/sys/netipsec/xform_ipcomp.c b/freebsd/sys/netipsec/xform_ipcomp.c index 4764e609..956383d5 100644 --- a/freebsd/sys/netipsec/xform_ipcomp.c +++ b/freebsd/sys/netipsec/xform_ipcomp.c @@ -276,7 +276,6 @@ static int ipcomp_input_cb(struct cryptop *crp) { IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); - struct cryptodesc *crd; struct xform_data *xd; struct mbuf *m; struct secasvar *sav; @@ -287,8 +286,6 @@ ipcomp_input_cb(struct cryptop *crp) int skip, protoff; uint8_t nproto; - crd = crp->crp_desc; - m = (struct mbuf *) crp->crp_buf; xd = (struct xform_data *) crp->crp_opaque; sav = xd->sav; diff --git a/freebsd/sys/netpfil/pf/if_pflog.c b/freebsd/sys/netpfil/pf/if_pflog.c index 1ad6a774..53cf94c8 100644 --- a/freebsd/sys/netpfil/pf/if_pflog.c +++ b/freebsd/sys/netpfil/pf/if_pflog.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-kernel-space.h> /*- + * SPDX-License-Identifier: ISC + * * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and * Niels Provos (provos@physnet.uni-hamburg.de). diff --git a/freebsd/sys/netpfil/pf/in4_cksum.c b/freebsd/sys/netpfil/pf/in4_cksum.c index 509c33cd..242909cc 100644 --- a/freebsd/sys/netpfil/pf/in4_cksum.c +++ b/freebsd/sys/netpfil/pf/in4_cksum.c @@ -5,7 +5,7 @@ /* $KAME: in4_cksum.c,v 1.10 2001/11/30 10:06:15 itojun Exp $ */ /* $NetBSD: in_cksum.c,v 1.13 1996/10/13 02:03:03 christos Exp $ */ -/* +/*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (C) 1999 WIDE Project. diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c index d94966b9..a904a0db 100644 --- a/freebsd/sys/netpfil/pf/pf.c +++ b/freebsd/sys/netpfil/pf/pf.c @@ -1500,7 +1500,7 @@ pf_unload_vnet_purge(void) * Now purge everything. */ pf_purge_expired_states(0, pf_hashmask); - pf_purge_expired_fragments(); + pf_purge_fragments(UINT_MAX); pf_purge_expired_src_nodes(); /* @@ -1615,6 +1615,7 @@ int pf_unlink_state(struct pf_state *s, u_int flags) { struct pf_idhash *ih = &V_pf_idhash[PF_IDHASH(s)]; + int last; if ((flags & PF_ENTER_LOCKED) == 0) PF_HASHROW_LOCK(ih); @@ -1655,7 +1656,8 @@ pf_unlink_state(struct pf_state *s, u_int flags) PF_HASHROW_UNLOCK(ih); pf_detach_state(s); - refcount_release(&s->refs); + last = refcount_release(&s->refs); + KASSERT(last == 0, ("Incorrect state reference count")); return (pf_release_state(s)); } diff --git a/freebsd/sys/netpfil/pf/pf.h b/freebsd/sys/netpfil/pf/pf.h index 333faea3..69472782 100644 --- a/freebsd/sys/netpfil/pf/pf.h +++ b/freebsd/sys/netpfil/pf/pf.h @@ -1,4 +1,4 @@ -/* +/*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2001 Daniel Hartmeier diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c index 98f190e7..a1b0b5e5 100644 --- a/freebsd/sys/netpfil/pf/pf_ioctl.c +++ b/freebsd/sys/netpfil/pf/pf_ioctl.c @@ -2543,7 +2543,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_table); - pfrts = malloc(totlen, M_TEMP, M_WAITOK); + pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), + M_TEMP, M_WAITOK); + if (! pfrts) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfrts, totlen); if (error) { free(pfrts, M_TEMP); @@ -2567,7 +2572,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_table); - pfrts = malloc(totlen, M_TEMP, M_WAITOK); + pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), + M_TEMP, M_WAITOK); + if (! pfrts) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfrts, totlen); if (error) { free(pfrts, M_TEMP); @@ -2591,7 +2601,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_table); - pfrts = malloc(totlen, M_TEMP, M_WAITOK); + pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), + M_TEMP, M_WAITOK); + if (! pfrts) { + error = ENOMEM; + break; + } PF_RULES_RLOCK(); error = pfr_get_tables(&io->pfrio_table, pfrts, &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); @@ -2612,7 +2627,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_tstats); - pfrtstats = malloc(totlen, M_TEMP, M_WAITOK); + pfrtstats = mallocarray(io->pfrio_size, + sizeof(struct pfr_tstats), M_TEMP, M_WAITOK); + if (! pfrtstats) { + error = ENOMEM; + break; + } PF_RULES_WLOCK(); error = pfr_get_tstats(&io->pfrio_table, pfrtstats, &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); @@ -2633,7 +2653,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_table); - pfrts = malloc(totlen, M_TEMP, M_WAITOK); + pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), + M_TEMP, M_WAITOK); + if (! pfrts) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfrts, totlen); if (error) { free(pfrts, M_TEMP); @@ -2657,7 +2682,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_table); - pfrts = malloc(totlen, M_TEMP, M_WAITOK); + pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), + M_TEMP, M_WAITOK); + if (! pfrts) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfrts, totlen); if (error) { free(pfrts, M_TEMP); @@ -2696,7 +2726,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), + M_TEMP, M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfras, totlen); if (error) { free(pfras, M_TEMP); @@ -2723,7 +2758,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), + M_TEMP, M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfras, totlen); if (error) { free(pfras, M_TEMP); @@ -2751,7 +2791,12 @@ DIOCCHANGEADDR_error: } count = max(io->pfrio_size, io->pfrio_size2); totlen = count * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP, + M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfras, totlen); if (error) { free(pfras, M_TEMP); @@ -2779,7 +2824,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), + M_TEMP, M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } PF_RULES_RLOCK(); error = pfr_get_addrs(&io->pfrio_table, pfras, &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); @@ -2800,7 +2850,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_astats); - pfrastats = malloc(totlen, M_TEMP, M_WAITOK); + pfrastats = mallocarray(io->pfrio_size, + sizeof(struct pfr_astats), M_TEMP, M_WAITOK); + if (! pfrastats) { + error = ENOMEM; + break; + } PF_RULES_RLOCK(); error = pfr_get_astats(&io->pfrio_table, pfrastats, &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); @@ -2821,7 +2876,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), + M_TEMP, M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfras, totlen); if (error) { free(pfras, M_TEMP); @@ -2848,7 +2908,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), + M_TEMP, M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfras, totlen); if (error) { free(pfras, M_TEMP); @@ -2875,7 +2940,12 @@ DIOCCHANGEADDR_error: break; } totlen = io->pfrio_size * sizeof(struct pfr_addr); - pfras = malloc(totlen, M_TEMP, M_WAITOK); + pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), + M_TEMP, M_WAITOK); + if (! pfras) { + error = ENOMEM; + break; + } error = copyin(io->pfrio_buffer, pfras, totlen); if (error) { free(pfras, M_TEMP); @@ -2917,7 +2987,12 @@ DIOCCHANGEADDR_error: break; } totlen = sizeof(struct pfioc_trans_e) * io->size; - ioes = malloc(totlen, M_TEMP, M_WAITOK); + ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), + M_TEMP, M_WAITOK); + if (! ioes) { + error = ENOMEM; + break; + } error = copyin(io->array, ioes, totlen); if (error) { free(ioes, M_TEMP); @@ -2983,7 +3058,12 @@ DIOCCHANGEADDR_error: break; } totlen = sizeof(struct pfioc_trans_e) * io->size; - ioes = malloc(totlen, M_TEMP, M_WAITOK); + ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), + M_TEMP, M_WAITOK); + if (! ioes) { + error = ENOMEM; + break; + } error = copyin(io->array, ioes, totlen); if (error) { free(ioes, M_TEMP); @@ -3049,7 +3129,12 @@ DIOCCHANGEADDR_error: break; } totlen = sizeof(struct pfioc_trans_e) * io->size; - ioes = malloc(totlen, M_TEMP, M_WAITOK); + ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), + M_TEMP, M_WAITOK); + if (! ioes) { + error = ENOMEM; + break; + } error = copyin(io->array, ioes, totlen); if (error) { free(ioes, M_TEMP); @@ -3250,7 +3335,12 @@ DIOCCHANGEADDR_error: } bufsiz = io->pfiio_size * sizeof(struct pfi_kif); - ifstore = malloc(bufsiz, M_TEMP, M_WAITOK); + ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif), + M_TEMP, M_WAITOK); + if (! ifstore) { + error = ENOMEM; + break; + } PF_RULES_RLOCK(); pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size); PF_RULES_RUNLOCK(); @@ -3845,12 +3935,6 @@ pf_modevent(module_t mod, int type, void *data) case MOD_LOAD: error = pf_load(); break; - case MOD_QUIESCE: - /* - * Module should not be unloaded due to race conditions. - */ - error = EBUSY; - break; case MOD_UNLOAD: /* Handled in SYSUNINIT(pf_unload) to ensure it's done after * the vnet_pf_uninit()s */ diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c index e3a00971..4f0966ed 100644 --- a/freebsd/sys/netpfil/pf/pf_norm.c +++ b/freebsd/sys/netpfil/pf/pf_norm.c @@ -221,9 +221,16 @@ pf_frag_compare(struct pf_fragment *a, struct pf_fragment *b) void pf_purge_expired_fragments(void) { + u_int32_t expire = time_uptime - + V_pf_default_rule.timeout[PFTM_FRAG]; + + pf_purge_fragments(expire); +} + +void +pf_purge_fragments(uint32_t expire) +{ struct pf_fragment *frag; - u_int32_t expire = time_uptime - - V_pf_default_rule.timeout[PFTM_FRAG]; PF_FRAG_LOCK(); while ((frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue)) != NULL) { diff --git a/freebsd/sys/netpfil/pf/pf_osfp.c b/freebsd/sys/netpfil/pf/pf_osfp.c index 7b55d20a..1ee16df5 100644 --- a/freebsd/sys/netpfil/pf/pf_osfp.c +++ b/freebsd/sys/netpfil/pf/pf_osfp.c @@ -1,6 +1,8 @@ #include <machine/rtems-bsd-kernel-space.h> /*- + * SPDX-License-Identifier: ISC + * * Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org> * * Permission to use, copy, modify, and distribute this software for any diff --git a/freebsd/sys/opencrypto/crypto.c b/freebsd/sys/opencrypto/crypto.c index 2631ca5b..f6943be2 100644 --- a/freebsd/sys/opencrypto/crypto.c +++ b/freebsd/sys/opencrypto/crypto.c @@ -903,11 +903,12 @@ crypto_dispatch(struct cryptop *crp) binuptime(&crp->crp_tstamp); #endif + crp->crp_retw_id = crp->crp_sid % crypto_workers_num; + if (CRYPTOP_ASYNC(crp)) { if (crp->crp_flags & CRYPTO_F_ASYNC_KEEPORDER) { struct crypto_ret_worker *ret_worker; - crp->crp_retw_id = crp->crp_sid % crypto_workers_num; ret_worker = CRYPTO_RETW(crp->crp_retw_id); CRYPTO_RETW_LOCK(ret_worker); @@ -1001,7 +1002,7 @@ kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp) static struct cryptocap * crypto_select_kdriver(const struct cryptkop *krp, int flags) { - struct cryptocap *cap, *best, *blocked; + struct cryptocap *cap, *best; int match, hid; CRYPTO_DRIVER_ASSERT(); @@ -1014,7 +1015,6 @@ crypto_select_kdriver(const struct cryptkop *krp, int flags) else match = CRYPTOCAP_F_SOFTWARE; best = NULL; - blocked = NULL; again: for (hid = 0; hid < crypto_drivers_num; hid++) { cap = &crypto_drivers[hid]; diff --git a/freebsd/sys/opencrypto/cryptodev.c b/freebsd/sys/opencrypto/cryptodev.c index 9d8b23dc..c24af195 100644 --- a/freebsd/sys/opencrypto/cryptodev.c +++ b/freebsd/sys/opencrypto/cryptodev.c @@ -280,14 +280,17 @@ struct csession { caddr_t key; int keylen; - u_char tmp_iv[EALG_MAX_BLOCK_LEN]; caddr_t mackey; int mackeylen; +}; + +struct cryptop_data { + struct csession *cse; - struct iovec iovec; + struct iovec iovec[1]; struct uio uio; - int error; + bool done; }; struct fcrypt { @@ -449,6 +452,7 @@ cryptof_ioctl( default: CRYPTDEB("invalid cipher"); + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } @@ -496,6 +500,7 @@ cryptof_ioctl( break; default: CRYPTDEB("invalid mac"); + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } @@ -509,6 +514,8 @@ cryptof_ioctl( sop->keylen < txform->minkey) { CRYPTDEB("invalid cipher parameters"); error = EINVAL; + SDT_PROBE1(opencrypto, dev, ioctl, error, + __LINE__); goto bail; } @@ -517,6 +524,8 @@ cryptof_ioctl( if ((error = copyin(sop->key, crie.cri_key, crie.cri_klen / 8))) { CRYPTDEB("invalid key"); + SDT_PROBE1(opencrypto, dev, ioctl, error, + __LINE__); goto bail; } if (thash) @@ -530,6 +539,8 @@ cryptof_ioctl( sop->mackeylen > thash->keysize) { CRYPTDEB("invalid mac key length"); error = EINVAL; + SDT_PROBE1(opencrypto, dev, ioctl, error, + __LINE__); goto bail; } @@ -539,6 +550,8 @@ cryptof_ioctl( if ((error = copyin(sop->mackey, cria.cri_key, cria.cri_klen / 8))) { CRYPTDEB("invalid mac key"); + SDT_PROBE1(opencrypto, dev, ioctl, + error, __LINE__); goto bail; } } @@ -554,6 +567,8 @@ cryptof_ioctl( error = checkforsoftware(&crid); if (error) { CRYPTDEB("checkforsoftware"); + SDT_PROBE1(opencrypto, dev, ioctl, error, + __LINE__); goto bail; } } else @@ -561,6 +576,7 @@ cryptof_ioctl( error = crypto_newsession(&sid, (txform ? &crie : &cria), crid); if (error) { CRYPTDEB("crypto_newsession"); + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } @@ -571,6 +587,7 @@ cryptof_ioctl( if (cse == NULL) { crypto_freesession(sid); error = EINVAL; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); CRYPTDEB("csecreate"); goto bail; } @@ -603,8 +620,10 @@ bail: case CIOCFSESSION: ses = *(u_int32_t *)data; cse = csefind(fcr, ses); - if (cse == NULL) + if (cse == NULL) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); + } csedelete(fcr, cse); error = csefree(cse); break; @@ -634,8 +653,10 @@ bail: case CIOCKEY32: case CIOCKEY232: #endif - if (!crypto_userasymcrypto) + if (!crypto_userasymcrypto) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EPERM); /* XXX compat? */ + } #ifdef COMPAT_FREEBSD32 if (cmd == CIOCKEY32 || cmd == CIOCKEY232) { kop = &kopc; @@ -669,8 +690,12 @@ bail: * fallback to doing them in software. */ *(int *)data = 0; - } else + } else { error = crypto_getfeat((int *)data); + if (error) + SDT_PROBE1(opencrypto, dev, ioctl, error, + __LINE__); + } break; case CIOCFINDDEV: error = cryptodev_find((struct crypt_find_op *)data); @@ -678,12 +703,15 @@ bail: case CIOCCRYPTAEAD: caead = (struct crypt_aead *)data; cse = csefind(fcr, caead->ses); - if (cse == NULL) + if (cse == NULL) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); + } error = cryptodev_aead(cse, caead, active_cred, td); break; default: error = EINVAL; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); break; } return (error); @@ -711,8 +739,36 @@ rtems_bsd_cryptof_ioctl(rtems_libio_t *iop, ioctl_command_t request, } #endif /* __rtems__ */ -static int cryptodev_cb(void *); +static int cryptodev_cb(struct cryptop *); + +static struct cryptop_data * +cod_alloc(struct csession *cse, size_t len, struct thread *td) +{ + struct cryptop_data *cod; + struct uio *uio; + + cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO); + + cod->cse = cse; + uio = &cod->uio; + uio->uio_iov = cod->iovec; + uio->uio_iovcnt = 1; + uio->uio_resid = len; + uio->uio_segflg = UIO_SYSSPACE; + uio->uio_rw = UIO_WRITE; + uio->uio_td = td; + uio->uio_iov[0].iov_len = len; + uio->uio_iov[0].iov_base = malloc(len, M_XDATA, M_WAITOK); + return (cod); +} + +static void +cod_free(struct cryptop_data *cod) +{ + free(cod->uio.uio_iov[0].iov_base, M_XDATA); + free(cod, M_XDATA); +} static int cryptodev_op( @@ -721,6 +777,7 @@ cryptodev_op( struct ucred *active_cred, struct thread *td) { + struct cryptop_data *cod = NULL; struct cryptop *crp = NULL; struct cryptodesc *crde = NULL, *crda = NULL; int error; @@ -737,20 +794,10 @@ cryptodev_op( } } - cse->uio.uio_iov = &cse->iovec; - cse->uio.uio_iovcnt = 1; - cse->uio.uio_offset = 0; - cse->uio.uio_resid = cop->len; - cse->uio.uio_segflg = UIO_SYSSPACE; - cse->uio.uio_rw = UIO_WRITE; - cse->uio.uio_td = td; - cse->uio.uio_iov[0].iov_len = cop->len; - if (cse->thash) { - cse->uio.uio_iov[0].iov_len += cse->thash->hashsize; - cse->uio.uio_resid += cse->thash->hashsize; - } - cse->uio.uio_iov[0].iov_base = malloc(cse->uio.uio_iov[0].iov_len, - M_XDATA, M_WAITOK); + if (cse->thash) + cod = cod_alloc(cse, cop->len + cse->thash->hashsize, td); + else + cod = cod_alloc(cse, cop->len, td); crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL)); if (crp == NULL) { @@ -777,7 +824,7 @@ cryptodev_op( goto bail; } - if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, + if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base, cop->len))) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; @@ -809,10 +856,10 @@ cryptodev_op( crp->crp_ilen = cop->len; crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM | (cop->flags & COP_F_BATCH); - crp->crp_buf = (caddr_t)&cse->uio; - crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; + crp->crp_uio = &cod->uio; + crp->crp_callback = cryptodev_cb; crp->crp_sid = cse->sid; - crp->crp_opaque = (void *)cse; + crp->crp_opaque = cod; if (cop->iv) { if (crde == NULL) { @@ -825,12 +872,11 @@ cryptodev_op( error = EINVAL; goto bail; } - if ((error = copyin(cop->iv, cse->tmp_iv, + if ((error = copyin(cop->iv, crde->crd_iv, cse->txform->blocksize))) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } - bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; crde->crd_skip = 0; } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ @@ -856,19 +902,20 @@ again: * entry and the crypto_done callback into us. */ error = crypto_dispatch(crp); - mtx_lock(&cse->lock); - if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) - error = msleep(crp, &cse->lock, PWAIT, "crydev", 0); - mtx_unlock(&cse->lock); - if (error != 0) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } + mtx_lock(&cse->lock); + while (!cod->done) + mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0); + mtx_unlock(&cse->lock); + if (crp->crp_etype == EAGAIN) { crp->crp_etype = 0; crp->crp_flags &= ~CRYPTO_F_DONE; + cod->done = false; goto again; } @@ -878,21 +925,15 @@ again: goto bail; } - if (cse->error) { - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - error = cse->error; - goto bail; - } - if (cop->dst && - (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, + (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst, cop->len))) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } if (cop->mac && - (error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + cop->len, + (error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + cop->len, cop->mac, cse->thash->hashsize))) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; @@ -901,8 +942,8 @@ again: bail: if (crp) crypto_freereq(crp); - if (cse->uio.uio_iov[0].iov_base) - free(cse->uio.uio_iov[0].iov_base, M_XDATA); + if (cod) + cod_free(cod); return (error); } @@ -914,34 +955,29 @@ cryptodev_aead( struct ucred *active_cred, struct thread *td) { - struct uio *uio; + struct cryptop_data *cod = NULL; struct cryptop *crp = NULL; struct cryptodesc *crde = NULL, *crda = NULL; int error; - if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) + if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (E2BIG); + } if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL || - (caead->len % cse->txform->blocksize) != 0) + (caead->len % cse->txform->blocksize) != 0) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); + } - uio = &cse->uio; - uio->uio_iov = &cse->iovec; - uio->uio_iovcnt = 1; - uio->uio_offset = 0; - uio->uio_resid = caead->aadlen + caead->len + cse->thash->hashsize; - uio->uio_segflg = UIO_SYSSPACE; - uio->uio_rw = UIO_WRITE; - uio->uio_td = td; - uio->uio_iov[0].iov_len = uio->uio_resid; - - uio->uio_iov[0].iov_base = malloc(uio->uio_iov[0].iov_len, - M_XDATA, M_WAITOK); + cod = cod_alloc(cse, caead->aadlen + caead->len + cse->thash->hashsize, + td); crp = crypto_getreq(2); if (crp == NULL) { error = ENOMEM; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } @@ -953,13 +989,17 @@ cryptodev_aead( crde = crda->crd_next; } - if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base, - caead->aadlen))) + if ((error = copyin(caead->aad, cod->uio.uio_iov[0].iov_base, + caead->aadlen))) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; + } - if ((error = copyin(caead->src, (char *)cse->uio.uio_iov[0].iov_base + - caead->aadlen, caead->len))) + if ((error = copyin(caead->src, (char *)cod->uio.uio_iov[0].iov_base + + caead->aadlen, caead->len))) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; + } /* * For GCM, crd_len covers only the AAD. For other ciphers @@ -992,20 +1032,22 @@ cryptodev_aead( crp->crp_ilen = caead->aadlen + caead->len; crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH); - crp->crp_buf = (caddr_t)&cse->uio.uio_iov; - crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; + crp->crp_uio = &cod->uio; + crp->crp_callback = cryptodev_cb; crp->crp_sid = cse->sid; - crp->crp_opaque = (void *)cse; + crp->crp_opaque = cod; if (caead->iv) { - if (caead->ivlen > sizeof cse->tmp_iv) { + if (caead->ivlen > sizeof(crde->crd_iv)) { error = EINVAL; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } - if ((error = copyin(caead->iv, cse->tmp_iv, caead->ivlen))) + if ((error = copyin(caead->iv, crde->crd_iv, caead->ivlen))) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; - bcopy(cse->tmp_iv, crde->crd_iv, caead->ivlen); + } crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; } else { crde->crd_flags |= CRD_F_IV_PRESENT; @@ -1013,9 +1055,11 @@ cryptodev_aead( crde->crd_len -= cse->txform->blocksize; } - if ((error = copyin(caead->tag, (caddr_t)cse->uio.uio_iov[0].iov_base + - caead->len + caead->aadlen, cse->thash->hashsize))) + if ((error = copyin(caead->tag, (caddr_t)cod->uio.uio_iov[0].iov_base + + caead->len + caead->aadlen, cse->thash->hashsize))) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; + } again: /* * Let the dispatch run unlocked, then, interlock against the @@ -1025,56 +1069,64 @@ again: * entry and the crypto_done callback into us. */ error = crypto_dispatch(crp); + if (error != 0) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + goto bail; + } + mtx_lock(&cse->lock); - if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) - error = msleep(crp, &cse->lock, PWAIT, "crydev", 0); + while (!cod->done) + mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0); mtx_unlock(&cse->lock); - if (error != 0) - goto bail; - if (crp->crp_etype == EAGAIN) { crp->crp_etype = 0; crp->crp_flags &= ~CRYPTO_F_DONE; + cod->done = false; goto again; } if (crp->crp_etype != 0) { error = crp->crp_etype; - goto bail; - } - - if (cse->error) { - error = cse->error; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } if (caead->dst && (error = copyout( - (caddr_t)cse->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst, - caead->len))) + (caddr_t)cod->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst, + caead->len))) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; + } - if ((error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + - caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) + if ((error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + + caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; + } bail: crypto_freereq(crp); - free(cse->uio.uio_iov[0].iov_base, M_XDATA); + if (cod) + cod_free(cod); return (error); } static int -cryptodev_cb(void *op) +cryptodev_cb(struct cryptop *crp) { - struct cryptop *crp = (struct cryptop *) op; - struct csession *cse = (struct csession *)crp->crp_opaque; + struct cryptop_data *cod = crp->crp_opaque; - mtx_lock(&cse->lock); - cse->error = crp->crp_etype; - wakeup_one(crp); - mtx_unlock(&cse->lock); + /* + * Lock to ensure the wakeup() is not missed by the loops + * waiting on cod->done in cryptodev_op() and + * cryptodev_aead(). + */ + mtx_lock(&cod->cse->lock); + cod->done = true; + mtx_unlock(&cod->cse->lock); + wakeup(cod); return (0); } @@ -1095,6 +1147,7 @@ cryptodev_key(struct crypt_kop *kop) int in, out, size, i; if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EFBIG); } @@ -1104,30 +1157,38 @@ cryptodev_key(struct crypt_kop *kop) case CRK_MOD_EXP: if (in == 3 && out == 1) break; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); case CRK_MOD_EXP_CRT: if (in == 6 && out == 1) break; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); case CRK_DSA_SIGN: if (in == 5 && out == 2) break; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); case CRK_DSA_VERIFY: if (in == 7 && out == 0) break; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); case CRK_DH_COMPUTE_KEY: if (in == 3 && out == 1) break; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); default: + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO); - if (!krp) + if (!krp) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (ENOMEM); + } krp->krp_op = kop->crk_op; krp->krp_status = kop->crk_status; krp->krp_iparams = kop->crk_iparams; @@ -1137,9 +1198,11 @@ cryptodev_key(struct crypt_kop *kop) krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; for (i = 0; i < CRK_MAXPARAM; i++) { - if (kop->crk_param[i].crp_nbits > 65536) + if (kop->crk_param[i].crp_nbits > 65536) { /* Limit is the same as in OpenBSD */ + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto fail; + } krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; } for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { @@ -1150,22 +1213,28 @@ cryptodev_key(struct crypt_kop *kop) if (i >= krp->krp_iparams) continue; error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); - if (error) + if (error) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto fail; + } } error = crypto_kdispatch(krp); - if (error) + if (error) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto fail; + } error = tsleep(krp, PSOCK, "crydev", 0); if (error) { /* XXX can this happen? if so, how do we recover? */ + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto fail; } kop->crk_crid = krp->krp_crid; /* device that did the work */ if (krp->krp_status != 0) { error = krp->krp_status; + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto fail; } @@ -1174,8 +1243,10 @@ cryptodev_key(struct crypt_kop *kop) if (size == 0) continue; error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); - if (error) + if (error) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto fail; + } } fail: diff --git a/freebsd/sys/opencrypto/cryptodev.h b/freebsd/sys/opencrypto/cryptodev.h index cfbda068..f929d10a 100644 --- a/freebsd/sys/opencrypto/cryptodev.h +++ b/freebsd/sys/opencrypto/cryptodev.h @@ -425,8 +425,12 @@ struct cryptop { * if CRYPTO_F_ASYNC flags is set */ - caddr_t crp_buf; /* Data to be processed */ - caddr_t crp_opaque; /* Opaque pointer, passed along */ + union { + caddr_t crp_buf; /* Data to be processed */ + struct mbuf *crp_mbuf; + struct uio *crp_uio; + }; + void * crp_opaque; /* Opaque pointer, passed along */ struct cryptodesc *crp_desc; /* Linked list of processing descriptors */ int (*crp_callback)(struct cryptop *); /* Callback function */ @@ -538,5 +542,6 @@ extern void crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out); extern int crypto_apply(int flags, caddr_t buf, int off, int len, int (*f)(void *, void *, u_int), void *arg); + #endif /* _KERNEL */ #endif /* _CRYPTO_CRYPTO_H_ */ diff --git a/freebsd/sys/opencrypto/cryptosoft.c b/freebsd/sys/opencrypto/cryptosoft.c index f0858b3c..b2828452 100644 --- a/freebsd/sys/opencrypto/cryptosoft.c +++ b/freebsd/sys/opencrypto/cryptosoft.c @@ -609,9 +609,7 @@ swcr_authenc(struct cryptop *crp) bzero(blk, blksz); crypto_copydata(crp->crp_flags, buf, crde->crd_skip + i, len, blk); - if (!(crde->crd_flags & CRD_F_ENCRYPT)) { - exf->decrypt(swe->sw_kschedule, blk); - } + exf->decrypt(swe->sw_kschedule, blk); crypto_copyback(crp->crp_flags, buf, crde->crd_skip + i, len, blk); } @@ -988,7 +986,6 @@ swcr_freesession_locked(device_t dev, u_int64_t tid) struct swcr_data *swd; struct enc_xform *txf; struct auth_hash *axf; - struct comp_algo *cxf; u_int32_t sid = CRYPTO_SESID2LID(tid); if (sid > swcr_sesnum || swcr_sessions == NULL || @@ -1063,7 +1060,7 @@ swcr_freesession_locked(device_t dev, u_int64_t tid) break; case CRYPTO_DEFLATE_COMP: - cxf = swd->sw_cxf; + /* Nothing to do */ break; } diff --git a/freebsd/sys/opencrypto/xform_userland.h b/freebsd/sys/opencrypto/xform_userland.h index 04266dc8..ef4845aa 100644 --- a/freebsd/sys/opencrypto/xform_userland.h +++ b/freebsd/sys/opencrypto/xform_userland.h @@ -34,7 +34,7 @@ #define KMALLOC(size, type, flags) malloc(size, type, flags) #define KFREE(ptr, type) free(ptr, type) #else /* not _KERNEL */ -#ifdef _STAND +#ifdef _STANDALONE #include <stand.h> #else /* !_STAND */ #include <stdlib.h> diff --git a/freebsd/sys/powerpc/include/machine/spr.h b/freebsd/sys/powerpc/include/machine/spr.h index 3e479415..db94753b 100644 --- a/freebsd/sys/powerpc/include/machine/spr.h +++ b/freebsd/sys/powerpc/include/machine/spr.h @@ -199,6 +199,9 @@ #define FSL_E300C3 0x8085 #define FSL_E300C4 0x8086 +#define SPR_LPCR 0x13e /* Logical Partitioning Control */ +#define LPCR_LPES 0x008 /* Bit 60 */ + #define SPR_EPCR 0x133 #define EPCR_EXTGS 0x80000000 #define EPCR_DTLBGS 0x40000000 @@ -673,19 +676,7 @@ #define PMC970N_CYCLES 0xf /* Processor cycles */ #define PMC970N_ICOMP 0x9 /* Instructions completed */ -#if defined(AIM) - -#define SPR_ESR 0x3d4 /* 4.. Exception Syndrome Register */ -#define ESR_MCI 0x80000000 /* Machine check - instruction */ -#define ESR_PIL 0x08000000 /* Program interrupt - illegal */ -#define ESR_PPR 0x04000000 /* Program interrupt - privileged */ -#define ESR_PTR 0x02000000 /* Program interrupt - trap */ -#define ESR_ST 0x01000000 /* Store operation */ -#define ESR_DST 0x00800000 /* Data storage interrupt - store fault */ -#define ESR_DIZ 0x00800000 /* Data/instruction storage interrupt - zone fault */ -#define ESR_U0F 0x00008000 /* Data storage interrupt - U0 fault */ - -#elif defined(BOOKE) +#if defined(BOOKE) #define SPR_MCARU 0x239 /* ..8 Machine Check Address register upper bits */ #define SPR_MCSR 0x23c /* ..8 Machine Check Syndrome register */ diff --git a/freebsd/sys/sys/_domainset.h b/freebsd/sys/sys/_domainset.h new file mode 100644 index 00000000..30d8501c --- /dev/null +++ b/freebsd/sys/sys/_domainset.h @@ -0,0 +1,60 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017, Jeffrey Roberson <jeff@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS__DOMAINSET_H_ +#define _SYS__DOMAINSET_H_ + +#include <sys/_bitset.h> + +#ifdef _KERNEL +#define DOMAINSET_SETSIZE MAXMEMDOM +#endif + +#define DOMAINSET_MAXSIZE 256 + +#ifndef DOMAINSET_SETSIZE +#define DOMAINSET_SETSIZE DOMAINSET_MAXSIZE +#endif + +BITSET_DEFINE(_domainset, DOMAINSET_SETSIZE); +typedef struct _domainset domainset_t; + +/* + * This structure is intended to be embedded in objects which have policy + * attributes. Each object keeps its own iterator so round-robin is + * synchronized and accurate. + */ +struct domainset; +struct domainset_ref { + struct domainset * volatile dr_policy; + int dr_iterator; +}; + +#endif /* !_SYS__DOMAINSET_H_ */ diff --git a/freebsd/sys/sys/bus_dma.h b/freebsd/sys/sys/bus_dma.h index c5799661..2bf46ca8 100644 --- a/freebsd/sys/sys/bus_dma.h +++ b/freebsd/sys/sys/bus_dma.h @@ -1,7 +1,7 @@ /* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ /*- - * SPDX-License-Identifier: BSD-2-Clause-NetBSD + * SPDX-License-Identifier: (BSD-2-Clause-NetBSD AND BSD-4-Clause) * * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -176,6 +176,14 @@ int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, void *lockfuncarg, bus_dma_tag_t *dmat); +/* + * Set the memory domain to be used for allocations. + * + * Automatic for PCI devices. Must be set prior to creating maps or + * allocating memory. + */ +int bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain); + int bus_dma_tag_destroy(bus_dma_tag_t dmat); /* diff --git a/freebsd/sys/sys/capsicum.h b/freebsd/sys/sys/capsicum.h index ae466952..847b4478 100644 --- a/freebsd/sys/sys/capsicum.h +++ b/freebsd/sys/sys/capsicum.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2008-2010, 2015 Robert N. M. Watson * Copyright (c) 2012 FreeBSD Foundation * All rights reserved. diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h index 7f240f68..3980eba2 100644 --- a/freebsd/sys/sys/conf.h +++ b/freebsd/sys/sys/conf.h @@ -367,8 +367,8 @@ struct dumperinfo { off_t mediasize; /* Space available in bytes. */ void *blockbuf; /* Buffer for padding shorter dump blocks */ off_t dumpoff; /* Offset of ongoing kernel dump. */ - struct kerneldumpcrypto *kdc; /* Kernel dump crypto. */ - struct kerneldumpgz *kdgz; /* Kernel dump compression. */ + struct kerneldumpcrypto *kdcrypto; /* Kernel dump crypto. */ + struct kerneldumpcomp *kdcomp; /* Kernel dump compression. */ }; #ifndef __rtems__ diff --git a/freebsd/sys/sys/domainset.h b/freebsd/sys/sys/domainset.h new file mode 100644 index 00000000..6580e1ed --- /dev/null +++ b/freebsd/sys/sys/domainset.h @@ -0,0 +1,102 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017, Jeffrey Roberson <jeff@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS_DOMAINSETSET_H_ +#define _SYS_DOMAINSETSET_H_ + +#include <sys/_domainset.h> + +#include <sys/bitset.h> + +#define _NDOMAINSETBITS _BITSET_BITS +#define _NDOMAINSETWORDS __bitset_words(DOMAINSET_SETSIZE) + +#define DOMAINSETSETBUFSIZ ((2 + sizeof(long) * 2) * _NDOMAINSETWORDS) + +#define DOMAINSET_CLR(n, p) BIT_CLR(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_COPY(f, t) BIT_COPY(DOMAINSET_SETSIZE, f, t) +#define DOMAINSET_ISSET(n, p) BIT_ISSET(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_SET(n, p) BIT_SET(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_ZERO(p) BIT_ZERO(DOMAINSET_SETSIZE, p) +#define DOMAINSET_FILL(p) BIT_FILL(DOMAINSET_SETSIZE, p) +#define DOMAINSET_SETOF(n, p) BIT_SETOF(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_EMPTY(p) BIT_EMPTY(DOMAINSET_SETSIZE, p) +#define DOMAINSET_ISFULLSET(p) BIT_ISFULLSET(DOMAINSET_SETSIZE, p) +#define DOMAINSET_SUBSET(p, c) BIT_SUBSET(DOMAINSET_SETSIZE, p, c) +#define DOMAINSET_OVERLAP(p, c) BIT_OVERLAP(DOMAINSET_SETSIZE, p, c) +#define DOMAINSET_CMP(p, c) BIT_CMP(DOMAINSET_SETSIZE, p, c) +#define DOMAINSET_OR(d, s) BIT_OR(DOMAINSET_SETSIZE, d, s) +#define DOMAINSET_AND(d, s) BIT_AND(DOMAINSET_SETSIZE, d, s) +#define DOMAINSET_NAND(d, s) BIT_NAND(DOMAINSET_SETSIZE, d, s) +#define DOMAINSET_CLR_ATOMIC(n, p) BIT_CLR_ATOMIC(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_SET_ATOMIC(n, p) BIT_SET_ATOMIC(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_SET_ATOMIC_ACQ(n, p) \ + BIT_SET_ATOMIC_ACQ(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_AND_ATOMIC(n, p) BIT_AND_ATOMIC(DOMAINSET_SETSIZE, n, p) +#define DOMAINSET_OR_ATOMIC(d, s) BIT_OR_ATOMIC(DOMAINSET_SETSIZE, d, s) +#define DOMAINSET_COPY_STORE_REL(f, t) \ + BIT_COPY_STORE_REL(DOMAINSET_SETSIZE, f, t) +#define DOMAINSET_FFS(p) BIT_FFS(DOMAINSET_SETSIZE, p) +#define DOMAINSET_FLS(p) BIT_FLS(DOMAINSET_SETSIZE, p) +#define DOMAINSET_COUNT(p) BIT_COUNT(DOMAINSET_SETSIZE, p) +#define DOMAINSET_FSET BITSET_FSET(_NDOMAINSETWORDS) +#define DOMAINSET_T_INITIALIZER BITSET_T_INITIALIZER + +#define DOMAINSET_POLICY_INVALID 0 +#define DOMAINSET_POLICY_ROUNDROBIN 1 +#define DOMAINSET_POLICY_FIRSTTOUCH 2 +#define DOMAINSET_POLICY_PREFER 3 +#define DOMAINSET_POLICY_MAX DOMAINSET_POLICY_PREFER + +#ifdef _KERNEL +#include <sys/queue.h> +LIST_HEAD(domainlist, domainset); + +struct domainset { + LIST_ENTRY(domainset) ds_link; + domainset_t ds_mask; /* allowed domains. */ + uint16_t ds_policy; /* Policy type. */ + int16_t ds_prefer; /* Preferred domain or -1. */ + uint16_t ds_cnt; /* popcnt from above. */ + uint16_t ds_max; /* Maximum domain in set. */ +}; + +void domainset_zero(void); + +#else +__BEGIN_DECLS +int cpuset_getdomain(cpulevel_t, cpuwhich_t, id_t, size_t, domainset_t *, + int *); +int cpuset_setdomain(cpulevel_t, cpuwhich_t, id_t, size_t, + const domainset_t *, int); + +__END_DECLS +#endif +#endif /* !_SYS_DOMAINSETSET_H_ */ diff --git a/freebsd/sys/sys/gtaskqueue.h b/freebsd/sys/sys/gtaskqueue.h index e8519637..41094603 100644 --- a/freebsd/sys/sys/gtaskqueue.h +++ b/freebsd/sys/sys/gtaskqueue.h @@ -1,6 +1,8 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2014 Jeffrey Roberson <jeff@freebsd.org> - * Copyright (c) 2016 Matthew Macy <mmacy@nextbsd.org> + * Copyright (c) 2016 Matthew Macy <mmacy@mattmacy.io> * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/freebsd/sys/sys/kernel.h b/freebsd/sys/sys/kernel.h index 1cc03275..81ceca04 100644 --- a/freebsd/sys/sys/kernel.h +++ b/freebsd/sys/sys/kernel.h @@ -54,6 +54,9 @@ /* for intrhook below */ #include <sys/queue.h> +/* for timestamping SYSINITs; other files may assume this is included here */ +#include <sys/tslog.h> + /* Global variables for the kernel. */ #ifndef __rtems__ @@ -240,6 +243,35 @@ struct sysinit { * correct warnings when -Wcast-qual is used. * */ +#ifdef TSLOG +struct sysinit_tslog { + sysinit_cfunc_t func; + const void * data; + const char * name; +}; +static inline void +sysinit_tslog_shim(const void * data) +{ + const struct sysinit_tslog * x = data; + + TSRAW(curthread, TS_ENTER, "SYSINIT", x->name); + (x->func)(x->data); + TSRAW(curthread, TS_EXIT, "SYSINIT", x->name); +} +#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ + static struct sysinit_tslog uniquifier ## _sys_init_tslog = { \ + func, \ + (ident), \ + #uniquifier \ + }; \ + static struct sysinit uniquifier ## _sys_init = { \ + subsystem, \ + order, \ + sysinit_tslog_shim, \ + &uniquifier ## _sys_init_tslog \ + }; \ + DATA_SET(sysinit_set,uniquifier ## _sys_init) +#else #ifndef __rtems__ #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ static struct sysinit uniquifier ## _sys_init = { \ @@ -274,6 +306,7 @@ struct sysinit { #define SYSINIT_DOMAIN_REFERENCE(dom) \ SYSINIT_REFERENCE(domain_add_ ## dom) #endif /* __rtems__ */ +#endif #define SYSINIT(uniquifier, subsystem, order, func, ident) \ C_SYSINIT(uniquifier, subsystem, order, \ diff --git a/freebsd/sys/sys/libkern.h b/freebsd/sys/sys/libkern.h index 4d043f5a..dc24036b 100644 --- a/freebsd/sys/sys/libkern.h +++ b/freebsd/sys/sys/libkern.h @@ -86,6 +86,13 @@ hex2ascii(int hex) return (hex2ascii_data[hex]); } +static inline bool +validbcd(int bcd) +{ + + return (bcd == 0 || (bcd > 0 && bcd <= 0x99 && bcd2bin_data[bcd] != 0)); +} + static __inline int imax(int a, int b) { return (a > b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline long lmax(long a, long b) { return (a > b ? a : b); } diff --git a/freebsd/sys/sys/malloc.h b/freebsd/sys/sys/malloc.h index c5ab6125..1920ff69 100644 --- a/freebsd/sys/sys/malloc.h +++ b/freebsd/sys/sys/malloc.h @@ -41,6 +41,7 @@ #include <sys/queue.h> #include <sys/_lock.h> #include <sys/_mutex.h> +#include <machine/_limits.h> #define MINALLOCSIZE UMA_SMALLEST_UNIT @@ -156,13 +157,6 @@ MALLOC_DECLARE(M_DEVBUF); MALLOC_DECLARE(M_TEMP); /* - * Deprecated macro versions of not-quite-malloc() and free(). - */ -#define MALLOC(space, cast, size, type, flags) \ - ((space) = (cast)malloc((u_long)(size), (type), (flags))) -#define FREE(addr, type) free((addr), (type)) - -/* * XXX this should be declared in <sys/uio.h>, but that tends to fail * because <sys/uio.h> is included in a header before the source file * has a chance to include <sys/malloc.h> to get MALLOC_DECLARE() defined. @@ -181,21 +175,45 @@ void *contigmalloc(unsigned long size, struct malloc_type *type, int flags, vm_paddr_t low, vm_paddr_t high, unsigned long alignment, vm_paddr_t boundary) __malloc_like __result_use_check __alloc_size(1) __alloc_align(6); +void *contigmalloc_domain(unsigned long size, struct malloc_type *type, + int domain, int flags, vm_paddr_t low, vm_paddr_t high, + unsigned long alignment, vm_paddr_t boundary) + __malloc_like __result_use_check __alloc_size(1) __alloc_align(6); void free(void *addr, struct malloc_type *type); -void *malloc(unsigned long size, struct malloc_type *type, int flags) - __malloc_like __result_use_check __alloc_size(1); +void free_domain(void *addr, struct malloc_type *type); +void *malloc(size_t size, struct malloc_type *type, int flags) __malloc_like + __result_use_check __alloc_size(1); +void *malloc_domain(size_t size, struct malloc_type *type, int domain, + int flags) __malloc_like __result_use_check __alloc_size(1); +void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type, + int flags) __malloc_like __result_use_check + __alloc_size2(1, 2); void malloc_init(void *); int malloc_last_fail(void); void malloc_type_allocated(struct malloc_type *type, unsigned long size); void malloc_type_freed(struct malloc_type *type, unsigned long size); void malloc_type_list(malloc_type_list_func_t *, void *); void malloc_uninit(void *); -void *realloc(void *addr, unsigned long size, struct malloc_type *type, - int flags) __result_use_check __alloc_size(2); -void *reallocf(void *addr, unsigned long size, struct malloc_type *type, - int flags) __alloc_size(2); +void *realloc(void *addr, size_t size, struct malloc_type *type, int flags) + __result_use_check __alloc_size(2); +void *reallocf(void *addr, size_t size, struct malloc_type *type, int flags) + __result_use_check __alloc_size(2); struct malloc_type *malloc_desc2type(const char *desc); + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 8 / 2)) +static inline bool +WOULD_OVERFLOW(size_t nmemb, size_t size) +{ + + return ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && __SIZE_T_MAX / nmemb < size); +} +#undef MUL_NO_OVERFLOW #endif /* _KERNEL */ #endif /* !_SYS_MALLOC_H_ */ diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h index 362c54e9..9d499004 100644 --- a/freebsd/sys/sys/mount.h +++ b/freebsd/sys/sys/mount.h @@ -40,6 +40,7 @@ #ifdef _KERNEL #include <sys/lock.h> #include <sys/lockmgr.h> +#include <sys/tslog.h> #include <sys/_mutex.h> #include <sys/_sx.h> #endif @@ -708,9 +709,11 @@ vfs_statfs_t __vfs_statfs; #define VFS_MOUNT(MP) ({ \ int _rc; \ \ + TSRAW(curthread, TS_ENTER, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\ VFS_PROLOGUE(MP); \ _rc = (*(MP)->mnt_op->vfs_mount)(MP); \ VFS_EPILOGUE(MP); \ + TSRAW(curthread, TS_EXIT, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\ _rc; }) #define VFS_UNMOUNT(MP, FORCE) ({ \ diff --git a/freebsd/sys/sys/mouse.h b/freebsd/sys/sys/mouse.h index 9fd1d6d8..a1f950cf 100644 --- a/freebsd/sys/sys/mouse.h +++ b/freebsd/sys/sys/mouse.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-1-Clause + * * Copyright (c) 1992, 1993 Erik Forsberg. * Copyright (c) 1996, 1997 Kazutaka YOKOTA * All rights reserved. @@ -135,6 +137,7 @@ typedef struct synapticshw { int maximumYCoord; int infoXupmm; int infoYupmm; + int forcePad; } synapticshw_t; /* iftype */ diff --git a/freebsd/sys/sys/nv.h b/freebsd/sys/sys/nv.h index fcea2b3e..bf40f8f3 100644 --- a/freebsd/sys/sys/nv.h +++ b/freebsd/sys/sys/nv.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause + * * Copyright (c) 2009-2013 The FreeBSD Foundation * Copyright (c) 2013-2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h index 7178c316..ab292769 100644 --- a/freebsd/sys/sys/proc.h +++ b/freebsd/sys/sys/proc.h @@ -62,11 +62,18 @@ #include <sys/time.h> /* For structs itimerval, timeval. */ #else #include <sys/pcpu.h> +#include <sys/systm.h> #endif #include <sys/ucontext.h> #include <sys/ucred.h> -#include <sys/_vm_domain.h> +#include <sys/types.h> +#include <sys/domainset.h> + #include <machine/proc.h> /* Machine-dependent proc substruct. */ +#ifdef _KERNEL +#include <machine/cpu.h> +#endif + /* * One structure allocated per session. @@ -179,11 +186,14 @@ struct procdesc; struct racct; struct sbuf; struct sleepqueue; +struct socket; struct syscall_args; struct td_sched; struct thread; struct trapframe; struct turnstile; +struct vm_map; +struct vm_map_entry; /* * XXX: Does this belong in resource.h or resourcevar.h instead? @@ -239,6 +249,7 @@ struct thread { TAILQ_ENTRY(thread) td_lockq; /* (t) Lock queue. */ LIST_ENTRY(thread) td_hash; /* (d) Hash chain. */ struct cpuset *td_cpuset; /* (t) CPU affinity mask. */ + struct domainset_ref td_domain; /* (a) NUMA policy */ #endif /* __rtems__ */ struct seltd *td_sel; /* Select queue/channel. */ struct sleepqueue *td_sleepqueue; /* (k) Associated sleep queue. */ @@ -246,7 +257,6 @@ struct thread { struct turnstile *td_turnstile; /* (k) Associated turnstile. */ struct rl_q_entry *td_rlqe; /* (k) Associated range lock entry. */ struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */ - struct vm_domain_policy td_vm_dom_policy; /* (c) current numa domain policy */ lwpid_t td_tid; /* (b) Thread ID. */ sigqueue_t td_sigqueue; /* (c) Sigs arrived, not delivered. */ #define td_siglist td_sigqueue.sq_signals @@ -315,7 +325,6 @@ struct thread { pid_t td_dbg_forked; /* (c) Child pid for debugger. */ u_int td_vp_reserv; /* (k) Count of reserved vnodes. */ int td_no_sleeping; /* (k) Sleeping disabled count. */ - int td_dom_rr_idx; /* (k) RR Numa domain selection. */ void *td_su; /* (k) FFS SU private */ sbintime_t td_sleeptimo; /* (t) Sleep timeout. */ int td_rtcgen; /* (s) rtc_generation of abs. sleep */ @@ -698,7 +707,6 @@ struct proc { uint64_t p_prev_runtime; /* (c) Resource usage accounting. */ struct racct *p_racct; /* (b) Resource accounting. */ int p_throttled; /* (c) Flag for racct pcpu throttling */ - struct vm_domain_policy p_vm_dom_policy; /* (c) process default VM domain, or -1 */ /* * An orphan is the child that has beed re-parented to the * debugger as a result of attaching to it. Need to keep @@ -1060,6 +1068,8 @@ void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); void fork_return(struct thread *, struct trapframe *); int inferior(struct proc *p); +void kern_proc_vmmap_resident(struct vm_map *map, struct vm_map_entry *entry, + int *resident_count, bool *super); #ifndef __rtems__ void kern_yield(int); void kick_proc0(void); diff --git a/freebsd/sys/sys/random.h b/freebsd/sys/sys/random.h index b022f5a3..78acaf9d 100644 --- a/freebsd/sys/sys/random.h +++ b/freebsd/sys/sys/random.h @@ -104,6 +104,7 @@ enum random_entropy_source { RANDOM_PURE_RNDTEST, RANDOM_PURE_VIRTIO, RANDOM_PURE_BROADCOM, + RANDOM_PURE_CCP, ENTROPYSOURCE }; diff --git a/freebsd/sys/sys/rman.h b/freebsd/sys/sys/rman.h index 4de6022f..9c2f4653 100644 --- a/freebsd/sys/sys/rman.h +++ b/freebsd/sys/sys/rman.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: MIT + * * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and diff --git a/freebsd/sys/sys/sf_buf.h b/freebsd/sys/sys/sf_buf.h index 08f1d9d7..b4ea671a 100644 --- a/freebsd/sys/sys/sf_buf.h +++ b/freebsd/sys/sys/sf_buf.h @@ -77,9 +77,6 @@ struct sfstat { /* sendfile statistics */ * that do no invalidate cache on the rest of CPUs. * SFBUF_NOMD This machine doesn't have machine/sf_buf.h * - * SFBUF_OPTIONAL_DIRECT_MAP Value of this define is used as boolean - * variable that tells whether machine is - * capable of direct map or not at runtime. * SFBUF_MAP This machine provides its own sf_buf_map() and * sf_buf_unmap(). * SFBUF_PROCESS_PAGE This machine provides sf_buf_process_page() @@ -109,9 +106,6 @@ struct sf_buf; #ifndef SFBUF_NOMD #include <machine/sf_buf.h> #endif -#ifdef SFBUF_OPTIONAL_DIRECT_MAP -#include <machine/md_var.h> -#endif #ifdef SFBUF struct sf_buf *sf_buf_alloc(struct vm_page *, int); @@ -121,10 +115,8 @@ void sf_buf_ref(struct sf_buf *); static inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { -#ifdef SFBUF_OPTIONAL_DIRECT_MAP - if (SFBUF_OPTIONAL_DIRECT_MAP) - return (SFBUF_PHYS_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf))); -#endif + if (PMAP_HAS_DMAP) + return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf))); return (sf->kva); } @@ -132,10 +124,8 @@ sf_buf_kva(struct sf_buf *sf) static inline vm_page_t sf_buf_page(struct sf_buf *sf) { -#ifdef SFBUF_OPTIONAL_DIRECT_MAP - if (SFBUF_OPTIONAL_DIRECT_MAP) + if (PMAP_HAS_DMAP) return ((vm_page_t)sf); -#endif return (sf->m); } diff --git a/freebsd/sys/sys/smp.h b/freebsd/sys/sys/smp.h index f1950fa2..aa0c3119 100644 --- a/freebsd/sys/sys/smp.h +++ b/freebsd/sys/sys/smp.h @@ -155,10 +155,13 @@ struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu); extern void (*cpustop_restartfunc)(void); extern int smp_cpus; -extern volatile cpuset_t started_cpus; -extern volatile cpuset_t stopped_cpus; -extern volatile cpuset_t suspended_cpus; -extern cpuset_t hlt_cpus_mask; +/* The suspend/resume cpusets are x86 only, but minimize ifdefs. */ +extern volatile cpuset_t resuming_cpus; /* woken up cpus in suspend pen */ +extern volatile cpuset_t started_cpus; /* cpus to let out of stop pen */ +extern volatile cpuset_t stopped_cpus; /* cpus in stop pen */ +extern volatile cpuset_t suspended_cpus; /* cpus [near] sleeping in susp pen */ +extern volatile cpuset_t toresume_cpus; /* cpus to let out of suspend pen */ +extern cpuset_t hlt_cpus_mask; /* XXX 'mask' is detail in old impl */ extern cpuset_t logical_cpus_mask; #endif /* SMP */ diff --git a/freebsd/sys/sys/socketvar.h b/freebsd/sys/sys/socketvar.h index d58ac2ea..f877a0df 100644 --- a/freebsd/sys/sys/socketvar.h +++ b/freebsd/sys/sys/socketvar.h @@ -71,7 +71,7 @@ struct socket; * (a) constant after allocation, no locking required. * (b) locked by SOCK_LOCK(so). * (cr) locked by SOCKBUF_LOCK(&so->so_rcv). - * (cs) locked by SOCKBUF_LOCK(&so->so_rcv). + * (cs) locked by SOCKBUF_LOCK(&so->so_snd). * (e) locked by SOLISTEN_LOCK() of corresponding listening socket. * (f) not locked since integer reads/writes are atomic. * (g) used only as a sleep/wakeup address, no value. diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index d5cda835..9148a395 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -11,6 +11,7 @@ #include <sys/signal.h> #include <sys/acl.h> #include <sys/cpuset.h> +#include <sys/domainset.h> #include <sys/_ffcounter.h> #include <sys/_semaphore.h> #include <sys/ucontext.h> @@ -1738,16 +1739,6 @@ struct utimensat_args { char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)]; char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; }; -struct numa_getaffinity_args { - char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)]; - char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; - char policy_l_[PADL_(struct vm_domain_policy_entry *)]; struct vm_domain_policy_entry * policy; char policy_r_[PADR_(struct vm_domain_policy_entry *)]; -}; -struct numa_setaffinity_args { - char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)]; - char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; - char policy_l_[PADL_(const struct vm_domain_policy_entry *)]; const struct vm_domain_policy_entry * policy; char policy_r_[PADR_(const struct vm_domain_policy_entry *)]; -}; struct fdatasync_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; }; @@ -1808,6 +1799,22 @@ struct kevent_args { char timeout_l_[PADL_(const struct timespec *)]; const struct timespec * timeout; char timeout_r_[PADR_(const struct timespec *)]; }; #ifndef __rtems__ +struct cpuset_getdomain_args { + char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)]; + char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)]; + char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; + char domainsetsize_l_[PADL_(size_t)]; size_t domainsetsize; char domainsetsize_r_[PADR_(size_t)]; + char mask_l_[PADL_(domainset_t *)]; domainset_t * mask; char mask_r_[PADR_(domainset_t *)]; + char policy_l_[PADL_(int *)]; int * policy; char policy_r_[PADR_(int *)]; +}; +struct cpuset_setdomain_args { + char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)]; + char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)]; + char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; + char domainsetsize_l_[PADL_(size_t)]; size_t domainsetsize; char domainsetsize_r_[PADR_(size_t)]; + char mask_l_[PADL_(domainset_t *)]; domainset_t * mask; char mask_r_[PADR_(domainset_t *)]; + char policy_l_[PADL_(int)]; int policy; char policy_r_[PADR_(int)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *); int sys_fork(struct thread *, struct fork_args *); @@ -2175,8 +2182,6 @@ int sys_procctl(struct thread *, struct procctl_args *); int sys_ppoll(struct thread *, struct ppoll_args *); int sys_futimens(struct thread *, struct futimens_args *); int sys_utimensat(struct thread *, struct utimensat_args *); -int sys_numa_getaffinity(struct thread *, struct numa_getaffinity_args *); -int sys_numa_setaffinity(struct thread *, struct numa_setaffinity_args *); int sys_fdatasync(struct thread *, struct fdatasync_args *); int sys_fstat(struct thread *, struct fstat_args *); int sys_fstatat(struct thread *, struct fstatat_args *); @@ -2188,6 +2193,8 @@ int sys_getfsstat(struct thread *, struct getfsstat_args *); int sys_fhstatfs(struct thread *, struct fhstatfs_args *); int sys_mknodat(struct thread *, struct mknodat_args *); int sys_kevent(struct thread *, struct kevent_args *); +int sys_cpuset_getdomain(struct thread *, struct cpuset_getdomain_args *); +int sys_cpuset_setdomain(struct thread *, struct cpuset_setdomain_args *); #ifdef COMPAT_43 @@ -3067,8 +3074,6 @@ int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *); #define SYS_AUE_ppoll AUE_POLL #define SYS_AUE_futimens AUE_FUTIMES #define SYS_AUE_utimensat AUE_FUTIMESAT -#define SYS_AUE_numa_getaffinity AUE_NULL -#define SYS_AUE_numa_setaffinity AUE_NULL #define SYS_AUE_fdatasync AUE_FSYNC #define SYS_AUE_fstat AUE_FSTAT #define SYS_AUE_fstatat AUE_FSTATAT @@ -3080,6 +3085,8 @@ int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *); #define SYS_AUE_fhstatfs AUE_FHSTATFS #define SYS_AUE_mknodat AUE_MKNODAT #define SYS_AUE_kevent AUE_KEVENT +#define SYS_AUE_cpuset_getdomain AUE_NULL +#define SYS_AUE_cpuset_setdomain AUE_NULL #endif /* __rtems__ */ #undef PAD_ diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h index e89719b8..2dfe959b 100644 --- a/freebsd/sys/sys/systm.h +++ b/freebsd/sys/sys/systm.h @@ -610,6 +610,22 @@ void intr_prof_stack_use(struct thread *td, struct trapframe *frame); void counted_warning(unsigned *counter, const char *msg); +/* + * APIs to manage deprecation and obsolescence. + */ +struct device; +void _gone_in(int major, const char *msg); +void _gone_in_dev(struct device *dev, int major, const char *msg); +#ifdef NO_OBSOLETE_CODE +#define __gone_ok(m, msg) \ + _Static_assert(m < P_OSREL_MAJOR(__FreeBSD_version)), \ + "Obsolete code" msg); +#else +#define __gone_ok(m, msg) +#endif +#define gone_in(major, msg) __gone_ok(major, msg) _gone_in(major, msg) +#define gone_in_dev(dev, major, msg) __gone_ok(major, msg) _gone_in_dev(dev, major, msg) + __NULLABILITY_PRAGMA_POP #endif /* !_SYS_SYSTM_H_ */ diff --git a/freebsd/sys/sys/tslog.h b/freebsd/sys/sys/tslog.h new file mode 100644 index 00000000..4b2971e4 --- /dev/null +++ b/freebsd/sys/sys/tslog.h @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2017 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _TSLOG_H_ +#define _TSLOG_H_ + +#ifdef TSLOG +#include <sys/_types.h> +#include <sys/pcpu.h> +#endif + +#define TS_ENTER 0 +#define TS_EXIT 1 +#define TS_THREAD 2 +#define TS_EVENT 3 + +#define TSENTER() TSRAW(curthread, TS_ENTER, __func__, NULL) +#define TSENTER2(x) TSRAW(curthread, TS_ENTER, __func__, x) +#define TSEXIT() TSRAW(curthread, TS_EXIT, __func__, NULL) +#define TSEXIT2(x) TSRAW(curthread, TS_EXIT, __func__, x) +#define TSTHREAD(td, x) TSRAW(td, TS_THREAD, x, NULL) +#define TSEVENT(x) TSRAW(curthread, TS_EVENT, x, NULL) +#define TSEVENT2(x, y) TSRAW(curthread, TS_EVENT, x, y) +#define TSLINE() TSEVENT2(__FILE__, __XSTRING(__LINE__)) +#define TSWAIT(x) TSEVENT2("WAIT", x); +#define TSUNWAIT(x) TSEVENT2("UNWAIT", x); +#define TSHOLD(x) TSEVENT2("HOLD", x); +#define TSRELEASE(x) TSEVENT2("RELEASE", x); + +#ifdef TSLOG +#define TSRAW(a, b, c, d) tslog(a, b, c, d) +void tslog(void *, int, const char *, const char *); +#else +#define TSRAW(a, b, c, d) /* Timestamp logging disabled */ +#endif + +#endif /* _TSLOG_H_ */ diff --git a/freebsd/sys/sys/vmmeter.h b/freebsd/sys/sys/vmmeter.h index 33d96b26..901604ae 100644 --- a/freebsd/sys/sys/vmmeter.h +++ b/freebsd/sys/sys/vmmeter.h @@ -41,7 +41,6 @@ */ #define MAXSLP 20 -/* Systemwide totals computed every five seconds. */ struct vmtotal { uint64_t t_vm; /* total virtual memory */ uint64_t t_avm; /* active virtual memory */ @@ -53,12 +52,12 @@ struct vmtotal { uint64_t t_armshr; /* active shared real memory */ uint64_t t_free; /* free memory pages */ int16_t t_rq; /* length of the run queue */ - int16_t t_dw; /* jobs in ``disk wait'' (neg + int16_t t_dw; /* threads in ``disk wait'' (neg priority) */ - int16_t t_pw; /* jobs in page wait */ - int16_t t_sl; /* jobs sleeping in core */ + int16_t t_pw; /* threads in page wait */ + int16_t t_sl; /* threads sleeping in core */ int16_t t_sw; /* swapped out runnable/short - block jobs */ + block threads */ uint16_t t_pad[3]; }; diff --git a/freebsd/sys/sys/watchdog.h b/freebsd/sys/sys/watchdog.h index 1b85ce7a..191456a4 100644 --- a/freebsd/sys/sys/watchdog.h +++ b/freebsd/sys/sys/watchdog.h @@ -112,6 +112,14 @@ EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn); u_int wdog_kern_last_timeout(void); int wdog_kern_pat(u_int utim); + +/* + * The following function pointer is used to attach a software watchdog + * if no hardware watchdog has been attached, and if the software module + * has initialized the function pointer. + */ + +extern void (*wdog_software_attach)(void); #endif #endif /* _SYS_WATCHDOG_H */ diff --git a/freebsd/sys/vm/uma.h b/freebsd/sys/vm/uma.h index 6fbe6588..2f80a448 100644 --- a/freebsd/sys/vm/uma.h +++ b/freebsd/sys/vm/uma.h @@ -128,7 +128,8 @@ typedef void (*uma_fini)(void *mem, int size); /* * Import new memory into a cache zone. */ -typedef int (*uma_import)(void *arg, void **store, int count, int flags); +typedef int (*uma_import)(void *arg, void **store, int count, int domain, + int flags); /* * Free memory from a cache zone. @@ -281,6 +282,10 @@ uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, * Allocates mp_maxid + 1 slabs sized to * sizeof(struct pcpu). */ +#define UMA_ZONE_NUMA 0x10000 /* + * NUMA aware Zone. Implements a best + * effort first-touch policy. + */ /* * These flags are shared between the keg and zone. In zones wishing to add @@ -326,6 +331,19 @@ void uma_zdestroy(uma_zone_t zone); void *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags); /* + * Allocate an item from a specific NUMA domain. This uses a slow path in + * the allocator but is guaranteed to allocate memory from the requested + * domain if M_WAITOK is set. + * + * Arguments: + * zone The zone we are allocating from + * arg This data is passed to the ctor function + * domain The domain to allocate from. + * flags See sys/malloc.h for available flags. + */ +void *uma_zalloc_domain(uma_zone_t zone, void *arg, int domain, int flags); + +/* * Allocates an item out of a zone without supplying an argument * * This is just a wrapper for uma_zalloc_arg for convenience. @@ -354,6 +372,16 @@ uma_zalloc(uma_zone_t zone, int flags) void uma_zfree_arg(uma_zone_t zone, void *item, void *arg); /* + * Frees an item back to the specified zone's domain specific pool. + * + * Arguments: + * zone The zone the item was originally allocated out of. + * item The memory to be freed. + * arg Argument passed to the destructor + */ +void uma_zfree_domain(uma_zone_t zone, void *item, void *arg); + +/* * Frees an item back to a zone without supplying an argument * * This is just a wrapper for uma_zfree_arg for convenience. @@ -373,25 +401,21 @@ uma_zfree(uma_zone_t zone, void *item) void uma_zwait(uma_zone_t zone); /* - * XXX The rest of the prototypes in this header are h0h0 magic for the VM. - * If you think you need to use it for a normal zone you're probably incorrect. - */ - -/* * Backend page supplier routines * * Arguments: * zone The zone that is requesting pages. * size The number of bytes being requested. * pflag Flags for these memory pages, see below. + * domain The NUMA domain that we prefer for this allocation. * wait Indicates our willingness to block. * * Returns: * A pointer to the allocated memory or NULL on failure. */ -typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag, - int wait); +typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, int domain, + uint8_t *pflag, int wait); /* * Backend page free routines @@ -406,8 +430,6 @@ typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag, */ typedef void (*uma_free)(void *item, vm_size_t size, uint8_t pflag); - - /* * Sets up the uma allocator. (Called by vm_mem_init) * @@ -702,6 +724,14 @@ struct uma_percpu_stat { void uma_reclaim_wakeup(void); void uma_reclaim_worker(void *); +unsigned long uma_limit(void); + +/* Return the amount of memory managed by UMA. */ +unsigned long uma_size(void); + +/* Return the amount of memory remaining. May be negative. */ +long uma_avail(void); + #ifdef __rtems__ void rtems_uma_drain_timeout(void); #endif /* __rtems__ */ diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c index 3d4abec0..a1c45c93 100644 --- a/freebsd/sys/vm/uma_core.c +++ b/freebsd/sys/vm/uma_core.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include <sys/eventhandler.h> #include <sys/kernel.h> #include <sys/types.h> +#include <sys/limits.h> #include <sys/queue.h> #include <sys/malloc.h> #include <sys/ktr.h> @@ -84,6 +85,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_page.h> #include <vm/vm_pageout.h> #include <vm/vm_param.h> +#include <vm/vm_phys.h> #include <vm/vm_map.h> #include <vm/vm_kern.h> #include <vm/vm_extern.h> @@ -93,21 +95,28 @@ __FBSDID("$FreeBSD$"); #include <ddb/ddb.h> #ifdef __rtems__ - #include <rtems/bsd/bsd.h> - - #ifdef RTEMS_SMP - #include <rtems/score/smp.h> - - /* - * It is essential that we have a per-processor cache, otherwise the - * critical_enter()/critical_exit() protection would be insufficient. - */ - #undef curcpu - #define curcpu _SMP_Get_current_processor() - #undef mp_maxid - #define mp_maxid (rtems_get_processor_count() - 1) - #define SMP - #endif +#include <rtems/bsd/bsd.h> +#include <rtems/malloc.h> +#include <rtems.h> + +#undef CACHE_LINE_SIZE +#define CACHE_LINE_SIZE CPU_CACHE_LINE_BYTES + +#ifdef RTEMS_SMP +#include <rtems/score/smp.h> + +/* +* It is essential that we have a per-processor cache, otherwise the +* critical_enter()/critical_exit() protection would be insufficient. +*/ +#undef curcpu +#define curcpu _SMP_Get_current_processor() +#undef mp_maxid +#define mp_maxid (rtems_get_processor_count() - 1) +#undef mp_ncpus +#define mp_ncpus rtems_get_processor_count() +#define SMP +#endif /* RTEMS_SMP */ #endif /* __rtems__ */ #ifdef DEBUG_MEMGUARD @@ -115,17 +124,12 @@ __FBSDID("$FreeBSD$"); #endif /* - * This is the zone and keg from which all zones are spawned. The idea is that - * even the zone & keg heads are allocated from the allocator, so we use the - * bss section to bootstrap us. + * This is the zone and keg from which all zones are spawned. */ -static struct uma_keg masterkeg; -static struct uma_zone masterzone_k; -static struct uma_zone masterzone_z; -static uma_zone_t kegs = &masterzone_k; -static uma_zone_t zones = &masterzone_z; +static uma_zone_t kegs; +static uma_zone_t zones; -/* This is the zone from which all of uma_slab_t's are allocated. */ +/* This is the zone from which all offpage uma_slab_ts are allocated. */ static uma_zone_t slabzone; /* @@ -173,7 +177,7 @@ static struct mtx uma_boot_pages_mtx; static struct sx uma_drain_lock; /* kmem soft limit. */ -static unsigned long uma_kmem_limit; +static unsigned long uma_kmem_limit = LONG_MAX; static volatile unsigned long uma_kmem_total; #ifndef __rtems__ @@ -258,17 +262,19 @@ struct uma_bucket_zone bucket_zones[] = { */ enum zfreeskip { SKIP_NONE = 0, SKIP_DTOR, SKIP_FINI }; +#define UMA_ANYDOMAIN -1 /* Special value for domain search. */ + /* Prototypes.. */ #ifndef __rtems__ -static void *noobj_alloc(uma_zone_t, vm_size_t, uint8_t *, int); +static void *noobj_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int); #endif /* __rtems__ */ -static void *page_alloc(uma_zone_t, vm_size_t, uint8_t *, int); +static void *page_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int); #ifndef __rtems__ -static void *startup_alloc(uma_zone_t, vm_size_t, uint8_t *, int); +static void *startup_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int); #endif /* __rtems__ */ static void page_free(void *, vm_size_t, uint8_t); -static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int); +static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int, int); static void cache_drain(uma_zone_t); static void bucket_drain(uma_zone_t, uma_bucket_t); static void bucket_cache_drain(uma_zone_t zone); @@ -286,25 +292,25 @@ static int hash_expand(struct uma_hash *, struct uma_hash *); static void hash_free(struct uma_hash *hash); static void uma_timeout(void *); static void uma_startup3(void); -static void *zone_alloc_item(uma_zone_t, void *, int); +static void *zone_alloc_item(uma_zone_t, void *, int, int); static void zone_free_item(uma_zone_t, void *, void *, enum zfreeskip); static void bucket_enable(void); static void bucket_init(void); static uma_bucket_t bucket_alloc(uma_zone_t zone, void *, int); static void bucket_free(uma_zone_t zone, uma_bucket_t, void *); static void bucket_zone_drain(void); -static uma_bucket_t zone_alloc_bucket(uma_zone_t zone, void *, int flags); -static uma_slab_t zone_fetch_slab(uma_zone_t zone, uma_keg_t last, int flags); +static uma_bucket_t zone_alloc_bucket(uma_zone_t, void *, int, int); +static uma_slab_t zone_fetch_slab(uma_zone_t, uma_keg_t, int, int); #ifndef __rtems__ -static uma_slab_t zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int flags); +static uma_slab_t zone_fetch_slab_multi(uma_zone_t, uma_keg_t, int, int); #endif /* __rtems__ */ static void *slab_alloc_item(uma_keg_t keg, uma_slab_t slab); static void slab_free_item(uma_keg_t keg, uma_slab_t slab, void *item); static uma_keg_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini, int align, uint32_t flags); -static int zone_import(uma_zone_t zone, void **bucket, int max, int flags); -static void zone_release(uma_zone_t zone, void **bucket, int cnt); -static void uma_zero_item(void *item, uma_zone_t zone); +static int zone_import(uma_zone_t, void **, int, int, int); +static void zone_release(uma_zone_t, void **, int); +static void uma_zero_item(void *, uma_zone_t); void uma_print_zone(uma_zone_t); void uma_print_stats(void); @@ -372,7 +378,7 @@ bucket_init(void) size += sizeof(void *) * ubz->ubz_entries; ubz->ubz_zone = uma_zcreate(ubz->ubz_name, size, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, - UMA_ZONE_MTXCLASS | UMA_ZFLAG_BUCKET); + UMA_ZONE_MTXCLASS | UMA_ZFLAG_BUCKET | UMA_ZONE_NUMA); } } @@ -612,7 +618,7 @@ hash_alloc(struct uma_hash *hash) } else { alloc = sizeof(hash->uh_slab_hash[0]) * UMA_HASH_SIZE_INIT; hash->uh_slab_hash = zone_alloc_item(hashzone, NULL, - M_WAITOK); + UMA_ANYDOMAIN, M_WAITOK); hash->uh_hashsize = UMA_HASH_SIZE_INIT; } if (hash->uh_slab_hash) { @@ -779,6 +785,7 @@ cache_drain_safe_cpu(uma_zone_t zone) { uma_cache_t cache; uma_bucket_t b1, b2; + int domain; if (zone->uz_flags & UMA_ZFLAG_INTERNAL) return; @@ -786,10 +793,14 @@ cache_drain_safe_cpu(uma_zone_t zone) b1 = b2 = NULL; ZONE_LOCK(zone); critical_enter(); + if (zone->uz_flags & UMA_ZONE_NUMA) + domain = PCPU_GET(domain); + else + domain = 0; cache = &zone->uz_cpu[curcpu]; if (cache->uc_allocbucket) { if (cache->uc_allocbucket->ub_cnt != 0) - LIST_INSERT_HEAD(&zone->uz_buckets, + LIST_INSERT_HEAD(&zone->uz_domain[domain].uzd_buckets, cache->uc_allocbucket, ub_link); else b1 = cache->uc_allocbucket; @@ -797,7 +808,7 @@ cache_drain_safe_cpu(uma_zone_t zone) } if (cache->uc_freebucket) { if (cache->uc_freebucket->ub_cnt != 0) - LIST_INSERT_HEAD(&zone->uz_buckets, + LIST_INSERT_HEAD(&zone->uz_domain[domain].uzd_buckets, cache->uc_freebucket, ub_link); else b2 = cache->uc_freebucket; @@ -853,18 +864,22 @@ cache_drain_safe(uma_zone_t zone) static void bucket_cache_drain(uma_zone_t zone) { + uma_zone_domain_t zdom; uma_bucket_t bucket; + int i; /* - * Drain the bucket queues and free the buckets, we just keep two per - * cpu (alloc/free). + * Drain the bucket queues and free the buckets. */ - while ((bucket = LIST_FIRST(&zone->uz_buckets)) != NULL) { - LIST_REMOVE(bucket, ub_link); - ZONE_UNLOCK(zone); - bucket_drain(zone, bucket); - bucket_free(zone, bucket, NULL); - ZONE_LOCK(zone); + for (i = 0; i < vm_ndomains; i++) { + zdom = &zone->uz_domain[i]; + while ((bucket = LIST_FIRST(&zdom->uzd_buckets)) != NULL) { + LIST_REMOVE(bucket, ub_link); + ZONE_UNLOCK(zone); + bucket_drain(zone, bucket); + bucket_free(zone, bucket, NULL); + ZONE_LOCK(zone); + } } /* @@ -909,7 +924,9 @@ static void keg_drain(uma_keg_t keg) { struct slabhead freeslabs = { 0 }; + uma_domain_t dom; uma_slab_t slab, tmp; + int i; /* * We don't want to take pages from statically allocated kegs at this @@ -924,22 +941,27 @@ keg_drain(uma_keg_t keg) if (keg->uk_free == 0) goto finished; - LIST_FOREACH_SAFE(slab, &keg->uk_free_slab, us_link, tmp) { + for (i = 0; i < vm_ndomains; i++) { + dom = &keg->uk_domain[i]; + LIST_FOREACH_SAFE(slab, &dom->ud_free_slab, us_link, tmp) { #ifndef __rtems__ - /* We have nowhere to free these to. */ - if (slab->us_flags & UMA_SLAB_BOOT) - continue; + /* We have nowhere to free these to. */ + if (slab->us_flags & UMA_SLAB_BOOT) + continue; #endif /* __rtems__ */ - LIST_REMOVE(slab, us_link); - keg->uk_pages -= keg->uk_ppera; - keg->uk_free -= keg->uk_ipers; + LIST_REMOVE(slab, us_link); + keg->uk_pages -= keg->uk_ppera; + keg->uk_free -= keg->uk_ipers; - if (keg->uk_flags & UMA_ZONE_HASH) - UMA_HASH_REMOVE(&keg->uk_hash, slab, slab->us_data); + if (keg->uk_flags & UMA_ZONE_HASH) + UMA_HASH_REMOVE(&keg->uk_hash, slab, + slab->us_data); - SLIST_INSERT_HEAD(&freeslabs, slab, us_hlink); + SLIST_INSERT_HEAD(&freeslabs, slab, us_hlink); + } } + finished: KEG_UNLOCK(keg); @@ -999,7 +1021,7 @@ zone_drain(uma_zone_t zone) * caller specified M_NOWAIT. */ static uma_slab_t -keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait) +keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int domain, int wait) { uma_alloc allocf; uma_slab_t slab; @@ -1008,6 +1030,8 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait) uint8_t flags; int i; + KASSERT(domain >= 0 && domain < vm_ndomains, + ("keg_alloc_slab: domain %d out of range", domain)); mtx_assert(&keg->uk_lock, MA_OWNED); slab = NULL; mem = NULL; @@ -1017,7 +1041,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait) size = keg->uk_ppera * PAGE_SIZE; if (keg->uk_flags & UMA_ZONE_OFFPAGE) { - slab = zone_alloc_item(keg->uk_slabzone, NULL, wait); + slab = zone_alloc_item(keg->uk_slabzone, NULL, domain, wait); if (slab == NULL) goto out; } @@ -1038,7 +1062,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait) wait |= M_NODUMP; /* zone is passed for legacy reasons. */ - mem = allocf(zone, size, &flags, wait); + mem = allocf(zone, size, domain, &flags, wait); if (mem == NULL) { if (keg->uk_flags & UMA_ZONE_OFFPAGE) zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE); @@ -1059,6 +1083,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait) slab->us_data = mem; slab->us_freecount = keg->uk_ipers; slab->us_flags = flags; + slab->us_domain = domain; BIT_FILL(SLAB_SETSIZE, &slab->us_free); #ifdef INVARIANTS BIT_ZERO(SLAB_SETSIZE, &slab->us_debugfree); @@ -1099,7 +1124,8 @@ out: * the VM is ready. */ static void * -startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait) +startup_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag, + int wait) { uma_keg_t keg; void *mem; @@ -1132,7 +1158,7 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait) #else keg->uk_allocf = page_alloc; #endif - return keg->uk_allocf(zone, bytes, pflag, wait); + return keg->uk_allocf(zone, bytes, domain, pflag, wait); } #endif /* __rtems__ */ @@ -1148,13 +1174,14 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait) * NULL if M_NOWAIT is set. */ static void * -page_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait) +page_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag, + int wait) { void *p; /* Returned page */ #ifndef __rtems__ *pflag = UMA_SLAB_KERNEL; - p = (void *) kmem_malloc(kernel_arena, bytes, wait); + p = (void *) kmem_malloc_domain(domain, bytes, wait); #else /* __rtems__ */ *pflag = 0; p = rtems_bsd_page_alloc(bytes, wait); @@ -1176,7 +1203,8 @@ page_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, int wait) * NULL if M_NOWAIT is set. */ static void * -noobj_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait) +noobj_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *flags, + int wait) { TAILQ_HEAD(, vm_page) alloctail; u_long npages; @@ -1189,7 +1217,7 @@ noobj_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *flags, int wait) npages = howmany(bytes, PAGE_SIZE); while (npages > 0) { - p = vm_page_alloc(NULL, 0, VM_ALLOC_INTERRUPT | + p = vm_page_alloc_domain(NULL, 0, domain, VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ | ((wait & M_WAITOK) != 0 ? VM_ALLOC_WAITOK : VM_ALLOC_NOWAIT)); @@ -1469,6 +1497,7 @@ keg_ctor(void *mem, int size, void *udata, int flags) keg->uk_init = arg->uminit; keg->uk_fini = arg->fini; keg->uk_align = arg->align; + keg->uk_cursor = 0; keg->uk_free = 0; keg->uk_reserve = 0; keg->uk_pages = 0; @@ -1614,6 +1643,8 @@ zone_ctor(void *mem, int size, void *udata, int flags) zone->uz_count_min = 0; zone->uz_flags = 0; zone->uz_warning = NULL; + /* The domain structures follow the cpu structures. */ + zone->uz_domain = (struct uma_zone_domain *)&zone->uz_cpu[mp_ncpus]; timevalclear(&zone->uz_ratecheck); keg = arg->keg; @@ -1819,22 +1850,60 @@ void uma_startup(void *mem, int npages) { struct uma_zctor_args args; + uma_keg_t masterkeg; + uintptr_t m; +#ifndef __rtems__ + int zsize; + int ksize; +#else /* __rtems__ */ + size_t zsize, ksize, size; +#endif /* __rtems__ */ rw_init(&uma_rwlock, "UMA lock"); + ksize = sizeof(struct uma_keg) + + (sizeof(struct uma_domain) * vm_ndomains); + zsize = sizeof(struct uma_zone) + + (sizeof(struct uma_cache) * mp_ncpus) + + (sizeof(struct uma_zone_domain) * vm_ndomains); +#ifdef __rtems__ + size = 2 * roundup(zsize, CACHE_LINE_SIZE) + + roundup(ksize, CACHE_LINE_SIZE); +#endif /* __rtems__ */ + +#ifndef __rtems__ + /* Use bootpages memory for the zone of zones and zone of kegs. */ + m = (uintptr_t)mem; +#else /* __rtems__ */ + m = (uintptr_t)rtems_heap_allocate_aligned_with_boundary( + size, CACHE_LINE_SIZE, 0); + BSD_ASSERT(m != 0); + memset((void *)m, 0, size); +#endif /* __rtems__ */ + zones = (uma_zone_t)m; + m += roundup(zsize, CACHE_LINE_SIZE); + kegs = (uma_zone_t)m; + m += roundup(zsize, CACHE_LINE_SIZE); + masterkeg = (uma_keg_t)m; +#ifndef __rtems__ + m += roundup(ksize, CACHE_LINE_SIZE); + m = roundup(m, PAGE_SIZE); + npages -= (m - (uintptr_t)mem) / PAGE_SIZE; + mem = (void *)m; +#endif /* __rtems__ */ + /* "manually" create the initial zone */ memset(&args, 0, sizeof(args)); args.name = "UMA Kegs"; - args.size = sizeof(struct uma_keg); + args.size = ksize; args.ctor = keg_ctor; args.dtor = keg_dtor; args.uminit = zero_init; args.fini = NULL; - args.keg = &masterkeg; + args.keg = masterkeg; args.align = 32 - 1; args.flags = UMA_ZFLAG_INTERNAL; - /* The initial zone has no Per cpu queues so it's smaller */ - zone_ctor(kegs, sizeof(struct uma_zone), &args, M_WAITOK); + zone_ctor(kegs, zsize, &args, M_WAITOK); #ifndef __rtems__ mtx_init(&uma_boot_pages_mtx, "UMA boot pages", NULL, MTX_DEF); @@ -1844,7 +1913,8 @@ uma_startup(void *mem, int npages) args.name = "UMA Zones"; args.size = sizeof(struct uma_zone) + - (sizeof(struct uma_cache) * (mp_maxid + 1)); + (sizeof(struct uma_cache) * (mp_maxid + 1)) + + (sizeof(struct uma_zone_domain) * vm_ndomains); args.ctor = zone_ctor; args.dtor = zone_dtor; args.uminit = zero_init; @@ -1852,8 +1922,7 @@ uma_startup(void *mem, int npages) args.keg = NULL; args.align = 32 - 1; args.flags = UMA_ZFLAG_INTERNAL; - /* The initial zone has no Per cpu queues so it's smaller */ - zone_ctor(zones, sizeof(struct uma_zone), &args, M_WAITOK); + zone_ctor(zones, zsize, &args, M_WAITOK); /* Now make a zone for slab headers */ slabzone = uma_zcreate("UMA Slabs", @@ -1924,7 +1993,7 @@ uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini, args.align = (align == UMA_ALIGN_CACHE) ? uma_align_cache : align; args.flags = flags; args.zone = zone; - return (zone_alloc_item(kegs, &args, M_WAITOK)); + return (zone_alloc_item(kegs, &args, UMA_ANYDOMAIN, M_WAITOK)); } /* See uma.h */ @@ -1987,7 +2056,7 @@ uma_zcreate(const char *name, size_t size, uma_ctor ctor, uma_dtor dtor, locked = true; } #endif /* __rtems__ */ - res = zone_alloc_item(zones, &args, M_WAITOK); + res = zone_alloc_item(zones, &args, UMA_ANYDOMAIN, M_WAITOK); #ifndef __rtems__ if (locked) #endif /* __rtems__ */ @@ -2030,7 +2099,7 @@ uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor, } #endif /* __rtems__ */ /* XXX Attaches only one keg of potentially many. */ - res = zone_alloc_item(zones, &args, M_WAITOK); + res = zone_alloc_item(zones, &args, UMA_ANYDOMAIN, M_WAITOK); #ifndef __rtems__ if (locked) #endif /* __rtems__ */ @@ -2059,7 +2128,7 @@ uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, args.align = 0; args.flags = flags; - return (zone_alloc_item(zones, &args, M_WAITOK)); + return (zone_alloc_item(zones, &args, UMA_ANYDOMAIN, M_WAITOK)); } #ifndef __rtems__ @@ -2166,11 +2235,11 @@ uma_zwait(uma_zone_t zone) void * uma_zalloc_arg(uma_zone_t zone, void *udata, int flags) { - void *item; - uma_cache_t cache; + uma_zone_domain_t zdom; uma_bucket_t bucket; - int lockfail; - int cpu; + uma_cache_t cache; + void *item; + int cpu, domain, lockfail; /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); @@ -2269,6 +2338,11 @@ zalloc_start: if (bucket != NULL) bucket_free(zone, bucket, udata); + if (zone->uz_flags & UMA_ZONE_NUMA) + domain = PCPU_GET(domain); + else + domain = UMA_ANYDOMAIN; + /* Short-circuit for zones without buckets and low memory. */ if (zone->uz_count == 0 || bucketdisable) goto zalloc_item; @@ -2309,7 +2383,11 @@ zalloc_start: /* * Check the zone's cache of buckets. */ - if ((bucket = LIST_FIRST(&zone->uz_buckets)) != NULL) { + if (domain == UMA_ANYDOMAIN) + zdom = &zone->uz_domain[0]; + else + zdom = &zone->uz_domain[domain]; + if ((bucket = LIST_FIRST(&zdom->uzd_buckets)) != NULL) { KASSERT(bucket->ub_cnt != 0, ("uma_zalloc_arg: Returning an empty bucket.")); @@ -2334,7 +2412,7 @@ zalloc_start: * works we'll restart the allocation from the beginning and it * will use the just filled bucket. */ - bucket = zone_alloc_bucket(zone, udata, flags); + bucket = zone_alloc_bucket(zone, udata, domain, flags); CTR3(KTR_UMA, "uma_zalloc: zone %s(%p) bucket zone returned %p", zone->uz_name, zone, bucket); if (bucket != NULL) { @@ -2347,10 +2425,12 @@ zalloc_start: * initialized bucket to make this less likely or claim * the memory directly. */ - if (cache->uc_allocbucket == NULL) - cache->uc_allocbucket = bucket; + if (cache->uc_allocbucket != NULL || + (zone->uz_flags & UMA_ZONE_NUMA && + domain != PCPU_GET(domain))) + LIST_INSERT_HEAD(&zdom->uzd_buckets, bucket, ub_link); else - LIST_INSERT_HEAD(&zone->uz_buckets, bucket, ub_link); + cache->uc_allocbucket = bucket; ZONE_UNLOCK(zone); goto zalloc_start; } @@ -2359,38 +2439,103 @@ zalloc_start: * We may not be able to get a bucket so return an actual item. */ zalloc_item: - item = zone_alloc_item(zone, udata, flags); + item = zone_alloc_item(zone, udata, domain, flags); return (item); } +void * +uma_zalloc_domain(uma_zone_t zone, void *udata, int domain, int flags) +{ + + /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ + random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); + + /* This is the fast path allocation */ + CTR5(KTR_UMA, + "uma_zalloc_domain thread %x zone %s(%p) domain %d flags %d", + curthread, zone->uz_name, zone, domain, flags); + + if (flags & M_WAITOK) { + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "uma_zalloc_domain: zone \"%s\"", zone->uz_name); + } + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), + ("uma_zalloc_domain: called with spinlock or critical section held")); + + return (zone_alloc_item(zone, udata, domain, flags)); +} + +/* + * Find a slab with some space. Prefer slabs that are partially used over those + * that are totally full. This helps to reduce fragmentation. + * + * If 'rr' is 1, search all domains starting from 'domain'. Otherwise check + * only 'domain'. + */ +static uma_slab_t +keg_first_slab(uma_keg_t keg, int domain, int rr) +{ + uma_domain_t dom; + uma_slab_t slab; + int start; + + KASSERT(domain >= 0 && domain < vm_ndomains, + ("keg_first_slab: domain %d out of range", domain)); + + slab = NULL; + start = domain; + do { + dom = &keg->uk_domain[domain]; + if (!LIST_EMPTY(&dom->ud_part_slab)) + return (LIST_FIRST(&dom->ud_part_slab)); + if (!LIST_EMPTY(&dom->ud_free_slab)) { + slab = LIST_FIRST(&dom->ud_free_slab); + LIST_REMOVE(slab, us_link); + LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link); + return (slab); + } + if (rr) + domain = (domain + 1) % vm_ndomains; + } while (domain != start); + + return (NULL); +} + static uma_slab_t -keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags) +keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, int flags) { + uma_domain_t dom; uma_slab_t slab; - int reserve; + int allocflags, domain, reserve, rr, start; mtx_assert(&keg->uk_lock, MA_OWNED); slab = NULL; reserve = 0; + allocflags = flags; if ((flags & M_USE_RESERVE) == 0) reserve = keg->uk_reserve; - for (;;) { - /* - * Find a slab with some space. Prefer slabs that are partially - * used over those that are totally full. This helps to reduce - * fragmentation. - */ - if (keg->uk_free > reserve) { - if (!LIST_EMPTY(&keg->uk_part_slab)) { - slab = LIST_FIRST(&keg->uk_part_slab); - } else { - slab = LIST_FIRST(&keg->uk_free_slab); - LIST_REMOVE(slab, us_link); - LIST_INSERT_HEAD(&keg->uk_part_slab, slab, - us_link); - } + /* + * Round-robin for non first-touch zones when there is more than one + * domain. + */ + if (vm_ndomains == 1) + rdomain = 0; + rr = rdomain == UMA_ANYDOMAIN; + if (rr) { + keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains; + domain = start = keg->uk_cursor; + /* Only block on the second pass. */ + if ((flags & (M_WAITOK | M_NOVM)) == M_WAITOK) + allocflags = (allocflags & ~M_WAITOK) | M_NOWAIT; + } else + domain = start = rdomain; + +again: + do { + if (keg->uk_free > reserve && + (slab = keg_first_slab(keg, domain, rr)) != NULL) { MPASS(slab->us_keg == keg); return (slab); } @@ -2413,12 +2558,12 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags) zone_maxaction(zone); } if (flags & M_NOWAIT) - break; + return (NULL); zone->uz_sleeps++; msleep(keg, &keg->uk_lock, PVM, "keglimit", 0); continue; } - slab = keg_alloc_slab(keg, zone, flags); + slab = keg_alloc_slab(keg, zone, domain, allocflags); /* * If we got a slab here it's safe to mark it partially used * and return. We assume that the caller is going to remove @@ -2426,21 +2571,37 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags) */ if (slab) { MPASS(slab->us_keg == keg); - LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link); + dom = &keg->uk_domain[slab->us_domain]; + LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link); return (slab); } - /* - * We might not have been able to get a slab but another cpu - * could have while we were unlocked. Check again before we - * fail. - */ - flags |= M_NOVM; + if (rr) { + keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains; + domain = keg->uk_cursor; + } + } while (domain != start); + + /* Retry domain scan with blocking. */ + if (allocflags != flags) { + allocflags = flags; + goto again; } - return (slab); + + /* + * We might not have been able to get a slab but another cpu + * could have while we were unlocked. Check again before we + * fail. + */ + if (keg->uk_free > reserve && + (slab = keg_first_slab(keg, domain, rr)) != NULL) { + MPASS(slab->us_keg == keg); + return (slab); + } + return (NULL); } static uma_slab_t -zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags) +zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int domain, int flags) { uma_slab_t slab; @@ -2450,7 +2611,7 @@ zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags) } for (;;) { - slab = keg_fetch_slab(keg, zone, flags); + slab = keg_fetch_slab(keg, zone, domain, flags); if (slab) return (slab); if (flags & (M_NOWAIT | M_NOVM)) @@ -2468,7 +2629,7 @@ zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags) * The last pointer is used to seed the search. It is not required. */ static uma_slab_t -zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags) +zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int domain, int rflags) { uma_klink_t klink; uma_slab_t slab; @@ -2488,7 +2649,7 @@ zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags) * the search. */ if (last != NULL) { - slab = keg_fetch_slab(last, zone, flags); + slab = keg_fetch_slab(last, zone, domain, flags); if (slab) return (slab); KEG_UNLOCK(last); @@ -2509,7 +2670,7 @@ zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags) keg = klink->kl_keg; KEG_LOCK(keg); if ((keg->uk_flags & UMA_ZFLAG_FULL) == 0) { - slab = keg_fetch_slab(keg, zone, flags); + slab = keg_fetch_slab(keg, zone, domain, flags); if (slab) return (slab); } @@ -2546,6 +2707,7 @@ zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags) static void * slab_alloc_item(uma_keg_t keg, uma_slab_t slab) { + uma_domain_t dom; void *item; uint8_t freei; @@ -2561,32 +2723,48 @@ slab_alloc_item(uma_keg_t keg, uma_slab_t slab) /* Move this slab to the full list */ if (slab->us_freecount == 0) { LIST_REMOVE(slab, us_link); - LIST_INSERT_HEAD(&keg->uk_full_slab, slab, us_link); + dom = &keg->uk_domain[slab->us_domain]; + LIST_INSERT_HEAD(&dom->ud_full_slab, slab, us_link); } return (item); } static int -zone_import(uma_zone_t zone, void **bucket, int max, int flags) +zone_import(uma_zone_t zone, void **bucket, int max, int domain, int flags) { uma_slab_t slab; uma_keg_t keg; + int stripe; int i; slab = NULL; keg = NULL; /* Try to keep the buckets totally full */ for (i = 0; i < max; ) { - if ((slab = zone->uz_slab(zone, keg, flags)) == NULL) + if ((slab = zone->uz_slab(zone, keg, domain, flags)) == NULL) break; keg = slab->us_keg; + stripe = howmany(max, vm_ndomains); while (slab->us_freecount && i < max) { bucket[i++] = slab_alloc_item(keg, slab); if (keg->uk_free <= keg->uk_reserve) break; +#ifdef NUMA + /* + * If the zone is striped we pick a new slab for every + * N allocations. Eliminating this conditional will + * instead pick a new domain for each bucket rather + * than stripe within each bucket. The current option + * produces more fragmentation and requires more cpu + * time but yields better distribution. + */ + if ((zone->uz_flags & UMA_ZONE_NUMA) == 0 && + vm_ndomains > 1 && --stripe == 0) + break; +#endif } - /* Don't grab more than one slab at a time. */ + /* Don't block if we allocated any successfully. */ flags &= ~M_WAITOK; flags |= M_NOWAIT; } @@ -2597,7 +2775,7 @@ zone_import(uma_zone_t zone, void **bucket, int max, int flags) } static uma_bucket_t -zone_alloc_bucket(uma_zone_t zone, void *udata, int flags) +zone_alloc_bucket(uma_zone_t zone, void *udata, int domain, int flags) { uma_bucket_t bucket; int max; @@ -2609,7 +2787,7 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int flags) max = MIN(bucket->ub_entries, zone->uz_count); bucket->ub_cnt = zone->uz_import(zone->uz_arg, bucket->ub_bucket, - max, flags); + max, domain, flags); /* * Initialize the memory if necessary. @@ -2651,6 +2829,7 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int flags) * Arguments * zone The zone to alloc for. * udata The data to be passed to the constructor. + * domain The domain to allocate from or UMA_ANYDOMAIN. * flags M_WAITOK, M_NOWAIT, M_ZERO. * * Returns @@ -2659,13 +2838,13 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int flags) */ static void * -zone_alloc_item(uma_zone_t zone, void *udata, int flags) +zone_alloc_item(uma_zone_t zone, void *udata, int domain, int flags) { void *item; item = NULL; - if (zone->uz_import(zone->uz_arg, &item, 1, flags) != 1) + if (zone->uz_import(zone->uz_arg, &item, 1, domain, flags) != 1) goto fail; atomic_add_long(&zone->uz_allocs, 1); @@ -2711,8 +2890,8 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata) { uma_cache_t cache; uma_bucket_t bucket; - int lockfail; - int cpu; + uma_zone_domain_t zdom; + int cpu, domain, lockfail; /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); @@ -2828,6 +3007,12 @@ zfree_start: /* We are no longer associated with this CPU. */ critical_exit(); + if ((zone->uz_flags & UMA_ZONE_NUMA) != 0) + domain = PCPU_GET(domain); + else + domain = 0; + zdom = &zone->uz_domain[0]; + /* Can we throw this on the zone full list? */ if (bucket != NULL) { CTR3(KTR_UMA, @@ -2836,7 +3021,7 @@ zfree_start: /* ub_cnt is pointing to the last free item */ KASSERT(bucket->ub_cnt != 0, ("uma_zfree: Attempting to insert an empty bucket onto the full list.\n")); - LIST_INSERT_HEAD(&zone->uz_buckets, bucket, ub_link); + LIST_INSERT_HEAD(&zdom->uzd_buckets, bucket, ub_link); } /* @@ -2854,7 +3039,9 @@ zfree_start: critical_enter(); cpu = curcpu; cache = &zone->uz_cpu[cpu]; - if (cache->uc_freebucket == NULL) { + if (cache->uc_freebucket == NULL && + ((zone->uz_flags & UMA_ZONE_NUMA) == 0 || + domain == PCPU_GET(domain))) { cache->uc_freebucket = bucket; goto zfree_start; } @@ -2876,21 +3063,43 @@ zfree_item: return; } +void +uma_zfree_domain(uma_zone_t zone, void *item, void *udata) +{ + + /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ + random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); + + CTR2(KTR_UMA, "uma_zfree_domain thread %x zone %s", curthread, + zone->uz_name); + + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), + ("uma_zfree_domain: called with spinlock or critical section held")); + + /* uma_zfree(..., NULL) does nothing, to match free(9). */ + if (item == NULL) + return; + zone_free_item(zone, item, udata, SKIP_NONE); +} + static void slab_free_item(uma_keg_t keg, uma_slab_t slab, void *item) { + uma_domain_t dom; uint8_t freei; mtx_assert(&keg->uk_lock, MA_OWNED); MPASS(keg == slab->us_keg); + dom = &keg->uk_domain[slab->us_domain]; + /* Do we need to remove from any lists? */ if (slab->us_freecount+1 == keg->uk_ipers) { LIST_REMOVE(slab, us_link); - LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link); + LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link); } else if (slab->us_freecount == 0) { LIST_REMOVE(slab, us_link); - LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link); + LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link); } /* Slab management. */ @@ -3223,24 +3432,28 @@ uma_zone_reserve_kva(uma_zone_t zone, int count) void uma_prealloc(uma_zone_t zone, int items) { - int slabs; + uma_domain_t dom; uma_slab_t slab; uma_keg_t keg; + int domain, slabs; keg = zone_first_keg(zone); if (keg == NULL) return; KEG_LOCK(keg); slabs = items / keg->uk_ipers; + domain = 0; if (slabs * keg->uk_ipers < items) slabs++; while (slabs > 0) { - slab = keg_alloc_slab(keg, zone, M_WAITOK); + slab = keg_alloc_slab(keg, zone, domain, M_WAITOK); if (slab == NULL) break; MPASS(slab->us_keg == keg); - LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link); + dom = &keg->uk_domain[slab->us_domain]; + LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link); slabs--; + domain = (domain + 1) % vm_ndomains; } KEG_UNLOCK(keg); } @@ -3295,7 +3508,7 @@ uma_reclaim_worker(void *arg __unused) for (;;) { sx_xlock(&uma_drain_lock); - while (uma_reclaim_needed == 0) + while (atomic_load_int(&uma_reclaim_needed) == 0) sx_sleep(uma_reclaim, &uma_drain_lock, PVM, "umarcl", hz); #ifndef __rtems__ @@ -3304,7 +3517,7 @@ uma_reclaim_worker(void *arg __unused) sx_xlock(&uma_drain_lock); #endif /* __rtems__ */ uma_reclaim_locked(true); - atomic_set_int(&uma_reclaim_needed, 0); + atomic_store_int(&uma_reclaim_needed, 0); sx_xunlock(&uma_drain_lock); /* Don't fire more than once per-second. */ pause("umarclslp", hz); @@ -3331,34 +3544,47 @@ uma_zone_exhausted_nolock(uma_zone_t zone) #ifndef __rtems__ void * -uma_large_malloc(vm_size_t size, int wait) +uma_large_malloc_domain(vm_size_t size, int domain, int wait) { - void *mem; + vm_offset_t addr; uma_slab_t slab; - uint8_t flags; - slab = zone_alloc_item(slabzone, NULL, wait); + slab = zone_alloc_item(slabzone, NULL, domain, wait); if (slab == NULL) return (NULL); - mem = page_alloc(NULL, size, &flags, wait); - if (mem) { - vsetslab((vm_offset_t)mem, slab); - slab->us_data = mem; - slab->us_flags = flags | UMA_SLAB_MALLOC; + if (domain == UMA_ANYDOMAIN) + addr = kmem_malloc(kernel_arena, size, wait); + else + addr = kmem_malloc_domain(domain, size, wait); + if (addr != 0) { + vsetslab(addr, slab); + slab->us_data = (void *)addr; + slab->us_flags = UMA_SLAB_KERNEL | UMA_SLAB_MALLOC; slab->us_size = size; + slab->us_domain = vm_phys_domidx(PHYS_TO_VM_PAGE( + pmap_kextract(addr))); uma_total_inc(size); } else { zone_free_item(slabzone, slab, NULL, SKIP_NONE); } - return (mem); + return ((void *)addr); +} + +void * +uma_large_malloc(vm_size_t size, int wait) +{ + + return uma_large_malloc_domain(size, UMA_ANYDOMAIN, wait); } void uma_large_free(uma_slab_t slab) { - page_free(slab->us_data, slab->us_size, slab->us_flags); + KASSERT((slab->us_flags & UMA_SLAB_KERNEL) != 0, + ("uma_large_free: Memory not allocated with uma_large_malloc.")); + kmem_free(kernel_arena, (vm_offset_t)slab->us_data, slab->us_size); uma_total_dec(slab->us_size); zone_free_item(slabzone, slab, NULL, SKIP_NONE); } @@ -3394,7 +3620,14 @@ unsigned long uma_size(void) { - return uma_kmem_total; + return (uma_kmem_total); +} + +long +uma_avail(void) +{ + + return (uma_kmem_limit - uma_kmem_total); } void @@ -3423,7 +3656,9 @@ cache_print(uma_cache_t cache) static void uma_print_keg(uma_keg_t keg) { + uma_domain_t dom; uma_slab_t slab; + int i; printf("keg: %s(%p) size %d(%d) flags %#x ipers %d ppera %d " "out %d free %d limit %d\n", @@ -3431,15 +3666,18 @@ uma_print_keg(uma_keg_t keg) keg->uk_ipers, keg->uk_ppera, (keg->uk_pages / keg->uk_ppera) * keg->uk_ipers - keg->uk_free, keg->uk_free, (keg->uk_maxpages / keg->uk_ppera) * keg->uk_ipers); - printf("Part slabs:\n"); - LIST_FOREACH(slab, &keg->uk_part_slab, us_link) - slab_print(slab); - printf("Free slabs:\n"); - LIST_FOREACH(slab, &keg->uk_free_slab, us_link) - slab_print(slab); - printf("Full slabs:\n"); - LIST_FOREACH(slab, &keg->uk_full_slab, us_link) - slab_print(slab); + for (i = 0; i < vm_ndomains; i++) { + dom = &keg->uk_domain[i]; + printf("Part slabs:\n"); + LIST_FOREACH(slab, &dom->ud_part_slab, us_link) + slab_print(slab); + printf("Free slabs:\n"); + LIST_FOREACH(slab, &dom->ud_free_slab, us_link) + slab_print(slab); + printf("Full slabs:\n"); + LIST_FOREACH(slab, &dom->ud_full_slab, us_link) + slab_print(slab); + } } void @@ -3531,6 +3769,7 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS) struct uma_type_header uth; struct uma_percpu_stat ups; uma_bucket_t bucket; + uma_zone_domain_t zdom; struct sbuf sbuf; uma_cache_t cache; uma_klink_t kl; @@ -3586,8 +3825,12 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS) (LIST_FIRST(&kz->uk_zones) != z)) uth.uth_zone_flags = UTH_ZONE_SECONDARY; - LIST_FOREACH(bucket, &z->uz_buckets, ub_link) - uth.uth_zone_free += bucket->ub_cnt; + for (i = 0; i < vm_ndomains; i++) { + zdom = &z->uz_domain[i]; + LIST_FOREACH(bucket, &zdom->uzd_buckets, + ub_link) + uth.uth_zone_free += bucket->ub_cnt; + } uth.uth_allocs = z->uz_allocs; uth.uth_frees = z->uz_frees; uth.uth_fails = z->uz_fails; @@ -3754,11 +3997,12 @@ uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item) #ifdef DDB DB_SHOW_COMMAND(uma, db_show_uma) { - uint64_t allocs, frees, sleeps; uma_bucket_t bucket; uma_keg_t kz; uma_zone_t z; - int cachefree; + uma_zone_domain_t zdom; + uint64_t allocs, frees, sleeps; + int cachefree, i; db_printf("%18s %8s %8s %8s %12s %8s %8s\n", "Zone", "Size", "Used", "Free", "Requests", "Sleeps", "Bucket"); @@ -3775,8 +4019,12 @@ DB_SHOW_COMMAND(uma, db_show_uma) if (!((z->uz_flags & UMA_ZONE_SECONDARY) && (LIST_FIRST(&kz->uk_zones) != z))) cachefree += kz->uk_free; - LIST_FOREACH(bucket, &z->uz_buckets, ub_link) - cachefree += bucket->ub_cnt; + for (i = 0; i < vm_ndomains; i++) { + zdom = &z->uz_domain[i]; + LIST_FOREACH(bucket, &zdom->uzd_buckets, + ub_link) + cachefree += bucket->ub_cnt; + } db_printf("%18s %8ju %8jd %8d %12ju %8ju %8u\n", z->uz_name, (uintmax_t)kz->uk_size, (intmax_t)(allocs - frees), cachefree, @@ -3789,17 +4037,21 @@ DB_SHOW_COMMAND(uma, db_show_uma) DB_SHOW_COMMAND(umacache, db_show_umacache) { - uint64_t allocs, frees; uma_bucket_t bucket; uma_zone_t z; - int cachefree; + uma_zone_domain_t zdom; + uint64_t allocs, frees; + int cachefree, i; db_printf("%18s %8s %8s %8s %12s %8s\n", "Zone", "Size", "Used", "Free", "Requests", "Bucket"); LIST_FOREACH(z, &uma_cachezones, uz_link) { uma_zone_sumstat(z, &cachefree, &allocs, &frees, NULL); - LIST_FOREACH(bucket, &z->uz_buckets, ub_link) - cachefree += bucket->ub_cnt; + for (i = 0; i < vm_ndomains; i++) { + zdom = &z->uz_domain[i]; + LIST_FOREACH(bucket, &zdom->uzd_buckets, ub_link) + cachefree += bucket->ub_cnt; + } db_printf("%18s %8ju %8jd %8d %12ju %8u\n", z->uz_name, (uintmax_t)z->uz_size, (intmax_t)(allocs - frees), cachefree, diff --git a/freebsd/sys/vm/uma_int.h b/freebsd/sys/vm/uma_int.h index 592e79d7..5852a1c3 100644 --- a/freebsd/sys/vm/uma_int.h +++ b/freebsd/sys/vm/uma_int.h @@ -39,7 +39,22 @@ */ /* - * Here's a quick description of the relationship between the objects: + * The brief summary; Zones describe unique allocation types. Zones are + * organized into per-CPU caches which are filled by buckets. Buckets are + * organized according to memory domains. Buckets are filled from kegs which + * are also organized according to memory domains. Kegs describe a unique + * allocation type, backend memory provider, and layout. Kegs are associated + * with one or more zones and zones reference one or more kegs. Kegs provide + * slabs which are virtually contiguous collections of pages. Each slab is + * broken down int one or more items that will satisfy an individual allocation. + * + * Allocation is satisfied in the following order: + * 1) Per-CPU cache + * 2) Per-domain cache of buckets + * 3) Slab from any of N kegs + * 4) Backend page provider + * + * More detail on individual objects is contained below: * * Kegs contain lists of slabs which are stored in either the full bin, empty * bin, or partially allocated bin, to reduce fragmentation. They also contain @@ -47,6 +62,13 @@ * and rsize is the result of that. The Keg also stores information for * managing a hash of page addresses that maps pages to uma_slab_t structures * for pages that don't have embedded uma_slab_t's. + * + * Keg slab lists are organized by memory domain to support NUMA allocation + * policies. By default allocations are spread across domains to reduce the + * potential for hotspots. Special keg creation flags may be specified to + * prefer location allocation. However there is no strict enforcement as frees + * may happen on any CPU and these are returned to the CPU-local cache + * regardless of the originating domain. * * The uma_slab_t may be embedded in a UMA_SLAB_SIZE chunk of memory or it may * be allocated off the page from a special slab zone. The free list within a @@ -182,6 +204,17 @@ struct uma_cache { typedef struct uma_cache * uma_cache_t; /* + * Per-domain memory list. Embedded in the kegs. + */ +struct uma_domain { + LIST_HEAD(,uma_slab) ud_part_slab; /* partially allocated slabs */ + LIST_HEAD(,uma_slab) ud_free_slab; /* empty slab list */ + LIST_HEAD(,uma_slab) ud_full_slab; /* full slabs */ +}; + +typedef struct uma_domain * uma_domain_t; + +/* * Keg management structure * * TODO: Optimize for cache line size @@ -192,10 +225,8 @@ struct uma_keg { struct uma_hash uk_hash; LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */ - LIST_HEAD(,uma_slab) uk_part_slab; /* partially allocated slabs */ - LIST_HEAD(,uma_slab) uk_free_slab; /* empty slab list */ - LIST_HEAD(,uma_slab) uk_full_slab; /* full slabs */ + uint32_t uk_cursor; /* Domain alloc cursor. */ uint32_t uk_align; /* Alignment mask */ uint32_t uk_pages; /* Total page count */ uint32_t uk_free; /* Count of items free in slabs */ @@ -221,6 +252,9 @@ struct uma_keg { /* Least used fields go to the last cache line. */ const char *uk_name; /* Name of creating zone. */ LIST_ENTRY(uma_keg) uk_link; /* List of all kegs */ + + /* Must be last, variable sized. */ + struct uma_domain uk_domain[]; /* Keg's slab lists. */ }; typedef struct uma_keg * uma_keg_t; @@ -250,7 +284,7 @@ struct uma_slab { #endif uint16_t us_freecount; /* How many are free? */ uint8_t us_flags; /* Page flags see uma.h */ - uint8_t us_pad; /* Pad to 32bits, unused. */ + uint8_t us_domain; /* Backing NUMA domain. */ }; #define us_link us_type._us_link @@ -258,8 +292,12 @@ struct uma_slab { #define us_size us_type._us_size #endif /* __rtems__ */ +#if MAXMEMDOM >= 255 +#error "Slab domain type insufficient" +#endif + typedef struct uma_slab * uma_slab_t; -typedef uma_slab_t (*uma_slaballoc)(uma_zone_t, uma_keg_t, int); +typedef uma_slab_t (*uma_slaballoc)(uma_zone_t, uma_keg_t, int, int); struct uma_klink { LIST_ENTRY(uma_klink) kl_link; @@ -267,6 +305,12 @@ struct uma_klink { }; typedef struct uma_klink *uma_klink_t; +struct uma_zone_domain { + LIST_HEAD(,uma_bucket) uzd_buckets; /* full buckets */ +}; + +typedef struct uma_zone_domain * uma_zone_domain_t; + /* * Zone management structure * @@ -279,7 +323,7 @@ struct uma_zone { const char *uz_name; /* Text name of the zone */ LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */ - LIST_HEAD(,uma_bucket) uz_buckets; /* full buckets */ + struct uma_zone_domain *uz_domain; /* per-domain buckets */ LIST_HEAD(,uma_klink) uz_kegs; /* List of kegs. */ struct uma_klink uz_klink; /* klink for first keg. */ @@ -313,7 +357,9 @@ struct uma_zone { * This HAS to be the last item because we adjust the zone size * based on NCPU and then allocate the space for the zones. */ - struct uma_cache uz_cpu[1]; /* Per cpu caches */ + struct uma_cache uz_cpu[]; /* Per cpu caches */ + + /* uz_domain follows here. */ }; /* @@ -344,6 +390,7 @@ zone_first_keg(uma_zone_t zone) /* Internal prototypes */ static __inline uma_slab_t hash_sfind(struct uma_hash *hash, uint8_t *data); void *uma_large_malloc(vm_size_t size, int wait); +void *uma_large_malloc_domain(vm_size_t size, int domain, int wait); void uma_large_free(uma_slab_t slab); /* Lock Macros */ @@ -437,16 +484,12 @@ vsetslab(vm_offset_t va, uma_slab_t slab) * if they can provide more efficient allocation functions. This is useful * for using direct mapped addresses. */ -void *uma_small_alloc(uma_zone_t zone, vm_size_t bytes, uint8_t *pflag, - int wait); +void *uma_small_alloc(uma_zone_t zone, vm_size_t bytes, int domain, + uint8_t *pflag, int wait); void uma_small_free(void *mem, vm_size_t size, uint8_t flags); /* Set a global soft limit on UMA managed memory. */ void uma_set_limit(unsigned long limit); -unsigned long uma_limit(void); - -/* Return the amount of memory managed by UMA. */ -unsigned long uma_size(void); #endif /* _KERNEL */ #endif /* VM_UMA_INT_H */ diff --git a/freebsd/sys/vm/vm.h b/freebsd/sys/vm/vm.h index f674fc56..b5de53d3 100644 --- a/freebsd/sys/vm/vm.h +++ b/freebsd/sys/vm/vm.h @@ -146,6 +146,8 @@ extern void vm_ksubmap_init(struct kva_md_info *); extern int old_mlock; +#define vm_ndomains 1 + struct ucred; int swap_reserve(vm_ooffset_t incr); int swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred); diff --git a/freebsd/sys/vm/vm_extern.h b/freebsd/sys/vm/vm_extern.h index c92933ca..e64637c1 100644 --- a/freebsd/sys/vm/vm_extern.h +++ b/freebsd/sys/vm/vm_extern.h @@ -56,14 +56,21 @@ void kmap_free_wakeup(vm_map_t, vm_offset_t, vm_size_t); /* These operate on virtual addresses backed by memory. */ vm_offset_t kmem_alloc_attr(struct vmem *, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr); +vm_offset_t kmem_alloc_attr_domain(int domain, vm_size_t size, int flags, + vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr); vm_offset_t kmem_alloc_contig(struct vmem *, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary, vm_memattr_t memattr); +vm_offset_t kmem_alloc_contig_domain(int domain, vm_size_t size, int flags, + vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary, + vm_memattr_t memattr); vm_offset_t kmem_malloc(struct vmem *, vm_size_t size, int flags); +vm_offset_t kmem_malloc_domain(int domain, vm_size_t size, int flags); void kmem_free(struct vmem *, vm_offset_t, vm_size_t); /* This provides memory for previously allocated address space. */ int kmem_back(vm_object_t, vm_offset_t, vm_size_t, int); +int kmem_back_domain(int, vm_object_t, vm_offset_t, vm_size_t, int); void kmem_unback(vm_object_t, vm_offset_t, vm_size_t); /* Bootstrapping. */ diff --git a/freebsd/sys/x86/include/machine/bus.h b/freebsd/sys/x86/include/machine/bus.h index 041ab156..297b5edc 100644 --- a/freebsd/sys/x86/include/machine/bus.h +++ b/freebsd/sys/x86/include/machine/bus.h @@ -118,6 +118,7 @@ #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF #if defined(__amd64__) || defined(PAE) +#define BUS_SPACE_MAXADDR_48BIT 0xFFFFFFFFFFFFULL #define BUS_SPACE_MAXADDR 0xFFFFFFFFFFFFFFFFULL #else #define BUS_SPACE_MAXADDR 0xFFFFFFFF diff --git a/freebsd/sys/x86/pci/pci_bus.c b/freebsd/sys/x86/pci/pci_bus.c index 8d37bdcd..0db41c18 100644 --- a/freebsd/sys/x86/pci/pci_bus.c +++ b/freebsd/sys/x86/pci/pci_bus.c @@ -686,8 +686,7 @@ DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, hostb_devclass, 0, 0); * ID is available and the PCI BIOS isn't, but for now we just * eat the PnP ID and do nothing else. * - * XXX we should silence this probe, as it will generally confuse - * people. + * we silence this probe, as it will generally confuse people. */ static struct isa_pnp_id pcibus_pnp_ids[] = { { 0x030ad041 /* PNP0A03 */, "PCI Bus" }, @@ -751,6 +750,7 @@ static devclass_t pcib_devclass; DEFINE_CLASS_1(pcib, pcibios_pcib_driver, pcibios_pcib_pci_methods, sizeof(struct pcib_softc), pcib_driver); DRIVER_MODULE(pcibios_pcib, pci, pcibios_pcib_driver, pcib_devclass, 0, 0); +ISA_PNP_INFO(pcibus_pnp_ids); static int pcibios_pcib_probe(device_t dev) diff --git a/freebsd/usr.bin/vmstat/vmstat.c b/freebsd/usr.bin/vmstat/vmstat.c index bd4997d6..818222e1 100644 --- a/freebsd/usr.bin/vmstat/vmstat.c +++ b/freebsd/usr.bin/vmstat/vmstat.c @@ -94,50 +94,38 @@ __FBSDID("$FreeBSD$"); #ifndef __rtems__ static char da[] = "da"; +enum x_stats { X_SUM, X_HZ, X_STATHZ, X_NCHSTATS, X_INTRNAMES, X_SINTRNAMES, + X_INTRCNT, X_SINTRCNT, X_DEFICIT, X_REC, X_PGIN, X_XSTATS }; + static struct nlist namelist[] = { -#define X_SUM 0 - { "_vm_cnt" }, -#define X_HZ 1 - { "_hz" }, -#define X_STATHZ 2 - { "_stathz" }, -#define X_NCHSTATS 3 - { "_nchstats" }, -#define X_INTRNAMES 4 - { "_intrnames" }, -#define X_SINTRNAMES 5 - { "_sintrnames" }, -#define X_INTRCNT 6 - { "_intrcnt" }, -#define X_SINTRCNT 7 - { "_sintrcnt" }, + [X_SUM] = { .n_name = "_vm_cnt", }, + [X_HZ] = { .n_name = "_hz", }, + [X_STATHZ] = { .n_name = "_stathz", }, + [X_NCHSTATS] = { .n_name = "_nchstats", }, + [X_INTRNAMES] = { .n_name = "_intrnames", }, + [X_SINTRNAMES] = { .n_name = "_sintrnames", }, + [X_INTRCNT] = { .n_name = "_intrcnt", }, + [X_SINTRCNT] = { .n_name = "_sintrcnt", }, #ifdef notyet -#define X_DEFICIT XXX - { "_deficit" }, -#define X_REC XXX - { "_rectime" }, -#define X_PGIN XXX - { "_pgintime" }, -#define X_XSTATS XXX - { "_xstats" }, -#define X_END XXX -#else -#define X_END 8 + [X_DEFICIT] = { .n_name = "_deficit", }, + [X_REC] = { .n_name = "_rectime", }, + [X_PGIN] = { .n_name = "_pgintime", }, + [X_XSTATS] = { .n_name = "_xstats", }, #endif - { "" }, + { .n_name = NULL, }, }; -static struct statinfo cur, last; -static int num_devices, maxshowdevs; -static long generation; -static struct device_selection *dev_select; -static int num_selected; static struct devstat_match *matches; -static int num_matches = 0; -static int num_devices_specified, num_selections; -static long select_generation; -static char **specified_devices; +static struct device_selection *dev_select; +static struct statinfo cur, last; static devstat_select_mode select_mode; +static size_t size_cp_times; +static long *cur_cp_times, *last_cp_times; +static long generation, select_generation; +static int hz, hdrcnt, maxshowdevs; +static int num_devices, num_devices_specified; +static int num_matches, num_selected, num_selections; +static char **specified_devices; static struct __vmmeter { uint64_t v_swtch; @@ -192,7 +180,7 @@ static struct __vmmeter { } sum, osum; #define VMSTAT_DEFAULT_LINES 20 /* Default number of `winlines'. */ -volatile sig_atomic_t wresized; /* Tty resized, when non-zero. */ +static volatile sig_atomic_t wresized; /* Tty resized when non-zero. */ static int winlines = VMSTAT_DEFAULT_LINES; /* Current number of tty rows. */ static int aflag; @@ -200,7 +188,7 @@ static int nflag; static int Pflag; static int hflag; -static kvm_t *kd; +static kvm_t *kd; #else /* __rtems__ */ #define kd ((kvm_t *)0) #endif /* __rtems__ */ @@ -211,12 +199,12 @@ static kvm_t *kd; #define SUMSTAT 0x08 #define TIMESTAT 0x10 #define VMSTAT 0x20 -#define ZMEMSTAT 0x40 +#define ZMEMSTAT 0x40 #define OBJSTAT 0x80 #ifndef __rtems__ static void cpustats(void); -static void pcpustats(int, u_long, int); +static void pcpustats(u_long, int); static void devstats(void); static void doforkst(void); static void dointr(unsigned int, int); @@ -229,7 +217,6 @@ static void domemstat_zone(void); #ifndef __rtems__ static void kread(int, void *, size_t); static void kreado(int, void *, size_t, size_t); -static char *kgetstr(const char *); static void needhdr(int); static void needresize(int); static void doresize(void); @@ -241,7 +228,7 @@ static void usage(void); static long pct(long, long); static long long getuptime(void); -static char **getdrivedata(char **); +static char **getdrivedata(char **); #endif /* __rtems__ */ #ifdef __rtems__ @@ -261,12 +248,17 @@ rtems_bsd_command_vmstat(int argc, char *argv[]) int main(int argc, char *argv[]) { - int c, todo; - unsigned int interval; +#ifndef __rtems__ + char *bp, *buf, *memf, *nlistf; +#endif /* __rtems__ */ float f; - int reps; #ifndef __rtems__ - char *memf, *nlistf; + int bufsize, c, len, reps, todo; +#else /* __rtems__ */ + int c, reps, todo; +#endif /* __rtems__ */ + unsigned int interval; +#ifndef __rtems__ char errbuf[_POSIX2_LINE_MAX]; #endif /* __rtems__ */ #ifdef __rtems__ @@ -290,7 +282,7 @@ main(int argc, char *argv[]) argc = xo_parse_args(argc, argv); if (argc < 0) - return argc; + return (argc); while ((c = getopt(argc, argv, "ac:fhHiM:mN:n:oPp:stw:z")) != -1) { switch (c) { @@ -330,13 +322,14 @@ main(int argc, char *argv[]) maxshowdevs = atoi(optarg); if (maxshowdevs < 0) xo_errx(1, "number of devices %d is < 0", - maxshowdevs); + maxshowdevs); break; case 'o': todo |= OBJSTAT; break; case 'p': - if (devstat_buildmatch(optarg, &matches, &num_matches) != 0) + if (devstat_buildmatch(optarg, &matches, &num_matches) + != 0) xo_errx(1, "%s", devstat_errbuf); break; case 's': @@ -346,7 +339,8 @@ main(int argc, char *argv[]) #ifdef notyet todo |= TIMESTAT; #else - xo_errx(EX_USAGE, "sorry, -t is not (re)implemented yet"); + xo_errx(EX_USAGE, + "sorry, -t is not (re)implemented yet"); #endif break; case 'w': @@ -380,10 +374,10 @@ main(int argc, char *argv[]) retry_nlist: if (kd != NULL && (c = kvm_nlist(kd, namelist)) != 0) { if (c > 0) { - int bufsize = 0, len = 0; - char *buf, *bp; + bufsize = 0, len = 0; + /* - * 'cnt' was renamed to 'vm_cnt'. If 'vm_cnt' is not + * 'cnt' was renamed to 'vm_cnt'. If 'vm_cnt' is not * found try looking up older 'cnt' symbol. * */ if (namelist[X_SUM].n_type == 0 && @@ -391,9 +385,11 @@ retry_nlist: namelist[X_SUM].n_name = "_cnt"; goto retry_nlist; } + for (c = 0; c < (int)(nitems(namelist)); c++) if (namelist[c].n_type == 0) - bufsize += strlen(namelist[c].n_name) + 1; + bufsize += strlen(namelist[c].n_name) + + 1; bufsize += len + 1; buf = bp = alloca(bufsize); @@ -484,6 +480,7 @@ mysysctl(const char *name, void *oldp, size_t *oldlenp) static char ** getdrivedata(char **argv) { + if ((num_devices = devstat_getnumdevs(NULL)) < 0) xo_errx(1, "%s", devstat_errbuf); @@ -496,20 +493,19 @@ getdrivedata(char **argv) num_devices = cur.dinfo->numdevs; generation = cur.dinfo->generation; - specified_devices = (char **)malloc(sizeof(char *)); + specified_devices = malloc(sizeof(char *)); for (num_devices_specified = 0; *argv; ++argv) { if (isdigit(**argv)) break; num_devices_specified++; - specified_devices = (char **)realloc(specified_devices, - sizeof(char *) * - num_devices_specified); + specified_devices = realloc(specified_devices, + sizeof(char *) * num_devices_specified); specified_devices[num_devices_specified - 1] = *argv; } dev_select = NULL; if (nflag == 0 && maxshowdevs < num_devices_specified) - maxshowdevs = num_devices_specified; + maxshowdevs = num_devices_specified; /* * People are generally only interested in disk statistics when @@ -524,7 +520,6 @@ getdrivedata(char **argv) if ((num_devices_specified == 0) && (num_matches == 0)) { if (devstat_buildmatch(da, &matches, &num_matches) != 0) xo_errx(1, "%s", devstat_errbuf); - select_mode = DS_SELECT_ADD; } else select_mode = DS_SELECT_ONLY; @@ -535,10 +530,10 @@ getdrivedata(char **argv) * or 1. If we get back -1, though, there is an error. */ if (devstat_selectdevs(&dev_select, &num_selected, &num_selections, - &select_generation, generation, cur.dinfo->devices, - num_devices, matches, num_matches, specified_devices, - num_devices_specified, select_mode, - maxshowdevs, 0) == -1) + &select_generation, generation, cur.dinfo->devices, + num_devices, matches, num_matches, specified_devices, + num_devices_specified, select_mode, + maxshowdevs, 0) == -1) xo_errx(1, "%s", devstat_errbuf); return(argv); @@ -551,19 +546,16 @@ getuptime(void) struct timespec sp; (void)clock_gettime(CLOCK_UPTIME, &sp); - return((long long)sp.tv_sec * 1000000000LL + sp.tv_nsec); } static void fill_vmmeter(struct __vmmeter *vmmp) { - struct pcpu **pcpu; - int maxcpu, i; + struct vmmeter vm_cnt; + size_t size; if (kd != NULL) { - struct vmmeter vm_cnt; - kread(X_SUM, &vm_cnt, sizeof(vm_cnt)); #define GET_COUNTER(name) \ vmmp->name = kvm_counter_u64_fetch(kd, (u_long)vm_cnt.name) @@ -598,8 +590,6 @@ fill_vmmeter(struct __vmmeter *vmmp) GET_COUNTER(v_kthreadpages); #undef GET_COUNTER } else { - size_t size; - #define GET_VM_STATS(cat, name) do { \ size = sizeof(vmmp->name); \ mysysctl("vm.stats." #cat "." #name, &vmmp->name, &size); \ @@ -663,11 +653,13 @@ fill_vmmeter(struct __vmmeter *vmmp) static void fill_vmtotal(struct vmtotal *vmtp) { + size_t size; + if (kd != NULL) { /* XXX fill vmtp */ xo_errx(1, "not implemented"); } else { - size_t size = sizeof(*vmtp); + size = sizeof(*vmtp); mysysctl("vm.vmtotal", vmtp, &size); if (size != sizeof(*vmtp)) xo_errx(1, "vm.total size mismatch"); @@ -678,14 +670,10 @@ fill_vmtotal(struct vmtotal *vmtp) static int getcpuinfo(u_long *maskp, int *maxidp) { - int maxcpu; - int maxid; - int ncpus; - int i, j; - int empty; - size_t size; long *times; u_long mask; + size_t size; + int empty, i, j, maxcpu, maxid, ncpus; if (kd != NULL) xo_errx(1, "not implemented"); @@ -723,8 +711,8 @@ getcpuinfo(u_long *maskp, int *maxidp) static void prthuman(const char *name, uint64_t val, int size) { - char buf[10]; int flags; + char buf[10]; char fmt[128]; snprintf(fmt, sizeof(fmt), "{:%s/%%*s}", name); @@ -737,28 +725,23 @@ prthuman(const char *name, uint64_t val, int size) xo_emit(fmt, size, buf); } -static int hz, hdrcnt; - -static long *cur_cp_times; -static long *last_cp_times; -static size_t size_cp_times; - static void dovmstat(unsigned int interval, int reps) { + struct clockinfo clockrate; struct vmtotal total; - time_t uptime, halfuptime; struct devinfo *tmp_dinfo; - size_t size; - int ncpus, maxid; u_long cpumask; - int rate_adj; + size_t size; + time_t uptime, halfuptime; + int ncpus, maxid, rate_adj, retval; uptime = getuptime() / 1000000000LL; halfuptime = uptime / 2; rate_adj = 1; ncpus = 1; maxid = 0; + cpumask = 0; /* * If the user stops the program (control-Z) and then resumes it, @@ -787,8 +770,6 @@ dovmstat(unsigned int interval, int reps) if (!hz) kread(X_HZ, &hz, sizeof(hz)); } else { - struct clockinfo clockrate; - size = sizeof(clockrate); mysysctl("kern.clockrate", &clockrate, &size); if (size != sizeof(clockrate)) @@ -837,19 +818,17 @@ dovmstat(unsigned int interval, int reps) case -1: xo_errx(1, "%s", devstat_errbuf); break; - case 1: { - int retval; - + case 1: num_devices = cur.dinfo->numdevs; generation = cur.dinfo->generation; retval = devstat_selectdevs(&dev_select, &num_selected, - &num_selections, &select_generation, - generation, cur.dinfo->devices, - num_devices, matches, num_matches, - specified_devices, - num_devices_specified, select_mode, - maxshowdevs, 0); + &num_selections, &select_generation, + generation, cur.dinfo->devices, + num_devices, matches, num_matches, + specified_devices, + num_devices_specified, select_mode, + maxshowdevs, 0); switch (retval) { case -1: xo_errx(1, "%s", devstat_errbuf); @@ -860,7 +839,7 @@ dovmstat(unsigned int interval, int reps) default: break; } - } + break; default: break; } @@ -869,8 +848,8 @@ dovmstat(unsigned int interval, int reps) fill_vmtotal(&total); xo_open_container("processes"); xo_emit("{:runnable/%1d} {:waiting/%ld} " - "{:swapped-out/%ld}", - total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw); + "{:swapped-out/%ld}", total.t_rq - 1, total.t_dw + + total.t_pw, total.t_sw); xo_close_container("processes"); xo_open_container("memory"); #define vmstat_pgtok(a) ((uintmax_t)(a) * (sum.v_page_size >> 10)) @@ -878,28 +857,29 @@ dovmstat(unsigned int interval, int reps) if (hflag) { xo_emit(""); prthuman("available-memory", - total.t_avm * (uint64_t)sum.v_page_size, 5); + total.t_avm * (uint64_t)sum.v_page_size, 5); xo_emit(" "); prthuman("free-memory", - total.t_free * (uint64_t)sum.v_page_size, 5); + total.t_free * (uint64_t)sum.v_page_size, 5); xo_emit(" "); } else { xo_emit(" "); xo_emit("{:available-memory/%7ju}", - vmstat_pgtok(total.t_avm)); + vmstat_pgtok(total.t_avm)); xo_emit(" "); xo_emit("{:free-memory/%7ju}", - vmstat_pgtok(total.t_free)); + vmstat_pgtok(total.t_free)); xo_emit(" "); } xo_emit("{:total-page-faults/%5lu} ", - (unsigned long)rate(sum.v_vm_faults - - osum.v_vm_faults)); + (unsigned long)rate(sum.v_vm_faults - + osum.v_vm_faults)); xo_close_container("memory"); xo_open_container("paging-rates"); xo_emit("{:page-reactivated/%3lu} ", - (unsigned long)rate(sum.v_reactivated - osum.v_reactivated)); + (unsigned long)rate(sum.v_reactivated - + osum.v_reactivated)); xo_emit("{:paged-in/%3lu} ", (unsigned long)rate(sum.v_swapin + sum.v_vnodein - (osum.v_swapin + osum.v_vnodein))); @@ -915,13 +895,13 @@ dovmstat(unsigned int interval, int reps) devstats(); xo_open_container("fault-rates"); xo_emit("{:interrupts/%4lu} {:system-calls/%5lu} " - "{:context-switches/%5u}", + "{:context-switches/%5lu}", (unsigned long)rate(sum.v_intr - osum.v_intr), (unsigned long)rate(sum.v_syscall - osum.v_syscall), (unsigned long)rate(sum.v_swtch - osum.v_swtch)); xo_close_container("fault-rates"); if (Pflag) - pcpustats(ncpus, cpumask, maxid); + pcpustats(cpumask, maxid); else cpustats(); xo_emit("\n"); @@ -949,13 +929,12 @@ printhdr(int maxid, u_long cpumask) int i, num_shown; num_shown = MIN(num_selected, maxshowdevs); - if (hflag) { + if (hflag) xo_emit("{T:procs} {T:memory} {T:/page%*s}", 19, ""); - } else { + else xo_emit("{T:procs} {T:memory} {T:/page%*s}", 19, ""); - } if (num_shown > 1) - xo_emit(" {T:/disks %*s}", num_shown * 4 - 7, ""); + xo_emit(" {T:/disks %*s}", num_shown * 4 - 7, ""); else if (num_shown == 1) xo_emit(" {T:disks}"); xo_emit(" {T:faults} "); @@ -968,16 +947,18 @@ printhdr(int maxid, u_long cpumask) } else xo_emit(" {T:cpu}\n"); if (hflag) { - xo_emit("{T:r} {T:b} {T:w} {T:avm} {T:fre} {T:flt} {T:re} {T:pi} {T:po} {T:fr} {T:sr} "); + xo_emit("{T:r} {T:b} {T:w} {T:avm} {T:fre} {T:flt} {T:re}" + " {T:pi} {T:po} {T:fr} {T:sr} "); } else { - xo_emit("{T:r} {T:b} {T:w} {T:avm} {T:fre} {T:flt} {T:re} {T:pi} {T:po} {T:fr} {T:sr} "); + xo_emit("{T:r} {T:b} {T:w} {T:avm} {T:fre} {T:flt} " + "{T:re} {T:pi} {T:po} {T:fr} {T:sr} "); } for (i = 0; i < num_devices; i++) - if ((dev_select[i].selected) - && (dev_select[i].selected <= maxshowdevs)) + if ((dev_select[i].selected) && + (dev_select[i].selected <= maxshowdevs)) xo_emit("{T:/%c%c%d} ", dev_select[i].device_name[0], - dev_select[i].device_name[1], - dev_select[i].unit_number); + dev_select[i].device_name[1], + dev_select[i].unit_number); xo_emit(" {T:in} {T:sy} {T:cs}"); if (Pflag) { for (i = 0; i <= maxid; i++) { @@ -1008,7 +989,7 @@ needhdr(int dummy __unused) * prepended to the next output. */ void -needresize(int signo) +needresize(int signo __unused) { wresized = 1; @@ -1021,8 +1002,8 @@ needresize(int signo) void doresize(void) { - int status; struct winsize w; + int status; for (;;) { status = ioctl(fileno(stdout), TIOCGWINSZ, &w); @@ -1053,13 +1034,13 @@ dotimes(void) kread(X_PGIN, &pgintime, sizeof(pgintime)); kread(X_SUM, &sum, sizeof(sum)); xo_emit("{:page-reclaims/%u} {N:reclaims}, " - "{:reclaim-time/%u} {N:total time (usec)}\n", + "{:reclaim-time/%u} {N:total time (usec)}\n", sum.v_pgrec, rectime); xo_emit("{L:average}: {:reclaim-average/%u} {N:usec \\/ reclaim}\n", - rectime / sum.v_pgrec); + rectime / sum.v_pgrec); xo_emit("\n"); xo_emit("{:page-ins/%u} {N:page ins}, " - "{:page-in-time/%u} {N:total time (msec)}\n", + "{:page-in-time/%u} {N:total time (msec)}\n", sum.v_pgin, pgintime / 10); xo_emit("{L:average}: {:average/%8.1f} {N:msec \\/ page in}\n", pgintime / (sum.v_pgin * 10.0)); @@ -1083,93 +1064,94 @@ static void dosum(void) { struct nchstats lnchstats; + size_t size; long nchtotal; fill_vmmeter(&sum); xo_open_container("summary-statistics"); xo_emit("{:context-switches/%9u} {N:cpu context switches}\n", - sum.v_swtch); + sum.v_swtch); xo_emit("{:interrupts/%9u} {N:device interrupts}\n", - sum.v_intr); + sum.v_intr); xo_emit("{:software-interrupts/%9u} {N:software interrupts}\n", - sum.v_soft); + sum.v_soft); xo_emit("{:traps/%9u} {N:traps}\n", sum.v_trap); xo_emit("{:system-calls/%9u} {N:system calls}\n", - sum.v_syscall); + sum.v_syscall); xo_emit("{:kernel-threads/%9u} {N:kernel threads created}\n", - sum.v_kthreads); + sum.v_kthreads); xo_emit("{:forks/%9u} {N: fork() calls}\n", sum.v_forks); xo_emit("{:vforks/%9u} {N:vfork() calls}\n", - sum.v_vforks); + sum.v_vforks); xo_emit("{:rforks/%9u} {N:rfork() calls}\n", - sum.v_rforks); + sum.v_rforks); xo_emit("{:swap-ins/%9u} {N:swap pager pageins}\n", - sum.v_swapin); + sum.v_swapin); xo_emit("{:swap-in-pages/%9u} {N:swap pager pages paged in}\n", - sum.v_swappgsin); + sum.v_swappgsin); xo_emit("{:swap-outs/%9u} {N:swap pager pageouts}\n", - sum.v_swapout); + sum.v_swapout); xo_emit("{:swap-out-pages/%9u} {N:swap pager pages paged out}\n", - sum.v_swappgsout); + sum.v_swappgsout); xo_emit("{:vnode-page-ins/%9u} {N:vnode pager pageins}\n", - sum.v_vnodein); + sum.v_vnodein); xo_emit("{:vnode-page-in-pages/%9u} {N:vnode pager pages paged in}\n", - sum.v_vnodepgsin); + sum.v_vnodepgsin); xo_emit("{:vnode-page-outs/%9u} {N:vnode pager pageouts}\n", - sum.v_vnodeout); + sum.v_vnodeout); xo_emit("{:vnode-page-out-pages/%9u} {N:vnode pager pages paged out}\n", - sum.v_vnodepgsout); + sum.v_vnodepgsout); xo_emit("{:page-daemon-wakeups/%9u} {N:page daemon wakeups}\n", - sum.v_pdwakeups); - xo_emit("{:page-daemon-pages/%9u} {N:pages examined by the page daemon}\n", - sum.v_pdpages); - xo_emit("{:page-reclamation-shortfalls/%9u} {N:clean page reclamation shortfalls}\n", - sum.v_pdshortfalls); + sum.v_pdwakeups); + xo_emit("{:page-daemon-pages/%9u} {N:pages examined by the page " + "daemon}\n", sum.v_pdpages); + xo_emit("{:page-reclamation-shortfalls/%9u} {N:clean page reclamation " + "shortfalls}\n", sum.v_pdshortfalls); xo_emit("{:reactivated/%9u} {N:pages reactivated by the page daemon}\n", - sum.v_reactivated); + sum.v_reactivated); xo_emit("{:copy-on-write-faults/%9u} {N:copy-on-write faults}\n", - sum.v_cow_faults); - xo_emit("{:copy-on-write-optimized-faults/%9u} {N:copy-on-write optimized faults}\n", - sum.v_cow_optim); + sum.v_cow_faults); + xo_emit("{:copy-on-write-optimized-faults/%9u} {N:copy-on-write " + "optimized faults}\n", sum.v_cow_optim); xo_emit("{:zero-fill-pages/%9u} {N:zero fill pages zeroed}\n", - sum.v_zfod); + sum.v_zfod); xo_emit("{:zero-fill-prezeroed/%9u} {N:zero fill pages prezeroed}\n", - sum.v_ozfod); + sum.v_ozfod); xo_emit("{:intransit-blocking/%9u} {N:intransit blocking page faults}\n", - sum.v_intrans); + sum.v_intrans); xo_emit("{:total-faults/%9u} {N:total VM faults taken}\n", - sum.v_vm_faults); + sum.v_vm_faults); xo_emit("{:faults-requiring-io/%9u} {N:page faults requiring I\\/O}\n", - sum.v_io_faults); - xo_emit("{:faults-from-thread-creation/%9u} {N:pages affected by kernel thread creation}\n", - sum.v_kthreadpages); + sum.v_io_faults); + xo_emit("{:faults-from-thread-creation/%9u} {N:pages affected by " + "kernel thread creation}\n", sum.v_kthreadpages); xo_emit("{:faults-from-fork/%9u} {N:pages affected by fork}()\n", - sum.v_forkpages); + sum.v_forkpages); xo_emit("{:faults-from-vfork/%9u} {N:pages affected by vfork}()\n", - sum.v_vforkpages); + sum.v_vforkpages); xo_emit("{:pages-rfork/%9u} {N:pages affected by rfork}()\n", - sum.v_rforkpages); + sum.v_rforkpages); xo_emit("{:pages-freed/%9u} {N:pages freed}\n", - sum.v_tfree); + sum.v_tfree); xo_emit("{:pages-freed-by-daemon/%9u} {N:pages freed by daemon}\n", - sum.v_dfree); + sum.v_dfree); xo_emit("{:pages-freed-on-exit/%9u} {N:pages freed by exiting processes}\n", - sum.v_pfree); + sum.v_pfree); xo_emit("{:active-pages/%9u} {N:pages active}\n", - sum.v_active_count); + sum.v_active_count); xo_emit("{:inactive-pages/%9u} {N:pages inactive}\n", - sum.v_inactive_count); + sum.v_inactive_count); xo_emit("{:laundry-pages/%9u} {N:pages in the laundry queue}\n", - sum.v_laundry_count); + sum.v_laundry_count); xo_emit("{:wired-pages/%9u} {N:pages wired down}\n", - sum.v_wire_count); + sum.v_wire_count); xo_emit("{:free-pages/%9u} {N:pages free}\n", - sum.v_free_count); + sum.v_free_count); xo_emit("{:bytes-per-page/%9u} {N:bytes per page}\n", sum.v_page_size); if (kd != NULL) { kread(X_NCHSTATS, &lnchstats, sizeof(lnchstats)); } else { - size_t size = sizeof(lnchstats); + size = sizeof(lnchstats); mysysctl("vfs.cache.nchstats", &lnchstats, &size); if (size != sizeof(lnchstats)) xo_errx(1, "vfs.cache.nchstats size mismatch"); @@ -1178,17 +1160,17 @@ dosum(void) lnchstats.ncs_badhits + lnchstats.ncs_falsehits + lnchstats.ncs_miss + lnchstats.ncs_long; xo_emit("{:total-name-lookups/%9ld} {N:total name lookups}\n", - nchtotal); + nchtotal); xo_emit("{P:/%9s} {N:cache hits} " - "({:positive-cache-hits/%ld}% pos + " - "{:negative-cache-hits/%ld}% {N:neg}) " - "system {:cache-hit-percent/%ld}% per-directory\n", + "({:positive-cache-hits/%ld}% pos + " + "{:negative-cache-hits/%ld}% {N:neg}) " + "system {:cache-hit-percent/%ld}% per-directory\n", "", PCT(lnchstats.ncs_goodhits, nchtotal), PCT(lnchstats.ncs_neghits, nchtotal), PCT(lnchstats.ncs_pass2, nchtotal)); xo_emit("{P:/%9s} {L:deletions} {:deletions/%ld}%, " - "{L:falsehits} {:false-hits/%ld}%, " - "{L:toolong} {:too-long/%ld}%\n", "", + "{L:falsehits} {:false-hits/%ld}%, " + "{L:toolong} {:too-long/%ld}%\n", "", PCT(lnchstats.ncs_badhits, nchtotal), PCT(lnchstats.ncs_falsehits, nchtotal), PCT(lnchstats.ncs_long, nchtotal)); @@ -1198,20 +1180,21 @@ dosum(void) static void doforkst(void) { + fill_vmmeter(&sum); xo_open_container("fork-statistics"); xo_emit("{:fork/%u} {N:forks}, {:fork-pages/%u} {N:pages}, " - "{L:average} {:fork-average/%.2f}\n", + "{L:average} {:fork-average/%.2f}\n", sum.v_forks, sum.v_forkpages, sum.v_forks == 0 ? 0.0 : (double)sum.v_forkpages / sum.v_forks); xo_emit("{:vfork/%u} {N:vforks}, {:vfork-pages/%u} {N:pages}, " - "{L:average} {:vfork-average/%.2f}\n", + "{L:average} {:vfork-average/%.2f}\n", sum.v_vforks, sum.v_vforkpages, sum.v_vforks == 0 ? 0.0 : (double)sum.v_vforkpages / sum.v_vforks); xo_emit("{:rfork/%u} {N:rforks}, {:rfork-pages/%u} {N:pages}, " - "{L:average} {:rfork-average/%.2f}\n", + "{L:average} {:rfork-average/%.2f}\n", sum.v_rforks, sum.v_rforkpages, sum.v_rforks == 0 ? 0.0 : (double)sum.v_rforkpages / sum.v_rforks); @@ -1221,10 +1204,9 @@ doforkst(void) static void devstats(void) { - int dn, state; - long double transfers_per_second; - long double busy_seconds; + long double busy_seconds, transfers_per_second; long tmp; + int di, dn, state; for (state = 0; state < CPUSTATES; ++state) { tmp = cur.cp_time[state]; @@ -1236,10 +1218,8 @@ devstats(void) xo_open_list("device"); for (dn = 0; dn < num_devices; dn++) { - int di; - - if ((dev_select[dn].selected == 0) - || (dev_select[dn].selected > maxshowdevs)) + if (dev_select[dn].selected == 0 || + dev_select[dn].selected > maxshowdevs) continue; di = dev_select[dn].position; @@ -1252,24 +1232,24 @@ devstats(void) xo_open_instance("device"); xo_emit("{ekq:name/%c%c%d}{:transfers/%3.0Lf} ", - dev_select[dn].device_name[0], - dev_select[dn].device_name[1], - dev_select[dn].unit_number, - transfers_per_second); + dev_select[dn].device_name[0], + dev_select[dn].device_name[1], + dev_select[dn].unit_number, + transfers_per_second); xo_close_instance("device"); } xo_close_list("device"); } static void -percent(const char *name, double pct, int *over) +percent(const char *name, double pctv, int *over) { + int l; char buf[10]; char fmt[128]; - int l; snprintf(fmt, sizeof(fmt), " {:%s/%%*s}", name); - l = snprintf(buf, sizeof(buf), "%.0f", pct); + l = snprintf(buf, sizeof(buf), "%.0f", pctv); if (l == 1 && *over) { xo_emit(fmt, 1, buf); (*over)--; @@ -1282,8 +1262,8 @@ percent(const char *name, double pct, int *over) static void cpustats(void) { - int state, over; double lpct, total; + int state, over; total = 0; for (state = 0; state < CPUSTATES; ++state) @@ -1294,19 +1274,20 @@ cpustats(void) lpct = 0.0; over = 0; xo_open_container("cpu-statistics"); - percent("user", (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * lpct, &over); - percent("system", (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * lpct, &over); + percent("user", (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * lpct, + &over); + percent("system", (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * lpct, + &over); percent("idle", cur.cp_time[CP_IDLE] * lpct, &over); xo_close_container("cpu-statistics"); } static void -pcpustats(int ncpus, u_long cpumask, int maxid) +pcpustats(u_long cpumask, int maxid) { - int state, i; double lpct, total; long tmp; - int over; + int i, over, state; /* devstats does this for cp_time */ for (i = 0; i <= maxid; i++) { @@ -1335,11 +1316,11 @@ pcpustats(int ncpus, u_long cpumask, int maxid) else lpct = 0.0; percent("user", (cur_cp_times[i * CPUSTATES + CP_USER] + - cur_cp_times[i * CPUSTATES + CP_NICE]) * lpct, &over); + cur_cp_times[i * CPUSTATES + CP_NICE]) * lpct, &over); percent("system", (cur_cp_times[i * CPUSTATES + CP_SYS] + - cur_cp_times[i * CPUSTATES + CP_INTR]) * lpct, &over); + cur_cp_times[i * CPUSTATES + CP_INTR]) * lpct, &over); percent("idle", cur_cp_times[i * CPUSTATES + CP_IDLE] * lpct, - &over); + &over); xo_close_instance("cpu"); } xo_close_list("cpu"); @@ -1370,12 +1351,12 @@ read_intrcnts(unsigned long **intrcnts) static void print_intrcnts(unsigned long *intrcnts, unsigned long *old_intrcnts, - char *intrnames, unsigned int nintr, - size_t istrnamlen, long long period_ms) + char *intrnames, unsigned int nintr, size_t istrnamlen, long long period_ms) { unsigned long *intrcnt, *old_intrcnt; + char *intrname; uint64_t inttotal, old_inttotal, total_count, total_rate; - char* intrname; + unsigned long count, rate; unsigned int i; inttotal = 0; @@ -1384,15 +1365,12 @@ print_intrcnts(unsigned long *intrcnts, unsigned long *old_intrcnts, xo_open_list("interrupt"); for (i = 0, intrcnt=intrcnts, old_intrcnt=old_intrcnts; i < nintr; i++) { if (intrname[0] != '\0' && (*intrcnt != 0 || aflag)) { - unsigned long count, rate; - count = *intrcnt - *old_intrcnt; rate = (count * 1000 + period_ms / 2) / period_ms; xo_open_instance("interrupt"); xo_emit("{d:name/%-*s}{ket:name/%s} " "{:total/%20lu} {:rate/%10lu}\n", - (int)istrnamlen, intrname, - intrname, count, rate); + (int)istrnamlen, intrname, intrname, count, rate); xo_close_instance("interrupt"); } intrname += strlen(intrname) + 1; @@ -1402,20 +1380,21 @@ print_intrcnts(unsigned long *intrcnts, unsigned long *old_intrcnts, total_count = inttotal - old_inttotal; total_rate = (total_count * 1000 + period_ms / 2) / period_ms; xo_close_list("interrupt"); - xo_emit("{L:/%-*s} {:total-interrupts/%20" PRIu64 "} " - "{:total-rate/%10" PRIu64 "}\n", (int)istrnamlen, - "Total", total_count, total_rate); + xo_emit("{L:/%-*s} {:total-interrupts/%20ju} " + "{:total-rate/%10ju}\n", (int)istrnamlen, + "Total", (uintmax_t)total_count, (uintmax_t)total_rate); } static void dointr(unsigned int interval, int reps) { - unsigned long *intrcnts; - long long uptime, period_ms; - unsigned long *old_intrcnts = NULL; + unsigned long *intrcnts, *old_intrcnts; + char *intrname, *intrnames; + long long period_ms, old_uptime, uptime; size_t clen, inamlen, istrnamlen; - char *intrnames, *intrname; + unsigned int nintr; + old_intrcnts = NULL; uptime = getuptime(); /* Get the names of each interrupt source */ @@ -1443,7 +1422,7 @@ dointr(unsigned int interval, int reps) intrname += strlen(intrname) + 1; } xo_emit("{T:/%-*s} {T:/%20s} {T:/%10s}\n", - (int)istrnamlen, "interrupt", "total", "rate"); + (int)istrnamlen, "interrupt", "total", "rate"); /* * Loop reps times printing differential interrupt counts. If reps is @@ -1453,9 +1432,6 @@ dointr(unsigned int interval, int reps) period_ms = uptime / 1000000; while(1) { - unsigned int nintr; - long long old_uptime; - nintr = read_intrcnts(&intrcnts); /* * Initialize old_intrcnts to 0 for the first pass, so @@ -1515,7 +1491,7 @@ domemstat_malloc(void) } xo_open_container("malloc-statistics"); xo_emit("{T:/%13s} {T:/%5s} {T:/%6s} {T:/%7s} {T:/%8s} {T:Size(s)}\n", - "Type", "InUse", "MemUse", "HighUse", "Requests"); + "Type", "InUse", "MemUse", "HighUse", "Requests"); xo_open_list("memory"); for (mtp = memstat_mtl_first(mtlp); mtp != NULL; mtp = memstat_mtl_next(mtp)) { @@ -1523,12 +1499,12 @@ domemstat_malloc(void) memstat_get_count(mtp) == 0) continue; xo_open_instance("memory"); - xo_emit("{k:type/%13s/%s} {:in-use/%5" PRIu64 "} " - "{:memory-use/%5" PRIu64 "}{U:K} {:high-use/%7s} " - "{:requests/%8" PRIu64 "} ", - memstat_get_name(mtp), memstat_get_count(mtp), - (memstat_get_bytes(mtp) + 1023) / 1024, "-", - memstat_get_numallocs(mtp)); + xo_emit("{k:type/%13s/%s} {:in-use/%5ju} " + "{:memory-use/%5ju}{U:K} {:high-use/%7s} " + "{:requests/%8ju} ", + memstat_get_name(mtp), (uintmax_t)memstat_get_count(mtp), + ((uintmax_t)memstat_get_bytes(mtp) + 1023) / 1024, "-", + (uintmax_t)memstat_get_numallocs(mtp)); first = 1; xo_open_list("size"); for (i = 0; i < 32; i++) { @@ -1554,10 +1530,10 @@ domemstat_zone(void) { struct memory_type_list *mtlp; struct memory_type *mtp; - char name[MEMTYPE_MAXNAME + 1]; #ifndef __rtems__ int error; #endif /* __rtems__ */ + char name[MEMTYPE_MAXNAME + 1]; mtlp = memstat_mtl_alloc(); if (mtlp == NULL) { @@ -1588,23 +1564,26 @@ domemstat_zone(void) } xo_open_container("memory-zone-statistics"); xo_emit("{T:/%-20s} {T:/%6s} {T:/%6s} {T:/%8s} {T:/%8s} {T:/%8s} " - "{T:/%4s} {T:/%4s}\n\n", "ITEM", "SIZE", - "LIMIT", "USED", "FREE", "REQ", "FAIL", "SLEEP"); + "{T:/%4s} {T:/%4s}\n\n", "ITEM", "SIZE", + "LIMIT", "USED", "FREE", "REQ", "FAIL", "SLEEP"); xo_open_list("zone"); for (mtp = memstat_mtl_first(mtlp); mtp != NULL; mtp = memstat_mtl_next(mtp)) { strlcpy(name, memstat_get_name(mtp), MEMTYPE_MAXNAME); strcat(name, ":"); xo_open_instance("zone"); - xo_emit("{d:name/%-20s}{ke:name/%s} {:size/%6" PRIu64 "}, " - "{:limit/%6" PRIu64 "},{:used/%8" PRIu64 "}," - "{:free/%8" PRIu64 "},{:requests/%8" PRIu64 "}," - "{:fail/%4" PRIu64 "},{:sleep/%4" PRIu64 "}\n", name, - memstat_get_name(mtp), - memstat_get_size(mtp), memstat_get_countlimit(mtp), - memstat_get_count(mtp), memstat_get_free(mtp), - memstat_get_numallocs(mtp), memstat_get_failures(mtp), - memstat_get_sleeps(mtp)); + xo_emit("{d:name/%-20s}{ke:name/%s} {:size/%6ju}, " + "{:limit/%6ju},{:used/%8ju}," + "{:free/%8ju},{:requests/%8ju}," + "{:fail/%4ju},{:sleep/%4ju}\n", name, + memstat_get_name(mtp), + (uintmax_t)memstat_get_size(mtp), + (uintmax_t)memstat_get_countlimit(mtp), + (uintmax_t)memstat_get_count(mtp), + (uintmax_t)memstat_get_free(mtp), + (uintmax_t)memstat_get_numallocs(mtp), + (uintmax_t)memstat_get_failures(mtp), + (uintmax_t)memstat_get_sleeps(mtp)); xo_close_instance("zone"); } memstat_mtl_free(mtlp); @@ -1736,7 +1715,7 @@ doobjstat(void) return; } xo_emit("{T:RES/%5s} {T:ACT/%5s} {T:INACT/%5s} {T:REF/%3s} {T:SHD/%3s} " - "{T:CM/%3s} {T:TP/%2s} {T:PATH/%s}\n"); + "{T:CM/%3s} {T:TP/%2s} {T:PATH/%s}\n"); xo_open_list("object"); for (i = 0; i < cnt; i++) display_object(&kvo[i]); @@ -1770,26 +1749,8 @@ kreado(int nlx, void *addr, size_t size, size_t offset) static void kread(int nlx, void *addr, size_t size) { - kreado(nlx, addr, size, 0); -} -static char * -kgetstr(const char *strp) -{ - int n = 0, size = 1; - char *ret = NULL; - - do { - if (size == n + 1) { - ret = realloc(ret, size); - if (ret == NULL) - xo_err(1, "%s: realloc", __func__); - size *= 2; - } - if (kvm_read(kd, (u_long)strp + n, &ret[n], 1) != 1) - xo_errx(1, "%s: %s", __func__, kvm_geterr(kd)); - } while (ret[n++] != '\0'); - return (ret); + kreado(nlx, addr, size, 0); } #endif /* __rtems__ */ @@ -1797,8 +1758,8 @@ static void usage(void) { xo_error("%s%s", - "usage: vmstat [-afHhimoPsz] [-M core [-N system]] [-c count] [-n devs]\n", - " [-p type,if,pass] [-w wait] [disks] [wait [count]]\n"); + "usage: vmstat [-afHhimoPsz] [-M core [-N system]] [-c count] [-n devs]\n", + " [-p type,if,pass] [-w wait] [disks] [wait [count]]\n"); xo_finish(); exit(1); } @@ -302,22 +302,24 @@ class rtems(builder.Module): 'pppd/sys-rtems.c', 'pppd/upap.c', 'pppd/utils.c', + 'sys/arm/lpc/if_lpe.c', + 'sys/arm/lpc/lpc_pwr.c', + 'sys/dev/atsam/if_atsam.c', + 'sys/dev/atsam/if_atsam_media.c', + 'sys/dev/dw_mmc/dw_mmc.c', + 'sys/dev/ffec/if_ffec_mcf548x.c', 'sys/dev/input/touchscreen/tsc_lpc32xx.c', + 'sys/dev/smc/if_smc_nexus.c', + 'sys/dev/tsec/if_tsec_nexus.c', 'sys/dev/usb/controller/ehci_mpc83xx.c', - 'sys/dev/usb/controller/ohci_lpc.c', 'sys/dev/usb/controller/ohci_lpc32xx.c', + 'sys/dev/usb/controller/ohci_lpc.c', 'sys/dev/usb/controller/usb_otg_transceiver.c', 'sys/dev/usb/controller/usb_otg_transceiver_dump.c', - 'sys/dev/smc/if_smc_nexus.c', - 'sys/dev/ffec/if_ffec_mcf548x.c', - 'sys/dev/atsam/if_atsam.c', - 'sys/dev/atsam/if_atsam_media.c', - 'sys/dev/dw_mmc/dw_mmc.c', 'sys/fs/devfs/devfs_devs.c', 'sys/net/if_ppp.c', 'sys/net/ppp_tty.c', 'telnetd/telnetd-service.c', - 'sys/dev/tsec/if_tsec_nexus.c', ], mm.generator['source']() ) @@ -374,6 +376,8 @@ class base(builder.Module): 'sys/sys/cpu.h', 'sys/sys/ctype.h', 'sys/sys/domain.h', + 'sys/sys/_domainset.h', + 'sys/sys/domainset.h', 'sys/sys/eventhandler.h', 'sys/sys/fail.h', 'sys/sys/filedesc.h', @@ -454,6 +458,7 @@ class base(builder.Module): 'sys/sys/systm.h', 'sys/sys/_task.h', 'sys/sys/taskqueue.h', + 'sys/sys/tslog.h', 'sys/sys/nlist_aout.h', 'sys/rpc/netconfig.h', 'sys/rpc/types.h', @@ -1344,9 +1349,6 @@ class dev_net(builder.Module): mm = self.manager self.addKernelSpaceHeaderFiles( [ - 'sys/arm/lpc/if_lpereg.h', - 'sys/arm/lpc/lpcreg.h', - 'sys/arm/lpc/lpcvar.h', 'sys/arm/xilinx/zy7_slcr.h', 'sys/dev/cadence/if_cgem_hw.h', 'sys/dev/dwc/if_dwc.h', @@ -1395,8 +1397,6 @@ class dev_net(builder.Module): 'sys/dev/cadence/if_cgem.c', 'sys/dev/dwc/if_dwc.c', 'sys/arm/xilinx/zy7_slcr.c', - 'sys/arm/lpc/lpc_pwr.c', - 'sys/arm/lpc/if_lpe.c', ], mm.generator['source']() ) @@ -4056,6 +4056,7 @@ class usr_sbin_tcpdump(builder.Module): 'contrib/tcpdump/ether.h', 'contrib/tcpdump/ethertype.h', 'contrib/tcpdump/extract.h', + 'contrib/tcpdump/funcattrs.h', 'contrib/tcpdump/gmpls.h', 'contrib/tcpdump/gmt2local.h', 'contrib/tcpdump/interface.h', diff --git a/rtemsbsd/include/machine/_limits.h b/rtemsbsd/include/machine/_limits.h index c7187c60..18383c33 100644 --- a/rtemsbsd/include/machine/_limits.h +++ b/rtemsbsd/include/machine/_limits.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2009, 2018 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -46,4 +46,6 @@ #define __INT_MAX INT_MAX +#define __SIZE_T_MAX __SIZE_MAX__ + #endif /* _RTEMS_BSD_MACHINE__LIMITS_H_ */ diff --git a/rtemsbsd/include/machine/atomic.h b/rtemsbsd/include/machine/atomic.h index b95a4b5a..f7de4178 100644 --- a/rtemsbsd/include/machine/atomic.h +++ b/rtemsbsd/include/machine/atomic.h @@ -492,6 +492,27 @@ atomic_readandclear_int(volatile int *p) } static inline int +atomic_load_int(volatile int *p) +{ + int tmp; + +#if defined(_RTEMS_BSD_MACHINE_ATOMIC_USE_ATOMIC) + std::atomic_int *q = + reinterpret_cast<std::atomic_int *>(const_cast<int *>(p)); + + tmp = q->load(std::memory_order_relaxed); +#elif defined(_RTEMS_BSD_MACHINE_ATOMIC_USE_STDATOMIC) + atomic_int *q = (atomic_int *)RTEMS_DEVOLATILE(int *, p); + + tmp = atomic_load_explicit(q, memory_order_relaxed); +#else + tmp = *p; +#endif + + return (tmp); +} + +static inline int atomic_load_acq_int(volatile int *p) { int tmp; @@ -514,6 +535,23 @@ atomic_load_acq_int(volatile int *p) } static inline void +atomic_store_int(volatile int *p, int v) +{ +#if defined(_RTEMS_BSD_MACHINE_ATOMIC_USE_ATOMIC) + std::atomic_int *q = + reinterpret_cast<std::atomic_int *>(const_cast<int *>(p)); + + q->store(v, std::memory_order_relaxed); +#elif defined(_RTEMS_BSD_MACHINE_ATOMIC_USE_STDATOMIC) + atomic_int *q = (atomic_int *)RTEMS_DEVOLATILE(int *, p); + + atomic_store_explicit(q, v, memory_order_relaxed); +#else + *p = v; +#endif +} + +static inline void atomic_store_rel_int(volatile int *p, int v) { #if defined(_RTEMS_BSD_MACHINE_ATOMIC_USE_ATOMIC) diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h index dd0b2ed2..3bdb6916 100644 --- a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h +++ b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h @@ -1744,6 +1744,7 @@ #define ieee80211_wme_initparams _bsd_ieee80211_wme_initparams #define ieee80211_wme_updateparams _bsd_ieee80211_wme_updateparams #define ieee80211_wme_updateparams_locked _bsd_ieee80211_wme_updateparams_locked +#define ieee80211_wme_vap_ac_is_noack _bsd_ieee80211_wme_vap_ac_is_noack #define ieee80211_wme_vap_getparams _bsd_ieee80211_wme_vap_getparams #define ifa_add_loopback_route _bsd_ifa_add_loopback_route #define ifa_alloc _bsd_ifa_alloc @@ -2594,6 +2595,7 @@ #define make_dev_args_init_impl _bsd_make_dev_args_init_impl #define make_dev_s _bsd_make_dev_s #define M_ALIAS _bsd_M_ALIAS +#define mallocarray _bsd_mallocarray #define malloc_init _bsd_malloc_init #define malloc_uninit _bsd_malloc_uninit #define m_append _bsd_m_append @@ -3207,6 +3209,7 @@ #define pf_pull_hdr _bsd_pf_pull_hdr #define pf_purge_expired_fragments _bsd_pf_purge_expired_fragments #define pf_purge_expired_src_nodes _bsd_pf_purge_expired_src_nodes +#define pf_purge_fragments _bsd_pf_purge_fragments #define pf_purge_proc _bsd_pf_purge_proc #define pf_purge_thread _bsd_pf_purge_thread #define pf_qids _bsd_pf_qids @@ -4043,7 +4046,6 @@ #define sctp_deact_sharedkey_ep _bsd_sctp_deact_sharedkey_ep #define sctp_default_supported_hmaclist _bsd_sctp_default_supported_hmaclist #define sctp_del_addr_from_vrf _bsd_sctp_del_addr_from_vrf -#define sctp_delayed_cksum _bsd_sctp_delayed_cksum #define sctp_delete_from_timewait _bsd_sctp_delete_from_timewait #define sctp_delete_prim_timer _bsd_sctp_delete_prim_timer #define sctp_delete_sharedkey _bsd_sctp_delete_sharedkey @@ -4654,6 +4656,7 @@ #define tcp6_usrreqs _bsd_tcp6_usrreqs #define tcp_abc_l_var _bsd_tcp_abc_l_var #define tcp_addoptions _bsd_tcp_addoptions +#define tcp_always_keepalive _bsd_tcp_always_keepalive #define tcp_autorcvbuf _bsd_tcp_autorcvbuf #define tcp_autorcvbuf_inc _bsd_tcp_autorcvbuf_inc #define tcp_autorcvbuf_max _bsd_tcp_autorcvbuf_max @@ -4770,6 +4773,7 @@ #define tcp_sendspace _bsd_tcp_sendspace #define tcp_setpersist _bsd_tcp_setpersist #define tcp_slowtimo _bsd_tcp_slowtimo +#define tcp_sndbuf_autoscale _bsd_tcp_sndbuf_autoscale #define tcps_states _bsd_tcps_states #define tcpstat _bsd_tcpstat #define tcp_state_change _bsd_tcp_state_change @@ -4963,6 +4967,7 @@ #define ulitecb _bsd_ulitecb #define ulitecbinfo _bsd_ulitecbinfo #define uma_align_cache _bsd_uma_align_cache +#define uma_avail _bsd_uma_avail #define uma_limit _bsd_uma_limit #define uma_print_stats _bsd_uma_print_stats #define uma_print_zone _bsd_uma_print_zone @@ -4974,10 +4979,12 @@ #define uma_size _bsd_uma_size #define uma_startup _bsd_uma_startup #define uma_zalloc_arg _bsd_uma_zalloc_arg +#define uma_zalloc_domain _bsd_uma_zalloc_domain #define uma_zcache_create _bsd_uma_zcache_create #define uma_zcreate _bsd_uma_zcreate #define uma_zdestroy _bsd_uma_zdestroy #define uma_zfree_arg _bsd_uma_zfree_arg +#define uma_zfree_domain _bsd_uma_zfree_domain #define uma_zone_exhausted _bsd_uma_zone_exhausted #define uma_zone_exhausted_nolock _bsd_uma_zone_exhausted_nolock #define uma_zone_get_cur _bsd_uma_zone_get_cur diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h index bfdc27ec..b22d73e2 100644 --- a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h +++ b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h @@ -92,4 +92,6 @@ void rtems_bsd_assert_func(const char *file, int line, const char *func, const c #define ENOIOCTL (-3) /* ioctl not handled by this layer */ #define EDIRIOCTL (-4) /* do direct ioctl in GEOM */ +#define EDOOFUS __ELASTERROR + #endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_KERNEL_SPACE_H_ */ diff --git a/rtemsbsd/include/rtems/bsd/local/device_if.h b/rtemsbsd/include/rtems/bsd/local/device_if.h index e27c2b52..2f085cbf 100644 --- a/rtemsbsd/include/rtems/bsd/local/device_if.h +++ b/rtemsbsd/include/rtems/bsd/local/device_if.h @@ -23,6 +23,9 @@ #ifndef _device_if_h_ #define _device_if_h_ + +#include <sys/tslog.h> + /** @brief Unique descriptor for the DEVICE_PROBE() method */ extern struct kobjop_desc device_probe_desc; /** @brief A function implementing the DEVICE_PROBE() method */ @@ -104,8 +107,16 @@ typedef int device_probe_t(device_t dev); static __inline int DEVICE_PROBE(device_t dev) { kobjop_t _m; + int rc; + +TSENTER2(device_get_name(dev)); + KOBJOPLOOKUP(((kobj_t)dev)->ops,device_probe); - return ((device_probe_t *) _m)(dev); + rc = ((device_probe_t *) _m)(dev); + +TSEXIT2(device_get_name(dev)); + + return (rc); } /** @brief Unique descriptor for the DEVICE_IDENTIFY() method */ @@ -176,8 +187,16 @@ typedef int device_attach_t(device_t dev); static __inline int DEVICE_ATTACH(device_t dev) { kobjop_t _m; + int rc; + +TSENTER2(device_get_name(dev)); + KOBJOPLOOKUP(((kobj_t)dev)->ops,device_attach); - return ((device_attach_t *) _m)(dev); + rc = ((device_attach_t *) _m)(dev); + +TSEXIT2(device_get_name(dev)); + + return (rc); } /** @brief Unique descriptor for the DEVICE_DETACH() method */ @@ -210,8 +229,10 @@ typedef int device_detach_t(device_t dev); static __inline int DEVICE_DETACH(device_t dev) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)dev)->ops,device_detach); - return ((device_detach_t *) _m)(dev); + rc = ((device_detach_t *) _m)(dev); + return (rc); } /** @brief Unique descriptor for the DEVICE_SHUTDOWN() method */ @@ -236,8 +257,10 @@ typedef int device_shutdown_t(device_t dev); static __inline int DEVICE_SHUTDOWN(device_t dev) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)dev)->ops,device_shutdown); - return ((device_shutdown_t *) _m)(dev); + rc = ((device_shutdown_t *) _m)(dev); + return (rc); } /** @brief Unique descriptor for the DEVICE_SUSPEND() method */ @@ -271,8 +294,10 @@ typedef int device_suspend_t(device_t dev); static __inline int DEVICE_SUSPEND(device_t dev) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)dev)->ops,device_suspend); - return ((device_suspend_t *) _m)(dev); + rc = ((device_suspend_t *) _m)(dev); + return (rc); } /** @brief Unique descriptor for the DEVICE_RESUME() method */ @@ -301,8 +326,10 @@ typedef int device_resume_t(device_t dev); static __inline int DEVICE_RESUME(device_t dev) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)dev)->ops,device_resume); - return ((device_resume_t *) _m)(dev); + rc = ((device_resume_t *) _m)(dev); + return (rc); } /** @brief Unique descriptor for the DEVICE_QUIESCE() method */ @@ -335,8 +362,10 @@ typedef int device_quiesce_t(device_t dev); static __inline int DEVICE_QUIESCE(device_t dev) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)dev)->ops,device_quiesce); - return ((device_quiesce_t *) _m)(dev); + rc = ((device_quiesce_t *) _m)(dev); + return (rc); } /** @brief Unique descriptor for the DEVICE_REGISTER() method */ @@ -364,8 +393,10 @@ typedef void * device_register_t(device_t dev); static __inline void * DEVICE_REGISTER(device_t dev) { kobjop_t _m; + void * rc; KOBJOPLOOKUP(((kobj_t)dev)->ops,device_register); - return ((device_register_t *) _m)(dev); + rc = ((device_register_t *) _m)(dev); + return (rc); } #endif /* _device_if_h_ */ diff --git a/rtemsbsd/include/rtems/bsd/local/ifdi_if.h b/rtemsbsd/include/rtems/bsd/local/ifdi_if.h index b1a5da05..a1b92481 100644 --- a/rtemsbsd/include/rtems/bsd/local/ifdi_if.h +++ b/rtemsbsd/include/rtems/bsd/local/ifdi_if.h @@ -22,8 +22,10 @@ typedef int ifdi_attach_pre_t(if_ctx_t _ctx); static __inline int IFDI_ATTACH_PRE(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_attach_pre); - return ((ifdi_attach_pre_t *) _m)(_ctx); + rc = ((ifdi_attach_pre_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_ATTACH_POST() method */ @@ -34,8 +36,10 @@ typedef int ifdi_attach_post_t(if_ctx_t _ctx); static __inline int IFDI_ATTACH_POST(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_attach_post); - return ((ifdi_attach_post_t *) _m)(_ctx); + rc = ((ifdi_attach_post_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_DETACH() method */ @@ -46,8 +50,10 @@ typedef int ifdi_detach_t(if_ctx_t _ctx); static __inline int IFDI_DETACH(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_detach); - return ((ifdi_detach_t *) _m)(_ctx); + rc = ((ifdi_detach_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_SUSPEND() method */ @@ -58,8 +64,10 @@ typedef int ifdi_suspend_t(if_ctx_t _ctx); static __inline int IFDI_SUSPEND(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_suspend); - return ((ifdi_suspend_t *) _m)(_ctx); + rc = ((ifdi_suspend_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_SHUTDOWN() method */ @@ -70,8 +78,10 @@ typedef int ifdi_shutdown_t(if_ctx_t _ctx); static __inline int IFDI_SHUTDOWN(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_shutdown); - return ((ifdi_shutdown_t *) _m)(_ctx); + rc = ((ifdi_shutdown_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_RESUME() method */ @@ -82,8 +92,10 @@ typedef int ifdi_resume_t(if_ctx_t _ctx); static __inline int IFDI_RESUME(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_resume); - return ((ifdi_resume_t *) _m)(_ctx); + rc = ((ifdi_resume_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_TX_QUEUES_ALLOC() method */ @@ -97,8 +109,10 @@ static __inline int IFDI_TX_QUEUES_ALLOC(if_ctx_t _ctx, caddr_t *_vaddrs, int ntxqsets) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_tx_queues_alloc); - return ((ifdi_tx_queues_alloc_t *) _m)(_ctx, _vaddrs, _paddrs, ntxqs, ntxqsets); + rc = ((ifdi_tx_queues_alloc_t *) _m)(_ctx, _vaddrs, _paddrs, ntxqs, ntxqsets); + return (rc); } /** @brief Unique descriptor for the IFDI_RX_QUEUES_ALLOC() method */ @@ -112,8 +126,10 @@ static __inline int IFDI_RX_QUEUES_ALLOC(if_ctx_t _ctx, caddr_t *_vaddrs, int nrxqsets) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rx_queues_alloc); - return ((ifdi_rx_queues_alloc_t *) _m)(_ctx, _vaddrs, _paddrs, nrxqs, nrxqsets); + rc = ((ifdi_rx_queues_alloc_t *) _m)(_ctx, _vaddrs, _paddrs, nrxqs, nrxqsets); + return (rc); } /** @brief Unique descriptor for the IFDI_QUEUES_FREE() method */ @@ -160,8 +176,10 @@ typedef int ifdi_msix_intr_assign_t(if_ctx_t _sctx, int msix); static __inline int IFDI_MSIX_INTR_ASSIGN(if_ctx_t _sctx, int msix) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_sctx)->ops,ifdi_msix_intr_assign); - return ((ifdi_msix_intr_assign_t *) _m)(_sctx, msix); + rc = ((ifdi_msix_intr_assign_t *) _m)(_sctx, msix); + return (rc); } /** @brief Unique descriptor for the IFDI_INTR_ENABLE() method */ @@ -196,8 +214,10 @@ typedef int ifdi_rx_queue_intr_enable_t(if_ctx_t _ctx, uint16_t _qid); static __inline int IFDI_RX_QUEUE_INTR_ENABLE(if_ctx_t _ctx, uint16_t _qid) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rx_queue_intr_enable); - return ((ifdi_rx_queue_intr_enable_t *) _m)(_ctx, _qid); + rc = ((ifdi_rx_queue_intr_enable_t *) _m)(_ctx, _qid); + return (rc); } /** @brief Unique descriptor for the IFDI_TX_QUEUE_INTR_ENABLE() method */ @@ -208,8 +228,10 @@ typedef int ifdi_tx_queue_intr_enable_t(if_ctx_t _ctx, uint16_t _qid); static __inline int IFDI_TX_QUEUE_INTR_ENABLE(if_ctx_t _ctx, uint16_t _qid) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_tx_queue_intr_enable); - return ((ifdi_tx_queue_intr_enable_t *) _m)(_ctx, _qid); + rc = ((ifdi_tx_queue_intr_enable_t *) _m)(_ctx, _qid); + return (rc); } /** @brief Unique descriptor for the IFDI_LINK_INTR_ENABLE() method */ @@ -244,8 +266,10 @@ typedef int ifdi_mtu_set_t(if_ctx_t _ctx, uint32_t _mtu); static __inline int IFDI_MTU_SET(if_ctx_t _ctx, uint32_t _mtu) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_mtu_set); - return ((ifdi_mtu_set_t *) _m)(_ctx, _mtu); + rc = ((ifdi_mtu_set_t *) _m)(_ctx, _mtu); + return (rc); } /** @brief Unique descriptor for the IFDI_MEDIA_SET() method */ @@ -268,8 +292,10 @@ typedef int ifdi_promisc_set_t(if_ctx_t _ctx, int _flags); static __inline int IFDI_PROMISC_SET(if_ctx_t _ctx, int _flags) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_promisc_set); - return ((ifdi_promisc_set_t *) _m)(_ctx, _flags); + rc = ((ifdi_promisc_set_t *) _m)(_ctx, _flags); + return (rc); } /** @brief Unique descriptor for the IFDI_CRCSTRIP_SET() method */ @@ -306,8 +332,10 @@ static __inline int IFDI_IOV_INIT(if_ctx_t _ctx, uint16_t num_vfs, const nvlist_t * params) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_iov_init); - return ((ifdi_iov_init_t *) _m)(_ctx, num_vfs, params); + rc = ((ifdi_iov_init_t *) _m)(_ctx, num_vfs, params); + return (rc); } /** @brief Unique descriptor for the IFDI_IOV_UNINIT() method */ @@ -332,8 +360,10 @@ static __inline int IFDI_IOV_VF_ADD(if_ctx_t _ctx, uint16_t num_vfs, const nvlist_t * params) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_iov_vf_add); - return ((ifdi_iov_vf_add_t *) _m)(_ctx, num_vfs, params); + rc = ((ifdi_iov_vf_add_t *) _m)(_ctx, num_vfs, params); + return (rc); } /** @brief Unique descriptor for the IFDI_UPDATE_ADMIN_STATUS() method */ @@ -368,8 +398,10 @@ typedef int ifdi_media_change_t(if_ctx_t _ctx); static __inline int IFDI_MEDIA_CHANGE(if_ctx_t _ctx) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_media_change); - return ((ifdi_media_change_t *) _m)(_ctx); + rc = ((ifdi_media_change_t *) _m)(_ctx); + return (rc); } /** @brief Unique descriptor for the IFDI_GET_COUNTER() method */ @@ -380,8 +412,10 @@ typedef uint64_t ifdi_get_counter_t(if_ctx_t _ctx, ift_counter cnt); static __inline uint64_t IFDI_GET_COUNTER(if_ctx_t _ctx, ift_counter cnt) { kobjop_t _m; + uint64_t rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_get_counter); - return ((ifdi_get_counter_t *) _m)(_ctx, cnt); + rc = ((ifdi_get_counter_t *) _m)(_ctx, cnt); + return (rc); } /** @brief Unique descriptor for the IFDI_PRIV_IOCTL() method */ @@ -392,8 +426,10 @@ typedef int ifdi_priv_ioctl_t(if_ctx_t _ctx, u_long _cmd, caddr_t _data); static __inline int IFDI_PRIV_IOCTL(if_ctx_t _ctx, u_long _cmd, caddr_t _data) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_priv_ioctl); - return ((ifdi_priv_ioctl_t *) _m)(_ctx, _cmd, _data); + rc = ((ifdi_priv_ioctl_t *) _m)(_ctx, _cmd, _data); + return (rc); } /** @brief Unique descriptor for the IFDI_I2C_REQ() method */ @@ -404,8 +440,10 @@ typedef int ifdi_i2c_req_t(if_ctx_t _ctx, struct ifi2creq *_req); static __inline int IFDI_I2C_REQ(if_ctx_t _ctx, struct ifi2creq *_req) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_i2c_req); - return ((ifdi_i2c_req_t *) _m)(_ctx, _req); + rc = ((ifdi_i2c_req_t *) _m)(_ctx, _req); + return (rc); } /** @brief Unique descriptor for the IFDI_TXQ_SETUP() method */ @@ -416,8 +454,10 @@ typedef int ifdi_txq_setup_t(if_ctx_t _ctx, uint32_t _txqid); static __inline int IFDI_TXQ_SETUP(if_ctx_t _ctx, uint32_t _txqid) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_txq_setup); - return ((ifdi_txq_setup_t *) _m)(_ctx, _txqid); + rc = ((ifdi_txq_setup_t *) _m)(_ctx, _txqid); + return (rc); } /** @brief Unique descriptor for the IFDI_RXQ_SETUP() method */ @@ -428,8 +468,10 @@ typedef int ifdi_rxq_setup_t(if_ctx_t _ctx, uint32_t _txqid); static __inline int IFDI_RXQ_SETUP(if_ctx_t _ctx, uint32_t _txqid) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_ctx)->ops,ifdi_rxq_setup); - return ((ifdi_rxq_setup_t *) _m)(_ctx, _txqid); + rc = ((ifdi_rxq_setup_t *) _m)(_ctx, _txqid); + return (rc); } /** @brief Unique descriptor for the IFDI_TIMER() method */ @@ -501,8 +543,10 @@ static __inline int IFDI_SYSCTL_INT_DELAY(if_ctx_t _sctx, if_int_delay_info_t _iidi) { kobjop_t _m; + int rc; KOBJOPLOOKUP(((kobj_t)_sctx)->ops,ifdi_sysctl_int_delay); - return ((ifdi_sysctl_int_delay_t *) _m)(_sctx, _iidi); + rc = ((ifdi_sysctl_int_delay_t *) _m)(_sctx, _iidi); + return (rc); } /** @brief Unique descriptor for the IFDI_DEBUG() method */ diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs.h b/rtemsbsd/include/rtems/bsd/local/usbdevs.h index dbb8b0f2..4848ccd7 100644 --- a/rtemsbsd/include/rtems/bsd/local/usbdevs.h +++ b/rtemsbsd/include/rtems/bsd/local/usbdevs.h @@ -1,5 +1,3 @@ -/* ??? */ - /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. * @@ -675,6 +673,7 @@ #define USB_VENDOR_AMIT2 0x15c5 /* AMIT */ #define USB_VENDOR_TEXTECH 0x15ca /* Textech International Ltd. */ #define USB_VENDOR_SOHOWARE 0x15e8 /* SOHOware */ +#define USB_VENDOR_ABIT 0x15eb /* ABIT Corporation */ #define USB_VENDOR_UMAX 0x1606 /* UMAX Data Systems */ #define USB_VENDOR_INSIDEOUT 0x1608 /* Inside Out Networks */ #define USB_VENDOR_AMOI 0x1614 /* Amoi Electronics */ @@ -714,6 +713,7 @@ #define USB_VENDOR_STELERA 0x1a8d /* Stelera Wireless */ #define USB_VENDOR_SEL 0x1adb /* Schweitzer Engineering Laboratories */ #define USB_VENDOR_CORSAIR 0x1b1c /* Corsair */ +#define USB_VENDOR_ASM 0x1b21 /* ASMedia Technology */ #define USB_VENDOR_MATRIXORBITAL 0x1b3d /* Matrix Orbital */ #define USB_VENDOR_OVISLINK 0x1b75 /* OvisLink */ #define USB_VENDOR_TML 0x1b91 /* The Mobility Lab */ @@ -757,6 +757,7 @@ #define USB_VENDOR_NHJ 0x2770 /* NHJ */ #define USB_VENDOR_THINGM 0x27b8 /* ThingM */ #define USB_VENDOR_PLANEX 0x2c02 /* Planex Communications */ +#define USB_VENDOR_QUECTEL 0x2c7c /* Quectel Wireless Solutions */ #define USB_VENDOR_VIDZMEDIA 0x3275 /* VidzMedia Pte Ltd */ #define USB_VENDOR_LINKINSTRUMENTS 0x3195 /* Link Instruments Inc. */ #define USB_VENDOR_AEI 0x3334 /* AEI */ @@ -822,6 +823,9 @@ #define USB_PRODUCT_ABBOTT_STEREO_PLUG 0x3410 /* Abbott Diabetics Stereo Plug */ #define USB_PRODUCT_ABBOTT_STRIP_PORT 0x3420 /* Abbott Diabetics Strip Port */ +/* ABIT products */ +#define USB_PRODUCT_ABIT_AK_020 0x7d0e /* 3G modem */ + /* AboCom products */ #define USB_PRODUCT_ABOCOM_XX1 0x110c /* XX1 */ #define USB_PRODUCT_ABOCOM_XX2 0x200c /* XX2 */ @@ -2581,6 +2585,7 @@ #define USB_PRODUCT_JETI_SPC1201 0x04b2 /* FTDI compatible adapter */ /* JMicron products */ +#define USB_PRODUCT_JMICRON_JMS567 0x0567 /* USB to SATA 6.0Gb/s bridge */ #define USB_PRODUCT_JMICRON_JM20336 0x2336 /* USB to SATA Bridge */ #define USB_PRODUCT_JMICRON_JM20337 0x2338 /* USB to ATA/ATAPI Bridge */ @@ -3818,12 +3823,15 @@ #define USB_PRODUCT_QUANTA_GLE 0xea06 /* HSDPA modem */ #define USB_PRODUCT_QUANTA_RW6815R 0xf003 /* HP iPAQ rw6815 RNDIS */ -/* Qtronix products */ -#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */ +/* Quectel products */ +#define USB_PRODUCT_QUECTEL_EC25 0x0125 /* LTE modem */ /* Quickshot products */ #define USB_PRODUCT_QUICKSHOT_STRIKEPAD 0x6238 /* USB StrikePad */ +/* Qtronix products */ +#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */ + /* Radio Shack */ #define USB_PRODUCT_RADIOSHACK_USBCABLE 0x4026 /* USB to Serial Cable */ @@ -3893,6 +3901,7 @@ #define USB_PRODUCT_REALTEK_RTL8188CU_COMBO 0x8754 /* RTL8188CU */ #define USB_PRODUCT_REALTEK_RTL8723BU 0xb720 /* RTL8723BU */ #define USB_PRODUCT_REALTEK_RTL8192SU 0xc512 /* RTL8192SU */ +#define USB_PRODUCT_REALTEK_RTL8812AU 0x8812 /* RTL8812AU Wireless Adapter */ /* RedOctane products */ #define USB_PRODUCT_REDOCTANE_DUMMY 0x0000 /* Dummy product */ diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h index ef168bbf..d8fe4aea 100644 --- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h +++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h @@ -1,5 +1,3 @@ -/* ??? */ - /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. * @@ -142,6 +140,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Abbott Diabetics Strip Port", }, { + USB_VENDOR_ABIT, USB_PRODUCT_ABIT_AK_020, + 0, + "ABIT Corporation", + "3G modem", + }, + { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1, 0, "AboCom Systems", @@ -8104,6 +8108,12 @@ const struct usb_knowndev usb_knowndevs[] = { "FTDI compatible adapter", }, { + USB_VENDOR_JMICRON, USB_PRODUCT_JMICRON_JMS567, + 0, + "JMicron", + "USB to SATA 6.0Gb/s bridge", + }, + { USB_VENDOR_JMICRON, USB_PRODUCT_JMICRON_JM20336, 0, "JMicron", @@ -14098,10 +14108,10 @@ const struct usb_knowndev usb_knowndevs[] = { "HP iPAQ rw6815 RNDIS", }, { - USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, + USB_VENDOR_QUECTEL, USB_PRODUCT_QUECTEL_EC25, 0, - "Qtronix", - "Scorpion-980N keyboard", + "Quectel Wireless Solutions", + "LTE modem", }, { USB_VENDOR_QUICKSHOT, USB_PRODUCT_QUICKSHOT_STRIKEPAD, @@ -14110,6 +14120,12 @@ const struct usb_knowndev usb_knowndevs[] = { "USB StrikePad", }, { + USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, + 0, + "Qtronix", + "Scorpion-980N keyboard", + }, + { USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE, 0, "Radio Shack", @@ -14464,6 +14480,12 @@ const struct usb_knowndev usb_knowndevs[] = { "RTL8192SU", }, { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8812AU, + 0, + "Realtek", + "RTL8812AU Wireless Adapter", + }, + { USB_VENDOR_REDOCTANE, USB_PRODUCT_REDOCTANE_DUMMY, 0, "RedOctane", @@ -22084,6 +22106,12 @@ const struct usb_knowndev usb_knowndevs[] = { NULL, }, { + USB_VENDOR_ABIT, 0, + USB_KNOWNDEV_NOPROD, + "ABIT Corporation", + NULL, + }, + { USB_VENDOR_UMAX, 0, USB_KNOWNDEV_NOPROD, "UMAX Data Systems", @@ -22318,6 +22346,12 @@ const struct usb_knowndev usb_knowndevs[] = { NULL, }, { + USB_VENDOR_ASM, 0, + USB_KNOWNDEV_NOPROD, + "ASMedia Technology", + NULL, + }, + { USB_VENDOR_MATRIXORBITAL, 0, USB_KNOWNDEV_NOPROD, "Matrix Orbital", @@ -22576,6 +22610,12 @@ const struct usb_knowndev usb_knowndevs[] = { NULL, }, { + USB_VENDOR_QUECTEL, 0, + USB_KNOWNDEV_NOPROD, + "Quectel Wireless Solutions", + NULL, + }, + { USB_VENDOR_VIDZMEDIA, 0, USB_KNOWNDEV_NOPROD, "VidzMedia Pte Ltd", diff --git a/rtemsbsd/include/vm/vm_phys.h b/rtemsbsd/include/vm/vm_phys.h new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/rtemsbsd/include/vm/vm_phys.h diff --git a/rtemsbsd/rtems/rtems-kernel-malloc.c b/rtemsbsd/rtems/rtems-kernel-malloc.c index b5cfc76d..51e4b74c 100644 --- a/rtemsbsd/rtems/rtems-kernel-malloc.c +++ b/rtemsbsd/rtems/rtems-kernel-malloc.c @@ -6,14 +6,15 @@ * @brief TODO. */ -/* - * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved. +/*- + * SPDX-License-Identifier: BSD-3-Clause * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Copyright (c) 1987, 1991, 1993 + * The Regents of the University of California. + * Copyright (c) 2005-2009 Robert N. M. Watson + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> (mallocarray) + * Copyright (c) 2009, 2018 embedded brains GmbH + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,11 +24,14 @@ * 2. 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. + * 3. Neither the name of the University 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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) @@ -35,6 +39,8 @@ * 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. + * + * @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94 */ #include <machine/rtems-bsd-kernel-space.h> @@ -55,7 +61,7 @@ MALLOC_DEFINE(M_IOV, "iov", "large iov's"); void malloc_init(void *data) { - struct malloc_type *mtp = data; + } void @@ -69,7 +75,7 @@ malloc_uninit(void *data) #undef malloc void * -_bsd_malloc(unsigned long size, struct malloc_type *mtp, int flags) +_bsd_malloc(size_t size, struct malloc_type *mtp, int flags) { void *p = malloc(size > 0 ? size : 1); @@ -77,13 +83,23 @@ _bsd_malloc(unsigned long size, struct malloc_type *mtp, int flags) memset(p, 0, size); } - return p; + return (p); +} + +void * +mallocarray(size_t nmemb, size_t size, struct malloc_type *type, int flags) +{ + + if (WOULD_OVERFLOW(nmemb, size)) + panic("mallocarray: %zu * %zu overflowed", nmemb, size); + + return (_bsd_malloc(size * nmemb, type, flags)); } #undef realloc + void * -_bsd_realloc( void *addr, unsigned long size, - struct malloc_type *type, int flags) +_bsd_realloc( void *addr, size_t size, struct malloc_type *type, int flags) { void *p = realloc(addr, size > 0 ? size : 1); @@ -95,23 +111,25 @@ _bsd_realloc( void *addr, unsigned long size, } #undef reallocf + void * -_bsd_reallocf( void *addr, unsigned long size, - struct malloc_type *type, int flags) +_bsd_reallocf( void *addr, size_t size, struct malloc_type *type, int flags) { void *p = realloc(addr, size > 0 ? size : 1); if (p == NULL) { - free(addr,NULL); + free(addr, NULL); } - return p; + return (p); } #undef free + void _bsd_free(void *addr, struct malloc_type *mtp) { + free(addr); } @@ -120,5 +138,6 @@ _bsd_free(void *addr, struct malloc_type *mtp) char * _bsd_strdup(const char *__restrict s, struct malloc_type *type) { - return strdup(s); + + return (strdup(s)); } diff --git a/freebsd/sys/arm/lpc/if_lpe.c b/rtemsbsd/sys/arm/lpc/if_lpe.c index 99016be3..99016be3 100755 --- a/freebsd/sys/arm/lpc/if_lpe.c +++ b/rtemsbsd/sys/arm/lpc/if_lpe.c diff --git a/freebsd/sys/arm/lpc/if_lpereg.h b/rtemsbsd/sys/arm/lpc/if_lpereg.h index a40bf8b5..a40bf8b5 100644 --- a/freebsd/sys/arm/lpc/if_lpereg.h +++ b/rtemsbsd/sys/arm/lpc/if_lpereg.h diff --git a/freebsd/sys/arm/lpc/lpc_pwr.c b/rtemsbsd/sys/arm/lpc/lpc_pwr.c index dd1064c8..dd1064c8 100755 --- a/freebsd/sys/arm/lpc/lpc_pwr.c +++ b/rtemsbsd/sys/arm/lpc/lpc_pwr.c diff --git a/freebsd/sys/arm/lpc/lpcreg.h b/rtemsbsd/sys/arm/lpc/lpcreg.h index d094e8f9..d094e8f9 100644 --- a/freebsd/sys/arm/lpc/lpcreg.h +++ b/rtemsbsd/sys/arm/lpc/lpcreg.h diff --git a/freebsd/sys/arm/lpc/lpcvar.h b/rtemsbsd/sys/arm/lpc/lpcvar.h index dafbef08..dafbef08 100644 --- a/freebsd/sys/arm/lpc/lpcvar.h +++ b/rtemsbsd/sys/arm/lpc/lpcvar.h |