netlink/netlink-message.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 05 May 2011 09:28:21 +0200
changeset 66 2fe1f3e576c9
parent 63 model/netlink-message.cc@e89dca438df6
permissions -rw-r--r--
make it somewhat build sanely
mathieu@0
     1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
mathieu@0
     2
/*
mathieu@0
     3
 * Copyright (c) 2008 Liu Jian
mathieu@0
     4
 *
mathieu@0
     5
 * This program is free software; you can redistribute it and/or modify
mathieu@0
     6
 * it under the terms of the GNU General Public License version 2 as
mathieu@0
     7
 * published by the Free Software Foundation;
mathieu@0
     8
 *
mathieu@0
     9
 * This program is distributed in the hope that it will be useful,
mathieu@0
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
mathieu@0
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
mathieu@0
    12
 * GNU General Public License for more details.
mathieu@0
    13
 *
mathieu@0
    14
 * You should have received a copy of the GNU General Public License
mathieu@0
    15
 * along with this program; if not, write to the Free Software
mathieu@0
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
mathieu@0
    17
 *
mathieu@0
    18
 * Author: Liu Jian <liujatp@gmail.com>
mathieu@0
    19
 *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
mathieu@0
    20
 */
mathieu@0
    21
mathieu@0
    22
#include "netlink-message.h"
mathieu@0
    23
#include "ns3/address-utils.h"
mathieu@0
    24
#include "ns3/log.h"
mathieu@0
    25
mathieu@0
    26
NS_LOG_COMPONENT_DEFINE ("NetlinkMessage");
mathieu@0
    27
mathieu@0
    28
namespace ns3 {
mathieu@0
    29
mathieu@0
    30
/***********************************************************************************
mathieu@0
    31
* \ NetlinkMessageHeader
mathieu@0
    32
***********************************************************************************/
mathieu@0
    33
NS_OBJECT_ENSURE_REGISTERED (NetlinkMessageHeader);
mathieu@0
    34
NS_OBJECT_ENSURE_REGISTERED (NetlinkMessage);
mathieu@0
    35
mathieu@0
    36
NetlinkMessageHeader::NetlinkMessageHeader ()
mathieu@0
    37
  : m_nlmsgLen (16),
mathieu@0
    38
    m_nlmsgType (0),
mathieu@0
    39
    m_nlmsgFlags (0),
mathieu@0
    40
    m_nlmsgSeq (0),
mathieu@0
    41
    m_nlmsgPid (0)
mathieu@0
    42
{}
mathieu@0
    43
mathieu@0
    44
NetlinkMessageHeader::NetlinkMessageHeader (uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid)
mathieu@0
    45
  : m_nlmsgLen (16),
mathieu@0
    46
    m_nlmsgType (type),
mathieu@0
    47
    m_nlmsgFlags (flags),
mathieu@0
    48
    m_nlmsgSeq (seq),
mathieu@0
    49
    m_nlmsgPid (pid)
mathieu@0
    50
{}
mathieu@0
    51
mathieu@0
    52
void
mathieu@0
    53
NetlinkMessageHeader::SetMsgLen (uint32_t v)
mathieu@0
    54
{
mathieu@0
    55
  m_nlmsgLen = v;
mathieu@0
    56
}
mathieu@0
    57
void
mathieu@0
    58
NetlinkMessageHeader::SetMsgFlags (uint16_t v)
mathieu@0
    59
{
mathieu@0
    60
  m_nlmsgFlags = v;
mathieu@0
    61
}
mathieu@0
    62
void
mathieu@0
    63
NetlinkMessageHeader::SetMsgType (uint16_t v)
mathieu@0
    64
{
mathieu@0
    65
  m_nlmsgType = v;
mathieu@0
    66
}
mathieu@0
    67
void
mathieu@0
    68
NetlinkMessageHeader::SetMsgSeq (uint32_t v)
mathieu@0
    69
{
mathieu@0
    70
  m_nlmsgSeq = v;
mathieu@0
    71
}
mathieu@0
    72
void
mathieu@0
    73
NetlinkMessageHeader::SetMsgPid (uint32_t v)
mathieu@0
    74
{
mathieu@0
    75
  m_nlmsgPid = v;
mathieu@0
    76
}
mathieu@0
    77
uint16_t
mathieu@0
    78
NetlinkMessageHeader::GetMsgFlags (void) const
mathieu@0
    79
{
mathieu@0
    80
  return m_nlmsgFlags;
mathieu@0
    81
}
mathieu@0
    82
uint32_t 
mathieu@0
    83
NetlinkMessageHeader::GetMsgLen (void) const
mathieu@0
    84
{
mathieu@0
    85
  return m_nlmsgLen;
mathieu@0
    86
}
mathieu@0
    87
uint16_t 
mathieu@0
    88
NetlinkMessageHeader::GetMsgType (void) const
mathieu@0
    89
{
mathieu@0
    90
  return m_nlmsgType;
mathieu@0
    91
}
mathieu@0
    92
uint32_t
mathieu@0
    93
NetlinkMessageHeader::GetMsgSeq (void) const
mathieu@0
    94
{
mathieu@0
    95
  return m_nlmsgSeq;
mathieu@0
    96
}
mathieu@0
    97
uint32_t 
mathieu@0
    98
NetlinkMessageHeader::GetMsgPid (void) const
mathieu@0
    99
{
mathieu@0
   100
  return m_nlmsgPid;
mathieu@0
   101
}
mathieu@0
   102
uint32_t
mathieu@0
   103
NetlinkMessageHeader::GetHeaderSize ()
mathieu@0
   104
{
mathieu@0
   105
  return NETLINK_MSG_HEADER_SIZE;
mathieu@0
   106
}
mathieu@0
   107
uint32_t
mathieu@0
   108
NetlinkMessageHeader::GetPayloadSize (void) const
mathieu@0
   109
{
mathieu@0
   110
  return NETLINK_MSG_ALIGN (m_nlmsgLen - NETLINK_MSG_HEADER_SIZE);
mathieu@0
   111
}
mathieu@0
   112
mathieu@0
   113
TypeId 
mathieu@0
   114
NetlinkMessageHeader::GetTypeId (void)
mathieu@0
   115
{
mathieu@0
   116
  static TypeId tid = TypeId ("ns3::NetlinkMessageHeader")
mathieu@0
   117
    .SetParent<Header> ()
mathieu@0
   118
    .AddConstructor<NetlinkMessageHeader> ()
mathieu@0
   119
    ;
mathieu@0
   120
  return tid;
mathieu@0
   121
}
mathieu@0
   122
TypeId 
mathieu@0
   123
NetlinkMessageHeader::GetInstanceTypeId (void) const
mathieu@0
   124
{
mathieu@0
   125
  return GetTypeId ();
mathieu@0
   126
}
mathieu@0
   127
void 
mathieu@0
   128
NetlinkMessageHeader::Print (std::ostream &os) const
mathieu@0
   129
{
mathieu@0
   130
  os << "NetlinkMessageHeader "
mathieu@0
   131
     << "len: " << m_nlmsgLen << " "
mathieu@0
   132
     << "flags: " << m_nlmsgFlags << " "
mathieu@0
   133
     << "type: " << m_nlmsgType << " "
mathieu@0
   134
     << "seq: " << m_nlmsgSeq << " "
mathieu@0
   135
     << "pid: " << m_nlmsgPid;
mathieu@0
   136
}
mathieu@0
   137
mathieu@0
   138
uint32_t 
mathieu@0
   139
NetlinkMessageHeader::GetSerializedSize (void) const
mathieu@0
   140
{
mathieu@0
   141
  /* this is the size of an nlmsghdr payload. */
mathieu@0
   142
  return NETLINK_MSG_HEADER_SIZE;
mathieu@0
   143
}
mathieu@0
   144
mathieu@0
   145
void
mathieu@0
   146
NetlinkMessageHeader::Serialize (Buffer::Iterator& start) const
mathieu@0
   147
{
mathieu@0
   148
  start.WriteU32 (m_nlmsgLen);
mathieu@0
   149
  start.WriteU16 (m_nlmsgType);
mathieu@0
   150
  start.WriteU16 (m_nlmsgFlags);
mathieu@0
   151
  start.WriteU32 (m_nlmsgSeq);
mathieu@0
   152
  start.WriteU32 (m_nlmsgPid);
mathieu@0
   153
}
mathieu@0
   154
mathieu@0
   155
uint32_t
mathieu@0
   156
NetlinkMessageHeader::Deserialize (Buffer::Iterator& start)
mathieu@0
   157
{
mathieu@0
   158
  m_nlmsgLen = start.ReadU32 ();
mathieu@0
   159
  m_nlmsgType = start.ReadU16 ();
mathieu@0
   160
  m_nlmsgFlags = start.ReadU16 ();
mathieu@0
   161
  m_nlmsgSeq = start.ReadU32 ();
mathieu@0
   162
  m_nlmsgPid = start.ReadU32 ();
mathieu@0
   163
mathieu@0
   164
  return GetSerializedSize ();
mathieu@0
   165
}
mathieu@0
   166
mathieu@0
   167
mathieu@0
   168
mathieu@0
   169
mathieu@0
   170
/***********************************************************************************
mathieu@0
   171
* \ NetlinkMessageError
mathieu@0
   172
***********************************************************************************/
mathieu@0
   173
mathieu@0
   174
NetlinkMessageError::NetlinkMessageError ()
mathieu@0
   175
  : m_error (0)
mathieu@0
   176
{
mathieu@0
   177
}
mathieu@0
   178
NetlinkMessageError::~NetlinkMessageError ()
mathieu@0
   179
{}
mathieu@0
   180
void 
mathieu@0
   181
NetlinkMessageError::SetError (int32_t v)
mathieu@0
   182
{
mathieu@0
   183
  m_error = v;
mathieu@0
   184
}
mathieu@0
   185
int32_t
mathieu@0
   186
NetlinkMessageError::GetError (void) const
mathieu@0
   187
{
mathieu@0
   188
  return m_error;
mathieu@0
   189
}
mathieu@0
   190
void
mathieu@0
   191
NetlinkMessageError::SetMsg (NetlinkMessageHeader v)
mathieu@0
   192
{
mathieu@0
   193
  m_msg = v;
mathieu@0
   194
}
mathieu@0
   195
NetlinkMessageHeader
mathieu@0
   196
NetlinkMessageError::GetMsg (void) const
mathieu@0
   197
{
mathieu@0
   198
  return m_msg;
mathieu@0
   199
}
mathieu@0
   200
mathieu@0
   201
TypeId 
mathieu@0
   202
NetlinkMessageError::GetTypeId (void)
mathieu@0
   203
{
mathieu@0
   204
  static TypeId tid = TypeId ("ns3::NetlinkMessageError")
mathieu@0
   205
    .SetParent<NetlinkPayload> ()
mathieu@0
   206
    .AddConstructor<NetlinkMessageError> ()
mathieu@0
   207
    ;
mathieu@0
   208
  return tid;
mathieu@0
   209
}
mathieu@0
   210
mathieu@0
   211
TypeId 
mathieu@0
   212
NetlinkMessageError::GetInstanceTypeId (void) const
mathieu@0
   213
{
mathieu@0
   214
  return GetTypeId ();
mathieu@0
   215
}
mathieu@0
   216
void 
mathieu@0
   217
NetlinkMessageError::Print (std::ostream &os) const
mathieu@0
   218
{  
mathieu@0
   219
  os << "----NetlinkMessageError "
mathieu@0
   220
     << "error: " << m_error << " "
mathieu@0
   221
     << "msg:( ";
mathieu@0
   222
  m_msg.Print(os);
mathieu@0
   223
  os << " )";
mathieu@0
   224
}
mathieu@0
   225
mathieu@0
   226
uint32_t 
mathieu@0
   227
NetlinkMessageError::GetSerializedSize (void) const
mathieu@0
   228
{
mathieu@0
   229
  /* this is the size of an nlmsgerr payload. */
mathieu@0
   230
  return NETLINK_MSG_ERROR_SIZE;
mathieu@0
   231
}
mathieu@0
   232
mathieu@0
   233
void
mathieu@0
   234
NetlinkMessageError::Serialize (Buffer::Iterator& start) const
mathieu@0
   235
{
mathieu@0
   236
  start.WriteU32 (m_error);
mathieu@0
   237
  m_msg.Serialize (start);
mathieu@0
   238
}
mathieu@0
   239
mathieu@0
   240
uint32_t
mathieu@0
   241
NetlinkMessageError::Deserialize (Buffer::Iterator& start)
mathieu@0
   242
{  
mathieu@0
   243
  m_error = start.ReadU32 ();
mathieu@0
   244
  m_msg.Deserialize (start);
mathieu@0
   245
  
mathieu@0
   246
  return GetSerializedSize ();
mathieu@0
   247
}
mathieu@0
   248
mathieu@0
   249
mathieu@0
   250
mathieu@0
   251
mathieu@0
   252
/***********************************************************************************
mathieu@0
   253
* \ NetlinkMessage
mathieu@0
   254
***********************************************************************************/
mathieu@0
   255
NetlinkMessage::NetlinkMessage ()
mathieu@0
   256
{}
mathieu@0
   257
mathieu@0
   258
void
mathieu@0
   259
NetlinkMessage::SetHeader (NetlinkMessageHeader hdr)
mathieu@0
   260
{
mathieu@0
   261
  m_hdr = hdr;
mathieu@0
   262
}
mathieu@0
   263
NetlinkMessageHeader
mathieu@0
   264
NetlinkMessage::GetHeader (void)const
mathieu@0
   265
{
mathieu@0
   266
  return m_hdr;
mathieu@0
   267
}
mathieu@0
   268
void
mathieu@0
   269
NetlinkMessage::SetGeneralMessage (GeneralMessage genmsg)
mathieu@0
   270
{
mathieu@0
   271
  m_genmsg = genmsg;
mathieu@0
   272
  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + genmsg.GetSerializedSize ());
mathieu@0
   273
}
mathieu@0
   274
void
mathieu@0
   275
NetlinkMessage::SetErrorMessage (NetlinkMessageError errmsg)
mathieu@0
   276
{
mathieu@0
   277
  m_errorMessage = errmsg;
mathieu@0
   278
  m_hdr.SetMsgLen(m_hdr.GetSerializedSize () + errmsg.GetSerializedSize ());
mathieu@0
   279
}
mathieu@0
   280
// the type is one of RTM_NEWLINK,RTM_DELLINK,RTM_GETLINK
mathieu@0
   281
void
mathieu@0
   282
NetlinkMessage::SetInterfaceInfoMessage (InterfaceInfoMessage v)
mathieu@0
   283
{
mathieu@0
   284
  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
mathieu@0
   285
  m_interfaceTemplate = v;
mathieu@0
   286
}
mathieu@0
   287
// the type is one of RTM_NEWADDR,RTM_DELADDR,RTM_GETADDR
mathieu@0
   288
void NetlinkMessage::SetInterfaceAddressMessage (InterfaceAddressMessage v)
mathieu@0
   289
{
mathieu@0
   290
  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
mathieu@0
   291
  m_addressTemplate = v;
mathieu@0
   292
}
mathieu@0
   293
// the type  is one of RTM_NEWROUTE,RTM_DELROUTE,RTM_GETROUTE
mathieu@0
   294
void NetlinkMessage::SetRouteMessage (RouteMessage v)
mathieu@0
   295
{
mathieu@0
   296
  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
mathieu@0
   297
  m_routeTemplate = v;
mathieu@0
   298
}
mathieu@0
   299
GeneralMessage
mathieu@0
   300
NetlinkMessage::GetGeneralMessage (void) const
mathieu@0
   301
{
mathieu@0
   302
  return m_genmsg;
mathieu@0
   303
}
mathieu@0
   304
NetlinkMessageError
mathieu@0
   305
NetlinkMessage::GetErrorMessage (void) const
mathieu@0
   306
{
mathieu@0
   307
  return m_errorMessage;
mathieu@0
   308
}
mathieu@0
   309
InterfaceInfoMessage
mathieu@0
   310
NetlinkMessage::GetInterfaceInfoMessage (void) const
mathieu@0
   311
{
mathieu@0
   312
  return m_interfaceTemplate;
mathieu@0
   313
}
mathieu@0
   314
InterfaceAddressMessage
mathieu@0
   315
NetlinkMessage::GetInterfaceAddressMessage (void) const
mathieu@0
   316
{
mathieu@0
   317
  return m_addressTemplate;
mathieu@0
   318
}
mathieu@0
   319
RouteMessage
mathieu@0
   320
NetlinkMessage::GetRouteMessage (void) const
mathieu@0
   321
{
mathieu@0
   322
  return m_routeTemplate;
mathieu@0
   323
}
mathieu@0
   324
bool
mathieu@0
   325
NetlinkMessage::IsMessageNetlinkControl (uint16_t type)
mathieu@0
   326
{
mathieu@0
   327
  return (type < NETLINK_RTM_BASE);
mathieu@0
   328
}
mathieu@0
   329
bool
mathieu@0
   330
NetlinkMessage::IsMessageNetlinkRoute (uint16_t type)
mathieu@0
   331
{
mathieu@0
   332
  return (type >= NETLINK_RTM_BASE && type < NETLINK_RTM_MAX);
mathieu@0
   333
}
mathieu@0
   334
bool
mathieu@0
   335
NetlinkMessage::IsMessageAddress (uint16_t type)
mathieu@0
   336
{
mathieu@0
   337
  return (type >= NETLINK_RTM_NEWADDR && type <= NETLINK_RTM_GETADDR);
mathieu@0
   338
}
mathieu@0
   339
bool
mathieu@0
   340
NetlinkMessage::IsMessageInterface (uint16_t type)
mathieu@0
   341
{
mathieu@0
   342
  return (type >= NETLINK_RTM_NEWLINK && type <= NETLINK_RTM_SETLINK);
mathieu@0
   343
}
mathieu@0
   344
bool
mathieu@0
   345
NetlinkMessage::IsMessageRoute (uint16_t type)
mathieu@0
   346
{
mathieu@0
   347
  return (type >= NETLINK_RTM_NEWROUTE && type <= NETLINK_RTM_GETROUTE);
mathieu@0
   348
}
mathieu@0
   349
bool
mathieu@0
   350
NetlinkMessage::IsMessageTypeGet (uint16_t type)
mathieu@0
   351
{
mathieu@0
   352
  return ((( type - NETLINK_RTM_BASE)&3) == 2);
mathieu@0
   353
}
mathieu@0
   354
bool
mathieu@0
   355
NetlinkMessage::IsMessageFlagsAck (uint16_t flags)
mathieu@0
   356
{
mathieu@0
   357
  return (flags & NETLINK_MSG_F_ACK) ? true : false;
mathieu@0
   358
}
mathieu@0
   359
bool
mathieu@0
   360
NetlinkMessage::IsMessageFlagsRequest (uint16_t flags)
mathieu@0
   361
{
mathieu@0
   362
  return (flags & NETLINK_MSG_F_REQUEST) ? true : false;
mathieu@0
   363
}
mathieu@0
   364
bool
mathieu@0
   365
NetlinkMessage::IsMessageFlagsDump (uint16_t flags)
mathieu@0
   366
{
mathieu@0
   367
  return (flags & NETLINK_MSG_F_DUMP) ? true : false;
mathieu@0
   368
}
mathieu@0
   369
mathieu@0
   370
NetlinkMessage::operator MultipartNetlinkMessage (void) const
mathieu@0
   371
{
mathieu@0
   372
  MultipartNetlinkMessage multi_nlmsg;
mathieu@0
   373
  multi_nlmsg.AppendMessage (*this);
mathieu@0
   374
  return multi_nlmsg;
mathieu@0
   375
}
mathieu@0
   376
mathieu@0
   377
TypeId 
mathieu@0
   378
NetlinkMessage::GetTypeId (void)
mathieu@0
   379
{
mathieu@0
   380
  static TypeId tid = TypeId ("ns3::NetlinkMessage")
mathieu@0
   381
    .SetParent<Header> ()
mathieu@0
   382
    .AddConstructor<NetlinkMessage> ()
mathieu@0
   383
    ;
mathieu@0
   384
  return tid;
mathieu@0
   385
}
mathieu@0
   386
TypeId 
mathieu@0
   387
NetlinkMessage::GetInstanceTypeId (void) const
mathieu@0
   388
{
mathieu@0
   389
  return GetTypeId ();
mathieu@0
   390
}
mathieu@0
   391
mathieu@0
   392
uint32_t
mathieu@0
   393
NetlinkMessage::GetTotalSize (void) const
mathieu@0
   394
{
mathieu@0
   395
  return NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ());
mathieu@0
   396
}
mathieu@0
   397
mathieu@0
   398
uint32_t
mathieu@0
   399
NetlinkMessage::GetMsgSize (void) const
mathieu@0
   400
{
mathieu@0
   401
  return m_hdr.GetMsgLen ();
mathieu@0
   402
}
mathieu@0
   403
mathieu@0
   404
uint32_t
mathieu@0
   405
NetlinkMessage::GetPayloadSize (void) const
mathieu@0
   406
{
mathieu@0
   407
  return m_hdr.GetPayloadSize ();
mathieu@0
   408
}
mathieu@0
   409
uint16_t
mathieu@0
   410
NetlinkMessage::GetMsgType (void) const
mathieu@0
   411
{
mathieu@0
   412
  return m_hdr.GetMsgType ();
mathieu@0
   413
}
mathieu@0
   414
mathieu@0
   415
uint8_t
mathieu@0
   416
NetlinkMessage::GetFamily(void) const
mathieu@0
   417
{
mathieu@0
   418
  if (IsMessageTypeGet (GetMsgType ()))
mathieu@0
   419
    {
mathieu@0
   420
      NS_LOG_DEBUG ("TypeGetMsg");
mathieu@0
   421
    }
mathieu@0
   422
  if (IsMessageAddress (m_hdr.GetMsgType ()))
mathieu@0
   423
    {
mathieu@0
   424
      return m_addressTemplate.GetFamily ();
mathieu@0
   425
    }
mathieu@0
   426
  else if (IsMessageInterface(m_hdr.GetMsgType ()))
mathieu@0
   427
    {
mathieu@0
   428
      return m_interfaceTemplate.GetFamily ();
mathieu@0
   429
    }
mathieu@0
   430
  else if (IsMessageRoute(m_hdr.GetMsgType ()))
mathieu@0
   431
    {
mathieu@0
   432
      return m_routeTemplate.GetFamily ();
mathieu@0
   433
    }
mathieu@0
   434
  else if (IsMessageFlagsDump (m_hdr.GetMsgFlags ()))
mathieu@0
   435
    {
mathieu@0
   436
      return m_genmsg.GetFamily (); //value is said to be always set to AF_UNSPEC
mathieu@0
   437
    }
mathieu@0
   438
  else
mathieu@0
   439
    {
mathieu@0
   440
      NS_LOG_WARN ("Netlink message type not supported, return AF_UNSPEC");
mathieu@0
   441
      return 0;
mathieu@0
   442
    }
mathieu@0
   443
}
mathieu@0
   444
mathieu@0
   445
void 
mathieu@0
   446
NetlinkMessage::Print (std::ostream &os) const
mathieu@0
   447
{
mathieu@0
   448
  uint16_t type = m_hdr.GetMsgType ();
mathieu@0
   449
mathieu@0
   450
  os << "NetlinkMessage  ";
mathieu@0
   451
  os << " ----Header:(";
mathieu@0
   452
  m_hdr.Print(os);
mathieu@0
   453
  os << ")";
mathieu@0
   454
mathieu@0
   455
  if (type == NETLINK_MSG_DONE )
mathieu@0
   456
    {
mathieu@0
   457
      os << "multipart message ends here";
mathieu@0
   458
    }
mathieu@0
   459
  else if (type == NETLINK_MSG_ERROR )
mathieu@0
   460
    {
mathieu@0
   461
      m_errorMessage.Print (os);
mathieu@0
   462
    }
mathieu@0
   463
  else if (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK)
mathieu@0
   464
    {
mathieu@0
   465
      m_genmsg.Print (os);
mathieu@0
   466
    }  
mathieu@0
   467
  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE)
mathieu@0
   468
    {
mathieu@0
   469
      m_routeTemplate.Print (os);
mathieu@0
   470
    }
mathieu@0
   471
  else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
mathieu@0
   472
    {
mathieu@0
   473
      m_addressTemplate.Print (os);
mathieu@0
   474
    }
mathieu@0
   475
  else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_DELLINK)
mathieu@0
   476
    {
mathieu@0
   477
      m_interfaceTemplate.Print (os);
mathieu@0
   478
    }
mathieu@0
   479
  else
mathieu@0
   480
    {
mathieu@0
   481
      os << "service not supported yet( " << type <<")";
mathieu@0
   482
    }
mathieu@0
   483
}
mathieu@0
   484
uint32_t 
mathieu@0
   485
NetlinkMessage::GetSerializedSize (void) const
mathieu@0
   486
{
mathieu@0
   487
  return NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ());
mathieu@0
   488
}
mathieu@0
   489
mathieu@0
   490
void
mathieu@0
   491
NetlinkMessage::Serialize (Buffer::Iterator& start) const
mathieu@0
   492
{
mathieu@0
   493
  NS_LOG_FUNCTION (this);
mathieu@0
   494
  //  Print (std::cout);
mathieu@0
   495
  uint16_t type = m_hdr.GetMsgType ();
mathieu@0
   496
mathieu@0
   497
  m_hdr.Serialize (start);
mathieu@0
   498
mathieu@0
   499
  if (type == NETLINK_MSG_DONE)
mathieu@0
   500
    {
mathieu@0
   501
      //nothing done
mathieu@0
   502
    }
mathieu@0
   503
  else if (type == NETLINK_MSG_ERROR)
mathieu@0
   504
    {
mathieu@0
   505
      m_errorMessage.Serialize (start);
mathieu@0
   506
    }  
mathieu@0
   507
  else if (NetlinkMessage::IsMessageFlagsDump (m_hdr.GetMsgFlags ()) && 
mathieu@0
   508
           (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK))
mathieu@0
   509
    {
mathieu@0
   510
      m_genmsg.Serialize (start);
mathieu@0
   511
    }  
mathieu@0
   512
  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
mathieu@0
   513
    {
mathieu@0
   514
      m_routeTemplate.Serialize (start);
mathieu@0
   515
    }
mathieu@0
   516
  else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
mathieu@0
   517
    {
mathieu@0
   518
      m_addressTemplate.Serialize (start);
mathieu@0
   519
    }
mathieu@0
   520
  else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_SETLINK)
mathieu@0
   521
    {
mathieu@0
   522
      m_interfaceTemplate.Serialize (start);
mathieu@0
   523
    }
mathieu@0
   524
  else
mathieu@0
   525
    {
mathieu@0
   526
    }  
mathieu@0
   527
}
mathieu@0
   528
mathieu@0
   529
mathieu@0
   530
uint32_t
mathieu@0
   531
NetlinkMessage::Deserialize (Buffer::Iterator&start)
mathieu@0
   532
{
mathieu@0
   533
  uint32_t remaining;
mathieu@0
   534
mathieu@0
   535
  m_hdr.Deserialize (start);
mathieu@0
   536
  remaining = NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ()) - m_hdr.GetSerializedSize ();
mathieu@0
   537
  
mathieu@0
   538
  //Deserialize service module
mathieu@0
   539
  uint16_t type = GetMsgType ();
mathieu@0
   540
  if (remaining)
mathieu@0
   541
    {        
mathieu@0
   542
      if (type == NETLINK_MSG_DONE)
mathieu@0
   543
        {
mathieu@0
   544
          //do nothing
mathieu@0
   545
        }
mathieu@0
   546
      else if (type == NETLINK_MSG_ERROR)
mathieu@0
   547
        {
mathieu@0
   548
          remaining -= m_errorMessage.Deserialize (start);
mathieu@0
   549
        }      
mathieu@0
   550
      else if (NetlinkMessage::IsMessageFlagsDump (m_hdr.GetMsgFlags()) &&
mathieu@0
   551
               (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK))
mathieu@0
   552
        {
mathieu@0
   553
          remaining -= m_genmsg.Deserialize (start, remaining);
mathieu@0
   554
        }
mathieu@0
   555
      else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
mathieu@0
   556
        {
mathieu@0
   557
          remaining -= m_routeTemplate.Deserialize (start, remaining);
mathieu@0
   558
        }
mathieu@0
   559
      else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
mathieu@0
   560
        {
mathieu@0
   561
          remaining -= m_addressTemplate.Deserialize (start, remaining);
mathieu@0
   562
        }
mathieu@0
   563
      else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_SETLINK)
mathieu@0
   564
        {
mathieu@0
   565
          remaining -= m_interfaceTemplate.Deserialize (start, remaining);
mathieu@0
   566
        }
mathieu@0
   567
      else
mathieu@0
   568
        {
mathieu@0
   569
          //do nothing
mathieu@0
   570
        }
mathieu@0
   571
    }
mathieu@0
   572
mathieu@0
   573
  return GetSerializedSize ();
mathieu@0
   574
}
mathieu@0
   575
mathieu@0
   576
mathieu@0
   577
/***********************************************************************************
mathieu@0
   578
* \ MultipartNetlinkMessage
mathieu@0
   579
***********************************************************************************/
mathieu@0
   580
MultipartNetlinkMessage::MultipartNetlinkMessage ()
mathieu@0
   581
{}
mathieu@0
   582
mathieu@0
   583
TypeId 
mathieu@0
   584
MultipartNetlinkMessage::GetTypeId (void)
mathieu@0
   585
{
mathieu@0
   586
  static TypeId tid = TypeId ("ns3::MultipartNetlinkMessage")
mathieu@0
   587
    .SetParent<Header> ()
mathieu@0
   588
    .AddConstructor<MultipartNetlinkMessage> ()
mathieu@0
   589
    ;
mathieu@0
   590
  return tid;
mathieu@0
   591
}
mathieu@0
   592
TypeId 
mathieu@0
   593
MultipartNetlinkMessage::GetInstanceTypeId (void) const
mathieu@0
   594
{
mathieu@0
   595
  return GetTypeId ();
mathieu@0
   596
}
mathieu@0
   597
mathieu@0
   598
void
mathieu@0
   599
MultipartNetlinkMessage::Print (std::ostream &os) const
mathieu@0
   600
{
mathieu@0
   601
  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
mathieu@0
   602
    {
mathieu@0
   603
      m_netlinkMessages[i].Print (os);
mathieu@0
   604
    }
mathieu@0
   605
}
mathieu@0
   606
uint32_t
mathieu@0
   607
MultipartNetlinkMessage::GetSerializedSize (void) const
mathieu@0
   608
{
mathieu@0
   609
  uint32_t len = 0;
mathieu@0
   610
mathieu@0
   611
  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
mathieu@0
   612
    {
mathieu@0
   613
      len +=  m_netlinkMessages[i].GetSerializedSize ();
mathieu@0
   614
    }
mathieu@0
   615
  return len;
mathieu@0
   616
}
mathieu@0
   617
void
mathieu@0
   618
MultipartNetlinkMessage::Serialize (Buffer::Iterator start) const
mathieu@0
   619
{
mathieu@0
   620
  NS_LOG_FUNCTION ("Multi" << this);
mathieu@0
   621
  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
mathieu@0
   622
    {
mathieu@0
   623
      m_netlinkMessages[i].Serialize (start);
mathieu@0
   624
    }
mathieu@0
   625
}
mathieu@0
   626
uint32_t
mathieu@0
   627
MultipartNetlinkMessage::Deserialize (Buffer::Iterator start)
mathieu@0
   628
{
mathieu@0
   629
  while (1)
mathieu@0
   630
    {
mathieu@0
   631
      NetlinkMessage nlmsg;
mathieu@0
   632
      nlmsg.Deserialize (start);
mathieu@0
   633
      AppendMessage (nlmsg);
mathieu@0
   634
mathieu@0
   635
      if (!(nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_MULTI))
mathieu@0
   636
        {
mathieu@0
   637
          break;
mathieu@0
   638
        }
mathieu@0
   639
mathieu@0
   640
      if (nlmsg.GetHeader ().GetMsgType() == NETLINK_MSG_DONE)
mathieu@0
   641
        {
mathieu@0
   642
          break;
mathieu@0
   643
        }
mathieu@0
   644
    }
mathieu@0
   645
  return GetSerializedSize ();
mathieu@0
   646
}
mathieu@0
   647
mathieu@0
   648
void
mathieu@0
   649
MultipartNetlinkMessage::AppendMessage (NetlinkMessage nlmsg)
mathieu@0
   650
{
mathieu@0
   651
  m_netlinkMessages.push_back (nlmsg);
mathieu@0
   652
}
mathieu@0
   653
mathieu@0
   654
void
mathieu@0
   655
MultipartNetlinkMessage::Clear ()
mathieu@0
   656
{
mathieu@0
   657
  m_netlinkMessages.clear ();
mathieu@0
   658
}
mathieu@0
   659
mathieu@0
   660
uint32_t
mathieu@0
   661
MultipartNetlinkMessage::GetNMessages (void) const
mathieu@0
   662
{
mathieu@0
   663
  return m_netlinkMessages.size ();
mathieu@0
   664
}
mathieu@0
   665
NetlinkMessage
mathieu@0
   666
MultipartNetlinkMessage::GetMessage (uint32_t index) const
mathieu@0
   667
{
mathieu@0
   668
  NS_ASSERT(index < m_netlinkMessages.size ());
mathieu@0
   669
  return m_netlinkMessages[index];
mathieu@0
   670
}
mathieu@0
   671
mathieu@0
   672
}; // namespace ns3