Back to index

glibc  2.9
Classes | Functions | Variables
netlinkaccess.h File Reference
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <kernel-features.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

Functions

int __netlink_open (struct netlink_handle *h)
void __netlink_close (struct netlink_handle *h)
void __netlink_free_handle (struct netlink_handle *h)
int __netlink_request (struct netlink_handle *h, int type)

Variables

int __no_netlink_support attribute_hidden

Class Documentation

struct netlink_res

Definition at line 29 of file netlinkaccess.h.

Collaboration diagram for netlink_res:
Class Members
struct netlink_res * next
struct nlmsghdr * nlh
uint32_t seq
size_t size
struct netlink_handle

Definition at line 38 of file netlinkaccess.h.

Collaboration diagram for netlink_handle:
Class Members
struct netlink_res * end_ptr
int fd
struct netlink_res * nlm_list
pid_t pid
uint32_t seq

Function Documentation

void __netlink_close ( struct netlink_handle h)

Definition at line 253 of file ifaddrs.c.

{
  /* Don't modify errno.  */
  INTERNAL_SYSCALL_DECL (err);
  (void) INTERNAL_SYSCALL (close, err, 1, h->fd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void __netlink_free_handle ( struct netlink_handle h)

Definition at line 87 of file ifaddrs.c.

{
  struct netlink_res *ptr;
  int saved_errno = errno;

  ptr = h->nlm_list;
  while (ptr != NULL)
    {
      struct netlink_res *tmpptr;

      tmpptr = ptr->next;
      free (ptr);
      ptr = tmpptr;
    }

  __set_errno (saved_errno);
}

Here is the caller graph for this function:

Definition at line 263 of file ifaddrs.c.

{
  struct sockaddr_nl nladdr;

  h->fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  if (h->fd < 0)
    goto out;

  memset (&nladdr, '\0', sizeof (nladdr));
  nladdr.nl_family = AF_NETLINK;
  if (__bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
    {
    close_and_out:
      __netlink_close (h);
    out:
#if __ASSUME_NETLINK_SUPPORT == 0
      __no_netlink_support = 1;
#endif
      return -1;
    }
  /* Determine the ID the kernel assigned for this netlink connection.
     It is not necessarily the PID if there is more than one socket
     open.  */
  socklen_t addr_len = sizeof (nladdr);
  if (__getsockname (h->fd, (struct sockaddr *) &nladdr, &addr_len) < 0)
    goto close_and_out;
  h->pid = nladdr.nl_pid;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int __netlink_request ( struct netlink_handle h,
int  type 
)

Definition at line 139 of file ifaddrs.c.

{
  struct netlink_res *nlm_next;
  struct sockaddr_nl nladdr;
  struct nlmsghdr *nlmh;
  ssize_t read_len;
  bool done = false;

#ifdef PAGE_SIZE
  /* Help the compiler optimize out the malloc call if PAGE_SIZE
     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
  const size_t buf_size = PAGE_SIZE;
#else
  const size_t buf_size = __getpagesize ();
#endif
  bool use_malloc = false;
  char *buf;

  if (__libc_use_alloca (buf_size))
    buf = alloca (buf_size);
  else
    {
      buf = malloc (buf_size);
      if (buf != NULL)
       use_malloc = true;
      else
       goto out_fail;
    }

  struct iovec iov = { buf, buf_size };

  if (__netlink_sendreq (h, type) < 0)
    goto out_fail;

  while (! done)
    {
      struct msghdr msg =
       {
         (void *) &nladdr, sizeof (nladdr),
         &iov, 1,
         NULL, 0,
         0
       };

      read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
      if (read_len < 0)
       goto out_fail;

      if (nladdr.nl_pid != 0)
       continue;

      if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
       goto out_fail;

      size_t count = 0;
      size_t remaining_len = read_len;
      for (nlmh = (struct nlmsghdr *) buf;
          NLMSG_OK (nlmh, remaining_len);
          nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
       {
         if ((pid_t) nlmh->nlmsg_pid != h->pid
             || nlmh->nlmsg_seq != h->seq)
           continue;

         ++count;
         if (nlmh->nlmsg_type == NLMSG_DONE)
           {
             /* We found the end, leave the loop.  */
             done = true;
             break;
           }
         if (nlmh->nlmsg_type == NLMSG_ERROR)
           {
             struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
             if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
              errno = EIO;
             else
              errno = -nlerr->error;
             goto out_fail;
           }
       }

      /* If there was nothing with the expected nlmsg_pid and nlmsg_seq,
        there is no point to record it.  */
      if (count == 0)
       continue;

      nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
                                          + read_len);
      if (nlm_next == NULL)
       goto out_fail;
      nlm_next->next = NULL;
      nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
      nlm_next->size = read_len;
      nlm_next->seq = h->seq;
      if (h->nlm_list == NULL)
       h->nlm_list = nlm_next;
      else
       h->end_ptr->next = nlm_next;
      h->end_ptr = nlm_next;
    }

  if (use_malloc)
    free (buf);
  return 0;

out_fail:
  if (use_malloc)
    free (buf);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int __no_netlink_support attribute_hidden

Definition at line 25 of file init-first.c.