2#ifndef CLICK_IP6ADDRESS_HH
3#define CLICK_IP6ADDRESS_HH
5#include <clicknet/ip6.h>
11# include <click/packet_anno.hh>
15class IP6Address {
public:
17 typedef uninitialized_type uninitialized_t;
21 memset(&_addr, 0,
sizeof(_addr));
25 explicit inline IP6Address(
const unsigned char *x) {
26 memcpy(&_addr, x,
sizeof(_addr));
37 explicit IP6Address(
const String &x);
40 explicit inline IP6Address(
const struct in6_addr &x)
45 explicit inline IP6Address(
const struct in_addr &x) {
50 inline IP6Address(
const uninitialized_type &unused) {
63 static IP6Address make_prefix(
int prefix_len);
70 static IP6Address make_inverted_prefix(
int prefix_len);
72 typedef uint32_t (IP6Address::*unspecified_bool_type)() const;
73 inline operator unspecified_bool_type()
const;
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; }
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]; }
87 inline uint32_t hashcode()
const;
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() {
101 bool has_ether_address()
const {
102 return _addr.s6_addr[11] == 0xFF && _addr.s6_addr[12] == 0xFE;
115 inline bool is_ip4_compatible()
const {
116 return data32()[0] == 0 && data32()[1] == 0
124 inline bool is_ip4_mapped()
const {
125 return data32()[0] == 0 && data32()[1] == 0
126 && data32()[2] == htonl(0x0000FFFFU);
133 inline bool is_multicast()
const {
134 return _addr.s6_addr[0] == 0xff;
141 inline bool is_link_local()
const {
142 return data32()[0] == htonl(0xfe800000) && data32()[1] == 0;
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 &);
163 inline IP6Address &operator=(
const struct in6_addr &);
164 inline IP6Address &operator=(
const struct in_addr &);
168 String unparse_expanded()
const;
170 String s()
const {
return unparse(); }
171 inline operator String() const CLICK_DEPRECATED;
173 typedef const IP6Address ¶meter_type;
177 struct in6_addr _addr;
182IP6Address::operator unspecified_bool_type()
const
184 const uint32_t *ai = data32();
185 return ai[0] || ai[1] || ai[2] || ai[3] ? &IP6Address::hashcode : 0;
189IP6Address::operator
String()
const
195operator==(
const IP6Address &a,
const IP6Address &b)
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];
202operator!=(
const IP6Address &a,
const IP6Address &b)
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];
215IP6Address::matches_prefix(
const IP6Address &addr,
const IP6Address &mask)
const
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;
225IP6Address::mask_as_specific(
const IP6Address &mask)
const
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]);
233IP6Address::operator&=(
const IP6Address &x)
235 uint32_t *ai = data32();
236 const uint32_t *bi = x.data32();
245IP6Address::operator&=(
const struct in6_addr &x)
247 uint32_t *ai = data32();
248 const uint32_t *bi = (uint32_t *)&x.s6_addr[0];
257IP6Address::operator|=(
const IP6Address &x)
259 uint32_t *ai = data32();
260 const uint32_t *bi = x.data32();
269IP6Address::operator|=(
const struct in6_addr &x)
271 uint32_t *ai = data32();
272 const uint32_t *bi = (uint32_t *)&x.s6_addr;
281operator&(
const IP6Address &a,
const IP6Address &b)
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];
294operator&(
const struct in6_addr &a,
const IP6Address &b)
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];
307operator|(
const IP6Address &a,
const IP6Address &b)
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];
320operator~(
const IP6Address &x)
322 const uint32_t *ai = x.data32();
323 IP6Address result = IP6Address::uninitialized_t();
324 uint32_t *ri = result.data32();
333IP6Address::operator=(
const struct in6_addr &a)
340IP6Address::operator=(
const struct in_addr &a)
342 memset(&_addr, 0, 10);
343 data16()[5] = 0xffff;
344 data32()[3] = a.s_addr;
349IP6Address::hashcode()
const
351 return (data32()[2] << 1) + data32()[3];
355inline const IP6Address &
358 return *
reinterpret_cast<IP6Address *
>(p->
anno_u8() + DST_IP6_ANNO_OFFSET);
362SET_DST_IP6_ANNO(
Packet *p,
const IP6Address &a)
364 memcpy(p->
anno_u8() + DST_IP6_ANNO_OFFSET, a.data(), DST_IP6_ANNO_SIZE);
368SET_DST_IP6_ANNO(
Packet *p,
const struct in6_addr &a)
370 memcpy(p->
anno_u8() + DST_IP6_ANNO_OFFSET, &a, DST_IP6_ANNO_SIZE);
378 static const char *basic_parse(
const String &str, IP6Address &result,
380 static bool parse(
const String &str, IP6Address &result,
382 static bool parse(
const String &str,
struct in6_addr &result,
384 return parse(str,
reinterpret_cast<IP6Address &
>(result), args);
393 : allow_bare_address(allow_bare_address_) {
395 bool parse(
const String &str, IP6Address &addr,
int &prefix_len,
397 bool parse(
const String &str, IP6Address &addr, IP6Address &prefix,
399 bool parse(
const String &str,
struct in6_addr &addr,
struct in6_addr &prefix,
401 return parse(str,
reinterpret_cast<IP6Address &
>(addr),
402 reinterpret_cast<IP6Address &
>(prefix), args);
404 bool allow_bare_address;
407static int round_up(
int num,
int factor)
409 return num + factor - 1 - (num + factor - 1) % factor;
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;
422 if ((
unsigned char*)eh >= end)
424 if (!fn(nxt, (
unsigned char*)eh))
428 case IP6_EH_HOPBYHOP:
431 eh = (click_ip6_eh*)(((
unsigned char*)eh) + (eh->len * 8 + 8));
435 eh = (click_ip6_eh*)(((
unsigned char*)eh) + round_up((eh->len + 2) * 4, 8));
437 case IP6_EH_FRAGMENT:
439 eh = (click_ip6_eh*)(((
unsigned char*)eh) + 8);
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)
461 ip6_follow_eh<decltype(fnt)>(ip6,end,fnt);
466template<>
struct DefaultArg<IP6Address> :
public IP6AddressArg {};
467template<>
struct DefaultArg<struct in6_addr> :
public IP6AddressArg {};
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.
Parser class for IPv6 addresses.
Definition ip6address.hh:377
Template determining whether T may be copied by memcpy.
Definition type_traits.hh:66