1 /* $NetBSD: pcap-dlpi.c,v 1.1.1.4 2013/12/31 16:57:26 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), 24 * University College London, and subsequently modified by 25 * Guy Harris (guy@alum.mit.edu), Mark Pizzolato 26 * <List-tcpdump-workers@subscriptions.pizzolato.net>, 27 * Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>. 28 */ 29 30 /* 31 * Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX. 32 * 33 * Notes: 34 * 35 * - The DLIOCRAW ioctl() is specific to SunOS. 36 * 37 * - There is a bug in bufmod(7) such that setting the snapshot 38 * length results in data being left of the front of the packet. 39 * 40 * - It might be desirable to use pfmod(7) to filter packets in the 41 * kernel when possible. 42 * 43 * - An older version of the HP-UX DLPI Programmer's Guide, which 44 * I think was advertised as the 10.20 version, used to be available 45 * at 46 * 47 * http://docs.hp.com/hpux/onlinedocs/B2355-90093/B2355-90093.html 48 * 49 * but is no longer available; it can still be found at 50 * 51 * http://h21007.www2.hp.com/dspp/files/unprotected/Drivers/Docs/Refs/B2355-90093.pdf 52 * 53 * in PDF form. 54 * 55 * - The HP-UX 10.x, 11.0, and 11i v1.6 version of the HP-UX DLPI 56 * Programmer's Guide, which I think was once advertised as the 57 * 11.00 version is available at 58 * 59 * http://docs.hp.com/en/B2355-90139/index.html 60 * 61 * - The HP-UX 11i v2 version of the HP-UX DLPI Programmer's Guide 62 * is available at 63 * 64 * http://docs.hp.com/en/B2355-90871/index.html 65 * 66 * - All of the HP documents describe raw-mode services, which are 67 * what we use if DL_HP_RAWDLS is defined. XXX - we use __hpux 68 * in some places to test for HP-UX, but use DL_HP_RAWDLS in 69 * other places; do we support any versions of HP-UX without 70 * DL_HP_RAWDLS? 71 */ 72 73 #ifndef lint 74 static const char rcsid[] _U_ = 75 "@(#) Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.128 2008-12-02 16:20:23 guy Exp (LBL)"; 76 #endif 77 78 #ifdef HAVE_CONFIG_H 79 #include "config.h" 80 #endif 81 82 #include <sys/types.h> 83 #include <sys/time.h> 84 #ifdef HAVE_SYS_BUFMOD_H 85 #include <sys/bufmod.h> 86 #endif 87 #include <sys/dlpi.h> 88 #ifdef HAVE_SYS_DLPI_EXT_H 89 #include <sys/dlpi_ext.h> 90 #endif 91 #ifdef HAVE_HPUX9 92 #include <sys/socket.h> 93 #endif 94 #ifdef DL_HP_PPA_REQ 95 #include <sys/stat.h> 96 #endif 97 #include <sys/stream.h> 98 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 99 #include <sys/systeminfo.h> 100 #endif 101 102 #ifdef HAVE_HPUX9 103 #include <net/if.h> 104 #endif 105 106 #include <ctype.h> 107 #ifdef HAVE_HPUX9 108 #include <nlist.h> 109 #endif 110 #include <errno.h> 111 #include <fcntl.h> 112 #include <memory.h> 113 #include <stdio.h> 114 #include <stdlib.h> 115 #include <string.h> 116 #include <stropts.h> 117 #include <unistd.h> 118 119 #ifdef HAVE_LIMITS_H 120 #include <limits.h> 121 #else 122 #define INT_MAX 2147483647 123 #endif 124 125 #include "pcap-int.h" 126 #include "dlpisubs.h" 127 128 #ifdef HAVE_OS_PROTO_H 129 #include "os-proto.h" 130 #endif 131 132 #ifndef PCAP_DEV_PREFIX 133 #ifdef _AIX 134 #define PCAP_DEV_PREFIX "/dev/dlpi" 135 #else 136 #define PCAP_DEV_PREFIX "/dev" 137 #endif 138 #endif 139 140 #define MAXDLBUF 8192 141 142 /* Forwards */ 143 static char *split_dname(char *, int *, char *); 144 static int dl_doattach(int, int, char *); 145 #ifdef DL_HP_RAWDLS 146 static int dl_dohpuxbind(int, char *); 147 #endif 148 static int dlpromiscon(pcap_t *, bpf_u_int32); 149 static int dlbindreq(int, bpf_u_int32, char *); 150 static int dlbindack(int, char *, char *, int *); 151 static int dlokack(int, const char *, char *, char *); 152 static int dlinforeq(int, char *); 153 static int dlinfoack(int, char *, char *); 154 155 #ifdef HAVE_DLPI_PASSIVE 156 static void dlpassive(int, char *); 157 #endif 158 159 #ifdef DL_HP_RAWDLS 160 static int dlrawdatareq(int, const u_char *, int); 161 #endif 162 static int recv_ack(int, int, const char *, char *, char *, int *); 163 static char *dlstrerror(bpf_u_int32); 164 static char *dlprim(bpf_u_int32); 165 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 166 static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *); 167 #endif 168 static int send_request(int, char *, int, char *, char *); 169 #ifdef HAVE_HPUX9 170 static int dlpi_kread(int, off_t, void *, u_int, char *); 171 #endif 172 #ifdef HAVE_DEV_DLPI 173 static int get_dlpi_ppa(int, const char *, int, char *); 174 #endif 175 176 /* XXX Needed by HP-UX (at least) */ 177 static bpf_u_int32 ctlbuf[MAXDLBUF]; 178 static struct strbuf ctl = { 179 MAXDLBUF, 180 0, 181 (char *)ctlbuf 182 }; 183 184 /* 185 * Cast a buffer to "union DL_primitives" without provoking warnings 186 * from the compiler. 187 */ 188 #define MAKE_DL_PRIMITIVES(ptr) ((union DL_primitives *)(void *)(ptr)) 189 190 static int 191 pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 192 { 193 int cc; 194 u_char *bp; 195 int flags; 196 struct strbuf data; 197 198 flags = 0; 199 cc = p->cc; 200 if (cc == 0) { 201 data.buf = (char *)p->buffer + p->offset; 202 data.maxlen = p->bufsize; 203 data.len = 0; 204 do { 205 /* 206 * Has "pcap_breakloop()" been called? 207 */ 208 if (p->break_loop) { 209 /* 210 * Yes - clear the flag that indicates 211 * that it has, and return -2 to 212 * indicate that we were told to 213 * break out of the loop. 214 */ 215 p->break_loop = 0; 216 return (-2); 217 } 218 /* 219 * XXX - check for the DLPI primitive, which 220 * would be DL_HP_RAWDATA_IND on HP-UX 221 * if we're in raw mode? 222 */ 223 if (getmsg(p->fd, &ctl, &data, &flags) < 0) { 224 /* Don't choke when we get ptraced */ 225 switch (errno) { 226 227 case EINTR: 228 cc = 0; 229 continue; 230 231 case EAGAIN: 232 return (0); 233 } 234 strlcpy(p->errbuf, pcap_strerror(errno), 235 sizeof(p->errbuf)); 236 return (-1); 237 } 238 cc = data.len; 239 } while (cc == 0); 240 bp = p->buffer + p->offset; 241 } else 242 bp = p->bp; 243 244 return (pcap_process_pkts(p, callback, user, cnt, bp, cc)); 245 } 246 247 static int 248 pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size) 249 { 250 #ifdef DL_HP_RAWDLS 251 struct pcap_dlpi *pd = p->priv; 252 #endif 253 int ret; 254 255 #if defined(DLIOCRAW) 256 ret = write(p->fd, buf, size); 257 if (ret == -1) { 258 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 259 pcap_strerror(errno)); 260 return (-1); 261 } 262 #elif defined(DL_HP_RAWDLS) 263 if (pd->send_fd < 0) { 264 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 265 "send: Output FD couldn't be opened"); 266 return (-1); 267 } 268 ret = dlrawdatareq(pd->send_fd, buf, size); 269 if (ret == -1) { 270 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 271 pcap_strerror(errno)); 272 return (-1); 273 } 274 /* 275 * putmsg() returns either 0 or -1; it doesn't indicate how 276 * many bytes were written (presumably they were all written 277 * or none of them were written). OpenBSD's pcap_inject() 278 * returns the number of bytes written, so, for API compatibility, 279 * we return the number of bytes we were told to write. 280 */ 281 ret = size; 282 #else /* no raw mode */ 283 /* 284 * XXX - this is a pain, because you might have to extract 285 * the address from the packet and use it in a DL_UNITDATA_REQ 286 * request. That would be dependent on the link-layer type. 287 * 288 * I also don't know what SAP you'd have to bind the descriptor 289 * to, or whether you'd need separate "receive" and "send" FDs, 290 * nor do I know whether you'd need different bindings for 291 * D/I/X Ethernet and 802.3, or for {FDDI,Token Ring} plus 292 * 802.2 and {FDDI,Token Ring} plus 802.2 plus SNAP. 293 * 294 * So, for now, we just return a "you can't send" indication, 295 * and leave it up to somebody with a DLPI-based system lacking 296 * both DLIOCRAW and DL_HP_RAWDLS to supply code to implement 297 * packet transmission on that system. If they do, they should 298 * send it to us - but should not send us code that assumes 299 * Ethernet; if the code doesn't work on non-Ethernet interfaces, 300 * it should check "p->linktype" and reject the send request if 301 * it's anything other than DLT_EN10MB. 302 */ 303 strlcpy(p->errbuf, "send: Not supported on this version of this OS", 304 PCAP_ERRBUF_SIZE); 305 ret = -1; 306 #endif /* raw mode */ 307 return (ret); 308 } 309 310 #ifndef DL_IPATM 311 #define DL_IPATM 0x12 /* ATM Classical IP interface */ 312 #endif 313 314 #ifdef HAVE_SOLARIS 315 /* 316 * For SunATM. 317 */ 318 #ifndef A_GET_UNITS 319 #define A_GET_UNITS (('A'<<8)|118) 320 #endif /* A_GET_UNITS */ 321 #ifndef A_PROMISCON_REQ 322 #define A_PROMISCON_REQ (('A'<<8)|121) 323 #endif /* A_PROMISCON_REQ */ 324 #endif /* HAVE_SOLARIS */ 325 326 static void 327 pcap_cleanup_dlpi(pcap_t *p) 328 { 329 #ifdef DL_HP_RAWDLS 330 struct pcap_dlpi *pd = p->priv; 331 332 if (pd->send_fd >= 0) { 333 close(pd->send_fd); 334 pd->send_fd = -1; 335 } 336 #endif 337 pcap_cleanup_live_common(p); 338 } 339 340 static int 341 pcap_activate_dlpi(pcap_t *p) 342 { 343 #ifdef DL_HP_RAWDLS 344 struct pcap_dlpi *pd = p->priv; 345 #endif 346 register char *cp; 347 int ppa; 348 #ifdef HAVE_SOLARIS 349 int isatm = 0; 350 #endif 351 register dl_info_ack_t *infop; 352 #ifdef HAVE_SYS_BUFMOD_H 353 bpf_u_int32 ss; 354 #ifdef HAVE_SOLARIS 355 register char *release; 356 bpf_u_int32 osmajor, osminor, osmicro; 357 #endif 358 #endif 359 bpf_u_int32 buf[MAXDLBUF]; 360 char dname[100]; 361 #ifndef HAVE_DEV_DLPI 362 char dname2[100]; 363 #endif 364 int status = PCAP_ERROR; 365 366 #ifdef HAVE_DEV_DLPI 367 /* 368 ** Remove any "/dev/" on the front of the device. 369 */ 370 cp = strrchr(p->opt.source, '/'); 371 if (cp == NULL) 372 strlcpy(dname, p->opt.source, sizeof(dname)); 373 else 374 strlcpy(dname, cp + 1, sizeof(dname)); 375 376 /* 377 * Split the device name into a device type name and a unit number; 378 * chop off the unit number, so "dname" is just a device type name. 379 */ 380 cp = split_dname(dname, &ppa, p->errbuf); 381 if (cp == NULL) { 382 status = PCAP_ERROR_NO_SUCH_DEVICE; 383 goto bad; 384 } 385 *cp = '\0'; 386 387 /* 388 * Use "/dev/dlpi" as the device. 389 * 390 * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that 391 * the "dl_mjr_num" field is for the "major number of interface 392 * driver"; that's the major of "/dev/dlpi" on the system on 393 * which I tried this, but there may be DLPI devices that 394 * use a different driver, in which case we may need to 395 * search "/dev" for the appropriate device with that major 396 * device number, rather than hardwiring "/dev/dlpi". 397 */ 398 cp = "/dev/dlpi"; 399 if ((p->fd = open(cp, O_RDWR)) < 0) { 400 if (errno == EPERM || errno == EACCES) 401 status = PCAP_ERROR_PERM_DENIED; 402 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 403 "%s: %s", cp, pcap_strerror(errno)); 404 goto bad; 405 } 406 407 #ifdef DL_HP_RAWDLS 408 /* 409 * XXX - HP-UX 10.20 and 11.xx don't appear to support sending and 410 * receiving packets on the same descriptor - you need separate 411 * descriptors for sending and receiving, bound to different SAPs. 412 * 413 * If the open fails, we just leave -1 in "pd->send_fd" and reject 414 * attempts to send packets, just as if, in pcap-bpf.c, we fail 415 * to open the BPF device for reading and writing, we just try 416 * to open it for reading only and, if that succeeds, just let 417 * the send attempts fail. 418 */ 419 pd->send_fd = open(cp, O_RDWR); 420 #endif 421 422 /* 423 * Get a table of all PPAs for that device, and search that 424 * table for the specified device type name and unit number. 425 */ 426 ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf); 427 if (ppa < 0) { 428 status = ppa; 429 goto bad; 430 } 431 #else 432 /* 433 * If the device name begins with "/", assume it begins with 434 * the pathname of the directory containing the device to open; 435 * otherwise, concatenate the device directory name and the 436 * device name. 437 */ 438 if (*p->opt.source == '/') 439 strlcpy(dname, p->opt.source, sizeof(dname)); 440 else 441 snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, 442 p->opt.source); 443 444 /* 445 * Get the unit number, and a pointer to the end of the device 446 * type name. 447 */ 448 cp = split_dname(dname, &ppa, p->errbuf); 449 if (cp == NULL) { 450 status = PCAP_ERROR_NO_SUCH_DEVICE; 451 goto bad; 452 } 453 454 /* 455 * Make a copy of the device pathname, and then remove the unit 456 * number from the device pathname. 457 */ 458 strlcpy(dname2, dname, sizeof(dname)); 459 *cp = '\0'; 460 461 /* Try device without unit number */ 462 if ((p->fd = open(dname, O_RDWR)) < 0) { 463 if (errno != ENOENT) { 464 if (errno == EPERM || errno == EACCES) 465 status = PCAP_ERROR_PERM_DENIED; 466 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname, 467 pcap_strerror(errno)); 468 goto bad; 469 } 470 471 /* Try again with unit number */ 472 if ((p->fd = open(dname2, O_RDWR)) < 0) { 473 if (errno == ENOENT) { 474 status = PCAP_ERROR_NO_SUCH_DEVICE; 475 476 /* 477 * We provide an error message even 478 * for this error, for diagnostic 479 * purposes (so that, for example, 480 * the app can show the message if the 481 * user requests it). 482 * 483 * In it, we just report "No DLPI device 484 * found" with the device name, so people 485 * don't get confused and think, for example, 486 * that if they can't capture on "lo0" 487 * on Solaris the fix is to change libpcap 488 * (or the application that uses it) to 489 * look for something other than "/dev/lo0", 490 * as the fix is to look for an operating 491 * system other than Solaris - you just 492 * *can't* capture on a loopback interface 493 * on Solaris, the lack of a DLPI device 494 * for the loopback interface is just a 495 * symptom of that inability. 496 */ 497 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 498 "%s: No DLPI device found", p->opt.source); 499 } else { 500 if (errno == EPERM || errno == EACCES) 501 status = PCAP_ERROR_PERM_DENIED; 502 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", 503 dname2, pcap_strerror(errno)); 504 } 505 goto bad; 506 } 507 /* XXX Assume unit zero */ 508 ppa = 0; 509 } 510 #endif 511 512 /* 513 ** Attach if "style 2" provider 514 */ 515 if (dlinforeq(p->fd, p->errbuf) < 0 || 516 dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) 517 goto bad; 518 infop = &(MAKE_DL_PRIMITIVES(buf))->info_ack; 519 #ifdef HAVE_SOLARIS 520 if (infop->dl_mac_type == DL_IPATM) 521 isatm = 1; 522 #endif 523 if (infop->dl_provider_style == DL_STYLE2) { 524 status = dl_doattach(p->fd, ppa, p->errbuf); 525 if (status < 0) 526 goto bad; 527 #ifdef DL_HP_RAWDLS 528 if (pd->send_fd >= 0) { 529 if (dl_doattach(pd->send_fd, ppa, p->errbuf) < 0) 530 goto bad; 531 } 532 #endif 533 } 534 535 if (p->opt.rfmon) { 536 /* 537 * This device exists, but we don't support monitor mode 538 * any platforms that support DLPI. 539 */ 540 status = PCAP_ERROR_RFMON_NOTSUP; 541 goto bad; 542 } 543 544 #ifdef HAVE_DLPI_PASSIVE 545 /* 546 * Enable Passive mode to be able to capture on aggregated link. 547 * Not supported in all Solaris versions. 548 */ 549 dlpassive(p->fd, p->errbuf); 550 #endif 551 /* 552 ** Bind (defer if using HP-UX 9 or HP-UX 10.20 or later, totally 553 ** skip if using SINIX) 554 */ 555 #if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20_OR_LATER) && !defined(sinix) 556 #ifdef _AIX 557 /* 558 ** AIX. 559 ** According to IBM's AIX Support Line, the dl_sap value 560 ** should not be less than 0x600 (1536) for standard Ethernet. 561 ** However, we seem to get DL_BADADDR - "DLSAP addr in improper 562 ** format or invalid" - errors if we use 1537 on the "tr0" 563 ** device, which, given that its name starts with "tr" and that 564 ** it's IBM, probably means a Token Ring device. (Perhaps we 565 ** need to use 1537 on "/dev/dlpi/en" because that device is for 566 ** D/I/X Ethernet, the "SAP" is actually an Ethernet type, and 567 ** it rejects invalid Ethernet types.) 568 ** 569 ** So if 1537 fails, we try 2, as Hyung Sik Yoon of IBM Korea 570 ** says that works on Token Ring (he says that 0 does *not* 571 ** work; perhaps that's considered an invalid LLC SAP value - I 572 ** assume the SAP value in a DLPI bind is an LLC SAP for network 573 ** types that use 802.2 LLC). 574 */ 575 if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 && 576 dlbindreq(p->fd, 2, p->errbuf) < 0) || 577 dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) 578 goto bad; 579 #elif defined(DL_HP_RAWDLS) 580 /* 581 ** HP-UX 10.0x and 10.1x. 582 */ 583 if (dl_dohpuxbind(p->fd, p->errbuf) < 0) 584 goto bad; 585 if (pd->send_fd >= 0) { 586 /* 587 ** XXX - if this fails, just close send_fd and 588 ** set it to -1, so that you can't send but can 589 ** still receive? 590 */ 591 if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0) 592 goto bad; 593 } 594 #else /* neither AIX nor HP-UX */ 595 /* 596 ** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other 597 ** OS using DLPI. 598 **/ 599 if (dlbindreq(p->fd, 0, p->errbuf) < 0 || 600 dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) 601 goto bad; 602 #endif /* AIX vs. HP-UX vs. other */ 603 #endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */ 604 605 #ifdef HAVE_SOLARIS 606 if (isatm) { 607 /* 608 ** Have to turn on some special ATM promiscuous mode 609 ** for SunATM. 610 ** Do *NOT* turn regular promiscuous mode on; it doesn't 611 ** help, and may break things. 612 */ 613 if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) { 614 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 615 "A_PROMISCON_REQ: %s", pcap_strerror(errno)); 616 goto bad; 617 } 618 } else 619 #endif 620 if (p->opt.promisc) { 621 /* 622 ** Enable promiscuous (not necessary on send FD) 623 */ 624 status = dlpromiscon(p, DL_PROMISC_PHYS); 625 if (status < 0) { 626 if (status == PCAP_ERROR_PERM_DENIED) 627 status = PCAP_ERROR_PROMISC_PERM_DENIED; 628 goto bad; 629 } 630 631 /* 632 ** Try to enable multicast (you would have thought 633 ** promiscuous would be sufficient). (Skip if using 634 ** HP-UX or SINIX) (Not necessary on send FD) 635 */ 636 #if !defined(__hpux) && !defined(sinix) 637 status = dlpromiscon(p, DL_PROMISC_MULTI); 638 if (status < 0) 639 status = PCAP_WARNING; 640 #endif 641 } 642 /* 643 ** Try to enable SAP promiscuity (when not in promiscuous mode 644 ** when using HP-UX, when not doing SunATM on Solaris, and never 645 ** under SINIX) (Not necessary on send FD) 646 */ 647 #ifndef sinix 648 #if defined(__hpux) 649 /* HP-UX - only do this when not in promiscuous mode */ 650 if (!p->opt.promisc) { 651 #elif defined(HAVE_SOLARIS) 652 /* Solaris - don't do this on SunATM devices */ 653 if (!isatm) { 654 #else 655 /* Everything else (except for SINIX) - always do this */ 656 { 657 #endif 658 status = dlpromiscon(p, DL_PROMISC_SAP); 659 if (status < 0) { 660 /* 661 * Not fatal, since the DL_PROMISC_PHYS mode worked. 662 * Report it as a warning, however. 663 */ 664 if (p->opt.promisc) 665 status = PCAP_WARNING; 666 else 667 goto bad; 668 } 669 } 670 #endif /* sinix */ 671 672 /* 673 ** HP-UX 9, and HP-UX 10.20 or later, must bind after setting 674 ** promiscuous options. 675 */ 676 #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER) 677 if (dl_dohpuxbind(p->fd, p->errbuf) < 0) 678 goto bad; 679 /* 680 ** We don't set promiscuous mode on the send FD, but we'll defer 681 ** binding it anyway, just to keep the HP-UX 9/10.20 or later 682 ** code together. 683 */ 684 if (pd->send_fd >= 0) { 685 /* 686 ** XXX - if this fails, just close send_fd and 687 ** set it to -1, so that you can't send but can 688 ** still receive? 689 */ 690 if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0) 691 goto bad; 692 } 693 #endif 694 695 /* 696 ** Determine link type 697 ** XXX - get SAP length and address length as well, for use 698 ** when sending packets. 699 */ 700 if (dlinforeq(p->fd, p->errbuf) < 0 || 701 dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) 702 goto bad; 703 704 infop = &(MAKE_DL_PRIMITIVES(buf))->info_ack; 705 if (pcap_process_mactype(p, infop->dl_mac_type) != 0) 706 goto bad; 707 708 #ifdef DLIOCRAW 709 /* 710 ** This is a non standard SunOS hack to get the full raw link-layer 711 ** header. 712 */ 713 if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { 714 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s", 715 pcap_strerror(errno)); 716 goto bad; 717 } 718 #endif 719 720 #ifdef HAVE_SYS_BUFMOD_H 721 ss = p->snapshot; 722 723 /* 724 ** There is a bug in bufmod(7). When dealing with messages of 725 ** less than snaplen size it strips data from the beginning not 726 ** the end. 727 ** 728 ** This bug is fixed in 5.3.2. Also, there is a patch available. 729 ** Ask for bugid 1149065. 730 */ 731 #ifdef HAVE_SOLARIS 732 release = get_release(&osmajor, &osminor, &osmicro); 733 if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && 734 getenv("BUFMOD_FIXED") == NULL) { 735 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 736 "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.", 737 release); 738 ss = 0; 739 status = PCAP_WARNING; 740 } 741 #endif 742 743 /* Push and configure bufmod. */ 744 if (pcap_conf_bufmod(p, ss) != 0) 745 goto bad; 746 #endif 747 748 /* 749 ** As the last operation flush the read side. 750 */ 751 if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { 752 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", 753 pcap_strerror(errno)); 754 goto bad; 755 } 756 757 /* Allocate data buffer. */ 758 if (pcap_alloc_databuf(p) != 0) 759 goto bad; 760 761 /* Success - but perhaps with a warning */ 762 if (status < 0) 763 status = 0; 764 765 /* 766 * "p->fd" is an FD for a STREAMS device, so "select()" and 767 * "poll()" should work on it. 768 */ 769 p->selectable_fd = p->fd; 770 771 p->read_op = pcap_read_dlpi; 772 p->inject_op = pcap_inject_dlpi; 773 p->setfilter_op = install_bpf_program; /* no kernel filtering */ 774 p->setdirection_op = NULL; /* Not implemented.*/ 775 p->set_datalink_op = NULL; /* can't change data link type */ 776 p->getnonblock_op = pcap_getnonblock_fd; 777 p->setnonblock_op = pcap_setnonblock_fd; 778 p->stats_op = pcap_stats_dlpi; 779 p->cleanup_op = pcap_cleanup_dlpi; 780 781 return (status); 782 bad: 783 pcap_cleanup_dlpi(p); 784 return (status); 785 } 786 787 /* 788 * Split a device name into a device type name and a unit number; 789 * return the a pointer to the beginning of the unit number, which 790 * is the end of the device type name, and set "*unitp" to the unit 791 * number. 792 * 793 * Returns NULL on error, and fills "ebuf" with an error message. 794 */ 795 static char * 796 split_dname(char *device, int *unitp, char *ebuf) 797 { 798 char *cp; 799 char *eos; 800 long unit; 801 802 /* 803 * Look for a number at the end of the device name string. 804 */ 805 cp = device + strlen(device) - 1; 806 if (*cp < '0' || *cp > '9') { 807 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", 808 device); 809 return (NULL); 810 } 811 812 /* Digits at end of string are unit number */ 813 while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9') 814 cp--; 815 816 errno = 0; 817 unit = strtol(cp, &eos, 10); 818 if (*eos != '\0') { 819 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); 820 return (NULL); 821 } 822 if (errno == ERANGE || unit > INT_MAX) { 823 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large", 824 device); 825 return (NULL); 826 } 827 if (unit < 0) { 828 snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative", 829 device); 830 return (NULL); 831 } 832 *unitp = (int)unit; 833 return (cp); 834 } 835 836 static int 837 dl_doattach(int fd, int ppa, char *ebuf) 838 { 839 dl_attach_req_t req; 840 bpf_u_int32 buf[MAXDLBUF]; 841 int err; 842 843 req.dl_primitive = DL_ATTACH_REQ; 844 req.dl_ppa = ppa; 845 if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0) 846 return (PCAP_ERROR); 847 848 err = dlokack(fd, "attach", (char *)buf, ebuf); 849 if (err < 0) 850 return (err); 851 return (0); 852 } 853 854 #ifdef DL_HP_RAWDLS 855 static int 856 dl_dohpuxbind(int fd, char *ebuf) 857 { 858 int hpsap; 859 int uerror; 860 bpf_u_int32 buf[MAXDLBUF]; 861 862 /* 863 * XXX - we start at 22 because we used to use only 22, but 864 * that was just because that was the value used in some 865 * sample code from HP. With what value *should* we start? 866 * Does it matter, given that we're enabling SAP promiscuity 867 * on the input FD? 868 */ 869 hpsap = 22; 870 for (;;) { 871 if (dlbindreq(fd, hpsap, ebuf) < 0) 872 return (-1); 873 if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0) 874 break; 875 /* 876 * For any error other than a UNIX EBUSY, give up. 877 */ 878 if (uerror != EBUSY) { 879 /* 880 * dlbindack() has already filled in ebuf for 881 * this error. 882 */ 883 return (-1); 884 } 885 886 /* 887 * For EBUSY, try the next SAP value; that means that 888 * somebody else is using that SAP. Clear ebuf so 889 * that application doesn't report the "Device busy" 890 * error as a warning. 891 */ 892 *ebuf = '\0'; 893 hpsap++; 894 if (hpsap > 100) { 895 strlcpy(ebuf, 896 "All SAPs from 22 through 100 are in use", 897 PCAP_ERRBUF_SIZE); 898 return (-1); 899 } 900 } 901 return (0); 902 } 903 #endif 904 905 #define STRINGIFY(n) #n 906 907 static int 908 dlpromiscon(pcap_t *p, bpf_u_int32 level) 909 { 910 dl_promiscon_req_t req; 911 bpf_u_int32 buf[MAXDLBUF]; 912 int err; 913 914 req.dl_primitive = DL_PROMISCON_REQ; 915 req.dl_level = level; 916 if (send_request(p->fd, (char *)&req, sizeof(req), "promiscon", 917 p->errbuf) < 0) 918 return (PCAP_ERROR); 919 err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf, 920 p->errbuf); 921 if (err < 0) 922 return (err); 923 return (0); 924 } 925 926 int 927 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 928 { 929 #ifdef HAVE_SOLARIS 930 int fd; 931 union { 932 u_int nunits; 933 char pad[516]; /* XXX - must be at least 513; is 516 934 in "atmgetunits" */ 935 } buf; 936 char baname[2+1+1]; 937 u_int i; 938 939 /* 940 * We may have to do special magic to get ATM devices. 941 */ 942 if ((fd = open("/dev/ba", O_RDWR)) < 0) { 943 /* 944 * We couldn't open the "ba" device. 945 * For now, just give up; perhaps we should 946 * return an error if the problem is neither 947 * a "that device doesn't exist" error (ENOENT, 948 * ENXIO, etc.) or a "you're not allowed to do 949 * that" error (EPERM, EACCES). 950 */ 951 return (0); 952 } 953 954 if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) { 955 snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s", 956 pcap_strerror(errno)); 957 return (-1); 958 } 959 for (i = 0; i < buf.nunits; i++) { 960 snprintf(baname, sizeof baname, "ba%u", i); 961 if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0) 962 return (-1); 963 } 964 #endif 965 966 return (0); 967 } 968 969 static int 970 send_request(int fd, char *ptr, int len, char *what, char *ebuf) 971 { 972 struct strbuf ctl; 973 int flags; 974 975 ctl.maxlen = 0; 976 ctl.len = len; 977 ctl.buf = ptr; 978 979 flags = 0; 980 if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { 981 snprintf(ebuf, PCAP_ERRBUF_SIZE, 982 "send_request: putmsg \"%s\": %s", 983 what, pcap_strerror(errno)); 984 return (-1); 985 } 986 return (0); 987 } 988 989 static int 990 recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror) 991 { 992 union DL_primitives *dlp; 993 struct strbuf ctl; 994 int flags; 995 996 /* 997 * Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR, 998 * making that the only place where EBUSY is treated specially. 999 */ 1000 if (uerror != NULL) 1001 *uerror = 0; 1002 1003 ctl.maxlen = MAXDLBUF; 1004 ctl.len = 0; 1005 ctl.buf = bufp; 1006 1007 flags = 0; 1008 if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { 1009 snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s", 1010 what, pcap_strerror(errno)); 1011 return (PCAP_ERROR); 1012 } 1013 1014 dlp = MAKE_DL_PRIMITIVES(ctl.buf); 1015 switch (dlp->dl_primitive) { 1016 1017 case DL_INFO_ACK: 1018 case DL_BIND_ACK: 1019 case DL_OK_ACK: 1020 #ifdef DL_HP_PPA_ACK 1021 case DL_HP_PPA_ACK: 1022 #endif 1023 /* These are OK */ 1024 break; 1025 1026 case DL_ERROR_ACK: 1027 switch (dlp->error_ack.dl_errno) { 1028 1029 case DL_SYSERR: 1030 if (uerror != NULL) 1031 *uerror = dlp->error_ack.dl_unix_errno; 1032 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1033 "recv_ack: %s: UNIX error - %s", 1034 what, pcap_strerror(dlp->error_ack.dl_unix_errno)); 1035 if (dlp->error_ack.dl_unix_errno == EPERM || 1036 dlp->error_ack.dl_unix_errno == EACCES) 1037 return (PCAP_ERROR_PERM_DENIED); 1038 break; 1039 1040 default: 1041 snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s", 1042 what, dlstrerror(dlp->error_ack.dl_errno)); 1043 if (dlp->error_ack.dl_errno == DL_BADPPA) 1044 return (PCAP_ERROR_NO_SUCH_DEVICE); 1045 else if (dlp->error_ack.dl_errno == DL_ACCESS) 1046 return (PCAP_ERROR_PERM_DENIED); 1047 break; 1048 } 1049 return (PCAP_ERROR); 1050 1051 default: 1052 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1053 "recv_ack: %s: Unexpected primitive ack %s", 1054 what, dlprim(dlp->dl_primitive)); 1055 return (PCAP_ERROR); 1056 } 1057 1058 if (ctl.len < size) { 1059 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1060 "recv_ack: %s: Ack too small (%d < %d)", 1061 what, ctl.len, size); 1062 return (PCAP_ERROR); 1063 } 1064 return (ctl.len); 1065 } 1066 1067 static char * 1068 dlstrerror(bpf_u_int32 dl_errno) 1069 { 1070 static char errstring[6+2+8+1]; 1071 1072 switch (dl_errno) { 1073 1074 case DL_ACCESS: 1075 return ("Improper permissions for request"); 1076 1077 case DL_BADADDR: 1078 return ("DLSAP addr in improper format or invalid"); 1079 1080 case DL_BADCORR: 1081 return ("Seq number not from outstand DL_CONN_IND"); 1082 1083 case DL_BADDATA: 1084 return ("User data exceeded provider limit"); 1085 1086 case DL_BADPPA: 1087 #ifdef HAVE_DEV_DLPI 1088 /* 1089 * With a single "/dev/dlpi" device used for all 1090 * DLPI providers, PPAs have nothing to do with 1091 * unit numbers. 1092 */ 1093 return ("Specified PPA was invalid"); 1094 #else 1095 /* 1096 * We have separate devices for separate devices; 1097 * the PPA is just the unit number. 1098 */ 1099 return ("Specified PPA (device unit) was invalid"); 1100 #endif 1101 1102 case DL_BADPRIM: 1103 return ("Primitive received not known by provider"); 1104 1105 case DL_BADQOSPARAM: 1106 return ("QOS parameters contained invalid values"); 1107 1108 case DL_BADQOSTYPE: 1109 return ("QOS structure type is unknown/unsupported"); 1110 1111 case DL_BADSAP: 1112 return ("Bad LSAP selector"); 1113 1114 case DL_BADTOKEN: 1115 return ("Token used not an active stream"); 1116 1117 case DL_BOUND: 1118 return ("Attempted second bind with dl_max_conind"); 1119 1120 case DL_INITFAILED: 1121 return ("Physical link initialization failed"); 1122 1123 case DL_NOADDR: 1124 return ("Provider couldn't allocate alternate address"); 1125 1126 case DL_NOTINIT: 1127 return ("Physical link not initialized"); 1128 1129 case DL_OUTSTATE: 1130 return ("Primitive issued in improper state"); 1131 1132 case DL_SYSERR: 1133 return ("UNIX system error occurred"); 1134 1135 case DL_UNSUPPORTED: 1136 return ("Requested service not supplied by provider"); 1137 1138 case DL_UNDELIVERABLE: 1139 return ("Previous data unit could not be delivered"); 1140 1141 case DL_NOTSUPPORTED: 1142 return ("Primitive is known but not supported"); 1143 1144 case DL_TOOMANY: 1145 return ("Limit exceeded"); 1146 1147 case DL_NOTENAB: 1148 return ("Promiscuous mode not enabled"); 1149 1150 case DL_BUSY: 1151 return ("Other streams for PPA in post-attached"); 1152 1153 case DL_NOAUTO: 1154 return ("Automatic handling XID&TEST not supported"); 1155 1156 case DL_NOXIDAUTO: 1157 return ("Automatic handling of XID not supported"); 1158 1159 case DL_NOTESTAUTO: 1160 return ("Automatic handling of TEST not supported"); 1161 1162 case DL_XIDAUTO: 1163 return ("Automatic handling of XID response"); 1164 1165 case DL_TESTAUTO: 1166 return ("Automatic handling of TEST response"); 1167 1168 case DL_PENDING: 1169 return ("Pending outstanding connect indications"); 1170 1171 default: 1172 sprintf(errstring, "Error %02x", dl_errno); 1173 return (errstring); 1174 } 1175 } 1176 1177 static char * 1178 dlprim(bpf_u_int32 prim) 1179 { 1180 static char primbuf[80]; 1181 1182 switch (prim) { 1183 1184 case DL_INFO_REQ: 1185 return ("DL_INFO_REQ"); 1186 1187 case DL_INFO_ACK: 1188 return ("DL_INFO_ACK"); 1189 1190 case DL_ATTACH_REQ: 1191 return ("DL_ATTACH_REQ"); 1192 1193 case DL_DETACH_REQ: 1194 return ("DL_DETACH_REQ"); 1195 1196 case DL_BIND_REQ: 1197 return ("DL_BIND_REQ"); 1198 1199 case DL_BIND_ACK: 1200 return ("DL_BIND_ACK"); 1201 1202 case DL_UNBIND_REQ: 1203 return ("DL_UNBIND_REQ"); 1204 1205 case DL_OK_ACK: 1206 return ("DL_OK_ACK"); 1207 1208 case DL_ERROR_ACK: 1209 return ("DL_ERROR_ACK"); 1210 1211 case DL_SUBS_BIND_REQ: 1212 return ("DL_SUBS_BIND_REQ"); 1213 1214 case DL_SUBS_BIND_ACK: 1215 return ("DL_SUBS_BIND_ACK"); 1216 1217 case DL_UNITDATA_REQ: 1218 return ("DL_UNITDATA_REQ"); 1219 1220 case DL_UNITDATA_IND: 1221 return ("DL_UNITDATA_IND"); 1222 1223 case DL_UDERROR_IND: 1224 return ("DL_UDERROR_IND"); 1225 1226 case DL_UDQOS_REQ: 1227 return ("DL_UDQOS_REQ"); 1228 1229 case DL_CONNECT_REQ: 1230 return ("DL_CONNECT_REQ"); 1231 1232 case DL_CONNECT_IND: 1233 return ("DL_CONNECT_IND"); 1234 1235 case DL_CONNECT_RES: 1236 return ("DL_CONNECT_RES"); 1237 1238 case DL_CONNECT_CON: 1239 return ("DL_CONNECT_CON"); 1240 1241 case DL_TOKEN_REQ: 1242 return ("DL_TOKEN_REQ"); 1243 1244 case DL_TOKEN_ACK: 1245 return ("DL_TOKEN_ACK"); 1246 1247 case DL_DISCONNECT_REQ: 1248 return ("DL_DISCONNECT_REQ"); 1249 1250 case DL_DISCONNECT_IND: 1251 return ("DL_DISCONNECT_IND"); 1252 1253 case DL_RESET_REQ: 1254 return ("DL_RESET_REQ"); 1255 1256 case DL_RESET_IND: 1257 return ("DL_RESET_IND"); 1258 1259 case DL_RESET_RES: 1260 return ("DL_RESET_RES"); 1261 1262 case DL_RESET_CON: 1263 return ("DL_RESET_CON"); 1264 1265 default: 1266 (void) sprintf(primbuf, "unknown primitive 0x%x", prim); 1267 return (primbuf); 1268 } 1269 } 1270 1271 static int 1272 dlbindreq(int fd, bpf_u_int32 sap, char *ebuf) 1273 { 1274 1275 dl_bind_req_t req; 1276 1277 memset((char *)&req, 0, sizeof(req)); 1278 req.dl_primitive = DL_BIND_REQ; 1279 /* XXX - what if neither of these are defined? */ 1280 #if defined(DL_HP_RAWDLS) 1281 req.dl_max_conind = 1; /* XXX magic number */ 1282 req.dl_service_mode = DL_HP_RAWDLS; 1283 #elif defined(DL_CLDLS) 1284 req.dl_service_mode = DL_CLDLS; 1285 #endif 1286 req.dl_sap = sap; 1287 1288 return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf)); 1289 } 1290 1291 static int 1292 dlbindack(int fd, char *bufp, char *ebuf, int *uerror) 1293 { 1294 1295 return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror)); 1296 } 1297 1298 static int 1299 dlokack(int fd, const char *what, char *bufp, char *ebuf) 1300 { 1301 1302 return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL)); 1303 } 1304 1305 1306 static int 1307 dlinforeq(int fd, char *ebuf) 1308 { 1309 dl_info_req_t req; 1310 1311 req.dl_primitive = DL_INFO_REQ; 1312 1313 return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf)); 1314 } 1315 1316 static int 1317 dlinfoack(int fd, char *bufp, char *ebuf) 1318 { 1319 1320 return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL)); 1321 } 1322 1323 #ifdef HAVE_DLPI_PASSIVE 1324 /* 1325 * Enable DLPI passive mode. We do not care if this request fails, as this 1326 * indicates the underlying DLPI device does not support link aggregation. 1327 */ 1328 static void 1329 dlpassive(int fd, char *ebuf) 1330 { 1331 dl_passive_req_t req; 1332 bpf_u_int32 buf[MAXDLBUF]; 1333 1334 req.dl_primitive = DL_PASSIVE_REQ; 1335 1336 if (send_request(fd, (char *)&req, sizeof(req), "dlpassive", ebuf) == 0) 1337 (void) dlokack(fd, "dlpassive", (char *)buf, ebuf); 1338 } 1339 #endif 1340 1341 #ifdef DL_HP_RAWDLS 1342 /* 1343 * There's an ack *if* there's an error. 1344 */ 1345 static int 1346 dlrawdatareq(int fd, const u_char *datap, int datalen) 1347 { 1348 struct strbuf ctl, data; 1349 long buf[MAXDLBUF]; /* XXX - char? */ 1350 union DL_primitives *dlp; 1351 int dlen; 1352 1353 dlp = MAKE_DL_PRIMITIVES(buf); 1354 1355 dlp->dl_primitive = DL_HP_RAWDATA_REQ; 1356 dlen = DL_HP_RAWDATA_REQ_SIZE; 1357 1358 /* 1359 * HP's documentation doesn't appear to show us supplying any 1360 * address pointed to by the control part of the message. 1361 * I think that's what raw mode means - you just send the raw 1362 * packet, you don't specify where to send it to, as that's 1363 * implied by the destination address. 1364 */ 1365 ctl.maxlen = 0; 1366 ctl.len = dlen; 1367 ctl.buf = (void *)buf; 1368 1369 data.maxlen = 0; 1370 data.len = datalen; 1371 data.buf = (void *)datap; 1372 1373 return (putmsg(fd, &ctl, &data, 0)); 1374 } 1375 #endif /* DL_HP_RAWDLS */ 1376 1377 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 1378 static char * 1379 get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp) 1380 { 1381 char *cp; 1382 static char buf[32]; 1383 1384 *majorp = 0; 1385 *minorp = 0; 1386 *microp = 0; 1387 if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0) 1388 return ("?"); 1389 cp = buf; 1390 if (!isdigit((unsigned char)*cp)) 1391 return (buf); 1392 *majorp = strtol(cp, &cp, 10); 1393 if (*cp++ != '.') 1394 return (buf); 1395 *minorp = strtol(cp, &cp, 10); 1396 if (*cp++ != '.') 1397 return (buf); 1398 *microp = strtol(cp, &cp, 10); 1399 return (buf); 1400 } 1401 #endif 1402 1403 #ifdef DL_HP_PPA_REQ 1404 /* 1405 * Under HP-UX 10 and HP-UX 11, we can ask for the ppa 1406 */ 1407 1408 1409 /* 1410 * Determine ppa number that specifies ifname. 1411 * 1412 * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, 1413 * the code that's used here is the old code for HP-UX 10.x. 1414 * 1415 * However, HP-UX 10.20, at least, appears to have such a member 1416 * in its "dl_hp_ppa_info_t" structure, so the new code is used. 1417 * The new code didn't work on an old 10.20 system on which Rick 1418 * Jones of HP tried it, but with later patches installed, it 1419 * worked - it appears that the older system had those members but 1420 * didn't put anything in them, so, if the search by name fails, we 1421 * do the old search. 1422 * 1423 * Rick suggests that making sure your system is "up on the latest 1424 * lancommon/DLPI/driver patches" is probably a good idea; it'd fix 1425 * that problem, as well as allowing libpcap to see packets sent 1426 * from the system on which the libpcap application is being run. 1427 * (On 10.20, in addition to getting the latest patches, you need 1428 * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; 1429 * a posting to "comp.sys.hp.hpux" at 1430 * 1431 * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 1432 * 1433 * says that, to see the machine's outgoing traffic, you'd need to 1434 * apply the right patches to your system, and also set that variable 1435 * with: 1436 1437 echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem 1438 1439 * which could be put in, for example, "/sbin/init.d/lan". 1440 * 1441 * Setting the variable is not necessary on HP-UX 11.x. 1442 */ 1443 static int 1444 get_dlpi_ppa(register int fd, register const char *device, register int unit, 1445 register char *ebuf) 1446 { 1447 register dl_hp_ppa_ack_t *ap; 1448 register dl_hp_ppa_info_t *ipstart, *ip; 1449 register int i; 1450 char dname[100]; 1451 register u_long majdev; 1452 struct stat statbuf; 1453 dl_hp_ppa_req_t req; 1454 char buf[MAXDLBUF]; 1455 char *ppa_data_buf; 1456 dl_hp_ppa_ack_t *dlp; 1457 struct strbuf ctl; 1458 int flags; 1459 int ppa; 1460 1461 memset((char *)&req, 0, sizeof(req)); 1462 req.dl_primitive = DL_HP_PPA_REQ; 1463 1464 memset((char *)buf, 0, sizeof(buf)); 1465 if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0) 1466 return (PCAP_ERROR); 1467 1468 ctl.maxlen = DL_HP_PPA_ACK_SIZE; 1469 ctl.len = 0; 1470 ctl.buf = (char *)buf; 1471 1472 flags = 0; 1473 /* 1474 * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal 1475 * recv_ack will fail because it set the maxlen to MAXDLBUF (8192) 1476 * which is NOT big enough for a DL_HP_PPA_REQ. 1477 * 1478 * This causes libpcap applications to fail on a system with HP-APA 1479 * installed. 1480 * 1481 * To figure out how big the returned data is, we first call getmsg 1482 * to get the small head and peek at the head to get the actual data 1483 * length, and then issue another getmsg to get the actual PPA data. 1484 */ 1485 /* get the head first */ 1486 if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { 1487 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1488 "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); 1489 return (PCAP_ERROR); 1490 } 1491 1492 dlp = (dl_hp_ppa_ack_t *)ctl.buf; 1493 if (dlp->dl_primitive != DL_HP_PPA_ACK) { 1494 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1495 "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x", 1496 (bpf_u_int32)dlp->dl_primitive); 1497 return (PCAP_ERROR); 1498 } 1499 1500 if (ctl.len < DL_HP_PPA_ACK_SIZE) { 1501 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1502 "get_dlpi_ppa: hpppa ack too small (%d < %lu)", 1503 ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE); 1504 return (PCAP_ERROR); 1505 } 1506 1507 /* allocate buffer */ 1508 if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) { 1509 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1510 "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno)); 1511 return (PCAP_ERROR); 1512 } 1513 ctl.maxlen = dlp->dl_length; 1514 ctl.len = 0; 1515 ctl.buf = (char *)ppa_data_buf; 1516 /* get the data */ 1517 if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { 1518 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1519 "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); 1520 free(ppa_data_buf); 1521 return (PCAP_ERROR); 1522 } 1523 if (ctl.len < dlp->dl_length) { 1524 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1525 "get_dlpi_ppa: hpppa ack too small (%d < %lu)", 1526 ctl.len, (unsigned long)dlp->dl_length); 1527 free(ppa_data_buf); 1528 return (PCAP_ERROR); 1529 } 1530 1531 ap = (dl_hp_ppa_ack_t *)buf; 1532 ipstart = (dl_hp_ppa_info_t *)ppa_data_buf; 1533 ip = ipstart; 1534 1535 #ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1536 /* 1537 * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1" 1538 * member that should, in theory, contain the part of the 1539 * name for the device that comes before the unit number, 1540 * and should also have a "dl_module_id_2" member that may 1541 * contain an alternate name (e.g., I think Ethernet devices 1542 * have both "lan", for "lanN", and "snap", for "snapN", with 1543 * the former being for Ethernet packets and the latter being 1544 * for 802.3/802.2 packets). 1545 * 1546 * Search for the device that has the specified name and 1547 * instance number. 1548 */ 1549 for (i = 0; i < ap->dl_count; i++) { 1550 if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 || 1551 strcmp((const char *)ip->dl_module_id_2, device) == 0) && 1552 ip->dl_instance_num == unit) 1553 break; 1554 1555 ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); 1556 } 1557 #else 1558 /* 1559 * We don't have that member, so the search is impossible; make it 1560 * look as if the search failed. 1561 */ 1562 i = ap->dl_count; 1563 #endif 1564 1565 if (i == ap->dl_count) { 1566 /* 1567 * Well, we didn't, or can't, find the device by name. 1568 * 1569 * HP-UX 10.20, whilst it has "dl_module_id_1" and 1570 * "dl_module_id_2" fields in the "dl_hp_ppa_info_t", 1571 * doesn't seem to fill them in unless the system is 1572 * at a reasonably up-to-date patch level. 1573 * 1574 * Older HP-UX 10.x systems might not have those fields 1575 * at all. 1576 * 1577 * Therefore, we'll search for the entry with the major 1578 * device number of a device with the name "/dev/<dev><unit>", 1579 * if such a device exists, as the old code did. 1580 */ 1581 snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit); 1582 if (stat(dname, &statbuf) < 0) { 1583 snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s", 1584 dname, pcap_strerror(errno)); 1585 return (PCAP_ERROR); 1586 } 1587 majdev = major(statbuf.st_rdev); 1588 1589 ip = ipstart; 1590 1591 for (i = 0; i < ap->dl_count; i++) { 1592 if (ip->dl_mjr_num == majdev && 1593 ip->dl_instance_num == unit) 1594 break; 1595 1596 ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); 1597 } 1598 } 1599 if (i == ap->dl_count) { 1600 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1601 "can't find /dev/dlpi PPA for %s%d", device, unit); 1602 return (PCAP_ERROR_NO_SUCH_DEVICE); 1603 } 1604 if (ip->dl_hdw_state == HDW_DEAD) { 1605 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1606 "%s%d: hardware state: DOWN\n", device, unit); 1607 free(ppa_data_buf); 1608 return (PCAP_ERROR); 1609 } 1610 ppa = ip->dl_ppa; 1611 free(ppa_data_buf); 1612 return (ppa); 1613 } 1614 #endif 1615 1616 #ifdef HAVE_HPUX9 1617 /* 1618 * Under HP-UX 9, there is no good way to determine the ppa. 1619 * So punt and read it from /dev/kmem. 1620 */ 1621 static struct nlist nl[] = { 1622 #define NL_IFNET 0 1623 { "ifnet" }, 1624 { "" } 1625 }; 1626 1627 static char path_vmunix[] = "/hp-ux"; 1628 1629 /* Determine ppa number that specifies ifname */ 1630 static int 1631 get_dlpi_ppa(register int fd, register const char *ifname, register int unit, 1632 register char *ebuf) 1633 { 1634 register const char *cp; 1635 register int kd; 1636 void *addr; 1637 struct ifnet ifnet; 1638 char if_name[sizeof(ifnet.if_name) + 1]; 1639 1640 cp = strrchr(ifname, '/'); 1641 if (cp != NULL) 1642 ifname = cp + 1; 1643 if (nlist(path_vmunix, &nl) < 0) { 1644 snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", 1645 path_vmunix); 1646 return (-1); 1647 } 1648 if (nl[NL_IFNET].n_value == 0) { 1649 snprintf(ebuf, PCAP_ERRBUF_SIZE, 1650 "could't find %s kernel symbol", 1651 nl[NL_IFNET].n_name); 1652 return (-1); 1653 } 1654 kd = open("/dev/kmem", O_RDONLY); 1655 if (kd < 0) { 1656 snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s", 1657 pcap_strerror(errno)); 1658 return (-1); 1659 } 1660 if (dlpi_kread(kd, nl[NL_IFNET].n_value, 1661 &addr, sizeof(addr), ebuf) < 0) { 1662 close(kd); 1663 return (-1); 1664 } 1665 for (; addr != NULL; addr = ifnet.if_next) { 1666 if (dlpi_kread(kd, (off_t)addr, 1667 &ifnet, sizeof(ifnet), ebuf) < 0 || 1668 dlpi_kread(kd, (off_t)ifnet.if_name, 1669 if_name, sizeof(ifnet.if_name), ebuf) < 0) { 1670 (void)close(kd); 1671 return (-1); 1672 } 1673 if_name[sizeof(ifnet.if_name)] = '\0'; 1674 if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) 1675 return (ifnet.if_index); 1676 } 1677 1678 snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); 1679 return (-1); 1680 } 1681 1682 static int 1683 dlpi_kread(register int fd, register off_t addr, 1684 register void *buf, register u_int len, register char *ebuf) 1685 { 1686 register int cc; 1687 1688 if (lseek(fd, addr, SEEK_SET) < 0) { 1689 snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s", 1690 pcap_strerror(errno)); 1691 return (-1); 1692 } 1693 cc = read(fd, buf, len); 1694 if (cc < 0) { 1695 snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s", 1696 pcap_strerror(errno)); 1697 return (-1); 1698 } else if (cc != len) { 1699 snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, 1700 len); 1701 return (-1); 1702 } 1703 return (cc); 1704 } 1705 #endif 1706 1707 pcap_t * 1708 pcap_create_interface(const char *device, char *ebuf) 1709 { 1710 pcap_t *p; 1711 #ifdef DL_HP_RAWDLS 1712 struct pcap_dlpi *pd; 1713 #endif 1714 1715 p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi)); 1716 if (p == NULL) 1717 return (NULL); 1718 1719 #ifdef DL_HP_RAWDLS 1720 pd = p->priv; 1721 pd->send_fd = -1; /* it hasn't been opened yet */ 1722 #endif 1723 1724 p->activate_op = pcap_activate_dlpi; 1725 return (p); 1726 } 1727