]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
Hoist a bunch of stuff that should be done by all if_print routines into
[tcpdump] / print-ip.c
index d8eda70a23e85fe7b490ac8a920dcd7d2b0c3a4b..795b4b0a3bc5782e4abd8f4c00524b1495a5e3ac 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.109 2002-07-21 20:48:26 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.117 2002-12-11 07:14:02 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
+#include <tcpdump-stdinc.h>
 
-#include <netinet/in.h>
-
-#include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #include "addrtoname.h"
 #include "interface.h"
@@ -76,13 +70,59 @@ ip_printroute(const char *type, register const u_char *cp, u_int length)
        printf("%s}", ptr == len? "#" : "");
 }
 
+/*
+ * If source-routing is present, return the final destination.
+ * Otherwise, return IP destination.
+ *
+ * This is used for UDP and TCP pseudo-header in the checksum
+ * calculation.
+ */
+u_int32_t
+ip_finddst(const struct ip *ip)
+{
+       int length;
+       int len;
+       const u_char *cp;
+       u_int32_t retval;
+
+       cp = (const u_char *)(ip + 1);
+       length = (IP_HL(ip) << 2) - sizeof(struct ip);
+
+       for (; length > 0; cp += len, length -= len) {
+               int tt = *cp;
+
+               if (tt == IPOPT_NOP || tt == IPOPT_EOL)
+                       len = 1;
+               else {
+                       if (&cp[1] >= snapend) {
+                               return 0;
+                       }
+                       len = cp[1];
+               }
+               if (len <= 0) {
+                       return 0;
+               }
+               if (&cp[1] >= snapend || cp + len > snapend) {
+                       return 0;
+               }
+               switch (tt) {
+
+               case IPOPT_SSRR:
+               case IPOPT_LSRR:
+                       memcpy(&retval, cp + len - 4, 4);
+                       return retval;
+               }
+       }
+       return ip->ip_dst.s_addr;
+}
+
 static void
 ip_printts(register const u_char *cp, u_int length)
 {
        register u_int ptr = cp[2] - 1;
        register u_int len = 0;
        int hoplen;
-       char *type;
+       const char *type;
 
        printf(" TS{");
        hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
@@ -313,30 +353,6 @@ ip_print(register const u_char *bp, register u_int length)
        struct protoent *proto;
 
        ip = (const struct ip *)bp;
-#ifdef LBL_ALIGN
-       /*
-        * If the IP header is not aligned, copy into abuf.
-        */
-       if ((long)ip & 3) {
-               static u_char *abuf = NULL;
-               static int didwarn = 0;
-
-               if (abuf == NULL) {
-                       abuf = (u_char *)malloc(snaplen);
-                       if (abuf == NULL)
-                               error("ip_print: malloc");
-               }
-               memcpy((char *)abuf, (char *)ip, min(length, snaplen));
-               snapend += abuf - (u_char *)ip;
-               packetp = abuf;
-               ip = (struct ip *)abuf;
-               /* We really want libpcap to give us aligned packets */
-               if (!didwarn) {
-                       warning("compensating for unaligned libpcap packets");
-                       ++didwarn;
-               }
-       }
-#endif
        if ((u_char *)(ip + 1) > snapend) {
                printf("[|ip]");
                return;
@@ -351,7 +367,7 @@ ip_print(register const u_char *bp, register u_int length)
                return;
        }
 
-       len = ntohs(ip->ip_len);
+       len = EXTRACT_16BITS(&ip->ip_len);
        if (length < len)
                (void)printf("truncated-ip - %d bytes missing! ",
                        len - length);
@@ -360,7 +376,7 @@ ip_print(register const u_char *bp, register u_int length)
 
         printf("IP ");
 
-       off = ntohs(ip->ip_off);
+       off = EXTRACT_16BITS(&ip->ip_off);
 
         if (vflag) {
             (void)printf("(tos 0x%x", (int)ip->ip_tos);
@@ -379,11 +395,11 @@ ip_print(register const u_char *bp, register u_int length)
             }
 
             if (ip->ip_ttl >= 1)
-                (void)printf(", ttl %d", (int)ip->ip_ttl);    
+                (void)printf(", ttl %u", ip->ip_ttl);    
 
             if ((off & 0x3fff) == 0)
-                (void)printf(", id %d", (int)ntohs(ip->ip_id));
-            (void)printf(", len %d) ", (int)ntohs(ip->ip_len));
+                (void)printf(", id %u", EXTRACT_16BITS(&ip->ip_id));
+            (void)printf(", len %u) ", EXTRACT_16BITS(&ip->ip_len));
        }
 
        /*
@@ -410,7 +426,7 @@ again:
 #endif
                case IPPROTO_AH:
                        nh = *cp;
-                       advance = ah_print(cp, (const u_char *)ip);
+                       advance = ah_print(cp);
                        cp += advance;
                        len -= advance;
                        goto again;
@@ -436,7 +452,7 @@ again:
                case IPPROTO_IPCOMP:
                    {
                        int enh;
-                       advance = ipcomp_print(cp, (const u_char *)ip, &enh);
+                       advance = ipcomp_print(cp, &enh);
                        cp += advance;
                        len -= advance;
                        if (enh < 0)
@@ -473,7 +489,7 @@ again:
                        break;
 
                case IPPROTO_EGP:
-                       egp_print(cp, len, (const u_char *)ip);
+                       egp_print(cp);
                        break;
 
 #ifndef IPPROTO_OSPF
@@ -509,6 +525,12 @@ again:
                        break;
 #endif /*INET6*/
 
+#ifndef IPPROTO_RSVP
+#define IPPROTO_RSVP 46
+#endif
+               case IPPROTO_RSVP:
+                       rsvp_print(cp, len);
+                       break;
 
 #ifndef IPPROTO_GRE
 #define IPPROTO_GRE 47
@@ -580,7 +602,7 @@ again:
 #ifndef IP_DF
 #define IP_DF 0x4000
 #endif /* IP_DF */
-               (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len,
+               (void)printf(" (frag %u:%u@%u%s)", EXTRACT_16BITS(&ip->ip_id), len,
                        (off & 0x1fff) * 8,
                        (off & IP_MF)? "+" : "");
 
@@ -589,12 +611,12 @@ again:
 
        if (vflag) {
                u_int16_t sum, ip_sum;
-               char *sep = "";
+               const char *sep = "";
 
                if ((u_char *)ip + hlen <= snapend) {
                        sum = in_cksum((const u_short *)ip, hlen, 0);
                        if (sum != 0) {
-                               ip_sum = ntohs(ip->ip_sum);
+                               ip_sum = EXTRACT_16BITS(&ip->ip_sum);
                                (void)printf("%sbad cksum %x (->%x)!", sep,
                                             ip_sum,
                                             in_cksum_shouldbe(ip_sum, sum));
@@ -636,3 +658,4 @@ ipN_print(register const u_char *bp, register u_int length)
 }
 
 
+