]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-tcp.c
More UNALIGNED_MEM{CPY,CMP} on IP addresses.
[tcpdump] / print-tcp.c
index b7a7448e85ef7199a8da9ed00a7c327d6be503db..bb76ac7c506177b57a8ea59a30c60d9f2b3d3000 100644 (file)
@@ -24,8 +24,6 @@
  */
 
 #ifndef lint
-static const char rcsid[] _U_ =
-"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)";
 #else
 __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
 #endif
@@ -70,13 +68,8 @@ static void print_tcp_rst_data(register const u_char *sp, u_int length);
 
 
 struct tha {
-#ifndef INET6
         struct in_addr src;
         struct in_addr dst;
-#else
-        struct in6_addr src;
-        struct in6_addr dst;
-#endif /*INET6*/
         u_int port;
 };
 
@@ -87,14 +80,32 @@ struct tcp_seq_hash {
         tcp_seq ack;
 };
 
+#ifdef INET6
+struct tha6 {
+        struct in6_addr src;
+        struct in6_addr dst;
+        u_int port;
+};
+
+struct tcp_seq_hash6 {
+        struct tcp_seq_hash6 *nxt;
+        struct tha6 addr;
+        tcp_seq seq;
+        tcp_seq ack;
+};
+#endif
+
 #define TSEQ_HASHSIZE 919
 
 /* These tcp optinos do not have the size octet */
 #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)
 
-static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
+static struct tcp_seq_hash tcp_seq_hash4[TSEQ_HASHSIZE];
+#ifdef INET6
+static struct tcp_seq_hash6 tcp_seq_hash6[TSEQ_HASHSIZE];
+#endif
 
-struct tok tcp_flag_values[] = {
+static const struct tok tcp_flag_values[] = {
         { TH_FIN, "F" },
         { TH_SYN, "S" },
         { TH_RST, "R" },
@@ -106,7 +117,7 @@ struct tok tcp_flag_values[] = {
         { 0, NULL }
 };
 
-struct tok tcp_option_values[] = {
+static const struct tok tcp_option_values[] = {
         { TCPOPT_EOL, "eol" },
         { TCPOPT_NOP, "nop" },
         { TCPOPT_MAXSEG, "mss" },
@@ -122,6 +133,8 @@ struct tok tcp_option_values[] = {
         { TCPOPT_SIGNATURE, "md5" },
         { TCPOPT_AUTH, "enhanced auth" },
         { TCPOPT_UTO, "uto" },
+        { TCPOPT_MPTCP, "mptcp" },
+        { TCPOPT_EXPERIMENT2, "exp" },
         { 0, NULL }
 };
 
@@ -129,63 +142,9 @@ static int tcp_cksum(register const struct ip *ip,
                     register const struct tcphdr *tp,
                     register u_int len)
 {
-        union phu {
-                struct phdr {
-                        u_int32_t src;
-                        u_int32_t dst;
-                        u_char mbz;
-                        u_char proto;
-                        u_int16_t len;
-                } ph;
-                u_int16_t pa[6];
-        } phu;
-        const u_int16_t *sp;
-
-        /* pseudo-header.. */
-        phu.ph.len = htons((u_int16_t)len);
-        phu.ph.mbz = 0;
-        phu.ph.proto = IPPROTO_TCP;
-        memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
-        if (IP_HL(ip) == 5)
-                memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
-        else
-                phu.ph.dst = ip_finddst(ip);
-
-        sp = &phu.pa[0];
-        return in_cksum((u_short *)tp, len,
-                        sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
-}
-
-#ifdef INET6
-static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
-                      u_int len)
-{
-        size_t i;
-        u_int32_t sum = 0;
-        union {
-                struct {
-                        struct in6_addr ph_src;
-                        struct in6_addr ph_dst;
-                        u_int32_t      ph_len;
-                        u_int8_t       ph_zero[3];
-                        u_int8_t       ph_nxt;
-                } ph;
-                u_int16_t pa[20];
-        } phu;
-
-        /* pseudo-header */
-        memset(&phu, 0, sizeof(phu));
-        phu.ph.ph_src = ip6->ip6_src;
-        phu.ph.ph_dst = ip6->ip6_dst;
-        phu.ph.ph_len = htonl(len);
-        phu.ph.ph_nxt = IPPROTO_TCP;
-
-        for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
-                sum += phu.pa[i];
-
-        return in_cksum((u_short *)tp, len, sum);
+       return (nextproto4_cksum(ip, (const u_int8_t *)tp, len,
+           IPPROTO_TCP));
 }
-#endif
 
 void
 tcp_print(register const u_char *bp, register u_int length,
@@ -198,7 +157,9 @@ tcp_print(register const u_char *bp, register u_int length,
         register char ch;
         u_int16_t sport, dport, win, urp;
         u_int32_t seq, ack, thseq, thack;
-        int threv;
+        u_int utoval;
+        u_int16_t magic;
+        register int rev;
 #ifdef INET6
         register const struct ip6_hdr *ip6;
 #endif
@@ -224,42 +185,6 @@ tcp_print(register const u_char *bp, register u_int length,
 
         hlen = TH_OFF(tp) * 4;
 
-        /*
-        * If data present, header length valid, and NFS port used,
-        * assume NFS.
-        * Pass offset of data plus 4 bytes for RPC TCP msg length
-        * to NFS print routines.
-        */
-       if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
-           (length - hlen) >= 4) {
-               u_char *fraglenp;
-               u_int32_t fraglen;
-               register struct sunrpc_msg *rp;
-               enum sunrpc_msg_type direction;
-
-               fraglenp = (u_char *)tp + hlen;
-               if (TTEST2(*fraglenp, 4)) {
-                       fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
-                       if (fraglen > (length - hlen) - 4)
-                               fraglen = (length - hlen) - 4;
-                       rp = (struct sunrpc_msg *)(fraglenp + 4);
-                       if (TTEST(rp->rm_direction)) {
-                               direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
-                               if (dport == NFS_PORT &&
-                                   direction == SUNRPC_CALL) {
-                                       nfsreq_print((u_char *)rp, fraglen,
-                                           (u_char *)ip);
-                                       return;
-                               }
-                               if (sport == NFS_PORT &&
-                                   direction == SUNRPC_REPLY) {
-                                       nfsreply_print((u_char *)rp, fraglen,
-                                           (u_char *)ip);
-                                       return;
-                               }
-                       }
-                }
-        }
 #ifdef INET6
         if (ip6) {
                 if (ip6->ip6_nxt == IPPROTO_TCP) {
@@ -313,109 +238,127 @@ tcp_print(register const u_char *bp, register u_int length,
         printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));
 
         if (!Sflag && (flags & TH_ACK)) {
-                register struct tcp_seq_hash *th;
-                const void *src, *dst;
-                register int rev;
-                struct tha tha;
                 /*
                  * Find (or record) the initial sequence numbers for
                  * this conversation.  (we pick an arbitrary
                  * collating order so there's only one entry for
                  * both directions).
                  */
-#ifdef INET6
-                memset(&tha, 0, sizeof(tha));
                 rev = 0;
+#ifdef INET6
                 if (ip6) {
+                        register struct tcp_seq_hash6 *th;
+                        struct tcp_seq_hash6 *tcp_seq_hash;
+                        const struct in6_addr *src, *dst;
+                        struct tha6 tha;
+
+                        tcp_seq_hash = tcp_seq_hash6;
                         src = &ip6->ip6_src;
                         dst = &ip6->ip6_dst;
                         if (sport > dport)
                                 rev = 1;
                         else if (sport == dport) {
-                                if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
+                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip6->ip6_dst) > 0)
                                         rev = 1;
                         }
                         if (rev) {
-                                memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
-                                memcpy(&tha.dst, src, sizeof ip6->ip6_src);
+                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst);
+                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src);
                                 tha.port = dport << 16 | sport;
                         } else {
-                                memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
-                                memcpy(&tha.src, src, sizeof ip6->ip6_src);
+                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst);
+                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src);
                                 tha.port = sport << 16 | dport;
                         }
+
+                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
+                             th->nxt; th = th->nxt)
+                                if (memcmp((char *)&tha, (char *)&th->addr,
+                                           sizeof(th->addr)) == 0)
+                                        break;
+
+                        if (!th->nxt || (flags & TH_SYN)) {
+                                /* didn't find it or new conversation */
+                                if (th->nxt == NULL) {
+                                        th->nxt = (struct tcp_seq_hash6 *)
+                                                calloc(1, sizeof(*th));
+                                        if (th->nxt == NULL)
+                                                error("tcp_print: calloc");
+                                }
+                                th->addr = tha;
+                                if (rev)
+                                        th->ack = seq, th->seq = ack - 1;
+                                else
+                                        th->seq = seq, th->ack = ack - 1;
+                        } else {
+                                if (rev)
+                                        seq -= th->ack, ack -= th->seq;
+                                else
+                                        seq -= th->seq, ack -= th->ack;
+                        }
+
+                        thseq = th->seq;
+                        thack = th->ack;
                 } else {
+#else  /*INET6*/
+                {
+#endif /*INET6*/
+                        register struct tcp_seq_hash *th;
+                        struct tcp_seq_hash *tcp_seq_hash;
+                        const struct in_addr *src, *dst;
+                        struct tha tha;
+
+                        tcp_seq_hash = tcp_seq_hash4;
                         src = &ip->ip_src;
                         dst = &ip->ip_dst;
                         if (sport > dport)
                                 rev = 1;
                         else if (sport == dport) {
-                                if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
+                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip->ip_dst) > 0)
                                         rev = 1;
                         }
                         if (rev) {
-                                memcpy(&tha.src, dst, sizeof ip->ip_dst);
-                                memcpy(&tha.dst, src, sizeof ip->ip_src);
+                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip->ip_dst);
+                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip->ip_src);
                                 tha.port = dport << 16 | sport;
                         } else {
-                                memcpy(&tha.dst, dst, sizeof ip->ip_dst);
-                                memcpy(&tha.src, src, sizeof ip->ip_src);
+                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip->ip_dst);
+                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip->ip_src);
                                 tha.port = sport << 16 | dport;
                         }
-                }
-#else
-                rev = 0;
-                src = &ip->ip_src;
-                dst = &ip->ip_dst;
-                if (sport > dport)
-                        rev = 1;
-                else if (sport == dport) {
-                        if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
-                                rev = 1;
-                }
-                if (rev) {
-                        memcpy(&tha.src, dst, sizeof ip->ip_dst);
-                        memcpy(&tha.dst, src, sizeof ip->ip_src);
-                        tha.port = dport << 16 | sport;
-                } else {
-                        memcpy(&tha.dst, dst, sizeof ip->ip_dst);
-                        memcpy(&tha.src, src, sizeof ip->ip_src);
-                        tha.port = sport << 16 | dport;
-                }
-#endif
 
-                threv = rev;
-                for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
-                     th->nxt; th = th->nxt)
-                        if (memcmp((char *)&tha, (char *)&th->addr,
-                                   sizeof(th->addr)) == 0)
-                                break;
+                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
+                             th->nxt; th = th->nxt)
+                                if (memcmp((char *)&tha, (char *)&th->addr,
+                                           sizeof(th->addr)) == 0)
+                                        break;
 
-                if (!th->nxt || (flags & TH_SYN)) {
-                        /* didn't find it or new conversation */
-                        if (th->nxt == NULL) {
-                                th->nxt = (struct tcp_seq_hash *)
-                                        calloc(1, sizeof(*th));
-                                if (th->nxt == NULL)
-                                        error("tcp_print: calloc");
+                        if (!th->nxt || (flags & TH_SYN)) {
+                                /* didn't find it or new conversation */
+                                if (th->nxt == NULL) {
+                                        th->nxt = (struct tcp_seq_hash *)
+                                                calloc(1, sizeof(*th));
+                                        if (th->nxt == NULL)
+                                                error("tcp_print: calloc");
+                                }
+                                th->addr = tha;
+                                if (rev)
+                                        th->ack = seq, th->seq = ack - 1;
+                                else
+                                        th->seq = seq, th->ack = ack - 1;
+                        } else {
+                                if (rev)
+                                        seq -= th->ack, ack -= th->seq;
+                                else
+                                        seq -= th->seq, ack -= th->ack;
                         }
-                        th->addr = tha;
-                        if (rev)
-                                th->ack = seq, th->seq = ack - 1;
-                        else
-                                th->seq = seq, th->ack = ack - 1;
-                } else {
-                        if (rev)
-                                seq -= th->ack, ack -= th->seq;
-                        else
-                                seq -= th->seq, ack -= th->ack;
-                }
 
-                thseq = th->seq;
-                thack = th->ack;
+                        thseq = th->seq;
+                        thack = th->ack;
+                }
         } else {
                 /*fool gcc*/
-                thseq = thack = threv = 0;
+                thseq = thack = rev = 0;
         }
         if (hlen > length) {
                 (void)printf(" [bad hdr length %u - too long, > %u]",
@@ -423,34 +366,40 @@ tcp_print(register const u_char *bp, register u_int length,
                 return;
         }
 
-        if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) {
+        if (vflag && !Kflag && !fragmented) {
+                /* Check the checksum, if possible. */
                 u_int16_t sum, tcp_sum;
-                if (TTEST2(tp->th_sport, length)) {
-                        sum = tcp_cksum(ip, tp, length);
 
-                        (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
-                        if (sum != 0) {
+                if (IP_V(ip) == 4) {
+                        if (TTEST2(tp->th_sport, length)) {
+                                sum = tcp_cksum(ip, tp, length);
                                 tcp_sum = EXTRACT_16BITS(&tp->th_sum);
-                                (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
-                        } else
-                                (void)printf(" (correct)");
+
+                                (void)printf(", cksum 0x%04x", tcp_sum);
+                                if (sum != 0)
+                                        (void)printf(" (incorrect -> 0x%04x)",
+                                            in_cksum_shouldbe(tcp_sum, sum));
+                                else
+                                        (void)printf(" (correct)");
+                        }
                 }
-        }
 #ifdef INET6
-        if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
-                u_int16_t sum,tcp_sum;
-                if (TTEST2(tp->th_sport, length)) {
-                        sum = tcp6_cksum(ip6, tp, length);
-                        (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
-                        if (sum != 0) {
+                else if (IP_V(ip) == 6 && ip6->ip6_plen) {
+                        if (TTEST2(tp->th_sport, length)) {
+                                sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP);
                                 tcp_sum = EXTRACT_16BITS(&tp->th_sum);
-                                (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
-                        } else
-                                (void)printf(" (correct)");
 
+                                (void)printf(", cksum 0x%04x", tcp_sum);
+                                if (sum != 0)
+                                        (void)printf(" (incorrect -> 0x%04x)",
+                                            in_cksum_shouldbe(tcp_sum, sum));
+                                else
+                                        (void)printf(" (correct)");
+
+                        }
                 }
-        }
 #endif
+        }
 
         length -= hlen;
         if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
@@ -501,7 +450,7 @@ tcp_print(register const u_char *bp, register u_int length,
 #define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }
 
 
-                        printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));
+                        printf("%s", tok2str(tcp_option_values, "unknown-%u", opt));
 
                         switch (opt) {
 
@@ -530,7 +479,7 @@ tcp_print(register const u_char *bp, register u_int length,
                                                 s = EXTRACT_32BITS(cp + i);
                                                 LENCHECK(i + 8);
                                                 e = EXTRACT_32BITS(cp + i + 4);
-                                                if (threv) {
+                                                if (rev) {
                                                         s -= thseq;
                                                         e -= thseq;
                                                 } else {
@@ -614,7 +563,7 @@ tcp_print(register const u_char *bp, register u_int length,
                         case TCPOPT_UTO:
                                 datalen = 2;
                                 LENCHECK(datalen);
-                                uint utoval = EXTRACT_16BITS(cp);
+                                utoval = EXTRACT_16BITS(cp);
                                 (void)printf("0x%x", utoval);
                                 if (utoval & 0x0001)
                                         utoval = (utoval >> 1) * 60;
@@ -623,8 +572,52 @@ tcp_print(register const u_char *bp, register u_int length,
                                 (void)printf(" %u", utoval);
                                 break;
 
+                        case TCPOPT_MPTCP:
+                                datalen = len - 2;
+                                LENCHECK(datalen);
+                                if (!mptcp_print(cp-2, len, flags))
+                                        goto bad;
+                                break;
+
+                        case TCPOPT_EXPERIMENT2:
+                                datalen = len - 2;
+                                LENCHECK(datalen);
+                                if (datalen < 2)
+                                        goto bad;
+                                /* RFC6994 */
+                                magic = EXTRACT_16BITS(cp);
+                                (void)printf("-");
+
+                                switch(magic) {
+
+                                case 0xf989:
+                                        /* TCP Fast Open: draft-ietf-tcpm-fastopen-04 */
+                                        if (datalen == 2) {
+                                                /* Fast Open Cookie Request */
+                                                (void)printf("tfo cookiereq");
+                                        } else {
+                                                /* Fast Open Cookie */
+                                                if (datalen % 2 != 0 || datalen < 6 || datalen > 18) {
+                                                        (void)printf("tfo malformed");
+                                                } else {
+                                                        (void)printf("tfo cookie ");
+                                                        for (i = 2; i < datalen; ++i)
+                                                                (void)printf("%02x", cp[i]);
+                                                }
+                                        }
+                                        break;
+
+                                default:
+                                        /* Unknown magic number */
+                                        (void)printf("%04x", magic);
+                                        break;
+                                }
+                                break;
+
                         default:
                                 datalen = len - 2;
+                                if (datalen)
+                                        printf(" 0x");
                                 for (i = 0; i < datalen; ++i) {
                                         LENCHECK(i);
                                         (void)printf("%02x", cp[i]);
@@ -664,7 +657,16 @@ tcp_print(register const u_char *bp, register u_int length,
         if ((flags & TH_RST) && vflag) {
                 print_tcp_rst_data(bp, length);
                 return;
-        } 
+        }
+
+        if (packettype) {
+                switch (packettype) {
+                case PT_ZMTP1:
+                        zmtp1_print(bp, length);
+                        break;
+                }
+                return;
+        }
 
         if (sport == TELNET_PORT || dport == TELNET_PORT) {
                 if (!qflag && vflag)
@@ -681,6 +683,8 @@ tcp_print(register const u_char *bp, register u_int length,
 #endif
         else if (sport == BEEP_PORT || dport == BEEP_PORT)
                 beep_print(bp, length);
+        else if (sport == OPENFLOW_PORT || dport == OPENFLOW_PORT)
+                openflow_print(bp, length);
         else if (length > 2 &&
                  (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT ||
                   sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) {
@@ -691,10 +695,42 @@ tcp_print(register const u_char *bp, register u_int length,
                 ns_print(bp + 2, length - 2, 0);
         } else if (sport == MSDP_PORT || dport == MSDP_PORT) {
                 msdp_print(bp, length);
+        } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) {
+                rpki_rtr_print(bp, length);
         }
         else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
                 ldp_print(bp, length);
         }
+        else if ((sport == NFS_PORT || dport == NFS_PORT) &&
+                 length >= 4 && TTEST2(*bp, 4)) {
+                /*
+                 * If data present, header length valid, and NFS port used,
+                 * assume NFS.
+                 * Pass offset of data plus 4 bytes for RPC TCP msg length
+                 * to NFS print routines.
+                 */
+                u_int32_t fraglen;
+                register struct sunrpc_msg *rp;
+                enum sunrpc_msg_type direction;
+
+                fraglen = EXTRACT_32BITS(bp) & 0x7FFFFFFF;
+                if (fraglen > (length) - 4)
+                        fraglen = (length) - 4;
+                rp = (struct sunrpc_msg *)(bp + 4);
+                if (TTEST(rp->rm_direction)) {
+                        direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
+                        if (dport == NFS_PORT && direction == SUNRPC_CALL) {
+                                (void)printf(": NFS request xid %u ", EXTRACT_32BITS(&rp->rm_xid));
+                                nfsreq_print_noaddr((u_char *)rp, fraglen, (u_char *)ip);
+                                return;
+                        }
+                        if (sport == NFS_PORT && direction == SUNRPC_REPLY) {
+                                (void)printf(": NFS reply xid %u ", EXTRACT_32BITS(&rp->rm_xid));
+                                nfsreply_print_noaddr((u_char *)rp, fraglen, (u_char *)ip);
+                                return;
+                        }
+                }
+        }
 
         return;
  bad:
@@ -745,6 +781,7 @@ print_tcp_rst_data(register const u_char *sp, u_int length)
 }
 
 #ifdef HAVE_LIBCRYPTO
+USES_APPLE_DEPRECATED_API
 static int
 tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
                      const u_char *data, int length, const u_char *rcvsig)
@@ -789,7 +826,7 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
                 ip6 = (struct ip6_hdr *)ip;
                 MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src));
                 MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst));
-                len32 = htonl(ntohs(ip6->ip6_plen));
+                len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen));
                 MD5_Update(&ctx, (char *)&len32, sizeof(len32));
                 nxt = 0;
                 MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
@@ -831,6 +868,7 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
         else
                 return (SIGNATURE_INVALID);
 }
+USES_APPLE_RST
 #endif /* HAVE_LIBCRYPTO */
 
 /*