Add network debugging feature to dump all packets to a .pcap file when logging is enabled
This commit is contained in:
@@ -54,6 +54,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#define HAVE_STDARG_H
|
#define HAVE_STDARG_H
|
||||||
#include <86box/86box.h>
|
#include <86box/86box.h>
|
||||||
#include <86box/device.h>
|
#include <86box/device.h>
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
#include <86box/net_3c503.h>
|
#include <86box/net_3c503.h>
|
||||||
#include <86box/net_ne2000.h>
|
#include <86box/net_ne2000.h>
|
||||||
#include <86box/net_pcnet.h>
|
#include <86box/net_pcnet.h>
|
||||||
|
#include <86box/net_plip.h>
|
||||||
#include <86box/net_wd8003.h>
|
#include <86box/net_wd8003.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -88,6 +90,8 @@ static netcard_t net_cards[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
{ "[ISA] Western Digital WD8013EBT","wd8013ebt", &wd8013ebt_device,
|
{ "[ISA] Western Digital WD8013EBT","wd8013ebt", &wd8013ebt_device,
|
||||||
NULL },
|
NULL },
|
||||||
|
{ "[LPT] PLIP", "plip", &plip_device,
|
||||||
|
NULL },
|
||||||
{ "[MCA] NetWorth Ethernet/MC", "ethernextmc", ðernext_mc_device,
|
{ "[MCA] NetWorth Ethernet/MC", "ethernextmc", ðernext_mc_device,
|
||||||
NULL },
|
NULL },
|
||||||
{ "[MCA] Western Digital WD8003ET/A","wd8003eta", &wd8003eta_device,
|
{ "[MCA] Western Digital WD8003ET/A","wd8003eta", &wd8003eta_device,
|
||||||
@@ -113,6 +117,7 @@ int network_ndev;
|
|||||||
int network_card;
|
int network_card;
|
||||||
char network_host[522];
|
char network_host[522];
|
||||||
netdev_t network_devs[32];
|
netdev_t network_devs[32];
|
||||||
|
int network_rx_pause = 0;
|
||||||
#ifdef ENABLE_NIC_LOG
|
#ifdef ENABLE_NIC_LOG
|
||||||
int nic_do_log = ENABLE_NIC_LOG;
|
int nic_do_log = ENABLE_NIC_LOG;
|
||||||
#endif
|
#endif
|
||||||
@@ -140,6 +145,7 @@ static struct {
|
|||||||
|
|
||||||
#ifdef ENABLE_NETWORK_LOG
|
#ifdef ENABLE_NETWORK_LOG
|
||||||
int network_do_log = ENABLE_NETWORK_LOG;
|
int network_do_log = ENABLE_NETWORK_LOG;
|
||||||
|
FILE *network_dump = NULL;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -153,8 +159,29 @@ network_log(const char *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
network_dump_packet(netpkt_t *pkt)
|
||||||
|
{
|
||||||
|
if (!network_dump)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
struct {
|
||||||
|
uint32_t ts_sec, ts_usec, incl_len, orig_len;
|
||||||
|
} pcap_packet_hdr = {
|
||||||
|
tv.tv_sec, tv.tv_usec, pkt->len, pkt->len
|
||||||
|
};
|
||||||
|
|
||||||
|
fwrite(&pcap_packet_hdr, sizeof(pcap_packet_hdr), 1, network_dump);
|
||||||
|
fwrite(pkt->data, pkt->len, 1, network_dump);
|
||||||
|
fflush(network_dump);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define network_log(fmt, ...)
|
#define network_log(fmt, ...)
|
||||||
|
#define network_dump_packet(pkt)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -220,6 +247,25 @@ network_init(void)
|
|||||||
i = net_pcap_prepare(&network_devs[network_ndev]);
|
i = net_pcap_prepare(&network_devs[network_ndev]);
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
network_ndev += i;
|
network_ndev += i;
|
||||||
|
|
||||||
|
#ifdef ENABLE_NETWORK_LOG
|
||||||
|
/* Start packet dump. */
|
||||||
|
network_dump = fopen("network.pcap", "wb");
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t magic_number;
|
||||||
|
uint16_t version_major, version_minor;
|
||||||
|
int32_t thiszone;
|
||||||
|
uint32_t sigfigs, snaplen, network;
|
||||||
|
} pcap_hdr = {
|
||||||
|
0xa1b2c3d4,
|
||||||
|
2, 4,
|
||||||
|
0,
|
||||||
|
0, 65535, 1
|
||||||
|
};
|
||||||
|
fwrite(&pcap_hdr, sizeof(pcap_hdr), 1, network_dump);
|
||||||
|
fflush(network_dump);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -294,12 +340,18 @@ network_queue_clear(int tx)
|
|||||||
static void
|
static void
|
||||||
network_rx_queue(void *priv)
|
network_rx_queue(void *priv)
|
||||||
{
|
{
|
||||||
|
if (network_rx_pause) {
|
||||||
|
timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
netpkt_t *pkt = NULL;
|
netpkt_t *pkt = NULL;
|
||||||
|
|
||||||
network_busy(1);
|
network_busy(1);
|
||||||
|
|
||||||
network_queue_get(0, &pkt);
|
network_queue_get(0, &pkt);
|
||||||
if ((pkt != NULL) && (pkt->len > 0)) {
|
if ((pkt != NULL) && (pkt->len > 0)) {
|
||||||
|
network_dump_packet(pkt);
|
||||||
net_cards[network_card].rx(pkt->priv, pkt->data, pkt->len);
|
net_cards[network_card].rx(pkt->priv, pkt->data, pkt->len);
|
||||||
if (pkt->len >= 128)
|
if (pkt->len >= 128)
|
||||||
timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) pkt->len));
|
timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) pkt->len));
|
||||||
@@ -404,6 +456,7 @@ network_close(void)
|
|||||||
/* Here is where we clear the queues. */
|
/* Here is where we clear the queues. */
|
||||||
network_queue_clear(0);
|
network_queue_clear(0);
|
||||||
network_queue_clear(1);
|
network_queue_clear(1);
|
||||||
|
network_rx_pause = 0;
|
||||||
|
|
||||||
network_log("NETWORK: closed.\n");
|
network_log("NETWORK: closed.\n");
|
||||||
}
|
}
|
||||||
@@ -501,6 +554,7 @@ network_do_tx(void)
|
|||||||
|
|
||||||
network_queue_get(1, &pkt);
|
network_queue_get(1, &pkt);
|
||||||
if ((pkt != NULL) && (pkt->len > 0)) {
|
if ((pkt != NULL) && (pkt->len > 0)) {
|
||||||
|
network_dump_packet(pkt);
|
||||||
switch(network_type) {
|
switch(network_type) {
|
||||||
case NET_TYPE_PCAP:
|
case NET_TYPE_PCAP:
|
||||||
net_pcap_in(pkt->data, pkt->len);
|
net_pcap_in(pkt->data, pkt->len);
|
||||||
|
Reference in New Issue
Block a user