summaryrefslogtreecommitdiff
path: root/sys/arch/i386/netboot/arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/netboot/arp.c')
-rw-r--r--sys/arch/i386/netboot/arp.c460
1 files changed, 0 insertions, 460 deletions
diff --git a/sys/arch/i386/netboot/arp.c b/sys/arch/i386/netboot/arp.c
deleted file mode 100644
index 9d0daea342d..00000000000
--- a/sys/arch/i386/netboot/arp.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/* $OpenBSD: arp.c,v 1.3 1996/04/26 18:22:58 mickey Exp $ */
-/* $NetBSD: arp.c,v 1.5 1996/02/02 18:06:14 mycroft Exp $ */
-
-/*
- * source in this file came from
- * the Mach ethernet boot written by Leendert van Doorn.
- *
- * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
- * No doubt this code is overkill, but I had it lying around.
- *
- * Copyright (c) 1992 by Leendert van Doorn
- */
-
-#include "proto.h"
-#include "assert.h"
-#include "param.h"
-#include "packet.h"
-#include "ether.h"
-#include "inet.h"
-#include "arp.h"
-#include "bootp.h"
-#include "tftp.h"
-
-static u_char bcastaddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-static arptab_t arptab[ARPTAB_SIZE];
-
-extern u_char vendor_area[64];
-ipaddr_t ip_myaddr = IP_ANYADDR;
-ipaddr_t ip_gateway = IP_ANYADDR;
-
-#ifdef USE_RARP
-/*
- * Broadcast a RARP request (i.e. who knows who I am)
- */
-static void
-RarpWhoAmI(void) {
- arphdr_t *ap;
- packet_t *pkt;
- pkt = PktAlloc(sizeof(ethhdr_t));
- pkt->pkt_len = sizeof(arphdr_t);
- ap = (arphdr_t *) pkt->pkt_offset;
- ap->arp_hrd = htons(ARPHRD_ETHER);
- ap->arp_pro = htons(ETHTYPE_IP);
- ap->arp_hln = ETH_ADDRSIZE;
- ap->arp_pln = sizeof(ipaddr_t);
- ap->arp_op = htons(REVARP_REQUEST);
- bcopy((char *)eth_myaddr, (char *)ap->arp_sha, ETH_ADDRSIZE);
- bcopy((char *)eth_myaddr, (char *)ap->arp_tha, ETH_ADDRSIZE);
- EtherSend(pkt, ETHTYPE_RARP, bcastaddr);
- PktRelease(pkt);
-}
-#endif
-
-
-#ifdef USE_BOOTP
-static int saved_bootp_xid; /* from last bootp req */
-extern int time_zero;
-/*
- * Broadcast a BOOTP request (i.e. who knows who I am)
- */
-static void
-BootpWhoAmI(void) {
- struct bootp *bp;
- packet_t *pkt;
- udphdr_t *up;
- pkt = PktAlloc(sizeof(ethhdr_t)+sizeof(iphdr_t));
- pkt->pkt_len = sizeof(ethhdr_t) + sizeof(iphdr_t) +
- sizeof(udphdr_t) +sizeof(struct bootp);
- up = (udphdr_t *) pkt->pkt_offset;
- bp = (struct bootp *) ((char *)up + sizeof(udphdr_t));
- up->uh_dport = htons(IPPORT_BOOTPS);
- up->uh_len = htons(sizeof(udphdr_t) + sizeof(struct bootp));
- bp->bp_op = BOOTREQUEST;
- bp->bp_htype = 1;
- bp->bp_hlen = ETH_ADDRSIZE;
- bp->bp_xid = saved_bootp_xid = rand();
- bp->bp_secs = htons(timer() - time_zero);
- bcopy((char *)eth_myaddr, (char *)bp->bp_chaddr, ETH_ADDRSIZE);
- IpSend(pkt, IP_BCASTADDR, IP_ANYADDR);
- PktInit();
-}
-#endif
-
-extern ipaddr_t tftp_gateway;
-extern ipaddr_t tftp_server;
-
-#ifdef USE_RARP
-/*
- * Called when packet containing RARP is received
- */
-static inline ipaddr_t
-RarpInput(packet_t *pkt, ipaddr_t *server) {
- ipaddr_t ipaddr;
- ethhdr_t *ep;
- ep = (ethhdr_t *)pkt->pkt_offset;
-
- /* is rarp? */
- if (pkt->pkt_len >= sizeof(arphdr_t) &&
- ntohs(ep->eth_proto) == ETHTYPE_RARP) {
- ipaddr_t ipa;
- arphdr_t *ap;
- ap = (arphdr_t *) (pkt->pkt_offset + sizeof(ethhdr_t));
- if (ntohs(ap->arp_op) != REVARP_REPLY ||
- ntohs(ap->arp_pro) != ETHTYPE_IP)
- return 0;
- if (bcmp(ap->arp_tha, eth_myaddr, ETH_ADDRSIZE))
- return 0;
-
- bcopy((char *)ap->arp_tpa, (char *)&ipaddr, sizeof(ipaddr_t));
- printf("From RARP server ");
- bcopy((char *)ap->arp_spa, (char *)&ipa, sizeof(ipaddr_t));
- IpPrintAddr(ipa);
- printf(": using IP address ");
- IpPrintAddr(ipaddr);
-
- if (server) {
- bcopy((char *)ap->arp_spa, (char *)server, sizeof(ipaddr_t));
- printf(",\n tftp server ");
- IpPrintAddr(*server);
- }
-
- printf("\n");
- return ipaddr;
- }
- return 0;
-}
-#endif
-
-#ifdef USE_BOOTP
-static inline ipaddr_t
-BootpInput(packet_t *pkt, ipaddr_t *server, ipaddr_t *gateway, char *filename) {
- ipaddr_t ipaddr;
- ethhdr_t *ep;
- ep = (ethhdr_t *)pkt->pkt_offset;
-
-
- if (pkt->pkt_len < sizeof(iphdr_t)+sizeof(udphdr_t)+sizeof(struct bootp))
- return 0;
- if (ntohs(ep->eth_proto) == ETHTYPE_IP) {
- iphdr_t *ip;
- udphdr_t *up;
- struct bootp *bp;
- ip = (iphdr_t *) ((char *)ep + sizeof(ethhdr_t));
- up = (udphdr_t *) ((char *)ip + sizeof(iphdr_t));
- bp = (struct bootp *) ((char *)up + sizeof(udphdr_t));
-
-#if 0
-DUMP_STRUCT("eboot", ep, 100);
-printf("pktlen %d of %d\n\n", pkt->pkt_len, sizeof(iphdr_t)+sizeof(udphdr_t)+sizeof(struct bootp));
-#endif
-
- if (ip->ip_p != IP_PROTO_UDP) {
- return 0;
- }
-
- if (up->uh_dport != htons(IPPORT_BOOTPC)) {
- return 0;
- }
-
- if (bp->bp_xid != saved_bootp_xid) {
- return 0;
- }
-
- /* passed all checks - is the packet we expected */
- ipaddr = bp->bp_yiaddr;
- printf("From BOOTP server ");
- IpPrintAddr(ip->ip_src);
- printf(": using IP address ");
- IpPrintAddr(bp->bp_yiaddr);
-
- if (server) {
- *server = bp->bp_siaddr;
- printf(",\n tftp server ");
- IpPrintAddr(bp->bp_siaddr);
- }
-
- if (bp->bp_giaddr) {
- *gateway = bp->bp_giaddr;
- printf(",\n gateway ");
- IpPrintAddr(bp->bp_giaddr);
- }
-
- if (*bp->bp_file) {
- bcopy((char *)bp->bp_file, filename, MAX_FILE_NAME_LEN-1);
- printf(",\n file '%s'", bp->bp_file);
- }
-
- bcopy((char *)bp->bp_vend, (char *)vendor_area, sizeof(vendor_area));
-
- printf("\n");
-
- PktInit();
- return ipaddr;
- }
- return 0;
-}
-#endif
-
-/*
- * Using the BOOTP and/or RARP request/reply exchange we try to obtain our
- * internet address (see RFC 903).
- */
-ipaddr_t
-GetIpAddress(ipaddr_t *serv_addr, ipaddr_t *myaddr, ipaddr_t *gateway, char *filename) {
- u_long time, current, timeout;
- int retry;
- packet_t *pkt;
- int spin = 0;
-
-#if TRACE > 0
- printe("GetIpAddress: Requesting IP address for ");
- EtherPrintAddr(eth_myaddr);
- printe("\n");
-#endif
-
- timeout = 4; /* four seconds */
- for (retry = 0; retry < NRETRIES; retry++) {
-#ifdef USE_RARP
- RarpWhoAmI();
-#endif
-#ifdef USE_BOOTP
- BootpWhoAmI();
-#endif
- printf("%c\b", "-\\|/"[spin++ % 4]);
-
- time = timer() + timeout;
- do {
- pkt = EtherReceive();
- if (pkt) {
- *myaddr = 0;
-#ifdef USE_RARP
- *myaddr = RarpInput(pkt, serv_addr);
-#endif
-#ifdef USE_BOOTP
- if (!*myaddr)
- *myaddr = BootpInput(pkt, serv_addr, gateway, filename);
-#endif
- PktRelease(pkt);
- if (*myaddr) {
- return 1;
- }
- }
- HandleKbdAttn();
- current = timer();
- } while (current < time);
- EtherReset();
- timeout <<= 1;
- }
- printf("No response for "
-#ifdef USE_BOOTP
- "BOOTP "
-#endif
-#ifdef USE_RARP
- "RARP "
-#endif
- "request\n");
- return IP_ANYADDR;
-}
-
-/*
- * Broadcast an ARP packet (i.e. ask who has address "addr")
- */
-static void
-ArpWhoHas(ipaddr_t addr) {
- arphdr_t *ap;
- packet_t *pkt;
-
- pkt = PktAlloc(sizeof(ethhdr_t));
- pkt->pkt_len = sizeof(arphdr_t);
- ap = (arphdr_t *) pkt->pkt_offset;
- ap->arp_hrd = htons(ARPHRD_ETHER);
- ap->arp_pro = htons(ETHTYPE_IP);
- ap->arp_hln = ETH_ADDRSIZE;
- ap->arp_pln = sizeof(ipaddr_t);
- ap->arp_op = htons(ARPOP_REQUEST);
- bcopy((char *)eth_myaddr, (char *)ap->arp_sha, ETH_ADDRSIZE);
- bcopy((char *)&ip_myaddr, (char *)ap->arp_spa, sizeof(ipaddr_t));
- bcopy((char *)&addr, (char *)ap->arp_tpa, sizeof(ipaddr_t));
-#if TRACE > 0
-printe("ArpWhoHas:\n");
-DUMP_STRUCT("arphdr_t", ap, sizeof(arphdr_t));
-#endif
- EtherSend(pkt, ETHTYPE_ARP, bcastaddr);
- PktRelease(pkt);
-}
-
-/*
- * Free an arptab entry
- */
-static void
-ArpTfree(arptab_t *at) {
- if (at->at_hold)
- PktRelease(at->at_hold);
- at->at_hold = (packet_t *)0;
- at->at_timer = at->at_flags = 0;
- at->at_ipaddr = 0;
-}
-
-/*
- * Enter a new address in arptab, pushing out the oldest entry
- * from the bucket if there is no room.
- */
-static arptab_t *
-ArpTnew(ipaddr_t addr) {
- u_short n;
- u_long oldest;
- arptab_t *at, *ato;
-
- oldest = ~0;
- ato = at = &arptab[ARPTAB_HASH(addr) * ARPTAB_BSIZ];
- for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) {
- if (at->at_flags == 0)
- goto out; /* found an empty entry */
- if (at->at_timer < oldest) {
- oldest = at->at_timer;
- ato = at;
- }
- }
- at = ato;
- ArpTfree(at);
- out:
- at->at_ipaddr = addr;
- at->at_flags = ATF_INUSE;
- return at;
-}
-
-/*
- * Resolve an IP address into a hardware address. If success,
- * destha is filled in and 1 is returned. If there is no entry
- * in arptab, set one up and broadcast a request
- * for the IP address; return 0. Hold onto this packet and
- * resend it once the address is finally resolved.
- */
-int
-ArpResolve(packet_t *pkt, ipaddr_t destip, u_char *destha) {
- arptab_t *at;
- u_long lna = ntohl(destip) & 0xFF;
-
- if (lna == 0xFF || lna == 0x0) { /* broadcast address */
- bcopy((char *)bcastaddr, (char *)destha, ETH_ADDRSIZE);
- return 1;
- }
-
- ARPTAB_LOOK(at, destip);
- if (at == 0) {
- at = ArpTnew(destip);
- at->at_hold = pkt;
- ArpWhoHas(destip);
- return 0;
- }
-
- at->at_timer = timer(); /* restart the timer */
- if (at->at_flags & ATF_COM) { /* entry is complete */
- bcopy((char *)at->at_eaddr, (char *)destha, ETH_ADDRSIZE);
- return 1;
- }
-
- /*
- * There is an arptab entry, but no hardware address
- * response yet. Replace the held packet with this
- * latest one.
- */
- if (at->at_hold)
- PktRelease(at->at_hold);
- at->at_hold = pkt;
- ArpWhoHas(destip);
- return 0;
-}
-
-
-/*
- * Called when packet containing ARP is received.
- * Algorithm is that given in RFC 826.
- */
-void
-ArpInput(packet_t *pkt) {
- arphdr_t *ap;
- arptab_t *at;
- packet_t *phold;
- ipaddr_t isaddr, itaddr;
-
-#if 0
-T(ArpInput);
-#endif
- if (pkt->pkt_len < sizeof(arphdr_t)) {
-#if 0
- printf("ArpInput: bad packet size %d\n", pkt->pkt_len);
-#endif
- return;
- }
-
- ap = (arphdr_t *) (pkt->pkt_offset + sizeof(ethhdr_t));
-#if 0
-DUMP_STRUCT("arphdr_t", ap, sizeof(arphdr_t));
-#endif
- if (ntohs(ap->arp_pro) != ETHTYPE_IP) {
-#if 0
- printf("ArpInput: incorrect proto addr %x\n", ap->arp_pro);
-#endif
- return;
- }
-
- bcopy((char *)ap->arp_spa, (char *)&isaddr, sizeof(ipaddr_t));
- bcopy((char *)ap->arp_tpa, (char *)&itaddr, sizeof(ipaddr_t));
- if (!bcmp(ap->arp_sha, eth_myaddr, ETH_ADDRSIZE)) {
-#if 0
- printf("ArpInput: incorrect sender h/w addr ");
- EtherPrintAddr(ap->arp_sha);
- printf("/n");
-#endif
- return;
- }
-
- at = (arptab_t *)0;
- ARPTAB_LOOK(at, isaddr);
- if (at) {
- bcopy((char *)ap->arp_sha, (char *)at->at_eaddr, ETH_ADDRSIZE);
- at->at_flags |= ATF_COM;
- if (at->at_hold) {
- phold = at->at_hold;
- at->at_hold = (packet_t *)0;
-#if 0
- printf("ArpInput: found addr, releasing packet\n");
-#endif
- EtherSend(phold, ETHTYPE_IP, at->at_eaddr);
- PktRelease(phold);
- }
- }
-
- /*
- * Only answer ARP request which are for me
- */
- if (itaddr != ip_myaddr) {
-#if 0
- printf("ArpInput: it addr ");
- IpPrintAddr(itaddr);
- printf(" somebody else\n");
-#endif
- return;
- }
-
- if (at == 0) { /* ensure we have a table entry */
- at = ArpTnew(isaddr);
- bcopy((char *)ap->arp_sha, (char *)at->at_eaddr, ETH_ADDRSIZE);
- at->at_flags |= ATF_COM;
- }
- if (ntohs(ap->arp_op) != ARPOP_REQUEST) {
- printf("ArpInput: incorrect operation: 0x%x\n", ntohs(ap->arp_op));
- return;
- }
- bcopy((char *)ap->arp_sha, (char *)ap->arp_tha, ETH_ADDRSIZE);
- bcopy((char *)ap->arp_spa, (char *)ap->arp_tpa, sizeof(ipaddr_t));
- bcopy((char *)eth_myaddr, (char *)ap->arp_sha, ETH_ADDRSIZE);
- bcopy((char *)&itaddr, (char *)ap->arp_spa, sizeof(ipaddr_t));
- ap->arp_op = htons(ARPOP_REPLY);
-#if 0
-printf("ArpInput: valid request rec'd, replying\n");
-#endif
- EtherSend(pkt, ETHTYPE_ARP, ap->arp_tha);
-}