Click
Loading...
Searching...
No Matches
ip6address.hh
1// -*- related-file-name: "../../lib/ip6address.cc" -*-
2#ifndef CLICK_IP6ADDRESS_HH
3#define CLICK_IP6ADDRESS_HH
4#include <click/string.hh>
5#include <clicknet/ip6.h>
6#include <click/ipaddress.hh>
8#include <functional>
9#if !CLICK_TOOL
10# include <click/packet.hh>
11# include <click/packet_anno.hh>
12#endif
13CLICK_DECLS
14
15class IP6Address { public:
16
17 typedef uninitialized_type uninitialized_t;
18
20 inline IP6Address() {
21 memset(&_addr, 0, sizeof(_addr));
22 }
23
25 explicit inline IP6Address(const unsigned char *x) {
26 memcpy(&_addr, x, sizeof(_addr));
27 }
28
32 explicit inline IP6Address(IPAddress x) {
33 *this = x;
34 }
35
37 explicit IP6Address(const String &x); // "fec0:0:0:1::1"
38
40 explicit inline IP6Address(const struct in6_addr &x)
41 : _addr(x) {
42 }
43
45 explicit inline IP6Address(const struct in_addr &x) {
46 *this = x;
47 }
48
50 inline IP6Address(const uninitialized_type &unused) {
51 (void) unused;
52 }
53
63 static IP6Address make_prefix(int prefix_len);
64
70 static IP6Address make_inverted_prefix(int prefix_len);
71
72 typedef uint32_t (IP6Address::*unspecified_bool_type)() const;
73 inline operator unspecified_bool_type() const;
74
75 operator const struct in6_addr &() const { return _addr; }
76 operator struct in6_addr &() { return _addr; }
77 const struct in6_addr &in6_addr() const { return _addr; }
78 struct in6_addr &in6_addr() { return _addr; }
79
80 unsigned char *data() { return &_addr.s6_addr[0]; }
81 const unsigned char *data() const { return &_addr.s6_addr[0]; }
82 uint16_t *data16() { return (uint16_t *)&_addr.s6_addr[0]; }
83 const uint16_t *data16() const { return (uint16_t *)&_addr.s6_addr[0]; }
84 uint32_t *data32() { return (uint32_t *)&_addr.s6_addr[0]; }
85 const uint32_t *data32() const { return (uint32_t *)&_addr.s6_addr[0]; }
86
87 inline uint32_t hashcode() const;
88
89 int mask_to_prefix_len() const;
90 inline bool matches_prefix(const IP6Address &addr, const IP6Address &mask) const;
91 inline bool mask_as_specific(const IP6Address &) const;
92 static inline IP6Address make_zero() {
93 return IP6Address();
94 }
95
101 bool has_ether_address() const {
102 return _addr.s6_addr[11] == 0xFF && _addr.s6_addr[12] == 0xFE;
103 }
104
108 bool ether_address(EtherAddress &x) const;
109
115 inline bool is_ip4_compatible() const {
116 return data32()[0] == 0 && data32()[1] == 0
117 && data32()[2] == 0;
118 }
119
124 inline bool is_ip4_mapped() const {
125 return data32()[0] == 0 && data32()[1] == 0
126 && data32()[2] == htonl(0x0000FFFFU);
127 }
128
133 inline bool is_multicast() const {
134 return _addr.s6_addr[0] == 0xff;
135 }
136
141 inline bool is_link_local() const {
142 return data32()[0] == htonl(0xfe800000) && data32()[1] == 0;
143 }
144
149 IPAddress ip4_address() const;
150
151 // bool operator==(const IP6Address &, const IP6Address &);
152 // bool operator!=(const IP6Address &, const IP6Address &);
153
154 // IP6Address operator&(const IP6Address &, const IP6Address &);
155 // IP6Address operator|(const IP6Address &, const IP6Address &);
156 // IP6Address operator~(const IP6Address &);
157
158 inline IP6Address &operator&=(const IP6Address &);
159 inline IP6Address &operator&=(const struct in6_addr &);
160 inline IP6Address &operator|=(const IP6Address &);
161 inline IP6Address &operator|=(const struct in6_addr &);
162
163 inline IP6Address &operator=(const struct in6_addr &);
164 inline IP6Address &operator=(const struct in_addr &);
165
166 void unparse(StringAccum &sa) const;
167 String unparse() const;
168 String unparse_expanded() const;
169
170 String s() const { return unparse(); }
171 inline operator String() const CLICK_DEPRECATED;
172
173 typedef const IP6Address &parameter_type;
174
175 private:
176
177 struct in6_addr _addr;
178
179};
180
181inline
182IP6Address::operator unspecified_bool_type() const
183{
184 const uint32_t *ai = data32();
185 return ai[0] || ai[1] || ai[2] || ai[3] ? &IP6Address::hashcode : 0;
186}
187
188inline
189IP6Address::operator String() const
190{
191 return unparse();
192}
193
194inline bool
195operator==(const IP6Address &a, const IP6Address &b)
196{
197 const uint32_t *ai = a.data32(), *bi = b.data32();
198 return ai[0] == bi[0] && ai[1] == bi[1] && ai[2] == bi[2] && ai[3] == bi[3];
199}
200
201inline bool
202operator!=(const IP6Address &a, const IP6Address &b)
203{
204 const uint32_t *ai = a.data32(), *bi = b.data32();
205 return ai[0] != bi[0] || ai[1] != bi[1] || ai[2] != bi[2] || ai[3] != bi[3];
206}
207
208inline StringAccum &
209operator<<(StringAccum &sa, const IP6Address &a) {
210 a.unparse(sa);
211 return sa;
212}
213
214inline bool
215IP6Address::matches_prefix(const IP6Address &addr, const IP6Address &mask) const
216{
217 const uint32_t *xi = data32(), *ai = addr.data32(), *mi = mask.data32();
218 return ((xi[0] ^ ai[0]) & mi[0]) == 0
219 && ((xi[1] ^ ai[1]) & mi[1]) == 0
220 && ((xi[2] ^ ai[2]) & mi[2]) == 0
221 && ((xi[3] ^ ai[3]) & mi[3]) == 0;
222}
223
224inline bool
225IP6Address::mask_as_specific(const IP6Address &mask) const
226{
227 const uint32_t *xi = data32(), *mi = mask.data32();
228 return ((xi[0] & mi[0]) == mi[0] && (xi[1] & mi[1]) == mi[1]
229 && (xi[2] & mi[2]) == mi[2] && (xi[3] & mi[3]) == mi[3]);
230}
231
232inline IP6Address &
233IP6Address::operator&=(const IP6Address &x)
234{
235 uint32_t *ai = data32();
236 const uint32_t *bi = x.data32();
237 ai[0] &= bi[0];
238 ai[1] &= bi[1];
239 ai[2] &= bi[2];
240 ai[3] &= bi[3];
241 return *this;
242}
243
244inline IP6Address &
245IP6Address::operator&=(const struct in6_addr &x)
246{
247 uint32_t *ai = data32();
248 const uint32_t *bi = (uint32_t *)&x.s6_addr[0];
249 ai[0] &= bi[0];
250 ai[1] &= bi[1];
251 ai[2] &= bi[2];
252 ai[3] &= bi[3];
253 return *this;
254}
255
256inline IP6Address &
257IP6Address::operator|=(const IP6Address &x)
258{
259 uint32_t *ai = data32();
260 const uint32_t *bi = x.data32();
261 ai[0] |= bi[0];
262 ai[1] |= bi[1];
263 ai[2] |= bi[2];
264 ai[3] |= bi[3];
265 return *this;
266}
267
268inline IP6Address &
269IP6Address::operator|=(const struct in6_addr &x)
270{
271 uint32_t *ai = data32();
272 const uint32_t *bi = (uint32_t *)&x.s6_addr;
273 ai[0] |= bi[0];
274 ai[1] |= bi[1];
275 ai[2] |= bi[2];
276 ai[3] |= bi[3];
277 return *this;
278}
279
280inline IP6Address
281operator&(const IP6Address &a, const IP6Address &b)
282{
283 const uint32_t *ai = a.data32(), *bi = b.data32();
284 IP6Address result = IP6Address::uninitialized_t();
285 uint32_t *ri = result.data32();
286 ri[0] = ai[0] & bi[0];
287 ri[1] = ai[1] & bi[1];
288 ri[2] = ai[2] & bi[2];
289 ri[3] = ai[3] & bi[3];
290 return result;
291}
292
293inline IP6Address
294operator&(const struct in6_addr &a, const IP6Address &b)
295{
296 const uint32_t *ai = (const uint32_t *)&a.s6_addr[0], *bi = b.data32();
297 IP6Address result = IP6Address::uninitialized_t();
298 uint32_t *ri = result.data32();
299 ri[0] = ai[0] & bi[0];
300 ri[1] = ai[1] & bi[1];
301 ri[2] = ai[2] & bi[2];
302 ri[3] = ai[3] & bi[3];
303 return result;
304}
305
306inline IP6Address
307operator|(const IP6Address &a, const IP6Address &b)
308{
309 const uint32_t *ai = a.data32(), *bi = b.data32();
310 IP6Address result = IP6Address::uninitialized_t();
311 uint32_t *ri = result.data32();
312 ri[0] = ai[0] | bi[0];
313 ri[1] = ai[1] | bi[1];
314 ri[2] = ai[2] | bi[2];
315 ri[3] = ai[3] | bi[3];
316 return result;
317}
318
319inline IP6Address
320operator~(const IP6Address &x)
321{
322 const uint32_t *ai = x.data32();
323 IP6Address result = IP6Address::uninitialized_t();
324 uint32_t *ri = result.data32();
325 ri[0] = ~ai[0];
326 ri[1] = ~ai[1];
327 ri[2] = ~ai[2];
328 ri[3] = ~ai[3];
329 return result;
330}
331
332inline IP6Address &
333IP6Address::operator=(const struct in6_addr &a)
334{
335 _addr = a;
336 return *this;
337}
338
339inline IP6Address &
340IP6Address::operator=(const struct in_addr &a)
341{
342 memset(&_addr, 0, 10);
343 data16()[5] = 0xffff;
344 data32()[3] = a.s_addr;
345 return *this;
346}
347
348inline uint32_t
349IP6Address::hashcode() const
350{
351 return (data32()[2] << 1) + data32()[3];
352}
353
354#if !CLICK_TOOL
355inline const IP6Address &
356DST_IP6_ANNO(Packet *p)
357{
358 return *reinterpret_cast<IP6Address *>(p->anno_u8() + DST_IP6_ANNO_OFFSET);
359}
360
361inline void
362SET_DST_IP6_ANNO(Packet *p, const IP6Address &a)
363{
364 memcpy(p->anno_u8() + DST_IP6_ANNO_OFFSET, a.data(), DST_IP6_ANNO_SIZE);
365}
366
367inline void
368SET_DST_IP6_ANNO(Packet *p, const struct in6_addr &a)
369{
370 memcpy(p->anno_u8() + DST_IP6_ANNO_OFFSET, &a, DST_IP6_ANNO_SIZE);
371}
372#endif
373
374
378 static const char *basic_parse(const String &str, IP6Address &result,
379 const ArgContext &args = blank_args);
380 static bool parse(const String &str, IP6Address &result,
381 const ArgContext &args = blank_args);
382 static bool parse(const String &str, struct in6_addr &result,
383 const ArgContext &args = blank_args) {
384 return parse(str, reinterpret_cast<IP6Address &>(result), args);
385 }
386
387};
388
391class IP6PrefixArg { public:
392 IP6PrefixArg(bool allow_bare_address_ = false)
393 : allow_bare_address(allow_bare_address_) {
394 }
395 bool parse(const String &str, IP6Address &addr, int &prefix_len,
396 const ArgContext &args = blank_args) const;
397 bool parse(const String &str, IP6Address &addr, IP6Address &prefix,
398 const ArgContext &args = blank_args) const;
399 bool parse(const String &str, struct in6_addr &addr, struct in6_addr &prefix,
400 const ArgContext &args = blank_args) const {
401 return parse(str, reinterpret_cast<IP6Address &>(addr),
402 reinterpret_cast<IP6Address &>(prefix), args);
403 }
404 bool allow_bare_address;
405};
406
407static int round_up(int num, int factor)
408{
409 return num + factor - 1 - (num + factor - 1) % factor;
410}
411
412
416template <typename F>
417inline void ip6_follow_eh(const click_ip6* ip6, const unsigned char* end, F fn) {
418 click_ip6_eh* eh = (click_ip6_eh*)(ip6 + 1);
419 uint8_t nxt = ip6->ip6_nxt;
420
421 do {
422 if ((unsigned char*)eh >= end)
423 return;
424 if (!fn(nxt, (unsigned char*)eh))
425 return;
426
427 switch (nxt) {
428 case IP6_EH_HOPBYHOP:
429 case IP6_EH_ROUTING:
430 nxt = eh->nxt;
431 eh = (click_ip6_eh*)(((unsigned char*)eh) + (eh->len * 8 + 8));
432 break;
433 case IP6_EH_AH:
434 nxt = eh->nxt;
435 eh = (click_ip6_eh*)(((unsigned char*)eh) + round_up((eh->len + 2) * 4, 8));
436 break;
437 case IP6_EH_FRAGMENT:
438 nxt = eh->nxt;
439 eh = (click_ip6_eh*)(((unsigned char*)eh) + 8);
440 break;
441 case IP6_EH_NONXT:
442 default:
443 return;
444 }
445
446 } while (1);
447}
448
449
450inline void* ip6_find_header(const click_ip6* ip6, const uint8_t type, const unsigned char* end) {
451 unsigned char* pos = 0;
452 auto fnt = [&pos,type] (const uint8_t next, unsigned char* hdr)
453CLICK_ALWAYS_INLINE
454 -> bool {
455 if (next == type) {
456 pos = hdr;
457 return 0;
458 }
459 return 1;
460 };
461 ip6_follow_eh<decltype(fnt)>(ip6,end,fnt);
462 return pos;
463}
464
465
466template<> struct DefaultArg<IP6Address> : public IP6AddressArg {};
467template<> struct DefaultArg<struct in6_addr> : public IP6AddressArg {};
468template<> struct has_trivial_copy<IP6Address> : public true_type {};
469
470CLICK_ENDDECLS
471#endif
Bitvector operator&(Bitvector a, const Bitvector &b)
Return the bitwise and of two bitvectors.
Definition bitvector.hh:299
Bitvector operator|(Bitvector a, const Bitvector &b)
Return the bitwise or of two bitvectors.
Definition bitvector.hh:305
Argument context class.
Definition args.hh:31
An Ethernet address.
Definition etheraddress.hh:9
Parser class for IPv6 address prefixes.
Definition ip6address.hh:391
An IPv4 address.
Definition ipaddress.hh:16
A network packet.
Definition packet.hh:68
uint8_t * anno_u8()
Return a pointer to the annotation area as uint8_ts.
Definition packet.hh:589
Efficiently build up Strings from pieces.
Definition straccum.hh:28
A string of characters.
Definition string.hh:22
Type wrapper for the constant true.
The EtherAddress type for Ethernet addresses.
The IPAddress type for IPv4 addresses.
The Packet class models packets in Click.
Click's String class.
Parser class for IPv6 addresses.
Definition ip6address.hh:377
Template determining whether T may be copied by memcpy.
Definition type_traits.hh:66