]> Git Repo - qemu.git/blob - slirp/ip6.h
lm32-softmmu.mak: express dependencies with Kconfig
[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 <glib.h>
10 #include <string.h>
11
12 #define ALLNODES_MULTICAST  { .s6_addr = \
13                             { 0xff, 0x02, 0x00, 0x00,\
14                             0x00, 0x00, 0x00, 0x00,\
15                             0x00, 0x00, 0x00, 0x00,\
16                             0x00, 0x00, 0x00, 0x01 } }
17
18 #define SOLICITED_NODE_PREFIX { .s6_addr = \
19                             { 0xff, 0x02, 0x00, 0x00,\
20                             0x00, 0x00, 0x00, 0x00,\
21                             0x00, 0x00, 0x00, 0x01,\
22                             0xff, 0x00, 0x00, 0x00 } }
23
24 #define LINKLOCAL_ADDR  { .s6_addr = \
25                         { 0xfe, 0x80, 0x00, 0x00,\
26                         0x00, 0x00, 0x00, 0x00,\
27                         0x00, 0x00, 0x00, 0x00,\
28                         0x00, 0x00, 0x00, 0x02 } }
29
30 #define ZERO_ADDR  { .s6_addr = \
31                         { 0x00, 0x00, 0x00, 0x00,\
32                         0x00, 0x00, 0x00, 0x00,\
33                         0x00, 0x00, 0x00, 0x00,\
34                         0x00, 0x00, 0x00, 0x00 } }
35
36 static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
37 {
38     return memcmp(a, b, sizeof(*a)) == 0;
39 }
40
41 static inline bool in6_equal_net(const struct in6_addr *a,
42                                  const struct in6_addr *b,
43                                  int prefix_len)
44 {
45     if (memcmp(a, b, prefix_len / 8) != 0) {
46         return 0;
47     }
48
49     if (prefix_len % 8 == 0) {
50         return 1;
51     }
52
53     return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8))
54         == b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
55 }
56
57 static inline bool in6_equal_mach(const struct in6_addr *a,
58                                   const struct in6_addr *b,
59                                   int prefix_len)
60 {
61     if (memcmp(&(a->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
62                &(b->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
63                16 - DIV_ROUND_UP(prefix_len, 8)) != 0) {
64         return 0;
65     }
66
67     if (prefix_len % 8 == 0) {
68         return 1;
69     }
70
71     return (a->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1))
72         == (b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));
73 }
74
75
76 #define in6_equal_router(a)\
77     ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
78       && in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len))\
79   || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
80       && in6_equal_mach(a, &slirp->vhost_addr6, 64)))
81
82 #define in6_equal_dns(a)\
83     ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
84       && in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\
85   || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
86       && in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
87
88 #define in6_equal_host(a)\
89     (in6_equal_router(a) || in6_equal_dns(a))
90
91 #define in6_solicitednode_multicast(a)\
92     (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
93
94 #define in6_zero(a)\
95     (in6_equal(a, &(struct in6_addr)ZERO_ADDR))
96
97 /* Compute emulated host MAC address from its ipv6 address */
98 static inline void in6_compute_ethaddr(struct in6_addr ip,
99                                        uint8_t eth[ETH_ALEN])
100 {
101     eth[0] = 0x52;
102     eth[1] = 0x56;
103     memcpy(&eth[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2);
104 }
105
106 /*
107  * Definitions for internet protocol version 6.
108  * Per RFC 2460, December 1998.
109  */
110 #define IP6VERSION      6
111 #define IP6_HOP_LIMIT 255
112
113 /*
114  * Structure of an internet header, naked of options.
115  */
116 struct ip6 {
117 #if G_BYTE_ORDER == G_BIG_ENDIAN
118     uint32_t
119         ip_v:4,         /* version */
120         ip_tc_hi:4,     /* traffic class */
121         ip_tc_lo:4,
122         ip_fl_hi:4,     /* flow label */
123         ip_fl_lo:16;
124 #else
125     uint32_t
126         ip_tc_hi:4,
127         ip_v:4,
128         ip_fl_hi:4,
129         ip_tc_lo:4,
130         ip_fl_lo:16;
131 #endif
132     uint16_t    ip_pl;               /* payload length */
133     uint8_t     ip_nh;               /* next header */
134     uint8_t     ip_hl;               /* hop limit */
135     struct in6_addr ip_src, ip_dst;  /* source and dest address */
136 };
137
138 /*
139  * IPv6 pseudo-header used by upper-layer protocols
140  */
141 struct ip6_pseudohdr {
142     struct      in6_addr ih_src;  /* source internet address */
143     struct      in6_addr ih_dst;  /* destination internet address */
144     uint32_t    ih_pl;            /* upper-layer packet length */
145     uint16_t    ih_zero_hi;       /* zero */
146     uint8_t     ih_zero_lo;       /* zero */
147     uint8_t     ih_nh;            /* next header */
148 };
149
150 /*
151  * We don't want to mark these ip6 structs as packed as they are naturally
152  * correctly aligned; instead assert that there is no stray padding.
153  * If we marked the struct as packed then we would be unable to take
154  * the address of any of the fields in it.
155  */
156 G_STATIC_ASSERT(sizeof(struct ip6) == 40);
157 G_STATIC_ASSERT(sizeof(struct ip6_pseudohdr) == 40);
158
159 #endif
This page took 0.029607 seconds and 4 git commands to generate.