#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <bits/sockaddr.h>
#include <linux/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

struct iovec
  {
    void *iov_base;     /* Pointer to data.  */
    size_t iov_len;     /* Length of data.  */
  };



main()
{

  int status;
  int ret = 0;
  int error;
   struct sockaddr_nl bind_addr;
   int rtnetlink_sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);


    bind_addr.nl_family = AF_NETLINK;
    bind_addr.nl_pad = 0; 
    bind_addr.nl_pid = getpid();
    bind_addr.nl_groups = ~0U;
    
    if (bind(rtnetlink_sk, (struct sockaddr *)&bind_addr,
            sizeof(bind_addr)) < 0) {
        perror("bind");
    }   

  while (1)
    {
      char buf[4096];
      struct iovec iov = { buf, sizeof buf };
      struct sockaddr_nl snl;
      struct msghdr msg = { (void*)&snl, sizeof snl, &iov, 1, NULL, 0, 0};
      struct nlmsghdr *h;

      status = recvmsg (rtnetlink_sk, &msg, 0);

      if (status < 0)
        {
          if (errno == EINTR)
            continue;
          if (errno == EWOULDBLOCK)
            break;
          continue;
        }

      if (status == 0)
        {
          return -1;
        }

      if (msg.msg_namelen != sizeof snl)
        {
          return -1;
        }

      for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, status);
           h = NLMSG_NEXT (h, status))
        {
          /* Finish of reading. */
          if (h->nlmsg_type == NLMSG_DONE)
            return ret;

          /* Error handling. */
          if (h->nlmsg_type == NLMSG_ERROR)
            {
              struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
              if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
                {

					printf("Received error message that to with invalid length\n");
                	return ;
               }

              return ;
            }

          /* OK we received netlink message. */

  		switch (h->nlmsg_type)
    	{
    		case RTM_NEWLINK:
			{
	  			printf("We are in NEWLINK ...\n");
      			break; 
			}
    		case RTM_DELLINK:
			{
	  			printf("We are in DELLINK ...\n");
      			break; 
			}
    		default: 
      		break;
    	} 
	}

      /* After error care. */
      if (msg.msg_flags & MSG_TRUNC)
        {
          continue;
        }
      if (status)
        {
          return -1;
        }
    }
  return ret;
}


