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/iptap.cc,v 1.3 2002/09/23 23:25:05 alefiyah Exp $ (ISI)";
00037 #endif
00038
00039 #include "iptap.h"
00040
00041
00042 static class IPTapAgentClass : public TclClass {
00043 public:
00044 IPTapAgentClass() : TclClass("Agent/IPTap") {}
00045 TclObject* create(int, const char*const*) {
00046 return (new IPTapAgent());
00047 }
00048 } class_iptap_agent;
00049
00050
00051 IPTapAgent::IPTapAgent()
00052 {
00053 int i = 0;
00054 index = 0;
00055 for (; i < MAX_PACKETS ; i++) {
00056 ident[i] = -1;
00057 offset[i] = -1;
00058 }
00059
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 int
00072 IPTapAgent::isDuplicate(unsigned short id, unsigned short off)
00073 {
00074 int i = 0;
00075 for( ; i < MAX_PACKETS; i++){
00076 if ((ident[i] == id) && (offset[i] == off)) {
00077 return 1;
00078 }
00079 }
00080 ident[index % MAX_PACKETS] = id;
00081 offset[index % MAX_PACKETS] = off;
00082 index++;
00083 return 0;
00084 }
00085
00086
00087
00088
00089
00090
00091 unsigned short
00092 IPTapAgent::in_cksum(unsigned short *addr, int len)
00093 {
00094 register int sum = 0;
00095 u_short answer = 0;
00096 register u_short *w = addr;
00097 register int nleft = len;
00098
00099
00100
00101
00102
00103
00104 while (nleft > 1) {
00105 sum += *w++;
00106 nleft -= 2;
00107 }
00108
00109
00110 if (nleft == 1) {
00111 *(u_char *)(&answer) = *(u_char *)w ;
00112 sum += answer;
00113 }
00114
00115
00116 sum = (sum >> 16) + (sum & 0xffff);
00117 sum += (sum >> 16);
00118 answer = ~sum;
00119 return(answer);
00120
00121 }
00122
00123 void
00124 IPTapAgent::pkt_handler(void *clientdata, Packet *p, const struct timeval &ts)
00125 {
00126 IPTapAgent *inst = (IPTapAgent *)clientdata;
00127 inst->processpkt(p, ts);
00128 }
00129
00130 void
00131 IPTapAgent::processpkt(Packet *p, const struct timeval &ts)
00132 {
00133 struct ip *ipheader;
00134 struct tcphdr *tcpheader;
00135 unsigned char *buf;
00136
00137
00138 int iphlen;
00139 unsigned short datagramlen;
00140 unsigned char ttl;
00141
00142
00143 unsigned char tcphlen;
00144
00145
00146
00147
00148
00149
00150
00151
00152 ipheader = (struct ip *) p->accessdata();
00153 buf = p->accessdata();
00154 iphlen = ipheader->ip_hl * 4;
00155 ttl = ipheader->ip_ttl;
00156 if (!(--ttl)) {
00157 fprintf(stderr,
00158 "IPTapAgent(%s) : received ttl zero.\n",
00159 name());
00160 Packet::free(p);
00161 return;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 datagramlen = ntohs(ipheader->ip_len);
00175
00176
00177 hdr_cmn *ch = HDR_CMN(p);
00178 ch->size() = datagramlen;
00179
00180 hdr_ip *ih = HDR_IP(p);
00181 ih->ttl() = ttl;
00182
00183
00184 target_->recv(p);
00185 return;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 void
00198 IPTapAgent::recvpkt()
00199 {
00200 if (net_->mode() != O_RDWR && net_->mode() != O_RDONLY) {
00201 fprintf(stderr,
00202 "IPTapAgent(%s): recvpkt called while in write-only mode!\n",
00203 name());
00204 return;
00205 }
00206
00207 int cc = net_->recv(pkt_handler, this);
00208 if (cc <= 0) {
00209 if (cc < 0) {
00210 perror("recv");
00211 }
00212 return;
00213 }
00214 TDEBUG4("%f: IPTapAgent(%s): recvpkt, cc:%d\n", now(), name(), cc);
00215
00216
00217
00218
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 int
00231 IPTapAgent::sendpkt(Packet* p)
00232 {
00233 int byteswritten;
00234 unsigned char *packet;
00235 unsigned char received_ttl;
00236 unsigned short dglen;
00237 struct ip *ipheader;
00238
00239 if (net_->mode() != O_RDWR && net_->mode() != O_WRONLY) {
00240 fprintf(stderr,
00241 "IPTapAgent(%s): sendpkt called while in read-only mode!\n",
00242 name());
00243 return (-1);
00244 }
00245
00246
00247 hdr_cmn* hc = HDR_CMN(p);
00248 if (net_ == NULL) {
00249 fprintf(stderr,
00250 "IPTapAgent(%s): sendpkt attempted with NULL net\n",
00251 name());
00252 drop(p);
00253 return (-1);
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 hdr_ip *ih = HDR_IP(p);
00266 received_ttl = ih->ttl_;
00267 if (!received_ttl) {
00268
00269 fprintf(stderr,
00270 "IPTapAgent(%s): received packet ttl zero.\n",
00271 name());
00272 drop(p);
00273 return(-1);
00274 }
00275
00276
00277
00278 packet = p->accessdata();
00279 ipheader = (struct ip *) packet;
00280 ipheader->ip_ttl = received_ttl;
00281 ipheader->ip_sum = 0;
00282 ipheader->ip_sum = (unsigned short) in_cksum((unsigned short *) ipheader,
00283 sizeof(struct ip));
00284
00285 if (net_->send(p->accessdata(), hc->size()) < 0) {
00286 fprintf(stderr,
00287 "IPTapAgent(%s): sendpkt (%p, %d): %s\n",
00288 name(), p->accessdata(), hc->size(), strerror(errno));
00289 Packet::free(p);
00290 return (-1);
00291
00292 }
00293 Packet::free(p);
00294 TDEBUG3("IPTapAgent(%s): sent packet (sz: %d)\n",
00295 name(), hc->size());
00296 return 0;
00297 }
00298
00299