1 /* 2 * Copyright (c) 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), 22 * University College London. 23 */ 24 25 /* 26 * Packet capture routine for dlpi under SunOS 5 27 * 28 * Notes: 29 * 30 * - Apparently the DLIOCRAW ioctl() is specific to SunOS. 31 * 32 * - There is a bug in bufmod(7) such that setting the snapshot 33 * length results in data being left of the front of the packet. 34 * 35 * - It might be desirable to use pfmod(7) to filter packets in the 36 * kernel. 37 */ 38 39 #ifndef lint 40 static const char rcsid[] = 41 "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.74 2001/12/10 07:14:15 guy Exp $ (LBL)"; 42 #endif 43 44 #ifdef HAVE_CONFIG_H 45 #include "config.h" 46 #endif 47 48 #include <sys/types.h> 49 #include <sys/time.h> 50 #ifdef HAVE_SYS_BUFMOD_H 51 #include <sys/bufmod.h> 52 #endif 53 #include <sys/dlpi.h> 54 #ifdef HAVE_SYS_DLPI_EXT_H 55 #include <sys/dlpi_ext.h> 56 #endif 57 #ifdef HAVE_HPUX9 58 #include <sys/socket.h> 59 #endif 60 #ifdef DL_HP_PPA_ACK_OBS 61 #include <sys/stat.h> 62 #endif 63 #include <sys/stream.h> 64 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 65 #include <sys/systeminfo.h> 66 #endif 67 68 #ifdef HAVE_HPUX9 69 #include <net/if.h> 70 #endif 71 72 #include <ctype.h> 73 #ifdef HAVE_HPUX9 74 #include <nlist.h> 75 #endif 76 #include <errno.h> 77 #include <fcntl.h> 78 #include <memory.h> 79 #include <stdio.h> 80 #include <stdlib.h> 81 #include <string.h> 82 #include <stropts.h> 83 #include <unistd.h> 84 85 #include "pcap-int.h" 86 87 #ifdef HAVE_OS_PROTO_H 88 #include "os-proto.h" 89 #endif 90 91 #ifndef PCAP_DEV_PREFIX 92 #ifdef _AIX 93 #define PCAP_DEV_PREFIX "/dev/dlpi" 94 #else 95 #define PCAP_DEV_PREFIX "/dev" 96 #endif 97 #endif 98 99 #define MAXDLBUF 8192 100 101 /* Forwards */ 102 static char *split_dname(char *, int *, char *); 103 static int dlattachreq(int, bpf_u_int32, char *); 104 static int dlbindack(int, char *, char *); 105 static int dlbindreq(int, bpf_u_int32, char *); 106 static int dlinfoack(int, char *, char *); 107 static int dlinforeq(int, char *); 108 static int dlokack(int, const char *, char *, char *); 109 static int recv_ack(int, int, const char *, char *, char *); 110 static char *dlstrerror(bpf_u_int32); 111 static char *dlprim(bpf_u_int32); 112 static int dlpromisconreq(int, bpf_u_int32, char *); 113 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 114 static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *); 115 #endif 116 static int send_request(int, char *, int, char *, char *); 117 #ifdef HAVE_SYS_BUFMOD_H 118 static int strioctl(int, int, int, char *); 119 #endif 120 #ifdef HAVE_HPUX9 121 static int dlpi_kread(int, off_t, void *, u_int, char *); 122 #endif 123 #ifdef HAVE_DEV_DLPI 124 static int get_dlpi_ppa(int, const char *, int, char *); 125 #endif 126 127 int 128 pcap_stats(pcap_t *p, struct pcap_stat *ps) 129 { 130 131 /* 132 * "ps_recv" counts packets handed to the filter, not packets 133 * that passed the filter. As filtering is done in userland, 134 * this does not include packets dropped because we ran out 135 * of buffer space. 136 * 137 * "ps_drop" counts packets dropped inside the DLPI service 138 * provider device device because of flow control requirements 139 * or resource exhaustion; it doesn't count packets dropped by 140 * the interface driver, or packets dropped upstream. As 141 * filtering is done in userland, it counts packets regardless 142 * of whether they would've passed the filter. 143 * 144 * These statistics don't include packets not yet read from 145 * the kernel by libpcap, but they may include packets not 146 * yet read from libpcap by the application. 147 */ 148 *ps = p->md.stat; 149 return (0); 150 } 151 152 /* XXX Needed by HP-UX (at least) */ 153 static bpf_u_int32 ctlbuf[MAXDLBUF]; 154 static struct strbuf ctl = { 155 MAXDLBUF, 156 0, 157 (char *)ctlbuf 158 }; 159 160 int 161 pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 162 { 163 register int cc, n, caplen, origlen; 164 register u_char *bp, *ep, *pk; 165 register struct bpf_insn *fcode; 166 #ifdef HAVE_SYS_BUFMOD_H 167 register struct sb_hdr *sbp; 168 #ifdef LBL_ALIGN 169 struct sb_hdr sbhdr; 170 #endif 171 #endif 172 int flags; 173 struct strbuf data; 174 struct pcap_pkthdr pkthdr; 175 176 flags = 0; 177 cc = p->cc; 178 if (cc == 0) { 179 data.buf = (char *)p->buffer + p->offset; 180 data.maxlen = MAXDLBUF; 181 data.len = 0; 182 do { 183 if (getmsg(p->fd, &ctl, &data, &flags) < 0) { 184 /* Don't choke when we get ptraced */ 185 if (errno == EINTR) { 186 cc = 0; 187 continue; 188 } 189 strlcpy(p->errbuf, pcap_strerror(errno), 190 sizeof(p->errbuf)); 191 return (-1); 192 } 193 cc = data.len; 194 } while (cc == 0); 195 bp = p->buffer + p->offset; 196 } else 197 bp = p->bp; 198 199 /* Loop through packets */ 200 fcode = p->fcode.bf_insns; 201 ep = bp + cc; 202 n = 0; 203 #ifdef HAVE_SYS_BUFMOD_H 204 while (bp < ep) { 205 #ifdef LBL_ALIGN 206 if ((long)bp & 3) { 207 sbp = &sbhdr; 208 memcpy(sbp, bp, sizeof(*sbp)); 209 } else 210 #endif 211 sbp = (struct sb_hdr *)bp; 212 p->md.stat.ps_drop += sbp->sbh_drops; 213 pk = bp + sizeof(*sbp); 214 bp += sbp->sbh_totlen; 215 origlen = sbp->sbh_origlen; 216 caplen = sbp->sbh_msglen; 217 #else 218 origlen = cc; 219 caplen = min(p->snapshot, cc); 220 pk = bp; 221 bp += caplen; 222 #endif 223 ++p->md.stat.ps_recv; 224 if (bpf_filter(fcode, pk, origlen, caplen)) { 225 #ifdef HAVE_SYS_BUFMOD_H 226 pkthdr.ts = sbp->sbh_timestamp; 227 #else 228 (void)gettimeofday(&pkthdr.ts, NULL); 229 #endif 230 pkthdr.len = origlen; 231 pkthdr.caplen = caplen; 232 /* Insure caplen does not exceed snapshot */ 233 if (pkthdr.caplen > p->snapshot) 234 pkthdr.caplen = p->snapshot; 235 (*callback)(user, &pkthdr, pk); 236 if (++n >= cnt && cnt >= 0) { 237 p->cc = ep - bp; 238 p->bp = bp; 239 return (n); 240 } 241 } 242 #ifdef HAVE_SYS_BUFMOD_H 243 } 244 #endif 245 p->cc = 0; 246 return (n); 247 } 248 249 pcap_t * 250 pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) 251 { 252 register char *cp; 253 register pcap_t *p; 254 int ppa; 255 register dl_info_ack_t *infop; 256 #ifdef HAVE_SYS_BUFMOD_H 257 bpf_u_int32 ss, flag; 258 #ifdef HAVE_SOLARIS 259 register char *release; 260 bpf_u_int32 osmajor, osminor, osmicro; 261 #endif 262 #endif 263 bpf_u_int32 buf[MAXDLBUF]; 264 char dname[100]; 265 #ifndef HAVE_DEV_DLPI 266 char dname2[100]; 267 #endif 268 269 p = (pcap_t *)malloc(sizeof(*p)); 270 if (p == NULL) { 271 strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 272 return (NULL); 273 } 274 memset(p, 0, sizeof(*p)); 275 p->fd = -1; /* indicate that it hasn't been opened yet */ 276 277 #ifdef HAVE_DEV_DLPI 278 /* 279 ** Remove any "/dev/" on the front of the device. 280 */ 281 cp = strrchr(device, '/'); 282 if (cp == NULL) 283 cp = device; 284 else 285 cp++; 286 strlcpy(dname, cp, sizeof(dname)); 287 288 /* 289 * Split the device name into a device type name and a unit number; 290 * chop off the unit number, so "dname" is just a device type name. 291 */ 292 cp = split_dname(dname, &ppa, ebuf); 293 if (cp == NULL) 294 goto bad; 295 *cp = '\0'; 296 297 /* 298 * Use "/dev/dlpi" as the device. 299 * 300 * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that 301 * the "dl_mjr_num" field is for the "major number of interface 302 * driver"; that's the major of "/dev/dlpi" on the system on 303 * which I tried this, but there may be DLPI devices that 304 * use a different driver, in which case we may need to 305 * search "/dev" for the appropriate device with that major 306 * device number, rather than hardwiring "/dev/dlpi". 307 */ 308 cp = "/dev/dlpi"; 309 if ((p->fd = open(cp, O_RDWR)) < 0) { 310 snprintf(ebuf, PCAP_ERRBUF_SIZE, 311 "%s: %s", cp, pcap_strerror(errno)); 312 goto bad; 313 } 314 315 /* 316 * Get a table of all PPAs for that device, and search that 317 * table for the specified device type name and unit number. 318 */ 319 ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf); 320 if (ppa < 0) 321 goto bad; 322 #else 323 /* 324 * Get the unit number, and a pointer to the end of the device 325 * type name. 326 */ 327 cp = split_dname(device, &ppa, ebuf); 328 if (cp == NULL) 329 goto bad; 330 331 /* 332 * If the device name begins with "/", assume it begins with 333 * the pathname of the directory containing the device to open; 334 * otherwise, concatenate the device directory name and the 335 * device name. 336 */ 337 if (*device == '/') 338 strlcpy(dname, device, sizeof(dname)); 339 else 340 snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, 341 device); 342 343 /* 344 * Make a copy of the device pathname, and then remove the unit 345 * number from the device pathname. 346 */ 347 strlcpy(dname2, dname, sizeof(dname)); 348 *(dname + strlen(dname) - strlen(cp)) = '\0'; 349 350 /* Try device without unit number */ 351 if ((p->fd = open(dname, O_RDWR)) < 0) { 352 if (errno != ENOENT) { 353 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname, 354 pcap_strerror(errno)); 355 goto bad; 356 } 357 358 /* Try again with unit number */ 359 if ((p->fd = open(dname2, O_RDWR)) < 0) { 360 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname2, 361 pcap_strerror(errno)); 362 goto bad; 363 } 364 /* XXX Assume unit zero */ 365 ppa = 0; 366 } 367 #endif 368 369 p->snapshot = snaplen; 370 371 /* 372 ** Attach if "style 2" provider 373 */ 374 if (dlinforeq(p->fd, ebuf) < 0 || 375 dlinfoack(p->fd, (char *)buf, ebuf) < 0) 376 goto bad; 377 infop = &((union DL_primitives *)buf)->info_ack; 378 if (infop->dl_provider_style == DL_STYLE2 && 379 (dlattachreq(p->fd, ppa, ebuf) < 0 || 380 dlokack(p->fd, "attach", (char *)buf, ebuf) < 0)) 381 goto bad; 382 /* 383 ** Bind (defer if using HP-UX 9 or HP-UX 10.20, totally skip if 384 ** using SINIX) 385 */ 386 #if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20) && !defined(sinix) 387 #ifdef _AIX 388 /* According to IBM's AIX Support Line, the dl_sap value 389 ** should not be less than 0x600 (1536) for standard Ethernet. 390 ** However, we seem to get DL_BADADDR - "DLSAP addr in improper 391 ** format or invalid" - errors if we use 1537 on the "tr0" 392 ** device, which, given that its name starts with "tr" and that 393 ** it's IBM, probably means a Token Ring device. (Perhaps we 394 ** need to use 1537 on "/dev/dlpi/en" because that device is for 395 ** D/I/X Ethernet, the "SAP" is actually an Ethernet type, and 396 ** it rejects invalid Ethernet types.) 397 ** 398 ** So if 1537 fails, we try 2, as Hyung Sik Yoon of IBM Korea 399 ** says that works on Token Ring (he says that 0 does *not* 400 ** work; perhaps that's considered an invalid LLC SAP value - I 401 ** assume the SAP value in a DLPI bind is an LLC SAP for network 402 ** types that use 802.2 LLC). 403 */ 404 if ((dlbindreq(p->fd, 1537, ebuf) < 0 && 405 dlbindreq(p->fd, 2, ebuf) < 0) || 406 #else 407 if (dlbindreq(p->fd, 0, ebuf) < 0 || 408 #endif 409 dlbindack(p->fd, (char *)buf, ebuf) < 0) 410 goto bad; 411 #endif 412 413 if (promisc) { 414 /* 415 ** Enable promiscuous 416 */ 417 if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 || 418 dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0) 419 goto bad; 420 421 /* 422 ** Try to enable multicast (you would have thought 423 ** promiscuous would be sufficient). (Skip if using 424 ** HP-UX or SINIX) 425 */ 426 #if !defined(__hpux) && !defined(sinix) 427 if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 || 428 dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0) 429 fprintf(stderr, 430 "WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf); 431 #endif 432 } 433 /* 434 ** Try to enable sap (when not in promiscuous mode when using 435 ** using HP-UX and never under SINIX) 436 */ 437 #ifndef sinix 438 if ( 439 #ifdef __hpux 440 !promisc && 441 #endif 442 (dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 || 443 dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) { 444 /* Not fatal if promisc since the DL_PROMISC_PHYS worked */ 445 if (promisc) 446 fprintf(stderr, 447 "WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf); 448 else 449 goto bad; 450 } 451 #endif 452 453 /* 454 ** HP-UX 9 and HP-UX 10.20 must bind after setting promiscuous 455 ** options) 456 */ 457 #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20) 458 if (dlbindreq(p->fd, 0, ebuf) < 0 || 459 dlbindack(p->fd, (char *)buf, ebuf) < 0) 460 goto bad; 461 #endif 462 463 /* 464 ** Determine link type 465 */ 466 if (dlinforeq(p->fd, ebuf) < 0 || 467 dlinfoack(p->fd, (char *)buf, ebuf) < 0) 468 goto bad; 469 470 infop = &((union DL_primitives *)buf)->info_ack; 471 switch (infop->dl_mac_type) { 472 473 case DL_CSMACD: 474 case DL_ETHER: 475 p->linktype = DLT_EN10MB; 476 p->offset = 2; 477 break; 478 479 case DL_FDDI: 480 p->linktype = DLT_FDDI; 481 p->offset = 3; 482 break; 483 484 case DL_TPR: 485 p->linktype = DLT_IEEE802; 486 p->offset = 2; 487 break; 488 489 default: 490 snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mac type %lu", 491 infop->dl_mac_type); 492 goto bad; 493 } 494 495 #ifdef DLIOCRAW 496 /* 497 ** This is a non standard SunOS hack to get the ethernet header. 498 */ 499 if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { 500 snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s", 501 pcap_strerror(errno)); 502 goto bad; 503 } 504 #endif 505 506 #ifdef HAVE_SYS_BUFMOD_H 507 /* 508 ** Another non standard call to get the data nicely buffered 509 */ 510 if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { 511 snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_PUSH bufmod: %s", 512 pcap_strerror(errno)); 513 goto bad; 514 } 515 516 /* 517 ** Now that the bufmod is pushed lets configure it. 518 ** 519 ** There is a bug in bufmod(7). When dealing with messages of 520 ** less than snaplen size it strips data from the beginning not 521 ** the end. 522 ** 523 ** This bug is supposed to be fixed in 5.3.2. Also, there is a 524 ** patch available. Ask for bugid 1149065. 525 */ 526 ss = snaplen; 527 #ifdef HAVE_SOLARIS 528 release = get_release(&osmajor, &osminor, &osmicro); 529 if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && 530 getenv("BUFMOD_FIXED") == NULL) { 531 fprintf(stderr, 532 "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n", 533 release); 534 ss = 0; 535 } 536 #endif 537 if (ss > 0 && 538 strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { 539 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSSNAP: %s", 540 pcap_strerror(errno)); 541 goto bad; 542 } 543 544 /* 545 ** Set up the bufmod flags 546 */ 547 if (strioctl(p->fd, SBIOCGFLAGS, sizeof(flag), (char *)&flag) < 0) { 548 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCGFLAGS: %s", 549 pcap_strerror(errno)); 550 goto bad; 551 } 552 flag |= SB_NO_DROPS; 553 if (strioctl(p->fd, SBIOCSFLAGS, sizeof(flag), (char *)&flag) != 0) { 554 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSFLAGS: %s", 555 pcap_strerror(errno)); 556 goto bad; 557 } 558 /* 559 ** Set up the bufmod timeout 560 */ 561 if (to_ms != 0) { 562 struct timeval to; 563 564 to.tv_sec = to_ms / 1000; 565 to.tv_usec = (to_ms * 1000) % 1000000; 566 if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { 567 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSTIME: %s", 568 pcap_strerror(errno)); 569 goto bad; 570 } 571 } 572 #endif 573 574 /* 575 ** As the last operation flush the read side. 576 */ 577 if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { 578 snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", 579 pcap_strerror(errno)); 580 goto bad; 581 } 582 /* Allocate data buffer */ 583 p->bufsize = MAXDLBUF * sizeof(bpf_u_int32); 584 p->buffer = (u_char *)malloc(p->bufsize + p->offset); 585 586 return (p); 587 bad: 588 if (p->fd >= 0) 589 close(p->fd); 590 free(p); 591 return (NULL); 592 } 593 594 /* 595 * Split a device name into a device type name and a unit number; 596 * return the a pointer to the beginning of the unit number, which 597 * is the end of the device type name, and set "*unitp" to the unit 598 * number. 599 * 600 * Returns NULL on error, and fills "ebuf" with an error message. 601 */ 602 static char * 603 split_dname(char *device, int *unitp, char *ebuf) 604 { 605 char *cp; 606 char *eos; 607 int unit; 608 609 /* 610 * Look for a number at the end of the device name string. 611 */ 612 cp = device + strlen(device) - 1; 613 if (*cp < '0' || *cp > '9') { 614 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", 615 device); 616 return (NULL); 617 } 618 619 /* Digits at end of string are unit number */ 620 while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9') 621 cp--; 622 623 unit = strtol(cp, &eos, 10); 624 if (*eos != '\0') { 625 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); 626 return (NULL); 627 } 628 *unitp = unit; 629 return (cp); 630 } 631 632 int 633 pcap_setfilter(pcap_t *p, struct bpf_program *fp) 634 { 635 636 if (install_bpf_program(p, fp) < 0) 637 return (-1); 638 return (0); 639 } 640 641 static int 642 send_request(int fd, char *ptr, int len, char *what, char *ebuf) 643 { 644 struct strbuf ctl; 645 int flags; 646 647 ctl.maxlen = 0; 648 ctl.len = len; 649 ctl.buf = ptr; 650 651 flags = 0; 652 if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { 653 snprintf(ebuf, PCAP_ERRBUF_SIZE, 654 "send_request: putmsg \"%s\": %s", 655 what, pcap_strerror(errno)); 656 return (-1); 657 } 658 return (0); 659 } 660 661 static int 662 recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf) 663 { 664 union DL_primitives *dlp; 665 struct strbuf ctl; 666 int flags; 667 668 ctl.maxlen = MAXDLBUF; 669 ctl.len = 0; 670 ctl.buf = bufp; 671 672 flags = 0; 673 if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { 674 snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s", 675 what, pcap_strerror(errno)); 676 return (-1); 677 } 678 679 dlp = (union DL_primitives *) ctl.buf; 680 switch (dlp->dl_primitive) { 681 682 case DL_INFO_ACK: 683 case DL_BIND_ACK: 684 case DL_OK_ACK: 685 #ifdef DL_HP_PPA_ACK 686 case DL_HP_PPA_ACK: 687 #endif 688 /* These are OK */ 689 break; 690 691 case DL_ERROR_ACK: 692 switch (dlp->error_ack.dl_errno) { 693 694 case DL_SYSERR: 695 snprintf(ebuf, PCAP_ERRBUF_SIZE, 696 "recv_ack: %s: UNIX error - %s", 697 what, pcap_strerror(dlp->error_ack.dl_unix_errno)); 698 break; 699 700 default: 701 snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s", 702 what, dlstrerror(dlp->error_ack.dl_errno)); 703 break; 704 } 705 return (-1); 706 707 default: 708 snprintf(ebuf, PCAP_ERRBUF_SIZE, 709 "recv_ack: %s: Unexpected primitive ack %s", 710 what, dlprim(dlp->dl_primitive)); 711 return (-1); 712 } 713 714 if (ctl.len < size) { 715 snprintf(ebuf, PCAP_ERRBUF_SIZE, 716 "recv_ack: %s: Ack too small (%d < %d)", 717 what, ctl.len, size); 718 return (-1); 719 } 720 return (ctl.len); 721 } 722 723 static char * 724 dlstrerror(bpf_u_int32 dl_errno) 725 { 726 static char errstring[6+2+8+1]; 727 728 switch (dl_errno) { 729 730 case DL_ACCESS: 731 return ("Improper permissions for request"); 732 733 case DL_BADADDR: 734 return ("DLSAP addr in improper format or invalid"); 735 736 case DL_BADCORR: 737 return ("Seq number not from outstand DL_CONN_IND"); 738 739 case DL_BADDATA: 740 return ("User data exceeded provider limit"); 741 742 case DL_BADPPA: 743 #ifdef HAVE_DEV_DLPI 744 /* 745 * With a single "/dev/dlpi" device used for all 746 * DLPI providers, PPAs have nothing to do with 747 * unit numbers. 748 */ 749 return ("Specified PPA was invalid"); 750 #else 751 /* 752 * We have separate devices for separate devices; 753 * the PPA is just the unit number. 754 */ 755 return ("Specified PPA (device unit) was invalid"); 756 #endif 757 758 case DL_BADPRIM: 759 return ("Primitive received not known by provider"); 760 761 case DL_BADQOSPARAM: 762 return ("QOS parameters contained invalid values"); 763 764 case DL_BADQOSTYPE: 765 return ("QOS structure type is unknown/unsupported"); 766 767 case DL_BADSAP: 768 return ("Bad LSAP selector"); 769 770 case DL_BADTOKEN: 771 return ("Token used not an active stream"); 772 773 case DL_BOUND: 774 return ("Attempted second bind with dl_max_conind"); 775 776 case DL_INITFAILED: 777 return ("Physical link initialization failed"); 778 779 case DL_NOADDR: 780 return ("Provider couldn't allocate alternate address"); 781 782 case DL_NOTINIT: 783 return ("Physical link not initialized"); 784 785 case DL_OUTSTATE: 786 return ("Primitive issued in improper state"); 787 788 case DL_SYSERR: 789 return ("UNIX system error occurred"); 790 791 case DL_UNSUPPORTED: 792 return ("Requested service not supplied by provider"); 793 794 case DL_UNDELIVERABLE: 795 return ("Previous data unit could not be delivered"); 796 797 case DL_NOTSUPPORTED: 798 return ("Primitive is known but not supported"); 799 800 case DL_TOOMANY: 801 return ("Limit exceeded"); 802 803 case DL_NOTENAB: 804 return ("Promiscuous mode not enabled"); 805 806 case DL_BUSY: 807 return ("Other streams for PPA in post-attached"); 808 809 case DL_NOAUTO: 810 return ("Automatic handling XID&TEST not supported"); 811 812 case DL_NOXIDAUTO: 813 return ("Automatic handling of XID not supported"); 814 815 case DL_NOTESTAUTO: 816 return ("Automatic handling of TEST not supported"); 817 818 case DL_XIDAUTO: 819 return ("Automatic handling of XID response"); 820 821 case DL_TESTAUTO: 822 return ("Automatic handling of TEST response"); 823 824 case DL_PENDING: 825 return ("Pending outstanding connect indications"); 826 827 default: 828 sprintf(errstring, "Error %02x", dl_errno); 829 return (errstring); 830 } 831 } 832 833 static char * 834 dlprim(bpf_u_int32 prim) 835 { 836 static char primbuf[80]; 837 838 switch (prim) { 839 840 case DL_INFO_REQ: 841 return ("DL_INFO_REQ"); 842 843 case DL_INFO_ACK: 844 return ("DL_INFO_ACK"); 845 846 case DL_ATTACH_REQ: 847 return ("DL_ATTACH_REQ"); 848 849 case DL_DETACH_REQ: 850 return ("DL_DETACH_REQ"); 851 852 case DL_BIND_REQ: 853 return ("DL_BIND_REQ"); 854 855 case DL_BIND_ACK: 856 return ("DL_BIND_ACK"); 857 858 case DL_UNBIND_REQ: 859 return ("DL_UNBIND_REQ"); 860 861 case DL_OK_ACK: 862 return ("DL_OK_ACK"); 863 864 case DL_ERROR_ACK: 865 return ("DL_ERROR_ACK"); 866 867 case DL_SUBS_BIND_REQ: 868 return ("DL_SUBS_BIND_REQ"); 869 870 case DL_SUBS_BIND_ACK: 871 return ("DL_SUBS_BIND_ACK"); 872 873 case DL_UNITDATA_REQ: 874 return ("DL_UNITDATA_REQ"); 875 876 case DL_UNITDATA_IND: 877 return ("DL_UNITDATA_IND"); 878 879 case DL_UDERROR_IND: 880 return ("DL_UDERROR_IND"); 881 882 case DL_UDQOS_REQ: 883 return ("DL_UDQOS_REQ"); 884 885 case DL_CONNECT_REQ: 886 return ("DL_CONNECT_REQ"); 887 888 case DL_CONNECT_IND: 889 return ("DL_CONNECT_IND"); 890 891 case DL_CONNECT_RES: 892 return ("DL_CONNECT_RES"); 893 894 case DL_CONNECT_CON: 895 return ("DL_CONNECT_CON"); 896 897 case DL_TOKEN_REQ: 898 return ("DL_TOKEN_REQ"); 899 900 case DL_TOKEN_ACK: 901 return ("DL_TOKEN_ACK"); 902 903 case DL_DISCONNECT_REQ: 904 return ("DL_DISCONNECT_REQ"); 905 906 case DL_DISCONNECT_IND: 907 return ("DL_DISCONNECT_IND"); 908 909 case DL_RESET_REQ: 910 return ("DL_RESET_REQ"); 911 912 case DL_RESET_IND: 913 return ("DL_RESET_IND"); 914 915 case DL_RESET_RES: 916 return ("DL_RESET_RES"); 917 918 case DL_RESET_CON: 919 return ("DL_RESET_CON"); 920 921 default: 922 (void) sprintf(primbuf, "unknown primitive 0x%x", prim); 923 return (primbuf); 924 } 925 } 926 927 static int 928 dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf) 929 { 930 dl_attach_req_t req; 931 932 req.dl_primitive = DL_ATTACH_REQ; 933 req.dl_ppa = ppa; 934 935 return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf)); 936 } 937 938 static int 939 dlbindreq(int fd, bpf_u_int32 sap, char *ebuf) 940 { 941 942 dl_bind_req_t req; 943 944 memset((char *)&req, 0, sizeof(req)); 945 req.dl_primitive = DL_BIND_REQ; 946 #ifdef DL_HP_RAWDLS 947 req.dl_max_conind = 1; /* XXX magic number */ 948 /* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */ 949 req.dl_sap = 22; 950 req.dl_service_mode = DL_HP_RAWDLS; 951 #else 952 req.dl_sap = sap; 953 #ifdef DL_CLDLS 954 req.dl_service_mode = DL_CLDLS; 955 #endif 956 #endif 957 958 return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf)); 959 } 960 961 static int 962 dlbindack(int fd, char *bufp, char *ebuf) 963 { 964 965 return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf)); 966 } 967 968 static int 969 dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf) 970 { 971 dl_promiscon_req_t req; 972 973 req.dl_primitive = DL_PROMISCON_REQ; 974 req.dl_level = level; 975 976 return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf)); 977 } 978 979 static int 980 dlokack(int fd, const char *what, char *bufp, char *ebuf) 981 { 982 983 return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf)); 984 } 985 986 987 static int 988 dlinforeq(int fd, char *ebuf) 989 { 990 dl_info_req_t req; 991 992 req.dl_primitive = DL_INFO_REQ; 993 994 return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf)); 995 } 996 997 static int 998 dlinfoack(int fd, char *bufp, char *ebuf) 999 { 1000 1001 return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf)); 1002 } 1003 1004 #ifdef HAVE_SYS_BUFMOD_H 1005 static int 1006 strioctl(int fd, int cmd, int len, char *dp) 1007 { 1008 struct strioctl str; 1009 int rc; 1010 1011 str.ic_cmd = cmd; 1012 str.ic_timout = -1; 1013 str.ic_len = len; 1014 str.ic_dp = dp; 1015 rc = ioctl(fd, I_STR, &str); 1016 1017 if (rc < 0) 1018 return (rc); 1019 else 1020 return (str.ic_len); 1021 } 1022 #endif 1023 1024 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 1025 static char * 1026 get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp) 1027 { 1028 char *cp; 1029 static char buf[32]; 1030 1031 *majorp = 0; 1032 *minorp = 0; 1033 *microp = 0; 1034 if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0) 1035 return ("?"); 1036 cp = buf; 1037 if (!isdigit((unsigned char)*cp)) 1038 return (buf); 1039 *majorp = strtol(cp, &cp, 10); 1040 if (*cp++ != '.') 1041 return (buf); 1042 *minorp = strtol(cp, &cp, 10); 1043 if (*cp++ != '.') 1044 return (buf); 1045 *microp = strtol(cp, &cp, 10); 1046 return (buf); 1047 } 1048 #endif 1049 1050 #ifdef DL_HP_PPA_ACK_OBS 1051 /* 1052 * Under HP-UX 10 and HP-UX 11, we can ask for the ppa 1053 */ 1054 1055 1056 /* 1057 * Determine ppa number that specifies ifname. 1058 * 1059 * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, 1060 * the code that's used here is the old code for HP-UX 10.x. 1061 * 1062 * However, HP-UX 10.20, at least, appears to have such a member 1063 * in its "dl_hp_ppa_info_t" structure, so the new code is used. 1064 * The new code didn't work on an old 10.20 system on which Rick 1065 * Jones of HP tried it, but with later patches installed, it 1066 * worked - it appears that the older system had those members but 1067 * didn't put anything in them, so, if the search by name fails, we 1068 * do the old search. 1069 * 1070 * Rick suggests that making sure your system is "up on the latest 1071 * lancommon/DLPI/driver patches" is probably a good idea; it'd fix 1072 * that problem, as well as allowing libpcap to see packets sent 1073 * from the system on which the libpcap application is being run. 1074 * (On 10.20, in addition to getting the latest patches, you need 1075 * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; 1076 * a posting to "comp.sys.hp.hpux" at 1077 * 1078 * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 1079 * 1080 * says that, to see the machine's outgoing traffic, you'd need to 1081 * apply the right patches to your system, and also set that variable 1082 * with: 1083 1084 echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem 1085 1086 * which could be put in, for example, "/sbin/init.d/lan". 1087 * 1088 * Setting the variable is not necessary on HP-UX 11.x. 1089 */ 1090 static int 1091 get_dlpi_ppa(register int fd, register const char *device, register int unit, 1092 register char *ebuf) 1093 { 1094 register dl_hp_ppa_ack_t *ap; 1095 register dl_hp_ppa_info_t *ipstart, *ip; 1096 register int i; 1097 char dname[100]; 1098 register u_long majdev; 1099 struct stat statbuf; 1100 dl_hp_ppa_req_t req; 1101 char buf[MAXDLBUF]; 1102 char *ppa_data_buf; 1103 dl_hp_ppa_ack_t *dlp; 1104 struct strbuf ctl; 1105 int flags; 1106 int ppa; 1107 1108 memset((char *)&req, 0, sizeof(req)); 1109 req.dl_primitive = DL_HP_PPA_REQ; 1110 1111 memset((char *)buf, 0, sizeof(buf)); 1112 if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0) 1113 return (-1); 1114 1115 ctl.maxlen = DL_HP_PPA_ACK_SIZE; 1116 ctl.len = 0; 1117 ctl.buf = (char *)buf; 1118 1119 flags = 0; 1120 /* 1121 * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal 1122 * recv_ack will fail because it set the maxlen to MAXDLBUF (8192) 1123 * which is NOT big enough for a DL_HP_PPA_REQ. 1124 * 1125 * This causes libpcap applications to fail on a system with HP-APA 1126 * installed. 1127 * 1128 * To figure out how big the returned data is, we first call getmsg 1129 * to get the small head and peek at the head to get the actual data 1130 * length, and then issue another getmsg to get the actual PPA data. 1131 */ 1132 /* get the head first */ 1133 if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { 1134 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1135 "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); 1136 return (-1); 1137 } 1138 1139 dlp = (dl_hp_ppa_ack_t *)ctl.buf; 1140 if (dlp->dl_primitive != DL_HP_PPA_ACK) { 1141 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1142 "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x", 1143 (bpf_u_int32)dlp->dl_primitive); 1144 return (-1); 1145 } 1146 1147 if (ctl.len < DL_HP_PPA_ACK_SIZE) { 1148 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1149 "get_dlpi_ppa: hpppa ack too small (%d < %d)", 1150 ctl.len, DL_HP_PPA_ACK_SIZE); 1151 return (-1); 1152 } 1153 1154 /* allocate buffer */ 1155 if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) { 1156 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1157 "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno)); 1158 return (-1); 1159 } 1160 ctl.maxlen = dlp->dl_length; 1161 ctl.len = 0; 1162 ctl.buf = (char *)ppa_data_buf; 1163 /* get the data */ 1164 if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { 1165 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1166 "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); 1167 free(ppa_data_buf); 1168 return (-1); 1169 } 1170 if (ctl.len < dlp->dl_length) { 1171 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1172 "get_dlpi_ppa: hpppa ack too small (%d < %d)", 1173 ctl.len, dlp->dl_length); 1174 free(ppa_data_buf); 1175 return (-1); 1176 } 1177 1178 ap = (dl_hp_ppa_ack_t *)buf; 1179 ipstart = (dl_hp_ppa_info_t *)ppa_data_buf; 1180 ip = ipstart; 1181 1182 #ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1183 /* 1184 * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1" 1185 * member that should, in theory, contain the part of the 1186 * name for the device that comes before the unit number, 1187 * and should also have a "dl_module_id_2" member that may 1188 * contain an alternate name (e.g., I think Ethernet devices 1189 * have both "lan", for "lanN", and "snap", for "snapN", with 1190 * the former being for Ethernet packets and the latter being 1191 * for 802.3/802.2 packets). 1192 * 1193 * Search for the device that has the specified name and 1194 * instance number. 1195 */ 1196 for (i = 0; i < ap->dl_count; i++) { 1197 if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 || 1198 strcmp((const char *)ip->dl_module_id_2, device) == 0) && 1199 ip->dl_instance_num == unit) 1200 break; 1201 1202 ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); 1203 } 1204 #else 1205 /* 1206 * We don't have that member, so the search is impossible; make it 1207 * look as if the search failed. 1208 */ 1209 i = ap->dl_count; 1210 #endif 1211 1212 if (i == ap->dl_count) { 1213 /* 1214 * Well, we didn't, or can't, find the device by name. 1215 * 1216 * HP-UX 10.20, whilst it has "dl_module_id_1" and 1217 * "dl_module_id_2" fields in the "dl_hp_ppa_info_t", 1218 * doesn't seem to fill them in unless the system is 1219 * at a reasonably up-to-date patch level. 1220 * 1221 * Older HP-UX 10.x systems might not have those fields 1222 * at all. 1223 * 1224 * Therefore, we'll search for the entry with the major 1225 * device number of a device with the name "/dev/<dev><unit>", 1226 * if such a device exists, as the old code did. 1227 */ 1228 snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit); 1229 if (stat(dname, &statbuf) < 0) { 1230 snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s", 1231 dname, pcap_strerror(errno)); 1232 return (-1); 1233 } 1234 majdev = major(statbuf.st_rdev); 1235 1236 ip = ipstart; 1237 1238 for (i = 0; i < ap->dl_count; i++) { 1239 if (ip->dl_mjr_num == majdev && 1240 ip->dl_instance_num == unit) 1241 break; 1242 1243 ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); 1244 } 1245 } 1246 if (i == ap->dl_count) { 1247 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1248 "can't find /dev/dlpi PPA for %s%d", device, unit); 1249 return (-1); 1250 } 1251 if (ip->dl_hdw_state == HDW_DEAD) { 1252 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1253 "%s%d: hardware state: DOWN\n", device, unit); 1254 free(ppa_data_buf); 1255 return (-1); 1256 } 1257 ppa = ip->dl_ppa; 1258 free(ppa_data_buf); 1259 return (ppa); 1260 } 1261 #endif 1262 1263 #ifdef HAVE_HPUX9 1264 /* 1265 * Under HP-UX 9, there is no good way to determine the ppa. 1266 * So punt and read it from /dev/kmem. 1267 */ 1268 static struct nlist nl[] = { 1269 #define NL_IFNET 0 1270 { "ifnet" }, 1271 { "" } 1272 }; 1273 1274 static char path_vmunix[] = "/hp-ux"; 1275 1276 /* Determine ppa number that specifies ifname */ 1277 static int 1278 get_dlpi_ppa(register int fd, register const char *ifname, register int unit, 1279 register char *ebuf) 1280 { 1281 register const char *cp; 1282 register int kd; 1283 void *addr; 1284 struct ifnet ifnet; 1285 char if_name[sizeof(ifnet.if_name) + 1]; 1286 1287 cp = strrchr(ifname, '/'); 1288 if (cp != NULL) 1289 ifname = cp + 1; 1290 if (nlist(path_vmunix, &nl) < 0) { 1291 snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", 1292 path_vmunix); 1293 return (-1); 1294 } 1295 if (nl[NL_IFNET].n_value == 0) { 1296 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1297 "could't find %s kernel symbol", 1298 nl[NL_IFNET].n_name); 1299 return (-1); 1300 } 1301 kd = open("/dev/kmem", O_RDONLY); 1302 if (kd < 0) { 1303 snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s", 1304 pcap_strerror(errno)); 1305 return (-1); 1306 } 1307 if (dlpi_kread(kd, nl[NL_IFNET].n_value, 1308 &addr, sizeof(addr), ebuf) < 0) { 1309 close(kd); 1310 return (-1); 1311 } 1312 for (; addr != NULL; addr = ifnet.if_next) { 1313 if (dlpi_kread(kd, (off_t)addr, 1314 &ifnet, sizeof(ifnet), ebuf) < 0 || 1315 dlpi_kread(kd, (off_t)ifnet.if_name, 1316 if_name, sizeof(ifnet.if_name), ebuf) < 0) { 1317 (void)close(kd); 1318 return (-1); 1319 } 1320 if_name[sizeof(ifnet.if_name)] = '\0'; 1321 if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) 1322 return (ifnet.if_index); 1323 } 1324 1325 snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); 1326 return (-1); 1327 } 1328 1329 static int 1330 dlpi_kread(register int fd, register off_t addr, 1331 register void *buf, register u_int len, register char *ebuf) 1332 { 1333 register int cc; 1334 1335 if (lseek(fd, addr, SEEK_SET) < 0) { 1336 snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s", 1337 pcap_strerror(errno)); 1338 return (-1); 1339 } 1340 cc = read(fd, buf, len); 1341 if (cc < 0) { 1342 snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s", 1343 pcap_strerror(errno)); 1344 return (-1); 1345 } else if (cc != len) { 1346 snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, 1347 len); 1348 return (-1); 1349 } 1350 return (cc); 1351 } 1352 #endif 1353