/* 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/IP/NetIPup.c,v $ Author(s): Affiliation: ETH Zuerich, TIK Version: $Revision: 1.1 $ Creation Date: Last Date of Change: $Date: 2000/03/31 17:50:37 $ by: $Author: gfa $ $Log: NetIPup.c,v $ Revision 1.1 2000/03/31 17:50:37 gfa Merged with /Net from several term projects */ #include "NetIP.h" #include "NetIPchecksum.h" #include #include #include #include #include #include #include #include #include static int netipVerify(NetBuf buf); static int netipForUs(NetBuf buf, NetAttrs attrs); static void netipSetAttrs(NetBuf buf, NetAttrs attrs); void netipUp(NetBuf buf, NetAttrs attrs) { NetIPHdr *hdr=(NetIPHdr *) NETBUF_DATA(buf); netdbgDisplay(NETDEBUG_IP, "netip : Verifying.\n"); /* Is the packet ok ? */ if(!netipVerify(buf)) goto discard; /* Is the packet for us ? */ if(!netipForUs(buf,attrs)) { netdbgDisplay(NETDEBUG_IP,"netip : Packet not for us.\n"); goto discard; /* no forwarding at the moment. */ } /* Set remaining attributes not already done */ netipSetAttrs(buf,attrs); netdbgDisplay(NETDEBUG_IP, "netip : Verification passed.\n"); netdbgPrintf(NETDEBUG_GENERIC, "netip: before=%p\n", NETBUF_DATA(buf)); /* Remove header */ buf->start += BNIBGET(hdr->bitfield1,1)<<2; if(buf->start>buf->end) goto discard; netdbgPrintf(NETDEBUG_GENERIC, "netip: after=%p\n", NETBUF_DATA(buf)); /* Send up packet */ netcfgSendNextUp(NETMODULE_IP, buf, attrs); return; discard: netdbgDisplay(NETDEBUG_IP, "netip : Discarding upcoming packet.\n"); netbufFree(buf); netbufFree((NetBuf)attrs); } static int netipVerify(NetBuf buf) { NetIPHdr *hdr=(NetIPHdr *) NETBUF_DATA(buf); int len; /* check minimal length */ if(NETBUF_LEN(buf) < sizeof(NetIPHdr)) { netdbgDisplay(NETDEBUG_IP, "netip : Packet size smaller than minimal length.\n"); return 0; } /* check version */ /* If version==6, the packet should be sent to the IPv6 module. */ if(BNIBGET(hdr->bitfield1,0) != 4) { netdbgDisplay(NETDEBUG_IP, "netip : IP version not 4.\n"); return 0; } /* check header length */ len = BNIBGET(hdr->bitfield1,1) << 2; if(NETBUF_LEN(buf) < len) return 0; /* check checksum */ if((hdr->checksum = netipChecksum(buf, len))) { netdbgDisplay(NETDEBUG_IP, "netip : Wrong checksum. Discarding packet.\n"); return 0; } /* check total length */ len = netbufLen(buf); if(len < hdr->tot_len) { netdbgPrintf(NETDEBUG_IP, "netip : Packet too small (is %d, should be at least %d).\n", len, hdr->tot_len); return 0; } if(len > hdr->tot_len) netbufTrim(buf, hdr->tot_len); return 1; } static int netipForUs(NetBuf buf, NetAttrs attrs) { NetIPHdr *hdr=(NetIPHdr *) NETBUF_DATA(buf); unsigned short iface,a; if(!netattrGet(attrs,NETATTR_IF_FROM,&iface)) return 0; /* Broadcast is not handled yet... */ if(!netifGetAttr(iface,NETATTR_IP_FROM_0,&a)) return 0; if(a!=hdr->daddr0) return 0; netattrSet(attrs,NETATTR_IP_TO_0,a); if(!netifGetAttr(iface,NETATTR_IP_FROM_1,&a)) return 0; if(a!=hdr->daddr1) return 0; netattrSet(attrs,NETATTR_IP_TO_1,a); if(!netifGetAttr(iface,NETATTR_IP_FROM_2,&a)) return 0; if(a!=hdr->daddr2) return 0; netattrSet(attrs,NETATTR_IP_TO_2,a); if(!netifGetAttr(iface,NETATTR_IP_FROM_3,&a)) return 0; if(a!=hdr->daddr3) return 0; netattrSet(attrs,NETATTR_IP_TO_3,a); return 1; } static void netipSetAttrs(NetBuf buf, NetAttrs attrs) { NetIPHdr *hdr=(NetIPHdr *) NETBUF_DATA(buf); unsigned short tmp; /* Source address */ netattrSet(attrs,NETATTR_IP_FROM_0,(unsigned short) hdr->saddr0); netattrSet(attrs,NETATTR_IP_FROM_1,(unsigned short) hdr->saddr1); netattrSet(attrs,NETATTR_IP_FROM_2,(unsigned short) hdr->saddr2); netattrSet(attrs,NETATTR_IP_FROM_3,(unsigned short) hdr->saddr3); /* Protocol */ tmp = hdr->protocol; netattrSet(attrs, NETATTR_IP_PROTOCOL, tmp); }