00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef lint
00035 static const char rcsid[] =
00036 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/emulate/icmp.cc,v 1.5 2000/09/01 03:04:10 haoboy Exp $";
00037 #endif
00038
00039 #include <stdio.h>
00040 #include <sys/types.h>
00041 #include <netinet/in.h>
00042 #include <netinet/in_systm.h>
00043 #include <netinet/ip.h>
00044 #include <netinet/ip_icmp.h>
00045 #include <netinet/ip_icmp.h>
00046 #include <arpa/inet.h>
00047
00048 #include "agent.h"
00049 #include "scheduler.h"
00050 #include "packet.h"
00051 #include "emulate/net.h"
00052 #include "emulate/internet.h"
00053
00054 #ifndef IPPROTO_GGP
00055 #define IPPROTO_GGP 3
00056 #endif // IPPROTO_GGP
00057
00058
00059
00060
00061
00062 class IcmpAgent : public Agent {
00063 public:
00064 IcmpAgent();
00065 void recv(Packet*, Handler*) { abort(); }
00066 protected:
00067 void sendredirect(in_addr& me, in_addr& target, in_addr& dest, in_addr& gw);
00068 int command(int argc, const char*const* argv);
00069
00070 int ttl_;
00071 };
00072
00073 static class IcmpAgentClass : public TclClass {
00074 public:
00075 IcmpAgentClass() : TclClass("Agent/IcmpAgent") {}
00076 TclObject* create(int , const char*const*) {
00077 return (new IcmpAgent());
00078 }
00079 } class_icmpsagent;
00080
00081 IcmpAgent::IcmpAgent() : Agent(PT_LIVE)
00082 {
00083 bind("ttl_", &ttl_);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 void
00093 IcmpAgent::sendredirect(in_addr& me, in_addr& target, in_addr& dst, in_addr& gw)
00094 {
00095
00096
00097
00098 int iplen = sizeof(ip) + 8 + sizeof(ip) + 8;
00099 Packet* p = allocpkt(iplen);
00100 hdr_cmn* hc = HDR_CMN(p);
00101 ip* iph = (ip*) p->accessdata();
00102 hc->size() = iplen;
00103
00104
00105
00106 Internet::makeip(iph, iplen, ttl_, IPPROTO_ICMP, me, target);
00107
00108
00109 icmp* icp = (icmp*) (iph + 1);
00110 icp->icmp_gwaddr = gw;
00111
00112
00113
00114
00115
00116 ip* dummyhdr = (ip*)((u_char*)icp + 8);
00117
00118 Internet::makeip(dummyhdr, 20, 254, IPPROTO_GGP, target, dst);
00119 u_short *port = (u_short*) (dummyhdr + 1);
00120 *port++ = htons(9);
00121 *port = htons(9);
00122 icp->icmp_cksum = 0;
00123 icp->icmp_type = ICMP_REDIRECT;
00124 icp->icmp_code = ICMP_REDIRECT_HOST;
00125 icp->icmp_cksum = Internet::in_cksum((u_short*)icp,
00126 8 + sizeof(ip) + 8);
00127
00128 send(p, 0);
00129 return;
00130 }
00131
00132 int
00133 IcmpAgent::command(int argc, const char*const* argv)
00134 {
00135 if (argc > 5) {
00136
00137 if (strcmp(argv[1], "send") == 0) {
00138 if (strcmp(argv[2], "redirect") == 0 &&
00139 argc == 7) {
00140
00141
00142
00143 u_long s, t, d, g;
00144 s = inet_addr(argv[3]);
00145 t = inet_addr(argv[4]);
00146 d = inet_addr(argv[5]);
00147 g = inet_addr(argv[6]);
00148 in_addr src, targ, dst, gw;
00149 src.s_addr = s;
00150 targ.s_addr = t;
00151 dst.s_addr = d;
00152 gw.s_addr = g;
00153 sendredirect(src, targ, dst, gw);
00154 return (TCL_OK);
00155 }
00156 }
00157 }
00158 return (Agent::command(argc, argv));
00159 }