ETHER: Gracefully handle dynamic pcap library initialization errors

- Test BPF using all available Ethernet capable interfaces
This commit is contained in:
Mark Pizzolato 2019-04-15 16:49:08 -07:00
parent 2f0db74483
commit 456aa3ed5d

View file

@ -1202,7 +1202,7 @@ int load_pcap(void) {
/* define functions with dynamic revectoring */ /* define functions with dynamic revectoring */
void pcap_close(pcap_t* a) { void pcap_close(pcap_t* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
p_pcap_close(a); p_pcap_close(a);
} }
} }
@ -1213,7 +1213,7 @@ int pcap_compile(pcap_t* a, struct bpf_program* b, char* c, int d, bpf_u_int32 e
#else #else
int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_int32 e) { int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_int32 e) {
#endif #endif
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_compile(a, b, c, d, e); return p_pcap_compile(a, b, c, d, e);
} else { } else {
return 0; return 0;
@ -1221,7 +1221,7 @@ int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_i
} }
int pcap_datalink(pcap_t* a) { int pcap_datalink(pcap_t* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_datalink(a); return p_pcap_datalink(a);
} else { } else {
return 0; return 0;
@ -1229,7 +1229,7 @@ int pcap_datalink(pcap_t* a) {
} }
int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) { int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_dispatch(a, b, c, d); return p_pcap_dispatch(a, b, c, d);
} else { } else {
return 0; return 0;
@ -1237,7 +1237,7 @@ int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
} }
int pcap_findalldevs(pcap_if_t** a, char* b) { int pcap_findalldevs(pcap_if_t** a, char* b) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_findalldevs(a, b); return p_pcap_findalldevs(a, b);
} else { } else {
*a = 0; *a = 0;
@ -1247,22 +1247,22 @@ int pcap_findalldevs(pcap_if_t** a, char* b) {
} }
void pcap_freealldevs(pcap_if_t* a) { void pcap_freealldevs(pcap_if_t* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
p_pcap_freealldevs(a); p_pcap_freealldevs(a);
} }
} }
void pcap_freecode(struct bpf_program* a) { void pcap_freecode(struct bpf_program* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
p_pcap_freecode(a); p_pcap_freecode(a);
} }
} }
char* pcap_geterr(pcap_t* a) { char* pcap_geterr(pcap_t* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_geterr(a); return p_pcap_geterr(a);
} else { } else {
return (char*) 0; return (char*) "";
} }
} }
@ -1284,15 +1284,15 @@ pcap_t* pcap_open_live(const char* a, int b, int c, int d, char* e) {
#ifdef _WIN32 #ifdef _WIN32
int pcap_setmintocopy(pcap_t* a, int b) { int pcap_setmintocopy(pcap_t* a, int b) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_setmintocopy(a, b); return p_pcap_setmintocopy(a, b);
} else { } else {
return 0; return -1;
} }
} }
HANDLE pcap_getevent(pcap_t* a) { HANDLE pcap_getevent(pcap_t* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_getevent(a); return p_pcap_getevent(a);
} else { } else {
return (HANDLE) 0; return (HANDLE) 0;
@ -1302,7 +1302,7 @@ HANDLE pcap_getevent(pcap_t* a) {
#else #else
#ifdef MUST_DO_SELECT #ifdef MUST_DO_SELECT
int pcap_get_selectable_fd(pcap_t* a) { int pcap_get_selectable_fd(pcap_t* a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_get_selectable_fd(a); return p_pcap_get_selectable_fd(a);
} else { } else {
return 0; return 0;
@ -1311,7 +1311,7 @@ int pcap_get_selectable_fd(pcap_t* a) {
#endif #endif
int pcap_fileno(pcap_t * a) { int pcap_fileno(pcap_t * a) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_fileno(a); return p_pcap_fileno(a);
} else { } else {
return 0; return 0;
@ -1320,7 +1320,7 @@ int pcap_fileno(pcap_t * a) {
#endif #endif
int pcap_sendpacket(pcap_t* a, const u_char* b, int c) { int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_sendpacket(a, b, c); return p_pcap_sendpacket(a, b, c);
} else { } else {
return 0; return 0;
@ -1328,7 +1328,7 @@ int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
} }
int pcap_setfilter(pcap_t* a, struct bpf_program* b) { int pcap_setfilter(pcap_t* a, struct bpf_program* b) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_setfilter(a, b); return p_pcap_setfilter(a, b);
} else { } else {
return 0; return 0;
@ -1336,7 +1336,7 @@ int pcap_setfilter(pcap_t* a, struct bpf_program* b) {
} }
int pcap_setnonblock(pcap_t* a, int nonblock, char *errbuf) { int pcap_setnonblock(pcap_t* a, int nonblock, char *errbuf) {
if (load_pcap() != 0) { if (a && (load_pcap() != 0)) {
return p_pcap_setnonblock(a, nonblock, errbuf); return p_pcap_setnonblock(a, nonblock, errbuf);
} else { } else {
return 0; return 0;
@ -2182,7 +2182,13 @@ else { /* !tap: */
} }
#endif /* xBSD */ #endif /* xBSD */
#if defined(_WIN32) #if defined(_WIN32)
pcap_setmintocopy ((pcap_t*)(*handle), 0); if ((pcap_setmintocopy ((pcap_t*)(*handle), 0) == -1) ||
(pcap_getevent ((pcap_t*)(*handle)) == NULL)) {
pcap_close ((pcap_t*)(*handle));
errbuf[PCAP_ERRBUF_SIZE-1] = '\0';
snprintf (errbuf, PCAP_ERRBUF_SIZE-1, "pcap can't initialize API for interface: %s", savname);
return SCPE_OPENERR;
}
#endif #endif
#if !defined (USE_READER_THREAD) #if !defined (USE_READER_THREAD)
#ifdef USE_SETNONBLOCK #ifdef USE_SETNONBLOCK
@ -4170,6 +4176,10 @@ int errors = 0;
t_stat r; t_stat r;
DEVICE eth_tst; DEVICE eth_tst;
ETH_DEV dev; ETH_DEV dev;
int eth_num;
int eth_opened;
ETH_LIST eth_list[ETH_MAX_DEVICE];
int eth_device_count;
int reflections, all_multicast, promiscuous; int reflections, all_multicast, promiscuous;
char buf[116+66*ETH_FILTER_MAX]; char buf[116+66*ETH_FILTER_MAX];
char mac[20]; char mac[20];
@ -4215,8 +4225,25 @@ int bpf_compile_skip_count = 0;
memset (&eth_tst, 0, sizeof(eth_tst)); memset (&eth_tst, 0, sizeof(eth_tst));
eth_open(&dev, "eth0", &eth_tst, 1); eth_device_count = eth_devices(ETH_MAX_DEVICE, eth_list);
for (reflections=0; reflections<=1; reflections++) { eth_opened = 0;
for (eth_num=0; eth_num<eth_device_count; eth_num++) {
char eth_name[10];
if ((0 == memcmp (eth_list[eth_num].name, "nat:", 4)) ||
(0 == memcmp (eth_list[eth_num].name, "tap:", 4)) ||
(0 == memcmp (eth_list[eth_num].name, "vde:", 4)) ||
(0 == memcmp (eth_list[eth_num].name, "udp:", 4)))
continue;
eth_name[sizeof (eth_name)-1] = '\0';
snprintf (eth_name, sizeof (eth_name)-1, "eth%d", eth_num);
r = eth_open(&dev, eth_name, &eth_tst, 1);
if (r != SCPE_OK) {
sim_printf ("%s: Eth: Error opening eth%d: %s\n", dptr->name, eth_num, sim_error_text (r));
continue;
}
++eth_opened;
for (reflections=0; reflections<=1; reflections++) {
for (all_multicast=0; all_multicast<=1; all_multicast++) { for (all_multicast=0; all_multicast<=1; all_multicast++) {
for (promiscuous=0; promiscuous<=1; promiscuous++) { for (promiscuous=0; promiscuous<=1; promiscuous++) {
for (addr_count=1; addr_count<=2; addr_count++) { for (addr_count=1; addr_count<=2; addr_count++) {
@ -4266,8 +4293,15 @@ for (reflections=0; reflections<=1; reflections++) {
} }
} }
} }
eth_close(&dev); eth_close(&dev);
sim_printf ("BPF Filter Count: %d\n", bpf_count); }
if (eth_opened == 0) {
errors = 1;
sim_printf ("%s: No testable LAN interfaces found\n", dptr->name);
}
if (bpf_count)
sim_printf ("BPF Filter Count: %d\n", bpf_count);
if (bpf_construct_error_count) if (bpf_construct_error_count)
sim_printf ("BPF Construct Errors: %d\n", bpf_construct_error_count); sim_printf ("BPF Construct Errors: %d\n", bpf_construct_error_count);
if (bpf_compile_error_count) if (bpf_compile_error_count)