xorp

packet.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU Lesser General Public License, Version
00008 // 2.1, June 1999 as published by the Free Software Foundation.
00009 // Redistribution and/or modification of this program under the terms of
00010 // any other version of the GNU Lesser General Public License is not
00011 // permitted.
00012 // 
00013 // This program is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00016 // see the GNU Lesser General Public License, Version 2.1, a copy of
00017 // which can be found in the XORP LICENSE.lgpl file.
00018 // 
00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00020 // http://xorp.net
00021 
00022 // $XORP: xorp/libproto/packet.hh,v 1.22 2008/12/18 11:13:59 abittau Exp $
00023 
00024 
00025 #ifndef __LIBPROTO_PACKET_HH__
00026 #define __LIBPROTO_PACKET_HH__
00027 
00028 
00029 #include "libxorp/xorp.h"
00030 
00031 #include "libxorp/ipv4.hh"
00032 #include "libxorp/ipv6.hh"
00033 #include "libxorp/mac.hh"
00034 
00035 
00036 //
00037 // Network protocols related constants
00038 //
00039 #ifndef ETHERTYPE_IP
00040 #define ETHERTYPE_IP        0x0800  // IP protocol
00041 #endif
00042 #ifndef ETHERTYPE_ARP
00043 #define ETHERTYPE_ARP       0x0806  // Address Resolution Protocol
00044 #endif
00045 
00046 #ifndef IPPROTO_VRRP
00047 #define IPPROTO_VRRP        112 // Virtual Router Redundancy Protocol
00048 #endif
00049 
00058 inline
00059 uint8_t
00060 extract_8(const uint8_t *ptr)
00061 {
00062     uint8_t val;
00063 
00064     val = ptr[0];
00065 
00066     return val;
00067 }
00068 
00077 inline
00078 void
00079 embed_8(uint8_t *ptr, uint8_t val)
00080 {
00081     ptr[0] = val;
00082 }
00083 
00092 inline
00093 uint16_t
00094 extract_16(const uint8_t *ptr)
00095 {
00096     uint16_t val;
00097 
00098     val = ptr[0];
00099     val <<= 8;
00100     val |= ptr[1];
00101 
00102     return val;
00103 }
00104 
00113 inline
00114 void
00115 embed_16(uint8_t *ptr, uint16_t val)
00116 {
00117     ptr[0] = (val >> 8) & 0xff;
00118     ptr[1] = val & 0xff;
00119 }
00120 
00129 inline
00130 uint32_t
00131 extract_24(const uint8_t *ptr)
00132 {
00133     uint32_t val;
00134 
00135     val = ptr[0];
00136     val <<= 8;
00137     val |= ptr[1];
00138     val <<= 8;
00139     val |= ptr[2];
00140 
00141     return val;
00142 }
00143 
00152 inline
00153 void
00154 embed_24(uint8_t *ptr, uint32_t val)
00155 {
00156     ptr[0] = (val >> 16) & 0xff;
00157     ptr[1] = (val >> 8) & 0xff;
00158     ptr[2] = val & 0xff;
00159 }
00160 
00169 inline
00170 uint32_t
00171 extract_32(const uint8_t *ptr)
00172 {
00173     uint32_t val;
00174 
00175     val = ptr[0];
00176     val <<= 8;
00177     val |= ptr[1];
00178     val <<= 8;
00179     val |= ptr[2];
00180     val <<= 8;
00181     val |= ptr[3];
00182 
00183     return val;
00184 }
00185 
00194 inline
00195 void
00196 embed_32(uint8_t *ptr, uint32_t val)
00197 {
00198     ptr[0] = (val >> 24) & 0xff;
00199     ptr[1] = (val >> 16) & 0xff;
00200     ptr[2] = (val >> 8) & 0xff;
00201     ptr[3] = val & 0xff;
00202 }
00203 
00212 inline
00213 uint8_t
00214 extract_host_8(const uint8_t *ptr)
00215 {
00216     uint8_t val;
00217 
00218     val = ptr[0];
00219 
00220     return val;
00221 }
00222 
00231 inline
00232 void
00233 embed_host_8(uint8_t *ptr, uint8_t val)
00234 {
00235     ptr[0] = val;
00236 }
00237 
00246 inline
00247 uint16_t
00248 extract_host_16(const uint8_t *ptr)
00249 {
00250     union {
00251     uint16_t val;
00252     uint8_t  c[sizeof(uint16_t)];
00253     } u;
00254 
00255     u.c[0] = ptr[0];
00256     u.c[1] = ptr[1];
00257 
00258     return u.val;
00259 }
00260 
00269 inline
00270 void
00271 embed_host_16(uint8_t *ptr, uint16_t val)
00272 {
00273     union {
00274     uint16_t val;
00275     uint8_t  c[sizeof(uint16_t)];
00276     } u;
00277 
00278     u.val = val;
00279     ptr[0] = u.c[0];
00280     ptr[1] = u.c[1];
00281 }
00282 
00283 /*
00284  * XXX: Note that we don't define extract_host_24() and embed_host_24(),
00285  * because 3 octets of data might occupy either 3 or 4 octets (depending
00286  * on the byte ordering). Hence, extract_host_32() and embed_host_32()
00287  * should be used instead.
00288  */
00289 
00298 inline
00299 uint32_t
00300 extract_host_32(const uint8_t *ptr)
00301 {
00302     union {
00303     uint32_t val;
00304     uint8_t  c[sizeof(uint32_t)];
00305     } u;
00306 
00307     u.c[0] = ptr[0];
00308     u.c[1] = ptr[1];
00309     u.c[2] = ptr[2];
00310     u.c[3] = ptr[3];
00311 
00312     return u.val;
00313 }
00314 
00323 inline
00324 void
00325 embed_host_32(uint8_t *ptr, uint32_t val)
00326 {
00327     union {
00328     uint32_t val;
00329     uint8_t  c[sizeof(uint32_t)];
00330     } u;
00331 
00332     u.val = val;
00333     ptr[0] = u.c[0];
00334     ptr[1] = u.c[1];
00335     ptr[2] = u.c[2];
00336     ptr[3] = u.c[3];
00337 }
00338 
00347 inline
00348 int
00349 extract_host_int(const uint8_t *ptr)
00350 {
00351     union {
00352     int val;
00353     uint8_t  c[sizeof(int)];
00354     } u;
00355 
00356     for (size_t i = 0; i < sizeof(int); i++) {
00357     u.c[i] = ptr[i];
00358     }
00359 
00360     return u.val;
00361 }
00362 
00371 inline
00372 void
00373 embed_host_int(uint8_t *ptr, int val)
00374 {
00375     union {
00376     int val;
00377     uint8_t  c[sizeof(int)];
00378     } u;
00379 
00380     u.val = val;
00381     for (size_t i = 0; i < sizeof(int); i++) {
00382     ptr[i] = u.c[i];
00383     }
00384 }
00385 
00402 class IpHeader4 {
00403 public:
00404     IpHeader4(const uint8_t* data)
00405     : _data(data),
00406       _ip_vhl(_data + _ip_vhl_offset),
00407       _ip_tos(_data + _ip_tos_offset),
00408       _ip_len(_data + _ip_len_offset),
00409       _ip_id(_data + _ip_id_offset),
00410       _ip_off(_data + _ip_off_offset),
00411       _ip_ttl(_data + _ip_ttl_offset),
00412       _ip_p(_data + _ip_p_offset),
00413       _ip_sum(_data + _ip_sum_offset),
00414       _ip_src(_data + _ip_src_offset),
00415       _ip_dst(_data + _ip_dst_offset)
00416     {
00417     x_static_assert(IpHeader4::SIZE == _ip_vhl_sizeof + _ip_tos_sizeof
00418               + _ip_len_sizeof + _ip_id_sizeof + _ip_off_sizeof
00419               + _ip_ttl_sizeof + _ip_p_sizeof + _ip_sum_sizeof
00420               + _ip_src_sizeof + _ip_dst_sizeof);
00421     x_static_assert(IpHeader4::SIZE == _ip_dst_offset + _ip_dst_sizeof);
00422     }
00423 
00424     static const size_t SIZE = 20;      // The header size
00425     static const uint8_t IP_VERSION = 4;    // IPv4 version
00426 
00434     static size_t size() { return IpHeader4::SIZE; }
00435 
00441     const uint8_t* data() const { return (_data); }
00442 
00446     uint8_t  ip_vhl() const { return extract_8(_ip_vhl); }
00447     uint8_t  ip_tos() const { return extract_8(_ip_tos); }
00448     uint16_t ip_len() const { return extract_16(_ip_len); }
00449     uint16_t ip_id() const  { return extract_16(_ip_id); }
00450     uint16_t ip_off() const { return extract_16(_ip_off); }
00451     uint8_t  ip_ttl() const { return extract_8(_ip_ttl); }
00452     uint8_t  ip_p() const   { return extract_8(_ip_p); }
00453     uint16_t ip_sum() const { return extract_16(_ip_sum); }
00454     IPv4     ip_src() const { return IPv4(_ip_src); }
00455     IPv4     ip_dst() const { return IPv4(_ip_dst); }
00456 
00457     /*
00458      * A method to extract the ip_len value that is presumably stored
00459      * in host order.
00460      *
00461      * @return the ip_len value that is presumably stored in host order.
00462      */
00463     uint16_t ip_len_host() const{ return extract_host_16(_ip_len); }
00464 
00470     uint8_t ip_version() const {
00471     uint8_t v = ip_vhl();
00472     return ((v >> 4) & 0x0f);
00473     }
00474 
00480     uint8_t ip_header_len() const { return ((ip_vhl() & 0x0f) << 2); }
00481 
00487     uint16_t ip_fragment_offset() const {
00488     return (ip_off() & IpHeader4::FRAGMENT_OFFSET_MASK);
00489     }
00490 
00496     uint16_t ip_fragment_flags() const {
00497     return (ip_off() & IpHeader4::FRAGMENT_FLAGS_MASK);
00498     }
00499 
00505     bool is_valid_version() const {
00506     return (ip_version() == IpHeader4::IP_VERSION);
00507     }
00508 
00523     int fragment(size_t mtu, list<vector<uint8_t> >& fragments,
00524          bool do_checksum, string& error_msg) const;
00525 
00526 protected:
00527     // IPv4 header related constants
00528     static const uint16_t FRAGMENT_OFFSET_MASK  = 0x1fff;
00529     static const uint16_t FRAGMENT_FLAGS_MASK   = 0xe000;
00530     static const uint16_t FRAGMENT_FLAGS_IP_DF  = 0x4000; // Don't fragment
00531     static const uint16_t FRAGMENT_FLAGS_IP_MF  = 0x2000; // More fragments
00532     static const uint8_t  OPTIONS_IPOPT_EOL = 0;    // End of option list
00533     static const uint8_t  OPTIONS_IPOPT_NOP = 1;    // No operation
00534     static const size_t   OPTIONS_IPOPT_OLEN    = 1;    // Option length offset
00535     static const uint8_t  OPTIONS_COPIED_FLAG   = 0x80; // Option copied flag
00536 
00537     // Sizes of the fields
00538     static const size_t _ip_vhl_sizeof  = 1;
00539     static const size_t _ip_tos_sizeof  = 1;
00540     static const size_t _ip_len_sizeof  = 2;
00541     static const size_t _ip_id_sizeof   = 2;
00542     static const size_t _ip_off_sizeof  = 2;
00543     static const size_t _ip_ttl_sizeof  = 1;
00544     static const size_t _ip_p_sizeof    = 1;
00545     static const size_t _ip_sum_sizeof  = 2;
00546     static const size_t _ip_src_sizeof  = 4;
00547     static const size_t _ip_dst_sizeof  = 4;
00548 
00549     // Offsets for the fields
00550     static const size_t _ip_vhl_offset  = 0;
00551     static const size_t _ip_tos_offset  = _ip_vhl_offset + _ip_vhl_sizeof;
00552     static const size_t _ip_len_offset  = _ip_tos_offset + _ip_tos_sizeof;
00553     static const size_t _ip_id_offset   = _ip_len_offset + _ip_len_sizeof;
00554     static const size_t _ip_off_offset  = _ip_id_offset + _ip_id_sizeof;
00555     static const size_t _ip_ttl_offset  = _ip_off_offset + _ip_off_sizeof;
00556     static const size_t _ip_p_offset    = _ip_ttl_offset + _ip_ttl_sizeof;
00557     static const size_t _ip_sum_offset  = _ip_p_offset + _ip_p_sizeof;
00558     static const size_t _ip_src_offset  = _ip_sum_offset + _ip_sum_sizeof;
00559     static const size_t _ip_dst_offset  = _ip_src_offset + _ip_src_sizeof;
00560 
00561 private:
00562     const uint8_t* _data;   // The buffer data
00563 
00564     // Pointers to the fields
00565     const uint8_t* _ip_vhl; // IP version and header length
00566     const uint8_t* _ip_tos; // Type of service
00567     const uint8_t* _ip_len; // Total length
00568     const uint8_t* _ip_id;  // Identification
00569     const uint8_t* _ip_off; // Fragment offset field
00570     const uint8_t* _ip_ttl; // Time to live
00571     const uint8_t* _ip_p;   // Protocol
00572     const uint8_t* _ip_sum; // Checksum
00573     const uint8_t* _ip_src; // Source address
00574     const uint8_t* _ip_dst; // Destination address
00575 };
00576 
00580 class IpHeader4Writer : public IpHeader4 {
00581 public:
00582     IpHeader4Writer(uint8_t* data)
00583     : IpHeader4(data),
00584       _data(data),
00585       _ip_vhl(_data + _ip_vhl_offset),
00586       _ip_tos(_data + _ip_tos_offset),
00587       _ip_len(_data + _ip_len_offset),
00588       _ip_id(_data + _ip_id_offset),
00589       _ip_off(_data + _ip_off_offset),
00590       _ip_ttl(_data + _ip_ttl_offset),
00591       _ip_p(_data + _ip_p_offset),
00592       _ip_sum(_data + _ip_sum_offset),
00593       _ip_src(_data + _ip_src_offset),
00594       _ip_dst(_data + _ip_dst_offset)
00595     {}
00596 
00602     uint8_t* data() { return (_data); }
00603 
00607     void set_ip_vhl(uint8_t v)      { embed_8(_ip_vhl, v); }
00608     void set_ip_tos(uint8_t v)      { embed_8(_ip_tos, v); }
00609     void set_ip_len(uint16_t v)     { embed_16(_ip_len, v); }
00610     void set_ip_id(uint16_t v)      { embed_16(_ip_id, v); }
00611     void set_ip_off(uint16_t v)     { embed_16(_ip_off, v); }
00612     void set_ip_ttl(uint8_t v)      { embed_8(_ip_ttl, v); }
00613     void set_ip_p(uint8_t v)        { embed_8(_ip_p, v); }
00614     void set_ip_sum(uint16_t v)     { embed_16(_ip_sum, v); }
00615     void set_ip_src(const IPv4& v)  { v.copy_out(_ip_src); }
00616     void set_ip_dst(const IPv4& v)  { v.copy_out(_ip_dst); }
00617 
00621     void compute_checksum();
00622 
00623     /*
00624      * A method to embed the ip_len value by storing it in host order.
00625      *
00626      * @param v the ip_len value that will be stored in host order.
00627      */
00628     void set_ip_len_host(uint16_t v)    { embed_host_16(_ip_len, v); }
00629 
00635     void set_ip_version(uint8_t v) {
00636     uint8_t vhl = ((v << 4) | (ip_header_len() >> 2));
00637     set_ip_vhl(vhl);
00638     }
00639 
00645     void set_ip_header_len(uint8_t v) {
00646     uint8_t vhl = ((ip_version() << 4) | (v >> 2));
00647     set_ip_vhl(vhl);
00648     }
00649 
00655     void set_ip_fragment_offset(uint16_t v) {
00656     uint16_t off = v & IpHeader4::FRAGMENT_OFFSET_MASK;
00657     off |= ip_fragment_flags();
00658     set_ip_off(off);
00659     }
00660 
00666     void set_ip_fragment_flags(uint16_t v) {
00667     uint16_t off = v & IpHeader4::FRAGMENT_FLAGS_MASK;
00668     off |= ip_fragment_offset();
00669     set_ip_off(off);
00670     }
00671 
00672 private:
00673     uint8_t* _data;     // The buffer data
00674 
00675     // Pointers to the fields
00676     uint8_t* _ip_vhl;       // IP version and header length
00677     uint8_t* _ip_tos;       // Type of service
00678     uint8_t* _ip_len;       // Total length
00679     uint8_t* _ip_id;        // Identification
00680     uint8_t* _ip_off;       // Fragment offset field
00681     uint8_t* _ip_ttl;       // Time to live
00682     uint8_t* _ip_p;     // Protocol
00683     uint8_t* _ip_sum;       // Checksum
00684     uint8_t* _ip_src;       // Source address
00685     uint8_t* _ip_dst;       // Destination address
00686 };
00687 
00700 class IpHeader6 {
00701 public:
00702     IpHeader6(const uint8_t* data)
00703     : _data(data),
00704       _ip_vtc_flow(_data + _ip_vtc_flow_offset),
00705       _ip_plen(_data + _ip_plen_offset),
00706       _ip_nxt(_data + _ip_nxt_offset),
00707       _ip_hlim(_data + _ip_hlim_offset),
00708       _ip_src(_data + _ip_src_offset),
00709       _ip_dst(_data + _ip_dst_offset)
00710     {
00711     x_static_assert(IpHeader6::SIZE == _ip_vtc_flow_sizeof
00712               + _ip_plen_sizeof + _ip_nxt_sizeof + _ip_hlim_sizeof
00713               + _ip_src_sizeof + _ip_dst_sizeof);
00714     x_static_assert(IpHeader6::SIZE == _ip_dst_offset + _ip_dst_sizeof);
00715     }
00716 
00717     static const size_t SIZE = 40;      // The header size
00718     static const uint8_t IP_VERSION = 6;    // IPv6 version
00719 
00727     static size_t size() { return IpHeader6::SIZE; }
00728 
00734     const uint8_t* data() const { return (_data); }
00735 
00739     uint32_t ip_vtc_flow() const { return extract_32(_ip_vtc_flow); }
00740     uint16_t ip_plen() const    { return extract_16(_ip_plen); }
00741     uint8_t  ip_nxt() const { return extract_8(_ip_nxt); }
00742     uint8_t  ip_hlim() const    { return extract_8(_ip_hlim); }
00743     IPv6     ip_src() const { return IPv6(_ip_src); }
00744     IPv6     ip_dst() const { return IPv6(_ip_dst); }
00745 
00751     uint8_t ip_version() const {
00752     uint32_t v = ip_vtc_flow() & IpHeader6::VERSION_MASK;
00753     return ((v >> IpHeader6::VERSION_SHIFT) & 0x0f);
00754     }
00755 
00761     uint8_t ip_traffic_class() const {
00762     uint32_t tc = ip_vtc_flow() & IpHeader6::TRAFFIC_CLASS_MASK;
00763     return ((tc >> IpHeader6::TRAFFIC_CLASS_SHIFT) & 0xff);
00764     }
00765 
00771     uint32_t ip_flow_label() const {
00772     uint32_t flow = ip_vtc_flow() & IpHeader6::FLOW_LABEL_MASK;
00773     return (flow >> IpHeader6::FLOW_LABEL_SHIFT);
00774     }
00775 
00781     bool is_valid_version() const {
00782     return (ip_version() == IpHeader6::IP_VERSION);
00783     }
00784 
00785 protected:
00786     static const uint32_t VERSION_MASK      = 0xf0000000;
00787     static const uint32_t TRAFFIC_CLASS_MASK    = 0x0ff00000;
00788     static const uint32_t FLOW_LABEL_MASK   = 0x000fffff;
00789     static const size_t   VERSION_SHIFT     = 28;
00790     static const size_t   TRAFFIC_CLASS_SHIFT   = 20;
00791     static const size_t   FLOW_LABEL_SHIFT  = 0;
00792 
00793     // Sizes of the fields
00794     static const size_t _ip_vtc_flow_sizeof = 4;
00795     static const size_t _ip_plen_sizeof     = 2;
00796     static const size_t _ip_nxt_sizeof      = 1;
00797     static const size_t _ip_hlim_sizeof     = 1;
00798     static const size_t _ip_src_sizeof      = 16;
00799     static const size_t _ip_dst_sizeof      = 16;
00800 
00801     // Offsets for the fields
00802     static const size_t _ip_vtc_flow_offset = 0;
00803     static const size_t _ip_plen_offset = _ip_vtc_flow_offset + _ip_vtc_flow_sizeof;
00804     static const size_t _ip_nxt_offset  = _ip_plen_offset + _ip_plen_sizeof;
00805     static const size_t _ip_hlim_offset = _ip_nxt_offset + _ip_nxt_sizeof;
00806     static const size_t _ip_src_offset  = _ip_hlim_offset + _ip_hlim_sizeof;
00807     static const size_t _ip_dst_offset  = _ip_src_offset + _ip_src_sizeof;
00808 
00809 private:
00810     const uint8_t* _data;   // The buffer data
00811 
00812     // Pointers to the fields
00813     const uint8_t* _ip_vtc_flow; // IP version, traffic class and flow label
00814     const uint8_t* _ip_plen;    // Payload length
00815     const uint8_t* _ip_nxt; // Next header
00816     const uint8_t* _ip_hlim;    // Hop limit
00817     const uint8_t* _ip_src; // Source address
00818     const uint8_t* _ip_dst; // Destination address
00819 };
00820 
00824 class IpHeader6Writer : public IpHeader6 {
00825 public:
00826     IpHeader6Writer(uint8_t* data)
00827     : IpHeader6(data),
00828       _data(data),
00829       _ip_vtc_flow(_data + _ip_vtc_flow_offset),
00830       _ip_plen(_data + _ip_plen_offset),
00831       _ip_nxt(_data + _ip_nxt_offset),
00832       _ip_hlim(_data + _ip_hlim_offset),
00833       _ip_src(_data + _ip_src_offset),
00834       _ip_dst(_data + _ip_dst_offset)
00835     {}
00836 
00842     uint8_t* data() { return (_data); }
00843 
00847     void set_ip_vtc_flow(uint32_t v)    { embed_32(_ip_vtc_flow, v); }
00848     void set_ip_plen(uint16_t v)    { embed_16(_ip_plen, v); }
00849     void set_ip_nxt(uint8_t v)      { embed_8(_ip_nxt, v); }
00850     void set_ip_hlim(uint8_t v)     { embed_8(_ip_hlim, v); }
00851     void set_ip_src(const IPv6& v)  { v.copy_out(_ip_src); }
00852     void set_ip_dst(const IPv6& v)  { v.copy_out(_ip_dst); }
00853 
00859     void set_ip_version(uint8_t v) {
00860     uint32_t vtc_flow = ip_vtc_flow() & ~IpHeader6::VERSION_MASK;
00861     uint32_t shifted_v = v;
00862     shifted_v <<= IpHeader6::VERSION_SHIFT;
00863     vtc_flow |= shifted_v;
00864     set_ip_vtc_flow(vtc_flow);
00865     }
00866 
00872     void set_ip_traffic_class(uint8_t v) {
00873     uint32_t vtc_flow = ip_vtc_flow() & ~IpHeader6::TRAFFIC_CLASS_MASK;
00874     uint32_t shifted_v = v;
00875     shifted_v <<= IpHeader6::TRAFFIC_CLASS_SHIFT;
00876     vtc_flow |= shifted_v;
00877     set_ip_vtc_flow(vtc_flow);
00878     }
00879 
00885     void set_ip_flow_label(uint32_t v) {
00886     uint32_t vtc_flow = ip_vtc_flow() & ~IpHeader6::FLOW_LABEL_MASK;
00887     uint32_t shifted_v = v;
00888     shifted_v <<= IpHeader6::FLOW_LABEL_SHIFT;
00889     vtc_flow |= shifted_v;
00890     set_ip_vtc_flow(vtc_flow);
00891     }
00892 
00893 private:
00894     uint8_t* _data;     // The buffer data
00895 
00896     // Pointers to the fields
00897     uint8_t* _ip_vtc_flow;  // IP version, traffic class and flow label
00898     uint8_t* _ip_plen;      // Payload length
00899     uint8_t* _ip_nxt;       // Next header
00900     uint8_t* _ip_hlim;      // Hop limit
00901     uint8_t* _ip_src;       // Source address
00902     uint8_t* _ip_dst;       // Destination address
00903 };
00904 
00908 class BadPacketException : public XorpReasonedException {
00909 public:
00910     BadPacketException(const char* file, size_t line, const string& why = "")
00911         : XorpReasonedException("BadPacketException", file, line, why) {}
00912 };
00913 
00917 class ArpHeader {
00918 public:
00919     enum Op {
00920     ARP_REQUEST = 1,
00921     ARP_REPLY
00922     };
00923     enum HwFmt {
00924     HW_ETHER = 1
00925     };
00926 
00927     ArpHeader();
00928     ArpHeader(const vector<uint8_t>& pkt);
00929 
00938     static void make_gratuitous(vector<uint8_t>& payload, const Mac& mac,
00939                 const IPv4& ip);
00940 
00947     void            set_sender(const Mac& mac, const IPv4& ip);
00948 
00954     void            set_request(const IPv4& ip);
00955 
00962     void            set_reply(const Mac& mac, const IPv4& ip);
00963 
00969     uint32_t            size() const;
00970 
00977     bool            is_request() const;
00978 
00984     IPv4            get_request() const;
00985 
00992     void make_reply(vector<uint8_t>& out, const Mac& mac) const;
00993 
00994 private:
00995     uint16_t    ah_hw_fmt;
00996     uint16_t    ah_proto_fmt;
00997     uint8_t ah_hw_len;
00998     uint8_t ah_proto_len;
00999     uint16_t    ah_op;
01000     uint8_t ah_data_store[6 * 2 + 4 * 2];
01001 } __attribute__((__packed__));
01002 
01003 
01004 #endif // __LIBPROTO_PACKET_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations