Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

packet.h

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by the Computer Systems
00017  *      Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/packet.h,v 1.93 2003/02/02 22:33:53 xuanc Exp $ (LBL)
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 // Used by wireless routing code to attach routing agent
00051 #define RT_PORT         255     /* port that all route msgs are sent to */
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))  /* chalermak's diffusion*/
00068 //#define HDR_DIFF(p)     (hdr_diff::access(p))  /* SCADD's diffusion ported into ns */
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         /* simple signalling messages */
00095         PT_REQUEST,     
00096         PT_ACCEPT,      
00097         PT_CONFIRM,     
00098         PT_TEARDOWN,    
00099         PT_LIVE,        // packet from live network
00100         PT_REJECT,
00101 
00102         PT_TELNET,      // not needed: telnet use TCP
00103         PT_FTP,
00104         PT_PARETO,
00105         PT_EXP,
00106         PT_INVAL,
00107         PT_HTTP,
00108 
00109         /* new encapsulator */
00110         PT_ENCAPSULATED,
00111         PT_MFTP,
00112 
00113         /* CMU/Monarch's extnsions */
00114         PT_ARP,
00115         PT_MAC,
00116         PT_TORA,
00117         PT_DSR,
00118         PT_AODV,
00119         PT_IMEP,
00120 
00121         // RAP packets
00122         PT_RAP_DATA,
00123         PT_RAP_ACK,
00124 
00125         PT_TFRC,
00126         PT_TFRC_ACK,
00127         PT_PING,
00128 
00129         // Diffusion packets - Chalermek
00130         PT_DIFF,
00131 
00132         // LinkState routing update packets
00133         PT_RTPROTO_LS,
00134 
00135         // MPLS LDP header
00136         PT_LDP,
00137 
00138         // GAF packet
00139         PT_GAF,  
00140 
00141         // ReadAudio traffic
00142         PT_REALAUDIO,
00143 
00144         // Pushback Messages
00145         PT_PUSHBACK,
00146 
00147 #ifdef HAVE_STL
00148         // Pragmatic General Multicast
00149         PT_PGM,
00150 #endif //STL
00151 
00152         // LMS packets
00153         PT_LMS,
00154         PT_LMS_SETUP,
00155 
00156         // insert new packet types here
00157         PT_NTYPE // This MUST be the LAST one
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                 /* For diffusion : Chalermek */
00214                 name_[PT_DIFF] = "diffusion";
00215 
00216                 // Link state routing updates
00217                 name_[PT_RTPROTO_LS] = "rtProtoLS";
00218 
00219                 // MPLS LDP packets
00220                 name_[PT_LDP] = "LDP";
00221 
00222                 // for GAF
00223                 name_[PT_GAF] = "gaf";      
00224 
00225                 // RealAudio packets
00226                 name_[PT_REALAUDIO] = "ra";
00227 
00228                 //pushback 
00229                 name_[PT_PUSHBACK] = "pushback";
00230 
00231 #ifdef HAVE_STL
00232                 // for PGM
00233                 name_[PT_PGM] = "PGM";
00234 #endif //STL
00235 
00236                 // LMS entries
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; /* map PT_* to string name */
00259 //extern char* p_info::name_[];
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 //Monarch ext
00304 typedef void (*FailureCallback)(Packet *,void *);
00305 
00306 class Packet : public Event {
00307 private:
00308         unsigned char* bits_;   // header bits
00309 //      unsigned char* data_;   // variable size buffer for 'data'
00310 //      unsigned int datalen_;  // length of variable size buffer
00311         AppData* data_;         // variable size buffer for 'data'
00312         static void init(Packet*);     // initialize pkt hdr 
00313         bool fflag_;
00314 protected:
00315         static Packet* free_;   // packet free list
00316         int     ref_count_;     // free the pkt until count to 0
00317 public:
00318         Packet* next_;          // for queues and the free list
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         // dirty hack for diffusion data
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         // This is used for backward compatibility, i.e., assuming user data
00338         // is PacketData and return its pointer.
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         // This is used to access application-specific data, not limited 
00346         // to PacketData.
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         // Monarch extn
00358 
00359         static void dump_header(Packet *p, int offset, int length);
00360 
00361         // the pkt stamp carries all info about how/where the pkt
00362         // was sent needed for a receiver to determine if it correctly
00363         // receives the pkt
00364         PacketStamp     txinfo_;  
00365 
00366         /*
00367          * According to cmu code:
00368          * This flag is set by the MAC layer on an incoming packet
00369          * and is cleared by the link layer.  It is an ugly hack, but
00370          * there's really no other way because NS always calls
00371          * the recv() function of an object.
00372          * 
00373          */
00374         u_int8_t        incoming;
00375 
00376         //monarch extns end;
00377 };
00378 
00379 /* 
00380  * static constant associations between interface special (negative) 
00381  * values and their c-string representations that are used from tcl
00382  */
00383 class iface_literal {
00384 public:
00385         enum iface_constant { 
00386                 UNKN_IFACE= -1, /* 
00387                                  * iface value for locally originated packets 
00388                                  */
00389                 ANY_IFACE= -2   /* 
00390                                  * hashnode with iif == ANY_IFACE_   
00391                                  * matches any pkt iface (imported from TCL);
00392                                  * this value should be different from 
00393                                  * hdr_cmn::UNKN_IFACE (packet.h)
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         /* strings used in TCL to access those special values */
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  * Note that NS_AF_* doesn't necessarily correspond with
00411  * the constants used in your system (because many
00412  * systems don't have NONE or ILINK).
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_;        // packet type (see above)
00419         int     size_;          // simulated packet size
00420         int     uid_;           // unique id
00421         int     error_;         // error flag
00422         int     errbitcnt_;     // # of corrupted bits jahn
00423         int     fecsize_;
00424         double  ts_;            // timestamp: for q-delay measurement
00425         int     iface_;         // receiving interface (label)
00426         dir_t   direction_;     // direction: 0=none, 1=up, -1=down
00427         // source routing 
00428         char src_rt_valid;
00429         double ts_arr_; // Required by Marker of JOBS 
00430 
00431         //Monarch extn begins
00432         nsaddr_t prev_hop_;     // IP addr of forwarding hop
00433         nsaddr_t next_hop_;     // next hop for this packet
00434         int      addr_type_;    // type of next_hop_ addr
00435         nsaddr_t last_hop_;     // for tracing on multi-user channels
00436 
00437         // called if pkt can't obtain media or isn't ack'd. not called if
00438         // droped by a queue
00439         FailureCallback xmit_failure_; 
00440         void *xmit_failure_data_;
00441 
00442         /*
00443          * MONARCH wants to know if the MAC layer is passing this back because
00444          * it could not get the RTS through or because it did not receive
00445          * an ACK.
00446          */
00447         int     xmit_reason_;
00448 #define XMIT_REASON_RTS 0x01
00449 #define XMIT_REASON_ACK 0x02
00450 
00451         // filled in by GOD on first transmission, used for trace analysis
00452         int num_forwards_;      // how many times this pkt was forwarded
00453         int opt_num_forwards_;   // optimal #forwards
00454         // Monarch extn ends;
00455 
00456         // tx time for this packet in sec
00457         double txtime_;
00458         inline double& txtime() { return(txtime_); }
00459 
00460         static int offset_;     // offset for this header
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         /* per-field member functions */
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         // monarch_begin
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         //monarch_end
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_;            // # of bytes for this header
00493         int* offset_;           // offset for this header
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); // Initialize bits_[]
00522         (HDR_CMN(p))->next_hop_ = -2; // -1 reserved for IP_BROADCAST
00523         (HDR_CMN(p))->last_hop_ = -2; // -1 reserved for IP_BROADCAST
00524         p->fflag_ = TRUE;
00525         (HDR_CMN(p))->direction() = hdr_cmn::DOWN;
00526         /* setting all direction of pkts to be downward as default; 
00527            until channel changes it to +1 (upward) */
00528         p->next_ = 0;
00529         return (p);
00530 }
00531 
00532 /* 
00533  * Allocate an n byte data buffer to an existing packet 
00534  * 
00535  * To set application-specific AppData, use Packet::setdata()
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 /* allocate a packet with an n byte data buffer */
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                          * A packet's uid may be < 0 (out of a event queue), or
00561                          * == 0 (newed but never gets into the event queue.
00562                          */
00563                         assert(p->uid_ <= 0);
00564                         // Delete user data because we won't need it any more.
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

Generated on Tue Apr 20 12:14:26 2004 for NS2.26SourcesOriginal by doxygen 1.3.3