• Main Page
  • Classes
  • Files
  • File List

/Users/yzchen/ns/ns-allinone-2.33/ns-2.33/common/packet.h

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: /cvsroot/nsnam/ns-2/common/packet.h,v 1.102 2008/02/18 03:39:02 tom_henderson 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_HDLC(p)     ((hdr_hdlc *)hdr_ll::access(p))
00061 #define HDR_IP(p)       (hdr_ip::access(p))
00062 #define HDR_RTP(p)      (hdr_rtp::access(p))
00063 #define HDR_TCP(p)      (hdr_tcp::access(p))
00064 #define HDR_SCTP(p)     (hdr_sctp::access(p))
00065 #define HDR_SR(p)       (hdr_sr::access(p))
00066 #define HDR_TFRC(p)     (hdr_tfrc::access(p))
00067 #define HDR_TORA(p)     (hdr_tora::access(p))
00068 #define HDR_IMEP(p)     (hdr_imep::access(p))
00069 #define HDR_CDIFF(p)    (hdr_cdiff::access(p))  /* chalermak's diffusion*/
00070 //#define HDR_DIFF(p)     (hdr_diff::access(p))  /* SCADD's diffusion ported into ns */
00071 #define HDR_LMS(p)              (hdr_lms::access(p))
00072 
00073 /* --------------------------------------------------------------------*/
00074 
00075 /*
00076  * modified ns-2.33, adding support for dynamic libraries
00077  *
00078  * packet_t is changed from enum to unsigned int in order to allow
00079  * dynamic definition of  new packet types within dynamic libraries.
00080  * Pre-defined packet types are implemented as static const.
00081  *
00082  */
00083 
00084 typedef unsigned int packet_t;
00085 
00086 static const packet_t PT_TCP = 0;
00087 static const packet_t PT_UDP = 1;
00088 static const packet_t PT_CBR = 2;
00089 static const packet_t PT_AUDIO = 3;
00090 static const packet_t PT_VIDEO = 4;
00091 static const packet_t PT_ACK = 5;
00092 static const packet_t PT_START = 6;
00093 static const packet_t PT_STOP = 7;
00094 static const packet_t PT_PRUNE = 8;
00095 static const packet_t PT_GRAFT = 9;
00096 static const packet_t PT_GRAFTACK = 10;
00097 static const packet_t PT_JOIN = 11;
00098 static const packet_t PT_ASSERT = 12;
00099 static const packet_t PT_MESSAGE = 13;
00100 static const packet_t PT_RTCP = 14;
00101 static const packet_t PT_RTP = 15;
00102 static const packet_t PT_RTPROTO_DV = 16;
00103 static const packet_t PT_CtrMcast_Encap = 17;
00104 static const packet_t PT_CtrMcast_Decap = 18;
00105 static const packet_t PT_SRM = 19;
00106         /* simple signalling messages */
00107 static const packet_t PT_REQUEST = 20;
00108 static const packet_t PT_ACCEPT = 21;
00109 static const packet_t PT_CONFIRM = 22;
00110 static const packet_t PT_TEARDOWN = 23;
00111 static const packet_t PT_LIVE = 24;   // packet from live network
00112 static const packet_t PT_REJECT = 25;
00113 
00114 static const packet_t PT_TELNET = 26; // not needed: telnet use TCP
00115 static const packet_t PT_FTP = 27;
00116 static const packet_t PT_PARETO = 28;
00117 static const packet_t PT_EXP = 29;
00118 static const packet_t PT_INVAL = 30;
00119 static const packet_t PT_HTTP = 31;
00120 
00121         /* new encapsulator */
00122 static const packet_t PT_ENCAPSULATED = 32;
00123 static const packet_t PT_MFTP = 33;
00124 
00125         /* CMU/Monarch's extnsions */
00126 static const packet_t PT_ARP = 34;
00127 static const packet_t PT_MAC = 35;
00128 static const packet_t PT_TORA = 36;
00129 static const packet_t PT_DSR = 37;
00130 static const packet_t PT_AODV = 38;
00131 static const packet_t PT_IMEP = 39;
00132 
00133         // RAP packets
00134 static const packet_t PT_RAP_DATA = 40;
00135 static const packet_t PT_RAP_ACK = 41;
00136 
00137 static const packet_t PT_TFRC = 42;
00138 static const packet_t PT_TFRC_ACK = 43;
00139 static const packet_t PT_PING = 44;
00140 
00141 static const packet_t PT_PBC = 45;
00142         // Diffusion packets - Chalermek
00143 static const packet_t PT_DIFF = 46;
00144 
00145         // LinkState routing update packets
00146 static const packet_t PT_RTPROTO_LS = 47;
00147 
00148         // MPLS LDP header
00149 static const packet_t PT_LDP = 48;
00150 
00151         // GAF packet
00152 static const packet_t PT_GAF = 49;
00153 
00154         // ReadAudio traffic
00155 static const packet_t PT_REALAUDIO = 50;
00156 
00157         // Pushback Messages
00158 static const packet_t PT_PUSHBACK = 51;
00159 
00160 #ifdef HAVE_STL
00161         // Pragmatic General Multicast
00162 static const packet_t PT_PGM = 52;
00163 #endif //STL
00164         // LMS packets
00165 static const packet_t PT_LMS = 53;
00166 static const packet_t PT_LMS_SETUP = 54;
00167 
00168 static const packet_t PT_SCTP = 55;
00169 static const packet_t PT_SCTP_APP1 = 56;
00170 
00171         // SMAC packet
00172 static const packet_t PT_SMAC = 57;
00173         // XCP packet
00174 static const packet_t PT_XCP = 58;
00175 
00176         // HDLC packet
00177 static const packet_t PT_HDLC = 59;
00178 
00179         // Bell Labs Traffic Trace Type (PackMime OL)
00180 static const packet_t PT_BLTRACE = 60;
00181 
00182         // UM-OLSR packet type
00183                 // added manually - YPC 20090228
00184 static const packet_t PT_OLSR = 61;
00185 
00186                 // CDSWL packet
00187                 // added by YPC 20090719
00188 static const packet_t PT_CDSWL = 62;
00189 
00190                 // MM app from "NS by Example
00191 static const packet_t PT_Multimedia = 63;
00192 
00193         // insert new packet types here
00194 static packet_t       PT_NTYPE = 64; // This MUST be the LAST one
00195 
00196 enum packetClass
00197 {
00198         UNCLASSIFIED,
00199         ROUTING,
00200         DATApkt
00201 };
00202 
00203 
00204 /*
00205  * ns-2.33 adding support for dynamic libraries
00206  *
00207  * The PacketClassifier class is needed to make
00208  * p_info::data_packet(packet_t) work also with dynamically defined
00209  * packet types.
00210  *
00211  */
00212 class PacketClassifier
00213 {
00214         public:
00215                 PacketClassifier(): next_(0){}
00216                 virtual ~PacketClassifier() {}
00217                 void setNext(PacketClassifier *next){next_ = next;}
00218                 PacketClassifier *getNext(){return next_;}
00219                 packetClass classify(packet_t type)
00220                 {
00221                         packetClass c = getClass(type);
00222                         if(c == UNCLASSIFIED && next_)
00223                                 c = next_->classify(type);
00224                         return c;
00225                 }
00226 
00227         protected:
00228                 //return 0 if the packet is unknown
00229                 virtual packetClass getClass(packet_t type) = 0;
00230                 PacketClassifier *next_;
00231 };
00232 
00233 
00234 class p_info {
00235 public:
00236         p_info()
00237         {
00238                 initName();
00239         }
00240 
00241         const char* name(packet_t p) const {
00242                 if ( p <= p_info::nPkt_ ) return name_[p];
00243                 return 0;
00244         }
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                          (type) == PT_SCTP || \
00254                          (type) == PT_SCTP_APP1 || \
00255                          (type) == PT_HDLC \
00256                         );
00257         }
00258 
00259         static packetClass classify(packet_t type) {
00260                 if (type == PT_DSR ||
00261                     type == PT_MESSAGE ||
00262                     type == PT_TORA ||
00263                     type == PT_OLSR ||
00264                     type == PT_CDSWL ||
00265                     type == PT_AODV)
00266                         return ROUTING;
00267                 if (type == PT_TCP ||
00268                     type == PT_TELNET ||
00269                     type == PT_CBR ||
00270                     type == PT_AUDIO ||
00271                     type == PT_VIDEO ||
00272                     type == PT_ACK ||
00273                     type == PT_SCTP ||
00274                     type == PT_SCTP_APP1 ||
00275                     type == PT_HDLC)
00276                         return DATApkt;
00277                 if (pc_)
00278                         return pc_->classify(type);
00279                 return UNCLASSIFIED;
00280         }
00281 
00282         static void addPacketClassifier(PacketClassifier *pc)
00283         {
00284                 if(!pc)
00285                         return;
00286                 pc->setNext(pc_);
00287                 pc_ = pc;
00288         }
00289 
00290         static void initName()
00291         {
00292                 if (nPkt_ >= PT_NTYPE+1)
00293                         return;
00294                 char **nameNew = new char*[PT_NTYPE+1];
00295                 for(unsigned int i = (unsigned int)PT_SMAC+1; i < nPkt_; i++)
00296                 {
00297                         nameNew[i] = name_[i];
00298                 }
00299                 if (!nPkt_)
00300                         delete [] name_;
00301 
00302                 name_ = nameNew;
00303                 nPkt_ = PT_NTYPE+1;
00304 
00305                 name_[PT_TCP]= "tcp";
00306                 name_[PT_UDP]= "udp";
00307                 name_[PT_CBR]= "cbr";
00308                 name_[PT_AUDIO]= "audio";
00309                 name_[PT_VIDEO]= "video";
00310                 name_[PT_ACK]= "ack";
00311                 name_[PT_START]= "start";
00312                 name_[PT_STOP]= "stop";
00313                 name_[PT_PRUNE]= "prune";
00314                 name_[PT_GRAFT]= "graft";
00315                 name_[PT_GRAFTACK]= "graftAck";
00316                 name_[PT_JOIN]= "join";
00317                 name_[PT_ASSERT]= "assert";
00318                 name_[PT_MESSAGE]= "message";
00319                 name_[PT_RTCP]= "rtcp";
00320                 name_[PT_RTP]= "rtp";
00321                 name_[PT_RTPROTO_DV]= "rtProtoDV";
00322                 name_[PT_CtrMcast_Encap]= "CtrMcast_Encap";
00323                 name_[PT_CtrMcast_Decap]= "CtrMcast_Decap";
00324                 name_[PT_SRM]= "SRM";
00325                 name_[PT_REQUEST]= "sa_req";
00326                 name_[PT_ACCEPT]= "sa_accept";
00327                 name_[PT_CONFIRM]= "sa_conf";
00328                 name_[PT_TEARDOWN]= "sa_teardown";
00329                 name_[PT_LIVE]= "live";
00330                 name_[PT_REJECT]= "sa_reject";
00331                 name_[PT_TELNET]= "telnet";
00332                 name_[PT_FTP]= "ftp";
00333                 name_[PT_PARETO]= "pareto";
00334                 name_[PT_EXP]= "exp";
00335                 name_[PT_INVAL]= "httpInval";
00336                 name_[PT_HTTP]= "http";
00337                 name_[PT_ENCAPSULATED]= "encap";
00338                 name_[PT_MFTP]= "mftp";
00339                 name_[PT_ARP]= "ARP";
00340                 name_[PT_MAC]= "MAC";
00341                 name_[PT_TORA]= "TORA";
00342                 name_[PT_DSR]= "DSR";
00343                 name_[PT_AODV]= "AODV";
00344                 name_[PT_IMEP]= "IMEP";
00345                 name_[PT_RAP_DATA] = "rap_data";
00346                 name_[PT_RAP_ACK] = "rap_ack";
00347                 name_[PT_TFRC]= "tcpFriend";
00348                 name_[PT_TFRC_ACK]= "tcpFriendCtl";
00349                 name_[PT_PING]="ping";
00350                 name_[PT_PBC] = "PBC";
00351                 /* For diffusion : Chalermek */
00352                 name_[PT_DIFF] = "diffusion";
00353                 // Link state routing updates
00354                 name_[PT_RTPROTO_LS] = "rtProtoLS";
00355                 // MPLS LDP packets
00356                 name_[PT_LDP] = "LDP";
00357                 // for GAF
00358                 name_[PT_GAF] = "gaf";
00359                 // RealAudio packets
00360                 name_[PT_REALAUDIO] = "ra";
00361                 //pushback
00362                 name_[PT_PUSHBACK] = "pushback";
00363 #ifdef HAVE_STL
00364                 // for PGM
00365                 name_[PT_PGM] = "PGM";
00366 #endif //STL
00367                 // LMS entries
00368                 name_[PT_LMS]="LMS";
00369                 name_[PT_LMS_SETUP]="LMS_SETUP";
00370                 name_[PT_SCTP]= "sctp";
00371                 name_[PT_SCTP_APP1] = "sctp_app1";
00372                 // smac
00373                 name_[PT_SMAC]="smac";
00374                 // HDLC
00375                 name_[PT_HDLC]="HDLC";
00376                 // XCP
00377                 name_[PT_XCP]="xcp";
00378                 // Bell Labs (PackMime OL)
00379                 name_[PT_BLTRACE]="BellLabsTrace";
00380                 // UM-OLSR
00381                 name_[PT_OLSR]= "OLSR";
00382                 // MUN-CDSWL
00383                 name_[PT_CDSWL] = "CDSWL";
00384                 name_[PT_Multimedia] = "Multimedia";
00385                 name_[PT_NTYPE]= "undefined";
00386         }
00387 
00388         static int addPacket(char *name);
00389 
00390         static packet_t getType(const char *name)
00391         {
00392                 for(unsigned int i = 0; i < nPkt_; i++)
00393                 {
00394                         if(strcmp(name, name_[i]) == 0)
00395                                 return i;
00396                 }
00397                 return PT_NTYPE;
00398         }
00399 
00400 private:
00401         static char** name_;
00402         static unsigned int nPkt_;
00403         static PacketClassifier *pc_;
00404 };
00405 
00406 extern p_info packet_info; /* map PT_* to string name */
00407 //extern char* p_info::name_[];
00408 
00409 #define DATA_PACKET(type) ( (type) == PT_TCP || \
00410                             (type) == PT_TELNET || \
00411                             (type) == PT_CBR || \
00412                             (type) == PT_AUDIO || \
00413                             (type) == PT_VIDEO || \
00414                             (type) == PT_ACK || \
00415                             (type) == PT_SCTP || \
00416                             (type) == PT_SCTP_APP1 \
00417                             )
00418 
00419 //#define OFFSET(type, field)   ((long) &((type *)0)->field)
00420 #define OFFSET(type, field) ( (char *)&( ((type *)256)->field )  - (char *)256)
00421 
00422 class PacketData : public AppData {
00423 public:
00424         PacketData(int sz) : AppData(PACKET_DATA) {
00425                 datalen_ = sz;
00426                 if (datalen_ > 0)
00427                         data_ = new unsigned char[datalen_];
00428                 else
00429                         data_ = NULL;
00430         }
00431         PacketData(PacketData& d) : AppData(d) {
00432                 datalen_ = d.datalen_;
00433                 if (datalen_ > 0) {
00434                         data_ = new unsigned char[datalen_];
00435                         memcpy(data_, d.data_, datalen_);
00436                 } else
00437                         data_ = NULL;
00438         }
00439         virtual ~PacketData() {
00440                 if (data_ != NULL)
00441                         delete []data_;
00442         }
00443         unsigned char* data() { return data_; }
00444 
00445         virtual int size() const { return datalen_; }
00446         virtual AppData* copy() { return new PacketData(*this); }
00447 private:
00448         unsigned char* data_;
00449         int datalen_;
00450 };
00451 
00452 //Monarch ext
00453 typedef void (*FailureCallback)(Packet *,void *);
00454 
00455 class Packet : public Event {
00456 private:
00457         unsigned char* bits_;   // header bits
00458 //      unsigned char* data_;   // variable size buffer for 'data'
00459 //      unsigned int datalen_;  // length of variable size buffer
00460         AppData* data_;         // variable size buffer for 'data'
00461         static void init(Packet*);     // initialize pkt hdr
00462         bool fflag_;
00463 protected:
00464         static Packet* free_;   // packet free list
00465         int     ref_count_;     // free the pkt until count to 0
00466 public:
00467         Packet* next_;          // for queues and the free list
00468         static int hdrlen_;
00469 
00470         Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }
00471         inline unsigned char* const bits() { return (bits_); }
00472         inline Packet* copy() const;
00473         inline Packet* refcopy() { ++ref_count_; return this; }
00474         inline int& ref_count() { return (ref_count_); }
00475         static inline Packet* alloc();
00476         static inline Packet* alloc(int);
00477         inline void allocdata(int);
00478         // dirty hack for diffusion data
00479         inline void initdata() { data_  = 0;}
00480         static inline void free(Packet*);
00481         inline unsigned char* access(int off) const {
00482                 if (off < 0)
00483                         abort();
00484                 return (&bits_[off]);
00485         }
00486         // This is used for backward compatibility, i.e., assuming user data
00487         // is PacketData and return its pointer.
00488         inline unsigned char* accessdata() const {
00489                 if (data_ == 0)
00490                         return 0;
00491                 assert(data_->type() == PACKET_DATA);
00492                 return (((PacketData*)data_)->data());
00493         }
00494         // This is used to access application-specific data, not limited
00495         // to PacketData.
00496         inline AppData* userdata() const {
00497                 return data_;
00498         }
00499         inline void setdata(AppData* d) {
00500                 if (data_ != NULL)
00501                         delete data_;
00502                 data_ = d;
00503         }
00504         inline int datalen() const { return data_ ? data_->size() : 0; }
00505 
00506         // Monarch extn
00507 
00508         static void dump_header(Packet *p, int offset, int length);
00509 
00510         // the pkt stamp carries all info about how/where the pkt
00511         // was sent needed for a receiver to determine if it correctly
00512         // receives the pkt
00513         PacketStamp     txinfo_;
00514 
00515         /*
00516          * According to cmu code:
00517          * This flag is set by the MAC layer on an incoming packet
00518          * and is cleared by the link layer.  It is an ugly hack, but
00519          * there's really no other way because NS always calls
00520          * the recv() function of an object.
00521          *
00522          */
00523         u_int8_t        incoming;
00524 
00525         //monarch extns end;
00526 };
00527 
00528 /*
00529  * static constant associations between interface special (negative)
00530  * values and their c-string representations that are used from tcl
00531  */
00532 class iface_literal {
00533 public:
00534         enum iface_constant {
00535                 UNKN_IFACE= -1, /*
00536                                  * iface value for locally originated packets
00537                                  */
00538                 ANY_IFACE= -2   /*
00539                                  * hashnode with iif == ANY_IFACE_
00540                                  * matches any pkt iface (imported from TCL);
00541                                  * this value should be different from
00542                                  * hdr_cmn::UNKN_IFACE (packet.h)
00543                                  */
00544         };
00545         iface_literal(const iface_constant i, const char * const n) :
00546                 value_(i), name_(n) {}
00547         inline int value() const { return value_; }
00548         inline const char * const name() const { return name_; }
00549 private:
00550         const iface_constant value_;
00551         /* strings used in TCL to access those special values */
00552         const char * const name_;
00553 };
00554 
00555 static const iface_literal UNKN_IFACE(iface_literal::UNKN_IFACE, "?");
00556 static const iface_literal ANY_IFACE(iface_literal::ANY_IFACE, "*");
00557 
00558 /*
00559  * Note that NS_AF_* doesn't necessarily correspond with
00560  * the constants used in your system (because many
00561  * systems don't have NONE or ILINK).
00562  */
00563 enum ns_af_enum { NS_AF_NONE, NS_AF_ILINK, NS_AF_INET };
00564 
00565 enum ModulationScheme {BPSK = 0, QPSK = 1, QAM16 = 2, QAM64 = 3};
00566 
00567 struct hdr_cmn {
00568         enum dir_t { DOWN= -1, NONE= 0, UP= 1 };
00569         packet_t ptype_;        // packet type (see above)
00570         int             size_;          // simulated packet size
00571         int             uid_;           // unique id
00572         int             error_;         // error flag
00573         int     errbitcnt_;     // # of corrupted bits jahn
00574         int     fecsize_;
00575         double  ts_;            // timestamp: for q-delay measurement
00576         int             iface_;         // receiving interface (label)
00577         dir_t   direction_;     // direction: 0=none, 1=up, -1=down
00578         // source routing
00579         char    src_rt_valid;
00580         double  ts_arr_; // Required by Marker of JOBS
00581 
00582         //Monarch extn begins
00583         nsaddr_t prev_hop_;     // IP addr of forwarding hop
00584         nsaddr_t next_hop_;             // next hop for this packet
00585         int      addr_type_;    // type of next_hop_ addr
00586         nsaddr_t last_hop_;     // for tracing on multi-user channels
00587 
00588         // called if pkt can't obtain media or isn't ack'd. not called if
00589         // dropped by a queue
00590         FailureCallback xmit_failure_;
00591         void *xmit_failure_data_;
00592 
00593         /*
00594          * MONARCH wants to know if the MAC layer is passing this back because
00595          * it could not get the RTS through or because it did not receive
00596          * an ACK.
00597          */
00598         int     xmit_reason_;
00599         #define XMIT_REASON_RTS 0x01
00600         #define XMIT_REASON_ACK 0x02
00601 
00602         // filled in by GOD on first transmission, used for trace analysis
00603         int num_forwards_;              // how many times this pkt was forwarded
00604         int opt_num_forwards_;  // optimal #forwards
00605         // Monarch extn ends;
00606 
00607         // tx time for this packet in sec
00608         double txtime_;
00609         inline double& txtime() { return(txtime_); }
00610 
00611         static int offset_;     // offset for this header
00612         inline static int& offset() { return offset_; }
00613         inline static hdr_cmn* access(const Packet* p) {
00614                 return (hdr_cmn*) p->access(offset_);
00615         }
00616 
00617         /* per-field member functions */
00618         inline packet_t& ptype() { return (ptype_); }
00619         inline int& size() { return (size_); }
00620         inline int& uid() { return (uid_); }
00621         inline int& error() { return error_; }
00622         inline int& errbitcnt() {return errbitcnt_; }
00623         inline int& fecsize() {return fecsize_; }
00624         inline double& timestamp() { return (ts_); }
00625         inline int& iface() { return (iface_); }
00626         inline dir_t& direction() { return (direction_); }
00627         // monarch_begin
00628         inline nsaddr_t& next_hop() { return (next_hop_); }
00629         inline int& addr_type() { return (addr_type_); }
00630         inline int& num_forwards() { return (num_forwards_); }
00631         inline int& opt_num_forwards() { return (opt_num_forwards_); }
00632         //monarch_end
00633 
00634         ModulationScheme mod_scheme_;
00635         inline ModulationScheme& mod_scheme() { return (mod_scheme_); }
00636 };
00637 
00638 
00639 class PacketHeaderClass : public TclClass {
00640 protected:
00641         PacketHeaderClass(const char* classname, int hdrsize);
00642         virtual int method(int argc, const char*const* argv);
00643         void field_offset(const char* fieldname, int offset);
00644         inline void bind_offset(int* off) { offset_ = off; }
00645         inline void offset(int* off) {offset_= off;}
00646         int hdrlen_;            // # of bytes for this header
00647         int* offset_;           // offset for this header
00648 public:
00649         virtual void bind();
00650         virtual void export_offsets();
00651         TclObject* create(int argc, const char*const* argv);
00652 };
00653 
00654 
00655 inline void Packet::init(Packet* p)
00656 {
00657         bzero(p->bits_, hdrlen_);
00658 }
00659 
00660 inline Packet* Packet::alloc()
00661 {
00662         Packet* p = free_;
00663         if (p != 0) {
00664                 assert(p->fflag_ == FALSE);
00665                 free_ = p->next_;
00666                 assert(p->data_ == 0);
00667                 p->uid_ = 0;
00668                 p->time_ = 0;
00669         } else {
00670                 p = new Packet;
00671                 p->bits_ = new unsigned char[hdrlen_];
00672                 if (p == 0 || p->bits_ == 0)
00673                         abort();
00674         }
00675         init(p); // Initialize bits_[]
00676         (HDR_CMN(p))->next_hop_ = -2; // -1 reserved for IP_BROADCAST
00677         (HDR_CMN(p))->last_hop_ = -2; // -1 reserved for IP_BROADCAST
00678         p->fflag_ = TRUE;
00679         (HDR_CMN(p))->direction() = hdr_cmn::DOWN;
00680         /* setting all direction of pkts to be downward as default;
00681            until channel changes it to +1 (upward) */
00682         p->next_ = 0;
00683         return (p);
00684 }
00685 
00686 /*
00687  * Allocate an n byte data buffer to an existing packet
00688  *
00689  * To set application-specific AppData, use Packet::setdata()
00690  */
00691 inline void Packet::allocdata(int n)
00692 {
00693         assert(data_ == 0);
00694         data_ = new PacketData(n);
00695         if (data_ == 0)
00696                 abort();
00697 }
00698 
00699 /* allocate a packet with an n byte data buffer */
00700 inline Packet* Packet::alloc(int n)
00701 {
00702         Packet* p = alloc();
00703         if (n > 0)
00704                 p->allocdata(n);
00705         return (p);
00706 }
00707 
00708 
00709 inline void Packet::free(Packet* p)
00710 {
00711         if (p->fflag_) {
00712                 if (p->ref_count_ == 0) {
00713                         /*
00714                          * A packet's uid may be < 0 (out of a event queue), or
00715                          * == 0 (newed but never gets into the event queue.
00716                          */
00717                         assert(p->uid_ <= 0);
00718                         // Delete user data because we won't need it any more.
00719                         if (p->data_ != 0) {
00720                                 delete p->data_;
00721                                 p->data_ = 0;
00722                         }
00723                         init(p);
00724                         p->next_ = free_;
00725                         free_ = p;
00726                         p->fflag_ = FALSE;
00727                 } else {
00728                         --p->ref_count_;
00729                 }
00730         }
00731 }
00732 
00733 inline Packet* Packet::copy() const
00734 {
00735 
00736         Packet* p = alloc();
00737         memcpy(p->bits(), bits_, hdrlen_);
00738         if (data_)
00739                 p->data_ = data_->copy();
00740         p->txinfo_.init(&txinfo_);
00741 
00742         return (p);
00743 }
00744 
00745 inline void
00746 Packet::dump_header(Packet *p, int offset, int length)
00747 {
00748         assert(offset + length <= p->hdrlen_);
00749         struct hdr_cmn *ch = HDR_CMN(p);
00750 
00751         fprintf(stderr, "\nPacket ID: %d\n", ch->uid());
00752 
00753         for(int i = 0; i < length ; i+=16) {
00754                 fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
00755                         p->bits_[offset + i],     p->bits_[offset + i + 1],
00756                         p->bits_[offset + i + 2], p->bits_[offset + i + 3],
00757                         p->bits_[offset + i + 4], p->bits_[offset + i + 5],
00758                         p->bits_[offset + i + 6], p->bits_[offset + i + 7],
00759                         p->bits_[offset + i + 8], p->bits_[offset + i + 9],
00760                         p->bits_[offset + i + 10], p->bits_[offset + i + 11],
00761                         p->bits_[offset + i + 12], p->bits_[offset + i + 13],
00762                         p->bits_[offset + i + 14], p->bits_[offset + i + 15]);
00763         }
00764 }
00765 
00766 #endif

Generated on Tue Aug 10 2010 16:16:06 for ns-2.33 by  doxygen 1.7.1