⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp.cc

📁 一个很好的LINUX底下的GPRS协议栈
💻 CC
字号:
/*-*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- * * Copyright (c) 1997 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the Computer Systems *	Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Header: /nfs/jade/vint/CVSROOT/ns-2/arp.cc,v 1.11 2000/09/01 03:04:05 haoboy Exp $ *//*  * Ported from CMU/Monarch's code, nov'98 -Padma. * * basic arp cache and MAC addr resolution * * Note: code in this file violates the convention that addresses of * type Af_INET stored in nsaddr_t variables are stored in 24/8 format. * Many variables in nsaddr_t's in this file store ip addrs as simple ints. */#include <errno.h>#include "delay.h"//#include "debug.h"#include "mac.h"#include "arp.h"#include "topography.h"#include "cmu-trace.h"#include "mobilenode.h"#include "ll.h"#include "packet.h"#include <address.h>// #define DEBUGstatic class ARPTableClass : public TclClass {public:        ARPTableClass() : TclClass("ARPTable") {}        TclObject* create(int, const char*const* argv) {                return (new ARPTable(argv[4], argv[5]));        }} class_arptable;int hdr_arp::offset_;static class ARPHeaderClass : public PacketHeaderClass {public:        ARPHeaderClass() : PacketHeaderClass("PacketHeader/ARP",                                             sizeof(hdr_arp)) { 		bind_offset(&hdr_arp::offset_);	}} class_arphdr;/* ======================================================================   Address Resolution (ARP) Table   ====================================================================== */ARPTable_List ARPTable::athead_ = { 0 };voidARPTable::Terminate(){	ARPEntry *ll;	for(ll = arphead_.lh_first; ll; ll = ll->arp_link_.le_next) {		if(ll->hold_) {			drop(ll->hold_, DROP_END_OF_SIMULATION);			ll->hold_ = 0;		}	}}ARPTable::ARPTable(const char *tclnode, const char *tclmac) : LinkDelay() {	LIST_INIT(&arphead_);        node_ = (MobileNode*) TclObject::lookup(tclnode);	assert(node_);	mac_ = (Mac*) TclObject::lookup(tclmac);	assert(mac_);	LIST_INSERT_HEAD(&athead_, this, link_);}intARPTable::command(int argc, const char*const* argv){	if (argc == 2 && strcasecmp(argv[1], "reset") == 0) {		Terminate();		//FALL-THROUGH to give parents a chance to reset	}	return LinkDelay::command(argc, argv);}intARPTable::arpresolve(nsaddr_t dst, Packet *p, LL *ll){        ARPEntry *llinfo ;		assert(initialized());	llinfo = arplookup(dst);#ifdef DEBUG        fprintf(stderr, "%d - %s\n", node_->address(), __FUNCTION__);#endif		if(llinfo && llinfo->up_) {		mac_->hdr_dst((char*) HDR_MAC(p), llinfo->macaddr_);		return 0;	}	if(llinfo == 0) {		/*		 *  Create a new ARP entry		 */		llinfo = new ARPEntry(&arphead_, dst);	}        if(llinfo->count_ >= ARP_MAX_REQUEST_COUNT) {                /*                 * Because there is not necessarily a scheduled event between                 * this callback and the point where the callback can return                 * to this point in the code, the order of operations is very                 * important here so that we don't get into an infinite loop.                 *                                      - josh                 */                Packet *t = llinfo->hold_;                llinfo->count_ = 0;                llinfo->hold_ = 0;		hdr_cmn* ch;		                if(t) {                        ch = HDR_CMN(t);                        if (ch->xmit_failure_) {                                ch->xmit_reason_ = 0;                                ch->xmit_failure_(t, ch->xmit_failure_data_);                        }                        else {                                drop(t, DROP_IFQ_ARP_FULL);                        }                }                ch = HDR_CMN(p);		if (ch->xmit_failure_) {                        ch->xmit_reason_ = 0;                        ch->xmit_failure_(p, ch->xmit_failure_data_);                }                else {                        drop(p, DROP_IFQ_ARP_FULL);                }                return EADDRNOTAVAIL;        }	llinfo->count_++;	if(llinfo->hold_)		drop(llinfo->hold_, DROP_IFQ_ARP_FULL);	llinfo->hold_ = p;	/*	 *  We don't have a MAC address for this node.  Send an ARP Request.	 *	 *  XXX: Do I need to worry about the case where I keep ARPing	 *	 for the SAME destination.	 */	int src = node_->address(); // this host's IP addr	arprequest(src, dst, ll);	return EADDRNOTAVAIL;}ARPEntry*ARPTable::arplookup(nsaddr_t dst){	ARPEntry *a;	for(a = arphead_.lh_first; a; a = a->nextarp()) {		if(a->ipaddr_ == dst)			return a;	}	return 0;}voidARPTable::arprequest(nsaddr_t src, nsaddr_t dst, LL *ll){		Scheduler& s = Scheduler::instance();	Packet *p = Packet::alloc();	hdr_cmn *ch = HDR_CMN(p);	char	*mh = (char*) HDR_MAC(p);	hdr_ll	*lh = HDR_LL(p);	hdr_arp	*ah = HDR_ARP(p);	ch->uid() = 0;	ch->ptype() = PT_ARP;	ch->size() = ARP_HDR_LEN;	ch->iface() = -2;	ch->error() = 0;	mac_->hdr_dst(mh, MAC_BROADCAST);	mac_->hdr_src(mh, ll->mac_->addr());	mac_->hdr_type(mh, ETHERTYPE_ARP);	lh->seqno() = 0;	lh->lltype() = LL_DATA;	ch->direction() = hdr_cmn::DOWN; // send this pkt down	ah->arp_hrd = ARPHRD_ETHER;	ah->arp_pro = ETHERTYPE_IP;	ah->arp_hln = ETHER_ADDR_LEN;	ah->arp_pln = sizeof(nsaddr_t);	ah->arp_op  = ARPOP_REQUEST;	ah->arp_sha = ll->mac_->addr();	ah->arp_spa = src;	ah->arp_tha = 0;		// what were're looking for	ah->arp_tpa = dst;	s.schedule(ll->downtarget_, p, delay_);}voidARPTable::arpinput(Packet *p, LL *ll){	Scheduler& s = Scheduler::instance();	hdr_arp *ah = HDR_ARP(p);	ARPEntry *llinfo;	assert(initialized());#ifdef DEBUG	fprintf(stderr,                "%d - %s\n\top: %x, sha: %x, tha: %x, spa: %x, tpa: %x\n",		node_->address(), __FUNCTION__, ah->arp_op,                ah->arp_sha, ah->arp_tha, ah->arp_spa, ah->arp_tpa);#endif	if((llinfo = arplookup(ah->arp_spa)) == 0) {		/*		 *  Create a new ARP entry		 */		llinfo = new ARPEntry(&arphead_, ah->arp_spa);	}        assert(llinfo);	llinfo->macaddr_ = ah->arp_sha;	llinfo->up_ = 1;	/*	 *  Can we send whatever's being held?	 */	if(llinfo->hold_) {		hdr_cmn *ch = HDR_CMN(llinfo->hold_);		char *mh = (char*) HDR_MAC(llinfo->hold_);                hdr_ip *ih = HDR_IP(llinfo->hold_);                		// XXXHACK for now: 		// Future work: separate port-id from IP address ??		int dst = Address::instance().get_nodeaddr(ih->daddr());				if((ch->addr_type() == NS_AF_NONE &&                    dst == ah->arp_spa) ||                   (NS_AF_INET == ch->addr_type() &&                    ch->next_hop() == ah->arp_spa)) {#ifdef DEBUG			fprintf(stderr, "\tsending HELD packet.\n");#endif			mac_->hdr_dst(mh, ah->arp_sha);			ll->fragDATA(llinfo->hold_); //for sandy's LL			//s.schedule(ll->downtarget_, llinfo->hold_, delay_);			llinfo->hold_ = 0;		}                else {                        fprintf(stderr, "\tfatal ARP error...\n");                        exit(1);                }	}	if(ah->arp_op == ARPOP_REQUEST &&		ah->arp_tpa == node_->address()) {				hdr_cmn *ch = HDR_CMN(p);		char	*mh = (char*)HDR_MAC(p);		hdr_ll  *lh = HDR_LL(p);		ch->size() = ARP_HDR_LEN;		ch->error() = 0;		ch->direction() = hdr_cmn::DOWN; // send this pkt down		mac_->hdr_dst(mh, ah->arp_sha);		mac_->hdr_src(mh, ll->mac_->addr());		mac_->hdr_type(mh, ETHERTYPE_ARP);		lh->seqno() = 0;		lh->lltype() = LL_DATA;		// ah->arp_hrd = 		// ah->arp_pro =		// ah->arp_hln =		// ah->arp_pln =		ah->arp_op  = ARPOP_REPLY;		ah->arp_tha = ah->arp_sha;		ah->arp_sha = ll->mac_->addr();		nsaddr_t t = ah->arp_spa;		ah->arp_spa = ah->arp_tpa;		ah->arp_tpa = t;		s.schedule(ll->downtarget_, p, delay_);		return;	}	Packet::free(p);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -