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:
parent
73e5df3928
commit
c20b391eea
10
3B2/3b2_ni.c
10
3B2/3b2_ni.c
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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(ð->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, ð->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 */
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
182
sim_ether.c
182
sim_ether.c
@ -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) {
|
||||
|
||||
52
sim_ether.h
52
sim_ether.h
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user