/* Copyright 2000 (c) by David Schweikert, Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. TOPSY -- A Teachable Operating System. Implementation of a tiny and simple micro kernel for teaching purposes. For further information, please visit http://www.tik.ee.ethz.ch/~topsy This software is provided under the terms of the GNU General Public Licence. A full copy of the GNU GPL is provided in the file COPYING found in the development root of Topsy. */ /* File: $Source: /usr/drwho/vault/cvs/topsy/Topsy/Net/NetConfigARP.c,v $ Author(s): Affiliation: ETH Zuerich, TIK Version: $Revision: 1.1 $ Creation Date: Last Date of Change: $Date: 2000/03/31 17:50:34 $ by: $Author: gfa $ $Log: NetConfigARP.c,v $ Revision 1.1 2000/03/31 17:50:34 gfa Merged with /Net from several term projects */ #include #include #include #include #include /* This file is the ARP cache */ void netcfgarpAddCacheETHIP(unsigned char *hw, unsigned char *ip); static void netcfgarpInitETHIP(); void netcfgarpInit() { netcfgarpInitETHIP(); } /* ETH <-> IP (ETHIP) is the most common Address Resolution Protocol (ARP) */ typedef struct NetCfgARP_ETHIP_Entry_t { unsigned char ip[4]; unsigned char hw[6]; } NetCfgARP_ETHIP_Entry; static NetCfgARP_ETHIP_Entry netcfgarp_ethip_cache[NETCFGARP_CACHESIZE]; static int netcfgarp_ethip_pos; NetCfgARP_ETHIP_Entry *netcfgarpLookupETHIP(unsigned char *ip); static void netcfgarpInitETHIP() { int i; for(i=0; iip[0]=ip[0]; entry->ip[1]=ip[1]; entry->ip[2]=ip[2]; entry->ip[3]=ip[3]; } entry->hw[0]=hw[0]; entry->hw[1]=hw[1]; entry->hw[2]=hw[2]; entry->hw[3]=hw[3]; entry->hw[4]=hw[4]; entry->hw[5]=hw[5]; #ifdef NETDEBUG netdbgPrintf(NETDEBUG_ARP, "netcfg: Adding ARP cache entry (%02x:%02x:%02x:%02x:%02x:%02x,%d.%d.%d.%d)\n", hw[0], hw[1], hw[2], hw[3], hw[4], hw[5], ip[0], ip[1], ip[2], ip[3]); #endif } NetCfgARP_ETHIP_Entry *netcfgarpLookupETHIP(unsigned char *ip) { int i,j; NetCfgARP_ETHIP_Entry *entry; /* brute search ... */ for(i=0; i=0; j--) { if(entry->ip[j] != ip[j]) { break; } } if(j<0) return entry; } /* not found...*/ netdbgPrintf(NETDEBUG_ARP, "netcfg: ARP lookup failed.\n"); return 0; } void netcfgarpSendRequestETHIP(NetBuf buf, NetAttrs attrs, unsigned char *ip); int netcfgarpResolveETHIP(NetBuf buf, NetAttrs attrs) { NetCfgARP_ETHIP_Entry *e; unsigned short tmp; unsigned char ip[4]; if(!netattrGet(attrs,NETATTR_IP_TO_0, &tmp)) return 0; ip[0] = tmp; if(!netattrGet(attrs,NETATTR_IP_TO_1, &tmp)) return 0; ip[1] = tmp; if(!netattrGet(attrs,NETATTR_IP_TO_2, &tmp)) return 0; ip[2] = tmp; if(!netattrGet(attrs,NETATTR_IP_TO_3, &tmp)) return 0; ip[3] = tmp; e = netcfgarpLookupETHIP(ip); if(e) { tmp = (unsigned short) e->hw[0]<<8 | e->hw[1]; netattrSet(attrs,NETATTR_ETH_TO_0,tmp); tmp = (unsigned short) e->hw[2]<<8 | e->hw[3]; netattrSet(attrs,NETATTR_ETH_TO_1,tmp); tmp = (unsigned short) e->hw[4]<<8 | e->hw[5]; netattrSet(attrs,NETATTR_ETH_TO_2,tmp); return 1; } else { /* send arp */ /* since IP doesn't make any delivery guarantee, it is ok * (although ugly) to throw away the not resolved packet * instead of putting it in a wait queue */ netdbgDisplay(NETDEBUG_CONFIG, "netcfg: Sending ARP request.\n"); netcfgarpSendRequestETHIP(buf, attrs, ip); return 0; } } void netcfgarpSendRequestETHIP(NetBuf buf, NetAttrs pkt_attrs, unsigned char *ip) { unsigned short tmp; NetAttrs arp_attrs; if(!netattrNew(&arp_attrs)) return; /* ARP should be sent on the same interface */ if(!netattrGet(pkt_attrs, NETATTR_IF_TO, &tmp)) { netattrFree(arp_attrs); return; } netattrSet(arp_attrs, NETATTR_IF_TO, tmp); /* set hw_type, hw_len, pr_type, pr_len */ netattrSet(arp_attrs, NETATTR_ARP_HW_TYPE, (unsigned short) NETARP_HWTYPE_ETH); netattrSet(arp_attrs, NETATTR_ARP_HW_LEN, (unsigned short) 6); netattrSet(arp_attrs, NETATTR_ARP_PR_TYPE, (unsigned short) NETETH_TYPE_IP); netattrSet(arp_attrs, NETATTR_ARP_PR_LEN, (unsigned short) 4); /* set target pr_address */ netattrSet(arp_attrs, NETATTR_ARP_PR_0, ip[0]+(ip[1]<<8)); netattrSet(arp_attrs, NETATTR_ARP_PR_1, ip[2]+(ip[3]<<8)); /* send... */ netdbgDisplay(NETDEBUG_CONFIG, "netcfg: Message sent to module ARP.\n"); netmodSendDown(NETMODULE_ARP, 0, arp_attrs); }