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