packet.h
上传用户:hzie11
上传日期:2013-10-07
资源大小:1487k
文件大小:17k
源码类别:

网络

开发平台:

C/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: /nfs/jade/vint/CVSROOT/ns-2/common/packet.h,v 1.98 2005/09/18 23:33:31 tomh 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. enum packet_t {
  69. PT_TCP,
  70. PT_UDP,
  71. PT_CBR,
  72. PT_AUDIO,
  73. PT_VIDEO,
  74. PT_ACK,
  75. PT_START,
  76. PT_STOP,
  77. PT_PRUNE,
  78. PT_GRAFT,
  79. PT_GRAFTACK,
  80. PT_JOIN,
  81. PT_ASSERT,
  82. PT_MESSAGE,
  83. PT_RTCP,
  84. PT_RTP,
  85. PT_RTPROTO_DV,
  86. PT_CtrMcast_Encap,
  87. PT_CtrMcast_Decap,
  88. PT_SRM,
  89. /* simple signalling messages */
  90. PT_REQUEST,
  91. PT_ACCEPT,
  92. PT_CONFIRM,
  93. PT_TEARDOWN,
  94. PT_LIVE, // packet from live network
  95. PT_REJECT,
  96. PT_TELNET, // not needed: telnet use TCP
  97. PT_FTP,
  98. PT_PARETO,
  99. PT_EXP,
  100. PT_INVAL,
  101. PT_HTTP,
  102. /* new encapsulator */
  103. PT_ENCAPSULATED,
  104. PT_MFTP,
  105. /* CMU/Monarch's extnsions */
  106. PT_ARP,
  107. PT_MAC,
  108. PT_TORA,
  109. PT_DSR,
  110. PT_AODV,
  111. PT_IMEP,
  112. // RAP packets
  113. PT_RAP_DATA,
  114. PT_RAP_ACK,
  115. PT_TFRC,
  116. PT_TFRC_ACK,
  117. PT_PING,
  118. // Diffusion packets - Chalermek
  119. PT_DIFF,
  120. // LinkState routing update packets
  121. PT_RTPROTO_LS,
  122. // MPLS LDP header
  123. PT_LDP,
  124. // GAF packet
  125.         PT_GAF,  
  126. // ReadAudio traffic
  127. PT_REALAUDIO,
  128. // Pushback Messages
  129. PT_PUSHBACK,
  130. #ifdef HAVE_STL
  131. // Pragmatic General Multicast
  132. PT_PGM,
  133. #endif //STL
  134. // LMS packets
  135. PT_LMS,
  136. PT_LMS_SETUP,
  137. PT_SCTP,
  138. PT_SCTP_APP1,
  139. // SMAC packet
  140. PT_SMAC,
  141. // XCP packet
  142. PT_XCP,
  143. // HDLC packet
  144. PT_HDLC,
  145. // WIMAX inter-BS packets
  146. PT_WIMAXBS,
  147. // insert new packet types here
  148. PT_NTYPE // This MUST be the LAST one
  149. };
  150. class p_info {
  151. public:
  152. p_info() {
  153. name_[PT_TCP]= "tcp";
  154. name_[PT_UDP]= "udp";
  155. name_[PT_CBR]= "cbr";
  156. name_[PT_AUDIO]= "audio";
  157. name_[PT_VIDEO]= "video";
  158. name_[PT_ACK]= "ack";
  159. name_[PT_START]= "start";
  160. name_[PT_STOP]= "stop";
  161. name_[PT_PRUNE]= "prune";
  162. name_[PT_GRAFT]= "graft";
  163. name_[PT_GRAFTACK]= "graftAck";
  164. name_[PT_JOIN]= "join";
  165. name_[PT_ASSERT]= "assert";
  166. name_[PT_MESSAGE]= "message";
  167. name_[PT_RTCP]= "rtcp";
  168. name_[PT_RTP]= "rtp";
  169. name_[PT_RTPROTO_DV]= "rtProtoDV";
  170. name_[PT_CtrMcast_Encap]= "CtrMcast_Encap";
  171. name_[PT_CtrMcast_Decap]= "CtrMcast_Decap";
  172. name_[PT_SRM]= "SRM";
  173. name_[PT_REQUEST]= "sa_req";
  174. name_[PT_ACCEPT]= "sa_accept";
  175. name_[PT_CONFIRM]= "sa_conf";
  176. name_[PT_TEARDOWN]= "sa_teardown";
  177. name_[PT_LIVE]= "live"; 
  178. name_[PT_REJECT]= "sa_reject";
  179. name_[PT_TELNET]= "telnet";
  180. name_[PT_FTP]= "ftp";
  181. name_[PT_PARETO]= "pareto";
  182. name_[PT_EXP]= "exp";
  183. name_[PT_INVAL]= "httpInval";
  184. name_[PT_HTTP]= "http";
  185. name_[PT_ENCAPSULATED]= "encap";
  186. name_[PT_MFTP]= "mftp";
  187. name_[PT_ARP]= "ARP";
  188. name_[PT_MAC]= "MAC";
  189. name_[PT_TORA]= "TORA";
  190. name_[PT_DSR]= "DSR";
  191. name_[PT_AODV]= "AODV";
  192. name_[PT_IMEP]= "IMEP";
  193. name_[PT_RAP_DATA] = "rap_data";
  194. name_[PT_RAP_ACK] = "rap_ack";
  195.   name_[PT_TFRC]= "tcpFriend";
  196. name_[PT_TFRC_ACK]= "tcpFriendCtl";
  197. name_[PT_PING]="ping";
  198.   /* For diffusion : Chalermek */
  199.   name_[PT_DIFF] = "diffusion";
  200. // Link state routing updates
  201. name_[PT_RTPROTO_LS] = "rtProtoLS";
  202. // MPLS LDP packets
  203. name_[PT_LDP] = "LDP";
  204. // for GAF
  205.                 name_[PT_GAF] = "gaf";      
  206. // RealAudio packets
  207. name_[PT_REALAUDIO] = "ra";
  208. //pushback 
  209. name_[PT_PUSHBACK] = "pushback";
  210. #ifdef HAVE_STL
  211. // for PGM
  212. name_[PT_PGM] = "PGM";
  213. #endif //STL
  214. // LMS entries
  215. name_[PT_LMS]="LMS";
  216. name_[PT_LMS_SETUP]="LMS_SETUP";
  217. name_[PT_SCTP]= "sctp";
  218.   name_[PT_SCTP_APP1] = "sctp_app1";
  219. // smac
  220. name_[PT_SMAC]="smac";
  221. // HDLC
  222. name_[PT_HDLC]="HDLC";
  223. // XCP
  224. name_[PT_XCP]="xcp";
  225. // WIMAX
  226. name_[PT_WIMAXBS]="wimaxCtrl";
  227. name_[PT_NTYPE]= "undefined";
  228. }
  229. const char* name(packet_t p) const { 
  230. if ( p <= PT_NTYPE ) return name_[p];
  231. return 0;
  232. }
  233. static bool data_packet(packet_t type) {
  234. return ( (type) == PT_TCP || 
  235.  (type) == PT_TELNET || 
  236.  (type) == PT_CBR || 
  237.  (type) == PT_AUDIO || 
  238.  (type) == PT_VIDEO || 
  239.  (type) == PT_ACK || 
  240.  (type) == PT_SCTP || 
  241.  (type) == PT_SCTP_APP1 || 
  242.  (type) == PT_HDLC 
  243. );
  244. }
  245. private:
  246. static char* name_[PT_NTYPE+1];
  247. };
  248. extern p_info packet_info; /* map PT_* to string name */
  249. //extern char* p_info::name_[];
  250. #define DATA_PACKET(type) ( (type) == PT_TCP || 
  251.                             (type) == PT_TELNET || 
  252.                             (type) == PT_CBR || 
  253.                             (type) == PT_AUDIO || 
  254.                             (type) == PT_VIDEO || 
  255.                             (type) == PT_ACK || 
  256.                             (type) == PT_SCTP || 
  257.                             (type) == PT_SCTP_APP1 
  258.                             )
  259. #define OFFSET(type, field) ((long) &((type *)0)->field)
  260. class PacketData : public AppData {
  261. public:
  262. PacketData(int sz) : AppData(PACKET_DATA) {
  263. datalen_ = sz;
  264. if (datalen_ > 0)
  265. data_ = new unsigned char[datalen_];
  266. else
  267. data_ = NULL;
  268. }
  269. PacketData(PacketData& d) : AppData(d) {
  270. datalen_ = d.datalen_;
  271. if (datalen_ > 0) {
  272. data_ = new unsigned char[datalen_];
  273. memcpy(data_, d.data_, datalen_);
  274. } else
  275. data_ = NULL;
  276. }
  277. virtual ~PacketData() { 
  278. if (data_ != NULL) 
  279. delete []data_; 
  280. }
  281. unsigned char* data() { return data_; }
  282. virtual int size() const { return datalen_; }
  283. virtual AppData* copy() { return new PacketData(*this); }
  284. private:
  285. unsigned char* data_;
  286. int datalen_;
  287. };
  288. //Monarch ext
  289. typedef void (*FailureCallback)(Packet *,void *);
  290. class Packet : public Event {
  291. private:
  292. unsigned char* bits_; // header bits
  293. // unsigned char* data_; // variable size buffer for 'data'
  294. //   unsigned int datalen_; // length of variable size buffer
  295. AppData* data_; // variable size buffer for 'data'
  296. static void init(Packet*);     // initialize pkt hdr 
  297. bool fflag_;
  298. protected:
  299. static Packet* free_; // packet free list
  300. int ref_count_; // free the pkt until count to 0
  301. public:
  302. Packet* next_; // for queues and the free list
  303. static int hdrlen_;
  304. Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }
  305. inline unsigned char* const bits() { return (bits_); }
  306. inline Packet* copy() const;
  307. inline Packet* refcopy() { ++ref_count_; return this; }
  308. inline int& ref_count() { return (ref_count_); }
  309. static inline Packet* alloc();
  310. static inline Packet* alloc(int);
  311. inline void allocdata(int);
  312. // dirty hack for diffusion data
  313. inline void initdata() { data_  = 0;}
  314. static inline void free(Packet*);
  315. inline unsigned char* access(int off) const {
  316. if (off < 0)
  317. abort();
  318. return (&bits_[off]);
  319. }
  320. // This is used for backward compatibility, i.e., assuming user data
  321. // is PacketData and return its pointer.
  322. inline unsigned char* accessdata() const { 
  323. if (data_ == 0)
  324. return 0;
  325. assert(data_->type() == PACKET_DATA);
  326. return (((PacketData*)data_)->data()); 
  327. }
  328. // This is used to access application-specific data, not limited 
  329. // to PacketData.
  330. inline AppData* userdata() const {
  331. return data_;
  332. }
  333. inline void setdata(AppData* d) { 
  334. if (data_ != NULL)
  335. delete data_;
  336. data_ = d; 
  337. }
  338. inline int datalen() const { return data_ ? data_->size() : 0; }
  339. // Monarch extn
  340. static void dump_header(Packet *p, int offset, int length);
  341. // the pkt stamp carries all info about how/where the pkt
  342.         // was sent needed for a receiver to determine if it correctly
  343.         // receives the pkt
  344.         PacketStamp txinfo_;  
  345. /*
  346.          * According to cmu code:
  347.  * This flag is set by the MAC layer on an incoming packet
  348.          * and is cleared by the link layer.  It is an ugly hack, but
  349.          * there's really no other way because NS always calls
  350.          * the recv() function of an object.
  351.  * 
  352.          */
  353.         u_int8_t        incoming;
  354. //monarch extns end;
  355. };
  356. /* 
  357.  * static constant associations between interface special (negative) 
  358.  * values and their c-string representations that are used from tcl
  359.  */
  360. class iface_literal {
  361. public:
  362. enum iface_constant { 
  363. UNKN_IFACE= -1, /* 
  364.  * iface value for locally originated packets 
  365.  */
  366. ANY_IFACE= -2   /* 
  367.  * hashnode with iif == ANY_IFACE_   
  368.  * matches any pkt iface (imported from TCL);
  369.  * this value should be different from 
  370.  * hdr_cmn::UNKN_IFACE (packet.h)
  371.  */ 
  372. };
  373. iface_literal(const iface_constant i, const char * const n) : 
  374. value_(i), name_(n) {}
  375. inline int value() const { return value_; }
  376. inline const char * const name() const { return name_; }
  377. private:
  378. const iface_constant value_;
  379. /* strings used in TCL to access those special values */
  380. const char * const name_; 
  381. };
  382. static const iface_literal UNKN_IFACE(iface_literal::UNKN_IFACE, "?");
  383. static const iface_literal ANY_IFACE(iface_literal::ANY_IFACE, "*");
  384. /*
  385.  * Note that NS_AF_* doesn't necessarily correspond with
  386.  * the constants used in your system (because many
  387.  * systems don't have NONE or ILINK).
  388.  */
  389. enum ns_af_enum { NS_AF_NONE, NS_AF_ILINK, NS_AF_INET };
  390. struct hdr_cmn {
  391. enum dir_t { DOWN= -1, NONE= 0, UP= 1 };
  392. packet_t ptype_; // packet type (see above)
  393. int size_; // simulated packet size
  394. int uid_; // unique id
  395. int error_; // error flag
  396. int     errbitcnt_;     // # of corrupted bits jahn
  397. int     fecsize_;
  398. double ts_; // timestamp: for q-delay measurement
  399. int iface_; // receiving interface (label)
  400. dir_t direction_; // direction: 0=none, 1=up, -1=down
  401. // source routing 
  402.         char src_rt_valid;
  403. double ts_arr_; // Required by Marker of JOBS 
  404. //Monarch extn begins
  405. nsaddr_t prev_hop_;     // IP addr of forwarding hop
  406. nsaddr_t next_hop_; // next hop for this packet
  407. int      addr_type_;    // type of next_hop_ addr
  408. nsaddr_t last_hop_;     // for tracing on multi-user channels
  409.         // called if pkt can't obtain media or isn't ack'd. not called if
  410.         // droped by a queue
  411.         FailureCallback xmit_failure_; 
  412.         void *xmit_failure_data_;
  413.         /*
  414.          * MONARCH wants to know if the MAC layer is passing this back because
  415.          * it could not get the RTS through or because it did not receive
  416.          * an ACK.
  417.          */
  418.         int     xmit_reason_;
  419. #define XMIT_REASON_RTS 0x01
  420. #define XMIT_REASON_ACK 0x02
  421.         // filled in by GOD on first transmission, used for trace analysis
  422.         int num_forwards_; // how many times this pkt was forwarded
  423.         int opt_num_forwards_;   // optimal #forwards
  424. // Monarch extn ends;
  425. // tx time for this packet in sec
  426. double txtime_;
  427. inline double& txtime() { return(txtime_); }
  428. static int offset_; // offset for this header
  429. inline static int& offset() { return offset_; }
  430. inline static hdr_cmn* access(const Packet* p) {
  431. return (hdr_cmn*) p->access(offset_);
  432. }
  433.         /* per-field member functions */
  434. inline packet_t& ptype() { return (ptype_); }
  435. inline int& size() { return (size_); }
  436. inline int& uid() { return (uid_); }
  437. inline int& error() { return error_; }
  438. inline int& errbitcnt() {return errbitcnt_; }
  439. inline int& fecsize() {return fecsize_; }
  440. inline double& timestamp() { return (ts_); }
  441. inline int& iface() { return (iface_); }
  442. inline dir_t& direction() { return (direction_); }
  443. // monarch_begin
  444. inline nsaddr_t& next_hop() { return (next_hop_); }
  445. inline int& addr_type() { return (addr_type_); }
  446. inline int& num_forwards() { return (num_forwards_); }
  447. inline int& opt_num_forwards() { return (opt_num_forwards_); }
  448.         //monarch_end
  449. };
  450. class PacketHeaderClass : public TclClass {
  451. protected:
  452. PacketHeaderClass(const char* classname, int hdrsize);
  453. virtual int method(int argc, const char*const* argv);
  454. void field_offset(const char* fieldname, int offset);
  455. inline void bind_offset(int* off) { offset_ = off; }
  456. inline void offset(int* off) {offset_= off;}
  457. int hdrlen_; // # of bytes for this header
  458. int* offset_; // offset for this header
  459. public:
  460. virtual void bind();
  461. virtual void export_offsets();
  462. TclObject* create(int argc, const char*const* argv);
  463. };
  464. inline void Packet::init(Packet* p)
  465. {
  466. bzero(p->bits_, hdrlen_);
  467. }
  468. inline Packet* Packet::alloc()
  469. {
  470. Packet* p = free_;
  471. if (p != 0) {
  472. assert(p->fflag_ == FALSE);
  473. free_ = p->next_;
  474. assert(p->data_ == 0);
  475. p->uid_ = 0;
  476. p->time_ = 0;
  477. } else {
  478. p = new Packet;
  479. p->bits_ = new unsigned char[hdrlen_];
  480. if (p == 0 || p->bits_ == 0)
  481. abort();
  482. }
  483. init(p); // Initialize bits_[]
  484. (HDR_CMN(p))->next_hop_ = -2; // -1 reserved for IP_BROADCAST
  485. (HDR_CMN(p))->last_hop_ = -2; // -1 reserved for IP_BROADCAST
  486. p->fflag_ = TRUE;
  487. (HDR_CMN(p))->direction() = hdr_cmn::DOWN;
  488. /* setting all direction of pkts to be downward as default; 
  489.    until channel changes it to +1 (upward) */
  490. p->next_ = 0;
  491. return (p);
  492. }
  493. /* 
  494.  * Allocate an n byte data buffer to an existing packet 
  495.  * 
  496.  * To set application-specific AppData, use Packet::setdata()
  497.  */
  498. inline void Packet::allocdata(int n)
  499. {
  500. assert(data_ == 0);
  501. data_ = new PacketData(n);
  502. if (data_ == 0)
  503. abort();
  504. }
  505. /* allocate a packet with an n byte data buffer */
  506. inline Packet* Packet::alloc(int n)
  507. {
  508. Packet* p = alloc();
  509. if (n > 0) 
  510. p->allocdata(n);
  511. return (p);
  512. }
  513. inline void Packet::free(Packet* p)
  514. {
  515. if (p->fflag_) {
  516. if (p->ref_count_ == 0) {
  517. /*
  518.  * A packet's uid may be < 0 (out of a event queue), or
  519.  * == 0 (newed but never gets into the event queue.
  520.  */
  521. assert(p->uid_ <= 0);
  522. // Delete user data because we won't need it any more.
  523. if (p->data_ != 0) {
  524. delete p->data_;
  525. p->data_ = 0;
  526. }
  527. init(p);
  528. p->next_ = free_;
  529. free_ = p;
  530. p->fflag_ = FALSE;
  531. } else {
  532. --p->ref_count_;
  533. }
  534. }
  535. }
  536. inline Packet* Packet::copy() const
  537. {
  538. Packet* p = alloc();
  539. memcpy(p->bits(), bits_, hdrlen_);
  540. if (data_) 
  541. p->data_ = data_->copy();
  542. p->txinfo_.init(&txinfo_);
  543.  
  544. return (p);
  545. }
  546. inline void
  547. Packet::dump_header(Packet *p, int offset, int length)
  548. {
  549.         assert(offset + length <= p->hdrlen_);
  550.         struct hdr_cmn *ch = HDR_CMN(p);
  551.         fprintf(stderr, "nPacket ID: %dn", ch->uid());
  552.         for(int i = 0; i < length ; i+=16) {
  553.                 fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02xn",
  554.                         p->bits_[offset + i],     p->bits_[offset + i + 1],
  555.                         p->bits_[offset + i + 2], p->bits_[offset + i + 3],
  556.                         p->bits_[offset + i + 4], p->bits_[offset + i + 5],
  557.                         p->bits_[offset + i + 6], p->bits_[offset + i + 7],
  558.                         p->bits_[offset + i + 8], p->bits_[offset + i + 9],
  559.                         p->bits_[offset + i + 10], p->bits_[offset + i + 11],
  560.                         p->bits_[offset + i + 12], p->bits_[offset + i + 13],
  561.                         p->bits_[offset + i + 14], p->bits_[offset + i + 15]);
  562.         }
  563. }
  564. #endif