- /*
- * We have to deal with two types of ARP packets:
- * - REQUEST packets will be answered by sending our
- * IP address - if we know it.
- * - REPLY packates are expected only after we asked
- * for the TFTP server's or the gateway's ethernet
- * address; so if we receive such a packet, we set
- * the server ethernet address
- */
-#ifdef ET_DEBUG
- puts ("Got ARP\n");
-#endif
- arp = (ARP_t *)ip;
- if (len < ARP_HDR_SIZE) {
- printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
- return;
- }
- if (ntohs(arp->ar_hrd) != ARP_ETHER) {
- return;
- }
- if (ntohs(arp->ar_pro) != PROT_IP) {
- return;
- }
- if (arp->ar_hln != 6) {
- return;
- }
- if (arp->ar_pln != 4) {
- return;
- }
-
- if (NetOurIP == 0) {
- return;
- }
-
- if (NetReadIP(&arp->ar_data[16]) != NetOurIP) {
- return;
- }
-
- switch (ntohs(arp->ar_op)) {
- case ARPOP_REQUEST: /* reply with our IP address */
-#ifdef ET_DEBUG
- puts ("Got ARP REQUEST, return our IP\n");
-#endif
- pkt = (uchar *)et;
- pkt += NetSetEther(pkt, et->et_src, PROT_ARP);
- arp->ar_op = htons(ARPOP_REPLY);
- memcpy (&arp->ar_data[10], &arp->ar_data[0], 6);
- NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);
- memcpy (&arp->ar_data[ 0], NetOurEther, 6);
- NetCopyIP(&arp->ar_data[ 6], &NetOurIP);
- (void) eth_send((uchar *)et, (pkt - (uchar *)et) + ARP_HDR_SIZE);
- return;
-
- case ARPOP_REPLY: /* arp reply */
- /* are we waiting for a reply */
- if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)
- break;
-#ifdef ET_DEBUG
- printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",
- arp->ar_data[0], arp->ar_data[1],
- arp->ar_data[2], arp->ar_data[3],
- arp->ar_data[4], arp->ar_data[5]);
-#endif
-
- tmp = NetReadIP(&arp->ar_data[6]);
-
- /* matched waiting packet's address */
- if (tmp == NetArpWaitReplyIP) {
-#ifdef ET_DEBUG
- puts ("Got it\n");
-#endif
- /* save address for later use */
- memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6);
-
-#ifdef CONFIG_NETCONSOLE
- (*packetHandler)(0,0,0,0);
-#endif
- /* modify header, and transmit it */
- memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);
- (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize);
-
- /* no arp request pending now */
- NetArpWaitPacketIP = 0;
- NetArpWaitTxPacketSize = 0;
- NetArpWaitPacketMAC = NULL;
-
- }
- return;
- default:
-#ifdef ET_DEBUG
- printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op));
-#endif
- return;
- }