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
00035
00036
00037 #ifndef ns_packet_h
00038 #define ns_packet_h
00039
00040 #include <string.h>
00041 #include <assert.h>
00042
00043 #include "config.h"
00044 #include "scheduler.h"
00045 #include "object.h"
00046 #include "lib/bsd-list.h"
00047 #include "packet-stamp.h"
00048 #include "ns-process.h"
00049
00050
00051 #define RT_PORT 255
00052
00053 #define HDR_CMN(p) (hdr_cmn::access(p))
00054 #define HDR_ARP(p) (hdr_arp::access(p))
00055 #define HDR_MAC(p) (hdr_mac::access(p))
00056 #define HDR_MAC802_11(p) ((hdr_mac802_11 *)hdr_mac::access(p))
00057 #define HDR_MAC_TDMA(p) ((hdr_mac_tdma *)hdr_mac::access(p))
00058 #define HDR_SMAC(p) ((hdr_smac *)hdr_mac::access(p))
00059 #define HDR_LL(p) (hdr_ll::access(p))
00060 #define HDR_IP(p) (hdr_ip::access(p))
00061 #define HDR_RTP(p) (hdr_rtp::access(p))
00062 #define HDR_TCP(p) (hdr_tcp::access(p))
00063 #define HDR_SR(p) (hdr_sr::access(p))
00064 #define HDR_TFRC(p) (hdr_tfrc::access(p))
00065 #define HDR_TORA(p) (hdr_tora::access(p))
00066 #define HDR_IMEP(p) (hdr_imep::access(p))
00067 #define HDR_CDIFF(p) (hdr_cdiff::access(p))
00068
00069 #define HDR_LMS(p) (hdr_lms::access(p))
00070
00071
00072
00073 enum packet_t {
00074 PT_TCP,
00075 PT_UDP,
00076 PT_CBR,
00077 PT_AUDIO,
00078 PT_VIDEO,
00079 PT_ACK,
00080 PT_START,
00081 PT_STOP,
00082 PT_PRUNE,
00083 PT_GRAFT,
00084 PT_GRAFTACK,
00085 PT_JOIN,
00086 PT_ASSERT,
00087 PT_MESSAGE,
00088 PT_RTCP,
00089 PT_RTP,
00090 PT_RTPROTO_DV,
00091 PT_CtrMcast_Encap,
00092 PT_CtrMcast_Decap,
00093 PT_SRM,
00094
00095 PT_REQUEST,
00096 PT_ACCEPT,
00097 PT_CONFIRM,
00098 PT_TEARDOWN,
00099 PT_LIVE,
00100 PT_REJECT,
00101
00102 PT_TELNET,
00103 PT_FTP,
00104 PT_PARETO,
00105 PT_EXP,
00106 PT_INVAL,
00107 PT_HTTP,
00108
00109
00110 PT_ENCAPSULATED,
00111 PT_MFTP,
00112
00113
00114 PT_ARP,
00115 PT_MAC,
00116 PT_TORA,
00117 PT_DSR,
00118 PT_AODV,
00119 PT_IMEP,
00120
00121
00122 PT_RAP_DATA,
00123 PT_RAP_ACK,
00124
00125 PT_TFRC,
00126 PT_TFRC_ACK,
00127 PT_PING,
00128
00129
00130 PT_DIFF,
00131
00132
00133 PT_RTPROTO_LS,
00134
00135
00136 PT_LDP,
00137
00138
00139 PT_GAF,
00140
00141
00142 PT_REALAUDIO,
00143
00144
00145 PT_PUSHBACK,
00146
00147 #ifdef HAVE_STL
00148
00149 PT_PGM,
00150 #endif //STL
00151
00152
00153 PT_LMS,
00154 PT_LMS_SETUP,
00155
00156
00157 PT_NTYPE
00158 };
00159
00160 class p_info {
00161 public:
00162 p_info() {
00163 name_[PT_TCP]= "tcp";
00164 name_[PT_UDP]= "udp";
00165 name_[PT_CBR]= "cbr";
00166 name_[PT_AUDIO]= "audio";
00167 name_[PT_VIDEO]= "video";
00168 name_[PT_ACK]= "ack";
00169 name_[PT_START]= "start";
00170 name_[PT_STOP]= "stop";
00171 name_[PT_PRUNE]= "prune";
00172 name_[PT_GRAFT]= "graft";
00173 name_[PT_GRAFTACK]= "graftAck";
00174 name_[PT_JOIN]= "join";
00175 name_[PT_ASSERT]= "assert";
00176 name_[PT_MESSAGE]= "message";
00177 name_[PT_RTCP]= "rtcp";
00178 name_[PT_RTP]= "rtp";
00179 name_[PT_RTPROTO_DV]= "rtProtoDV";
00180 name_[PT_CtrMcast_Encap]= "CtrMcast_Encap";
00181 name_[PT_CtrMcast_Decap]= "CtrMcast_Decap";
00182 name_[PT_SRM]= "SRM";
00183
00184 name_[PT_REQUEST]= "sa_req";
00185 name_[PT_ACCEPT]= "sa_accept";
00186 name_[PT_CONFIRM]= "sa_conf";
00187 name_[PT_TEARDOWN]= "sa_teardown";
00188 name_[PT_LIVE]= "live";
00189 name_[PT_REJECT]= "sa_reject";
00190
00191 name_[PT_TELNET]= "telnet";
00192 name_[PT_FTP]= "ftp";
00193 name_[PT_PARETO]= "pareto";
00194 name_[PT_EXP]= "exp";
00195 name_[PT_INVAL]= "httpInval";
00196 name_[PT_HTTP]= "http";
00197 name_[PT_ENCAPSULATED]= "encap";
00198 name_[PT_MFTP]= "mftp";
00199 name_[PT_ARP]= "ARP";
00200 name_[PT_MAC]= "MAC";
00201 name_[PT_TORA]= "TORA";
00202 name_[PT_DSR]= "DSR";
00203 name_[PT_AODV]= "AODV";
00204 name_[PT_IMEP]= "IMEP";
00205
00206 name_[PT_RAP_DATA] = "rap_data";
00207 name_[PT_RAP_ACK] = "rap_ack";
00208
00209 name_[PT_TFRC]= "tcpFriend";
00210 name_[PT_TFRC_ACK]= "tcpFriendCtl";
00211 name_[PT_PING]="ping";
00212
00213
00214 name_[PT_DIFF] = "diffusion";
00215
00216
00217 name_[PT_RTPROTO_LS] = "rtProtoLS";
00218
00219
00220 name_[PT_LDP] = "LDP";
00221
00222
00223 name_[PT_GAF] = "gaf";
00224
00225
00226 name_[PT_REALAUDIO] = "ra";
00227
00228
00229 name_[PT_PUSHBACK] = "pushback";
00230
00231 #ifdef HAVE_STL
00232
00233 name_[PT_PGM] = "PGM";
00234 #endif //STL
00235
00236
00237 name_[PT_LMS]="LMS";
00238 name_[PT_LMS_SETUP]="LMS_SETUP";
00239
00240 name_[PT_NTYPE]= "undefined";
00241 }
00242 const char* name(packet_t p) const {
00243 if ( p <= PT_NTYPE ) return name_[p];
00244 return 0;
00245 }
00246 static bool data_packet(packet_t type) {
00247 return ( (type) == PT_TCP || \
00248 (type) == PT_TELNET || \
00249 (type) == PT_CBR || \
00250 (type) == PT_AUDIO || \
00251 (type) == PT_VIDEO || \
00252 (type) == PT_ACK \
00253 );
00254 }
00255 private:
00256 static char* name_[PT_NTYPE+1];
00257 };
00258 extern p_info packet_info;
00259
00260
00261
00262 #define DATA_PACKET(type) ( (type) == PT_TCP || \
00263 (type) == PT_TELNET || \
00264 (type) == PT_CBR || \
00265 (type) == PT_AUDIO || \
00266 (type) == PT_VIDEO || \
00267 (type) == PT_ACK \
00268 )
00269
00270
00271 #define OFFSET(type, field) ((int) &((type *)0)->field)
00272
00273 class PacketData : public AppData {
00274 public:
00275 PacketData(int sz) : AppData(PACKET_DATA) {
00276 datalen_ = sz;
00277 if (datalen_ > 0)
00278 data_ = new unsigned char[datalen_];
00279 else
00280 data_ = NULL;
00281 }
00282 PacketData(PacketData& d) : AppData(d) {
00283 datalen_ = d.datalen_;
00284 if (datalen_ > 0) {
00285 data_ = new unsigned char[datalen_];
00286 memcpy(data_, d.data_, datalen_);
00287 } else
00288 data_ = NULL;
00289 }
00290 virtual ~PacketData() {
00291 if (data_ != NULL)
00292 delete []data_;
00293 }
00294 unsigned char* data() { return data_; }
00295
00296 virtual int size() const { return datalen_; }
00297 virtual AppData* copy() { return new PacketData(*this); }
00298 private:
00299 unsigned char* data_;
00300 int datalen_;
00301 };
00302
00303
00304 typedef void (*FailureCallback)(Packet *,void *);
00305
00306 class Packet : public Event {
00307 private:
00308 unsigned char* bits_;
00309
00310
00311 AppData* data_;
00312 static void init(Packet*);
00313 bool fflag_;
00314 protected:
00315 static Packet* free_;
00316 int ref_count_;
00317 public:
00318 Packet* next_;
00319 static int hdrlen_;
00320
00321 Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }
00322 inline unsigned char* const bits() { return (bits_); }
00323 inline Packet* copy() const;
00324 inline Packet* refcopy() { ++ref_count_; return this; }
00325 inline int& ref_count() { return (ref_count_); }
00326 static inline Packet* alloc();
00327 static inline Packet* alloc(int);
00328 inline void allocdata(int);
00329
00330 inline void initdata() { data_ = 0;}
00331 static inline void free(Packet*);
00332 inline unsigned char* access(int off) const {
00333 if (off < 0)
00334 abort();
00335 return (&bits_[off]);
00336 }
00337
00338
00339 inline unsigned char* accessdata() const {
00340 if (data_ == 0)
00341 return 0;
00342 assert(data_->type() == PACKET_DATA);
00343 return (((PacketData*)data_)->data());
00344 }
00345
00346
00347 inline AppData* userdata() const {
00348 return data_;
00349 }
00350 inline void setdata(AppData* d) {
00351 if (data_ != NULL)
00352 delete data_;
00353 data_ = d;
00354 }
00355 inline int datalen() const { return data_ ? data_->size() : 0; }
00356
00357
00358
00359 static void dump_header(Packet *p, int offset, int length);
00360
00361
00362
00363
00364 PacketStamp txinfo_;
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 u_int8_t incoming;
00375
00376
00377 };
00378
00379
00380
00381
00382
00383 class iface_literal {
00384 public:
00385 enum iface_constant {
00386 UNKN_IFACE= -1,
00387
00388
00389 ANY_IFACE= -2
00390
00391
00392
00393
00394
00395 };
00396 iface_literal(const iface_constant i, const char * const n) :
00397 value_(i), name_(n) {}
00398 inline int value() const { return value_; }
00399 inline const char * const name() const { return name_; }
00400 private:
00401 const iface_constant value_;
00402
00403 const char * const name_;
00404 };
00405
00406 static const iface_literal UNKN_IFACE(iface_literal::UNKN_IFACE, "?");
00407 static const iface_literal ANY_IFACE(iface_literal::ANY_IFACE, "*");
00408
00409
00410
00411
00412
00413
00414 enum ns_af_enum { NS_AF_NONE, NS_AF_ILINK, NS_AF_INET };
00415
00416 struct hdr_cmn {
00417 enum dir_t { DOWN= -1, NONE= 0, UP= 1 };
00418 packet_t ptype_;
00419 int size_;
00420 int uid_;
00421 int error_;
00422 int errbitcnt_;
00423 int fecsize_;
00424 double ts_;
00425 int iface_;
00426 dir_t direction_;
00427
00428 char src_rt_valid;
00429 double ts_arr_;
00430
00431
00432 nsaddr_t prev_hop_;
00433 nsaddr_t next_hop_;
00434 int addr_type_;
00435 nsaddr_t last_hop_;
00436
00437
00438
00439 FailureCallback xmit_failure_;
00440 void *xmit_failure_data_;
00441
00442
00443
00444
00445
00446
00447 int xmit_reason_;
00448 #define XMIT_REASON_RTS 0x01
00449 #define XMIT_REASON_ACK 0x02
00450
00451
00452 int num_forwards_;
00453 int opt_num_forwards_;
00454
00455
00456
00457 double txtime_;
00458 inline double& txtime() { return(txtime_); }
00459
00460 static int offset_;
00461 inline static int& offset() { return offset_; }
00462 inline static hdr_cmn* access(const Packet* p) {
00463 return (hdr_cmn*) p->access(offset_);
00464 }
00465
00466
00467 inline packet_t& ptype() { return (ptype_); }
00468 inline int& size() { return (size_); }
00469 inline int& uid() { return (uid_); }
00470 inline int& error() { return error_; }
00471 inline int& errbitcnt() {return errbitcnt_; }
00472 inline int& fecsize() {return fecsize_; }
00473 inline double& timestamp() { return (ts_); }
00474 inline int& iface() { return (iface_); }
00475 inline dir_t& direction() { return (direction_); }
00476
00477 inline nsaddr_t& next_hop() { return (next_hop_); }
00478 inline int& addr_type() { return (addr_type_); }
00479 inline int& num_forwards() { return (num_forwards_); }
00480 inline int& opt_num_forwards() { return (opt_num_forwards_); }
00481
00482 };
00483
00484
00485 class PacketHeaderClass : public TclClass {
00486 protected:
00487 PacketHeaderClass(const char* classname, int hdrsize);
00488 virtual int method(int argc, const char*const* argv);
00489 void field_offset(const char* fieldname, int offset);
00490 inline void bind_offset(int* off) { offset_ = off; }
00491 inline void offset(int* off) {offset_= off;}
00492 int hdrlen_;
00493 int* offset_;
00494 public:
00495 virtual void bind();
00496 virtual void export_offsets();
00497 TclObject* create(int argc, const char*const* argv);
00498 };
00499
00500
00501 inline void Packet::init(Packet* p)
00502 {
00503 bzero(p->bits_, hdrlen_);
00504 }
00505
00506 inline Packet* Packet::alloc()
00507 {
00508 Packet* p = free_;
00509 if (p != 0) {
00510 assert(p->fflag_ == FALSE);
00511 free_ = p->next_;
00512 assert(p->data_ == 0);
00513 p->uid_ = 0;
00514 p->time_ = 0;
00515 } else {
00516 p = new Packet;
00517 p->bits_ = new unsigned char[hdrlen_];
00518 if (p == 0 || p->bits_ == 0)
00519 abort();
00520 }
00521 init(p);
00522 (HDR_CMN(p))->next_hop_ = -2;
00523 (HDR_CMN(p))->last_hop_ = -2;
00524 p->fflag_ = TRUE;
00525 (HDR_CMN(p))->direction() = hdr_cmn::DOWN;
00526
00527
00528 p->next_ = 0;
00529 return (p);
00530 }
00531
00532
00533
00534
00535
00536
00537 inline void Packet::allocdata(int n)
00538 {
00539 assert(data_ == 0);
00540 data_ = new PacketData(n);
00541 if (data_ == 0)
00542 abort();
00543 }
00544
00545
00546 inline Packet* Packet::alloc(int n)
00547 {
00548 Packet* p = alloc();
00549 if (n > 0)
00550 p->allocdata(n);
00551 return (p);
00552 }
00553
00554
00555 inline void Packet::free(Packet* p)
00556 {
00557 if (p->fflag_) {
00558 if (p->ref_count_ == 0) {
00559
00560
00561
00562
00563 assert(p->uid_ <= 0);
00564
00565 if (p->data_ != 0) {
00566 delete p->data_;
00567 p->data_ = 0;
00568 }
00569 init(p);
00570 p->next_ = free_;
00571 free_ = p;
00572 p->fflag_ = FALSE;
00573 } else {
00574 --p->ref_count_;
00575 }
00576 }
00577 }
00578
00579 inline Packet* Packet::copy() const
00580 {
00581
00582 Packet* p = alloc();
00583 memcpy(p->bits(), bits_, hdrlen_);
00584 if (data_)
00585 p->data_ = data_->copy();
00586 p->txinfo_.init(&txinfo_);
00587
00588 return (p);
00589 }
00590
00591 inline void
00592 Packet::dump_header(Packet *p, int offset, int length)
00593 {
00594 assert(offset + length <= p->hdrlen_);
00595 struct hdr_cmn *ch = HDR_CMN(p);
00596
00597 fprintf(stderr, "\nPacket ID: %d\n", ch->uid());
00598
00599 for(int i = 0; i < length ; i+=16) {
00600 fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
00601 p->bits_[offset + i], p->bits_[offset + i + 1],
00602 p->bits_[offset + i + 2], p->bits_[offset + i + 3],
00603 p->bits_[offset + i + 4], p->bits_[offset + i + 5],
00604 p->bits_[offset + i + 6], p->bits_[offset + i + 7],
00605 p->bits_[offset + i + 8], p->bits_[offset + i + 9],
00606 p->bits_[offset + i + 10], p->bits_[offset + i + 11],
00607 p->bits_[offset + i + 12], p->bits_[offset + i + 13],
00608 p->bits_[offset + i + 14], p->bits_[offset + i + 15]);
00609 }
00610 }
00611
00612 #endif