††
†
†1 /********************************************* 2 * sniff.c 3 * 4 * packet monitor using DLPI 5 * 6 * gcc sniff.c -lnsl -o sniff 7 * 8 ********************************************/ 9 #Include <netinet/in.h> 10 #include <sys/types.h> 11 #include <sys/socket.h> 12 #include <sys/stropts.h> 13 #include <sys/dlpi.h> 14 #include <fcntl.h> 15 #include <stdio.h> 16 #include <sys/signal.h> 17 #include <sys/stream.h> 18 #include <string.h> 19 #include <net/if.h> 20 #include <netinet/if_ether.h> 21 #include <netinet/in_systm.h> 22 #include <netinet/tcp.h> 23 #include <netinet/ip.h> 24 #include <sys/varargs.h> 25 #include <errno.h> 26 #include <unistd.h> 27 28 #define ERR_MSG_MAX 300 29 #define MAXDLBUFSIZE 8192 30 #define DLBUFSIZE 8192 31 #define TCP_DATA_PRINT_LENGTH 100 32 #define PRINT_MAC_ADDR(ether_addr_octet) { \ 33 int i; \ 34 for ( i =0; i < 6; i++){ \ 35 printf("%02x",(ether_addr_octet[i])); \ 36 if(i != 5) \ 37 printf(":"); \ 38 } \ 39 } 40 41 void print_packet(caddr_t, int); 42 void print_usage(char *); 43 int dlattachreq(int, t_uscalar_t, caddr_t ); 44 int dlpromisconreq(int, t_uscalar_t, caddr_t); 45 int dlbindreq(int, t_uscalar_t, t_uscalar_t, uint16_t, uint16_t, t_uscalar_t, caddr_t); 46 void print_err(int , char *, ...); 47 int dldetachreq(int , caddr_t); 48 int dlpromiscoffreq(int, t_uscalar_t, caddr_t); 49 50 int 51 main(int argc, char *argv[]) 52 { 55 union DL_primitives *dlp; 56 int flags = 0; 65 66 if (argc != 2) 67 print_usage(argv[0]); 68 69 interface = argv[1]; 70 if ((instance = strpbrk(interface, "0123456789")) == NULL){ 71 fprintf(stderr, "%s: no instance specified\n", interface); 72 print_usage(argv[0]); 73 } 74 75 ppa = atoi(instance); 76 77 strncpy(devname, interface, instance - interface); 78 79 sprintf(devpath, "/dev/%s",devname); 80 81 /* 83 */ 84 if((fd = open (devpath , O_RDWR)) < 0 ){ 85 perror("open"); 86 exit(1); 87 } 88 89 /* 91 */ 92 if(dlattachreq(fd, ppa, buf) < 0){ 93 fprintf(stderr, "%s: no such instance\n", interface); 94 print_usage(argv[0]); 95 } 96 97 /* 99 */ 100 if(dlpromisconreq(fd, DL_PROMISC_PHYS, buf) < 0){ 101 fprintf(stderr, "%s: Cannot set promiscuous mode\n", interface); 102 exit(1); 103 } 104 105 /* 107 */ 108 if(dlbindreq (fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0, buf) < 0){ 109 fprintf(stderr, "%s: Cannot bind to ETHERTYPE_IP\n", interface); 110 exit(1); 111 } 112 113 /* 115 */ 116 strioc.ic_cmd = DLIOCRAW; 117 strioc.ic_timout = -1; 118 strioc.ic_len = 0; 119 strioc.ic_dp = NULL; 120 if(ioctl(fd, I_STR, &strioc) < 0){ 121 perror("ioctl: I_STR: DLIOCRAW"); 122 exit(1); 123 } 124 125 /* 127 */ 128 if (ioctl(fd, I_FLUSH, FLUSHR) < 0){ 129 perror("ioctl: I_FLUSH"); 130 exit(1); 131 } 132 133 databuf.maxlen = MAXDLBUFSIZE; 134 databuf.len = 0; 135 databuf.buf = (caddr_t)buf; 136 137 while (getmsg(fd, NULL, &databuf, &flags) == 0) { 138 if (databuf.len > 0) 139 print_packet(databuf.buf, databuf.len); 140 } 141 142 perror("getmsg"); 143 exit(1); 144 } 145 146 void 147 print_packet(caddr_t buf, int len) 148 { 149 struct ether_header *ether; 150 struct tcphdr *tcp; 151 struct ip *ip; 152 u_char *tcpdata; 153 int etherlen; 154 int iphlen; 155 int iptotlen; 156 int tcphlen; 157 int tcpdatalen; 158 159 etherlen = sizeof(struct ether_header); 160 ether = (struct ether_header *)buf; 161 162 /* 164 */ 165 if(ether->ether_type != ETHERTYPE_IP) 166 return; 167 168 /* 172 */ 173 if(len < etherlen + sizeof(struct ip) + sizeof(struct tcphdr) ) 174 return; 175 176 /* 179 */ 180 ip = (struct ip *)malloc(len); 181 memcpy(ip, buf + etherlen, len); 182 183 /* 185 */ 186 if(ip->ip_p != IPPROTO_TCP) 187 goto error; 188 189 iphlen = ip->ip_hl << 2; 190 191 /* 195 */ 196 if(len < etherlen + iphlen + sizeof(struct tcphdr) ) 197 goto error; 198 199 tcp = (struct tcphdr *)((u_char *)ip + iphlen); 200 tcphlen = tcp->th_off << 2; 201 202 /* 206 */ 207 if(len < etherlen + iphlen + tcphlen ) 208 goto error; 209 210 printf("\n----Ether Header----\n"); 211 printf("src addr : "); 212 PRINT_MAC_ADDR(ether->ether_shost.ether_addr_octet); 213 printf("\n"); 214 printf("dest addr : "); 215 PRINT_MAC_ADDR(ether->ether_dhost.ether_addr_octet); 216 printf("\n"); 217 printf("ether type : 0x%x\n",ether->ether_type); 218 219 printf("----IP Header----\n"); 220 printf("version : %d\n",ip->ip_v); 221 printf("header len : %d (%d bytes)\n",ip->ip_hl, ip->ip_hl <<2); 222 printf("tos : %d\n",ip->ip_tos); 223 printf("total len : %d\n",ntohs(ip->ip_len)); 224 printf("id : %d\n",ntohs(ip->ip_id)); 225 printf("frag offset : %d\n",ip->ip_off); 226 printf("ttl : %d\n",ip->ip_ttl); 227 printf("protocol : %d\n",ip->ip_p); 228 printf("checksum : 0x%x\n",ip->ip_sum); 229 printf("src address : %s\n",inet_ntoa(ip->ip_src)); 230 printf("dst address : %s\n",inet_ntoa(ip->ip_dst)); 231 232 printf("----TCP Header----\n"); 233 printf("source port : %d\n",ntohs(tcp->th_sport)); 234 printf("dest port : %d\n",ntohs(tcp->th_dport)); 235 printf("seq : %u\n",ntohl(tcp->th_seq)); 236 printf("ack : %u\n",ntohl(tcp->th_ack)); 237 printf("data offset : %d (%d bytes)\n",tcp->th_off, tcp->th_off <<2); 238 printf("flags : "); 239 if((tcp->th_flags | TH_FIN) == tcp->th_flags) 240 printf("FIN "); 241 if((tcp->th_flags | TH_SYN) == tcp->th_flags) 242 printf("SIN "); 243 if((tcp->th_flags | TH_RST) == tcp->th_flags) 244 printf("RST "); 245 if((tcp->th_flags | TH_PUSH) == tcp->th_flags) 246 printf("PUSH "); 247 if((tcp->th_flags | TH_ACK) == tcp->th_flags) 248 printf("ACK "); 249 if((tcp->th_flags | TH_URG) == tcp->th_flags) 250 printf("URG "); 251 printf("\n"); 252 printf("window : %d\n",ntohs(tcp->th_win)); 253 printf("check sum : 0x%x\n",tcp->th_sum); 254 printf("urt_ptr : %d\n",tcp->th_urp); 255 256 /* 260 */ 261 iptotlen = ntohs(ip->ip_len); 262 tcpdatalen = iptotlen - iphlen - tcphlen; 263 if( tcpdatalen > len - etherlen - iphlen - tcphlen) 264 tcpdatalen = len - etherlen - iphlen - tcphlen; 265 266 if( tcpdatalen > 0){ 267 int i = 0; 268 269 tcpdata = (u_char *)tcp + tcphlen; 270 printf("------DATA-------\n"); 271 printf("data length : %d\n", tcpdatalen); 272 /* 274 */ 275 while ( i < tcpdatalen && i < TCP_DATA_PRINT_LENGTH){ 276 if(isprint(tcpdata[i])) 277 printf("%c",tcpdata[i]); 278 i++; 279 } 280 } 281 282 printf("\n\n"); 283 284 error: 285 free(ip); 286 return; 287 } 288 289 /***************************************************************************** 290 * print_usage() 291 * 293 *****************************************************************************/ 294 void 295 print_usage(char *argv) 296 { 297 printf("Usage: %s ifname \n",argv); 298 printf(" Example) %s eri0\n", argv); 299 exit(1); 300 } 301 302 /***************************************************************************** 303 * dlattachreq() 304 * 306 * 307 *****************************************************************************/ 308 int 309 dlattachreq(int fd, t_uscalar_t ppa ,caddr_t buf) 310 { 311 union DL_primitives *primitive; 312 dl_attach_req_t attachreq; 313 struct strbuf ctlbuf; 314 int flags = 0; 315 int ret; 316 317 attachreq.dl_primitive = DL_ATTACH_REQ; 318 attachreq.dl_ppa = ppa; 319 320 ctlbuf.maxlen = 0; 321 ctlbuf.len = sizeof(attachreq); 322 ctlbuf.buf = (caddr_t)&attachreq; 323 324 if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){ 325 fprintf(stderr, "dlattachreq: putmsg: %s", strerror(errno)); 326 return(-1); 327 } 328 329 ctlbuf.maxlen = MAXDLBUFSIZE; 330 ctlbuf.len = 0; 331 ctlbuf.buf = (caddr_t)buf; 332 333 if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) { 334 fprintf(stderr, "dlattachreq: getmsg: %s\n", strerror(errno)); 335 return(-1); 336 } 337 338 primitive = (union DL_primitives *) ctlbuf.buf; 339 if ( primitive->dl_primitive != DL_OK_ACK){ 340 fprintf(stderr, "dlattachreq: not DL_OK_ACK\n"); 341 return(-1); 342 } 343 344 return(0); 345 } 346 347 /***************************************************************************** 348 * dlpromisconreq() 349 * 351 * 352 *****************************************************************************/ 353 int 354 dlpromisconreq(int fd, t_uscalar_t level, caddr_t buf) 355 { 356 union DL_primitives *primitive; 357 dl_promiscon_req_t promisconreq; 358 struct strbuf ctlbuf; 359 int flags = 0; 360 int ret; 361 362 promisconreq.dl_primitive = DL_PROMISCON_REQ; 363 promisconreq.dl_level = level; 364 365 ctlbuf.maxlen = 0; 366 ctlbuf.len = sizeof (promisconreq); 367 ctlbuf.buf = (caddr_t)&promisconreq; 368 369 if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){ 370 fprintf(stderr, "dlpromisconreq: putmsg: %s", strerror(errno)); 371 return(-1); 372 } 373 374 ctlbuf.maxlen = MAXDLBUFSIZE; 375 ctlbuf.len = 0; 376 ctlbuf.buf = (caddr_t)buf; 377 378 if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) { 379 fprintf(stderr, "dlpromisconreq: getmsg: %s\n", strerror(errno)); 380 return(-1); 381 } 382 383 primitive = (union DL_primitives *) ctlbuf.buf; 384 if ( primitive->dl_primitive != DL_OK_ACK){ 385 fprintf(stderr, "dlpromisconreq: not DL_OK_ACK\n"); 386 return(-1); 387 } 388 389 return(0); 390 } 391 392 /***************************************************************************** 393 * dlbindreq() 394 * 396 * 397 *****************************************************************************/ 398 int 399 dlbindreq( 400 int fd, 401 t_uscalar_t sap, 402 t_uscalar_t max_conind, 403 uint16_t service_mode, 404 uint16_t conn_mgmt, 405 t_uscalar_t xidtest_flg, 406 caddr_t buf 407 ) 408 { 409 union DL_primitives *primitive; 410 dl_bind_req_t bindreq; 411 struct strbuf ctlbuf; 412 int flags = 0; 413 int ret; 414 415 bindreq.dl_primitive = DL_BIND_REQ; 416 bindreq.dl_sap = sap; 417 bindreq.dl_max_conind = max_conind; 418 bindreq.dl_service_mode = service_mode; 419 bindreq.dl_conn_mgmt = conn_mgmt; 420 bindreq.dl_xidtest_flg = xidtest_flg; 421 422 ctlbuf.maxlen = 0; 423 ctlbuf.len = sizeof(bindreq); 424 ctlbuf.buf = (caddr_t)&bindreq; 425 426 if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){ 427 fprintf(stderr, "dlbindreq: putmsg: %s", strerror(errno)); 428 return(-1); 429 } 430 431 ctlbuf.maxlen = MAXDLBUFSIZE; 432 ctlbuf.len = 0; 433 ctlbuf.buf = (caddr_t)buf; 434 435 if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) { 436 fprintf(stderr, "dlbindreq: getmsg: %s\n", strerror(errno)); 437 return(-1); 438 } 439 440 primitive = (union DL_primitives *) ctlbuf.buf; 441 †# ./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 */
† |