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