diff --git a/src/core/nic.c b/src/core/nic.c index be6eb7bc..04d48a11 100644 --- a/src/core/nic.c +++ b/src/core/nic.c @@ -24,6 +24,18 @@ Literature dealing with the network protocols: #include "background.h" #include "elf.h" /* FOR EM_CURRENT */ +struct arprequest { + uint16_t hwtype; + uint16_t protocol; + uint8_t hwlen; + uint8_t protolen; + uint16_t opcode; + uint8_t shwaddr[6]; + uint8_t sipaddr[4]; + uint8_t thwaddr[6]; + uint8_t tipaddr[4]; +} PACKED; + struct arptable_t arptable[MAX_ARP]; /* Put rom_info in .nocompress section so romprefix.S can write to it */ struct rom_info rom __attribute__ ((section (".text16.nocompress"))) = {0,0}; @@ -427,7 +439,7 @@ static int await_arp(int ival, void *ptr, return 0; arpreply = (struct arprequest *)&nic.packet[ETH_HLEN]; - if (arpreply->opcode != htons(ARP_REPLY)) + if (arpreply->opcode != htons(ARPOP_REPLY)) return 0; if (memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) != 0) return 0; @@ -474,10 +486,10 @@ int ip_transmit(int len, const void *buf) break; if (i == ETH_ALEN) { /* Need to do arp request */ arpreq.hwtype = htons(1); - arpreq.protocol = htons(IP); + arpreq.protocol = htons(ETH_P_IP); arpreq.hwlen = ETH_ALEN; arpreq.protolen = 4; - arpreq.opcode = htons(ARP_REQUEST); + arpreq.opcode = htons(ARPOP_REQUEST); memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr)); memset(arpreq.thwaddr, 0, ETH_ALEN); @@ -974,9 +986,9 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout) arpreply = (struct arprequest *)&nic.packet[ETH_HLEN]; memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr)); - if ((arpreply->opcode == htons(ARP_REQUEST)) && + if ((arpreply->opcode == htons(ARPOP_REQUEST)) && (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) { - arpreply->opcode = htons(ARP_REPLY); + arpreply->opcode = htons(ARPOP_REPLY); memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr)); memcpy(arpreply->thwaddr, arpreply->shwaddr, ETH_ALEN); memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr)); diff --git a/src/include/etherboot.h b/src/include/etherboot.h index 6ce55c10..10abef1e 100644 --- a/src/include/etherboot.h +++ b/src/include/etherboot.h @@ -119,7 +119,7 @@ #define NULL ((void *)0) #endif -#include "if_ether.h" +#include enum { ARP_CLIENT, ARP_SERVER, ARP_GATEWAY, @@ -144,7 +144,7 @@ enum { #define ENCAP_OPT #endif -#include "if_arp.h" +#include #include "ip.h" #include "udp.h" #include "old_tcp.h" diff --git a/src/include/gpxe/if_arp.h b/src/include/gpxe/if_arp.h new file mode 100644 index 00000000..31e993de --- /dev/null +++ b/src/include/gpxe/if_arp.h @@ -0,0 +1,100 @@ +#ifndef _IF_ARP_H +#define _IF_ARP_H + +/** @file + * + * Address Resolution Protocol constants and types + * + */ + +#include + +/* ARP protocol HARDWARE identifiers. */ +#define ARPHRD_NETROM 0 /**< from KA9Q: NET/ROM pseudo */ +#define ARPHRD_ETHER 1 /**< Ethernet 10Mbps */ +#define ARPHRD_EETHER 2 /**< Experimental Ethernet */ +#define ARPHRD_AX25 3 /**< AX.25 Level 2 */ +#define ARPHRD_PRONET 4 /**< PROnet token ring */ +#define ARPHRD_CHAOS 5 /**< Chaosnet */ +#define ARPHRD_IEEE802 6 /**< IEEE 802.2 Ethernet/TR/TB */ +#define ARPHRD_ARCNET 7 /**< ARCnet */ +#define ARPHRD_APPLETLK 8 /**< APPLEtalk */ +#define ARPHRD_DLCI 15 /**< Frame Relay DLCI */ +#define ARPHRD_ATM 19 /**< ATM */ +#define ARPHRD_METRICOM 23 /**< Metricom STRIP (new IANA id) */ +#define ARPHRD_IEEE1394 24 /**< IEEE 1394 IPv4 - RFC 2734 */ +#define ARPHRD_EUI64 27 /**< EUI-64 */ +#define ARPHRD_INFINIBAND 32 /**< InfiniBand */ + +/* ARP protocol opcodes. */ +#define ARPOP_REQUEST 1 /**< ARP request */ +#define ARPOP_REPLY 2 /**< ARP reply */ +#define ARPOP_RREQUEST 3 /**< RARP request */ +#define ARPOP_RREPLY 4 /**< RARP reply */ +#define ARPOP_InREQUEST 8 /**< InARP request */ +#define ARPOP_InREPLY 9 /**< InARP reply */ +#define ARPOP_NAK 10 /**< (ATM)ARP NAK */ + +/** + * An ARP header + * + * This contains only the fixed-size portions of an ARP header; for + * other fields use the arp_{sender,target}_{ha,pa} family of + * functions. + */ +struct arphdr { + /** Link-layer protocol + * + * This is an ARPHRD_XXX constant + */ + uint16_t ar_hrd; + /** Network-layer protocol + * + * This is, for Ethernet, an ETH_P_XXX constant. + */ + uint16_t ar_pro; + /** Link-layer address length */ + uint8_t ar_hln; + /** Network-layer address length */ + uint8_t ar_pln; + /** ARP opcode */ + uint16_t ar_op; +} __attribute__ (( packed )); + +/** ARP packet sender hardware address + * + * @v arphdr ARP header + * @ret ar_sha Sender hardware address + */ +static inline void * arp_sender_ha ( struct arphdr *arphdr ) { + return ( ( ( void * ) arphdr ) + sizeof ( *arphdr ) ); +} + +/** ARP packet sender protocol address + * + * @v arphdr ARP header + * @ret ar_spa Sender protocol address + */ +static inline void * arp_sender_pa ( struct arphdr *arphdr ) { + return ( arp_sender_ha ( arphdr ) + arphdr->ar_hln ); +} + +/** ARP packet target hardware address + * + * @v arphdr ARP header + * @ret ar_tha Target hardware address + */ +static inline void * arp_target_ha ( struct arphdr *arphdr ) { + return ( arp_sender_pa ( arphdr ) + arphdr->ar_pln ); +} + +/** ARP packet target protocol address + * + * @v arphdr ARP header + * @ret ar_tpa Target protocol address + */ +static inline void * arp_target_pa ( struct arphdr *arphdr ) { + return ( arp_target_ha ( arphdr ) + arphdr->ar_hln ); +} + +#endif /* _IF_ARP_H */ diff --git a/src/include/if_ether.h b/src/include/gpxe/if_ether.h similarity index 68% rename from src/include/if_ether.h rename to src/include/gpxe/if_ether.h index c36ec889..7f0abacb 100644 --- a/src/include/if_ether.h +++ b/src/include/gpxe/if_ether.h @@ -1,13 +1,7 @@ #ifndef _IF_ETHER_H #define _IF_ETHER_H -/* - I'm moving towards the defined names in linux/if_ether.h for clarity. - The confusion between 60/64 and 1514/1518 arose because the NS8390 - counts the 4 byte frame checksum in the incoming packet, but not - in the outgoing packet. 60/1514 are the correct numbers for most - if not all of the other NIC controllers. -*/ +#include #define ETH_ALEN 6 /* Size of Ethernet address */ #define ETH_HLEN 14 /* Size of ethernet header */ @@ -24,4 +18,14 @@ #define ETH_P_IPV6 0x86DD /* IPv6 over blueblook */ #define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */ +/** An Ethernet link-layer header */ +struct ethhdr { + /** Destination MAC address */ + uint8_t h_dest[ETH_ALEN]; + /** Source MAC address */ + uint8_t h_source[ETH_ALEN]; + /** Protocol ID */ + uint16_t h_protocol; +} __attribute__ ((packed)); + #endif /* _IF_ETHER_H */ diff --git a/src/include/if_arp.h b/src/include/if_arp.h deleted file mode 100644 index b3aebf74..00000000 --- a/src/include/if_arp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _IF_ARP_H -#define _IF_ARP_H - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -/* - * A pity sipaddr and tipaddr are not longword aligned or we could use - * in_addr. No, I don't want to use #pragma packed. - */ -struct arprequest { - uint16_t hwtype; - uint16_t protocol; - uint8_t hwlen; - uint8_t protolen; - uint16_t opcode; - uint8_t shwaddr[6]; - uint8_t sipaddr[4]; - uint8_t thwaddr[6]; - uint8_t tipaddr[4]; -} PACKED; - -#endif /* _IF_ARP_H */