Skip to content

Commit

Permalink
Prefix-counter
Browse files Browse the repository at this point in the history
  • Loading branch information
hbn1987 committed Dec 19, 2023
1 parent 0124c78 commit b5f61c1
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 75 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ make
-F # Specifies the seedset file.
-d # Output with the probe type i.e., (Target, Responder, Probe).
-r # Probing rate, 100Kpps by default.
-b # Probe budget, 10M by default.
-b # Probe budget, 100M by default.
-k # Specifies the probe number for each iteration in the heuristic ping.
```

Expand Down
58 changes: 26 additions & 32 deletions scanner/6scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ int main(int argc, char **argv)
Traceroute6 *trace = new Traceroute6(&config, stats);
Strategy *strategy = new Strategy(&config);
trace->unlock();


/* Pre-scan */
if (config.pre_scan) {
Expand Down Expand Up @@ -209,7 +210,8 @@ int main(int argc, char **argv)
} else {
scope_file = get_asfile(scope);
}
readJson(scope_file, stats->prefixes);
vector<string> basicPrefixes;
readJson(scope_file, basicPrefixes);

string type = Tr_Type_String[config.type];
iplist->setkey(config.seed);
Expand All @@ -220,43 +222,33 @@ int main(int argc, char **argv)
stats->mask = 48;
}

for (auto& it : stats->prefixes) {
for (auto& it : basicPrefixes) {
int pos = it.find("/");
it = seed2vec(it.substr(0, pos));
}

while (stats->mask <= 100) {
for (auto& it : stats->prefixes) {
stats->prefix_map.insert(pair<string, int>{it.substr(0, stats->mask/4), 0});
if (stats->prefix_map.size() >= 50000) // Prevent replies from taking up too much memory
break;
for (auto& it : basicPrefixes) {
stats->hashMap.initInsert(it.substr(0, stats->mask/4));
}

strategy->target_generation_heuristic(iplist, stats->prefix_map, stats->mask, config.probes);
strategy->target_generation_heuristic(iplist, stats->hashMap, stats->mask, config.probes);

if (iplist->targets.size())
loop(&config, iplist, trace, stats);
iplist->targets.clear();
iplist->seeded = false;
sleep(1);
cout << "Probing " << stats->prefix_map.size() << " /" << stats->mask << "'s every /" << stats->mask + 4 << " subprefixes with low-byte pattern addresses, budget consumption: " << stats->count << endl;
cout << "Probing " << stats->hashMap.nonEmptyKeyCount() << " /" << stats->mask << "'s every /" << stats->mask + 4 << " subprefixes with low-byte pattern addresses, budget consumption: " << stats->count << endl;

if (stats->count >= config.budget)
break;

cout << "Candicate alias-prefix resolution with mask of " << stats->mask << " ..." << endl;
unordered_map<string, int>::iterator it = stats->prefix_map.begin();
while (it != stats->prefix_map.end()) {
if (it->second > 12*config.probes) { // Response rate of 0.75
for (auto i = 0; i < stats->prefixes.size(); ++i) { // Radical deletion of possible alias prefixes
if (stats->prefixes[i].find(it->first) != string::npos)
stats->prefixes.erase(stats->prefixes.begin() + i);
}
strategy->target_generation_alias(iplist, it->first); // APD
it++;
} else {
stats->prefix_map.erase(it++);
}
vector<string> aliasCandicate;
aliasCandicate = stats->hashMap.traverse(Alias_Threshold*config.probes*16); // Response rate of 0.75
for (auto&it : aliasCandicate) {
string alias_prefix = get_alias(it, stats->mask);
stats->dump_alias(config.alias_out, alias_prefix);
}

if (iplist->targets.size())
Expand All @@ -265,13 +257,11 @@ int main(int argc, char **argv)
iplist->seeded = false;
sleep(1);

for (auto& it : stats->prefix_map) {
if (it.second > 12*config.probes + 8) { // APD, a response rate of more than 8/16 is considered an alias prefix
string alias_prefix = get_alias(it.first, stats->mask);
stats->dump_alias(config.alias_out, alias_prefix);
}
}
stats->prefix_map.clear();
vector<string> acquirePrefxies;
acquirePrefxies = stats->hashMap.acquiredPrefixes();
stats->hashMap.clear();
for (auto& it : acquirePrefxies)
stats->hashMap.initInsert(it);
stats->mask += 4;
}
}
Expand Down Expand Up @@ -519,11 +509,15 @@ int main(int argc, char **argv)
stats->end_time();
cout << "Waiting " << SHUTDOWN_WAIT << "s for outstanding replies..." << endl;
sleep(SHUTDOWN_WAIT);
if(config.pre_scan or config.exp_seed) {
if (config.pre_scan or config.exp_seed) {
float t = (float) tsdiff(&stats->end, &stats->start) / 1000.0;
cout << "Budget consumption: " << (float) stats->count /1000000 << "M, Time cost: " << t << "s, Probing rate: " << (float) stats->count / t << "pps" << endl;
} else if(config.strategy)
stats->dump(config.out);
} else if (config.strategy) {
if (config.strategy != Heuristic)
stats->dump(config.out);
else
stats->dumpHeuristic(config.out);
}

delete iplist;
delete trace;
Expand Down
4 changes: 2 additions & 2 deletions scanner/6scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ std::string get_alias(std::string line, int mask);
#define OUTPUT "./output" // Output folder
#define RATE 100000 // Probing rate
#define TTL 128
#define BUDGET 10000000 // Budget number
#define BUDGET 100000000 // Budget number
#define PREFIXES "prefixes32"

#define Alias_Threshold 0.9
#define Alias_Threshold 0.75

#include "strategy/strategy.h"

Expand Down
18 changes: 8 additions & 10 deletions scanner/icmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,17 @@ void ICMP6::write(FILE ** out, Stats* stats, bool probe_type) {
else if (type == ICMP6_ECHO_REPLY) {
inet_ntop(AF_INET6, scan_target, target, INET6_ADDRSTRLEN);
type_str = "ICMP6_EchoReply_";
}
}

if (is_scan) {
type_str += "withPayload_";
if (stats->strategy == Heuristic) {
string addr = seed2vec(target);
string prefix = addr.substr(0, stats->mask/4);
string hexString = addr.substr(stats->mask/4, 1);
stats->hashMap.insert(prefix, hexString);
}

if (strcmp(src, target) == 0) {
type_str += "Target";
if ((stats->strategy == Scan6) or (stats->strategy == Hit6)) {
Expand All @@ -357,15 +364,6 @@ void ICMP6::write(FILE ** out, Stats* stats, bool probe_type) {
warn("Returning error regional identification %lu", index);
stats->baddst++;
}
} else if (stats->strategy == Heuristic) {
string addr = seed2vec(src);
string prefix = addr.substr(0, stats->mask/4);
unordered_map<string, int>::iterator iter = stats->prefix_map.find(prefix);
if (iter != stats->prefix_map.end())
iter->second++;
if (addr.substr(addr.length()-4) != "abcd" and stats->prefixes.size() <= 1000000) { // If the address is not the pseudorandom address for APD, write it into the hitlist
stats->prefixes.push_back(addr);
}
}
} else
type_str += "Src";
Expand Down
138 changes: 135 additions & 3 deletions scanner/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,138 @@
#include "6scan.h"
#include "strategy/tree.h"

#include <array>
#include <numeric>
#include <string>
#include <sstream>
class FixedSizeHashMap {
public:
FixedSizeHashMap(size_t size) : size_(size), data_(size, std::make_pair("", std::array<int, 16>{})) {}

void initInsert(const std::string& key) {
size_t index = hashFunction(key) % size_;
data_[index] = std::make_pair(key, std::array<int, 16>{});
}

void insert(const std::string& key, const std::string& hexString) {
int digit = std::stoi(hexString, nullptr, 16);

size_t index = hashFunction(key) % size_;
if (data_[index].first == key) {
data_[index].second[digit]++;
}
}

std::vector<std::string> traverse(int threshold) {
std::vector<std::string> alias_candidates;

for (auto& pair : data_) {
int sum = std::accumulate(pair.second.begin(), pair.second.end(), 0);
if (sum >= threshold) {
alias_candidates.push_back(pair.first);
pair.second = std::array<int, 16>{}; // Mark for deletion
}
}

// Remove marked elements using std::remove_if; Radical deletion of possible alias prefixes
data_.erase(std::remove_if(data_.begin(), data_.end(),
[](const auto& pair) { return pair.second == std::array<int, 16>{}; }),
data_.end());

return alias_candidates;
}

std::vector<std::string> acquiredPrefixes() const {
std::string prefix;
std::vector<std::string> Prefixes;
std::stringstream ss;

for (const auto& pair : data_) {
for (auto i = 0; i < 16; ++i) {
if (pair.second[i] > 0 and !pair.first.empty()) {
ss << std::hex << i;
std::string hexString = ss.str();
prefix = pair.first + ss.str();
Prefixes.push_back(prefix);
ss.str(""); // Clear the stringstream
}
}
}

return Prefixes;
}

std::vector<std::string> nonEmptyKeys() const {
std::vector<std::string> keys;
for (const auto& pair : data_) {
if (!pair.first.empty()) {
keys.push_back(pair.first);
}
}
return keys;
}

size_t nonEmptyKeyCount() const {
return std::count_if(data_.begin(), data_.end(),
[](const auto& pair) { return !pair.first.empty(); });
}

void clear() {
data_.clear();
data_.resize(size_, std::make_pair("", std::array<int, 16>{}));
}

//for debug
size_t getDataSize() const {
size_t vectorSize = sizeof(data_);
for (const auto& pair : data_) {
vectorSize += sizeof(pair);
vectorSize += sizeof(std::string) + pair.first.capacity(); // Include string's dynamic memory
vectorSize += sizeof(std::array<int, 16>); // Include std::array's size
}
return vectorSize;
}

//for debug
std::array<int, 16> find(const std::string& key) const {
size_t index = hashFunction(key) % size_;
if (data_[index].first == key) {
return data_[index].second;
} else
return {};
}

// for debug
void printArray(const std::array<int, 16>& value) const {
std::cout << "Array elements: ";
for (int v : value) {
std::cout << v << " ";
}
std::cout << std::endl;
}

private:
//std::hash
size_t hashFunction(const std::string& key) const {
return std::hash<std::string>{}(key);
}

size_t size_;
std::vector<std::pair<std::string, std::array<int, 16>>> data_;
};

class Stats {
public:
int strategy = 0;
int mask;
int mask = 32;
uint64_t count = 0; // number of probes sent
uint64_t baddst = 0; // checksum invalid on destination in response

Node_List nodelist;

std::unordered_map<std::string, int> prefix_map;
std::vector<std::string> prefixes;
// std::unordered_map<std::string, int> prefix_map;
// std::vector<std::string> prefixes;
FixedSizeHashMap hashMap{100000}; // 100K prefixes at most by default

std::unordered_set<std::string> IPv4;

Expand Down Expand Up @@ -62,6 +183,17 @@ class Stats {
fprintf(stdout, "# Time cost: Total %2.2fs, Preparation %2.2fs, Scanning %2.2fs\n", t, m, t-m);
};

void dumpHeuristic(FILE *out) {
float t = (float) tsdiff(&end, &start) / 1000.0;
fprintf(out, "# Budget: %" PRId64 "\n", count);
fprintf(out, "# Probing rate: %2.2fpps\n", (float) count / t);
fprintf(out, "# Time cost: Total %2.2fs\n", t);

fprintf(stdout, "# Budget: %" PRId64 "\n", count);
fprintf(stdout, "# Probing rate: %2.2fpps\n", (float) count / t);
fprintf(stdout, "# Time cost: Total %2.2fs\n", t);
};

void dump_budget(FILE *out) {
fprintf(out, "# Budget consumption: %" PRId64 "\n", count);
}
Expand Down
18 changes: 8 additions & 10 deletions scanner/tcp6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ void TCP6::write(FILE ** out, Stats* stats, bool probe_type) {
if (is_scan) {
type_str += "withPayload_";
inet_ntop(AF_INET6, scan_target, target, INET6_ADDRSTRLEN);
if (stats->strategy == Heuristic) {
string addr = seed2vec(target);
string prefix = addr.substr(0, stats->mask/4);
string hexString = addr.substr(stats->mask/4, 1);
stats->hashMap.insert(prefix, hexString);
}

if (strcmp(src, target) == 0) {
type_str += "Target";
if ((stats->strategy == Scan6) or (stats->strategy == Hit6)) {
Expand All @@ -65,16 +72,7 @@ void TCP6::write(FILE ** out, Stats* stats, bool probe_type) {
warn("Returning error regional identification %lu", index);
stats->baddst++;
}
} else if (stats->strategy == Heuristic) {
string addr = seed2vec(src);
string prefix = addr.substr(0, stats->mask/4);
unordered_map<string, int>::iterator iter = stats->prefix_map.find(prefix);
if (iter != stats->prefix_map.end())
iter->second++;
if (addr.substr(addr.length()-4) != "abcd" and stats->prefixes.size() <= 1000000) { // If the address is not the pseudorandom address, write it into the hitlist
stats->prefixes.push_back(addr);
}
}
}
} else
type_str += "Src";
} else
Expand Down
2 changes: 0 additions & 2 deletions scanner/trace6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Traceroute6::Traceroute6(ScanConfig *_config, Stats *_stats) : Traceroute(_confi
}
inet_ntop(AF_INET6, &source6.sin6_addr, addrstr, INET6_ADDRSTRLEN);
config->set("SourceIP", addrstr, true);

sndsock = raw_sock6(&source6);

pcount = 0;
Expand All @@ -40,7 +39,6 @@ Traceroute6::Traceroute6(ScanConfig *_config, Stats *_stats) : Traceroute(_confi
payload->fingerprint = htonl(0);

payload->instance = config->instance;

pthread_create(&recv_thread, NULL, listener6, this);
/* give listener thread time to startup */
sleep(1);
Expand Down
Loading

0 comments on commit b5f61c1

Please sign in to comment.