Network cleanup, updated pcap_if to have a sniffer, PCAP now works properly. Removed all Slirp warnings.

This commit is contained in:
waltje
2017-05-09 22:09:55 -04:00
parent 645ade52b1
commit b975839b41
9 changed files with 2081 additions and 1936 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,17 @@
/* Copyright holders: SA1988 /*
see COPYING for more details * 86Box A hypervisor and IBM PC system emulator that specializes in
*/ * running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the NE2000 ethernet controller.
*
* Version: @(#)net_ne2000.h 1.0.1 2017/05/09
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
#ifndef NET_NE2000_H #ifndef NET_NE2000_H
# define NET_NE2000_H # define NET_NE2000_H
@@ -10,10 +21,10 @@ extern device_t rtl8029as_device;
extern void ne2000_generate_maclocal(uint32_t mac); extern void ne2000_generate_maclocal(uint32_t mac);
extern uint32_t net2000_get_maclocal(void); extern uint32_t ne2000_get_maclocal(void);
extern void ne2000_generate_maclocal_pci(uint32_t mac); extern void ne2000_generate_maclocal_pci(uint32_t mac);
extern uint32_t net2000_get_maclocal_pci(void); extern uint32_t ne2000_get_maclocal_pci(void);
#endif /*NET_NE2000_H*/ #endif /*NET_NE2000_H*/

View File

@@ -1,16 +1,27 @@
/* Copyright holders: Sarah Walker, Tenshi /*
see COPYING for more details * 86Box A hypervisor and IBM PC system emulator that specializes in
*/ * running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the network module.
*
* Version: @(#)network.c 1.0.1 2017/05/09
*
* Authors: Kotori, <oubattler@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*/
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "ibm.h" #include "ibm.h"
#include "device.h" #include "device.h"
#include "network.h"
#include "timer.h" #include "timer.h"
#include "thread.h" #include "thread.h"
#include "network.h"
#include "net_ne2000.h" #include "net_ne2000.h"
@@ -21,14 +32,13 @@ typedef struct {
} NETCARD; } NETCARD;
typedef struct { typedef struct {
void (*poller)(void *p); void (*poller)(void *);
void *priv; void *priv;
} NETPOLL; } NETPOLL;
static int net_handlers_num; static int net_handlers_num;
static int net_card_last = 0; static uint32_t net_poll_time = 100;
static uint32_t net_poll_time = 0;
static NETPOLL net_handlers[8]; static NETPOLL net_handlers[8];
static NETCARD net_cards[] = { static NETCARD net_cards[] = {
{ "None", "none", NULL }, { "None", "none", NULL },
@@ -37,8 +47,8 @@ static NETCARD net_cards[] = {
{ "", "", NULL } { "", "", NULL }
}; };
int network_card_current = 0;
int network_card_current = 0;
uint8_t ethif; uint8_t ethif;
int inum; int inum;
@@ -65,24 +75,12 @@ net_poll(void *priv)
void void
network_init(void) network_init(void)
{ {
if (net_cards[network_card_current].device) /* No network interface right now. */
device_add(net_cards[network_card_current].device); network_card_current = 0;
net_handlers_num = 0;
net_card_last = network_card_current; /* This should be a config value, really. --FvK */
net_poll_time = 100;
if (network_card_current != 0) {
network_reset();
}
}
/* Add a handler for a network card. */
void
network_add_handler(void (*poller)(void *p), void *p)
{
net_handlers[net_handlers_num].poller = poller;
net_handlers[net_handlers_num].priv = p;
net_handlers_num++;
} }
@@ -90,15 +88,28 @@ network_add_handler(void (*poller)(void *p), void *p)
void void
network_reset(void) network_reset(void)
{ {
pclog("network_reset()\n"); pclog("NETWORK: reset (card=%d)\n", network_card_current);
net_handlers_num = 0; if (! network_card_current) return;
if (network_card_current) { if (net_cards[network_card_current].device) {
pclog("NETWORK: adding timer...\n"); pclog("NETWORK: adding device '%s'\n",
net_cards[network_card_current].name);
timer_add(net_poll, &net_poll_time, TIMER_ALWAYS_ENABLED, NULL); device_add(net_cards[network_card_current].device);
} }
pclog("NETWORK: adding timer...\n");
timer_add(net_poll, &net_poll_time, TIMER_ALWAYS_ENABLED, NULL);
}
/* Add a handler for a network card. */
void
network_add_handler(void (*poller)(void *), void *p)
{
net_handlers[net_handlers_num].poller = poller;
net_handlers[net_handlers_num].priv = p;
net_handlers_num++;
} }

View File

@@ -1,6 +1,18 @@
/* Copyright holders: Sarah Walker, Tenshi /*
see COPYING for more details * 86Box A hypervisor and IBM PC system emulator that specializes in
*/ * running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the network module.
*
* Version: @(#)network.h 1.0.1 2017/05/09
*
* Authors: Kotori, <oubattler@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*/
#ifndef NETWORK_H #ifndef NETWORK_H
# define NETWORK_H # define NETWORK_H
# include <stdint.h> # include <stdint.h>
@@ -10,10 +22,9 @@
#define RTL8029AS 2 #define RTL8029AS 2
extern int network_card_current; extern int network_card_current;
extern uint8_t ethif;
extern uint8_t ethif; extern int inum;
extern int inum;
extern void network_init(void); extern void network_init(void);

View File

@@ -319,9 +319,12 @@ void initpc(int argc, wchar_t *argv[])
} }
} }
/* Initialize modules. */
network_init();
mouse_init(); mouse_init();
midi_init(); midi_init();
serial_init(); serial_init();
disc_random_init();
if (config_file == NULL) if (config_file == NULL)
{ {
@@ -332,8 +335,6 @@ void initpc(int argc, wchar_t *argv[])
append_filename_w(config_file_default, pcempath, config_file, 511); append_filename_w(config_file_default, pcempath, config_file, 511);
} }
disc_random_init();
loadconfig(config_file); loadconfig(config_file);
pclog("Config loaded\n"); pclog("Config loaded\n");
if (config_file) if (config_file)
@@ -488,8 +489,6 @@ void resetpchard(void)
ide_qua_init(); ide_qua_init();
} }
network_init();
for (i = 0; i < CDROM_NUM; i++) for (i = 0; i < CDROM_NUM; i++)
{ {
if (cdrom_drives[i].bus_type) if (cdrom_drives[i].bus_type)
@@ -498,6 +497,7 @@ void resetpchard(void)
} }
} }
network_reset();
resetide(); resetide();
scsi_card_init(); scsi_card_init();

View File

@@ -6,51 +6,218 @@
* *
* This file is part of the 86Box distribution. * This file is part of the 86Box distribution.
* *
* Simple program to show usable interfaces for WinPcap. * Simple program to show usage of WinPcap.
* *
* Based on the "libpcap" example. * Based on the "libpcap" examples.
* *
* Version: @(#)pcap_if.c 1.0.1 2017/05/08 * Version: @(#)pcap_if.c 1.0.2 2017/05/09
* *
* Author: Fred N. van Kempen, <decwiz@yahoo.com> * Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h>
#include <pcap.h> #include <pcap.h>
typedef struct {
char device[128];
char description[128];
} dev_t;
/* Retrieve an easy-to-use list of devices. */
static int
get_devlist(dev_t *list)
{
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist, *dev;
int i = 0;
/* Retrieve the device list from the local machine */
if (pcap_findalldevs(&devlist, errbuf) == -1) {
fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
return(-1);
}
for (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. */
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("%04x %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;
struct tm *ltime;
time_t now;
pcap_t *pcap;
int rc;
/* Open the device for reading from it. */
pcap = 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 = 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,%.6d len=%d\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. */
pcap_close(pcap);
return(0);
}
/* Show a list of available network interfaces. */
static void
show_devs(dev_t *list, int num)
{
int i;
if (num > 0) {
printf("Available network interfaces:\n\n");
for (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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char errbuf[PCAP_ERRBUF_SIZE]; dev_t interfaces[32];
pcap_if_t *alldevs; dev_t *dev = interfaces;
pcap_if_t *d; int numdev, i;
int i=0;
/* Get the list. */
/* Retrieve the device list from the local machine */ numdev = get_devlist(interfaces);
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); if (argc == 1) {
exit(1); /* No arguments, just show the list. */
} show_devs(interfaces, numdev);
/* Print the list */ return(numdev);
for (d= alldevs; d != NULL; d= d->next) {
printf("%d. %s\n", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
printf("\n");
i++;
}
if (i == 0) {
printf("No interfaces found! Make sure WinPcap is installed.\n");
return(i);
} }
/* Not really needed as we are about to exit, but oh-well. */ /* Assume argument to be the interface number to listen on. */
pcap_freealldevs(alldevs); i = atoi(argv[1]);
if (i < 0 || i > numdev) {
fprintf(stderr, "Invalid interface number %d !\n", i);
return(1);
}
/* Looks good, go and listen.. */
i = start_cap(interfaces[i-1].device);
return(i); return(i);
} }

View File

@@ -91,14 +91,14 @@ getouraddr()
char buff[512]; char buff[512];
struct hostent *he = NULL; struct hostent *he = NULL;
#define ANCIENT #define ANCIENT
#ifdef ANCIENT #ifdef ANCIENT
if (gethostname(buff,500) == 0) if (gethostname(buff,500) == 0)
he = gethostbyname(buff); he = gethostbyname(buff);
if (he) if (he)
our_addr = *(struct in_addr *)he->h_addr; our_addr = *(struct in_addr *)he->h_addr;
if (our_addr.s_addr == 0) if (our_addr.s_addr == 0)
our_addr.s_addr = loopback_addr.s_addr; our_addr.s_addr = loopback_addr.s_addr;
#else #else
if (gethostname(buff,256) == 0) if (gethostname(buff,256) == 0)
{ {
struct addrinfo hints = { 0 }; struct addrinfo hints = { 0 };
@@ -113,8 +113,9 @@ getouraddr()
} }
if (our_addr.s_addr == 0) if (our_addr.s_addr == 0)
our_addr.s_addr = loopback_addr.s_addr; our_addr.s_addr = loopback_addr.s_addr;
#endif #endif
#undef ANCIENT #undef ANCIENT
pclog("My IP address: %s (%s)\n", inet_ntoa(our_addr), buff);
} }
//#if SIZEOF_CHAR_P == 8 //#if SIZEOF_CHAR_P == 8

View File

@@ -36,7 +36,6 @@ extern int config_get_int(char *, char *, int);
#ifdef _WIN32 #ifdef _WIN32
static int get_dns_addr(struct in_addr *pdns_addr) static int get_dns_addr(struct in_addr *pdns_addr)
{ {
FIXED_INFO *FixedInfo=NULL; FIXED_INFO *FixedInfo=NULL;
@@ -68,7 +67,7 @@ static int get_dns_addr(struct in_addr *pdns_addr)
pIPAddr = &(FixedInfo->DnsServerList); pIPAddr = &(FixedInfo->DnsServerList);
inet_aton(pIPAddr->IpAddress.String, &tmp_addr); inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
*pdns_addr = tmp_addr; *pdns_addr = tmp_addr;
#if 0 #if 1
printf( "DNS Servers:\n" ); printf( "DNS Servers:\n" );
printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
@@ -123,9 +122,9 @@ static int get_dns_addr(struct in_addr *pdns_addr)
return -1; return -1;
return 0; return 0;
} }
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
void slirp_cleanup(void) void slirp_cleanup(void)
{ {
@@ -649,6 +648,7 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
struct SLIRPmbuf *m; struct SLIRPmbuf *m;
int proto; int proto;
pclog("SLIRP_input(%08lx, %d)\n", pkt, pkt_len);
if (pkt_len < ETH_HLEN) if (pkt_len < ETH_HLEN)
return; return;

View File

@@ -1,6 +1,8 @@
#ifndef __COMMON_H__ #ifndef __COMMON_H__
#define __COMMON_H__ #define __COMMON_H__
#define SLIRP_DEBUG 1
#define SLIRP_VERSION "Cockatrice special" #define SLIRP_VERSION "Cockatrice special"
#define CONFIG_QEMU #define CONFIG_QEMU