qemu/slirp/ip6.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013
   3 * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
   4 */
   5
   6#ifndef SLIRP_IP6_H_
   7#define SLIRP_IP6_H_
   8
   9#include "net/eth.h"
  10
  11#define ALLNODES_MULTICAST  { .s6_addr = \
  12                            { 0xff, 0x02, 0x00, 0x00,\
  13                            0x00, 0x00, 0x00, 0x00,\
  14                            0x00, 0x00, 0x00, 0x00,\
  15                            0x00, 0x00, 0x00, 0x01 } }
  16
  17#define SOLICITED_NODE_PREFIX { .s6_addr = \
  18                            { 0xff, 0x02, 0x00, 0x00,\
  19                            0x00, 0x00, 0x00, 0x00,\
  20                            0x00, 0x00, 0x00, 0x01,\
  21                            0xff, 0x00, 0x00, 0x00 } }
  22
  23#define LINKLOCAL_ADDR  { .s6_addr = \
  24                        { 0xfe, 0x80, 0x00, 0x00,\
  25                        0x00, 0x00, 0x00, 0x00,\
  26                        0x00, 0x00, 0x00, 0x00,\
  27                        0x00, 0x00, 0x00, 0x02 } }
  28
  29static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
  30{
  31    return memcmp(a, b, sizeof(*a)) == 0;
  32}
  33
  34static inline bool in6_equal_net(const struct in6_addr *a,
  35                                 const struct in6_addr *b,
  36                                 int prefix_len)
  37{
  38    if (memcmp(a, b, prefix_len / 8) != 0) {
  39        return 0;
  40    }
  41
  42    if (prefix_len % 8 == 0) {
  43        return 1;
  44    }
  45
  46    return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8))
  47        == b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
  48}
  49
  50static inline bool in6_equal_mach(const struct in6_addr *a,
  51                                  const struct in6_addr *b,
  52                                  int prefix_len)
  53{
  54    if (memcmp(&(a->s6_addr[(prefix_len + 7) / 8]),
  55               &(b->s6_addr[(prefix_len + 7) / 8]),
  56               16 - (prefix_len + 7) / 8) != 0) {
  57        return 0;
  58    }
  59
  60    if (prefix_len % 8 == 0) {
  61        return 1;
  62    }
  63
  64    return (a->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1))
  65        == (b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));
  66}
  67
  68
  69#define in6_equal_router(a)\
  70    ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
  71      && in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len))\
  72  || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
  73      && in6_equal_mach(a, &slirp->vhost_addr6, 64)))
  74
  75#define in6_equal_dns(a)\
  76    ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
  77      && in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\
  78  || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
  79      && in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
  80
  81#define in6_equal_host(a)\
  82    (in6_equal_router(a) || in6_equal_dns(a))
  83
  84#define in6_solicitednode_multicast(a)\
  85    (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
  86
  87/* Compute emulated host MAC address from its ipv6 address */
  88static inline void in6_compute_ethaddr(struct in6_addr ip,
  89                                       uint8_t eth[ETH_ALEN])
  90{
  91    eth[0] = 0x52;
  92    eth[1] = 0x56;
  93    memcpy(&eth[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2);
  94}
  95
  96/*
  97 * Definitions for internet protocol version 6.
  98 * Per RFC 2460, December 1998.
  99 */
 100#define IP6VERSION      6
 101#define IP6_HOP_LIMIT 255
 102
 103/*
 104 * Structure of an internet header, naked of options.
 105 */
 106struct ip6 {
 107#ifdef HOST_WORDS_BIGENDIAN
 108    uint32_t
 109        ip_v:4,         /* version */
 110        ip_tc_hi:4,     /* traffic class */
 111        ip_tc_lo:4,
 112        ip_fl_hi:4,     /* flow label */
 113        ip_fl_lo:16;
 114#else
 115    uint32_t
 116        ip_tc_hi:4,
 117        ip_v:4,
 118        ip_fl_hi:4,
 119        ip_tc_lo:4,
 120        ip_fl_lo:16;
 121#endif
 122    uint16_t    ip_pl;               /* payload length */
 123    uint8_t     ip_nh;               /* next header */
 124    uint8_t     ip_hl;               /* hop limit */
 125    struct in6_addr ip_src, ip_dst;  /* source and dest address */
 126} QEMU_PACKED;
 127
 128/*
 129 * IPv6 pseudo-header used by upper-layer protocols
 130 */
 131struct ip6_pseudohdr {
 132    struct      in6_addr ih_src;  /* source internet address */
 133    struct      in6_addr ih_dst;  /* destination internet address */
 134    uint32_t    ih_pl;            /* upper-layer packet length */
 135    uint16_t    ih_zero_hi;       /* zero */
 136    uint8_t     ih_zero_lo;       /* zero */
 137    uint8_t     ih_nh;            /* next header */
 138} QEMU_PACKED;
 139
 140
 141#endif
 142