diff --git a/BasiliskII/src/BeOS/ether_beos.cpp b/BasiliskII/src/BeOS/ether_beos.cpp index 801ba195..a50fc11b 100644 --- a/BasiliskII/src/BeOS/ether_beos.cpp +++ b/BasiliskII/src/BeOS/ether_beos.cpp @@ -461,17 +461,18 @@ void ether_stop_udp_thread(void) void EtherInterrupt(void) { D(bug("EtherIRQ\n")); + EthernetPacket ether_packet; + uint32 packet = ether_packet.addr(); if (udp_tunnel) { - uint8 packet[1514]; ssize_t length; // Read packets from socket and hand to ether_udp_read() for processing while (true) { struct sockaddr_in from; socklen_t from_len = sizeof(from); - length = recvfrom(fd, packet, 1514, 0, (struct sockaddr *)&from, &from_len); + length = recvfrom(fd, Mac2HostAddr(packet), 1514, 0, (struct sockaddr *)&from, &from_len); if (length < 14) break; ether_udp_read(packet, length, &from); @@ -483,15 +484,16 @@ void EtherInterrupt(void) net_packet *p = &net_buffer_ptr->read[rd_pos]; while (p->cmd & IN_USE) { if ((p->cmd >> 8) == SHEEP_PACKET) { + Host2Mac_memcpy(packet, p->data, p->length); #if MONITOR bug("Receiving Ethernet packet:\n"); for (int i=0; ilength; i++) { - bug("%02x ", p->data[i]); + bug("%02x ", ReadMacInt8(packet + i)); } bug("\n"); #endif // Get packet type - uint16 type = ntohs(*(uint16 *)(p->data + 12)); + uint16 type = ReadMacInt16(packet + 12); // Look for protocol NetProtocol *prot = find_protocol(type); @@ -503,14 +505,14 @@ void EtherInterrupt(void) goto next; // Copy header to RHA - Host2Mac_memcpy(ether_data + ed_RHA, p->data, 14); + Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14); D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); // Call protocol handler M68kRegisters r; r.d[0] = type; // Packet type r.d[1] = p->length - 14; // Remaining packet length (without header, for ReadPacket) - r.a[0] = (uint32)p->data + 14; // Pointer to packet (host address, for ReadPacket) + r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket) r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index ebfd1978..84e62bad 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -466,8 +466,8 @@ void EtherInterrupt(void) D(bug("EtherIRQ\n")); // Call protocol handler for received packets - // NOTE: "static" so that packet[] has a 32-bit address (.data section, not stack) - static uint8 packet[1516]; + EthernetPacket ether_packet; + uint32 packet = ether_packet.addr(); ssize_t length; for (;;) { @@ -476,7 +476,7 @@ void EtherInterrupt(void) // Read packet from socket struct sockaddr_in from; socklen_t from_len = sizeof(from); - length = recvfrom(fd, packet, 1514, 0, (struct sockaddr *)&from, &from_len); + length = recvfrom(fd, Mac2HostAddr(packet), 1514, 0, (struct sockaddr *)&from, &from_len); if (length < 14) break; ether_udp_read(packet, length, &from); @@ -485,9 +485,9 @@ void EtherInterrupt(void) // Read packet from sheep_net device #if defined(__linux__) - length = read(fd, packet, net_if_type == NET_IF_ETHERTAP ? 1516 : 1514); + length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514); #else - length = read(fd, packet, 1514); + length = read(fd, Mac2HostAddr(packet), 1514); #endif if (length < 14) break; @@ -495,13 +495,13 @@ void EtherInterrupt(void) #if MONITOR bug("Receiving Ethernet packet:\n"); for (int i=0; i 0 ) { + while( (length = dequeue_packet(Mac2HostAddr(packet))) > 0 ) { if (length < 14) continue; #if MONITOR bug("Receiving Ethernet packet (%d bytes):\n",(int)length); - dump_packet( packet, length ); + dump_packet( Mac2HostAddr(packet), length ); #endif // Get packet type - uint16 type = ntohs(*(uint16 *)(packet + 12)); + uint16 type = ReadMacInt16(packet + 12); // Look for protocol NetProtocol *prot = find_protocol(type); @@ -1067,7 +1068,7 @@ void EtherInterrupt(void) // break; // Copy header to RHA - memcpy(Mac2HostAddr(ether_data + ed_RHA), packet, 14); + Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14); D(bug(" header %08lx%04lx %08lx%04lx %04lx\r\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); // Call protocol handler @@ -1075,7 +1076,7 @@ void EtherInterrupt(void) r.d[0] = type; // Packet type r.d[1] = length - 14; // Remaining packet length (without header, for ReadPacket) - r.a[0] = (uint32)packet + 14; // Pointer to packet (host address, for ReadPacket) + r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket) r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\r\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); diff --git a/BasiliskII/src/emul_op.cpp b/BasiliskII/src/emul_op.cpp index c5d2daff..b51c0e4a 100644 --- a/BasiliskII/src/emul_op.cpp +++ b/BasiliskII/src/emul_op.cpp @@ -353,7 +353,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r) break; case M68K_EMUL_OP_ETHER_READ_PACKET: - EtherReadPacket((uint8 **)&r->a[0], r->a[3], r->d[3], r->d[1]); + EtherReadPacket(r->a[0], r->a[3], r->d[3], r->d[1]); break; case M68K_EMUL_OP_SOUNDIN_OPEN: // Sound input driver functions diff --git a/BasiliskII/src/ether.cpp b/BasiliskII/src/ether.cpp index 3d87de37..b4924250 100644 --- a/BasiliskII/src/ether.cpp +++ b/BasiliskII/src/ether.cpp @@ -390,12 +390,12 @@ int16 EtherControl(uint32 pb, uint32 dce) * Ethernet ReadPacket routine */ -void EtherReadPacket(uint8 **src, uint32 &dest, uint32 &len, uint32 &remaining) +void EtherReadPacket(uint32 &src, uint32 &dest, uint32 &len, uint32 &remaining) { - D(bug("EtherReadPacket src %p, dest %08x, len %08x, remaining %08x\n", *src, dest, len, remaining)); + D(bug("EtherReadPacket src %08x, dest %08x, len %08x, remaining %08x\n", src, dest, len, remaining)); uint32 todo = len > remaining ? remaining : len; - Host2Mac_memcpy(dest, *src, todo); - *src += todo; + Mac2Mac_memcpy(dest, src, todo); + src += todo; dest += todo; len -= todo; remaining -= todo; @@ -407,22 +407,22 @@ void EtherReadPacket(uint8 **src, uint32 &dest, uint32 &len, uint32 &remaining) * Read packet from UDP socket */ -void ether_udp_read(uint8 *packet, int length, struct sockaddr_in *from) +void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from) { // Drop packets sent by us - if (memcmp(packet + 6, ether_addr, 6) == 0) + if (memcmp(Mac2HostAddr(packet) + 6, ether_addr, 6) == 0) return; #if MONITOR bug("Receiving Ethernet packet:\n"); for (int i=0; i 0) { + bug("WARNING: Nested allocation of ethernet packets!\n"); + } +} +#endif diff --git a/BasiliskII/src/include/ether.h b/BasiliskII/src/include/ether.h index 040a71d9..70ed4f4f 100644 --- a/BasiliskII/src/include/ether.h +++ b/BasiliskII/src/include/ether.h @@ -28,7 +28,7 @@ extern void EtherExit(void); extern int16 EtherOpen(uint32 pb, uint32 dce); extern int16 EtherControl(uint32 pb, uint32 dce); -extern void EtherReadPacket(uint8 **src, uint32 &dest, uint32 &len, uint32 &remaining); +extern void EtherReadPacket(uint32 &src, uint32 &dest, uint32 &len, uint32 &remaining); // System specific and internal functions/data extern void EtherReset(void); @@ -44,7 +44,7 @@ extern int16 ether_detach_ph(uint16 type); extern int16 ether_write(uint32 wds); extern bool ether_start_udp_thread(int socket_fd); extern void ether_stop_udp_thread(void); -extern void ether_udp_read(uint8 *packet, int length, struct sockaddr_in *from); +extern void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from); extern uint8 ether_addr[6]; // Ethernet address (set by ether_init()) @@ -61,6 +61,21 @@ enum { extern uint32 ether_data; // Mac address of driver data in MacOS RAM +// Ethernet packet allocator (optimized for 32-bit platforms in real addressing mode) +class EthernetPacket { +#if SIZEOF_VOID_P == 4 && REAL_ADDRESSING + uint8 packet[1516]; + public: + uint32 addr(void) const { return (uint32)packet; } +#else + uint32 packet; + public: + EthernetPacket(); + ~EthernetPacket(); + uint32 addr(void) const { return packet; } +#endif +}; + // Copy packet data from WDS to linear buffer (must hold at least 1514 bytes), // returns packet length static inline int ether_wds_to_buffer(uint32 wds, uint8 *p)