††
†
†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 if ( primitive->dl_primitive != DL_BIND_ACK){ 442 fprintf(stderr, "dlbindreq: not DL_BIND_ACK\n"); 443 return(-1); 444 } 445 446 return(0); 447 } †# ./sniff hme0 ----Ether Header---- src addr : 08:00:20:c6:69:c7 dest addr : 00:13:d3:a9:8f:40 ether type : 0x800 ----IP Header---- version : 4 header len : 5 (20 bytes) tos : 0 total len : 1292 id : 51935 frag offset : 16384 ttl : 60 protocol : 6 checksum : 0x8497 src address : 172.29.73.55 dst address : 172.29.73.3 ----TCP Header---- source port : 23 dest port : 1277 seq : 371774688 ack : 3757417225 data offset : 5 (20 bytes) flags : ACK window : 50400 check sum : 0x6420 urt_ptr : 0 ------DATA-------
†
55 union DL_primitives *dlp;
84 if((fd = open (devpath , O_RDWR)) < 0 ){ 92 if(dlattachreq(fd, ppa, buf) < 0){ 317 attachreq.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 */ };
324 if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){
333 if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) {
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 } 100 if(dlpromisconreq(fd, DL_PROMISC_PHYS, buf) < 0){ ... 108 if(dlbindreq (fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0, buf) < 0){ 120 if(ioctl(fd, I_STR, &strioc) < 0){ 121 perror("ioctl: I_STR: DLIOCRAW"); 122 exit(1); 123 }
struct strioctl { }; 116 strioc.ic_cmd = DLIOCRAW; 117 strioc.ic_timout = -1; 118 strioc.ic_len = 0; 119 strioc.ic_dp = NULL; 128 if (ioctl(fd, I_FLUSH, FLUSHR) < 0){ #define FLUSHR 0x01 /* flush read queue */
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 }
†
†
††100 if(dlpromisconreq(fd, DL_PROMISC_SAP, buf) < 0){ /* * 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 */
† |