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