nbd: Permit simple error to NBD_CMD_BLOCK_STATUS
[qemu/ericb.git] / slirp / src / ip6.h
blob33683c8e2079869509f63441f76f14d71c65485c
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3 * Copyright (c) 2013
4 * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
5 */
7 #ifndef SLIRP_IP6_H
8 #define SLIRP_IP6_H
10 #include <glib.h>
11 #include <string.h>
13 #define ALLNODES_MULTICAST { .s6_addr = \
14 { 0xff, 0x02, 0x00, 0x00,\
15 0x00, 0x00, 0x00, 0x00,\
16 0x00, 0x00, 0x00, 0x00,\
17 0x00, 0x00, 0x00, 0x01 } }
19 #define SOLICITED_NODE_PREFIX { .s6_addr = \
20 { 0xff, 0x02, 0x00, 0x00,\
21 0x00, 0x00, 0x00, 0x00,\
22 0x00, 0x00, 0x00, 0x01,\
23 0xff, 0x00, 0x00, 0x00 } }
25 #define LINKLOCAL_ADDR { .s6_addr = \
26 { 0xfe, 0x80, 0x00, 0x00,\
27 0x00, 0x00, 0x00, 0x00,\
28 0x00, 0x00, 0x00, 0x00,\
29 0x00, 0x00, 0x00, 0x02 } }
31 #define ZERO_ADDR { .s6_addr = \
32 { 0x00, 0x00, 0x00, 0x00,\
33 0x00, 0x00, 0x00, 0x00,\
34 0x00, 0x00, 0x00, 0x00,\
35 0x00, 0x00, 0x00, 0x00 } }
37 static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
39 return memcmp(a, b, sizeof(*a)) == 0;
42 static inline bool in6_equal_net(const struct in6_addr *a,
43 const struct in6_addr *b,
44 int prefix_len)
46 if (memcmp(a, b, prefix_len / 8) != 0) {
47 return 0;
50 if (prefix_len % 8 == 0) {
51 return 1;
54 return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8))
55 == b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
58 static inline bool in6_equal_mach(const struct in6_addr *a,
59 const struct in6_addr *b,
60 int prefix_len)
62 if (memcmp(&(a->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
63 &(b->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
64 16 - DIV_ROUND_UP(prefix_len, 8)) != 0) {
65 return 0;
68 if (prefix_len % 8 == 0) {
69 return 1;
72 return (a->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1))
73 == (b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));
77 #define in6_equal_router(a)\
78 ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
79 && in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len))\
80 || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
81 && in6_equal_mach(a, &slirp->vhost_addr6, 64)))
83 #define in6_equal_dns(a)\
84 ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
85 && in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\
86 || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
87 && in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
89 #define in6_equal_host(a)\
90 (in6_equal_router(a) || in6_equal_dns(a))
92 #define in6_solicitednode_multicast(a)\
93 (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
95 #define in6_zero(a)\
96 (in6_equal(a, &(struct in6_addr)ZERO_ADDR))
98 /* Compute emulated host MAC address from its ipv6 address */
99 static inline void in6_compute_ethaddr(struct in6_addr ip,
100 uint8_t eth[ETH_ALEN])
102 eth[0] = 0x52;
103 eth[1] = 0x56;
104 memcpy(&eth[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2);
108 * Definitions for internet protocol version 6.
109 * Per RFC 2460, December 1998.
111 #define IP6VERSION 6
112 #define IP6_HOP_LIMIT 255
115 * Structure of an internet header, naked of options.
117 struct ip6 {
118 #if G_BYTE_ORDER == G_BIG_ENDIAN
119 uint32_t
120 ip_v:4, /* version */
121 ip_tc_hi:4, /* traffic class */
122 ip_tc_lo:4,
123 ip_fl_hi:4, /* flow label */
124 ip_fl_lo:16;
125 #else
126 uint32_t
127 ip_tc_hi:4,
128 ip_v:4,
129 ip_fl_hi:4,
130 ip_tc_lo:4,
131 ip_fl_lo:16;
132 #endif
133 uint16_t ip_pl; /* payload length */
134 uint8_t ip_nh; /* next header */
135 uint8_t ip_hl; /* hop limit */
136 struct in6_addr ip_src, ip_dst; /* source and dest address */
140 * IPv6 pseudo-header used by upper-layer protocols
142 struct ip6_pseudohdr {
143 struct in6_addr ih_src; /* source internet address */
144 struct in6_addr ih_dst; /* destination internet address */
145 uint32_t ih_pl; /* upper-layer packet length */
146 uint16_t ih_zero_hi; /* zero */
147 uint8_t ih_zero_lo; /* zero */
148 uint8_t ih_nh; /* next header */
152 * We don't want to mark these ip6 structs as packed as they are naturally
153 * correctly aligned; instead assert that there is no stray padding.
154 * If we marked the struct as packed then we would be unable to take
155 * the address of any of the fields in it.
157 G_STATIC_ASSERT(sizeof(struct ip6) == 40);
158 G_STATIC_ASSERT(sizeof(struct ip6_pseudohdr) == 40);
160 #endif