Back to index

glibc  2.9
Functions
inet6_rth.c File Reference
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip6.h>

Go to the source code of this file.

Functions

socklen_t inet6_rth_space (int type, int segments)
void * inet6_rth_init (void *bp, socklen_t bp_len, int type, int segments)
int inet6_rth_add (void *bp, const struct in6_addr *addr)
int inet6_rth_reverse (const void *in, void *out)
int inet6_rth_segments (const void *bp)
struct in6_addrinet6_rth_getaddr (const void *bp, int index)

Function Documentation

int inet6_rth_add ( void *  bp,
const struct in6_addr addr 
)

Definition at line 87 of file inet6_rth.c.

{
  struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;

  switch (rthdr->ip6r_type)
    {
      struct ip6_rthdr0 *rthdr0;
    case IPV6_RTHDR_TYPE_0:
      rthdr0 = (struct ip6_rthdr0 *) rthdr;

      memcpy (&rthdr0->ip6r0_addr[rthdr0->ip6r0_segleft++],
             addr, sizeof (struct in6_addr));

      return 0;
    }

  return -1;
}
struct in6_addr* inet6_rth_getaddr ( const void *  bp,
int  index 
) [read]

Definition at line 175 of file inet6_rth.c.

{
  struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;

  switch (rthdr->ip6r_type)
    {
       struct ip6_rthdr0 *rthdr0;
    case IPV6_RTHDR_TYPE_0:
      rthdr0 = (struct ip6_rthdr0 *) rthdr;

      if (index >= rthdr0->ip6r0_len * 8 / sizeof (struct in6_addr))
       break;

      return &rthdr0->ip6r0_addr[index];
    }

  return NULL;
}

Here is the call graph for this function:

void* inet6_rth_init ( void *  bp,
socklen_t  bp_len,
int  type,
int  segments 
)

Definition at line 53 of file inet6_rth.c.

{
  struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;

  switch (type)
    {
    case IPV6_RTHDR_TYPE_0:
      /* Make sure the parameters are valid and the buffer is large enough.  */
      if (segments < 0 || segments > 127)
       break;

      socklen_t len = (sizeof (struct ip6_rthdr0)
                     + segments * sizeof (struct in6_addr));
      if (len > bp_len)
       break;

      /* Some implementations seem to initialize the whole memory area.  */
      memset (bp, '\0', len);

      /* Length in units of 8 octets.  */
      rthdr->ip6r_len = segments * sizeof (struct in6_addr) / 8;
      rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
      return bp;
    }

  return NULL;
}
int inet6_rth_reverse ( const void *  in,
void *  out 
)

Definition at line 115 of file inet6_rth.c.

{
  struct ip6_rthdr *in_rthdr = (struct ip6_rthdr *) in;

  switch (in_rthdr->ip6r_type)
    {
      struct ip6_rthdr0 *in_rthdr0;
      struct ip6_rthdr0 *out_rthdr0;
    case IPV6_RTHDR_TYPE_0:
      in_rthdr0 = (struct ip6_rthdr0 *) in;
      out_rthdr0 = (struct ip6_rthdr0 *) out;

      /* Copy header, not the addresses.  The memory regions can overlap.  */
      memmove (out_rthdr0, in_rthdr0, sizeof (struct ip6_rthdr0));

      int total = in_rthdr0->ip6r0_segleft * 8 / sizeof (struct in6_addr);
      for (int i = 0; i < total / 2; ++i)
       {
         /* Remember, IN_RTHDR0 and OUT_RTHDR0 might overlap.  */
         struct in6_addr temp = in_rthdr0->ip6r0_addr[i];
         out_rthdr0->ip6r0_addr[i] = in_rthdr0->ip6r0_addr[total - 1 - i];
         out_rthdr0->ip6r0_addr[total - 1 - i] = temp;
       }
      if (total % 2 != 0 && in != out)
       out_rthdr0->ip6r0_addr[total / 2] = in_rthdr0->ip6r0_addr[total / 2];

      return 0;
    }

  return -1;
}
int inet6_rth_segments ( const void *  bp)

Definition at line 153 of file inet6_rth.c.

{
  struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;

  switch (rthdr->ip6r_type)
    {
    case IPV6_RTHDR_TYPE_0:

      return rthdr->ip6r_len * 8 / sizeof (struct in6_addr);
    }

  return -1;
}
socklen_t inet6_rth_space ( int  type,
int  segments 
)

Definition at line 32 of file inet6_rth.c.

{
  switch (type)
    {
    case IPV6_RTHDR_TYPE_0:
      if (segments < 0 || segments > 127)
       return 0;

      return sizeof (struct ip6_rthdr0) + segments * sizeof (struct in6_addr);
    }

  return 0;
}