home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "kernel.h"
- #include "swis.h"
- #include "global.h"
-
- struct arp arplist[MAXARP];
-
- void Receive_ARP(int bcast, int portno, struct mbuf *mbuf)
- {
- char *data;
-
- data = mbuf->m_next->m_dat + mbuf->m_next->m_off - MMINOFF;
-
- if (get16(data + 0) == HARDWARE_ETHER &&
- get16(data + 2) == FRAME_IP &&
- get32(data + 24) == port[portno].ipaddr)
- {
- switch (get16(data + 6))
- {
- case ARP_REQUEST:
- Receive_ARP_Request(portno, bcast, data);
- break;
- case ARP_RESPONSE:
- Receive_ARP_Response(portno, bcast, data);
- break;
- default:
- break;
- }
- }
-
- free_rx_mbuf(mbuf);
- }
-
- void Create_ARP_Request(int ipaddr, struct packet *packet)
- {
- register struct arp *arp;
- register int i;
-
- for (i = 0; i < MAXARP; i++)
- {
- if (arplist[i].ipaddr == ipaddr &&
- arplist[i].port == packet->port &&
- arplist[i].status == ARP_RESOLVING)
- {
- free_tx_mbuf(packet->data);
- free_packet(packet);
- Transmit_ARP_Request(arplist + i);
- return;
- }
- }
-
- arp = Free_ARP_Slot();
-
- arp->ipaddr = ipaddr;
- arp->port = packet->port;
- arp->ttl = TIMEOUT_RESOLVING;
- arp->status = ARP_RESOLVING;
- arp->packet = packet;
-
- Transmit_ARP_Request(arp);
- }
-
- void Transmit_ARP_Request(struct arp *arp)
- {
- struct packet *packet;
- struct mbuf *mbuf;
- int portno = arp->port;
-
- if ((mbuf = alloc_tx_mbuf(1)) == NULLMBUF)
- return;
-
- if ((packet = alloc_packet()) == NULLPACKET)
- {
- memout++;
- free_tx_mbuf(mbuf);
- return;
- }
-
- port[portno].arpreqtx++;
-
- mbuf->m_next = NULLMBUF;
- mbuf->m_off = MMINOFF;
- mbuf->m_len = 28;
- mbuf->m_indir = FALSE;
- mbuf->m_type = MT_DATA;
-
- put16(mbuf->m_dat + 0, HARDWARE_ETHER);
- put16(mbuf->m_dat + 2, FRAME_IP);
- mbuf->m_dat[4] = 6;
- mbuf->m_dat[5] = 4;
- put16(mbuf->m_dat + 6, ARP_REQUEST);
-
- /* Sender */
- mbuf->m_dat[8] = port[portno].hwaddr[0];
- mbuf->m_dat[9] = port[portno].hwaddr[1];
- mbuf->m_dat[10] = port[portno].hwaddr[2];
- mbuf->m_dat[11] = port[portno].hwaddr[3];
- mbuf->m_dat[12] = port[portno].hwaddr[4];
- mbuf->m_dat[13] = port[portno].hwaddr[5];
- put32(mbuf->m_dat + 14, port[portno].ipaddr);
-
- /* Target */
- mbuf->m_dat[18] = 0x00;
- mbuf->m_dat[19] = 0x00;
- mbuf->m_dat[20] = 0x00;
- mbuf->m_dat[21] = 0x00;
- mbuf->m_dat[22] = 0x00;
- mbuf->m_dat[23] = 0x00;
- put32(mbuf->m_dat + 24, arp->ipaddr);
-
- packet->next = NULLPACKET;
- packet->hwaddr[0] = bcast_hwaddr[0];
- packet->hwaddr[1] = bcast_hwaddr[1];
- packet->hwaddr[2] = bcast_hwaddr[2];
- packet->hwaddr[3] = bcast_hwaddr[3];
- packet->hwaddr[4] = bcast_hwaddr[4];
- packet->hwaddr[5] = bcast_hwaddr[5];
- packet->port = portno;
- packet->type = FRAME_ARP;
- packet->data = mbuf;
-
- Queue_Transmit_Packet(packet);
- }
-
- void Receive_ARP_Request(int portno, int bcast, char *data)
- {
- struct packet *packet;
- struct arp *arp;
- struct mbuf *mbuf;
- int ipaddr;
-
- port[portno].arpreqrx++;
-
- if ((mbuf = alloc_tx_mbuf(1)) == NULLMBUF)
- return;
-
- if ((packet = alloc_packet()) == NULLPACKET)
- {
- memout++;
- free_tx_mbuf(mbuf);
- return;
- }
-
- port[portno].arprestx++;
-
- mbuf->m_next = NULLMBUF;
- mbuf->m_off = MMINOFF;
- mbuf->m_len = 28;
- mbuf->m_indir = FALSE;
- mbuf->m_type = MT_DATA;
-
- ipaddr = get32(data + 14);
-
- put16(mbuf->m_dat + 0, HARDWARE_ETHER);
- put16(mbuf->m_dat + 2, FRAME_IP);
- mbuf->m_dat[4] = 6;
- mbuf->m_dat[5] = 4;
- put16(mbuf->m_dat + 6, ARP_RESPONSE);
-
- /* Sender */
- mbuf->m_dat[8] = port[portno].hwaddr[0];
- mbuf->m_dat[9] = port[portno].hwaddr[1];
- mbuf->m_dat[10] = port[portno].hwaddr[2];
- mbuf->m_dat[11] = port[portno].hwaddr[3];
- mbuf->m_dat[12] = port[portno].hwaddr[4];
- mbuf->m_dat[13] = port[portno].hwaddr[5];
- put32(mbuf->m_dat + 14, port[portno].ipaddr);
-
- /* Target */
- mbuf->m_dat[18] = data[8];
- mbuf->m_dat[19] = data[9];
- mbuf->m_dat[20] = data[10];
- mbuf->m_dat[21] = data[11];
- mbuf->m_dat[22] = data[12];
- mbuf->m_dat[23] = data[13];
- put32(mbuf->m_dat + 24, ipaddr);
-
- packet->next = NULLPACKET;
- packet->hwaddr[0] = data[8];
- packet->hwaddr[1] = data[9];
- packet->hwaddr[2] = data[10];
- packet->hwaddr[3] = data[11];
- packet->hwaddr[4] = data[12];
- packet->hwaddr[5] = data[13];
- packet->port = portno;
- packet->type = FRAME_ARP;
- packet->data = mbuf;
-
- Queue_Transmit_Packet(packet);
-
- if (Search_ARP_Cache(portno, ipaddr) == NULL)
- {
- arp = Free_ARP_Slot();
-
- arp->ipaddr = ipaddr;
- arp->hwaddr[0] = data[8];
- arp->hwaddr[1] = data[9];
- arp->hwaddr[2] = data[10];
- arp->hwaddr[3] = data[11];
- arp->hwaddr[4] = data[12];
- arp->hwaddr[5] = data[13];
- arp->port = portno;
- arp->ttl = TIMEOUT_RESOLVED;
- arp->status = ARP_RESOLVED;
- arp->packet = NULLPACKET;
- }
- }
-
- void Receive_ARP_Response(int portno, int bcast, char *data)
- {
- struct arp *arp;
- register int i;
- int ipaddr;
-
- port[portno].arpresrx++;
-
- ipaddr = get32(data + 14);
-
- for (i = 0; i < MAXARP; i++)
- {
- if (arplist[i].ipaddr == ipaddr &&
- arplist[i].port == portno &&
- arplist[i].status != ARP_UNUSED)
- {
- arplist[i].hwaddr[0] = data[8];
- arplist[i].hwaddr[1] = data[9];
- arplist[i].hwaddr[2] = data[10];
- arplist[i].hwaddr[3] = data[11];
- arplist[i].hwaddr[4] = data[12];
- arplist[i].hwaddr[5] = data[13];
-
- arplist[i].status = ARP_RESOLVED;
- arplist[i].ttl = TIMEOUT_RESOLVED;
-
- if (arplist[i].packet != NULLPACKET)
- {
- arplist[i].packet->hwaddr[0] = data[8];
- arplist[i].packet->hwaddr[1] = data[9];
- arplist[i].packet->hwaddr[2] = data[10];
- arplist[i].packet->hwaddr[3] = data[11];
- arplist[i].packet->hwaddr[4] = data[12];
- arplist[i].packet->hwaddr[5] = data[13];
-
- Queue_Transmit_Packet(arplist[i].packet);
-
- arplist[i].packet = NULLPACKET;
- }
-
- return;
- }
- }
-
- arp = Free_ARP_Slot();
-
- arp->ipaddr = ipaddr;
- arp->hwaddr[0] = data[8];
- arp->hwaddr[1] = data[9];
- arp->hwaddr[2] = data[10];
- arp->hwaddr[3] = data[11];
- arp->hwaddr[4] = data[12];
- arp->hwaddr[5] = data[13];
- arp->port = portno;
- arp->ttl = TIMEOUT_RESOLVED;
- arp->status = ARP_RESOLVED;
- arp->packet = NULLPACKET;
- }
-
- void Initialise_ARP_Cache(void)
- {
- register int i;
-
- for (i = 0; i < MAXARP; i++)
- arplist[i].status = ARP_UNUSED;
- }
-
- void Timeout_ARP_Cache(void)
- {
- register int i;
-
- for (i = 0; i < MAXARP; i++)
- {
- if (arplist[i].status != ARP_UNUSED)
- {
- arplist[i].ttl--;
-
- if (arplist[i].ttl == 0)
- {
- arplist[i].status = ARP_UNUSED;
-
- if (arplist[i].packet != NULLPACKET)
- {
- free_tx_mbuf(arplist[i].packet->data);
- free_packet(arplist[i].packet);
- }
- }
- }
- }
- }
-
- char *Search_ARP_Cache(int portno, int ipaddr)
- {
- register int i;
-
- for (i = 0; i < MAXARP; i++)
- {
- if (arplist[i].ipaddr == ipaddr && arplist[i].port == portno)
- {
- if (arplist[i].status == ARP_RESOLVED)
- {
- arplist[i].ttl = TIMEOUT_RESOLVED;
- return(arplist[i].hwaddr);
- }
-
- if (arplist[i].status == ARP_RESOLVING)
- return(NULL);
- }
- }
-
- return(NULL);
- }
-
- struct arp *Free_ARP_Slot(void)
- {
- register int i, oldest;
-
- for (oldest = 0, i = 0; i < MAXARP; i++)
- {
- if (arplist[i].status == ARP_UNUSED)
- return(arplist + i);
-
- if (arplist[i].status == ARP_RESOLVED)
- if (arplist[i].ttl < arplist[oldest].ttl)
- oldest = i;
- }
-
- return(arplist + oldest);
- }
-
- void ARP_Stats(void)
- {
- register int i;
- char addr[4];
-
- for (i = 0; i < MAXARP; i++)
- {
- if (arplist[i].status != ARP_UNUSED)
- {
- put32(addr, arplist[i].ipaddr);
-
- printf("Port:%d IP:%d.%d.%d.%d HW:%02X:%02X:%02X:%02X:%02X:%02X State:%s TTL:%d %s\n",
- arplist[i].port,
- addr[0], addr[1], addr[2], addr[3],
- arplist[i].hwaddr[0], arplist[i].hwaddr[1],
- arplist[i].hwaddr[2], arplist[i].hwaddr[3],
- arplist[i].hwaddr[4], arplist[i].hwaddr[5],
- (arplist[i].status == ARP_RESOLVED) ? "Resolved" : "Resolving",
- arplist[i].ttl / 100,
- (arplist[i].packet != NULLPACKET) ? "Packet" : "");
-
- }
- }
- }
-