package: update version (2.8.0.6)
[sdk/emulator/qemu.git] / slirp / ip6.h
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
35 static 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
40 static 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
56 static 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[(prefix_len + 7) / 8]),
61                &(b->s6_addr[(prefix_len + 7) / 8]),
62                16 - (prefix_len + 7) / 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 */
97 static 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  */
115 struct 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  */
140 struct 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