static int pcap_setuserbuffer_win32(pcap_t *p, int size) { unsigned char *new_buff; if (size<=0) { /* Bogus parameter */ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error: invalid size %d",size); return (-1); } /* Allocate the buffer */ new_buff=(unsigned char*)malloc(sizeof(char)*size); if (!new_buff) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error: not enough memory"); return (-1); } free(p->buffer); p->buffer=new_buff; p->bufsize=size; return (0); }
static int pcap_live_dump_win32(pcap_t *p, char *filename, int maxsize, int maxpacks) { struct pcap_win *pw = p->priv; BOOLEAN res; /* Set the packet driver in dump mode */ res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP); if(res == FALSE){ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error setting dump mode"); return (-1); } /* Set the name of the dump file */ res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename)); if(res == FALSE){ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error setting kernel dump file name"); return (-1); } /* Set the limits of the dump file */ res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks); if(res == FALSE) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error setting dump limit"); return (-1); } return (0); }
/* * \brief Checks that the address, port and flags given are valids and it returns an 'addrinfo' structure. * * This function basically calls the getaddrinfo() calls, and it performs a set of sanity checks * to control that everything is fine (e.g. a TCP socket cannot have a mcast address, and such). * If an error occurs, it writes the error message into 'errbuf'. * * \param host: a pointer to a string identifying the host. It can be * a host name, a numeric literal address, or NULL or "" (useful * in case of a server socket which has to bind to all addresses). * * \param port: a pointer to a user-allocated buffer containing the network port to use. * * \param hints: an addrinfo variable (passed by reference) containing the flags needed to create the * addrinfo structure appropriately. * * \param addrinfo: it represents the true returning value. This is a pointer to an addrinfo variable * (passed by reference), which will be allocated by this function and returned back to the caller. * This variable will be used in the next sockets calls. * * \param errbuf: a pointer to an user-allocated buffer that will contain the complete * error message. This buffer has to be at least 'errbuflen' in length. * It can be NULL; in this case the error cannot be printed. * * \param errbuflen: length of the buffer that will contains the error. The error message cannot be * larger than 'errbuflen - 1' because the last char is reserved for the string terminator. * * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned * in the 'errbuf' variable. The addrinfo variable that has to be used in the following sockets calls is * returned into the addrinfo parameter. * * \warning The 'addrinfo' variable has to be deleted by the programmer by calling freeaddrinfo() when * it is no longer needed. * * \warning This function requires the 'hints' variable as parameter. The semantic of this variable is the same * of the one of the corresponding variable used into the standard getaddrinfo() socket function. We suggest * the programmer to look at that function in order to set the 'hints' variable appropriately. */ int sock_initaddress(const char *host, const char *port, struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen) { int retval; retval = getaddrinfo(host, port, hints, addrinfo); if (retval != 0) { /* * if the getaddrinfo() fails, you have to use gai_strerror(), instead of using the standard * error routines (errno) in UNIX; Winsock suggests using the GetLastError() instead. */ if (errbuf) { #ifdef _WIN32 sock_geterror("getaddrinfo(): ", errbuf, errbuflen); #else pcap_snprintf(errbuf, errbuflen, "getaddrinfo() %s", gai_strerror(retval)); #endif } return -1; } /* * \warning SOCKET: I should check all the accept() in order to bind to all addresses in case * addrinfo has more han one pointers */ /* * This software only supports PF_INET and PF_INET6. * * XXX - should we just check that at least *one* address is * either PF_INET or PF_INET6, and, when using the list, * ignore all addresses that are neither? (What, no IPX * support? :-)) */ if (((*addrinfo)->ai_family != PF_INET) && ((*addrinfo)->ai_family != PF_INET6)) { if (errbuf) pcap_snprintf(errbuf, errbuflen, "getaddrinfo(): socket type not supported"); freeaddrinfo(*addrinfo); *addrinfo = NULL; return -1; } /* * You can't do multicast (or broadcast) TCP. */ if (((*addrinfo)->ai_socktype == SOCK_STREAM) && (sock_ismcastaddr((*addrinfo)->ai_addr) == 0)) { if (errbuf) pcap_snprintf(errbuf, errbuflen, "getaddrinfo(): multicast addresses are not valid when using TCP streams"); freeaddrinfo(*addrinfo); *addrinfo = NULL; return -1; } return 0; }
static u_int pcap_sendqueue_transmit_win32(pcap_t *p, pcap_send_queue *queue, int sync) { struct pcap_win *pw = p->priv; u_int res; char errbuf[PCAP_ERRBUF_SIZE+1]; if (pw->adapter==NULL) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot transmit a queue to an offline capture or to a TurboCap port"); return (0); } res = PacketSendPackets(pw->adapter, queue->buffer, queue->len, (BOOLEAN)sync); if(res != queue->len){ pcap_win32_err_to_str(GetLastError(), errbuf); pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", errbuf); } return (res); }
static int TcSetNonBlock(pcap_t *p, int nonblock, char *errbuf) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Setting the non blocking status is not available for TurboCap ports"); pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Setting the non blocking status is not available for TurboCap ports"); return -1; }
static int TcStats(pcap_t *p, struct pcap_stat *ps) { struct pcap_tc *pt = p->priv; TC_STATISTICS statistics; TC_STATUS status; ULONGLONG counter; struct pcap_stat s; status = g_TcFunctions.InstanceQueryStatistics(pt->TcInstance, &statistics); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } memset(&s, 0, sizeof(s)); status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } if (counter <= (ULONGLONG)0xFFFFFFFF) { s.ps_recv = (ULONG)counter; } else { s.ps_recv = 0xFFFFFFFF; } status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } if (counter <= (ULONGLONG)0xFFFFFFFF) { s.ps_ifdrop = (ULONG)counter; s.ps_drop = (ULONG)counter; } else { s.ps_ifdrop = 0xFFFFFFFF; s.ps_drop = 0xFFFFFFFF; } #if defined(_WIN32) && defined(HAVE_REMOTE) s.ps_capt = pt->TcAcceptedCount; #endif *ps = s; return 0; }
static struct pcap_stat * TcStatsEx(pcap_t *p, int *pcap_stat_size) { struct pcap_tc *pt = p->priv; TC_STATISTICS statistics; TC_STATUS status; ULONGLONG counter; *pcap_stat_size = sizeof (p->stat); status = g_TcFunctions.InstanceQueryStatistics(pt->TcInstance, &statistics); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return NULL; } memset(&p->stat, 0, sizeof(p->stat)); status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return NULL; } if (counter <= (ULONGLONG)0xFFFFFFFF) { p->stat.ps_recv = (ULONG)counter; } else { p->stat.ps_recv = 0xFFFFFFFF; } status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return NULL; } if (counter <= (ULONGLONG)0xFFFFFFFF) { p->stat.ps_ifdrop = (ULONG)counter; p->stat.ps_drop = (ULONG)counter; } else { p->stat.ps_ifdrop = 0xFFFFFFFF; p->stat.ps_drop = 0xFFFFFFFF; } #ifdef HAVE_REMOTE p->stat.ps_capt = pt->TcAcceptedCount; #endif return &p->stat; }
int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str) { libusb_context *fdctx; libusb_device** devs; unsigned char sernum[65]; int cnt, i; if (libusb_init(&fdctx) != 0) { /* * XXX - if this doesn't just mean "no USB file system mounted", * perhaps we should report a real error rather than just * saying "no CANUSB devices". */ return 0; } cnt = libusb_get_device_list(fdctx,&devs); for(i=0;i<cnt;i++) { int ret; /* Check if this device is interesting. */ struct libusb_device_descriptor desc; libusb_device_handle *dh; libusb_get_device_descriptor(devs[i],&desc); if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID)) continue; /* It is not, check next device */ /* It is! */ dh = NULL; if ((ret = libusb_open(devs[i],&dh)) == 0) { char dev_name[30]; char dev_descr[50]; int n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,sernum,64); sernum[n] = 0; pcap_snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum); pcap_snprintf(dev_descr, 50, "CanUSB [%s]", sernum); libusb_close(dh); if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0) { libusb_free_device_list(devs,1); libusb_exit(fdctx); return -1; } } } libusb_free_device_list(devs,1); libusb_exit(fdctx); return 0; }
/* Send a packet to the network */ static int TcInject(pcap_t *p, const void *buf, size_t size) { struct pcap_tc *pt = p->priv; TC_STATUS status; TC_PACKETS_BUFFER buffer; TC_PACKET_HEADER header; if (size >= 0xFFFF) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k"); return -1; } status = g_TcFunctions.PacketsBufferCreate(sizeof(TC_PACKET_HEADER) + TC_ALIGN_USHORT_TO_64BIT((USHORT)size), &buffer); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } /* * we assume that the packet is without the checksum, as common with WinPcap */ memset(&header, 0, sizeof(header)); header.Length = (USHORT)size; header.CapturedLength = header.Length; status = g_TcFunctions.PacketsBufferCommitNextPacket(buffer, &header, (PVOID)buf); if (status == TC_SUCCESS) { status = g_TcFunctions.InstanceTransmitPackets(pt->TcInstance, buffer); if (status != TC_SUCCESS) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); } } else { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); } g_TcFunctions.PacketsBufferDestroy(buffer); if (status != TC_SUCCESS) { return -1; } else { return 0; } }
/* without these identifying probes packet data can't be fully decoded */ static void probe_devices(int bus) { struct usbdevfs_ctrltransfer ctrl; struct dirent* data; int ret = 0; char buf[40]; DIR* dir; /* scan usb bus directories for device nodes */ pcap_snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus); dir = opendir(buf); if (!dir) return; while ((ret >= 0) && ((data = readdir(dir)) != 0)) { int fd; char* name = data->d_name; if (name[0] == '.') continue; pcap_snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name); fd = open(buf, O_RDWR); if (fd == -1) continue; /* * Sigh. Different kernels have different member names * for this structure. */ #ifdef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; ctrl.wValue = USB_DT_DEVICE << 8; ctrl.wIndex = 0; ctrl.wLength = sizeof(buf); #else ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ctrl.request = USB_REQ_GET_DESCRIPTOR; ctrl.value = USB_DT_DEVICE << 8; ctrl.index = 0; ctrl.length = sizeof(buf); #endif ctrl.data = buf; ctrl.timeout = CTRL_TIMEOUT; ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl); close(fd); } closedir(dir); }
/* facility to add an USB device to the device list*/ static int usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str) { char dev_name[10]; char dev_descr[30]; pcap_snprintf(dev_name, 10, USB_IFACE"%d", n); pcap_snprintf(dev_descr, 30, "USB bus number %d", n); if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0) return -1; return 0; }
/* Determine ppa number that specifies ifname */ static int get_dlpi_ppa(register int fd, register const char *ifname, register int unit, register char *ebuf) { register const char *cp; register int kd; void *addr; struct ifnet ifnet; char if_name[sizeof(ifnet.if_name) + 1]; cp = strrchr(ifname, '/'); if (cp != NULL) ifname = cp + 1; if (nlist(path_vmunix, &nl) < 0) { pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", path_vmunix); return (-1); } if (nl[NL_IFNET].n_value == 0) { pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "could't find %s kernel symbol", nl[NL_IFNET].n_name); return (-1); } kd = open("/dev/kmem", O_RDONLY); if (kd < 0) { pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s", pcap_strerror(errno)); return (-1); } if (dlpi_kread(kd, nl[NL_IFNET].n_value, &addr, sizeof(addr), ebuf) < 0) { close(kd); return (-1); } for (; addr != NULL; addr = ifnet.if_next) { if (dlpi_kread(kd, (off_t)addr, &ifnet, sizeof(ifnet), ebuf) < 0 || dlpi_kread(kd, (off_t)ifnet.if_name, if_name, sizeof(ifnet.if_name), ebuf) < 0) { (void)close(kd); return (-1); } if_name[sizeof(ifnet.if_name)] = '\0'; if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) return (ifnet.if_index); } pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); return (-1); }
int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */ FILE *fp; char buf[MAX_LINE_SIZE]; char *ptr, *ptr2; int pos; int chassis, geoslot; unit_t *u; empty_unit_table(); if ((fp = fopen("/etc/hosts", "r")) == NULL) { /* try to open the hosts file and if it fails */ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */ return -1; } while (fgets(buf, MAX_LINE_SIZE-1, fp)) { /* while looping over the file */ pos = strcspn(buf, "#\n\r"); /* find the first comment character or EOL */ *(buf + pos) = '\0'; /* and clobber it and anything that follows it */ pos = strspn(buf, " \t"); /* then find the first non-white space */ if (pos == strlen(buf)) /* if there is nothing but white space on the line */ continue; /* ignore that empty line */ ptr = buf + pos; /* and skip over any of that leading whitespace */ if ((ptr2 = strstr(ptr, "_I_")) == NULL) /* skip any lines that don't have names that look like they belong to IOPs */ continue; if (*(ptr2 + 4) != '_') /* and skip other lines that have names that don't look like ACN components */ continue; *(ptr + strcspn(ptr, " \t")) = '\0'; /* null terminate the IP address so its a standalone string */ chassis = *(ptr2 + 3) - '0'; /* extract the chassis number */ geoslot = *(ptr2 + 5) - '0'; /* and geo-slot number */ if (chassis < 1 || chassis > MAX_CHASSIS || geoslot < 1 || geoslot > MAX_GEOSLOT) { /* if the chassis and/or slot numbers appear to be bad... */ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */ continue; /* and ignore the entry */ } if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) { pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno, "malloc"); continue; } strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */ u = &units[chassis][geoslot]; u->ip = ptr2; /* and remember the whole shebang */ u->chassis = chassis; u->geoslot = geoslot; } fclose(fp); if (*errbuf) return -1; else return 0; }
static int dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) { struct pcap_dbus *handlep = handle->priv; struct pcap_pkthdr pkth; DBusMessage *message; char *raw_msg; int raw_msg_len; int count = 0; message = dbus_connection_pop_message(handlep->conn); while (!message) { /* XXX handle->opt.timeout = timeout_ms; */ if (!dbus_connection_read_write(handlep->conn, 100)) { pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed"); return -1; } if (handle->break_loop) { handle->break_loop = 0; return -2; } message = dbus_connection_pop_message(handlep->conn); } if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected"); return -1; } if (dbus_message_marshal(message, &raw_msg, &raw_msg_len)) { pkth.caplen = pkth.len = raw_msg_len; /* pkth.caplen = min (payload_len, handle->snapshot); */ gettimeofday(&pkth.ts, NULL); if (handle->fcode.bf_insns == NULL || bpf_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, (u_char *)raw_msg); count++; } dbus_free(raw_msg); } return count; }
int pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) { #ifdef HAVE_SOLARIS int fd; union { u_int nunits; char pad[516]; /* XXX - must be at least 513; is 516 in "atmgetunits" */ } buf; char baname[2+1+1]; u_int i; #endif /* * Get the list of regular interfaces first. */ if (pcap_findalldevs_interfaces(devlistp, errbuf, is_dlpi_interface) == -1) return (-1); /* failure */ #ifdef HAVE_SOLARIS /* * We may have to do special magic to get ATM devices. */ if ((fd = open("/dev/ba", O_RDWR)) < 0) { /* * We couldn't open the "ba" device. * For now, just give up; perhaps we should * return an error if the problem is neither * a "that device doesn't exist" error (ENOENT, * ENXIO, etc.) or a "you're not allowed to do * that" error (EPERM, EACCES). */ return (0); } if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s", pcap_strerror(errno)); return (-1); } for (i = 0; i < buf.nunits; i++) { pcap_snprintf(baname, sizeof baname, "ba%u", i); if (add_dev(devlistp, baname, 0, NULL, errbuf) == NULL) return (-1); } #endif return (0); }
/* facility to add an USB device to the device list*/ static int usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str) { char dev_name[10]; char dev_descr[30]; pcap_snprintf(dev_name, 10, USB_IFACE"%d", n); if (n == 0) pcap_snprintf(dev_descr, 30, "All USB buses"); else pcap_snprintf(dev_descr, 30, "USB bus number %d", n); if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL) return -1; return 0; }
/* * In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find * network links that are plumbed and are up. dlpi_walk(3DLPI) will find * additional network links present in the system. */ int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) { int retv = 0; linknamelist_t *entry, *next; linkwalk_t lw = {NULL, 0}; int save_errno; /* dlpi_walk() for loopback will be added here. */ dlpi_walk(list_interfaces, &lw, 0); if (lw.lw_err != 0) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dlpi_walk: %s", pcap_strerror(lw.lw_err)); retv = -1; goto done; } /* Add linkname if it does not exist on the list. */ for (entry = lw.lw_list; entry != NULL; entry = entry->lnl_next) { if (pcap_add_if(alldevsp, entry->linkname, 0, NULL, errbuf) < 0) retv = -1; } done: save_errno = errno; for (entry = lw.lw_list; entry != NULL; entry = next) { next = entry->lnl_next; free(entry); } errno = save_errno; return (retv); }
static pcap_dumper_t * pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname) { #if defined(_WIN32) || defined(MSDOS) /* * If we're writing to the standard output, put it in binary * mode, as savefiles are binary files. * * Otherwise, we turn off buffering. * XXX - why? And why not on the standard output? */ if (f == stdout) SET_BINMODE(f); else setbuf(f, NULL); #endif if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s", fname, pcap_strerror(errno)); if (f != stdout) (void)fclose(f); return (NULL); } return ((pcap_dumper_t *)f); }
static HANDLE sf_getevent(pcap_t *pcap) { (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), "The read event cannot be retrieved while reading from a file"); return (INVALID_HANDLE_VALUE); }
static int sf_setmintocopy(pcap_t *p, int size) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The mintocopy parameter cannot be set while reading from a file"); return (-1); }
static int sf_setmode(pcap_t *p, int mode) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file"); return (-1); }
static int sf_setbuff(pcap_t *p, int dim) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file"); return (-1); }
static struct pcap_stat * sf_stats_ex(pcap_t *p, int *size) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Statistics aren't available from savefiles"); return (NULL); }
/* * Win32-only routine for getting statistics. * * This way is definitely safer than passing the pcap_stat * from the userland. * In fact, there could happen than the user allocates a variable which is not * big enough for the new structure, and the library will write in a zone * which is not allocated to this variable. * * In this way, we're pretty sure we are writing on memory allocated to this * variable. * * XXX - but this is the wrong way to handle statistics. Instead, we should * have an API that returns data in a form like the Options section of a * pcapng Interface Statistics Block: * * http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6 * * which would let us add new statistics straightforwardly and indicate which * statistics we are and are *not* providing, rather than having to provide * possibly-bogus values for statistics we can't provide. */ struct pcap_stat * pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size) { struct pcap_win *pw = p->priv; struct bpf_stat bstats; char errbuf[PCAP_ERRBUF_SIZE+1]; *pcap_stat_size = sizeof (p->stat); /* * Try to get statistics. * * (Please note - "struct pcap_stat" is *not* the same as * WinPcap's "struct bpf_stat". It might currently have the * same layout, but let's not cheat.) */ if (!PacketGetStatsEx(pw->adapter, &bstats)) { pcap_win32_err_to_str(GetLastError(), errbuf); pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStatsEx error: %s", errbuf); return (NULL); } p->stat.ps_recv = bstats.bs_recv; p->stat.ps_drop = bstats.bs_drop; p->stat.ps_ifdrop = bstats.ps_ifdrop; #ifdef ENABLE_REMOTE p->stat.ps_capt = bstats.bs_capt; #endif return (&p->stat); }
static void * get_from_block_data(struct block_cursor *cursor, size_t chunk_size, char *errbuf) { void *data; /* * Make sure we have the specified amount of data remaining in * the block data. */ if (cursor->data_remaining < chunk_size) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "block of type %u in pcap-ng dump file is too short", cursor->block_type); return (NULL); } /* * Return the current pointer, and skip past the chunk. */ data = cursor->data; cursor->data += chunk_size; cursor->data_remaining -= chunk_size; return (data); }
static int usb_inject_linux(pcap_t *handle, const void *buf, size_t size) { pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on " "USB devices"); return (-1); }
/* * \brief It translates an address from the 'presentation' form into the 'network' form. * * This function basically replaces inet_pton(), which does not exist in Winsock because * the same result can be obtained by using the getaddrinfo(). * An additional advantage is that 'Address' can be both a numeric address (e.g. '127.0.0.1', * like in inet_pton() ) and a literal name (e.g. 'localhost'). * * This function does the reverse job of sock_getascii_addrport(). * * \param address: a zero-terminated string which contains the name you have to * translate. The name can be either literal (e.g. 'localhost') or numeric (e.g. '::1'). * * \param sockaddr: a user-allocated sockaddr_storage structure which will contains the * 'network' form of the requested address. * * \param addr_family: a constant which can assume the following values: * - 'AF_INET' if we want to ping an IPv4 host * - 'AF_INET6' if we want to ping an IPv6 host * - 'AF_UNSPEC' if we do not have preferences about the protocol used to ping the host * * \param errbuf: a pointer to an user-allocated buffer that will contain the complete * error message. This buffer has to be at least 'errbuflen' in length. * It can be NULL; in this case the error cannot be printed. * * \param errbuflen: length of the buffer that will contains the error. The error message cannot be * larger than 'errbuflen - 1' because the last char is reserved for the string terminator. * * \return '-1' if the translation succeeded, '-2' if there was some non critical error, '0' * otherwise. In case it fails, the content of the SockAddr variable remains unchanged. * A 'non critical error' can occur in case the 'Address' is a literal name, which can be mapped * to several network addresses (e.g. 'foo.bar.com' => '10.2.2.2' and '10.2.2.3'). In this case * the content of the SockAddr parameter will be the address corresponding to the first mapping. * * \warning The sockaddr_storage structure MUST be allocated by the user. */ int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen) { int retval; struct addrinfo *addrinfo; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = addr_family; if ((retval = sock_initaddress(address, "22222" /* fake port */, &hints, &addrinfo, errbuf, errbuflen)) == -1) return 0; if (addrinfo->ai_family == PF_INET) memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in)); else memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in6)); if (addrinfo->ai_next != NULL) { freeaddrinfo(addrinfo); if (errbuf) pcap_snprintf(errbuf, errbuflen, "More than one socket requested; using the first one returned"); return -2; } freeaddrinfo(addrinfo); return -1; }
static int sf_stats(pcap_t *p, struct pcap_stat *ps) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Statistics aren't available from savefiles"); return (-1); }
/* * Attempts to open a regular interface fail. */ pcap_t * pcap_create_interface(const char *device, char *errbuf) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "This version of libpcap only supports SNF cards"); return NULL; }
static int pcap_oid_get_request_win32(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp) { struct pcap_win *pw = p->priv; PACKET_OID_DATA *oid_data_arg; char errbuf[PCAP_ERRBUF_SIZE+1]; /* * Allocate a PACKET_OID_DATA structure to hand to PacketRequest(). * It should be big enough to hold "*lenp" bytes of data; it * will actually be slightly larger, as PACKET_OID_DATA has a * 1-byte data array at the end, standing in for the variable-length * data that's actually there. */ oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp); if (oid_data_arg == NULL) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Couldn't allocate argument buffer for PacketRequest"); return (PCAP_ERROR); } /* * No need to copy the data - we're doing a fetch. */ oid_data_arg->Oid = oid; oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */ if (!PacketRequest(pw->adapter, FALSE, oid_data_arg)) { pcap_win32_err_to_str(GetLastError(), errbuf); pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error calling PacketRequest: %s", errbuf); free(oid_data_arg); return (PCAP_ERROR); } /* * Get the length actually supplied. */ *lenp = oid_data_arg->Length; /* * Copy back the data we fetched. */ memcpy(data, oid_data_arg->Data, *lenp); free(oid_data_arg); return (0); }