diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c deleted file mode 100644 index 1d3e39221..000000000 --- a/src/network/pcap_if.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * Simple program to show usage of (Win)Pcap. - * - * Based on the "libpcap" examples. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> - -static void *pcap_handle; /* handle to WinPcap DLL */ - -/* Pointers to the real functions. */ -static int (*f_pcap_findalldevs)(pcap_if_t **, char *); -static void (*f_pcap_freealldevs)(pcap_if_t *); -static pcap_t *(*f_pcap_open_live)(const char *, int, int, int, char *); -static int (*f_pcap_next_ex)(pcap_t *, struct pcap_pkthdr **, const unsigned char **); -static void (*f_pcap_close)(pcap_t *); -static dllimp_t pcap_imports[] = { - // clang-format off - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_next_ex", &f_pcap_next_ex }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, - // clang-format on -}; - -typedef struct { - char device[128]; - char description[128]; -} capdev_t; - -/* Retrieve an easy-to-use list of devices. */ -static int -get_devlist(capdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *devlist; - int i = 0; - - /* Retrieve the device list from the local machine */ - if (f_pcap_findalldevs(&devlist, errbuf) == -1) { - fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf); - return (-1); - } - - for (pcap_if_t *dev = devlist; dev != NULL; dev = dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; - i++; - } - - /* Release the memory. */ - f_pcap_freealldevs(devlist); - - return i; -} - -/* Simple HEXDUMP routine for raw data. */ -static void -hex_dump(unsigned char *bufp, int len) -{ - char asci[20]; - unsigned char c; - long addr; - - addr = 0; - while (len-- > 0) { - c = bufp[addr]; - if ((addr % 16) == 0) - printf("%04lx %02x", addr, c); - else - printf(" %02x", c); - asci[addr & 15] = (uint8_t) isprint(c) ? c : '.'; - if ((++addr % 16) == 0) { - asci[16] = '\0'; - printf(" | %s |\n", asci); - } - } - - if (addr % 16) { - while (addr % 16) { - printf(" "); - asci[addr & 15] = ' '; - addr++; - } - asci[16] = '\0'; - printf(" | %s |\n", asci); - } -} - -/* Print a standard Ethernet MAC address. */ -static void -eth_praddr(unsigned char *ptr) -{ - printf("%02x:%02x:%02x:%02x:%02x:%02x", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); -} - -/* Print a standard Ethernet header. */ -static int -eth_prhdr(unsigned char *ptr) -{ - unsigned short type; - - printf("Ethernet "); - eth_praddr(ptr + 6); - printf(" > "); - eth_praddr(ptr); - type = (ptr[12] << 8) | ptr[13]; - printf(" type %04x\n", type); - - return 14; -} - -/* Capture packets from the network, and print them. */ -static int -start_cap(char *dev) -{ - char temp[PCAP_ERRBUF_SIZE]; - struct pcap_pkthdr *hdr; - const unsigned char *pkt; - const struct tm *ltime; - time_t now; - pcap_t *pcap; - int rc; - - /* Open the device for reading from it. */ - pcap = f_pcap_open_live(dev, - 1518, /* MTU */ - 1, /* promisc mode */ - 10, /* timeout */ - temp); - if (pcap == NULL) { - fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); - return 2; - } - - printf("Listening on '%s'..\n", dev); - for (;;) { - rc = f_pcap_next_ex(pcap, &hdr, &pkt); - if (rc < 0) - break; - - /* Did we time out? */ - if (rc == 0) - continue; - - /* Convert the timestamp to readable format. */ - now = hdr->ts.tv_sec; - ltime = localtime(&now); - strftime(temp, sizeof(temp), "%H:%M:%S", ltime); - - /* Process and print the packet. */ - printf("\n<< %s,%.6ld len=%u\n", - temp, hdr->ts.tv_usec, hdr->len); - rc = eth_prhdr((unsigned char *) pkt); - hex_dump((unsigned char *) pkt + rc, hdr->len - rc); - } - - /* All done, close up. */ - f_pcap_close(pcap); - - return 0; -} - -/* Show a list of available network interfaces. */ -static void -show_devs(capdev_t *list, int num) -{ - if (num > 0) { - printf("Available network interfaces:\n\n"); - - for (int i = 0; i < num; i++) { - printf(" %d - %s\n", i + 1, list->device); - if (list->description[0] != '\0') - printf(" (%s)\n", list->description); - else - printf(" (No description available)\n"); - list++; - printf("\n"); - } - } else { - printf("No interfaces found!\nMake sure WinPcap is installed.\n"); - } -} - -int -main(int argc, char **argv) -{ - capdev_t interfaces[32]; - int numdev; - int i; - - /* Try loading the DLL. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#elif defined __APPLE__ - pcap_handle = dynld_module("libpcap.dylib", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) { -#ifdef _WIN32 - fprintf(stderr, "Unable to load WinPcap DLL !\n"); -#else - fprintf(stderr, "Unable to load libpcap.so !\n"); -#endif - return 1; - } - - /* Get the list. */ - numdev = get_devlist(interfaces); - - if (argc == 1) { - /* No arguments, just show the list. */ - show_devs(interfaces, numdev); - - dynld_close(pcap_handle); - - return numdev; - } - - /* Assume argument to be the interface number to listen on. */ - i = atoi(argv[1]); - if (i < 0 || i > numdev) { - fprintf(stderr, "Invalid interface number %d !\n", i); - - dynld_close(pcap_handle); - - return 1; - } - - /* Looks good, go and listen.. */ - i = start_cap(interfaces[i - 1].device); - - dynld_close(pcap_handle); - - return i; -}