1
0
mirror of https://github.com/open-simh/simh.git synced 2026-01-11 23:53:30 +00:00

ETH_MAC indirection erratum

Pervasive misuse of "ETH_MAC *" (a pointer to an ETH_MAC, aka a 6
element unsigned char array) when a simple "ETH_MAC" is correct.  The
best example of this was eth_mac_fmt() in sim_ether.c with the following
prototype:

    t_stat eth_mac_fmt (ETH_MAC* const mac, char* strmac)

The first parameter is a pointer to an array of 6 unsigned characters,
whereas it really just wants to be a pointer to the first element of the
array:

    t_stat eth_mac_scan (const ETH_MAC mac, char* strmac)

The "ETH_MAC *" indirection error also results in subtle memcpy() and
memcmp() issues, e.g.:

    void network_func(DEVICE *dev, ETH_MAC *mac)
    {
      ETH_MAC other_mac;

      /* ...code... */

      /* memcpy() bug: */
      memcpy(other_mac, mac, sizeof(ETH_MAC));

      /* or worse: */
      memcpy(mac, other_mac, sizeof(ETH_MAC));
    }

eth_copy_mac() and eth_mac_cmp() replace calls to memcpy() and memcmp()
that copy or compare Ethernet MAC addresses. These are type-enforcing
functions, i.e., the parameters are ETH_MAC-s, to avoid the subtle
memcpy() and memcmp() bugs.

This fix solves at least one Heisenbug in _eth_close() while free()-ing
write request buffers (and possibly other Heisenbugs.)
This commit is contained in:
B. Scott Michel 2025-03-03 16:26:28 -08:00 committed by Paul Koning
parent 73e5df3928
commit c20b391eea
10 changed files with 256 additions and 225 deletions

View File

@ -557,7 +557,7 @@ t_stat ni_setmac(UNIT *uptr, int32 val, CONST char* cptr, void* desc)
UNUSED(desc);
status = SCPE_OK;
status = eth_mac_scan_ex(&ni.macs[NI_NIC_MAC], cptr, uptr);
status = eth_mac_scan_ex(ni.macs[NI_NIC_MAC], cptr, uptr);
if (status == SCPE_OK) {
eth_filter(ni.eth, ni.filter_count, ni.macs, 0, 0);
@ -577,7 +577,7 @@ t_stat ni_showmac(FILE* st, UNIT* uptr, int32 val, CONST void* desc)
UNUSED(val);
UNUSED(desc);
eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer);
eth_mac_fmt(ni.macs[NI_NIC_MAC], buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -591,12 +591,12 @@ t_stat ni_show_filters(FILE* st, UNIT* uptr, int32 val, CONST void* desc)
UNUSED(val);
UNUSED(desc);
eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer);
eth_mac_fmt(ni.macs[NI_NIC_MAC], buffer);
fprintf(st, "Physical Address=%s\n", buffer);
if (ni.filter_count > 0) {
fprintf(st, "Filters:\n");
for (i=0; i < ni.filter_count; i++) {
eth_mac_fmt((ETH_MAC *) ni.macs[i], buffer);
eth_mac_fmt(ni.macs[i], buffer);
fprintf(st, "[%2d]: %s\n", i, buffer);
}
fprintf(st, "\n");
@ -948,7 +948,7 @@ t_stat ni_attach(UNIT *uptr, CONST char *cptr)
return status;
}
status = eth_check_address_conflict(ni.eth, &ni.macs[NI_NIC_MAC]);
status = eth_check_address_conflict(ni.eth, ni.macs[NI_NIC_MAC]);
if (status != SCPE_OK) {
sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: mac check\n");
eth_close(ni.eth);

View File

@ -573,8 +573,8 @@ void nia_start()
nia_rh.wcr);
nia_data.pia = (int)(nia_rh.buf & 7);
nia_data.status |= NIA_MRN;
memcpy(&nia_data.macs[0], &nia_data.mac, sizeof (ETH_MAC));
memcpy(&nia_data.macs[1], &broadcast_ethaddr, sizeof(ETH_MAC));
eth_copy_mac(nia_data.macs[0], nia_data.mac);
eth_copy_mac(nia_data.macs[1], broadcast_ethaddr);
}
void nia_stop()
@ -634,16 +634,14 @@ void nia_disable()
/*
* Copy a MAC address from string to memory word.
*/
void nia_cpy_mac(uint64 word1, uint64 word2, ETH_MAC *mac)
void nia_cpy_mac(uint64 word1, uint64 word2, ETH_MAC mac)
{
ETH_MAC m;
m[0] = (unsigned char)((word1 >> 28) & 0xff);
m[1] = (unsigned char)((word1 >> 20) & 0xff);
m[2] = (unsigned char)((word1 >> 12) & 0xff);
m[3] = (unsigned char)((word1 >> 4) & 0xff);
m[4] = (unsigned char)((word2 >> 28) & 0xff);
m[5] = (unsigned char)((word2 >> 20) & 0xff);
memcpy(mac, &m, sizeof(ETH_MAC));
mac[0] = (unsigned char)((word1 >> 28) & 0xff);
mac[1] = (unsigned char)((word1 >> 20) & 0xff);
mac[2] = (unsigned char)((word1 >> 12) & 0xff);
mac[3] = (unsigned char)((word1 >> 4) & 0xff);
mac[4] = (unsigned char)((word2 >> 28) & 0xff);
mac[5] = (unsigned char)((word2 >> 20) & 0xff);
}
/*
@ -903,9 +901,9 @@ void nia_load_mcast()
t_addr addr = nia_data.mcast_addr;
/* Start with our own address. */
memcpy(&nia_data.macs[n], &nia_data.mac, sizeof (ETH_MAC));
eth_copy_mac(nia_data.macs[n], nia_data.mac);
n++;
memcpy(&nia_data.macs[n], &broadcast_ethaddr, sizeof (ETH_MAC));
eth_copy_mac(nia_data.macs[n], broadcast_ethaddr);
n++;
for (i = 0; i < 17; i++) {
uint64 word1, word2;
@ -919,12 +917,12 @@ void nia_load_mcast()
return;
}
if (word2 & 1) {
nia_cpy_mac(word1, word2, &nia_data.macs[n]);
nia_cpy_mac(word1, word2, nia_data.macs[n]);
n++;
}
}
for(i = 0; i< n; i++) {
eth_mac_fmt(&nia_data.macs[i], buffer);
eth_mac_fmt(nia_data.macs[i], buffer);
sim_debug(DEBUG_DETAIL, &nia_dev, "NIA load mcast%d: %s\n",i,buffer);
}
nia_data.macs_n = n - 2;
@ -1021,12 +1019,12 @@ void nia_packet_debug(struct nia_device *nia, const char *action,
if (!(nia_dev.dctrl & DEBUG_ARP))
return;
eth_mac_fmt(&arp->ethhdr.src, eth_src);
eth_mac_fmt(&arp->ethhdr.dest, eth_dst);
eth_mac_fmt(&arp->shwaddr, arp_shwaddr);
eth_mac_fmt(arp->ethhdr.src, eth_src);
eth_mac_fmt(arp->ethhdr.dest, eth_dst);
eth_mac_fmt(arp->shwaddr, arp_shwaddr);
memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr));
strlcpy(arp_sipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_sipaddr));
eth_mac_fmt(&arp->dhwaddr, arp_dhwaddr);
eth_mac_fmt(arp->dhwaddr, arp_dhwaddr);
memcpy(&in_addr, &arp->dipaddr, sizeof(in_addr));
strlcpy(arp_dipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_dipaddr));
sim_debug(DEBUG_ARP, &nia_dev,
@ -1142,10 +1140,10 @@ int nia_send_pkt(uint64 cmd)
nia_error(EBSERR);
return 0;
}
nia_cpy_mac(word1, word2, &dest);
memcpy(hdr->dest, dest, sizeof(ETH_MAC));
nia_cpy_mac(word1, word2, dest);
eth_copy_mac(hdr->dest, dest);
/* Copy our address over */
memcpy(hdr->src, nia_data.mac, sizeof(ETH_MAC));
eth_copy_mac(hdr->src, nia_data.mac);
/* Set packet length */
nia_data.snd_buff.len = len + sizeof(struct nia_eth_hdr);
/* Preappend length if asking for pad */
@ -1319,7 +1317,7 @@ t_stat nia_cmd_srv(UNIT * uptr)
nia_error(EBSERR);
return SCPE_OK;
}
nia_cpy_mac(word1, word2, &nia_data.mac);
nia_cpy_mac(word1, word2, nia_data.mac);
if (Mem_read_word(nia_data.cmd_entry + 6, &word1, 0)) {
nia_error(EBSERR);
return SCPE_OK;
@ -1331,7 +1329,7 @@ t_stat nia_cmd_srv(UNIT * uptr)
nia_data.prmsc = (int)(word1 & 1);
nia_data.h4000 = (int)((word1 & 2) != 0);
nia_data.amc = (int)((word1 & 4) != 0);
memcpy(&nia_data.macs[0], &nia_data.mac, sizeof (ETH_MAC));
eth_copy_mac(nia_data.macs[0], nia_data.mac);
if (nia_recv_uptr->flags & UNIT_ATT)
eth_filter (&nia_data.etherface, nia_data.macs_n + 2,
nia_data.macs, 0, 0);
@ -1549,7 +1547,7 @@ t_stat nia_rec_srv(UNIT * uptr)
t_stat nia_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
{
char buffer[20];
eth_mac_fmt(&nia_data.mac, buffer);
eth_mac_fmt(nia_data.mac, buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -1561,7 +1559,7 @@ t_stat nia_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
if (!cptr) return SCPE_IERR;
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
status = eth_mac_scan_ex(&nia_data.mac, cptr, uptr);
status = eth_mac_scan_ex(nia_data.mac, cptr, uptr);
if (status != SCPE_OK)
return status;
@ -1594,16 +1592,16 @@ t_stat nia_attach(UNIT* uptr, CONST char* cptr)
if (tptr == NULL) return SCPE_MEM;
strcpy(tptr, cptr);
memcpy(&nia_data.macs[0], &nia_data.mac, sizeof (ETH_MAC));
eth_copy_mac(nia_data.macs[0], nia_data.mac);
memcpy(&nia_data.macs[1], &broadcast_ethaddr, 6);
status = eth_open(&nia_data.etherface, cptr, &nia_dev, DEBUG_ETHER);
if (status != SCPE_OK) {
free(tptr);
return status;
}
eth_mac_fmt(&nia_data.mac, buf); /* format ethernet mac address */
eth_mac_fmt(nia_data.mac, buf); /* format ethernet mac address */
if (SCPE_OK != eth_check_address_conflict (&nia_data.etherface,
&nia_data.mac)) {
nia_data.mac)) {
eth_close(&nia_data.etherface);
free(tptr);
return sim_messagef (SCPE_NOATT,

View File

@ -521,7 +521,7 @@ void imp_packet_in(struct imp_device *imp);
void imp_send_packet (struct imp_device *imp_data, int len);
void imp_free_packet(struct imp_device *imp, struct imp_packet *p);
struct imp_packet * imp_get_packet(struct imp_device *imp);
void imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int age);
void imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC ethaddr, int age);
void imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet);
void imp_arp_arpout(struct imp_device *imp, in_addr_T ipaddr);
struct arp_entry * imp_arp_lookup(struct imp_device *imp, in_addr_T ipaddr);
@ -1430,7 +1430,7 @@ imp_packet_in(struct imp_device *imp)
/* Process as IP if it is for us */
if (ip_hdr->ip_dst == imp_data.ip || ip_hdr->ip_dst == 0) {
/* Add mac address since we will probably need it later */
imp_arp_update(imp, ip_hdr->ip_src, &hdr->src, 0);
imp_arp_update(imp, ip_hdr->ip_src, hdr->src, 0);
/* Clear beginning of message */
memset(&imp->rbuffer[0], 0, 256);
imp->rbuffer[0] = 0xf;
@ -1955,12 +1955,12 @@ void imp_packet_debug(struct imp_device *imp, const char *action, ETH_PACK *pack
if (!(imp_dev.dctrl & DEBUG_ARP))
return;
eth_mac_fmt(&arp->ethhdr.src, eth_src);
eth_mac_fmt(&arp->ethhdr.dest, eth_dst);
eth_mac_fmt(&arp->shwaddr, arp_shwaddr);
eth_mac_fmt(arp->ethhdr.src, eth_src);
eth_mac_fmt(arp->ethhdr.dest, eth_dst);
eth_mac_fmt(arp->shwaddr, arp_shwaddr);
memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr));
strlcpy(arp_sipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_sipaddr));
eth_mac_fmt(&arp->dhwaddr, arp_dhwaddr);
eth_mac_fmt(arp->dhwaddr, arp_dhwaddr);
memcpy(&in_addr, &arp->dipaddr, sizeof(in_addr));
strlcpy(arp_dipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_dipaddr));
sim_debug(DEBUG_ARP, &imp_dev,
@ -2013,7 +2013,7 @@ void imp_packet_debug(struct imp_device *imp, const char *action, ETH_PACK *pack
memcpy(&ipaddr, &dhcp->giaddr, sizeof(ipaddr));
sim_debug(DEBUG_DHCP, &imp_dev, ", giaddr=%s", ipv4_inet_ntoa(ipaddr));
}
eth_mac_fmt((ETH_MAC*)&dhcp->chaddr, mac_buf);
eth_mac_fmt(dhcp->chaddr, mac_buf);
sim_debug(DEBUG_DHCP, &imp_dev, ", chaddr=%s Options: ", mac_buf);
while (*opt != DHCP_OPTION_END) {
int opt_len;
@ -2129,7 +2129,7 @@ void imp_write(struct imp_device *imp, ETH_PACK *packet) {
* Update the ARP table, first use free entry, else use oldest.
*/
void
imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int age)
imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC ethaddr, int age)
{
struct arp_entry *tabptr;
int i;
@ -2141,8 +2141,8 @@ imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int a
if (tabptr->ipaddr != 0) {
if (tabptr->ipaddr == ipaddr) {
if (0 != memcmp(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC))) {
memcpy(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC));
if (0 != eth_mac_cmp(tabptr->ethaddr, ethaddr)) {
eth_copy_mac(tabptr->ethaddr, ethaddr);
eth_mac_fmt(ethaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev,
"updating entry for IP %s to %s\n",
@ -2178,7 +2178,7 @@ imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int a
}
/* Now save the entry */
memcpy(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC));
eth_copy_mac(tabptr->ethaddr, ethaddr);
tabptr->ipaddr = ipaddr;
tabptr->age = age;
eth_mac_fmt(ethaddr, mac_buf);
@ -2204,7 +2204,7 @@ void imp_arp_age(struct imp_device *imp)
if (tabptr->age > IMP_ARP_MAX_AGE) {
char mac_buf[20];
eth_mac_fmt(&tabptr->ethaddr, mac_buf);
eth_mac_fmt(tabptr->ethaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev,
"discarding ARP entry for IP %s %s after %d seconds\n",
ipv4_inet_ntoa(*((struct in_addr *)&tabptr->ipaddr)), mac_buf, IMP_ARP_MAX_AGE);
@ -2232,7 +2232,7 @@ imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
return;
arp = (struct arp_hdr *)(&packet->msg[0]);
op = ntohs(arp->opcode);
imp_arp_update(imp, arp->sipaddr, &arp->shwaddr, 0);
imp_arp_update(imp, arp->sipaddr, arp->shwaddr, 0);
switch (op) {
case ARP_REQUEST:
@ -2249,7 +2249,7 @@ imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
arp->ethhdr.type = htons(ETHTYPE_ARP);
packet->len = sizeof(struct arp_hdr);
imp_write(imp, packet);
eth_mac_fmt(&arp->dhwaddr, mac_buf);
eth_mac_fmt(arp->dhwaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev, "replied to received request for IP %s from %s\n",
ipv4_inet_ntoa(*((struct in_addr *)&imp->ip)), mac_buf);
}
@ -2260,7 +2260,7 @@ imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
if (arp->dipaddr == imp->ip) {
struct imp_packet *nq = NULL; /* New send queue */
eth_mac_fmt(&arp->shwaddr, mac_buf);
eth_mac_fmt(arp->shwaddr, mac_buf);
memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr));
sim_debug(DEBUG_ARP, &imp_dev, "received reply for IP %s as %s\n",
ipv4_inet_ntoa(in_addr), mac_buf);
@ -2351,12 +2351,12 @@ t_stat imp_set_arp (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
cptr = get_glyph (cptr, abuf, '=');
if (cptr && *cptr) {
if (SCPE_OK != eth_mac_scan (&mac_addr, cptr)) /* scan string for mac, put in mac */
if (SCPE_OK != eth_mac_scan (mac_addr, cptr)) /* scan string for mac, put in mac */
return sim_messagef(SCPE_ARG, "Invalid MAC address: %s\n", abuf);
} else
return sim_messagef(SCPE_ARG, "MAC address empty\n");
if (ipv4_inet_aton (abuf, (struct in_addr *)&ip)) {
imp_arp_update(&imp_data, ip, &mac_addr, ARP_DONT_AGE);
imp_arp_update(&imp_data, ip, mac_addr, ARP_DONT_AGE);
return SCPE_OK;
}
return sim_messagef(SCPE_ARG, "Invalid IP Address: %s\n", abuf);
@ -2377,7 +2377,7 @@ t_stat imp_show_arp (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
if (tabptr->ipaddr == 0)
continue;
eth_mac_fmt(&tabptr->ethaddr, buf); /* format ethernet mac address */
eth_mac_fmt(tabptr->ethaddr, buf); /* format ethernet mac address */
if (tabptr->age == ARP_DONT_AGE)
fprintf (st, "%-17s%-19s%s\n",
ipv4_inet_ntoa(*((struct in_addr *)&tabptr->ipaddr)),
@ -2457,7 +2457,7 @@ imp_do_send_dhcp(struct imp_device *imp,
packet->len = len + sizeof(struct ip_hdr);
imp_write(imp, packet);
eth_mac_fmt (&pkt->ethhdr.dest, mac_buf);
eth_mac_fmt (pkt->ethhdr.dest, mac_buf);
memcpy(&in_addr, &udp_hdr.ip_dst, sizeof(in_addr));
sim_debug(DEBUG_DHCP, &imp_dev,
"client sent %s packet to: %s:%d(%s)\n",
@ -2574,7 +2574,7 @@ imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *read_buffer)
}
}
eth_mac_fmt(&eth->src, mac_buf);
eth_mac_fmt(eth->src, mac_buf);
memcpy(&in_addr, &udp_hdr.ip_src, sizeof(in_addr));
sim_debug(DEBUG_DHCP, &imp_dev,
"client incoming %s packet: dhcp_state=%s - wait_time=%d from: %s:%d(%s)\n",
@ -2617,7 +2617,7 @@ imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *read_buffer)
break;
}
/* Record a static ARP for the DHCP server */
imp_arp_update(imp, dhcpip, &eth->src, ARP_DONT_AGE);
imp_arp_update(imp, dhcpip, eth->src, ARP_DONT_AGE);
/* Broadcast an ARP Reply with the assigned IP Address */
memset(&arp_pkt, 0, sizeof(ETH_PACK));
@ -2948,7 +2948,7 @@ t_stat imp_show_mpx (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
t_stat imp_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
{
char buffer[20];
eth_mac_fmt(&imp_data.mac, buffer);
eth_mac_fmt(imp_data.mac, buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -2960,7 +2960,7 @@ t_stat imp_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
if (!cptr) return SCPE_IERR;
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
status = eth_mac_scan_ex(&imp_data.mac, cptr, uptr);
status = eth_mac_scan_ex(imp_data.mac, cptr, uptr);
if (status != SCPE_OK)
return status;
@ -3160,8 +3160,8 @@ t_stat imp_attach(UNIT* uptr, CONST char* cptr)
free(tptr);
return status;
}
eth_mac_fmt(&imp_data.mac, buf); /* format ethernet mac address */
if (SCPE_OK != eth_check_address_conflict (&imp_data.etherface, &imp_data.mac)) {
eth_mac_fmt(imp_data.mac, buf); /* format ethernet mac address */
if (SCPE_OK != eth_check_address_conflict (&imp_data.etherface, imp_data.mac)) {
eth_close(&imp_data.etherface);
free(tptr);
return sim_messagef (SCPE_NOATT, "%s: MAC Address Conflict on LAN for address %s\n",
@ -3215,7 +3215,7 @@ t_stat imp_attach(UNIT* uptr, CONST char* cptr)
imp_arp_arpin(&imp_data, &read_buffer);
} while (read_buffer.len > 0);
if ((arp = imp_arp_lookup(&imp_data, imp_data.gwip)))
imp_arp_update(&imp_data, imp_data.gwip, &arp->ethaddr, ARP_DONT_AGE);
imp_arp_update(&imp_data, imp_data.gwip, arp->ethaddr, ARP_DONT_AGE);
}
eth_set_async (&imp_data.etherface, 0); /* Allow Asynchronous inbound packets */

View File

@ -652,7 +652,7 @@ t_stat xq_showmac (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
CTLR* xq = xq_unit2ctlr(uptr);
char buffer[20];
eth_mac_fmt((ETH_MAC*)xq->var->mac, buffer);
eth_mac_fmt(xq->var->mac, buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -687,7 +687,7 @@ t_stat xq_setmac (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
if (!cptr) return SCPE_IERR;
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
status = eth_mac_scan_ex(&xq->var->mac, cptr, uptr);
status = eth_mac_scan_ex(xq->var->mac, cptr, uptr);
if (status != SCPE_OK)
return status;
@ -745,10 +745,10 @@ t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
int i;
if (xq->var->mode == XQ_T_DELQA_PLUS) {
eth_mac_fmt(&xq->var->init.phys, buffer);
eth_mac_fmt(xq->var->init.phys, buffer);
fprintf(st, "Physical Address=%s\n", buffer);
for (i=1; i<xq->var->etherface->addr_count; i++) {
eth_mac_fmt((ETH_MAC*)xq->var->etherface->filter_address[i], buffer);
eth_mac_fmt(xq->var->etherface->filter_address[i], buffer);
fprintf(st, "Additional Filter:[%2d]: %s\n", (int)i, buffer);
}
if (xq->var->etherface->hash_filter) {
@ -762,7 +762,7 @@ t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
} else {
fprintf(st, "Filters:\n");
for (i=0; i<XQ_FILTER_MAX; i++) {
eth_mac_fmt((ETH_MAC*)xq->var->setup.macs[i], buffer);
eth_mac_fmt(xq->var->setup.macs[i], buffer);
fprintf(st, " [%2d]: %s\n", (int)i, buffer);
}
if (xq->var->setup.multicast)
@ -1366,7 +1366,6 @@ t_stat xq_process_setup(CTLR* xq)
int count = 0;
float secs = 0;
uint32 saved_debug = xq->dev->dctrl;
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
ETH_MAC filters[XQ_FILTER_MAX + 1];
sim_debug(DBG_TRC, xq->dev, "xq_process_setup()\n");
@ -1456,10 +1455,10 @@ t_stat xq_process_setup(CTLR* xq)
xq_reset_santmr(xq);
/* set ethernet filter */
/* memcpy (filters[count++], xq->mac, sizeof(ETH_MAC)); */
/* eth_copy_mac(filters[count++], xq->mac); */
for (i = 0; i < XQ_FILTER_MAX; i++)
if (memcmp(zeros, &xq->var->setup.macs[i], sizeof(ETH_MAC)))
memcpy (filters[count++], xq->var->setup.macs[i], sizeof(ETH_MAC));
if (eth_mac_cmp(eth_mac_any, xq->var->setup.macs[i]))
eth_copy_mac(filters[count++], xq->var->setup.macs[i]);
eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous);
/* process MOP information */
@ -2012,11 +2011,11 @@ t_stat xq_process_loopback(CTLR* xq, ETH_PACK* pack)
(we may receive others if we're in promiscuous mode, but shouldn't
respond to them) */
if ((0 == (pack->msg[0]&1)) && /* Multicast or Broadcast */
(0 != memcmp(physical_address, pack->msg, sizeof(ETH_MAC))))
(0 != eth_mac_cmp(*physical_address, pack->msg)))
return SCPE_NOFNC;
memcpy (&response.msg[0], &response.msg[offset+2], sizeof(ETH_MAC));
memcpy (&response.msg[6], physical_address, sizeof(ETH_MAC));
eth_copy_mac (&response.msg[0], &response.msg[offset+2]);
eth_copy_mac (&response.msg[6], *physical_address);
offset += 8 - 16; /* Account for the Ethernet Header and Offset value in this number */
response.msg[14] = offset & 0xFF;
response.msg[15] = (offset >> 8) & 0xFF;
@ -2043,7 +2042,7 @@ t_stat xq_process_remote_console (CTLR* xq, ETH_PACK* pack)
switch (code) {
case 0x05: /* request id */
receipt = pack->msg[18] | (pack->msg[19] << 8);
memcpy(source, &pack->msg[6], sizeof(ETH_MAC));
eth_copy_mac(source, &pack->msg[6]);
/* send system id to requestor */
status = xq_system_id (xq, source, receipt);
@ -2164,14 +2163,13 @@ void xq_sw_reset(CTLR* xq)
xq->var->setup.promiscuous = 0;
if (xq->var->etherface) {
int count = 0;
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
ETH_MAC filters[XQ_FILTER_MAX + 1];
/* set ethernet filter */
/* memcpy (filters[count++], xq->mac, sizeof(ETH_MAC)); */
/* eth_copy_mac(filters[count++], xq->mac); */
for (i = 0; i < XQ_FILTER_MAX; i++)
if (memcmp(zeros, &xq->var->setup.macs[i], sizeof(ETH_MAC)))
memcpy (filters[count++], xq->var->setup.macs[i], sizeof(ETH_MAC));
if (eth_mac_cmp(eth_mac_any, xq->var->setup.macs[i]))
eth_copy_mac(filters[count++], xq->var->setup.macs[i]);
eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous);
}
@ -2685,8 +2683,8 @@ t_stat xq_system_id (CTLR* xq, const ETH_MAC dest, uint16 receipt_id)
return SCPE_NOFNC;
memset (&system_id, 0, sizeof(system_id));
memcpy (&msg[0], dest, sizeof(ETH_MAC));
memcpy (&msg[6], xq->var->setup.valid ? xq->var->setup.macs[0] : xq->var->mac, sizeof(ETH_MAC));
eth_copy_mac(&msg[0], dest);
eth_copy_mac(&msg[6], xq->var->setup.valid ? xq->var->setup.macs[0] : xq->var->mac);
msg[12] = 0x60; /* type */
msg[13] = 0x02; /* type */
msg[14] = 0x1C; /* character count */
@ -2720,7 +2718,7 @@ t_stat xq_system_id (CTLR* xq, const ETH_MAC dest, uint16 receipt_id)
msg[31] = 0x07; /* type */
msg[32] = 0x00; /* type */
msg[33] = 0x06; /* length */
memcpy (&msg[34], xq->var->mac, sizeof(ETH_MAC)); /* ROM address */
eth_copy_mac(&msg[34], xq->var->mac); /* ROM address */
/* DEVICE TYPE */
msg[40] = 100; /* type */
@ -2907,7 +2905,7 @@ t_stat xq_attach(UNIT* uptr, CONST char* cptr)
} else {
xq->var->must_poll = (SCPE_OK != eth_clr_async(xq->var->etherface));
}
if (SCPE_OK != eth_check_address_conflict (xq->var->etherface, &xq->var->mac)) {
if (SCPE_OK != eth_check_address_conflict (xq->var->etherface, xq->var->mac)) {
eth_close(xq->var->etherface);
free(tptr);
free(xq->var->etherface);
@ -2936,12 +2934,11 @@ t_stat xq_attach(UNIT* uptr, CONST char* cptr)
else
if (xq->var->setup.valid) {
int i, count = 0;
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
ETH_MAC filters[XQ_FILTER_MAX + 1];
for (i = 0; i < XQ_FILTER_MAX; i++)
if (memcmp(zeros, &xq->var->setup.macs[i], sizeof(ETH_MAC)))
memcpy (filters[count++], xq->var->setup.macs[i], sizeof(ETH_MAC));
if (eth_mac_cmp(eth_mac_any, xq->var->setup.macs[i]))
eth_copy_mac(filters[count++], xq->var->setup.macs[i]);
eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous);
}
else
@ -3085,7 +3082,7 @@ void xq_debug_setup(CTLR* xq)
}
for (i = 0; i < XQ_FILTER_MAX; i++) {
eth_mac_fmt(&xq->var->setup.macs[i], buffer);
eth_mac_fmt(xq->var->setup.macs[i], buffer);
sim_debug(DBG_SET, xq->dev, "%s: setup> set addr[%d]: %s\n", xq->dev->name, i, buffer);
}
@ -3118,7 +3115,7 @@ void xq_debug_turbo_setup(CTLR* xq)
if (xq->var->init.mode & XQ_IN_MO_LOP) strcat(buffer, "LOP ");
sim_debug(DBG_SET, xq->dev, "%s: setup> set Mode: %s\n", xq->dev->name, buffer);
eth_mac_fmt(&xq->var->init.phys, buffer);
eth_mac_fmt(xq->var->init.phys, buffer);
sim_debug(DBG_SET, xq->dev, "%s: setup> set Physical MAC Address: %s\n", xq->dev->name, buffer);
buffer[0] = '\0';

View File

@ -368,7 +368,7 @@ t_stat xu_showmac (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
CTLR* xu = xu_unit2ctlr(uptr);
char buffer[20];
eth_mac_fmt((ETH_MAC*)xu->var->mac, buffer);
eth_mac_fmt(xu->var->mac, buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -380,7 +380,7 @@ t_stat xu_setmac (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
if (!cptr) return SCPE_IERR;
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
status = eth_mac_scan_ex(&xu->var->mac, cptr, uptr);
status = eth_mac_scan_ex(xu->var->mac, cptr, uptr);
return status;
}
@ -421,7 +421,7 @@ t_stat xu_show_filters (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
fprintf(st, "Filters:\n");
for (i=0; i<XU_FILTER_MAX; i++) {
eth_mac_fmt((ETH_MAC*)xu->var->setup.macs[i], buffer);
eth_mac_fmt(xu->var->setup.macs[i], buffer);
fprintf(st, " [%2d]: %s\n", i, buffer);
}
if (xu->var->setup.multicast)
@ -570,7 +570,7 @@ t_stat xu_process_loopback(CTLR* xu, ETH_PACK* pack)
/* create forward response packet */
memcpy (&response, pack, sizeof(ETH_PACK));
memcpy (physical_address, xu->var->setup.macs[0], sizeof(ETH_MAC));
eth_copy_mac(physical_address, xu->var->setup.macs[0]);
/* The only packets we should be responding to are ones which
we received due to them being directed to our physical MAC address,
@ -578,12 +578,12 @@ t_stat xu_process_loopback(CTLR* xu, ETH_PACK* pack)
(we may receive others if we're in promiscuous mode, but shouldn't
respond to them) */
if ((0 == (pack->msg[0]&1)) && /* Multicast or Broadcast */
(0 != memcmp(physical_address, pack->msg, sizeof(ETH_MAC))))
(0 != eth_mac_cmp(physical_address, pack->msg)))
return SCPE_NOFNC;
memcpy (&response.msg[0], &response.msg[offset+2], sizeof(ETH_MAC));
memcpy (&response.msg[6], physical_address, sizeof(ETH_MAC));
eth_copy_mac(&response.msg[0], &response.msg[offset+2]);
eth_copy_mac(&response.msg[6], physical_address);
offset += 8 - 16; /* Account for the Ethernet Header and Offset value in this number */
response.msg[14] = offset & 0xFF;
response.msg[15] = (offset >> 8) & 0xFF;
@ -652,8 +652,8 @@ t_stat xu_system_id (CTLR* xu, const ETH_MAC dest, uint16 receipt_id)
sim_debug(DBG_TRC, xu->dev, "xu_system_id()\n");
memset (&system_id, 0, sizeof(system_id));
memcpy (&msg[0], dest, sizeof(ETH_MAC));
memcpy (&msg[6], xu->var->setup.macs[0], sizeof(ETH_MAC));
eth_copy_mac(&msg[0], dest);
eth_copy_mac(&msg[6], xu->var->setup.macs[0]);
msg[12] = 0x60; /* type */
msg[13] = 0x02; /* type */
msg[14] = 0x1C; /* character count */
@ -687,7 +687,7 @@ t_stat xu_system_id (CTLR* xu, const ETH_MAC dest, uint16 receipt_id)
msg[31] = 0x07; /* type */
msg[32] = 0x00; /* type */
msg[33] = 0x06; /* length */
memcpy (&msg[34], xu->var->mac, sizeof(ETH_MAC)); /* ROM address */
eth_copy_mac(&msg[34], xu->var->mac); /* ROM address */
/* DEVICE TYPE */
msg[40] = 0x64; /* type */
@ -824,7 +824,7 @@ t_stat xu_sw_reset (CTLR* xu)
memset(&xu->var->stats, 0, sizeof(struct xu_stats));
/* reset ethernet interface */
memcpy (xu->var->setup.macs[0], xu->var->mac, sizeof(ETH_MAC));
eth_copy_mac(xu->var->setup.macs[0], xu->var->mac);
for (i=0; i<6; i++)
xu->var->setup.macs[1][i] = 0xff; /* Broadcast Address */
xu->var->setup.mac_count = 2;
@ -887,7 +887,6 @@ int32 xu_command(CTLR* xu)
struct xu_stats* stats = &xu->var->stats;
uint16* udb = xu->var->udb;
uint16* mac_w = (uint16*) xu->var->mac;
static const ETH_MAC zeros = {0,0,0,0,0,0};
static const ETH_MAC mcast_load_server = {0xAB, 0x00, 0x00, 0x01, 0x00, 0x00};
static const char* command[] = {
"NO-OP",
@ -1166,7 +1165,7 @@ int32 xu_command(CTLR* xu)
break;
case FC_RLSA: /* read load server address */
if (memcmp(xu->var->load_server, zeros, sizeof(ETH_MAC))) {
if (eth_mac_cmp(xu->var->load_server, eth_mac_any)) {
/* not set, use default multicast load address */
wstatus = Map_WriteB(xu->var->pcbb + 2, 6, (const uint8*) mcast_load_server);
} else {
@ -1452,7 +1451,7 @@ void xu_process_transmit(CTLR* xu)
/* As described in the DEUNA User Guide (Section 4.7), the DEUNA is responsible
for inserting the appropriate source MAC address in the outgoing packet header,
so we do that now. */
memcpy(xu->var->write_buffer.msg+6, (uint8*)&xu->var->setup.macs[0], sizeof(ETH_MAC));
eth_copy_mac(xu->var->write_buffer.msg+6, xu->var->setup.macs[0]);
/* are we in internal loopback mode ? */
if ((xu->var->mode & MODE_LOOP) && (xu->var->mode & MODE_INTL)) {
@ -1485,7 +1484,7 @@ void xu_process_transmit(CTLR* xu)
/* was packet self-addressed? */
for (i=0; i<XU_FILTER_MAX; i++)
if (memcmp(xu->var->write_buffer.msg, xu->var->setup.macs[i], sizeof(ETH_MAC)) == 0)
if (eth_mac_cmp(xu->var->write_buffer.msg, xu->var->setup.macs[i]) == 0)
xu->var->txhdr[2] |= TXR_MTCH;
/* tell host we transmitted a packet */
@ -1775,7 +1774,7 @@ t_stat xu_attach(UNIT* uptr, CONST char* cptr)
return status;
}
eth_set_throttle (xu->var->etherface, xu->var->throttle_time, xu->var->throttle_burst, xu->var->throttle_delay);
if (SCPE_OK != eth_check_address_conflict (xu->var->etherface, &xu->var->mac)) {
if (SCPE_OK != eth_check_address_conflict (xu->var->etherface, xu->var->mac)) {
eth_close(xu->var->etherface);
free(tptr);
free(xu->var->etherface);
@ -1798,12 +1797,11 @@ t_stat xu_attach(UNIT* uptr, CONST char* cptr)
if (xu->var->setup.valid) {
int i, count = 0;
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
ETH_MAC filters[XU_FILTER_MAX + 1];
for (i = 0; i < XU_FILTER_MAX; i++)
if (memcmp(zeros, &xu->var->setup.macs[i], sizeof(ETH_MAC)))
memcpy (filters[count++], xu->var->setup.macs[i], sizeof(ETH_MAC));
if (eth_mac_cmp(eth_mac_any, xu->var->setup.macs[i]))
eth_copy_mac (filters[count++], xu->var->setup.macs[i]);
eth_filter (xu->var->etherface, count, filters, xu->var->setup.multicast, xu->var->setup.promiscuous);
}

View File

@ -808,12 +808,12 @@ t_stat ec_srv(UNIT *uptr)
}
}
memcpy(&ec_data.mac, &buf[0], sizeof (ETH_MAC));
eth_mac_fmt(&ec_data.mac, (char *)&buf[0]);
eth_copy_mac(ec_data.mac, &buf[0]);
eth_mac_fmt(ec_data.mac, (char *)&buf[0]);
sim_debug(DEBUG_CMD, dptr, "ec_srv setting mac %s\n", buf);
n = ec_data.macs_n + 2;
memcpy(&ec_data.macs[0], &ec_data.mac, sizeof (ETH_MAC));
memcpy(&ec_data.macs[1], &broadcast_ethaddr, sizeof (ETH_MAC));
eth_copy_mac(ec_data.macs[0], ec_data.mac);
eth_copy_mac(ec_data.macs[1], broadcast_ethaddr);
if (ec_master_uptr->flags & UNIT_ATT)
/* set promiscuous if bit 7 of byte zero of mac address is set */
eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc,
@ -846,13 +846,13 @@ t_stat ec_srv(UNIT *uptr)
}
if (i != sizeof (ETH_MAC))
break;
memcpy(&ec_data.macs[len++], &buf[0], sizeof (ETH_MAC));
eth_copy_mac(ec_data.macs[len++], &buf[0]);
}
ec_data.macs_n = len - 2;
ec_data.amc = 1;
for (i = 0; i< len; i++) {
eth_mac_fmt(&ec_data.macs[i], (char *)&buf[0]);
eth_mac_fmt(ec_data.macs[i], (char *) &buf[0]);
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv load mcast%d: %s\n",i,buf);
}
@ -946,7 +946,7 @@ t_stat ec_srv(UNIT *uptr)
}
}
/* insert 6 byte source from configuration */
memcpy(&hdr->src, ec_data.mac, sizeof(ETH_MAC));
eth_copy_mac(hdr->src, ec_data.mac);
/* copy two byte type/len from user buffer */
for (i = sizeof(ETH_MAC) * 2; i < sizeof(struct ec_eth_hdr); i++) {
@ -1023,7 +1023,7 @@ t_stat ec_srv(UNIT *uptr)
}
}
/* insert source(6) */
memcpy(&hdr->src, ec_data.mac, sizeof(ETH_MAC));
eth_copy_mac(hdr->src, ec_data.mac);
//#define USE_DATA_CNT
#ifdef USE_DATA_CNT
@ -1706,12 +1706,12 @@ void ec_packet_debug(struct ec_device *ec, const char *action,
if (!(ec_dev.dctrl & DEBUG_ARP))
return;
eth_mac_fmt(&arp->ethhdr.src, eth_src);
eth_mac_fmt(&arp->ethhdr.dest, eth_dst);
eth_mac_fmt(&arp->shwaddr, arp_shwaddr);
eth_mac_fmt(arp->ethhdr.src, eth_src);
eth_mac_fmt(arp->ethhdr.dest, eth_dst);
eth_mac_fmt(arp->shwaddr, arp_shwaddr);
memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr));
strlcpy(arp_sipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_sipaddr));
eth_mac_fmt(&arp->dhwaddr, arp_dhwaddr);
eth_mac_fmt(arp->dhwaddr, arp_dhwaddr);
memcpy(&in_addr, &arp->dipaddr, sizeof(in_addr));
strlcpy(arp_dipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_dipaddr));
sim_debug(DEBUG_ARP, &ec_dev,
@ -1806,7 +1806,7 @@ t_stat ec_set_mode (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
t_stat ec_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
{
char buffer[20];
eth_mac_fmt(&ec_data.mac, buffer);
eth_mac_fmt(ec_data.mac, buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -1818,7 +1818,7 @@ t_stat ec_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc)
if (!cptr) return SCPE_IERR;
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
status = eth_mac_scan_ex(&ec_data.mac, cptr, uptr);
status = eth_mac_scan_ex(ec_data.mac, cptr, uptr);
if (status != SCPE_OK)
return status;
@ -1866,16 +1866,16 @@ t_stat ec_attach(UNIT* uptr, CONST char* cptr)
if (tptr == NULL) return SCPE_MEM;
strcpy(tptr, cptr);
memcpy(&ec_data.macs[0], &ec_data.mac, sizeof (ETH_MAC));
memcpy(&ec_data.macs[1], &broadcast_ethaddr, sizeof (ETH_MAC));
eth_copy_mac(ec_data.macs[0], ec_data.mac);
eth_copy_mac(ec_data.macs[1], broadcast_ethaddr);
status = eth_open(&ec_data.etherface, cptr, &ec_dev, DEBUG_ETHER);
if (status != SCPE_OK) {
free(tptr);
return status;
}
eth_mac_fmt(&ec_data.mac, buf); /* format ethernet mac address */
eth_mac_fmt(ec_data.mac, buf); /* format ethernet mac address */
if (SCPE_OK != eth_check_address_conflict (&ec_data.etherface,
&ec_data.mac)) {
ec_data.mac)) {
eth_close(&ec_data.etherface);
free(tptr);
return sim_messagef (SCPE_NOATT,

View File

@ -81,7 +81,7 @@ t_stat nar_showmac (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
{
char buffer[20];
eth_mac_fmt ((ETH_MAC*)nar_mac, buffer);
eth_mac_fmt (nar_mac, buffer);
fprintf (st, "MAC=%s", buffer);
return SCPE_OK;
}
@ -92,7 +92,7 @@ t_stat status;
if (!cptr)
return SCPE_IERR;
status = eth_mac_scan (&nar_mac, cptr);
status = eth_mac_scan (nar_mac, cptr);
if (status != SCPE_OK)
return status;
nar_reset (&nar_dev);
@ -136,7 +136,7 @@ t_stat r;
if (!nar_init) { /* set initial MAC */
nar_init = TRUE;
r = eth_mac_scan (&nar_mac, "08:00:2B:00:00:00/24");
r = eth_mac_scan (nar_mac, "08:00:2B:00:00:00/24");
if (r != SCPE_OK)
return r;
}

View File

@ -645,7 +645,7 @@ xs->var->csr0 = xs->var->csr0 | CSR0_INIT;
xs->var->csr0 = xs->var->csr0 & ~CSR0_STOP;
/* reset ethernet interface */
memcpy (xs->var->setup.macs[0], xs->var->mac, sizeof(ETH_MAC));
eth_copy_mac(xs->var->setup.macs[0], xs->var->mac);
xs->var->setup.mac_count = 1;
if (xs->var->etherface)
eth_filter (xs->var->etherface, xs->var->setup.mac_count,

View File

@ -391,25 +391,25 @@ static int _eth_get_system_id (char *buf, size_t buf_size);
static void eth_get_nic_hw_addr(ETH_DEV* dev, const char *devname, int set_on);
static const unsigned char framer_oui[3] = { 0xaa, 0x00, 0x03 };
const ETH_MAC eth_mac_any = {0, 0, 0, 0, 0, 0};
const ETH_MAC eth_mac_bcast = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
/*============================================================================*/
/* OS-independent ethernet routines */
/*============================================================================*/
t_stat eth_mac_scan (ETH_MAC* mac, const char* strmac)
t_stat eth_mac_scan (ETH_MAC mac, const char* strmac)
{
return eth_mac_scan_ex (mac, strmac, NULL);
}
t_stat eth_mac_scan_ex (ETH_MAC* mac, const char* strmac, UNIT *uptr)
t_stat eth_mac_scan_ex (ETH_MAC mac, const char* strmac, UNIT *uptr)
{
unsigned int a[6], g[6];
FILE *f;
char filebuf[64] = "";
uint32 i;
static const ETH_MAC zeros = {0,0,0,0,0,0};
static const ETH_MAC ones = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
ETH_MAC newmac;
ETH_MAC newmac = {0, 0, 0, 0, 0, 0};
struct {
uint32 bits;
char system_id[64];
@ -475,8 +475,8 @@ t_stat eth_mac_scan_ex (ETH_MAC* mac, const char* strmac, UNIT *uptr)
}
/* final check - mac cannot be broadcast or multicast address */
if (!memcmp(newmac, zeros, sizeof(ETH_MAC)) || /* broadcast */
!memcmp(newmac, ones, sizeof(ETH_MAC)) || /* broadcast */
if (!eth_mac_cmp(newmac, eth_mac_any) || /* broadcast */
!eth_mac_cmp(newmac, eth_mac_bcast) || /* broadcast */
(newmac[0] & 0x01) /* multicast */
)
return sim_messagef (SCPE_ARG, "Can't use Broadcast or MultiCast address as interface MAC address\n");
@ -487,29 +487,28 @@ t_stat eth_mac_scan_ex (ETH_MAC* mac, const char* strmac, UNIT *uptr)
f = fopen (state.file, "w");
if (f == NULL)
return sim_messagef (SCPE_ARG, "Can't open MAC address configuration file '%s'.\n", state.file);
eth_mac_fmt (&newmac, filebuf);
eth_mac_fmt (newmac, filebuf);
fprintf (f, "%s/48\n", filebuf);
fprintf (f, "system-id: %s\n", state.system_id);
fprintf (f, "directory: %s\n", state.cwd);
fprintf (f, "simulator: %s\n", state.sim);
fprintf (f, "device: %s\n", state.uname);
fprintf (f, "file: %s\n", state.file);
eth_mac_fmt (&state.base_mac, filebuf);
eth_mac_fmt (state.base_mac, filebuf);
fprintf (f, "base-mac: %s\n", filebuf);
fprintf (f, "specified: %d bits\n", state.bits);
fprintf (f, "generated: %d bits\n", 48-state.bits);
fclose (f);
}
/* copy into passed mac */
memcpy (*mac, newmac, sizeof(ETH_MAC));
eth_copy_mac (mac, newmac);
return SCPE_OK;
}
void eth_mac_fmt(ETH_MAC* const mac, char* buff)
void eth_mac_fmt(const ETH_MAC mac, char* buff)
{
const uint8* m = (const uint8*) mac;
const uint8* m = (const uint8 *) mac;
sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X", m[0], m[1], m[2], m[3], m[4], m[5]);
return;
}
static const uint32 crcTable[256] = {
@ -620,8 +619,8 @@ void eth_packet_trace_ex(ETH_DEV* dev, const uint8 *msg, int len, const char* tx
char dst[20];
const unsigned short* proto = (const unsigned short*) &msg[12];
uint32 crc = eth_crc32(0, msg, len);
eth_mac_fmt((ETH_MAC*)msg, dst);
eth_mac_fmt((ETH_MAC*)(msg+6), src);
eth_mac_fmt(msg, dst);
eth_mac_fmt(msg + 6, src);
sim_debug(reason, dev->dptr, "%s dst: %s src: %s proto: 0x%04X len: %d crc: %X\n",
txt, dst, src, ntohs(*proto), len, crc);
if (detail) {
@ -630,7 +629,7 @@ void eth_packet_trace_ex(ETH_DEV* dev, const uint8 *msg, int len, const char* tx
static const char hex[] = "0123456789ABCDEF";
for (i=same=0; i<len; i += 16) {
if ((i > 0) && (0 == memcmp(&msg[i], &msg[i-16], 16))) {
if ((i > 0) && (0 == eth_mac_cmp(&msg[i], &msg[i-16]))) {
++same;
continue;
}
@ -784,6 +783,8 @@ ethq_insert_data(que, type, pack->oversize ? pack->oversize : pack->msg, pack->u
t_stat eth_show_devices (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, CONST char *desc)
{
(void) dptr;
(void) desc;
return eth_show (st, uptr, val, NULL);
}
@ -878,8 +879,11 @@ static char *(*p_pcap_lib_version) (void);
static void _eth_add_to_open_list (ETH_DEV* dev)
{
eth_open_devices = (ETH_DEV**)realloc(eth_open_devices, (eth_open_device_count+1)*sizeof(*eth_open_devices));
eth_open_devices[eth_open_device_count++] = dev;
ETH_DEV **tmp = (ETH_DEV**)realloc(eth_open_devices, (eth_open_device_count+1)*sizeof(*eth_open_devices));
if (tmp != NULL) {
eth_open_devices = tmp;
eth_open_devices[eth_open_device_count++] = dev;
}
}
static void _eth_remove_from_open_list (ETH_DEV* dev)
@ -900,6 +904,11 @@ t_stat eth_show (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
ETH_LIST list[ETH_MAX_DEVICE];
int number;
/* Squelch unused parameters. But do we really need them? */
(void) uptr;
(void) val;
(void) desc;
number = eth_devices(ETH_MAX_DEVICE, list, FALSE);
fprintf(st, "ETH devices:\n");
if (number == -1)
@ -917,11 +926,11 @@ t_stat eth_show (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
}
if (eth_open_device_count) {
int i;
char desc[ETH_DEV_DESC_MAX], *d;
char devdesc[ETH_DEV_DESC_MAX], *d;
fprintf(st,"Open ETH Devices:\n");
for (i=0; i<eth_open_device_count; i++) {
d = eth_getdesc_byname(eth_open_devices[i]->name, desc);
d = eth_getdesc_byname(eth_open_devices[i]->name, devdesc);
if (d)
fprintf(st, " %-7s%s (%s)\n", eth_open_devices[i]->dptr->name, eth_open_devices[i]->dptr->units[0].filename, d);
else
@ -950,8 +959,7 @@ t_stat eth_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const cha
fprintf (st, "This simulator was not built with ethernet device support\n");
return SCPE_OK;
}
t_stat eth_check_address_conflict (ETH_DEV* dev,
ETH_MAC* const mac)
t_stat eth_check_address_conflict (ETH_DEV* dev, const ETH_MAC mac)
{return SCPE_NOFNC;}
t_stat eth_set_throttle (ETH_DEV* dev, uint32 time, uint32 burst, uint32 delay)
{return SCPE_NOFNC;}
@ -963,13 +971,13 @@ t_stat eth_write (ETH_DEV* dev, ETH_PACK* packet, ETH_PCALLBACK routine)
{return SCPE_NOFNC;}
int eth_read (ETH_DEV* dev, ETH_PACK* packet, ETH_PCALLBACK routine)
{return SCPE_NOFNC;}
t_stat eth_filter (ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
t_stat eth_filter (ETH_DEV* dev, int addr_count, const ETH_MAC addresses[],
ETH_BOOL all_multicast, ETH_BOOL promiscuous)
{return SCPE_NOFNC;}
t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, const ETH_MAC addresses[],
ETH_BOOL all_multicast, ETH_BOOL promiscuous, ETH_MULTIHASH* const hash)
{return SCPE_NOFNC;}
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, const ETH_MAC addresses[],
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
{return SCPE_NOFNC;}
@ -2936,7 +2944,7 @@ return (rand() & 0xFF);
}
t_stat eth_check_address_conflict_ex (ETH_DEV* dev,
ETH_MAC* const mac,
const ETH_MAC mac,
int *reflections,
t_bool silent)
{
@ -2953,9 +2961,9 @@ eth_mac_fmt(mac, mac_string);
sim_debug(dev->dbit, dev->dptr, "Determining Address Conflict for MAC address: %s\n", mac_string);
/* 00:00:00:00:00:00 or any address with a multi-cast address is invalid */
if ((((*mac)[0] == 0) && ((*mac)[1] == 0) && ((*mac)[2] == 0) &&
((*mac)[3] == 0) && ((*mac)[4] == 0) && ((*mac)[5] == 0)) ||
((*mac)[0] & 1)) {
if (((mac[0] == 0) && (mac[1] == 0) && (mac[2] == 0) &&
(mac[3] == 0) && (mac[4] == 0) && (mac[5] == 0)) ||
(mac[0] & 1)) {
return sim_messagef (SCPE_ARG, "%s: Invalid NIC MAC Address: %s\n", sim_dname(dev->dptr), mac_string);
}
@ -3024,15 +3032,15 @@ memset (&send, 0, sizeof(ETH_PACK));
send.len = ETH_MIN_PACKET; /* minimum packet size */
for (i=0; i<send.len; i++)
send.msg[i] = _eth_rand_byte();
memcpy(&send.msg[0], mac, sizeof(ETH_MAC)); /* target address */
memcpy(&send.msg[6], mac, sizeof(ETH_MAC)); /* source address */
eth_copy_mac(&send.msg[0], mac); /* target address */
eth_copy_mac(&send.msg[6], mac); /* source address */
send.msg[12] = 0x90; /* loopback packet type */
send.msg[13] = 0;
send.msg[14] = 0; /* Offset */
send.msg[15] = 0;
send.msg[16] = 2; /* Forward */
send.msg[17] = 0;
memcpy(&send.msg[18], mac, sizeof(ETH_MAC)); /* Forward Destination */
eth_copy_mac(&send.msg[18], mac); /* Forward Destination */
send.msg[24] = 1; /* Reply */
send.msg[25] = 0;
@ -3079,13 +3087,12 @@ if (reflections)
return SCPE_OK;
}
t_stat eth_check_address_conflict (ETH_DEV* dev,
ETH_MAC* const mac)
t_stat eth_check_address_conflict (ETH_DEV* dev, const ETH_MAC mac)
{
char mac_string[32];
eth_mac_fmt(mac, mac_string);
if (0 == memcmp (mac, dev->host_nic_phy_hw_addr, sizeof *mac))
if (0 == eth_mac_cmp (mac, dev->host_nic_phy_hw_addr))
return sim_messagef (SCPE_OK, "Sharing the host NIC MAC address %s may cause unexpected behavior\n", mac_string);
return eth_check_address_conflict_ex (dev, mac, NULL, FALSE);
}
@ -3101,7 +3108,7 @@ static ETH_MAC mac = {0xfe,0xff,0xff,0xff,0xff,0xfe};
sim_debug(dev->dbit, dev->dptr, "Determining Reflections...\n");
r = eth_check_address_conflict_ex (dev, &mac, &dev->reflections, TRUE);
r = eth_check_address_conflict_ex (dev, mac, &dev->reflections, TRUE);
if (r != SCPE_OK)
return sim_messagef (r, "eth: Error determining reflection count\n");
@ -3225,8 +3232,8 @@ if ((packet->len >= ETH_MIN_PACKET) && (packet->len <= ETH_MAX_PACKET)) {
/* Direct loopback responses to the host physical address since our physical address
may not have been learned yet. */
if (loopback_self_frame && dev->have_host_nic_phy_addr) {
memcpy(&packet->msg[6], dev->host_nic_phy_hw_addr, sizeof(ETH_MAC));
memcpy(&packet->msg[18], dev->host_nic_phy_hw_addr, sizeof(ETH_MAC));
eth_copy_mac(&packet->msg[6], dev->host_nic_phy_hw_addr);
eth_copy_mac(&packet->msg[18], dev->host_nic_phy_hw_addr);
eth_packet_trace (dev, packet->msg, packet->len, "writing-fixed");
}
#ifdef USE_READER_THREAD
@ -3327,7 +3334,6 @@ t_stat eth_write(ETH_DEV* dev, ETH_PACK* packet, ETH_PCALLBACK routine)
{
#ifdef USE_READER_THREAD
ETH_WRITE_REQUEST *request;
int write_queue_size = 1;
/* make sure device exists */
if ((!dev) || (dev->eth_api == ETH_API_NONE)) return SCPE_UNATT;
@ -3339,11 +3345,12 @@ if (packet->len > sizeof (packet->msg)) /* packet oversized? */
pthread_mutex_lock (&dev->writer_lock);
if (NULL != (request = dev->write_buffers))
dev->write_buffers = request->next;
pthread_mutex_unlock (&dev->writer_lock);
if (NULL == request)
request = (ETH_WRITE_REQUEST *)malloc(sizeof(*request));
/* Copy buffer contents */
request->next = NULL;
request->packet.len = packet->len;
request->packet.used = packet->used;
request->packet.status = packet->status;
@ -3352,25 +3359,21 @@ memcpy(request->packet.msg, packet->msg, packet->len);
/* Insert buffer at the end of the write list (to make sure that */
/* packets make it to the wire in the order they were presented here) */
pthread_mutex_lock (&dev->writer_lock);
request->next = NULL;
if (dev->write_requests) {
ETH_WRITE_REQUEST *last_request = dev->write_requests;
{
int write_queue_size = 1;
ETH_WRITE_REQUEST **last_request = &dev->write_requests;
++write_queue_size;
while (last_request->next) {
last_request = last_request->next;
while (*last_request != NULL) {
last_request = &(*last_request)->next;
++write_queue_size;
}
last_request->next = request;
*last_request = request;
if (write_queue_size > dev->write_queue_peak)
dev->write_queue_peak = write_queue_size;
}
else
dev->write_requests = request;
if (write_queue_size > dev->write_queue_peak)
dev->write_queue_peak = write_queue_size;
pthread_mutex_unlock (&dev->writer_lock);
/* Awaken writer thread to perform actual write */
pthread_mutex_unlock (&dev->writer_lock);
pthread_cond_signal (&dev->writer_cond);
/* Return with a status from some prior write */
@ -3848,7 +3851,7 @@ if (function != 2) /*forward*/
(we may receive others if we're in promiscuous mode, but shouldn't
respond to them) */
if ((0 == (data[0]&1)) && /* Multicast or Broadcast */
(0 != memcmp(dev->filter_address[0], data, sizeof(ETH_MAC))))
(0 != eth_mac_cmp(dev->filter_address[0], data)))
return 0;
/* Attempts to forward to multicast or broadcast addresses are explicitly
@ -3864,8 +3867,8 @@ sim_debug(dev->dbit, dev->dptr, "_eth_process_loopback()\n");
memset(&response, 0, sizeof(response));
response.len = len;
memcpy(response.msg, data, len);
memcpy(&response.msg[0], &response.msg[offset+2], sizeof(ETH_MAC));
memcpy(&response.msg[6], dev->filter_address[0], sizeof(ETH_MAC));
eth_copy_mac(&response.msg[0], &response.msg[offset+2]);
eth_copy_mac(&response.msg[6], dev->filter_address[0]);
offset += 8 - 16; /* Account for the Ethernet Header and Offset value in this number */
response.msg[14] = offset & 0xFF;
response.msg[15] = (offset >> 8) & 0xFF;
@ -3896,8 +3899,8 @@ if (LOOPBACK_PHYSICAL_RESPONSE(dev, data)) {
host's interface instead of the programmatically set physical address of this pseudo
device, we restore parts of the modified packet back as needed */
memcpy(datacopy, data, header->len);
memcpy(datacopy, dev->physical_addr, sizeof(ETH_MAC));
memcpy(datacopy+18, dev->physical_addr, sizeof(ETH_MAC));
eth_copy_mac(datacopy, dev->physical_addr);
eth_copy_mac(datacopy+18, dev->physical_addr);
_eth_callback(info, header, datacopy);
free(datacopy);
return;
@ -3980,7 +3983,7 @@ if (bpf_used ? to_me : (to_me && !from_me)) {
#if defined (USE_READER_THREAD)
if (1) {
int crc_len = 0;
uint8 crc_data[4];
uint8 crc_data[4] = { 0, 0, 0, 0 };
uint32 len = header->len;
u_char *moved_data = NULL;
@ -4195,8 +4198,8 @@ return status;
t_stat eth_bpf_filter (ETH_DEV* dev, int addr_count, ETH_MAC* const filter_address,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
int reflections,
ETH_MAC* physical_addr,
ETH_MAC* host_nic_phy_hw_addr,
ETH_MAC physical_addr,
ETH_MAC host_nic_phy_hw_addr,
ETH_MULTIHASH* const hash,
char *buf)
{
@ -4212,7 +4215,7 @@ strcpy(buf, "");
our simulated interface doesn't want. */
if (!promiscuous) {
for (i = 0; i < addr_count; i++) {
eth_mac_fmt(&filter_address[i], mac);
eth_mac_fmt(filter_address[i], mac);
if (!strstr(buf, mac)) /* eliminate duplicates */
sprintf(&buf[strlen(buf)], "%s(ether dst %s)", (*buf) ? " or " : "((", mac);
}
@ -4236,7 +4239,7 @@ if ((addr_count > 0) && (reflections > 0)) {
buf2 = &buf[strlen(buf)];
for (i = 0; i < addr_count; i++) {
if (filter_address[i][0] & 0x01) continue; /* skip multicast addresses */
eth_mac_fmt(&filter_address[i], mac);
eth_mac_fmt(filter_address[i], mac);
if (!strstr(buf2, mac)) /* only process each address once */
sprintf(&buf2[strlen(buf2)], "%s(ether src %s)", (*buf2) ? " or " : "", mac);
}
@ -4268,14 +4271,12 @@ if (strlen(buf) > 0)
simulated machine. */
/* check for physical address in filters */
if ((!promiscuous) && (addr_count) && (reflections > 0)) {
eth_mac_fmt(&physical_addr[0], mac);
eth_mac_fmt(physical_addr, mac);
if (strcmp(mac, "00:00:00:00:00:00") != 0) {
/* let packets through where dst and src are the same as our physical address */
sprintf (&buf[strlen(buf)], " or ((ether dst %s) and (ether src %s))", mac, mac);
if (host_nic_phy_hw_addr) {
eth_mac_fmt(&host_nic_phy_hw_addr[0], mac);
sprintf(&buf[strlen(buf)], " or ((ether dst %s) and (ether proto 0x9000))", mac);
}
eth_mac_fmt(host_nic_phy_hw_addr, mac);
sprintf(&buf[strlen(buf)], " or ((ether dst %s) and (ether proto 0x9000))", mac);
}
}
if ((0 == strlen(buf)) && (!promiscuous)) /* Empty filter means match nothing */
@ -4284,7 +4285,7 @@ sim_debug(dev->dbit, dev->dptr, "BPF string is: |%s|\n", buf);
return SCPE_OK;
}
t_stat eth_filter(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
t_stat eth_filter(ETH_DEV* dev, int addr_count, const ETH_MAC addresses[],
ETH_BOOL all_multicast, ETH_BOOL promiscuous)
{
return eth_filter_hash_ex(dev, addr_count, addresses,
@ -4292,7 +4293,7 @@ return eth_filter_hash_ex(dev, addr_count, addresses,
NULL);
}
t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, const ETH_MAC addresses[],
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_MULTIHASH* const hash)
{
@ -4301,7 +4302,7 @@ return eth_filter_hash_ex(dev, addr_count, addresses,
hash);
}
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, const ETH_MAC addresses[],
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
{
@ -4330,7 +4331,7 @@ if (dev->reflections == -1)
/* set new filter addresses */
for (i = 0; i < addr_count; i++)
memcpy(dev->filter_address[i], addresses[i], sizeof(ETH_MAC));
eth_copy_mac(dev->filter_address[i], addresses[i]);
dev->addr_count = addr_count;
if (match_broadcast) {
memset(&dev->filter_address[addr_count], 0xFF, sizeof(ETH_MAC));
@ -4355,9 +4356,9 @@ if (hash) {
if (dev->dptr->dctrl & dev->dbit) {
sim_debug(dev->dbit, dev->dptr, "Filter Set\n");
for (i = 0; i < addr_count; i++) {
char mac[20];
eth_mac_fmt(&dev->filter_address[i], mac);
sim_debug(dev->dbit, dev->dptr, " Addr[%d]: %s\n", i, mac);
char macaddr[20];
eth_mac_fmt(dev->filter_address[i], macaddr);
sim_debug(dev->dbit, dev->dptr, " Addr[%d]: %s\n", i, macaddr);
}
if (dev->all_multicast) {
sim_debug(dev->dbit, dev->dptr, "All Multicast\n");
@ -4376,9 +4377,9 @@ dev->loopback_self_sent = 0;
for (i = 0; i < addr_count; i++) {
if (dev->filter_address[i][0]&1)
continue; /* skip all multicast addresses */
eth_mac_fmt(&dev->filter_address[i], mac);
eth_mac_fmt(dev->filter_address[i], mac);
if (strcmp(mac, "00:00:00:00:00:00") != 0) {
memcpy(dev->physical_addr, &dev->filter_address[i], sizeof(ETH_MAC));
eth_copy_mac(dev->physical_addr, dev->filter_address[i]);
break;
}
}
@ -4389,8 +4390,8 @@ for (i = 0; i < addr_count; i++) {
/* setup BPF filters and other fields to minimize packet delivery */
eth_bpf_filter (dev, dev->addr_count, dev->filter_address,
dev->all_multicast, dev->promiscuous,
dev->reflections, &dev->physical_addr,
dev->have_host_nic_phy_addr ? &dev->host_nic_phy_hw_addr: NULL,
dev->reflections, dev->physical_addr,
dev->host_nic_phy_hw_addr,
(dev->hash_filter ? &dev->hash : NULL), buf);
/* get netmask, which is a required argument for compiling. The value,
@ -4414,9 +4415,9 @@ if (dev->eth_api == ETH_API_PCAP) {
sim_printf ("Eth: Reflections: %d\n", dev->reflections);
sim_printf ("Eth: Filter Set:\n");
for (i = 0; i < addr_count; i++) {
char mac[20];
eth_mac_fmt(&dev->filter_address[i], mac);
sim_printf ("Eth: Addr[%d]: %s\n", i, mac);
char macaddr[20];
eth_mac_fmt(dev->filter_address[i], macaddr);
sim_printf ("Eth: Addr[%d]: %s\n", i, macaddr);
}
if (dev->all_multicast)
sim_printf ("Eth: All Multicast\n");
@ -4427,7 +4428,7 @@ if (dev->eth_api == ETH_API_PCAP) {
dev->hash[0], dev->hash[1], dev->hash[2], dev->hash[3],
dev->hash[4], dev->hash[5], dev->hash[6], dev->hash[7]);
if (dev->have_host_nic_phy_addr) {
eth_mac_fmt(&dev->host_nic_phy_hw_addr, mac);
eth_mac_fmt(dev->host_nic_phy_hw_addr, mac);
sim_printf ("Eth: host_nic_phy_hw_addr: %s\n", mac);
}
}
@ -4474,7 +4475,7 @@ fprintf(st, " Self Loopbacks Rcvd: %d\n", dev->loopback_self_rcvd_total);
if (dev->have_host_nic_phy_addr) {
char hw_mac[20];
eth_mac_fmt(&dev->host_nic_phy_hw_addr, hw_mac);
eth_mac_fmt(dev->host_nic_phy_hw_addr, hw_mac);
fprintf(st, " Host NIC Address: %s\n", hw_mac);
}
if (dev->jumbo_dropped)
@ -4512,12 +4513,11 @@ if (dev->error_reopen_count)
fprintf(st, " Error Reopen Count: %d\n", (int)dev->error_reopen_count);
if (1) {
int i, count = 0;
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
char buffer[20];
for (i = 0; i < ETH_FILTER_MAX; i++) {
if (memcmp(zeros, &dev->filter_address[i], sizeof(ETH_MAC))) {
eth_mac_fmt(&dev->filter_address[i], buffer);
if (eth_mac_cmp(eth_mac_any, dev->filter_address[i])) {
eth_mac_fmt(dev->filter_address[i], buffer);
fprintf(st, " MAC Filter[%2d]: %s\n", count++, buffer);
}
}
@ -4622,7 +4622,7 @@ int bpf_compile_skip_count = 0;
sim_printf ("Eth: Reflections: %d\n", reflections); \
sim_printf ("Eth: Filter Set:\n"); \
for (i = 0; i < addr_count; i++) { \
eth_mac_fmt(&filter_address[i], mac); \
eth_mac_fmt(filter_address[i], mac); \
sim_printf ("Eth: Addr[%d]: %s\n", i, mac); \
} \
if (all_multicast) \
@ -4634,7 +4634,7 @@ int bpf_compile_skip_count = 0;
(*hash_list[hash_listindex])[0], (*hash_list[hash_listindex])[1], (*hash_list[hash_listindex])[2], (*hash_list[hash_listindex])[3], \
(*hash_list[hash_listindex])[4], (*hash_list[hash_listindex])[5], (*hash_list[hash_listindex])[6], (*hash_list[hash_listindex])[7]);\
if (host_phy_addr_list[host_phy_addr_listindex]) { \
eth_mac_fmt(host_phy_addr_list[host_phy_addr_listindex], mac);\
eth_mac_fmt(*host_phy_addr_list[host_phy_addr_listindex], mac);\
sim_printf ("Eth: host_nic_phy_hw_addr: %s\n", mac); \
} \
}
@ -4671,8 +4671,8 @@ for (eth_num=0; eth_num<eth_device_count; eth_num++) {
++bpf_count;
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
all_multicast, promiscuous, reflections,
&filter_address[0],
host_phy_addr_list[host_phy_addr_listindex],
filter_address[0],
*host_phy_addr_list[host_phy_addr_listindex],
hash_list[hash_listindex],
buf);
if (r != SCPE_OK) {

View File

@ -341,22 +341,22 @@ t_stat eth_write (ETH_DEV* dev, ETH_PACK* packet, /* write synchronous pac
int eth_read (ETH_DEV* dev, ETH_PACK* packet, /* read single packet; */
ETH_PCALLBACK routine); /* callback when done*/
t_stat eth_filter (ETH_DEV* dev, int addr_count, /* set filter on incoming packets */
ETH_MAC* const addresses,
const ETH_MAC addresses[],
ETH_BOOL all_multicast,
ETH_BOOL promiscuous);
t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, /* set filter on incoming packets with hash */
ETH_MAC* const addresses,
const ETH_MAC addresses[],
ETH_BOOL all_multicast,
ETH_BOOL promiscuous,
ETH_MULTIHASH* const hash); /* AUTODIN II based 8 byte imperfect hash */
t_stat eth_filter_hash_ex (ETH_DEV* dev, int addr_count,/* set filter on incoming packets with hash */
ETH_MAC* const addresses,
const ETH_MAC addresses[],
ETH_BOOL all_multicast,
ETH_BOOL promiscuous,
ETH_BOOL match_broadcast,
ETH_MULTIHASH* const hash); /* AUTODIN II based 8 byte imperfect hash */
t_stat eth_check_address_conflict (ETH_DEV* dev,
ETH_MAC* const address);
const ETH_MAC address);
const char *eth_version (void); /* Version of dynamically loaded library (pcap) */
void eth_setcrc (ETH_DEV* dev, int need_crc); /* enable/disable CRC mode */
t_stat eth_set_async (ETH_DEV* dev, int latency); /* set read behavior to be async */
@ -373,9 +373,9 @@ t_stat eth_show_devices (FILE* st, DEVICE *dptr, /* show ethernet devices
int eth_devices (int max, ETH_LIST* dev, ETH_BOOL framers); /* get ethernet devices on host */
void eth_show_dev (FILE*st, ETH_DEV* dev); /* show ethernet device state */
void eth_mac_fmt (ETH_MAC* const add, char* buffer); /* format ethernet mac address */
t_stat eth_mac_scan (ETH_MAC* mac, const char* strmac); /* scan string for mac, put in mac */
t_stat eth_mac_scan_ex (ETH_MAC* mac, /* scan string for mac, put in mac */
void eth_mac_fmt (const ETH_MAC add, char* buffer); /* format ethernet mac address */
t_stat eth_mac_scan (ETH_MAC mac, const char* strmac); /* scan string for mac, put in mac */
t_stat eth_mac_scan_ex (ETH_MAC mac, /* scan string for mac, put in mac */
const char* strmac, UNIT *uptr);/* for specified unit */
t_stat ethq_init (ETH_QUE* que, int max); /* initialize FIFO queue */
@ -390,6 +390,44 @@ t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */
const char *eth_capabilities(void);
t_stat sim_ether_test (DEVICE *dptr, const char *cptr); /* unit test routine */
/* Well-known Ethernet MAC addresses:
*
* eth_mac_any: All zeroes/any address
* eth_mac_bcast: All ones broadcast.
*/
extern const ETH_MAC eth_mac_any;
extern const ETH_MAC eth_mac_bcast;
/* Type-enforcing MAC address copy function.
*
* This inline helps to prevent the following situation:
*
* void network_func(DEVICE *dev, ETH_MAC *mac)
* {
* ETH_MAC other_mac;
*
* ...
* memcpy(other_mac, mac, sizeof(ETH_MAC));
* }
*
* The compiler will happily accept the memcpy() as valid because src and dst are
* converted to "void *". This is a subtle bug -- mac is a pointer to an ETH_MAC
* and memcpy will copy from somewhere other than the first byte of the source MAC
* address.
*/
static inline void eth_copy_mac(ETH_MAC dst, const ETH_MAC src)
{
memcpy(dst, src, sizeof(ETH_MAC));
}
/* Type-enforcing MAC comparison function. Helps to avoid subtle memcmp() issues
* (see above).
*/
static inline int eth_mac_cmp(const ETH_MAC a, const ETH_MAC b)
{
return memcmp(a, b, sizeof(ETH_MAC));
}
#if !defined(SIM_TEST_INIT) /* Need stubs for test APIs */
#define SIM_TEST_INIT
#define SIM_TEST(xxx)