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

📄 nat.cc

📁 柯老师网站上找到的
💻 CC
字号:
/*     * Copyright (c) 1998 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 Network Research *      Group at Lawrence Berkeley National 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. */  #ifndef lintstatic const char rcsid[] =    "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/emulate/nat.cc,v 1.7 2000/02/10 01:48:30 salehi Exp $";#endif#include <stdio.h>#include <sys/types.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#ifndef __FAVOR_BSD#define __FAVOR_BSD#endif;#include <netinet/tcp.h>#include <arpa/inet.h>#include "agent.h"#include "scheduler.h"#include "packet.h"#include "ip.h"#include "emulate/net.h"#include "emulate/internet.h"//// Nat -- a limited-functionality TCP address rewriting// facility for emulation mode.// class NatAgent : public Agent {public:	NatAgent() : Agent(PT_LIVE) { }	void recv(Packet*, Handler*);protected:	virtual void	rewrite_addr(ip*) = 0;	u_short		addrsum(in_addr*);	u_short		addrsum(in_addr*, in_addr*);	void	nat(Packet*);	virtual u_short	newval() = 0;	virtual u_short oldval(ip*) = 0;	void	fixipcksum(ip*, int);		// ip only	void	fixtcpudpcksum(ip*, int);	// tcp,udp/ip	virtual void	fixtsum(ip*, int) { };	// any transport	int	command(int argc, const char*const* argv);};class TCPDestNat : public virtual NatAgent {protected:	void	rewrite_addr(ip*);	void	fixtsum(ip* iph, int hlen) {		fixtcpudpcksum(iph, hlen);	}	u_short newval();	u_short oldval(ip*);	int	command(int argc, const char*const* argv);	in_addr	newdst_;};class TCPSrcNat : public virtual NatAgent {protected:	void	rewrite_addr(ip*);	void	fixtsum(ip* iph, int hlen) {		fixtcpudpcksum(iph, hlen);	}	u_short newval();	u_short oldval(ip*);	int	command(int argc, const char*const* argv);	in_addr	newsrc_;};class TCPSrcDestNat : public TCPDestNat, public TCPSrcNat {protected:	void	rewrite_addr(ip*);	u_short newval();	u_short oldval(ip*);	void	fixtsum(ip* iph, int hlen) {		fixtcpudpcksum(iph, hlen);	}	int	command(int argc, const char*const* argv);};static class NatTCPSrcAgentClass : public TclClass { public:        NatTCPSrcAgentClass() : TclClass("Agent/NatAgent/TCPSrc") {}        TclObject* create(int , const char*const*) {                return (new TCPSrcNat());        } } class_tcpsrcnat;static class NatTCPDestAgentClass : public TclClass { public:        NatTCPDestAgentClass() : TclClass("Agent/NatAgent/TCPDest") {}        TclObject* create(int , const char*const*) {                return (new TCPDestNat());        } } class_tcpdstnat;static class NatTCPSrcDestAgentClass : public TclClass { public:        NatTCPSrcDestAgentClass() : TclClass("Agent/NatAgent/TCPSrcDest") {}        TclObject* create(int , const char*const*) {                return (new TCPSrcDestNat());        } } class_tcpsrcdstnat;voidNatAgent::recv(Packet *pkt, Handler *){	nat(pkt);	// we are merely rewriting an already-existing	// packet (which was destined for us), so be	// sure to rewrite the simulator's notion of the	// address, otherwise we just keep sending to ourselves	// (ouch).	hdr_ip* iph = hdr_ip::access(pkt);	iph->src() = here_;	iph->dst() = dst_;	send(pkt, 0);}/* * NatAgent base class: fix only IP-layer checksums */voidNatAgent::fixipcksum(ip* iph, int iphlen){	// fix IP cksum	iph->ip_sum = 0;	iph->ip_sum = Internet::in_cksum((u_short*) iph, iphlen);	return;}/* * rewrite packet addresses, calls object-specific rewrite_addr() function */voidNatAgent::nat(Packet* pkt){        hdr_cmn* hc = (hdr_cmn*)pkt->access(off_cmn_);        ip* iph = (ip*) pkt->accessdata();	if (pkt->datalen() < hc->size()) {		fprintf(stderr,		    "NatAgent(%s): recvd packet with pkt sz %d but bsize %d\n",			name(), hc->size(), pkt->datalen());		return;	}	int iphlen = (((u_char*)iph)[0] & 0x0f) << 2;	fixtcpudpcksum(iph, iphlen);	// requires orig header!	rewrite_addr(iph);	fixipcksum(iph, iphlen);}/* * functions to compute 1's complement sum of 1 and 2 IP addresses * (note: only the sum, not the complement of the sum) */u_shortNatAgent::addrsum(in_addr* ia){	u_short* p = (u_short*) ia;	u_short sum = 0;	sum += *p++;	sum += *p;	sum = (sum >> 16) + (sum & 0xffff);	sum += (sum >> 16);	return (sum);}u_shortNatAgent::addrsum(in_addr* ia1, in_addr* ia2){	u_short* p = (u_short*) ia1;	u_short sum = 0;	sum += *p++;	sum += *p;	p = (u_short*) ia2;	sum += *p++;	sum += *p;	sum = (sum >> 16) + (sum & 0xffff);	sum += (sum >> 16);	return (sum);}/* * incrementally update tcp or udp packet for new addresses: *	rewrite IP addresses and recompute IP header cksum *	recompute TCP or UDP pseudoheader checksum * * note: this code is tricky because of the masking. * Please do not modify without careful testing. */voidNatAgent::fixtcpudpcksum(ip* iph, int iphlen){	tcphdr* tcph = (tcphdr*)(((u_char*) iph) + iphlen);	u_short sum = tcph->th_sum;//printf("isum: 0x%x\n", sum & 0xffff);//printf("oval: 0x%x, nval: 0x%x\n",//~oldval(iph) & 0xffff, newval());	u_long nsum;	nsum = ~sum & 0xffff;	nsum += ~oldval(iph) & 0xffff;	nsum += newval();//printf("nsum2: 0x%x\n", nsum);	nsum = (nsum >> 16) + (nsum & 0xffff);	nsum += (nsum >> 16);	sum = ~nsum;	tcph->th_sum = sum & 0xffff;//printf("fsum: 0x%hx\n", tcph->th_sum);	return;}voidTCPSrcNat::rewrite_addr(ip* iph){	iph->ip_src = newsrc_;}u_shortTCPSrcNat::newval(){	return (addrsum(&newsrc_));}u_shortTCPSrcNat::oldval(ip* iph){	return (addrsum(&iph->ip_src));}u_shortTCPDestNat::newval(){	return (addrsum(&newdst_));}u_shortTCPDestNat::oldval(ip* iph){	return (addrsum(&iph->ip_dst));}voidTCPDestNat::rewrite_addr(ip* iph){	iph->ip_dst = newdst_;}voidTCPSrcDestNat::rewrite_addr(ip* iph){	TCPSrcNat::rewrite_addr(iph);	TCPDestNat::rewrite_addr(iph);}u_shortTCPSrcDestNat::newval(){	return(addrsum(&newsrc_, &newdst_));}u_shortTCPSrcDestNat::oldval(ip* iph){//printf("oldval:%hx\n", addrsum(&iph->ip_src, &iph->ip_dst));	return(addrsum(&iph->ip_src, &iph->ip_dst));}intNatAgent::command(int argc, const char*const* argv){	return(Agent::command(argc, argv));}intTCPSrcNat::command(int argc, const char*const* argv){	// $srcnat source <ipaddr>	if (argc == 3) {		if (strcmp(argv[1], "source") == 0) {			u_long ns;			ns = inet_addr(argv[2]);			newsrc_.s_addr = ns;			return (TCL_OK);		}	}	return (NatAgent::command(argc, argv));}intTCPDestNat::command(int argc, const char*const* argv){	// $srcnat destination <ipaddr>	if (argc == 3) {		if (strcmp(argv[1], "destination") == 0) {			u_long nd;			nd = inet_addr(argv[2]);			newdst_.s_addr = nd;			return (TCL_OK);		}	}	return (NatAgent::command(argc, argv));}intTCPSrcDestNat::command(int argc, const char*const* argv){	// $srcnat source <ipaddr>	if (argc == 3) {		if (strcmp(argv[1], "source") == 0) {			u_long ns;			ns = inet_addr(argv[2]);			newsrc_.s_addr = ns;			return (TCL_OK);		}	}	// $srcnat destination <ipaddr>	if (argc == 3) {		if (strcmp(argv[1], "destination") == 0) {			u_long nd;			nd = inet_addr(argv[2]);			newdst_.s_addr = nd;			return (TCL_OK);		}	}	return (NatAgent::command(argc, argv));}

⌨️ 快捷键说明

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