1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (c) 1993, 1994, 1995, 1996, 1997 3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The Regents of the University of California. All rights reserved. 4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Redistribution and use in source and binary forms, with or without 6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * modification, are permitted provided that: (1) source code distributions 7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * retain the above copyright notice and this paragraph in its entirety, (2) 8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * distributions including binary code include the above copyright notice and 9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this paragraph in its entirety in the documentation or other materials 10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * provided with the distribution, and (3) all advertising materials mentioning 11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * features or use of this software display the following acknowledgement: 12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ``This product includes software developed by the University of California, 13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the University nor the names of its contributors may be used to endorse 15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or promote products derived from this software without specific prior 16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * written permission. 17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This code contributed by Sagun Shakya (sagun.shakya@sun.com) 22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Packet capture routines for DLPI using libdlpi under SunOS 5.11. 25511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef lint 28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char rcsid[] _U_ = 29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.6 2008-04-14 20:40:58 guy Exp $ (LBL)"; 30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_CONFIG_H 33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "config.h" 34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/types.h> 37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/time.h> 38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/bufmod.h> 39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/stream.h> 40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <libdlpi.h> 41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <errno.h> 42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <memory.h> 43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stropts.h> 44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdio.h> 45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h> 46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h> 47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-int.h" 49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "dlpisubs.h" 50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* Forwards. */ 52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int dlpromiscon(pcap_t *, bpf_u_int32); 53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *); 54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int pcap_inject_libdlpi(pcap_t *, const void *, size_t); 55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void pcap_libdlpi_err(const char *, const char *, int, char *); 56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void pcap_cleanup_libdlpi(pcap_t *); 57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * list_interfaces() will list all the network links that are 60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * available on a system. 61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic boolean_t list_interfaces(const char *, void *); 63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralltypedef struct linknamelist { 65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char linkname[DLPI_LINKNAME_MAX]; 66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct linknamelist *lnl_next; 67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} linknamelist_t; 68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralltypedef struct linkwalk { 70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linknamelist_t *lw_list; 71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int lw_err; 72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} linkwalk_t; 73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * The caller of this function should free the memory allocated 76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for each linknamelist_t "entry" allocated. 77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic boolean_t 79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralllist_interfaces(const char *linkname, void *arg) 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linkwalk_t *lwp = arg; 82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linknamelist_t *entry; 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((entry = calloc(1, sizeof(linknamelist_t))) == NULL) { 85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall lwp->lw_err = ENOMEM; 86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (B_TRUE); 87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void) strlcpy(entry->linkname, linkname, DLPI_LINKNAME_MAX); 89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (lwp->lw_list == NULL) { 91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall lwp->lw_list = entry; 92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall entry->lnl_next = lwp->lw_list; 94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall lwp->lw_list = entry; 95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (B_FALSE); 98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_activate_libdlpi(pcap_t *p) 102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv; 105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dlpi_handle_t dh; 106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dlpi_info_t dlinfo; 107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int err = PCAP_ERROR; 108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Enable Solaris raw and passive DLPI extensions; 111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * dlpi_open() will not fail if the underlying link does not support 112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * passive mode. See dlpi(7P) for details. 113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE); 115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv != DLPI_SUCCESS) { 116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK) 117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_ERROR_NO_SUCH_DEVICE; 118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else if (retv == DL_SYSERR && 119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (errno == EPERM || errno == EACCES)) 120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_ERROR_PERM_DENIED; 121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_libdlpi_err(p->opt.source, "dlpi_open", retv, 122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->errbuf); 123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (err); 124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pd->dlpi_hd = dh; 126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.rfmon) { 128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This device exists, but we don't support monitor mode 130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * any platforms that support DLPI. 131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_ERROR_RFMON_NOTSUP; 133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Bind with DLPI_ANY_SAP. */ 137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) { 138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf); 139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Enable promiscuous mode. */ 143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.promisc) { 144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = dlpromiscon(p, DL_PROMISC_PHYS); 145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (err < 0) { 146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "You don't have permission to capture on 148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this device" and "you don't have permission 149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to capture in promiscuous mode on this 150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * device" are different; let the user know, 151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * so if they can't get permission to 152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * capture in promiscuous mode, they can at 153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * least try to capture in non-promiscuous 154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * mode. 155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX - you might have to capture in 157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * promiscuous mode to see outgoing packets. 158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (err == PCAP_ERROR_PERM_DENIED) 160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_ERROR_PROMISC_PERM_DENIED; 161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Try to enable multicast. */ 165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = dlpromiscon(p, DL_PROMISC_MULTI); 166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (err < 0) 167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Try to enable SAP promiscuity. */ 171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = dlpromiscon(p, DL_PROMISC_SAP); 172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (err < 0) { 173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Not fatal, since the DL_PROMISC_PHYS mode worked. 175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Report it as a warning, however. 176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.promisc) 178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_WARNING; 179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else 180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Determine link type. */ 184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) { 185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf); 186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_process_mactype(p, dlinfo.di_mactype) != 0) 190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->fd = dlpi_fd(pd->dlpi_hd); 193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Push and configure bufmod. */ 195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_conf_bufmod(p, p->snapshot) != 0) 196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Flush the read side. 200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { 202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", 203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_strerror(errno)); 204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Allocate data buffer. */ 208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_alloc_databuf(p) != 0) 209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; 210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "p->fd" is a FD for a STREAMS device, so "select()" and 213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "poll()" should work on it. 214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->selectable_fd = p->fd; 216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->read_op = pcap_read_libdlpi; 218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->inject_op = pcap_inject_libdlpi; 219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->setfilter_op = install_bpf_program; /* No kernel filtering */ 220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->setdirection_op = NULL; /* Not implemented */ 221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->set_datalink_op = NULL; /* Can't change data link type */ 222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->getnonblock_op = pcap_getnonblock_fd; 223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->setnonblock_op = pcap_setnonblock_fd; 224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->stats_op = pcap_stats_dlpi; 225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->cleanup_op = pcap_cleanup_libdlpi; 226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (0); 228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallbad: 229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_cleanup_libdlpi(p); 230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (err); 231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define STRINGIFY(n) #n 234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldlpromiscon(pcap_t *p, bpf_u_int32 level) 237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv; 240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int err; 241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = dlpi_promiscon(pd->dlpi_hd, level); 243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv != DLPI_SUCCESS) { 244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv == DL_SYSERR && 245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (errno == EPERM || errno == EACCES)) 246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_ERROR_PERM_DENIED; 247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else 248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall err = PCAP_ERROR; 249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_libdlpi_err(p->opt.source, "dlpi_promiscon" STRINGIFY(level), 250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv, p->errbuf); 251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (err); 252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (0); 254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find 258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * network links that are plumbed and are up. dlpi_walk(3DLPI) will find 259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * additional network links present in the system. 260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv = 0; 265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linknamelist_t *entry, *next; 267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall linkwalk_t lw = {NULL, 0}; 268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int save_errno; 269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* dlpi_walk() for loopback will be added here. */ 271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dlpi_walk(list_interfaces, &lw, 0); 273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (lw.lw_err != 0) { 275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(errbuf, PCAP_ERRBUF_SIZE, 276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "dlpi_walk: %s", pcap_strerror(lw.lw_err)); 277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = -1; 278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto done; 279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Add linkname if it does not exist on the list. */ 282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (entry = lw.lw_list; entry != NULL; entry = entry->lnl_next) { 283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_add_if(alldevsp, entry->linkname, 0, NULL, errbuf) < 0) 284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = -1; 285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldone: 287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall save_errno = errno; 288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (entry = lw.lw_list; entry != NULL; entry = next) { 289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall next = entry->lnl_next; 290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(entry); 291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall errno = save_errno; 293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (retv); 295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Read data received on DLPI handle. Returns -2 if told to terminate, else 299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * returns the number of packets read. 300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user) 303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int len; 306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_char *bufp; 307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall size_t msglen; 308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv; 309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall len = p->cc; 311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (len != 0) { 312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bufp = p->bp; 313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto process_pkts; 314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall do { 316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Has "pcap_breakloop()" been called? */ 317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->break_loop) { 318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Yes - clear the flag that indicates that it has, 320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * and return -2 to indicate that we were told to 321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * break out of the loop. 322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->break_loop = 0; 324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-2); 325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall msglen = p->bufsize; 328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bufp = p->buffer + p->offset; 329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp, 331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall &msglen, -1, NULL); 332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv != DLPI_SUCCESS) { 333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is most likely a call to terminate out of the 335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * loop. So, do not return an error message, instead 336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * check if "pcap_breakloop()" has been called above. 337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv == DL_SYSERR && errno == EINTR) { 339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall len = 0; 340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_libdlpi_err(dlpi_linkname(pd->dlpi_hd), 343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "dlpi_recv", retv, p->errbuf); 344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall len = msglen; 347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } while (len == 0); 348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallprocess_pkts: 350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (pcap_process_pkts(p, callback, user, count, bufp, len)); 351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_inject_libdlpi(pcap_t *p, const void *buf, size_t size) 355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv; 358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = dlpi_send(pd->dlpi_hd, NULL, 0, buf, size, NULL); 360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (retv != DLPI_SUCCESS) { 361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_libdlpi_err(dlpi_linkname(pd->dlpi_hd), "dlpi_send", retv, 362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->errbuf); 363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * dlpi_send(3DLPI) does not provide a way to return the number of 367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * bytes sent on the wire. Based on the fact that DLPI_SUCCESS was 368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * returned we are assuming 'size' bytes were sent. 369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (size); 371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Close dlpi handle. 375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_cleanup_libdlpi(pcap_t *p) 378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pd->dlpi_hd != NULL) { 382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dlpi_close(pd->dlpi_hd); 383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pd->dlpi_hd = NULL; 384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->fd = -1; 385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_cleanup_live_common(p); 387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Write error message to buffer. 391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf) 394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s", 396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall func, linkname, dlpi_strerror(err)); 397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_t * 400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_create_interface(const char *device, char *ebuf) 401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_t *p; 403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi)); 405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p == NULL) 406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (NULL); 407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->activate_op = pcap_activate_libdlpi; 409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (p); 410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 411