pcap-dlpi.c revision 356341
1139823Simp/* 2130407Sdfr * Copyright (c) 1993, 1994, 1995, 1996, 1997 3130407Sdfr * The Regents of the University of California. All rights reserved. 4130407Sdfr * 5130407Sdfr * Redistribution and use in source and binary forms, with or without 6130407Sdfr * modification, are permitted provided that: (1) source code distributions 7130407Sdfr * retain the above copyright notice and this paragraph in its entirety, (2) 8130407Sdfr * distributions including binary code include the above copyright notice and 9130407Sdfr * this paragraph in its entirety in the documentation or other materials 10130407Sdfr * provided with the distribution, and (3) all advertising materials mentioning 11130407Sdfr * features or use of this software display the following acknowledgement: 12130407Sdfr * ``This product includes software developed by the University of California, 13130407Sdfr * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14130407Sdfr * the University nor the names of its contributors may be used to endorse 15130407Sdfr * or promote products derived from this software without specific prior 16130407Sdfr * written permission. 17130407Sdfr * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18130407Sdfr * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19130407Sdfr * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20130407Sdfr * 21130407Sdfr * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), 22130407Sdfr * University College London, and subsequently modified by 23130407Sdfr * Guy Harris (guy@alum.mit.edu), Mark Pizzolato 24130407Sdfr * <List-tcpdump-workers@subscriptions.pizzolato.net>, 25130407Sdfr * Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>. 26130407Sdfr */ 27130407Sdfr 28130407Sdfr/* 29130407Sdfr * Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX. 30130407Sdfr * 31130407Sdfr * Notes: 32130407Sdfr * 33130407Sdfr * - The DLIOCRAW ioctl() is specific to SunOS. 34130407Sdfr * 35131177Spjd * - There is a bug in bufmod(7) such that setting the snapshot 36130407Sdfr * length results in data being left of the front of the packet. 37130407Sdfr * 38130407Sdfr * - It might be desirable to use pfmod(7) to filter packets in the 39130407Sdfr * kernel when possible. 40131177Spjd * 41130407Sdfr * - An older version of the HP-UX DLPI Programmer's Guide, which 42130407Sdfr * I think was advertised as the 10.20 version, used to be available 43147256Sbrooks * at 44130407Sdfr * 45130407Sdfr * http://docs.hp.com/hpux/onlinedocs/B2355-90093/B2355-90093.html 46130407Sdfr * 47130407Sdfr * but is no longer available; it can still be found at 48130407Sdfr * 49130407Sdfr * http://h21007.www2.hp.com/dspp/files/unprotected/Drivers/Docs/Refs/B2355-90093.pdf 50130407Sdfr * 51130407Sdfr * in PDF form. 52130407Sdfr * 53130407Sdfr * - The HP-UX 10.x, 11.0, and 11i v1.6 version of the HP-UX DLPI 54130407Sdfr * Programmer's Guide, which I think was once advertised as the 55130407Sdfr * 11.00 version is available at 56130407Sdfr * 57130407Sdfr * http://docs.hp.com/en/B2355-90139/index.html 58130407Sdfr * 59130407Sdfr * - The HP-UX 11i v2 version of the HP-UX DLPI Programmer's Guide 60130407Sdfr * is available at 61130407Sdfr * 62130407Sdfr * http://docs.hp.com/en/B2355-90871/index.html 63130407Sdfr * 64130407Sdfr * - All of the HP documents describe raw-mode services, which are 65130407Sdfr * what we use if DL_HP_RAWDLS is defined. XXX - we use __hpux 66130407Sdfr * in some places to test for HP-UX, but use DL_HP_RAWDLS in 67147256Sbrooks * other places; do we support any versions of HP-UX without 68147256Sbrooks * DL_HP_RAWDLS? 69130407Sdfr */ 70130407Sdfr 71130407Sdfr#ifdef HAVE_CONFIG_H 72130407Sdfr#include <config.h> 73130407Sdfr#endif 74130407Sdfr 75130407Sdfr#include <sys/types.h> 76130407Sdfr#include <sys/time.h> 77130407Sdfr#ifdef HAVE_SYS_BUFMOD_H 78130407Sdfr#include <sys/bufmod.h> 79130407Sdfr#endif 80130407Sdfr#include <sys/dlpi.h> 81130407Sdfr#ifdef HAVE_SYS_DLPI_EXT_H 82147256Sbrooks#include <sys/dlpi_ext.h> 83130407Sdfr#endif 84148954Sglebius#ifdef HAVE_HPUX9 85130407Sdfr#include <sys/socket.h> 86130407Sdfr#endif 87130407Sdfr#ifdef DL_HP_PPA_REQ 88130407Sdfr#include <sys/stat.h> 89130407Sdfr#endif 90130407Sdfr#include <sys/stream.h> 91130407Sdfr#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 92130407Sdfr#include <sys/systeminfo.h> 93130407Sdfr#endif 94130429Sdfr 95130429Sdfr#ifdef HAVE_HPUX9 96130429Sdfr#include <net/if.h> 97130429Sdfr#endif 98130429Sdfr 99130429Sdfr#include <ctype.h> 100148887Srwatson#ifdef HAVE_HPUX9 101148887Srwatson#include <nlist.h> 102130407Sdfr#endif 103130407Sdfr#include <errno.h> 104130407Sdfr#include <fcntl.h> 105130407Sdfr#include <memory.h> 106148954Sglebius#include <stdio.h> 107148954Sglebius#include <stdlib.h> 108148954Sglebius#include <string.h> 109148954Sglebius#include <stropts.h> 110148954Sglebius#include <unistd.h> 111148954Sglebius 112130407Sdfr#ifdef HAVE_LIMITS_H 113130407Sdfr#include <limits.h> 114130407Sdfr#else 115130407Sdfr#define INT_MAX 2147483647 116130407Sdfr#endif 117130407Sdfr 118130407Sdfr#include "pcap-int.h" 119130407Sdfr#include "dlpisubs.h" 120130407Sdfr 121130407Sdfr#ifdef HAVE_OS_PROTO_H 122130407Sdfr#include "os-proto.h" 123130407Sdfr#endif 124130407Sdfr 125130407Sdfr#if defined(__hpux) 126130407Sdfr /* 127130407Sdfr * HP-UX has a /dev/dlpi device; you open it and set the PPA of the actual 128130407Sdfr * network device you want. 129130407Sdfr */ 130130407Sdfr #define HAVE_DEV_DLPI 131130407Sdfr#elif defined(_AIX) 132130407Sdfr /* 133130407Sdfr * AIX has a /dev/dlpi directory, with devices named after the interfaces 134130407Sdfr * underneath it. 135130407Sdfr */ 136130407Sdfr #define PCAP_DEV_PREFIX "/dev/dlpi" 137130407Sdfr#elif defined(HAVE_SOLARIS) 138130407Sdfr /* 139130407Sdfr * Solaris has devices named after the interfaces underneath /dev. 140130407Sdfr */ 141130407Sdfr #define PCAP_DEV_PREFIX "/dev" 142130407Sdfr#endif 143130407Sdfr 144130407Sdfr#define MAXDLBUF 8192 145130407Sdfr 146130407Sdfr/* Forwards */ 147130407Sdfrstatic char *split_dname(char *, u_int *, char *); 148130407Sdfrstatic int dl_doattach(int, int, char *); 149130407Sdfr#ifdef DL_HP_RAWDLS 150130407Sdfrstatic int dl_dohpuxbind(int, char *); 151130407Sdfr#endif 152130407Sdfrstatic int dlpromiscon(pcap_t *, bpf_u_int32); 153130407Sdfrstatic int dlbindreq(int, bpf_u_int32, char *); 154130407Sdfrstatic int dlbindack(int, char *, char *, int *); 155130407Sdfrstatic int dlokack(int, const char *, char *, char *); 156130407Sdfrstatic int dlinforeq(int, char *); 157130407Sdfrstatic int dlinfoack(int, char *, char *); 158130407Sdfr 159130407Sdfr#ifdef HAVE_DL_PASSIVE_REQ_T 160130407Sdfrstatic void dlpassive(int, char *); 161130407Sdfr#endif 162130407Sdfr 163130407Sdfr#ifdef DL_HP_RAWDLS 164130407Sdfrstatic int dlrawdatareq(int, const u_char *, int); 165130407Sdfr#endif 166130407Sdfrstatic int recv_ack(int, int, const char *, char *, char *, int *); 167130407Sdfrstatic char *dlstrerror(char *, size_t, bpf_u_int32); 168130407Sdfrstatic char *dlprim(char *, size_t, bpf_u_int32); 169130407Sdfr#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 170130407Sdfr#define GET_RELEASE_BUFSIZE 32 171130407Sdfrstatic void get_release(char *, size_t, bpf_u_int32 *, bpf_u_int32 *, 172130407Sdfr bpf_u_int32 *); 173130407Sdfr#endif 174130407Sdfrstatic int send_request(int, char *, int, char *, char *); 175130407Sdfr#ifdef HAVE_HPUX9 176130407Sdfrstatic int dlpi_kread(int, off_t, void *, u_int, char *); 177147256Sbrooks#endif 178130407Sdfr#ifdef HAVE_DEV_DLPI 179130407Sdfrstatic int get_dlpi_ppa(int, const char *, u_int, u_int *, char *); 180130407Sdfr#endif 181130407Sdfr 182130407Sdfr/* 183130407Sdfr * Cast a buffer to "union DL_primitives" without provoking warnings 184130407Sdfr * from the compiler. 185130407Sdfr */ 186130407Sdfr#define MAKE_DL_PRIMITIVES(ptr) ((union DL_primitives *)(void *)(ptr)) 187130407Sdfr 188130407Sdfrstatic int 189130407Sdfrpcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 190130407Sdfr{ 191130407Sdfr int cc; 192130407Sdfr u_char *bp; 193130407Sdfr int flags; 194130407Sdfr bpf_u_int32 ctlbuf[MAXDLBUF]; 195130407Sdfr struct strbuf ctl = { 196130407Sdfr MAXDLBUF, 197130407Sdfr 0, 198130407Sdfr (char *)ctlbuf 199130407Sdfr }; 200130407Sdfr struct strbuf data; 201130407Sdfr 202130407Sdfr flags = 0; 203130407Sdfr cc = p->cc; 204130407Sdfr if (cc == 0) { 205130407Sdfr data.buf = (char *)p->buffer + p->offset; 206130407Sdfr data.maxlen = p->bufsize; 207130407Sdfr data.len = 0; 208130407Sdfr do { 209130407Sdfr /* 210130407Sdfr * Has "pcap_breakloop()" been called? 211130407Sdfr */ 212130407Sdfr if (p->break_loop) { 213130407Sdfr /* 214130407Sdfr * Yes - clear the flag that indicates 215130407Sdfr * that it has, and return -2 to 216130407Sdfr * indicate that we were told to 217130407Sdfr * break out of the loop. 218130407Sdfr */ 219130407Sdfr p->break_loop = 0; 220130407Sdfr return (-2); 221130407Sdfr } 222130407Sdfr /* 223130407Sdfr * XXX - check for the DLPI primitive, which 224130407Sdfr * would be DL_HP_RAWDATA_IND on HP-UX 225130407Sdfr * if we're in raw mode? 226130407Sdfr */ 227130407Sdfr ctl.buf = (char *)ctlbuf; 228130407Sdfr ctl.maxlen = MAXDLBUF; 229130407Sdfr ctl.len = 0; 230130407Sdfr if (getmsg(p->fd, &ctl, &data, &flags) < 0) { 231130407Sdfr /* Don't choke when we get ptraced */ 232130407Sdfr switch (errno) { 233130407Sdfr 234130407Sdfr case EINTR: 235130407Sdfr cc = 0; 236130407Sdfr continue; 237130407Sdfr 238130407Sdfr case EAGAIN: 239130407Sdfr return (0); 240130407Sdfr } 241130407Sdfr pcap_fmt_errmsg_for_errno(p->errbuf, 242130407Sdfr sizeof(p->errbuf), errno, "getmsg"); 243130407Sdfr return (-1); 244130407Sdfr } 245130407Sdfr cc = data.len; 246144114Sgallatin } while (cc == 0); 247130407Sdfr bp = (u_char *)p->buffer + p->offset; 248130407Sdfr } else 249130407Sdfr bp = p->bp; 250130407Sdfr 251130407Sdfr return (pcap_process_pkts(p, callback, user, cnt, bp, cc)); 252130407Sdfr} 253130549Smlaier 254130549Smlaierstatic int 255130407Sdfrpcap_inject_dlpi(pcap_t *p, const void *buf, size_t size) 256130407Sdfr{ 257130407Sdfr#ifdef DL_HP_RAWDLS 258130407Sdfr struct pcap_dlpi *pd = p->priv; 259130407Sdfr#endif 260130407Sdfr int ret; 261130407Sdfr 262130407Sdfr#if defined(DLIOCRAW) 263130407Sdfr ret = write(p->fd, buf, size); 264130407Sdfr if (ret == -1) { 265130407Sdfr pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 266130407Sdfr errno, "send"); 267130407Sdfr return (-1); 268130407Sdfr } 269130407Sdfr#elif defined(DL_HP_RAWDLS) 270130407Sdfr if (pd->send_fd < 0) { 271130407Sdfr pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 272130407Sdfr "send: Output FD couldn't be opened"); 273130407Sdfr return (-1); 274130407Sdfr } 275130407Sdfr ret = dlrawdatareq(pd->send_fd, buf, size); 276130407Sdfr if (ret == -1) { 277130407Sdfr pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 278130407Sdfr errno, "send"); 279130407Sdfr return (-1); 280130407Sdfr } 281130407Sdfr /* 282130407Sdfr * putmsg() returns either 0 or -1; it doesn't indicate how 283130407Sdfr * many bytes were written (presumably they were all written 284130407Sdfr * or none of them were written). OpenBSD's pcap_inject() 285130407Sdfr * returns the number of bytes written, so, for API compatibility, 286130407Sdfr * we return the number of bytes we were told to write. 287130407Sdfr */ 288144114Sgallatin ret = size; 289144114Sgallatin#else /* no raw mode */ 290130407Sdfr /* 291130407Sdfr * XXX - this is a pain, because you might have to extract 292130407Sdfr * the address from the packet and use it in a DL_UNITDATA_REQ 293130407Sdfr * request. That would be dependent on the link-layer type. 294130407Sdfr * 295130407Sdfr * I also don't know what SAP you'd have to bind the descriptor 296130407Sdfr * to, or whether you'd need separate "receive" and "send" FDs, 297130407Sdfr * nor do I know whether you'd need different bindings for 298144114Sgallatin * D/I/X Ethernet and 802.3, or for {FDDI,Token Ring} plus 299144114Sgallatin * 802.2 and {FDDI,Token Ring} plus 802.2 plus SNAP. 300144114Sgallatin * 301130407Sdfr * So, for now, we just return a "you can't send" indication, 302130407Sdfr * and leave it up to somebody with a DLPI-based system lacking 303130407Sdfr * both DLIOCRAW and DL_HP_RAWDLS to supply code to implement 304130407Sdfr * packet transmission on that system. If they do, they should 305130407Sdfr * send it to us - but should not send us code that assumes 306130407Sdfr * Ethernet; if the code doesn't work on non-Ethernet interfaces, 307130407Sdfr * it should check "p->linktype" and reject the send request if 308130407Sdfr * it's anything other than DLT_EN10MB. 309130407Sdfr */ 310130407Sdfr pcap_strlcpy(p->errbuf, "send: Not supported on this version of this OS", 311130407Sdfr PCAP_ERRBUF_SIZE); 312130407Sdfr ret = -1; 313130549Smlaier#endif /* raw mode */ 314130549Smlaier return (ret); 315130407Sdfr} 316130407Sdfr 317130407Sdfr#ifndef DL_IPATM 318130407Sdfr#define DL_IPATM 0x12 /* ATM Classical IP interface */ 319130407Sdfr#endif 320130407Sdfr 321130407Sdfr#ifdef HAVE_SOLARIS 322130407Sdfr/* 323130407Sdfr * For SunATM. 324130407Sdfr */ 325130407Sdfr#ifndef A_GET_UNITS 326130407Sdfr#define A_GET_UNITS (('A'<<8)|118) 327130407Sdfr#endif /* A_GET_UNITS */ 328130407Sdfr#ifndef A_PROMISCON_REQ 329130407Sdfr#define A_PROMISCON_REQ (('A'<<8)|121) 330130407Sdfr#endif /* A_PROMISCON_REQ */ 331130407Sdfr#endif /* HAVE_SOLARIS */ 332130407Sdfr 333130407Sdfrstatic void 334130407Sdfrpcap_cleanup_dlpi(pcap_t *p) 335130407Sdfr{ 336130407Sdfr#ifdef DL_HP_RAWDLS 337130407Sdfr struct pcap_dlpi *pd = p->priv; 338130407Sdfr 339130407Sdfr if (pd->send_fd >= 0) { 340130407Sdfr close(pd->send_fd); 341130407Sdfr pd->send_fd = -1; 342134246Srwatson } 343134246Srwatson#endif 344130407Sdfr pcap_cleanup_live_common(p); 345130407Sdfr} 346130407Sdfr 347130407Sdfrstatic int 348130407Sdfropen_dlpi_device(const char *name, u_int *ppa, char *errbuf) 349130407Sdfr{ 350130407Sdfr int status; 351130407Sdfr char dname[100]; 352130407Sdfr char *cp; 353130407Sdfr int fd; 354130407Sdfr#ifdef HAVE_DEV_DLPI 355130407Sdfr u_int unit; 356130407Sdfr#else 357130407Sdfr char dname2[100]; 358130407Sdfr#endif 359130407Sdfr 360130407Sdfr#ifdef HAVE_DEV_DLPI 361130407Sdfr /* 362130407Sdfr ** Remove any "/dev/" on the front of the device. 363130407Sdfr */ 364130407Sdfr cp = strrchr(name, '/'); 365130407Sdfr if (cp == NULL) 366130407Sdfr pcap_strlcpy(dname, name, sizeof(dname)); 367130407Sdfr else 368130407Sdfr pcap_strlcpy(dname, cp + 1, sizeof(dname)); 369130407Sdfr 370130407Sdfr /* 371130407Sdfr * Split the device name into a device type name and a unit number; 372130407Sdfr * chop off the unit number, so "dname" is just a device type name. 373130407Sdfr */ 374130407Sdfr cp = split_dname(dname, &unit, errbuf); 375130407Sdfr if (cp == NULL) 376130407Sdfr return (PCAP_ERROR_NO_SUCH_DEVICE); 377130407Sdfr *cp = '\0'; 378130407Sdfr 379130407Sdfr /* 380130407Sdfr * Use "/dev/dlpi" as the device. 381130407Sdfr * 382130407Sdfr * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that 383130407Sdfr * the "dl_mjr_num" field is for the "major number of interface 384130407Sdfr * driver"; that's the major of "/dev/dlpi" on the system on 385130407Sdfr * which I tried this, but there may be DLPI devices that 386130407Sdfr * use a different driver, in which case we may need to 387130407Sdfr * search "/dev" for the appropriate device with that major 388130407Sdfr * device number, rather than hardwiring "/dev/dlpi". 389130407Sdfr */ 390130407Sdfr cp = "/dev/dlpi"; 391130407Sdfr if ((fd = open(cp, O_RDWR)) < 0) { 392130407Sdfr if (errno == EPERM || errno == EACCES) 393130407Sdfr status = PCAP_ERROR_PERM_DENIED; 394130407Sdfr else 395130407Sdfr status = PCAP_ERROR; 396130407Sdfr pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 397130407Sdfr errno, "%s", cp); 398130407Sdfr return (status); 399130407Sdfr } 400130407Sdfr 401130407Sdfr /* 402130407Sdfr * Get a table of all PPAs for that device, and search that 403130407Sdfr * table for the specified device type name and unit number. 404130407Sdfr */ 405130407Sdfr status = get_dlpi_ppa(fd, dname, unit, ppa, errbuf); 406130407Sdfr if (status < 0) { 407130407Sdfr close(fd); 408130407Sdfr return (status); 409130407Sdfr } 410130407Sdfr#else 411130407Sdfr /* 412130407Sdfr * If the device name begins with "/", assume it begins with 413130407Sdfr * the pathname of the directory containing the device to open; 414130407Sdfr * otherwise, concatenate the device directory name and the 415130407Sdfr * device name. 416130407Sdfr */ 417130407Sdfr if (*name == '/') 418130407Sdfr pcap_strlcpy(dname, name, sizeof(dname)); 419130407Sdfr else 420130407Sdfr pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, 421130407Sdfr name); 422130407Sdfr 423130407Sdfr /* 424130407Sdfr * Get the unit number, and a pointer to the end of the device 425130407Sdfr * type name. 426130407Sdfr */ 427130407Sdfr cp = split_dname(dname, ppa, errbuf); 428130407Sdfr if (cp == NULL) 429130407Sdfr return (PCAP_ERROR_NO_SUCH_DEVICE); 430130407Sdfr 431130407Sdfr /* 432130407Sdfr * Make a copy of the device pathname, and then remove the unit 433130407Sdfr * number from the device pathname. 434130407Sdfr */ 435130407Sdfr pcap_strlcpy(dname2, dname, sizeof(dname)); 436130407Sdfr *cp = '\0'; 437130407Sdfr 438130407Sdfr /* Try device without unit number */ 439130407Sdfr if ((fd = open(dname, O_RDWR)) < 0) { 440130407Sdfr if (errno != ENOENT) { 441130407Sdfr if (errno == EPERM || errno == EACCES) 442130407Sdfr status = PCAP_ERROR_PERM_DENIED; 443130407Sdfr else 444130407Sdfr status = PCAP_ERROR; 445130407Sdfr pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 446130407Sdfr errno, "%s", dname); 447130407Sdfr return (status); 448130407Sdfr } 449130407Sdfr 450130407Sdfr /* Try again with unit number */ 451130407Sdfr if ((fd = open(dname2, O_RDWR)) < 0) { 452130407Sdfr if (errno == ENOENT) { 453130407Sdfr status = PCAP_ERROR_NO_SUCH_DEVICE; 454130407Sdfr 455130407Sdfr /* 456130407Sdfr * We provide an error message even 457130407Sdfr * for this error, for diagnostic 458130407Sdfr * purposes (so that, for example, 459130407Sdfr * the app can show the message if the 460130407Sdfr * user requests it). 461130407Sdfr * 462130407Sdfr * In it, we just report "No DLPI device 463130407Sdfr * found" with the device name, so people 464130407Sdfr * don't get confused and think, for example, 465130407Sdfr * that if they can't capture on "lo0" 466130407Sdfr * on Solaris prior to Solaris 11 the fix 467130407Sdfr * is to change libpcap (or the application 468130407Sdfr * that uses it) to look for something other 469130407Sdfr * than "/dev/lo0", as the fix is to use 470130407Sdfr * Solaris 11 or some operating system 471130407Sdfr * other than Solaris - you just *can't* 472130407Sdfr * capture on a loopback interface 473130407Sdfr * on Solaris prior to Solaris 11, the lack 474130407Sdfr * of a DLPI device for the loopback 475130407Sdfr * interface is just a symptom of that 476130407Sdfr * inability. 477130407Sdfr */ 478130407Sdfr pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 479130407Sdfr "%s: No DLPI device found", name); 480130407Sdfr } else { 481130407Sdfr if (errno == EPERM || errno == EACCES) 482130407Sdfr status = PCAP_ERROR_PERM_DENIED; 483130407Sdfr else 484130407Sdfr status = PCAP_ERROR; 485130407Sdfr pcap_fmt_errmsg_for_errno(errbuf, 486130407Sdfr PCAP_ERRBUF_SIZE, errno, "%s", dname2); 487130407Sdfr } 488130407Sdfr return (status); 489130407Sdfr } 490130407Sdfr /* XXX Assume unit zero */ 491130407Sdfr *ppa = 0; 492130407Sdfr } 493130407Sdfr#endif 494130407Sdfr return (fd); 495130407Sdfr} 496130407Sdfr 497130407Sdfrstatic int 498130407Sdfrpcap_activate_dlpi(pcap_t *p) 499130407Sdfr{ 500130407Sdfr#ifdef DL_HP_RAWDLS 501130407Sdfr struct pcap_dlpi *pd = p->priv; 502147256Sbrooks#endif 503130407Sdfr int status = 0; 504130407Sdfr int retv; 505130407Sdfr u_int ppa; 506130407Sdfr#ifdef HAVE_SOLARIS 507130407Sdfr int isatm = 0; 508130407Sdfr#endif 509130407Sdfr register dl_info_ack_t *infop; 510130407Sdfr#ifdef HAVE_SYS_BUFMOD_H 511130407Sdfr bpf_u_int32 ss; 512130407Sdfr#ifdef HAVE_SOLARIS 513130407Sdfr char release[GET_RELEASE_BUFSIZE]; 514130407Sdfr bpf_u_int32 osmajor, osminor, osmicro; 515130407Sdfr#endif 516130407Sdfr#endif 517130407Sdfr bpf_u_int32 buf[MAXDLBUF]; 518130407Sdfr 519130407Sdfr p->fd = open_dlpi_device(p->opt.device, &ppa, p->errbuf); 520130407Sdfr if (p->fd < 0) { 521130407Sdfr status = p->fd; 522130407Sdfr goto bad; 523130407Sdfr } 524130407Sdfr 525130407Sdfr#ifdef DL_HP_RAWDLS 526151265Simp /* 527130407Sdfr * XXX - HP-UX 10.20 and 11.xx don't appear to support sending and 528130407Sdfr * receiving packets on the same descriptor - you need separate 529130407Sdfr * descriptors for sending and receiving, bound to different SAPs. 530130407Sdfr * 531130407Sdfr * If the open fails, we just leave -1 in "pd->send_fd" and reject 532130407Sdfr * attempts to send packets, just as if, in pcap-bpf.c, we fail 533151265Simp * to open the BPF device for reading and writing, we just try 534130407Sdfr * to open it for reading only and, if that succeeds, just let 535130407Sdfr * the send attempts fail. 536130407Sdfr */ 537130407Sdfr pd->send_fd = open("/dev/dlpi", O_RDWR); 538130407Sdfr#endif 539130407Sdfr 540130407Sdfr /* 541130407Sdfr ** Attach if "style 2" provider 542130407Sdfr */ 543130407Sdfr if (dlinforeq(p->fd, p->errbuf) < 0 || 544130407Sdfr dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) { 545130407Sdfr status = PCAP_ERROR; 546130407Sdfr goto bad; 547130407Sdfr } 548130407Sdfr infop = &(MAKE_DL_PRIMITIVES(buf))->info_ack; 549130407Sdfr#ifdef HAVE_SOLARIS 550130407Sdfr if (infop->dl_mac_type == DL_IPATM) 551130407Sdfr isatm = 1; 552130407Sdfr#endif 553130407Sdfr if (infop->dl_provider_style == DL_STYLE2) { 554130407Sdfr retv = dl_doattach(p->fd, ppa, p->errbuf); 555130407Sdfr if (retv < 0) { 556130407Sdfr status = retv; 557130407Sdfr goto bad; 558130407Sdfr } 559130407Sdfr#ifdef DL_HP_RAWDLS 560130407Sdfr if (pd->send_fd >= 0) { 561130407Sdfr retv = dl_doattach(pd->send_fd, ppa, p->errbuf); 562130407Sdfr if (retv < 0) { 563130407Sdfr status = retv; 564130407Sdfr goto bad; 565130407Sdfr } 566130407Sdfr } 567130407Sdfr#endif 568130407Sdfr } 569130407Sdfr 570130407Sdfr if (p->opt.rfmon) { 571130407Sdfr /* 572130407Sdfr * This device exists, but we don't support monitor mode 573130407Sdfr * any platforms that support DLPI. 574130407Sdfr */ 575130407Sdfr status = PCAP_ERROR_RFMON_NOTSUP; 576130407Sdfr goto bad; 577130407Sdfr } 578130407Sdfr 579130407Sdfr#ifdef HAVE_DL_PASSIVE_REQ_T 580130407Sdfr /* 581130407Sdfr * Enable Passive mode to be able to capture on aggregated link. 582130407Sdfr * Not supported in all Solaris versions. 583130407Sdfr */ 584130407Sdfr dlpassive(p->fd, p->errbuf); 585130407Sdfr#endif 586130407Sdfr /* 587130407Sdfr ** Bind (defer if using HP-UX 9 or HP-UX 10.20 or later, totally 588130407Sdfr ** skip if using SINIX) 589130407Sdfr */ 590130407Sdfr#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20_OR_LATER) && !defined(sinix) 591130407Sdfr#ifdef _AIX 592130407Sdfr /* 593130407Sdfr ** AIX. 594130407Sdfr ** According to IBM's AIX Support Line, the dl_sap value 595130407Sdfr ** should not be less than 0x600 (1536) for standard Ethernet. 596130407Sdfr ** However, we seem to get DL_BADADDR - "DLSAP addr in improper 597130407Sdfr ** format or invalid" - errors if we use 1537 on the "tr0" 598130407Sdfr ** device, which, given that its name starts with "tr" and that 599130407Sdfr ** it's IBM, probably means a Token Ring device. (Perhaps we 600130407Sdfr ** need to use 1537 on "/dev/dlpi/en" because that device is for 601130407Sdfr ** D/I/X Ethernet, the "SAP" is actually an Ethernet type, and 602130407Sdfr ** it rejects invalid Ethernet types.) 603130407Sdfr ** 604130407Sdfr ** So if 1537 fails, we try 2, as Hyung Sik Yoon of IBM Korea 605130407Sdfr ** says that works on Token Ring (he says that 0 does *not* 606130407Sdfr ** work; perhaps that's considered an invalid LLC SAP value - I 607130407Sdfr ** assume the SAP value in a DLPI bind is an LLC SAP for network 608130407Sdfr ** types that use 802.2 LLC). 609130407Sdfr */ 610130407Sdfr if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 && 611130407Sdfr dlbindreq(p->fd, 2, p->errbuf) < 0) || 612130407Sdfr dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) { 613130407Sdfr status = PCAP_ERROR; 614130407Sdfr goto bad; 615130407Sdfr } 616130407Sdfr#elif defined(DL_HP_RAWDLS) 617130407Sdfr /* 618130407Sdfr ** HP-UX 10.0x and 10.1x. 619130407Sdfr */ 620130407Sdfr if (dl_dohpuxbind(p->fd, p->errbuf) < 0) { 621130407Sdfr status = PCAP_ERROR; 622130407Sdfr goto bad; 623130407Sdfr } 624130407Sdfr if (pd->send_fd >= 0) { 625130407Sdfr /* 626130407Sdfr ** XXX - if this fails, just close send_fd and 627130407Sdfr ** set it to -1, so that you can't send but can 628130407Sdfr ** still receive? 629130407Sdfr */ 630130407Sdfr if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0) { 631130407Sdfr status = PCAP_ERROR; 632130407Sdfr goto bad; 633130407Sdfr } 634130407Sdfr } 635130407Sdfr#else /* neither AIX nor HP-UX */ 636130407Sdfr /* 637130407Sdfr ** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other 638130407Sdfr ** OS using DLPI. 639130407Sdfr **/ 640130407Sdfr if (dlbindreq(p->fd, 0, p->errbuf) < 0 || 641130407Sdfr dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) { 642130407Sdfr status = PCAP_ERROR; 643130407Sdfr goto bad; 644130407Sdfr } 645130407Sdfr#endif /* AIX vs. HP-UX vs. other */ 646130407Sdfr#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */ 647130407Sdfr 648130407Sdfr /* 649130407Sdfr * Turn a negative snapshot value (invalid), a snapshot value of 650130407Sdfr * 0 (unspecified), or a value bigger than the normal maximum 651130407Sdfr * value, into the maximum allowed value. 652130407Sdfr * 653130407Sdfr * If some application really *needs* a bigger snapshot 654130407Sdfr * length, we should just increase MAXIMUM_SNAPLEN. 655130407Sdfr */ 656130407Sdfr if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 657130407Sdfr p->snapshot = MAXIMUM_SNAPLEN; 658130407Sdfr 659130407Sdfr#ifdef HAVE_SOLARIS 660130407Sdfr if (isatm) { 661130407Sdfr /* 662130407Sdfr ** Have to turn on some special ATM promiscuous mode 663130407Sdfr ** for SunATM. 664130407Sdfr ** Do *NOT* turn regular promiscuous mode on; it doesn't 665130407Sdfr ** help, and may break things. 666130407Sdfr */ 667130407Sdfr if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) { 668130407Sdfr status = PCAP_ERROR; 669130407Sdfr pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 670130407Sdfr errno, "A_PROMISCON_REQ"); 671130407Sdfr goto bad; 672130407Sdfr } 673130407Sdfr } else 674130407Sdfr#endif 675130407Sdfr if (p->opt.promisc) { 676130407Sdfr /* 677130407Sdfr ** Enable promiscuous (not necessary on send FD) 678130407Sdfr */ 679130407Sdfr retv = dlpromiscon(p, DL_PROMISC_PHYS); 680130407Sdfr if (retv < 0) { 681130407Sdfr if (retv == PCAP_ERROR_PERM_DENIED) 682130407Sdfr status = PCAP_ERROR_PROMISC_PERM_DENIED; 683130407Sdfr else 684130407Sdfr status = retv; 685130407Sdfr goto bad; 686130407Sdfr } 687130407Sdfr 688130407Sdfr /* 689130407Sdfr ** Try to enable multicast (you would have thought 690130407Sdfr ** promiscuous would be sufficient). (Skip if using 691130407Sdfr ** HP-UX or SINIX) (Not necessary on send FD) 692130407Sdfr */ 693130407Sdfr#if !defined(__hpux) && !defined(sinix) 694130407Sdfr retv = dlpromiscon(p, DL_PROMISC_MULTI); 695130407Sdfr if (retv < 0) 696130407Sdfr status = PCAP_WARNING; 697130407Sdfr#endif 698130407Sdfr } 699130407Sdfr /* 700130407Sdfr ** Try to enable SAP promiscuity (when not in promiscuous mode 701130407Sdfr ** when using HP-UX, when not doing SunATM on Solaris, and never 702130407Sdfr ** under SINIX) (Not necessary on send FD) 703130407Sdfr */ 704130407Sdfr#ifndef sinix 705130407Sdfr#if defined(__hpux) 706130407Sdfr /* HP-UX - only do this when not in promiscuous mode */ 707130407Sdfr if (!p->opt.promisc) { 708130407Sdfr#elif defined(HAVE_SOLARIS) 709130407Sdfr /* Solaris - don't do this on SunATM devices */ 710130407Sdfr if (!isatm) { 711130407Sdfr#else 712130407Sdfr /* Everything else (except for SINIX) - always do this */ 713130407Sdfr { 714130407Sdfr#endif 715130407Sdfr retv = dlpromiscon(p, DL_PROMISC_SAP); 716130407Sdfr if (retv < 0) { 717130407Sdfr if (p->opt.promisc) { 718130407Sdfr /* 719130407Sdfr * Not fatal, since the DL_PROMISC_PHYS mode 720130407Sdfr * worked. 721130407Sdfr * 722130407Sdfr * Report it as a warning, however. 723130407Sdfr */ 724130407Sdfr status = PCAP_WARNING; 725130407Sdfr } else { 726130407Sdfr /* 727130407Sdfr * Fatal. 728130407Sdfr */ 729130407Sdfr status = retv; 730130407Sdfr goto bad; 731130407Sdfr } 732130407Sdfr } 733130407Sdfr } 734130407Sdfr#endif /* sinix */ 735130407Sdfr 736130407Sdfr /* 737130407Sdfr ** HP-UX 9, and HP-UX 10.20 or later, must bind after setting 738130407Sdfr ** promiscuous options. 739130407Sdfr */ 740130407Sdfr#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER) 741130407Sdfr if (dl_dohpuxbind(p->fd, p->errbuf) < 0) { 742130407Sdfr status = PCAP_ERROR; 743130407Sdfr goto bad; 744130407Sdfr } 745130407Sdfr /* 746130407Sdfr ** We don't set promiscuous mode on the send FD, but we'll defer 747130407Sdfr ** binding it anyway, just to keep the HP-UX 9/10.20 or later 748130407Sdfr ** code together. 749130407Sdfr */ 750147256Sbrooks if (pd->send_fd >= 0) { 751130407Sdfr /* 752130407Sdfr ** XXX - if this fails, just close send_fd and 753130407Sdfr ** set it to -1, so that you can't send but can 754130407Sdfr ** still receive? 755130407Sdfr */ 756130407Sdfr if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0) { 757130407Sdfr status = PCAP_ERROR; 758130407Sdfr goto bad; 759130407Sdfr } 760130407Sdfr } 761130407Sdfr#endif 762130407Sdfr 763130407Sdfr /* 764130407Sdfr ** Determine link type 765130407Sdfr ** XXX - get SAP length and address length as well, for use 766130407Sdfr ** when sending packets. 767130407Sdfr */ 768130407Sdfr if (dlinforeq(p->fd, p->errbuf) < 0 || 769130407Sdfr dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) { 770130407Sdfr status = PCAP_ERROR; 771130407Sdfr goto bad; 772130407Sdfr } 773130407Sdfr 774130407Sdfr infop = &(MAKE_DL_PRIMITIVES(buf))->info_ack; 775130407Sdfr if (pcap_process_mactype(p, infop->dl_mac_type) != 0) { 776130407Sdfr status = PCAP_ERROR; 777130407Sdfr goto bad; 778130407Sdfr } 779130407Sdfr 780130407Sdfr#ifdef DLIOCRAW 781130407Sdfr /* 782130407Sdfr ** This is a non standard SunOS hack to get the full raw link-layer 783130407Sdfr ** header. 784130407Sdfr */ 785130407Sdfr if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { 786130407Sdfr status = PCAP_ERROR; 787130407Sdfr pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 788130407Sdfr errno, "DLIOCRAW"); 789130407Sdfr goto bad; 790130407Sdfr } 791130407Sdfr#endif 792130407Sdfr 793130407Sdfr#ifdef HAVE_SYS_BUFMOD_H 794130407Sdfr ss = p->snapshot; 795130407Sdfr 796130407Sdfr /* 797147256Sbrooks ** There is a bug in bufmod(7). When dealing with messages of 798130407Sdfr ** less than snaplen size it strips data from the beginning not 799130407Sdfr ** the end. 800130407Sdfr ** 801130407Sdfr ** This bug is fixed in 5.3.2. Also, there is a patch available. 802130407Sdfr ** Ask for bugid 1149065. 803130407Sdfr */ 804130407Sdfr#ifdef HAVE_SOLARIS 805130407Sdfr get_release(release, sizeof (release), &osmajor, &osminor, &osmicro); 806130407Sdfr if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && 807130407Sdfr getenv("BUFMOD_FIXED") == NULL) { 808130407Sdfr pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 809130407Sdfr "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.", 810130407Sdfr release); 811130407Sdfr ss = 0; 812130407Sdfr status = PCAP_WARNING; 813130407Sdfr } 814147256Sbrooks#endif 815147256Sbrooks 816147256Sbrooks /* Push and configure bufmod. */ 817147256Sbrooks if (pcap_conf_bufmod(p, ss) != 0) { 818147256Sbrooks status = PCAP_ERROR; 819147256Sbrooks goto bad; 820147256Sbrooks } 821147256Sbrooks#endif 822147256Sbrooks 823147256Sbrooks /* 824147256Sbrooks ** As the last operation flush the read side. 825147256Sbrooks */ 826147256Sbrooks if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { 827147256Sbrooks status = PCAP_ERROR; 828147256Sbrooks pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 829147256Sbrooks errno, "FLUSHR"); 830147256Sbrooks goto bad; 831147256Sbrooks } 832147256Sbrooks 833147256Sbrooks /* Allocate data buffer. */ 834147256Sbrooks if (pcap_alloc_databuf(p) != 0) { 835147256Sbrooks status = PCAP_ERROR; 836147256Sbrooks goto bad; 837147256Sbrooks } 838147256Sbrooks 839147256Sbrooks /* 840147256Sbrooks * Success. 841147256Sbrooks * 842147256Sbrooks * "p->fd" is an FD for a STREAMS device, so "select()" and 843147256Sbrooks * "poll()" should work on it. 844147256Sbrooks */ 845147256Sbrooks p->selectable_fd = p->fd; 846147256Sbrooks 847147256Sbrooks p->read_op = pcap_read_dlpi; 848147256Sbrooks p->inject_op = pcap_inject_dlpi; 849147256Sbrooks p->setfilter_op = install_bpf_program; /* no kernel filtering */ 850147256Sbrooks p->setdirection_op = NULL; /* Not implemented.*/ 851147256Sbrooks p->set_datalink_op = NULL; /* can't change data link type */ 852147256Sbrooks p->getnonblock_op = pcap_getnonblock_fd; 853150988Savatar p->setnonblock_op = pcap_setnonblock_fd; 854147256Sbrooks p->stats_op = pcap_stats_dlpi; 855147256Sbrooks p->cleanup_op = pcap_cleanup_dlpi; 856147256Sbrooks 857147256Sbrooks return (status); 858150988Savatarbad: 859150988Savatar pcap_cleanup_dlpi(p); 860 return (status); 861} 862 863/* 864 * Split a device name into a device type name and a unit number; 865 * return the a pointer to the beginning of the unit number, which 866 * is the end of the device type name, and set "*unitp" to the unit 867 * number. 868 * 869 * Returns NULL on error, and fills "ebuf" with an error message. 870 */ 871static char * 872split_dname(char *device, u_int *unitp, char *ebuf) 873{ 874 char *cp; 875 char *eos; 876 long unit; 877 878 /* 879 * Look for a number at the end of the device name string. 880 */ 881 cp = device + strlen(device) - 1; 882 if (*cp < '0' || *cp > '9') { 883 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", 884 device); 885 return (NULL); 886 } 887 888 /* Digits at end of string are unit number */ 889 while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9') 890 cp--; 891 892 errno = 0; 893 unit = strtol(cp, &eos, 10); 894 if (*eos != '\0') { 895 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); 896 return (NULL); 897 } 898 if (errno == ERANGE || unit > INT_MAX) { 899 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large", 900 device); 901 return (NULL); 902 } 903 if (unit < 0) { 904 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative", 905 device); 906 return (NULL); 907 } 908 *unitp = (u_int)unit; 909 return (cp); 910} 911 912static int 913dl_doattach(int fd, int ppa, char *ebuf) 914{ 915 dl_attach_req_t req; 916 bpf_u_int32 buf[MAXDLBUF]; 917 int err; 918 919 req.dl_primitive = DL_ATTACH_REQ; 920 req.dl_ppa = ppa; 921 if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0) 922 return (PCAP_ERROR); 923 924 err = dlokack(fd, "attach", (char *)buf, ebuf); 925 if (err < 0) 926 return (err); 927 return (0); 928} 929 930#ifdef DL_HP_RAWDLS 931static int 932dl_dohpuxbind(int fd, char *ebuf) 933{ 934 int hpsap; 935 int uerror; 936 bpf_u_int32 buf[MAXDLBUF]; 937 938 /* 939 * XXX - we start at 22 because we used to use only 22, but 940 * that was just because that was the value used in some 941 * sample code from HP. With what value *should* we start? 942 * Does it matter, given that we're enabling SAP promiscuity 943 * on the input FD? 944 */ 945 hpsap = 22; 946 for (;;) { 947 if (dlbindreq(fd, hpsap, ebuf) < 0) 948 return (-1); 949 if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0) 950 break; 951 /* 952 * For any error other than a UNIX EBUSY, give up. 953 */ 954 if (uerror != EBUSY) { 955 /* 956 * dlbindack() has already filled in ebuf for 957 * this error. 958 */ 959 return (-1); 960 } 961 962 /* 963 * For EBUSY, try the next SAP value; that means that 964 * somebody else is using that SAP. Clear ebuf so 965 * that application doesn't report the "Device busy" 966 * error as a warning. 967 */ 968 *ebuf = '\0'; 969 hpsap++; 970 if (hpsap > 100) { 971 pcap_strlcpy(ebuf, 972 "All SAPs from 22 through 100 are in use", 973 PCAP_ERRBUF_SIZE); 974 return (-1); 975 } 976 } 977 return (0); 978} 979#endif 980 981#define STRINGIFY(n) #n 982 983static int 984dlpromiscon(pcap_t *p, bpf_u_int32 level) 985{ 986 dl_promiscon_req_t req; 987 bpf_u_int32 buf[MAXDLBUF]; 988 int err; 989 990 req.dl_primitive = DL_PROMISCON_REQ; 991 req.dl_level = level; 992 if (send_request(p->fd, (char *)&req, sizeof(req), "promiscon", 993 p->errbuf) < 0) 994 return (PCAP_ERROR); 995 err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf, 996 p->errbuf); 997 if (err < 0) 998 return (err); 999 return (0); 1000} 1001 1002/* 1003 * Not all interfaces are DLPI interfaces, and thus not all interfaces 1004 * can be opened with DLPI (for example, the loopback interface is not 1005 * a DLPI interface on Solaris prior to Solaris 11), so try to open 1006 * the specified interface; return 0 if we fail with PCAP_ERROR_NO_SUCH_DEVICE 1007 * and 1 otherwise. 1008 */ 1009static int 1010is_dlpi_interface(const char *name) 1011{ 1012 int fd; 1013 u_int ppa; 1014 char errbuf[PCAP_ERRBUF_SIZE]; 1015 1016 fd = open_dlpi_device(name, &ppa, errbuf); 1017 if (fd < 0) { 1018 /* 1019 * Error - was it PCAP_ERROR_NO_SUCH_DEVICE? 1020 */ 1021 if (fd == PCAP_ERROR_NO_SUCH_DEVICE) { 1022 /* 1023 * Yes, so we can't open this because it's 1024 * not a DLPI interface. 1025 */ 1026 return (0); 1027 } 1028 /* 1029 * No, so, in the case where there's a single DLPI 1030 * device for all interfaces of this type ("style 1031 * 2" providers?), we don't know whether it's a DLPI 1032 * interface or not, as we didn't try an attach. 1033 * Say it is a DLPI device, so that the user can at 1034 * least try to open it and report the error (which 1035 * is probably "you don't have permission to open that 1036 * DLPI device"; reporting those interfaces means 1037 * users will ask "why am I getting a permissions error 1038 * when I try to capture" rather than "why am I not 1039 * seeing any interfaces", making the underlying problem 1040 * clearer). 1041 */ 1042 return (1); 1043 } 1044 1045 /* 1046 * Success. 1047 */ 1048 close(fd); 1049 return (1); 1050} 1051 1052static int 1053get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_) 1054{ 1055 /* 1056 * Nothing we can do other than mark loopback devices as "the 1057 * connected/disconnected status doesn't apply". 1058 * 1059 * XXX - on Solaris, can we do what the dladm command does, 1060 * i.e. get a connected/disconnected indication from a kstat? 1061 * (Note that you can also get the link speed, and possibly 1062 * other information, from a kstat as well.) 1063 */ 1064 if (*flags & PCAP_IF_LOOPBACK) { 1065 /* 1066 * Loopback devices aren't wireless, and "connected"/ 1067 * "disconnected" doesn't apply to them. 1068 */ 1069 *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; 1070 return (0); 1071 } 1072 return (0); 1073} 1074 1075int 1076pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) 1077{ 1078#ifdef HAVE_SOLARIS 1079 int fd; 1080 union { 1081 u_int nunits; 1082 char pad[516]; /* XXX - must be at least 513; is 516 1083 in "atmgetunits" */ 1084 } buf; 1085 char baname[2+1+1]; 1086 u_int i; 1087#endif 1088 1089 /* 1090 * Get the list of regular interfaces first. 1091 */ 1092 if (pcap_findalldevs_interfaces(devlistp, errbuf, is_dlpi_interface, 1093 get_if_flags) == -1) 1094 return (-1); /* failure */ 1095 1096#ifdef HAVE_SOLARIS 1097 /* 1098 * We may have to do special magic to get ATM devices. 1099 */ 1100 if ((fd = open("/dev/ba", O_RDWR)) < 0) { 1101 /* 1102 * We couldn't open the "ba" device. 1103 * For now, just give up; perhaps we should 1104 * return an error if the problem is neither 1105 * a "that device doesn't exist" error (ENOENT, 1106 * ENXIO, etc.) or a "you're not allowed to do 1107 * that" error (EPERM, EACCES). 1108 */ 1109 return (0); 1110 } 1111 1112 if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) { 1113 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1114 errno, "A_GET_UNITS"); 1115 return (-1); 1116 } 1117 for (i = 0; i < buf.nunits; i++) { 1118 pcap_snprintf(baname, sizeof baname, "ba%u", i); 1119 /* 1120 * XXX - is there a notion of "up" and "running"? 1121 * And is there a way to determine whether the 1122 * interface is plugged into a network? 1123 */ 1124 if (add_dev(devlistp, baname, 0, NULL, errbuf) == NULL) 1125 return (-1); 1126 } 1127#endif 1128 1129 return (0); 1130} 1131 1132static int 1133send_request(int fd, char *ptr, int len, char *what, char *ebuf) 1134{ 1135 struct strbuf ctl; 1136 int flags; 1137 1138 ctl.maxlen = 0; 1139 ctl.len = len; 1140 ctl.buf = ptr; 1141 1142 flags = 0; 1143 if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { 1144 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1145 errno, "send_request: putmsg \"%s\"", what); 1146 return (-1); 1147 } 1148 return (0); 1149} 1150 1151static int 1152recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror) 1153{ 1154 union DL_primitives *dlp; 1155 struct strbuf ctl; 1156 int flags; 1157 char errmsgbuf[PCAP_ERRBUF_SIZE]; 1158 char dlprimbuf[64]; 1159 1160 /* 1161 * Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR, 1162 * making that the only place where EBUSY is treated specially. 1163 */ 1164 if (uerror != NULL) 1165 *uerror = 0; 1166 1167 ctl.maxlen = MAXDLBUF; 1168 ctl.len = 0; 1169 ctl.buf = bufp; 1170 1171 flags = 0; 1172 if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { 1173 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1174 errno, "recv_ack: %s getmsg", what); 1175 return (PCAP_ERROR); 1176 } 1177 1178 dlp = MAKE_DL_PRIMITIVES(ctl.buf); 1179 switch (dlp->dl_primitive) { 1180 1181 case DL_INFO_ACK: 1182 case DL_BIND_ACK: 1183 case DL_OK_ACK: 1184#ifdef DL_HP_PPA_ACK 1185 case DL_HP_PPA_ACK: 1186#endif 1187 /* These are OK */ 1188 break; 1189 1190 case DL_ERROR_ACK: 1191 switch (dlp->error_ack.dl_errno) { 1192 1193 case DL_SYSERR: 1194 if (uerror != NULL) 1195 *uerror = dlp->error_ack.dl_unix_errno; 1196 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1197 dlp->error_ack.dl_unix_errno, 1198 "recv_ack: %s: UNIX error", what); 1199 if (dlp->error_ack.dl_unix_errno == EPERM || 1200 dlp->error_ack.dl_unix_errno == EACCES) 1201 return (PCAP_ERROR_PERM_DENIED); 1202 break; 1203 1204 default: 1205 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1206 "recv_ack: %s: %s", what, 1207 dlstrerror(errmsgbuf, sizeof (errmsgbuf), dlp->error_ack.dl_errno)); 1208 if (dlp->error_ack.dl_errno == DL_BADPPA) 1209 return (PCAP_ERROR_NO_SUCH_DEVICE); 1210 else if (dlp->error_ack.dl_errno == DL_ACCESS) 1211 return (PCAP_ERROR_PERM_DENIED); 1212 break; 1213 } 1214 return (PCAP_ERROR); 1215 1216 default: 1217 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1218 "recv_ack: %s: Unexpected primitive ack %s", 1219 what, dlprim(dlprimbuf, sizeof (dlprimbuf), dlp->dl_primitive)); 1220 return (PCAP_ERROR); 1221 } 1222 1223 if (ctl.len < size) { 1224 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1225 "recv_ack: %s: Ack too small (%d < %d)", 1226 what, ctl.len, size); 1227 return (PCAP_ERROR); 1228 } 1229 return (ctl.len); 1230} 1231 1232static char * 1233dlstrerror(char *errbuf, size_t errbufsize, bpf_u_int32 dl_errno) 1234{ 1235 switch (dl_errno) { 1236 1237 case DL_ACCESS: 1238 return ("Improper permissions for request"); 1239 1240 case DL_BADADDR: 1241 return ("DLSAP addr in improper format or invalid"); 1242 1243 case DL_BADCORR: 1244 return ("Seq number not from outstand DL_CONN_IND"); 1245 1246 case DL_BADDATA: 1247 return ("User data exceeded provider limit"); 1248 1249 case DL_BADPPA: 1250#ifdef HAVE_DEV_DLPI 1251 /* 1252 * With a single "/dev/dlpi" device used for all 1253 * DLPI providers, PPAs have nothing to do with 1254 * unit numbers. 1255 */ 1256 return ("Specified PPA was invalid"); 1257#else 1258 /* 1259 * We have separate devices for separate devices; 1260 * the PPA is just the unit number. 1261 */ 1262 return ("Specified PPA (device unit) was invalid"); 1263#endif 1264 1265 case DL_BADPRIM: 1266 return ("Primitive received not known by provider"); 1267 1268 case DL_BADQOSPARAM: 1269 return ("QOS parameters contained invalid values"); 1270 1271 case DL_BADQOSTYPE: 1272 return ("QOS structure type is unknown/unsupported"); 1273 1274 case DL_BADSAP: 1275 return ("Bad LSAP selector"); 1276 1277 case DL_BADTOKEN: 1278 return ("Token used not an active stream"); 1279 1280 case DL_BOUND: 1281 return ("Attempted second bind with dl_max_conind"); 1282 1283 case DL_INITFAILED: 1284 return ("Physical link initialization failed"); 1285 1286 case DL_NOADDR: 1287 return ("Provider couldn't allocate alternate address"); 1288 1289 case DL_NOTINIT: 1290 return ("Physical link not initialized"); 1291 1292 case DL_OUTSTATE: 1293 return ("Primitive issued in improper state"); 1294 1295 case DL_SYSERR: 1296 return ("UNIX system error occurred"); 1297 1298 case DL_UNSUPPORTED: 1299 return ("Requested service not supplied by provider"); 1300 1301 case DL_UNDELIVERABLE: 1302 return ("Previous data unit could not be delivered"); 1303 1304 case DL_NOTSUPPORTED: 1305 return ("Primitive is known but not supported"); 1306 1307 case DL_TOOMANY: 1308 return ("Limit exceeded"); 1309 1310 case DL_NOTENAB: 1311 return ("Promiscuous mode not enabled"); 1312 1313 case DL_BUSY: 1314 return ("Other streams for PPA in post-attached"); 1315 1316 case DL_NOAUTO: 1317 return ("Automatic handling XID&TEST not supported"); 1318 1319 case DL_NOXIDAUTO: 1320 return ("Automatic handling of XID not supported"); 1321 1322 case DL_NOTESTAUTO: 1323 return ("Automatic handling of TEST not supported"); 1324 1325 case DL_XIDAUTO: 1326 return ("Automatic handling of XID response"); 1327 1328 case DL_TESTAUTO: 1329 return ("Automatic handling of TEST response"); 1330 1331 case DL_PENDING: 1332 return ("Pending outstanding connect indications"); 1333 1334 default: 1335 pcap_snprintf(errbuf, errbufsize, "Error %02x", dl_errno); 1336 return (errbuf); 1337 } 1338} 1339 1340static char * 1341dlprim(char *primbuf, size_t primbufsize, bpf_u_int32 prim) 1342{ 1343 switch (prim) { 1344 1345 case DL_INFO_REQ: 1346 return ("DL_INFO_REQ"); 1347 1348 case DL_INFO_ACK: 1349 return ("DL_INFO_ACK"); 1350 1351 case DL_ATTACH_REQ: 1352 return ("DL_ATTACH_REQ"); 1353 1354 case DL_DETACH_REQ: 1355 return ("DL_DETACH_REQ"); 1356 1357 case DL_BIND_REQ: 1358 return ("DL_BIND_REQ"); 1359 1360 case DL_BIND_ACK: 1361 return ("DL_BIND_ACK"); 1362 1363 case DL_UNBIND_REQ: 1364 return ("DL_UNBIND_REQ"); 1365 1366 case DL_OK_ACK: 1367 return ("DL_OK_ACK"); 1368 1369 case DL_ERROR_ACK: 1370 return ("DL_ERROR_ACK"); 1371 1372 case DL_SUBS_BIND_REQ: 1373 return ("DL_SUBS_BIND_REQ"); 1374 1375 case DL_SUBS_BIND_ACK: 1376 return ("DL_SUBS_BIND_ACK"); 1377 1378 case DL_UNITDATA_REQ: 1379 return ("DL_UNITDATA_REQ"); 1380 1381 case DL_UNITDATA_IND: 1382 return ("DL_UNITDATA_IND"); 1383 1384 case DL_UDERROR_IND: 1385 return ("DL_UDERROR_IND"); 1386 1387 case DL_UDQOS_REQ: 1388 return ("DL_UDQOS_REQ"); 1389 1390 case DL_CONNECT_REQ: 1391 return ("DL_CONNECT_REQ"); 1392 1393 case DL_CONNECT_IND: 1394 return ("DL_CONNECT_IND"); 1395 1396 case DL_CONNECT_RES: 1397 return ("DL_CONNECT_RES"); 1398 1399 case DL_CONNECT_CON: 1400 return ("DL_CONNECT_CON"); 1401 1402 case DL_TOKEN_REQ: 1403 return ("DL_TOKEN_REQ"); 1404 1405 case DL_TOKEN_ACK: 1406 return ("DL_TOKEN_ACK"); 1407 1408 case DL_DISCONNECT_REQ: 1409 return ("DL_DISCONNECT_REQ"); 1410 1411 case DL_DISCONNECT_IND: 1412 return ("DL_DISCONNECT_IND"); 1413 1414 case DL_RESET_REQ: 1415 return ("DL_RESET_REQ"); 1416 1417 case DL_RESET_IND: 1418 return ("DL_RESET_IND"); 1419 1420 case DL_RESET_RES: 1421 return ("DL_RESET_RES"); 1422 1423 case DL_RESET_CON: 1424 return ("DL_RESET_CON"); 1425 1426 default: 1427 pcap_snprintf(primbuf, primbufsize, "unknown primitive 0x%x", 1428 prim); 1429 return (primbuf); 1430 } 1431} 1432 1433static int 1434dlbindreq(int fd, bpf_u_int32 sap, char *ebuf) 1435{ 1436 1437 dl_bind_req_t req; 1438 1439 memset((char *)&req, 0, sizeof(req)); 1440 req.dl_primitive = DL_BIND_REQ; 1441 /* XXX - what if neither of these are defined? */ 1442#if defined(DL_HP_RAWDLS) 1443 req.dl_max_conind = 1; /* XXX magic number */ 1444 req.dl_service_mode = DL_HP_RAWDLS; 1445#elif defined(DL_CLDLS) 1446 req.dl_service_mode = DL_CLDLS; 1447#endif 1448 req.dl_sap = sap; 1449 1450 return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf)); 1451} 1452 1453static int 1454dlbindack(int fd, char *bufp, char *ebuf, int *uerror) 1455{ 1456 1457 return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror)); 1458} 1459 1460static int 1461dlokack(int fd, const char *what, char *bufp, char *ebuf) 1462{ 1463 1464 return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL)); 1465} 1466 1467 1468static int 1469dlinforeq(int fd, char *ebuf) 1470{ 1471 dl_info_req_t req; 1472 1473 req.dl_primitive = DL_INFO_REQ; 1474 1475 return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf)); 1476} 1477 1478static int 1479dlinfoack(int fd, char *bufp, char *ebuf) 1480{ 1481 1482 return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL)); 1483} 1484 1485#ifdef HAVE_DL_PASSIVE_REQ_T 1486/* 1487 * Enable DLPI passive mode. We do not care if this request fails, as this 1488 * indicates the underlying DLPI device does not support link aggregation. 1489 */ 1490static void 1491dlpassive(int fd, char *ebuf) 1492{ 1493 dl_passive_req_t req; 1494 bpf_u_int32 buf[MAXDLBUF]; 1495 1496 req.dl_primitive = DL_PASSIVE_REQ; 1497 1498 if (send_request(fd, (char *)&req, sizeof(req), "dlpassive", ebuf) == 0) 1499 (void) dlokack(fd, "dlpassive", (char *)buf, ebuf); 1500} 1501#endif 1502 1503#ifdef DL_HP_RAWDLS 1504/* 1505 * There's an ack *if* there's an error. 1506 */ 1507static int 1508dlrawdatareq(int fd, const u_char *datap, int datalen) 1509{ 1510 struct strbuf ctl, data; 1511 long buf[MAXDLBUF]; /* XXX - char? */ 1512 union DL_primitives *dlp; 1513 int dlen; 1514 1515 dlp = MAKE_DL_PRIMITIVES(buf); 1516 1517 dlp->dl_primitive = DL_HP_RAWDATA_REQ; 1518 dlen = DL_HP_RAWDATA_REQ_SIZE; 1519 1520 /* 1521 * HP's documentation doesn't appear to show us supplying any 1522 * address pointed to by the control part of the message. 1523 * I think that's what raw mode means - you just send the raw 1524 * packet, you don't specify where to send it to, as that's 1525 * implied by the destination address. 1526 */ 1527 ctl.maxlen = 0; 1528 ctl.len = dlen; 1529 ctl.buf = (void *)buf; 1530 1531 data.maxlen = 0; 1532 data.len = datalen; 1533 data.buf = (void *)datap; 1534 1535 return (putmsg(fd, &ctl, &data, 0)); 1536} 1537#endif /* DL_HP_RAWDLS */ 1538 1539#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) 1540static void 1541get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp, 1542 bpf_u_int32 *minorp, bpf_u_int32 *microp) 1543{ 1544 char *cp; 1545 1546 *majorp = 0; 1547 *minorp = 0; 1548 *microp = 0; 1549 if (sysinfo(SI_RELEASE, buf, bufsize) < 0) { 1550 pcap_strlcpy(buf, "?", bufsize); 1551 return; 1552 } 1553 cp = buf; 1554 if (!isdigit((unsigned char)*cp)) 1555 return; 1556 *majorp = strtol(cp, &cp, 10); 1557 if (*cp++ != '.') 1558 return; 1559 *minorp = strtol(cp, &cp, 10); 1560 if (*cp++ != '.') 1561 return; 1562 *microp = strtol(cp, &cp, 10); 1563} 1564#endif 1565 1566#ifdef DL_HP_PPA_REQ 1567/* 1568 * Under HP-UX 10 and HP-UX 11, we can ask for the ppa 1569 */ 1570 1571 1572/* 1573 * Determine ppa number that specifies ifname. 1574 * 1575 * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, 1576 * the code that's used here is the old code for HP-UX 10.x. 1577 * 1578 * However, HP-UX 10.20, at least, appears to have such a member 1579 * in its "dl_hp_ppa_info_t" structure, so the new code is used. 1580 * The new code didn't work on an old 10.20 system on which Rick 1581 * Jones of HP tried it, but with later patches installed, it 1582 * worked - it appears that the older system had those members but 1583 * didn't put anything in them, so, if the search by name fails, we 1584 * do the old search. 1585 * 1586 * Rick suggests that making sure your system is "up on the latest 1587 * lancommon/DLPI/driver patches" is probably a good idea; it'd fix 1588 * that problem, as well as allowing libpcap to see packets sent 1589 * from the system on which the libpcap application is being run. 1590 * (On 10.20, in addition to getting the latest patches, you need 1591 * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; 1592 * a posting to "comp.sys.hp.hpux" at 1593 * 1594 * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 1595 * 1596 * says that, to see the machine's outgoing traffic, you'd need to 1597 * apply the right patches to your system, and also set that variable 1598 * with: 1599 1600echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem 1601 1602 * which could be put in, for example, "/sbin/init.d/lan". 1603 * 1604 * Setting the variable is not necessary on HP-UX 11.x. 1605 */ 1606static int 1607get_dlpi_ppa(register int fd, register const char *device, register u_int unit, 1608 u_int *ppa, register char *ebuf) 1609{ 1610 register dl_hp_ppa_ack_t *ap; 1611 register dl_hp_ppa_info_t *ipstart, *ip; 1612 register u_int i; 1613 char dname[100]; 1614 register u_long majdev; 1615 struct stat statbuf; 1616 dl_hp_ppa_req_t req; 1617 char buf[MAXDLBUF]; 1618 char *ppa_data_buf; 1619 dl_hp_ppa_ack_t *dlp; 1620 struct strbuf ctl; 1621 int flags; 1622 1623 memset((char *)&req, 0, sizeof(req)); 1624 req.dl_primitive = DL_HP_PPA_REQ; 1625 1626 memset((char *)buf, 0, sizeof(buf)); 1627 if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0) 1628 return (PCAP_ERROR); 1629 1630 ctl.maxlen = DL_HP_PPA_ACK_SIZE; 1631 ctl.len = 0; 1632 ctl.buf = (char *)buf; 1633 1634 flags = 0; 1635 /* 1636 * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal 1637 * recv_ack will fail because it set the maxlen to MAXDLBUF (8192) 1638 * which is NOT big enough for a DL_HP_PPA_REQ. 1639 * 1640 * This causes libpcap applications to fail on a system with HP-APA 1641 * installed. 1642 * 1643 * To figure out how big the returned data is, we first call getmsg 1644 * to get the small head and peek at the head to get the actual data 1645 * length, and then issue another getmsg to get the actual PPA data. 1646 */ 1647 /* get the head first */ 1648 if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { 1649 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1650 errno, "get_dlpi_ppa: hpppa getmsg"); 1651 return (PCAP_ERROR); 1652 } 1653 if (ctl.len == -1) { 1654 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1655 "get_dlpi_ppa: hpppa getmsg: control buffer has no data"); 1656 return (PCAP_ERROR); 1657 } 1658 1659 dlp = (dl_hp_ppa_ack_t *)ctl.buf; 1660 if (dlp->dl_primitive != DL_HP_PPA_ACK) { 1661 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1662 "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x", 1663 (bpf_u_int32)dlp->dl_primitive); 1664 return (PCAP_ERROR); 1665 } 1666 1667 if ((size_t)ctl.len < DL_HP_PPA_ACK_SIZE) { 1668 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1669 "get_dlpi_ppa: hpppa ack too small (%d < %lu)", 1670 ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE); 1671 return (PCAP_ERROR); 1672 } 1673 1674 /* allocate buffer */ 1675 if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) { 1676 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1677 errno, "get_dlpi_ppa: hpppa malloc"); 1678 return (PCAP_ERROR); 1679 } 1680 ctl.maxlen = dlp->dl_length; 1681 ctl.len = 0; 1682 ctl.buf = (char *)ppa_data_buf; 1683 /* get the data */ 1684 if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { 1685 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1686 errno, "get_dlpi_ppa: hpppa getmsg"); 1687 free(ppa_data_buf); 1688 return (PCAP_ERROR); 1689 } 1690 if (ctl.len == -1) { 1691 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1692 "get_dlpi_ppa: hpppa getmsg: control buffer has no data"); 1693 return (PCAP_ERROR); 1694 } 1695 if ((u_int)ctl.len < dlp->dl_length) { 1696 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1697 "get_dlpi_ppa: hpppa ack too small (%d < %lu)", 1698 ctl.len, (unsigned long)dlp->dl_length); 1699 free(ppa_data_buf); 1700 return (PCAP_ERROR); 1701 } 1702 1703 ap = (dl_hp_ppa_ack_t *)buf; 1704 ipstart = (dl_hp_ppa_info_t *)ppa_data_buf; 1705 ip = ipstart; 1706 1707#ifdef HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1 1708 /* 1709 * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1" 1710 * member that should, in theory, contain the part of the 1711 * name for the device that comes before the unit number, 1712 * and should also have a "dl_module_id_2" member that may 1713 * contain an alternate name (e.g., I think Ethernet devices 1714 * have both "lan", for "lanN", and "snap", for "snapN", with 1715 * the former being for Ethernet packets and the latter being 1716 * for 802.3/802.2 packets). 1717 * 1718 * Search for the device that has the specified name and 1719 * instance number. 1720 */ 1721 for (i = 0; i < ap->dl_count; i++) { 1722 if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 || 1723 strcmp((const char *)ip->dl_module_id_2, device) == 0) && 1724 ip->dl_instance_num == unit) 1725 break; 1726 1727 ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); 1728 } 1729#else 1730 /* 1731 * We don't have that member, so the search is impossible; make it 1732 * look as if the search failed. 1733 */ 1734 i = ap->dl_count; 1735#endif 1736 1737 if (i == ap->dl_count) { 1738 /* 1739 * Well, we didn't, or can't, find the device by name. 1740 * 1741 * HP-UX 10.20, whilst it has "dl_module_id_1" and 1742 * "dl_module_id_2" fields in the "dl_hp_ppa_info_t", 1743 * doesn't seem to fill them in unless the system is 1744 * at a reasonably up-to-date patch level. 1745 * 1746 * Older HP-UX 10.x systems might not have those fields 1747 * at all. 1748 * 1749 * Therefore, we'll search for the entry with the major 1750 * device number of a device with the name "/dev/<dev><unit>", 1751 * if such a device exists, as the old code did. 1752 */ 1753 pcap_snprintf(dname, sizeof(dname), "/dev/%s%u", device, unit); 1754 if (stat(dname, &statbuf) < 0) { 1755 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1756 errno, "stat: %s", dname); 1757 return (PCAP_ERROR); 1758 } 1759 majdev = major(statbuf.st_rdev); 1760 1761 ip = ipstart; 1762 1763 for (i = 0; i < ap->dl_count; i++) { 1764 if (ip->dl_mjr_num == majdev && 1765 ip->dl_instance_num == unit) 1766 break; 1767 1768 ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); 1769 } 1770 } 1771 if (i == ap->dl_count) { 1772 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1773 "can't find /dev/dlpi PPA for %s%u", device, unit); 1774 return (PCAP_ERROR_NO_SUCH_DEVICE); 1775 } 1776 if (ip->dl_hdw_state == HDW_DEAD) { 1777 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1778 "%s%d: hardware state: DOWN\n", device, unit); 1779 free(ppa_data_buf); 1780 return (PCAP_ERROR); 1781 } 1782 *ppa = ip->dl_ppa; 1783 free(ppa_data_buf); 1784 return (0); 1785} 1786#endif 1787 1788#ifdef HAVE_HPUX9 1789/* 1790 * Under HP-UX 9, there is no good way to determine the ppa. 1791 * So punt and read it from /dev/kmem. 1792 */ 1793static struct nlist nl[] = { 1794#define NL_IFNET 0 1795 { "ifnet" }, 1796 { "" } 1797}; 1798 1799static char path_vmunix[] = "/hp-ux"; 1800 1801/* Determine ppa number that specifies ifname */ 1802static int 1803get_dlpi_ppa(register int fd, register const char *ifname, register u_int unit, 1804 u_int *ppa, register char *ebuf) 1805{ 1806 register const char *cp; 1807 register int kd; 1808 void *addr; 1809 struct ifnet ifnet; 1810 char if_name[sizeof(ifnet.if_name) + 1]; 1811 1812 cp = strrchr(ifname, '/'); 1813 if (cp != NULL) 1814 ifname = cp + 1; 1815 if (nlist(path_vmunix, &nl) < 0) { 1816 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", 1817 path_vmunix); 1818 return (PCAP_ERROR); 1819 } 1820 if (nl[NL_IFNET].n_value == 0) { 1821 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1822 "could't find %s kernel symbol", 1823 nl[NL_IFNET].n_name); 1824 return (PCAP_ERROR); 1825 } 1826 kd = open("/dev/kmem", O_RDONLY); 1827 if (kd < 0) { 1828 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1829 errno, "kmem open"); 1830 return (PCAP_ERROR); 1831 } 1832 if (dlpi_kread(kd, nl[NL_IFNET].n_value, 1833 &addr, sizeof(addr), ebuf) < 0) { 1834 close(kd); 1835 return (PCAP_ERROR); 1836 } 1837 for (; addr != NULL; addr = ifnet.if_next) { 1838 if (dlpi_kread(kd, (off_t)addr, 1839 &ifnet, sizeof(ifnet), ebuf) < 0 || 1840 dlpi_kread(kd, (off_t)ifnet.if_name, 1841 if_name, sizeof(ifnet.if_name), ebuf) < 0) { 1842 (void)close(kd); 1843 return (PCAP_ERROR); 1844 } 1845 if_name[sizeof(ifnet.if_name)] = '\0'; 1846 if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) { 1847 *ppa = ifnet.if_index; 1848 return (0); 1849 } 1850 } 1851 1852 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); 1853 return (PCAP_ERROR_NO_SUCH_DEVICE); 1854} 1855 1856static int 1857dlpi_kread(register int fd, register off_t addr, 1858 register void *buf, register u_int len, register char *ebuf) 1859{ 1860 register int cc; 1861 1862 if (lseek(fd, addr, SEEK_SET) < 0) { 1863 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1864 errno, "lseek"); 1865 return (-1); 1866 } 1867 cc = read(fd, buf, len); 1868 if (cc < 0) { 1869 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1870 errno, "read"); 1871 return (-1); 1872 } else if (cc != len) { 1873 pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, 1874 len); 1875 return (-1); 1876 } 1877 return (cc); 1878} 1879#endif 1880 1881pcap_t * 1882pcap_create_interface(const char *device _U_, char *ebuf) 1883{ 1884 pcap_t *p; 1885#ifdef DL_HP_RAWDLS 1886 struct pcap_dlpi *pd; 1887#endif 1888 1889 p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi)); 1890 if (p == NULL) 1891 return (NULL); 1892 1893#ifdef DL_HP_RAWDLS 1894 pd = p->priv; 1895 pd->send_fd = -1; /* it hasn't been opened yet */ 1896#endif 1897 1898 p->activate_op = pcap_activate_dlpi; 1899 return (p); 1900} 1901 1902/* 1903 * Libpcap version string. 1904 */ 1905const char * 1906pcap_lib_version(void) 1907{ 1908 return (PCAP_VERSION_STRING); 1909} 1910