void write_packet(unsigned char* ether_addr, uint16_t ether_type, unsigned char* buf, uint16_t len) { uint16_t packet_length = len + sizeof(struct ether_header); unsigned char* packet = malloc(packet_length); struct ether_header* eth = (struct ether_header*)packet; memcpy(eth->dest, ether_addr, ETHER_ADDR_LEN); memcpy(eth->source, MAC_ADDRESS, ETHER_ADDR_LEN); eth->type = ether_type; ntohs(ð->type); memcpy(eth + 1, buf, len); lput_str("OUT: "); lput16_hex(packet_length); lput_str(" bytes\r\n"); lput_buffer(packet, packet_length); ether_write(packet, packet_length); lput_str("wrote\r\n.\r\n"); free(buf); }
int16 EtherControl(uint32 pb, uint32 dce) { uint16 code = ReadMacInt16(pb + csCode); D(bug("EtherControl %d\n", code)); switch (code) { case 1: // KillIO return -1; case kENetAddMulti: // Add multicast address D(bug("AddMulti %08lx%04x\n", ReadMacInt32(pb + eMultiAddr), ReadMacInt16(pb + eMultiAddr + 4))); if (net_open) return ether_add_multicast(pb); else return noErr; case kENetDelMulti: // Delete multicast address D(bug("DelMulti %08lx%04x\n", ReadMacInt32(pb + eMultiAddr), ReadMacInt16(pb + eMultiAddr + 4))); if (net_open) return ether_del_multicast(pb); else return noErr; case kENetAttachPH: // Attach protocol handler D(bug("AttachPH prot %04x, handler %08lx\n", ReadMacInt16(pb + eProtType), ReadMacInt32(pb + ePointer))); if (net_open) return ether_attach_ph(ReadMacInt16(pb + eProtType), ReadMacInt32(pb + ePointer)); else return noErr; case kENetDetachPH: // Detach protocol handler D(bug("DetachPH prot %04x\n", ReadMacInt16(pb + eProtType))); if (net_open) return ether_detach_ph(ReadMacInt16(pb + eProtType)); else return noErr; case kENetWrite: // Transmit raw Ethernet packet D(bug("EtherWrite\n")); if (ReadMacInt16(ReadMacInt32(pb + ePointer)) < 14) return eLenErr; // Header incomplete if (net_open) return ether_write(ReadMacInt32(pb + ePointer)); else return noErr; case kENetGetInfo: { // Get device information/statistics D(bug("GetInfo buf %08lx, size %d\n", ReadMacInt32(pb + ePointer), ReadMacInt16(pb + eBuffSize))); // Collect info (only ethernet address) uint8 buf[18]; memset(buf, 0, 18); memcpy(buf, ether_addr, 6); // Transfer info to supplied buffer int16 size = ReadMacInt16(pb + eBuffSize); if (size > 18) size = 18; WriteMacInt16(pb + eDataSize, size); // Number of bytes actually written Host2Mac_memcpy(ReadMacInt32(pb + ePointer), buf, size); return noErr; } case kENetSetGeneral: // Set general mode (always in general mode) D(bug("SetGeneral\n")); return noErr; default: printf("WARNING: Unknown EtherControl(%d)\n", code); return controlErr; } }