3.2.2 RoutingTableNewRequest

The following RoutingTableNewRequest class is an example to send a NetlinkRequest for the structure rtmsg to register a new route.
Note:
1. Define your own netlink request C++ class.
2. Add a member variable of NetlinkRouteAttributeRequest<T> which includes a netlink message header and a requst body of type T.
3. Add a member variable of SocketNetlink which can be used as a communication channel to the kernel.
4. Add a member variable of NetlinkReply<T> which includes a netlink message header and ack data from the kernel.
5. Define a contructor to initialize the above two member variables.
6. Define a send method to send your netlink request to the kernel through the SocketNetlink.
7. Define a recv method to receive a reply from the kernel through the SocketNetlink.
8. In main function, create an instance of your request class, and call the send and recv mothods for the instance.

If the second argument gatewayIP address of this program were not known to the host, the kernel would return an nlmsgerr: No such process.
If you tried to add an already registered route again, you would get an nlmsgerr: File exists.



//
// RoutingTableNewRequest.cpp
//Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.

#include <oz++/CommonObject.h>
#include <oz++/Locale.h>
#include <oz++/Exception.h>

#include <oz++/netlink/SocketNetlink.h>
#include <oz++/netlink/RoutingTableMsg.h>
#include <oz++/netlink/NetlinkRouteAttributeRequest.h>
#include <oz++/netlink/NetlinkReply.h>
#include <oz++/netlink/NetlinkMsgError.h>

//Simple program to register a new route through Netlink++ with RTM_NEWROUTE message.
//This program should be run as the root user.

namespace OZ {
    
class RoutingTableNewRequest :public CommonObject {
private:
  NetlinkRouteAttributeRequest<rtmsg> request;
  SocketNetlink              socketNetlink;
  NetlinkReply<rtmsg>        reply;
    
public:
  RoutingTableNewRequest(unsigned char family, __u32 dest, __u32 gateway)
  {     
    NetlinkMsgHeader header(request.head());
    header.type(RTM_NEWROUTE);
    header.flags(NLM_F_CREATE|NLM_F_REQUEST| NLM_F_ACK);
    header.seq(100);
    header.pid(0); 

    RoutingTableMsg body(request.body());
    header.length( NLMSG_LENGTH(body.size()) );
    
    body.family(family); 
    body.table(RT_TABLE_UNSPEC);
    body.dstlen(32);  //Specifiy 32 bits for IPv4. 
    body.srclen(32);
    body.scope(RT_SCOPE_UNIVERSE);
    body.type(RTN_UNICAST);
    body.protocol(RTPROT_UNSPEC);
    body.flags(RTM_F_NOTIFY);
    
    request.addAttribute(RTA_DST,     &dest,   4);
    request.addAttribute(RTA_GATEWAY, &gateway, 4);         
  }

  int send()
  {
    RouteAttributeRequest<rtmsg>& req = request.request();
    size_t length = request.length();
    return socketNetlink.send((const char*)&req, length, 0);   
  }
    
  void recv()
  {
    while (true) {
        
      bzero(&reply, sizeof(reply));
      int n = socketNetlink.recv((char*)&reply, sizeof(reply), 0);
      if (n < 0){
        break;;
      }
        
      NetlinkMsgHeader replyHeader(&reply.head);

      if (replyHeader.isError() ) {
        //You should check the reply from the kernel, it may return success or error.
        NetlinkMsgError error(replyHeader.errorMsg());
        error.display();
        break;
      }
      fflush(stdout);  
    } //while
  }
};
    
}


//
int main(int argc, char* argv[])
{
  if (argc != 3) {
    printf("Usage: %s destIP gatewayIP\n", argv[0]);        
    return 0;
  }
  try {
    __u32 dest    = 0;
    __u32 gateway = 0;
    unsigned char family = AF_INET;
    
    if (inet_pton(family, argv[1], (struct in_addr*)&dest) <= 0) {
        throw IException("Invalid destIP %s", argv[1]);  
    }
    if (inet_pton(family, argv[2], (struct in_addr*)&gateway) <= 0) {
        throw IException("Invalid gatewayIP %s", argv[2]);   
    }

    RoutingTableNewRequest request(family, dest, gateway);
    request.send();
    request.recv();
    
  } catch (Exception& ex) {
    caught(ex);
  }
  return 0;
}



Last modified: 29 Aug 2016

 Last modified: 29 Aug2016

Copyright (c) 2000-2016 Antillia.com ALL RIGHTS RESERVED.