packet.h
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:22k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Computer Systems
  17.  * Engineering Group at Lawrence Berkeley Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  * @(#) $Header: /cvsroot/nsnam/ns-2/common/packet.h,v 1.102 2008/02/18 03:39:02 tom_henderson Exp $ (LBL)
  35.  */
  36. #ifndef ns_packet_h
  37. #define ns_packet_h
  38. #include <string.h>
  39. #include <assert.h>
  40. #include "config.h"
  41. #include "scheduler.h"
  42. #include "object.h"
  43. #include "lib/bsd-list.h"
  44. #include "packet-stamp.h"
  45. #include "ns-process.h"
  46. // Used by wireless routing code to attach routing agent
  47. #define RT_PORT 255 /* port that all route msgs are sent to */
  48. #define HDR_CMN(p)      (hdr_cmn::access(p))
  49. #define HDR_ARP(p)      (hdr_arp::access(p))
  50. #define HDR_MAC(p)      (hdr_mac::access(p))
  51. #define HDR_MAC802_11(p) ((hdr_mac802_11 *)hdr_mac::access(p))
  52. #define HDR_MAC_TDMA(p) ((hdr_mac_tdma *)hdr_mac::access(p))
  53. #define HDR_SMAC(p)     ((hdr_smac *)hdr_mac::access(p))
  54. #define HDR_LL(p)       (hdr_ll::access(p))
  55. #define HDR_HDLC(p)     ((hdr_hdlc *)hdr_ll::access(p))
  56. #define HDR_IP(p)       (hdr_ip::access(p))
  57. #define HDR_RTP(p)      (hdr_rtp::access(p))
  58. #define HDR_TCP(p)      (hdr_tcp::access(p))
  59. #define HDR_SCTP(p)     (hdr_sctp::access(p))
  60. #define HDR_SR(p)       (hdr_sr::access(p))
  61. #define HDR_TFRC(p)     (hdr_tfrc::access(p))
  62. #define HDR_TORA(p)     (hdr_tora::access(p))
  63. #define HDR_IMEP(p)     (hdr_imep::access(p))
  64. #define HDR_CDIFF(p)    (hdr_cdiff::access(p))  /* chalermak's diffusion*/
  65. //#define HDR_DIFF(p)     (hdr_diff::access(p))  /* SCADD's diffusion ported into ns */
  66. #define HDR_LMS(p) (hdr_lms::access(p))
  67. /* --------------------------------------------------------------------*/
  68. /*
  69.  * modified ns-2.33, adding support for dynamic libraries
  70.  * 
  71.  * packet_t is changed from enum to unsigned int in order to allow
  72.  * dynamic definition of  new packet types within dynamic libraries.
  73.  * Pre-defined packet types are implemented as static const.
  74.  * 
  75.  */
  76. typedef unsigned int packet_t;
  77. static const packet_t PT_TCP = 0;
  78. static const packet_t PT_UDP = 1;
  79. static const packet_t PT_CBR = 2;
  80. static const packet_t PT_AUDIO = 3;
  81. static const packet_t PT_VIDEO = 4;
  82. static const packet_t PT_ACK = 5;
  83. static const packet_t PT_START = 6;
  84. static const packet_t PT_STOP = 7;
  85. static const packet_t PT_PRUNE = 8;
  86. static const packet_t PT_GRAFT = 9;
  87. static const packet_t PT_GRAFTACK = 10;
  88. static const packet_t PT_JOIN = 11;
  89. static const packet_t PT_ASSERT = 12;
  90. static const packet_t PT_MESSAGE = 13;
  91. static const packet_t PT_RTCP = 14;
  92. static const packet_t PT_RTP = 15;
  93. static const packet_t PT_RTPROTO_DV = 16;
  94. static const packet_t PT_CtrMcast_Encap = 17;
  95. static const packet_t PT_CtrMcast_Decap = 18;
  96. static const packet_t PT_SRM = 19;
  97.         /* simple signalling messages */
  98. static const packet_t PT_REQUEST = 20;
  99. static const packet_t PT_ACCEPT = 21;
  100. static const packet_t PT_CONFIRM = 22;
  101. static const packet_t PT_TEARDOWN = 23;
  102. static const packet_t PT_LIVE = 24;   // packet from live network
  103. static const packet_t PT_REJECT = 25;
  104. static const packet_t PT_TELNET = 26; // not needed: telnet use TCP
  105. static const packet_t PT_FTP = 27;
  106. static const packet_t PT_PARETO = 28;
  107. static const packet_t PT_EXP = 29;
  108. static const packet_t PT_INVAL = 30;
  109. static const packet_t PT_HTTP = 31;
  110.         /* new encapsulator */
  111. static const packet_t PT_ENCAPSULATED = 32;
  112. static const packet_t PT_MFTP = 33;
  113.         /* CMU/Monarch's extnsions */
  114. static const packet_t PT_ARP = 34;
  115. static const packet_t PT_MAC = 35;
  116. static const packet_t PT_TORA = 36;
  117. static const packet_t PT_DSR = 37;
  118. static const packet_t PT_AODV = 38;
  119. static const packet_t PT_IMEP = 39;
  120.         
  121.         // RAP packets
  122. static const packet_t PT_RAP_DATA = 40;
  123. static const packet_t PT_RAP_ACK = 41;
  124.   
  125. static const packet_t PT_TFRC = 42;
  126. static const packet_t PT_TFRC_ACK = 43;
  127. static const packet_t PT_PING = 44;
  128.         
  129. static const packet_t PT_PBC = 45;
  130.         // Diffusion packets - Chalermek
  131. static const packet_t PT_DIFF = 46;
  132.         
  133.         // LinkState routing update packets
  134. static const packet_t PT_RTPROTO_LS = 47;
  135.         
  136.         // MPLS LDP header
  137. static const packet_t PT_LDP = 48;
  138.         
  139.         // GAF packet
  140. static const packet_t PT_GAF = 49;
  141.         
  142.         // ReadAudio traffic
  143. static const packet_t PT_REALAUDIO = 50;
  144.         
  145.         // Pushback Messages
  146. static const packet_t PT_PUSHBACK = 51;
  147.   
  148.   #ifdef HAVE_STL
  149.         // Pragmatic General Multicast
  150. static const packet_t PT_PGM = 52;
  151.   #endif //STL
  152.         // LMS packets
  153. static const packet_t PT_LMS = 53;
  154. static const packet_t PT_LMS_SETUP = 54;
  155. static const packet_t PT_SCTP = 55;
  156. static const packet_t PT_SCTP_APP1 = 56;
  157.         // SMAC packet
  158. static const packet_t PT_SMAC = 57;
  159.         // XCP packet
  160. static const packet_t PT_XCP = 58;
  161.         // HDLC packet
  162. static const packet_t PT_HDLC = 59;
  163.         // Bell Labs Traffic Trace Type (PackMime OL)
  164. static const packet_t PT_BLTRACE = 60;
  165.         // insert new packet types here
  166. static packet_t       PT_NTYPE = 61; // This MUST be the LAST one
  167. enum packetClass
  168. {
  169. UNCLASSIFIED,
  170. ROUTING,
  171. DATApkt
  172.   };
  173. /*
  174.  * ns-2.33 adding support for dynamic libraries
  175.  * 
  176.  * The PacketClassifier class is needed to make
  177.  * p_info::data_packet(packet_t) work also with dynamically defined
  178.  * packet types.
  179.  * 
  180.  */
  181. class PacketClassifier
  182. {
  183. public:
  184. PacketClassifier(): next_(0){}
  185. virtual ~PacketClassifier() {}
  186. void setNext(PacketClassifier *next){next_ = next;}
  187. PacketClassifier *getNext(){return next_;}
  188. packetClass classify(packet_t type) 
  189. {
  190.         packetClass c = getClass(type);
  191.         if(c == UNCLASSIFIED && next_)
  192.                 c = next_->classify(type);
  193.         return c;
  194. }
  195. protected:
  196. //return 0 if the packet is unknown
  197. virtual packetClass getClass(packet_t type) = 0;        
  198. PacketClassifier *next_;
  199. };
  200. class p_info {
  201. public:
  202. p_info()
  203. {
  204. initName();
  205. }
  206. const char* name(packet_t p) const { 
  207. if ( p <= p_info::nPkt_ ) return name_[p];
  208. return 0;
  209. }
  210. static bool data_packet(packet_t type) {
  211. return ( (type) == PT_TCP || 
  212.          (type) == PT_TELNET || 
  213.          (type) == PT_CBR || 
  214.          (type) == PT_AUDIO || 
  215.          (type) == PT_VIDEO || 
  216.          (type) == PT_ACK || 
  217.          (type) == PT_SCTP || 
  218.          (type) == PT_SCTP_APP1 || 
  219.          (type) == PT_HDLC 
  220.         );
  221. }
  222. static packetClass classify(packet_t type) {
  223. if (type == PT_DSR || 
  224.     type == PT_MESSAGE || 
  225.     type == PT_TORA || 
  226.     type == PT_AODV)
  227. return ROUTING;
  228. if (type == PT_TCP || 
  229.     type == PT_TELNET || 
  230.     type == PT_CBR || 
  231.     type == PT_AUDIO || 
  232.     type == PT_VIDEO || 
  233.     type == PT_ACK || 
  234.     type == PT_SCTP || 
  235.     type == PT_SCTP_APP1 || 
  236.     type == PT_HDLC)
  237. return DATApkt;
  238. if (pc_)
  239. return pc_->classify(type);
  240. return UNCLASSIFIED;
  241. }
  242. static void addPacketClassifier(PacketClassifier *pc)
  243. {
  244. if(!pc)
  245.         return;
  246. pc->setNext(pc_);
  247. pc_ = pc;
  248. }       
  249. static void initName()
  250. {
  251. if(nPkt_ >= PT_NTYPE+1)
  252.         return;
  253. char **nameNew = new char*[PT_NTYPE+1];
  254. for(unsigned int i = (unsigned int)PT_SMAC+1; i < nPkt_; i++)
  255. {
  256.         nameNew[i] = name_[i];
  257. }
  258. if(!nPkt_)
  259.         delete [] name_;
  260. name_ = nameNew;
  261. nPkt_ = PT_NTYPE+1;
  262. name_[PT_TCP]= "tcp";
  263. name_[PT_UDP]= "udp";
  264. name_[PT_CBR]= "cbr";
  265. name_[PT_AUDIO]= "audio";
  266. name_[PT_VIDEO]= "video";
  267. name_[PT_ACK]= "ack";
  268. name_[PT_START]= "start";
  269. name_[PT_STOP]= "stop";
  270. name_[PT_PRUNE]= "prune";
  271. name_[PT_GRAFT]= "graft";
  272. name_[PT_GRAFTACK]= "graftAck";
  273. name_[PT_JOIN]= "join";
  274. name_[PT_ASSERT]= "assert";
  275. name_[PT_MESSAGE]= "message";
  276. name_[PT_RTCP]= "rtcp";
  277. name_[PT_RTP]= "rtp";
  278. name_[PT_RTPROTO_DV]= "rtProtoDV";
  279. name_[PT_CtrMcast_Encap]= "CtrMcast_Encap";
  280. name_[PT_CtrMcast_Decap]= "CtrMcast_Decap";
  281. name_[PT_SRM]= "SRM";
  282. name_[PT_REQUEST]= "sa_req";
  283. name_[PT_ACCEPT]= "sa_accept";
  284. name_[PT_CONFIRM]= "sa_conf";
  285. name_[PT_TEARDOWN]= "sa_teardown";
  286. name_[PT_LIVE]= "live"; 
  287. name_[PT_REJECT]= "sa_reject";
  288. name_[PT_TELNET]= "telnet";
  289. name_[PT_FTP]= "ftp";
  290. name_[PT_PARETO]= "pareto";
  291. name_[PT_EXP]= "exp";
  292. name_[PT_INVAL]= "httpInval";
  293. name_[PT_HTTP]= "http";
  294. name_[PT_ENCAPSULATED]= "encap";
  295. name_[PT_MFTP]= "mftp";
  296. name_[PT_ARP]= "ARP";
  297. name_[PT_MAC]= "MAC";
  298. name_[PT_TORA]= "TORA";
  299. name_[PT_DSR]= "DSR";
  300. name_[PT_AODV]= "AODV";
  301. name_[PT_IMEP]= "IMEP";
  302. name_[PT_RAP_DATA] = "rap_data";
  303. name_[PT_RAP_ACK] = "rap_ack";
  304.   name_[PT_TFRC]= "tcpFriend";
  305. name_[PT_TFRC_ACK]= "tcpFriendCtl";
  306. name_[PT_PING]="ping";
  307. name_[PT_PBC] = "PBC";
  308.   /* For diffusion : Chalermek */
  309.   name_[PT_DIFF] = "diffusion";
  310. // Link state routing updates
  311. name_[PT_RTPROTO_LS] = "rtProtoLS";
  312. // MPLS LDP packets
  313. name_[PT_LDP] = "LDP";
  314. // for GAF
  315.                 name_[PT_GAF] = "gaf";      
  316. // RealAudio packets
  317. name_[PT_REALAUDIO] = "ra";
  318. //pushback 
  319. name_[PT_PUSHBACK] = "pushback";
  320. #ifdef HAVE_STL
  321. // for PGM
  322. name_[PT_PGM] = "PGM";
  323. #endif //STL
  324. // LMS entries
  325. name_[PT_LMS]="LMS";
  326. name_[PT_LMS_SETUP]="LMS_SETUP";
  327. name_[PT_SCTP]= "sctp";
  328.   name_[PT_SCTP_APP1] = "sctp_app1";
  329. // smac
  330. name_[PT_SMAC]="smac";
  331. // HDLC
  332. name_[PT_HDLC]="HDLC";
  333. // XCP
  334. name_[PT_XCP]="xcp";
  335. // Bell Labs (PackMime OL)
  336. name_[PT_BLTRACE]="BellLabsTrace";
  337. name_[PT_NTYPE]= "undefined";
  338. }
  339. static int addPacket(char *name);
  340. static packet_t getType(const char *name)
  341. {
  342. for(unsigned int i = 0; i < nPkt_; i++)
  343. {
  344.         if(strcmp(name, name_[i]) == 0)
  345.                 return i;
  346. }
  347. return PT_NTYPE;
  348. }
  349. private:
  350. static char** name_;
  351. static unsigned int nPkt_;
  352. static PacketClassifier *pc_;
  353. };
  354. extern p_info packet_info; /* map PT_* to string name */
  355. //extern char* p_info::name_[];
  356. #define DATA_PACKET(type) ( (type) == PT_TCP || 
  357.                             (type) == PT_TELNET || 
  358.                             (type) == PT_CBR || 
  359.                             (type) == PT_AUDIO || 
  360.                             (type) == PT_VIDEO || 
  361.                             (type) == PT_ACK || 
  362.                             (type) == PT_SCTP || 
  363.                             (type) == PT_SCTP_APP1 
  364.                             )
  365. //#define OFFSET(type, field) ((long) &((type *)0)->field)
  366. #define OFFSET(type, field) ( (char *)&( ((type *)256)->field )  - (char *)256)
  367. class PacketData : public AppData {
  368. public:
  369. PacketData(int sz) : AppData(PACKET_DATA) {
  370. datalen_ = sz;
  371. if (datalen_ > 0)
  372. data_ = new unsigned char[datalen_];
  373. else
  374. data_ = NULL;
  375. }
  376. PacketData(PacketData& d) : AppData(d) {
  377. datalen_ = d.datalen_;
  378. if (datalen_ > 0) {
  379. data_ = new unsigned char[datalen_];
  380. memcpy(data_, d.data_, datalen_);
  381. } else
  382. data_ = NULL;
  383. }
  384. virtual ~PacketData() { 
  385. if (data_ != NULL) 
  386. delete []data_; 
  387. }
  388. unsigned char* data() { return data_; }
  389. virtual int size() const { return datalen_; }
  390. virtual AppData* copy() { return new PacketData(*this); }
  391. private:
  392. unsigned char* data_;
  393. int datalen_;
  394. };
  395. //Monarch ext
  396. typedef void (*FailureCallback)(Packet *,void *);
  397. class Packet : public Event {
  398. private:
  399. unsigned char* bits_; // header bits
  400. // unsigned char* data_; // variable size buffer for 'data'
  401. //   unsigned int datalen_; // length of variable size buffer
  402. AppData* data_; // variable size buffer for 'data'
  403. static void init(Packet*);     // initialize pkt hdr 
  404. bool fflag_;
  405. protected:
  406. static Packet* free_; // packet free list
  407. int ref_count_; // free the pkt until count to 0
  408. public:
  409. Packet* next_; // for queues and the free list
  410. static int hdrlen_;
  411. Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }
  412. inline unsigned char* const bits() { return (bits_); }
  413. inline Packet* copy() const;
  414. inline Packet* refcopy() { ++ref_count_; return this; }
  415. inline int& ref_count() { return (ref_count_); }
  416. static inline Packet* alloc();
  417. static inline Packet* alloc(int);
  418. inline void allocdata(int);
  419. // dirty hack for diffusion data
  420. inline void initdata() { data_  = 0;}
  421. static inline void free(Packet*);
  422. inline unsigned char* access(int off) const {
  423. if (off < 0)
  424. abort();
  425. return (&bits_[off]);
  426. }
  427. // This is used for backward compatibility, i.e., assuming user data
  428. // is PacketData and return its pointer.
  429. inline unsigned char* accessdata() const { 
  430. if (data_ == 0)
  431. return 0;
  432. assert(data_->type() == PACKET_DATA);
  433. return (((PacketData*)data_)->data()); 
  434. }
  435. // This is used to access application-specific data, not limited 
  436. // to PacketData.
  437. inline AppData* userdata() const {
  438. return data_;
  439. }
  440. inline void setdata(AppData* d) { 
  441. if (data_ != NULL)
  442. delete data_;
  443. data_ = d; 
  444. }
  445. inline int datalen() const { return data_ ? data_->size() : 0; }
  446. // Monarch extn
  447. static void dump_header(Packet *p, int offset, int length);
  448. // the pkt stamp carries all info about how/where the pkt
  449.         // was sent needed for a receiver to determine if it correctly
  450.         // receives the pkt
  451.         PacketStamp txinfo_;  
  452. /*
  453.          * According to cmu code:
  454.  * This flag is set by the MAC layer on an incoming packet
  455.          * and is cleared by the link layer.  It is an ugly hack, but
  456.          * there's really no other way because NS always calls
  457.          * the recv() function of an object.
  458.  * 
  459.          */
  460.         u_int8_t        incoming;
  461. //monarch extns end;
  462. };
  463. /* 
  464.  * static constant associations between interface special (negative) 
  465.  * values and their c-string representations that are used from tcl
  466.  */
  467. class iface_literal {
  468. public:
  469. enum iface_constant { 
  470. UNKN_IFACE= -1, /* 
  471.  * iface value for locally originated packets 
  472.  */
  473. ANY_IFACE= -2   /* 
  474.  * hashnode with iif == ANY_IFACE_   
  475.  * matches any pkt iface (imported from TCL);
  476.  * this value should be different from 
  477.  * hdr_cmn::UNKN_IFACE (packet.h)
  478.  */ 
  479. };
  480. iface_literal(const iface_constant i, const char * const n) : 
  481. value_(i), name_(n) {}
  482. inline int value() const { return value_; }
  483. inline const char * const name() const { return name_; }
  484. private:
  485. const iface_constant value_;
  486. /* strings used in TCL to access those special values */
  487. const char * const name_; 
  488. };
  489. static const iface_literal UNKN_IFACE(iface_literal::UNKN_IFACE, "?");
  490. static const iface_literal ANY_IFACE(iface_literal::ANY_IFACE, "*");
  491. /*
  492.  * Note that NS_AF_* doesn't necessarily correspond with
  493.  * the constants used in your system (because many
  494.  * systems don't have NONE or ILINK).
  495.  */
  496. enum ns_af_enum { NS_AF_NONE, NS_AF_ILINK, NS_AF_INET };
  497. enum ModulationScheme {BPSK = 0, QPSK = 1, QAM16 = 2, QAM64 = 3};
  498. struct hdr_cmn {
  499. enum dir_t { DOWN= -1, NONE= 0, UP= 1 };
  500. packet_t ptype_; // packet type (see above)
  501. int size_; // simulated packet size
  502. int uid_; // unique id
  503. int error_; // error flag
  504. int     errbitcnt_;     // # of corrupted bits jahn
  505. int     fecsize_;
  506. double ts_; // timestamp: for q-delay measurement
  507. int iface_; // receiving interface (label)
  508. dir_t direction_; // direction: 0=none, 1=up, -1=down
  509. // source routing 
  510.         char src_rt_valid;
  511. double ts_arr_; // Required by Marker of JOBS 
  512. //Monarch extn begins
  513. nsaddr_t prev_hop_;     // IP addr of forwarding hop
  514. nsaddr_t next_hop_; // next hop for this packet
  515. int      addr_type_;    // type of next_hop_ addr
  516. nsaddr_t last_hop_;     // for tracing on multi-user channels
  517.         // called if pkt can't obtain media or isn't ack'd. not called if
  518.         // droped by a queue
  519.         FailureCallback xmit_failure_; 
  520.         void *xmit_failure_data_;
  521.         /*
  522.          * MONARCH wants to know if the MAC layer is passing this back because
  523.          * it could not get the RTS through or because it did not receive
  524.          * an ACK.
  525.          */
  526.         int     xmit_reason_;
  527. #define XMIT_REASON_RTS 0x01
  528. #define XMIT_REASON_ACK 0x02
  529.         // filled in by GOD on first transmission, used for trace analysis
  530.         int num_forwards_; // how many times this pkt was forwarded
  531.         int opt_num_forwards_;   // optimal #forwards
  532. // Monarch extn ends;
  533. // tx time for this packet in sec
  534. double txtime_;
  535. inline double& txtime() { return(txtime_); }
  536. static int offset_; // offset for this header
  537. inline static int& offset() { return offset_; }
  538. inline static hdr_cmn* access(const Packet* p) {
  539. return (hdr_cmn*) p->access(offset_);
  540. }
  541.         /* per-field member functions */
  542. inline packet_t& ptype() { return (ptype_); }
  543. inline int& size() { return (size_); }
  544. inline int& uid() { return (uid_); }
  545. inline int& error() { return error_; }
  546. inline int& errbitcnt() {return errbitcnt_; }
  547. inline int& fecsize() {return fecsize_; }
  548. inline double& timestamp() { return (ts_); }
  549. inline int& iface() { return (iface_); }
  550. inline dir_t& direction() { return (direction_); }
  551. // monarch_begin
  552. inline nsaddr_t& next_hop() { return (next_hop_); }
  553. inline int& addr_type() { return (addr_type_); }
  554. inline int& num_forwards() { return (num_forwards_); }
  555. inline int& opt_num_forwards() { return (opt_num_forwards_); }
  556.         //monarch_end
  557. ModulationScheme mod_scheme_;
  558. inline ModulationScheme& mod_scheme() { return (mod_scheme_); }
  559. };
  560. class PacketHeaderClass : public TclClass {
  561. protected:
  562. PacketHeaderClass(const char* classname, int hdrsize);
  563. virtual int method(int argc, const char*const* argv);
  564. void field_offset(const char* fieldname, int offset);
  565. inline void bind_offset(int* off) { offset_ = off; }
  566. inline void offset(int* off) {offset_= off;}
  567. int hdrlen_; // # of bytes for this header
  568. int* offset_; // offset for this header
  569. public:
  570. virtual void bind();
  571. virtual void export_offsets();
  572. TclObject* create(int argc, const char*const* argv);
  573. };
  574. inline void Packet::init(Packet* p)
  575. {
  576. bzero(p->bits_, hdrlen_);
  577. }
  578. inline Packet* Packet::alloc()
  579. {
  580. Packet* p = free_;
  581. if (p != 0) {
  582. assert(p->fflag_ == FALSE);
  583. free_ = p->next_;
  584. assert(p->data_ == 0);
  585. p->uid_ = 0;
  586. p->time_ = 0;
  587. } else {
  588. p = new Packet;
  589. p->bits_ = new unsigned char[hdrlen_];
  590. if (p == 0 || p->bits_ == 0)
  591. abort();
  592. }
  593. init(p); // Initialize bits_[]
  594. (HDR_CMN(p))->next_hop_ = -2; // -1 reserved for IP_BROADCAST
  595. (HDR_CMN(p))->last_hop_ = -2; // -1 reserved for IP_BROADCAST
  596. p->fflag_ = TRUE;
  597. (HDR_CMN(p))->direction() = hdr_cmn::DOWN;
  598. /* setting all direction of pkts to be downward as default; 
  599.    until channel changes it to +1 (upward) */
  600. p->next_ = 0;
  601. return (p);
  602. }
  603. /* 
  604.  * Allocate an n byte data buffer to an existing packet 
  605.  * 
  606.  * To set application-specific AppData, use Packet::setdata()
  607.  */
  608. inline void Packet::allocdata(int n)
  609. {
  610. assert(data_ == 0);
  611. data_ = new PacketData(n);
  612. if (data_ == 0)
  613. abort();
  614. }
  615. /* allocate a packet with an n byte data buffer */
  616. inline Packet* Packet::alloc(int n)
  617. {
  618. Packet* p = alloc();
  619. if (n > 0) 
  620. p->allocdata(n);
  621. return (p);
  622. }
  623. inline void Packet::free(Packet* p)
  624. {
  625. if (p->fflag_) {
  626. if (p->ref_count_ == 0) {
  627. /*
  628.  * A packet's uid may be < 0 (out of a event queue), or
  629.  * == 0 (newed but never gets into the event queue.
  630.  */
  631. assert(p->uid_ <= 0);
  632. // Delete user data because we won't need it any more.
  633. if (p->data_ != 0) {
  634. delete p->data_;
  635. p->data_ = 0;
  636. }
  637. init(p);
  638. p->next_ = free_;
  639. free_ = p;
  640. p->fflag_ = FALSE;
  641. } else {
  642. --p->ref_count_;
  643. }
  644. }
  645. }
  646. inline Packet* Packet::copy() const
  647. {
  648. Packet* p = alloc();
  649. memcpy(p->bits(), bits_, hdrlen_);
  650. if (data_) 
  651. p->data_ = data_->copy();
  652. p->txinfo_.init(&txinfo_);
  653.  
  654. return (p);
  655. }
  656. inline void
  657. Packet::dump_header(Packet *p, int offset, int length)
  658. {
  659.         assert(offset + length <= p->hdrlen_);
  660.         struct hdr_cmn *ch = HDR_CMN(p);
  661.         fprintf(stderr, "nPacket ID: %dn", ch->uid());
  662.         for(int i = 0; i < length ; i+=16) {
  663.                 fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02xn",
  664.                         p->bits_[offset + i],     p->bits_[offset + i + 1],
  665.                         p->bits_[offset + i + 2], p->bits_[offset + i + 3],
  666.                         p->bits_[offset + i + 4], p->bits_[offset + i + 5],
  667.                         p->bits_[offset + i + 6], p->bits_[offset + i + 7],
  668.                         p->bits_[offset + i + 8], p->bits_[offset + i + 9],
  669.                         p->bits_[offset + i + 10], p->bits_[offset + i + 11],
  670.                         p->bits_[offset + i + 12], p->bits_[offset + i + 13],
  671.                         p->bits_[offset + i + 14], p->bits_[offset + i + 15]);
  672.         }
  673. }
  674. #endif