/* * Handler for the connection "arp" command: * arp show * arp show -ip ip_addr * arp del * arp del -ip ip_addr */ void arpCmd() { char *next_tok; uchar mac_addr[6], ip_addr[4]; next_tok = strtok(NULL, " \n"); if (next_tok == NULL) { printf("[arpCmd]:: missing arp action.. type help arp for usage \n"); return; } if (!strcmp(next_tok, "show")) ARPPrintTable(); else if (!strcmp(next_tok, "del")) { if ((next_tok = strtok(NULL, " \n")) != NULL) { if (!strcmp("-ip", next_tok)) { next_tok = strtok(NULL, " \n"); Dot2IP(next_tok, ip_addr); ARPDeleteEntry(ip_addr); } } else ARPReInitTable(); } else if (!strcmp(next_tok, "add")) { if ((next_tok = strtok(NULL, " \n")) != NULL) { if (!strcmp("-ip", next_tok)) { next_tok = strtok(NULL, " \n"); Dot2IP(next_tok, ip_addr); } } else if ((next_tok = strtok(NULL, " \n")) != NULL) { if (!strcmp("-mac", next_tok)) { next_tok = strtok(NULL, " \n"); Colon2MAC(next_tok, mac_addr); ARPAddEntry(ip_addr, mac_addr); } } } }
/* * ARPProcess: Process a received ARP packet... from remote nodes. If it is * a reply for a ARP request sent from the local node, use it * to update the local ARP cache. Flush (dequeue, process, and send) any packets * that are buffered for ARP processing that match the ARP reply. * If it a request, send a reply.. no need to record any state here. */ void ARPProcess(gpacket_t *pkt) { char tmpbuf[MAX_TMPBUF_LEN]; arp_packet_t *apkt = (arp_packet_t *) pkt->data.data; // check packet is ethernet and addresses of IP type.. otherwise throw away if ((ntohs(apkt->hw_addr_type) != ETHERNET_PROTOCOL) || (ntohs(apkt->arp_prot) != IP_PROTOCOL)) { verbose(2, "[ARPProcess]:: unknown hwtype or protocol, dropping ARP packet"); return; } verbose(2, "[ARPProcess]:: adding sender of received packet to ARP table"); ARPAddEntry(gNtohl((uchar *)tmpbuf, apkt->src_ip_addr), apkt->src_hw_addr); // Check it's actually destined to us,if not throw packet if (COMPARE_IP(apkt->dst_ip_addr, gHtonl((uchar *)tmpbuf, pkt->frame.src_ip_addr)) != 0) { verbose(2, "[APRProcess]:: packet has a frame source (after ntohl) %s ...", IP2Dot(tmpbuf, gNtohl((uchar *)tmpbuf, pkt->frame.src_ip_addr))); verbose(2, "[APRProcess]:: packet destined for %s, dropping", IP2Dot(tmpbuf, gNtohl((uchar *)tmpbuf, apkt->dst_ip_addr))); return; } // We have a valid ARP packet, lets process it now. // If it's a REQUEST, send a reply back if (ntohs(apkt->arp_opcode) == ARP_REQUEST) { apkt->arp_opcode = htons(ARP_REPLY); COPY_MAC(apkt->src_hw_addr, pkt->frame.src_hw_addr); COPY_MAC(apkt->dst_hw_addr, pkt->data.header.src); COPY_IP(apkt->dst_ip_addr, apkt->src_ip_addr); COPY_IP(apkt->src_ip_addr, gHtonl((uchar *)tmpbuf, pkt->frame.src_ip_addr)); verbose(2, "[ARPProcess]:: packet was ARP REQUEST, sending ARP REPLY packet"); // prepare for sending. Set some parameters that is going to be used // by the GNET adapter... pkt->frame.dst_interface = pkt->frame.src_interface; COPY_MAC(pkt->data.header.dst, pkt->data.header.src); COPY_MAC(pkt->data.header.src, pkt->frame.src_hw_addr); COPY_IP(pkt->frame.nxth_ip_addr, gNtohl((uchar *)tmpbuf, apkt->dst_ip_addr)); pkt->frame.arp_valid = TRUE; pkt->data.header.prot = htons(ARP_PROTOCOL); ARPSend2Output(pkt); } else if (ntohs(apkt->arp_opcode) == ARP_REPLY) { // Flush buffer of any packets waiting for the incoming ARP.. verbose(2, "[ARPProcess]:: packet was ARP REPLY... "); ARPFlushBuffer(gNtohl((uchar *)tmpbuf, apkt->src_ip_addr), apkt->src_hw_addr); verbose(2, "[ARPProcess]:: flushed the ARP buffer ... "); } else verbose(2, "[ARPProcess]:: unknown ARP type"); return; }