1 /* 2 * Marko Kiiskila carnil@cs.tut.fi 3 * 4 * Tampere University of Technology - Telecommunications Laboratory 5 * 6 * Permission to use, copy, modify and distribute this 7 * software and its documentation is hereby granted, 8 * provided that both the copyright notice and this 9 * permission notice appear in all copies of the software, 10 * derivative works or modified versions, and any portions 11 * thereof, that both notices appear in supporting 12 * documentation, and that the use of this software is 13 * acknowledged in any publications resulting from using 14 * the software. 15 * 16 * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR 18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS 19 * SOFTWARE. 20 * 21 */ 22 23 #ifndef lint 24 static const char rcsid[] = 25 "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.11 2000/12/22 22:45:10 guy Exp $ (LBL)"; 26 #endif 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include <sys/param.h> 33 #include <sys/time.h> 34 #include <sys/types.h> 35 #include <sys/socket.h> 36 37 38 #include <netinet/in.h> 39 40 #include <stdio.h> 41 #include <pcap.h> 42 43 #include "interface.h" 44 #include "addrtoname.h" 45 #include "ethertype.h" 46 #include "ether.h" 47 48 const u_char *packetp; 49 const u_char *snapend; 50 51 #define RFC1483LLC_LEN 8 52 53 static unsigned char rfcllc[] = { 54 0xaa, /* DSAP: non-ISO */ 55 0xaa, /* SSAP: non-ISO */ 56 0x03, /* Ctrl: Unnumbered Information Command PDU */ 57 0x00, /* OUI: EtherType */ 58 0x00, 59 0x00 }; 60 61 static inline void 62 cip_print(register const u_char *bp, int length) 63 { 64 int i; 65 66 if (memcmp(rfcllc, bp, sizeof(rfcllc))) { 67 if (qflag) { 68 for (i = 0;i < RFC1483LLC_LEN; i++) 69 (void)printf("%2.2x ",bp[i]); 70 } else { 71 for (i = 0;i < RFC1483LLC_LEN - 2; i++) 72 (void)printf("%2.2x ",bp[i]); 73 etherproto_string(((u_short*)bp)[3]); 74 } 75 } else { 76 if (qflag) 77 (void)printf("(null encapsulation)"); 78 else { 79 (void)printf("(null encap)"); 80 etherproto_string(ETHERTYPE_IP); 81 } 82 } 83 } 84 85 /* 86 * This is the top level routine of the printer. 'p' is the points 87 * to the raw header of the packet, 'tvp' is the timestamp, 88 * 'length' is the length of the packet off the wire, and 'caplen' 89 * is the number of bytes actually captured. 90 */ 91 void 92 cip_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 93 { 94 int caplen = h->caplen; 95 int length = h->len; 96 u_short ether_type; 97 u_short extracted_ethertype; 98 u_short *bp; 99 100 ts_print(&h->ts); 101 102 if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) { 103 printf("[|cip]"); 104 goto out; 105 } 106 107 if (eflag) 108 cip_print(p, length); 109 110 /* 111 * Some printers want to get back at the ethernet addresses, 112 * and/or check that they're not walking off the end of the packet. 113 * Rather than pass them all the way down, we set these globals. 114 */ 115 packetp = p; 116 snapend = p + caplen; 117 118 if (memcmp(rfcllc, p, sizeof(rfcllc))==0) { 119 length -= RFC1483LLC_LEN; 120 caplen -= RFC1483LLC_LEN; 121 bp = (u_short *)p; 122 p += RFC1483LLC_LEN; 123 ether_type = ntohs(bp[3]); 124 } else { 125 ether_type = ETHERTYPE_IP; 126 bp = (u_short *)p; 127 } 128 129 /* 130 * Is it (gag) an 802.3 encapsulation? 131 */ 132 extracted_ethertype = 0; 133 if (ether_type < ETHERMTU) { 134 /* Try to print the LLC-layer header & higher layers */ 135 if (llc_print(p, length, caplen, NULL, NULL, 136 &extracted_ethertype)==0) { 137 /* ether_type not known, print raw packet */ 138 if (!eflag) 139 cip_print((u_char *)bp, length + RFC1483LLC_LEN); 140 if (extracted_ethertype) { 141 printf("(LLC %s) ", 142 etherproto_string(htons(extracted_ethertype))); 143 } 144 if (!xflag && !qflag) 145 default_print(p, caplen); 146 } 147 } else if (ether_encap_print(ether_type, p, length, caplen, 148 &extracted_ethertype) == 0) { 149 /* ether_type not known, print raw packet */ 150 if (!eflag) 151 cip_print((u_char *)bp, length + RFC1483LLC_LEN); 152 if (!xflag && !qflag) 153 default_print(p, caplen); 154 } 155 if (xflag) 156 default_print(p, caplen); 157 out: 158 putchar('\n'); 159 } 160