netlink/netlink-message.h
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 05 May 2011 09:28:21 +0200
changeset 66 2fe1f3e576c9
parent 63 model/netlink-message.h@e89dca438df6
permissions -rw-r--r--
make it somewhat build sanely
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2008 Liu Jian
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Liu Jian <liujatp@gmail.com>
    19  *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
    20  */
    21 
    22 #ifndef NETLINK_MESSAGE_H
    23 #define NETLINK_MESSAGE_H
    24 
    25 #include "ns3/header.h"
    26 #include "ns3/address.h"
    27 #include "netlink-message-route.h"
    28 #include "netlink-attribute.h"
    29 
    30 
    31 namespace ns3 {
    32   class NetlinkPayload;
    33   class GeneralMessage;
    34   class InterfaceAddressMessage;
    35   class InterfaceInfoMessage;
    36   class RouteMessage;
    37   class MultipartNetlinkMessage;
    38 
    39 /**
    40 * \brief The Netlink message structure for an netlink packet
    41 * 
    42 There are three levels to a Netlink message: The general Netlink
    43 message header, the IP service specific template, and the IP service
    44 specific data.
    45 
    46 0                   1                   2                   3
    47 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    48 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    49 |                                                               |
    50 |                   Netlink message header                      |
    51 |                                                               |
    52 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    53 |                                                               |
    54 |                  IP Service Template                          |
    55 |                                                               |
    56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    57 |                                                               |
    58 |                  IP Service specific data in TLVs             |
    59 |                                                               |
    60 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    61 */
    62 
    63   enum NetlinkMessageFlag
    64   {
    65     NETLINK_MSG_F_REQUEST = 1,  // It is request message.
    66     NETLINK_MSG_F_MULTI = 2,    // Multipart message, terminated by NETLINK_MSG_DONE
    67     NETLINK_MSG_F_ACK = 4,      // Reply with ack, with zero or error code
    68     NETLINK_MSG_F_ECHO = 8,     // Echo this request 
    69 
    70     /* Modifiers to Get request */
    71     NETLINK_MSG_F_ROOT = 0x100,        // specify tree root
    72     NETLINK_MSG_F_MATCH = 0x200,       // return all matching
    73     NETLINK_MSG_F_ATOMIC = 0x400,      // atomic Get =
    74     NETLINK_MSG_F_DUMP = (NETLINK_MSG_F_ROOT|NETLINK_MSG_F_MATCH),
    75 
    76     /* Modifiers to NEW request */
    77     NETLINK_MSG_F_REPLACE = 0x100, // Override existing = 
    78     NETLINK_MSG_F_EXCL = 0x200,   // Do not touch, if it exists
    79     NETLINK_MSG_F_CREATE = 0x400,  // Create, if it does not exist
    80     NETLINK_MSG_F_APPEND = 0x800,  // Add to end of list = 
    81   };
    82 
    83   enum NetlinkMessageType
    84   {
    85     NETLINK_MSG_NOOP = 0x1,          // Nothing.
    86     NETLINK_MSG_ERROR = 0x2,         // Error
    87     NETLINK_MSG_DONE = 0x3,          // End of a dump
    88     NETLINK_MSG_OVERRUN = 0x4,       // Data lost
    89     NETLINK_MSG_MIN_TYPE = 0x10,     // < 0x10: reserved control messages
    90   };
    91 
    92 #define NETLINK_MSG_ALIGNTO 4
    93 #define NETLINK_MSG_ALIGN(X)    (((X)+NETLINK_MSG_ALIGNTO-1) & ~(NETLINK_MSG_ALIGNTO-1) )
    94 
    95 class NetlinkMessageHeader : public ObjectBase
    96 {
    97 public:
    98   NetlinkMessageHeader ();
    99   NetlinkMessageHeader (uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid);
   100 
   101   static TypeId GetTypeId (void);
   102   virtual TypeId GetInstanceTypeId (void) const;
   103   void Print (std::ostream &os) const;
   104   uint32_t GetSerializedSize (void) const;
   105   void Serialize (Buffer::Iterator& start) const;
   106   uint32_t Deserialize (Buffer::Iterator& start);
   107 
   108   void SetMsgLen (uint32_t v);
   109   void SetMsgFlags (uint16_t v);
   110   void SetMsgType (uint16_t v);
   111   void SetMsgSeq (uint32_t v);
   112   void SetMsgPid (uint32_t v);
   113   uint32_t GetMsgLen (void) const;
   114   uint16_t GetMsgFlags (void) const;
   115   uint16_t GetMsgType (void) const;
   116   uint32_t GetMsgSeq (void) const;
   117   uint32_t GetMsgPid (void) const;
   118 
   119   static uint32_t GetHeaderSize ();
   120   uint32_t GetPayloadSize (void) const;
   121 
   122 private:
   123   static const uint32_t NETLINK_MSG_HEADER_SIZE = 16; /* size of the nlmsghdr field*/
   124   uint32_t m_nlmsgLen;	/* Length of message including header */
   125   uint16_t m_nlmsgType;	/* Message content */
   126   uint16_t m_nlmsgFlags;	/* Additional flags */
   127   uint32_t m_nlmsgSeq;	/* Sequence number */
   128   uint32_t m_nlmsgPid;	/* Sending process PID */
   129 };
   130 
   131 /**
   132 * \brief The struct nlmsgerr
   133 */
   134 class NetlinkMessageError : public NetlinkPayload
   135 {
   136 public:
   137   NetlinkMessageError ();
   138   virtual ~NetlinkMessageError();
   139 
   140   static TypeId GetTypeId (void);
   141   virtual TypeId GetInstanceTypeId (void) const;
   142   virtual void Serialize (Buffer::Iterator& start) const;
   143   virtual uint32_t Deserialize (Buffer::Iterator& start);
   144   virtual void Print (std::ostream &os) const;
   145   virtual uint32_t GetSerializedSize (void) const;
   146 
   147   void SetError (int32_t v);
   148   int32_t GetError (void) const;
   149   void SetMsg(NetlinkMessageHeader v);
   150   NetlinkMessageHeader GetMsg (void) const;
   151 
   152 private:
   153   static const int NETLINK_MSG_ERROR_SIZE = 20; /* size of the nlmsgerror field*/
   154   int32_t m_error;
   155   NetlinkMessageHeader m_msg;        
   156 };
   157 
   158 
   159 class NetlinkMessage : public ObjectBase
   160 {
   161 public:
   162   NetlinkMessage ();
   163 
   164   static TypeId GetTypeId (void);
   165   TypeId GetInstanceTypeId (void) const;
   166   void Print (std::ostream &os) const;
   167   uint32_t GetSerializedSize (void) const;
   168   void Serialize (Buffer::Iterator& start) const;
   169   uint32_t Deserialize (Buffer::Iterator& start);
   170 
   171   operator MultipartNetlinkMessage (void) const;
   172 
   173   uint32_t GetTotalSize (void) const;  //length of netlink message including padding
   174   uint32_t GetMsgSize (void) const;    //length of netlink message not including padding
   175   uint32_t GetPayloadSize (void) const; //length of message payload
   176   uint16_t GetMsgType (void) const;
   177   uint8_t GetFamily(void) const;
   178 
   179   void SetHeader (NetlinkMessageHeader hdr);
   180   NetlinkMessageHeader GetHeader (void) const;
   181 
   182   //before set message body, should set header first
   183   void SetErrorMessage (NetlinkMessageError errmsg);
   184   void SetGeneralMessage (GeneralMessage genmsg);
   185   void SetInterfaceInfoMessage (InterfaceInfoMessage v);
   186   void SetInterfaceAddressMessage (InterfaceAddressMessage v);
   187   void SetRouteMessage (RouteMessage v);
   188   NetlinkMessageError GetErrorMessage (void) const;
   189   GeneralMessage GetGeneralMessage (void) const;
   190   InterfaceInfoMessage GetInterfaceInfoMessage (void) const;
   191   InterfaceAddressMessage GetInterfaceAddressMessage (void) const;
   192   RouteMessage GetRouteMessage (void) const;
   193 
   194   /**
   195   * \returns true if type was control type, false otherwise.
   196   */
   197   static bool IsMessageNetlinkControl (uint16_t type);
   198   /**
   199   * \returns true if type was netlink route, false otherwise.
   200   */
   201   static bool IsMessageNetlinkRoute (uint16_t type);
   202   static bool IsMessageAddress (uint16_t type);
   203   static bool IsMessageInterface (uint16_t type);
   204   static bool IsMessageRoute (uint16_t type);
   205   /**
   206   * \returns true if type was GETxxx , false otherwise.
   207   */
   208   static bool IsMessageTypeGet (uint16_t type);
   209   /**
   210   * \returns true if flag has ack , false otherwise.
   211   */
   212   static bool IsMessageFlagsAck (uint16_t flags);
   213   /**
   214   * \returns true if flag has request , false otherwise.
   215   */
   216   static bool IsMessageFlagsRequest (uint16_t flags);
   217   /**
   218   * \returns true if flag has dump , false otherwise.
   219   */
   220   static bool IsMessageFlagsDump (uint16_t flags);
   221 
   222 private:
   223   NetlinkMessageHeader m_hdr;
   224 
   225   //only one type of messages below exists in real world application
   226   NetlinkMessageError m_errorMessage;  
   227   GeneralMessage m_genmsg;
   228   InterfaceInfoMessage m_interfaceTemplate;
   229   InterfaceAddressMessage m_addressTemplate;
   230   RouteMessage m_routeTemplate;
   231 };
   232 
   233 class MultipartNetlinkMessage : public Header
   234 {
   235 public:
   236   MultipartNetlinkMessage ();
   237 
   238   static TypeId GetTypeId (void);
   239   virtual TypeId GetInstanceTypeId (void) const;
   240   virtual void Print (std::ostream &os) const;
   241   virtual uint32_t GetSerializedSize (void) const;
   242   virtual void Serialize (Buffer::Iterator start) const;
   243   virtual uint32_t Deserialize (Buffer::Iterator start);
   244 
   245   void AppendMessage (NetlinkMessage nlmsg);
   246   void Clear();
   247   uint32_t GetNMessages (void) const;
   248   NetlinkMessage GetMessage (uint32_t index) const;
   249 
   250 private:
   251   std::vector<NetlinkMessage> m_netlinkMessages;
   252 };
   253 
   254 }; // namespace ns3
   255 
   256 #endif /* NETLINK_MESSAGE_H */