-
Notifications
You must be signed in to change notification settings - Fork 13
/
subnet_list.cpp
93 lines (83 loc) · 2.36 KB
/
subnet_list.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "yarrp.h"
#include "subnet_list.h"
SubnetList::SubnetList(uint8_t _maxttl, uint8_t _gran) : maxttl(_maxttl), granularity(_gran) {
addr_count = 0;
current_twentyfour = 0;
current_48 = 0;
current_ttl = 0;
ttlmask_bits = intlog(maxttl);
ttlmask = (1 << ttlmask_bits) - 1;
};
SubnetList::~SubnetList() {
};
void
SubnetList::add_subnet(string s, bool ipv6) {
if (ipv6) {
Subnet6 subnet = Subnet6(s, granularity);
subnets6.push_back(subnet);
current_subnet6 = subnets6.begin();
addr_count += subnet.count() * maxttl;
} else {
Subnet subnet = Subnet(s);
subnets.push_back(subnet);
current_subnet = subnets.begin();
addr_count += subnet.count() * maxttl;
}
}
uint32_t
SubnetList::next_address(struct in6_addr *in, uint8_t * ttl) {
if (current_subnet6 == subnets6.end()) {
return 0;
}
*ttl = current_ttl;
// don't muck w/ the iterator; copy
memcpy(in, current_subnet6->first(), sizeof(struct in6_addr));
/* since we're dividing in /48s:
- increment second word's high 16 bits by current_48
- only increment first word (32bits) if we overflow current_48 16 bits
*/
int word0 = current_48 / 65536;
int word1 = current_48 % 65536;
(*in).s6_addr32[0] += htonl(word0);
(*in).s6_addr32[1] += htonl(word1<<16);
(*in).s6_addr32[3] += htonl(getHost(0));
/*
char output[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, in, output, INET6_ADDRSTRLEN);
cout << "Start: " << output << endl;
*/
if (++current_ttl > maxttl) {
current_ttl = 0;
current_48 += 1;
}
if (current_48 >= (*current_subnet6).count()) {
current_48 = 0;
current_subnet6++;
}
return 1;
}
uint32_t
SubnetList::next_address(struct in_addr *in, uint8_t * ttl) {
if (current_subnet == subnets.end()) {
return 0;
}
in->s_addr = htonl((*current_subnet).first() + (current_twentyfour << 8) + getHost(0));
*ttl = current_ttl;
if (++current_ttl > maxttl) {
current_ttl = 0;
current_twentyfour += 1;
}
if (current_twentyfour >= (*current_subnet).count()) {
current_twentyfour = 0;
current_subnet++;
}
return 1;
}
uint32_t
SubnetList::count() {
return addr_count;
}
uint16_t
SubnetList::getHost(uint8_t * addr) {
return 1;
}