††
†
†1 /* 2 * packet monitor 3 * gcc sniff.c -lsocket -lnsl -o sniff 4 */ 5 #include <netinet/in.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <sys/stropts.h> 9 #include <sys/dlpi.h> 10 #include <fcntl.h> 11 #include <stdio.h> 12 #include <sys/signal.h> 13 #include <sys/stream.h> 14 #include <string.h> 15 #include <net/if.h> 16 #include <netinet/if_ether.h> 17 #include <netinet/in_systm.h> 18 #include <netinet/tcp.h> 19 #include <netinet/ip.h> 20 21 #define MAXDLBUF 32768 22 #define MAXWAIT 15 23 #define FLAMETYPE 0x800 24 25 long databuf[MAXDLBUF]; 26 27 main(argc, argv) 28 int argc; 29 char *argv[]; 30 { 31 long buf[MAXDLBUF]; 32 union DL_primitives *dlp; 33 int flags; 34 int ppa, sap; 35 int fd; 36 int i; 37 char *device; 38 struct strbuf data; 39 40 dlp = (union DL_primitives*) buf; 41 42 if (argc != 3) 43 printf(" Usage: %s device instance \n",argv[0]); 44 45 device = argv[1]; 46 ppa = atoi (argv[2]); 47 48 if((fd = open (device , O_RDWR)) < 0 ) 49 syserr(device); 50 51 dlattachreq(fd, ppa); 52 dlokack(fd, buf); 53 54 dlpromisconreq(fd, DL_PROMISC_PHYS); 55 dlokack(fd, buf); 56 57 dlbindreq (fd, FLAMETYPE, 0, DL_CLDLS, 0, 0); 58 dlbindack (fd, buf); 59 60 if (strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0) 61 syserr("DLIOCRAW"); 62 63 if (ioctl(fd, I_FLUSH, FLUSHR) < 0) 64 syserr("I_FLUSH"); 65 66 data.buf = (char *) databuf; 67 data.maxlen = MAXDLBUF; 68 data.len = 0; 69 70 while (getmsg(fd, NULL, &data, &flags) == 0) { 71 print_pkt(data.buf); 72 } 73 74 return (0); 75 } 76 77 dlattachreq(fd, ppa) 78 int fd; 79 u_long ppa; 80 { 81 dl_attach_req_t attach_req; 82 struct strbuf ctl; 83 int flags; 84 85 attach_req.dl_primitive = DL_ATTACH_REQ; 86 attach_req.dl_ppa = ppa; 87 88 ctl.maxlen = 0; 89 ctl.len = sizeof (attach_req); 90 ctl.buf = (char *) &attach_req; 91 92 flags = 0; 93 94 if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 95 syserr("dlattachreq: putmsg"); 96 } 97 98 dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest) 99 int fd; 100 u_long sap; 101 u_long max_conind; 102 u_long service_mode; 103 u_long conn_mgmt; 104 u_long xidtest; 105 { 106 dl_bind_req_t bind_req; 107 struct strbuf ctl; 108 int flags; 109 110 bind_req.dl_primitive = DL_BIND_REQ; 111 bind_req.dl_sap = sap; 112 bind_req.dl_max_conind = max_conind; 113 bind_req.dl_service_mode = service_mode; 114 bind_req.dl_conn_mgmt = conn_mgmt; 115 bind_req.dl_xidtest_flg = xidtest; 116 117 ctl.maxlen = 0; 118 ctl.len = sizeof (bind_req); 119 ctl.buf = (char *) &bind_req; 120 121 flags = 0; 122 123 if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 124 syserr("dlbindreq: putmsg"); 125 } 126 127 dlbindack(fd, bufp) 128 int fd; 129 char *bufp; 130 { 131 union DL_primitives *dlp; 132 struct strbuf ctl; 133 int flags; 134 135 ctl.maxlen = MAXDLBUF; 136 ctl.len = 0; 137 ctl.buf = bufp; 138 139 strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack"); 140 141 dlp = (union DL_primitives *) ctl.buf; 142 143 expecting(DL_BIND_ACK, dlp); 144 145 if (flags != RS_HIPRI) 146 err("dlbindack: DL_OK_ACK was not M_PCPROTO"); 147 148 if (ctl.len < sizeof (dl_bind_ack_t)) 149 err("dlbindack: short response ctl.len: %d", ctl.len); 150 } 151 152 dlokack(fd, bufp) 153 int fd; 154 char *bufp; 155 { 156 union DL_primitives *dlp; 157 struct strbuf ctl; 158 int flags; 159 160 ctl.maxlen = MAXDLBUF; 161 ctl.len = 0; 162 ctl.buf = bufp; 163 164 strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack"); 165 166 dlp = (union DL_primitives *) ctl.buf; 167 168 expecting(DL_OK_ACK, dlp); 169 170 if (ctl.len < sizeof (dl_ok_ack_t)) 171 err("dlokack: response ctl.len too short: %d", ctl.len); 172 173 if (flags != RS_HIPRI) 174 err("dlokack: DL_OK_ACK was not M_PCPROTO"); 175 176 if (ctl.len < sizeof (dl_ok_ack_t)) 177 err("dlokack: short response ctl.len: %d", ctl.len); 178 } 179 180 syserr(s) 181 char *s; 182 { 183 (void) perror(s); 184 exit(1); 185 } 186 187 err(fmt, a1, a2, a3, a4) 188 char *fmt; 189 char *a1, *a2, *a3, *a4; 190 { 191 (void) fprintf(stderr, fmt, a1, a2, a3, a4); 192 (void) fprintf(stderr, "\n"); 193 (void) exit(1); 194 } 195 196 void sigalrm() 197 { 198 (void) err("sigalrm: TIMEOUT"); 199 } 200 201 strgetmsg(fd, ctlp, datap, flagsp, caller) 202 int fd; 203 struct strbuf *ctlp, *datap; 204 int *flagsp; 205 char *caller; 206 { 207 int rc; 208 static char errmsg[80]; 209 210 (void) signal(SIGALRM, sigalrm); 211 if (alarm(MAXWAIT) < 0) { 212 (void) sprintf(errmsg, "%s: alarm", caller); 213 syserr(errmsg); 214 } 215 216 *flagsp = 0; 217 if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) { 218 (void) sprintf(errmsg, "%s: getmsg", caller); 219 syserr(errmsg); 220 } 221 222 if (alarm(0) < 0) { 223 (void) sprintf(errmsg, "%s: alarm", caller); 224 syserr(errmsg); 225 } 226 227 if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) 228 err("%s: MORECTL|MOREDATA", caller); 229 if (rc & MORECTL) 230 err("%s: MORECTL", caller); 231 if (rc & MOREDATA) 232 err("%s: MOREDATA", caller); 233 234 if (ctlp->len < sizeof (long)) 235 err("getmsg: control portion length < sizeof (long): %d", ctlp->len); 236 } 237 238 expecting(prim, dlp) 239 int prim; 240 union DL_primitives *dlp; 241 { 242 if (dlp->dl_primitive != (u_long)prim) { 243 err("unexpected dlprim error\n"); 244 exit(1); 245 } 246 } 247 248 dlpromisconreq(fd, level) 249 int fd; 250 u_long level; 251 { 252 dl_promiscon_req_t promiscon_req; 253 struct strbuf ctl; 254 int flags; 255 256 promiscon_req.dl_primitive = DL_PROMISCON_REQ; 257 promiscon_req.dl_level = level; 258 259 ctl.maxlen = 0; 260 ctl.len = sizeof (promiscon_req); 261 ctl.buf = (char *) &promiscon_req; 262 263 flags = 0; 264 265 if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 266 syserr("dlpromiscon: putmsg"); 267 268 } 269 270 strioctl(fd, cmd, timout, len, dp) 271 int fd; 272 int cmd; 273 int timout; 274 int len; 275 char *dp; 276 { 277 struct strioctl sioc; 278 int rc; 279 280 sioc.ic_cmd = cmd; 281 sioc.ic_timout = timout; 282 sioc.ic_len = len; 283 sioc.ic_dp = dp; 284 285 rc = ioctl(fd, I_STR, &sioc); 286 287 if (rc < 0) 288 return (rc); 289 else 290 return (sioc.ic_len); 291 } 292 293 print_pkt(data) 294 char *data; 295 { 296 struct in_addr insaddr, indaddr; 297 int i, j; 298 299 struct dgram 300 { 301 struct ether_header ether; 302 struct ip ip; 303 struct tcphdr tcp; 304 unsigned char blah[65535]; 305 } buf_ether, buf; 306 310 311 printf("\n----Ether Header----\n"); 312 printf("src addr : "); 313 for ( i =0;i<6;i++) 314 printf("%x:",(buf_ether.ether.ether_shost.ether_addr_octet[i])); 315 printf("\n"); 316 printf("dest addr : "); 317 for ( i =0;i<6;i++) 318 printf("%x:",(buf_ether.ether.ether_dhost.ether_addr_octet[i])); 319 printf("\n"); 320 printf("ether type : %x\n",buf_ether.ether.ether_type); 321 322 insaddr.s_addr = buf.ip.ip_src._S_un._S_addr; 323 indaddr.s_addr = buf.ip.ip_dst._S_un._S_addr; 324 325 326 printf("----IP Header----\n"); 327 printf("version : %d\n",buf.ip.ip_v); 328 printf("ihl : %d\n",buf.ip.ip_hl); 329 printf("tos : %d\n",buf.ip.ip_tos); 330 printf("tot length : %d\n",buf.ip.ip_len); 331 printf("id : %d\n",ntohs(buf.ip.ip_id)); 332 printf("frag_off : %d\n",buf.ip.ip_off); 333 printf("ttl : %d\n",buf.ip.ip_ttl); 334 printf("protocol : %d\n",buf.ip.ip_p); 335 printf("check : %d\n",buf.ip.ip_sum); 336 printf("saddr : %s\n",inet_ntoa(insaddr)); 337 printf("daddr : %s\n",inet_ntoa(indaddr)); 338 339 printf("----TCP Header----\n"); 340 printf("source port : %d\n",ntohs(buf.tcp.th_sport)); 341 printf("dest port : %d\n",ntohs(buf.tcp.th_dport)); 342 printf("sequence : %u\n",ntohl(buf.tcp.th_seq)); 343 printf("ack seq : %u\n",ntohl(buf.tcp.th_ack)); 344 printf("data offset : %d\n",ntohl(buf.tcp.th_off)); 345 printf("flags : "); 346 if((buf.tcp.th_flags | TH_FIN) == buf.tcp.th_flags) 347 printf("FIN "); 348 if((buf.tcp.th_flags | TH_SYN) == buf.tcp.th_flags) 349 printf("SIN "); 350 if((buf.tcp.th_flags | TH_RST) == buf.tcp.th_flags) 351 printf("RST "); 352 if((buf.tcp.th_flags | TH_PUSH) == buf.tcp.th_flags) 353 printf("PUSH "); 354 if((buf.tcp.th_flags | TH_ACK) == buf.tcp.th_flags) 355 printf("ACK "); 356 if((buf.tcp.th_flags | TH_URG) == buf.tcp.th_flags) 357 printf("URG "); 358 printf("\n"); 359 printf("window : %d\n",ntohs(buf.tcp.th_win)); 360 printf("check : %d\n",buf.tcp.th_sum); 361 printf("urt_ptr : %d\n",buf.tcp.th_urp); 362 363 printf("------DATA-------\n"); 364 printf("%s\n\n\n",(buf.blah)); 365 } †# ./sniff /dev/hme 0 ----Ether Header---- src addr : 8:0:20:91:a6:90: dest addr : 0:0:f4:5d:6a:a9: ether type : 800 ----IP Header---- version : 4 ihl : 5 tos : 0 tot length : 40 id : 59439 frag_off : 16384 ttl : 64 protocol : 6 check : 26633 saddr : 172.29.73.90 daddr : 172.29.73.2 ----TCP Header---- source port : 1021 dest port : 2049 sequence : 1137017927 ack seq : 1486710309 data offset : 5 flags : ACK window : 50400 check : 28047 urt_ptr : 0 ------DATA-------
†
32 union DL_primitives *dlp;
48 if((fd = open (device , O_RDWR)) < 0 ) 51 dlattachreq(fd, ppa); 85 attach_req.dl_primitive = DL_ATTACH_REQ;
typedef struct { t_uscalar_t dl_primitive; /* set to DL_ATTACH_REQ */ t_uscalar_t dl_ppa; /* id of the PPA */ } dl_attach_req_t; struct strbuf { int maxlen; /* no. of bytes in buffer */ int len; /* no. of bytes returned */ caddr_t buf; /* pointer to data */ };
94 if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
201 strgetmsg(fd, ctlp, datap, flagsp, caller)
217 if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) { 218 (void) sprintf(errmsg, "%s: getmsg", caller); 219 syserr(errmsg); 220 }
164 strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack"); 165 166 dlp = (union DL_primitives *) ctl.buf; 167 168 expecting(DL_OK_ACK, dlp); 54 dlpromisconreq(fd, DL_PROMISC_PHYS); 55 dlokack(fd, buf); 56 57 dlbindreq (fd, FLAMETYPE, 0, DL_CLDLS, 0, 0); 58 dlbindack (fd, buf);
60 if (strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0) 61 syserr("DLIOCRAW");
285 rc = ioctl(fd, I_STR, &sioc); struct strioctl { }; 63 if (ioctl(fd, I_FLUSH, FLUSHR) < 0) #define FLUSHR 0x01 /* flush read queue */
66 data.buf = (char *) databuf; 67 data.maxlen = MAXDLBUF; 68 data.len = 0; 69 70 while (getmsg(fd, NULL, &data, &flags) == 0) {
†
†
††54 dlpromisconreq(fd, DL_PROMISC_SAP); /* * DLPI promiscuous mode definitions */ #define DL_PROMISC_PHYS 0x01 /* promiscuous mode at phys level */ #define DL_PROMISC_SAP 0x02 /* promiscous mode at sap level */ #define DL_PROMISC_MULTI 0x03 /* promiscuous mode for multicast */
† |