#include <endian.h>
#include <errno.h>
+#include <netinet/in.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <loc/as.h>
#include <loc/database.h>
#include <loc/format.h>
+#include <loc/network.h>
#include <loc/private.h>
#include <loc/stringpool.h>
return 1;
}
+
+// Returns the network at position pos
+static int loc_database_fetch_network(struct loc_database* db, struct loc_network** network, struct in6_addr* address, off_t pos) {
+ if ((size_t)pos >= db->networks_count)
+ return -EINVAL;
+
+ DEBUG(db->ctx, "Fetching network at position %jd\n", pos);
+
+ int r;
+ switch (db->version) {
+ case 0:
+ r = loc_network_new_from_database_v0(db->ctx, network, address, db->networks_v0 + pos);
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (r == 0) {
+ char* string = loc_network_str(*network);
+ DEBUG(db->ctx, "Got network %s\n", string);
+ free(string);
+ }
+
+ return r;
+}
struct loc_network;
int loc_network_new(struct loc_ctx* ctx, struct loc_network** network,
- struct in6_addr start_address, unsigned int prefix);
+ struct in6_addr* start_address, unsigned int prefix);
int loc_network_new_from_string(struct loc_ctx* ctx, struct loc_network** network,
const char* address_string);
struct loc_network* loc_network_ref(struct loc_network* network);
int loc_network_set_asn(struct loc_network* network, uint32_t asn);
int loc_network_to_database_v0(struct loc_network* network, struct loc_database_network_v0* dbobj);
+int loc_network_new_from_database_v0(struct loc_ctx* ctx, struct loc_network** network,
+ struct in6_addr* address, const struct loc_database_network_v0* dbobj);
struct loc_network_tree;
int loc_network_tree_new(struct loc_ctx* ctx, struct loc_network_tree** tree);
}
LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network,
- struct in6_addr address, unsigned int prefix) {
+ struct in6_addr* address, unsigned int prefix) {
// Address cannot be unspecified
if (IN6_IS_ADDR_UNSPECIFIED(&address)) {
DEBUG(ctx, "Start address is unspecified\n");
}
// Validate the prefix
- if (valid_prefix(&address, prefix) != 0) {
+ if (valid_prefix(address, prefix) != 0) {
DEBUG(ctx, "Invalid prefix: %u\n", prefix);
return -EINVAL;
}
n->refcount = 1;
// Store the first address in the network
- n->start_address = make_start_address(&address, prefix);
+ n->start_address = make_start_address(address, prefix);
n->prefix = prefix;
DEBUG(n->ctx, "Network allocated at %p\n", n);
free(buffer);
if (r == 0) {
- r = loc_network_new(ctx, network, start_address, prefix);
+ r = loc_network_new(ctx, network, &start_address, prefix);
}
return r;
return 0;
}
+LOC_EXPORT int loc_network_new_from_database_v0(struct loc_ctx* ctx, struct loc_network** network,
+ struct in6_addr* address, const struct loc_database_network_v0* dbobj) {
+ int r = loc_network_new(ctx, network, address, dbobj->prefix);
+ if (r)
+ return r;
+
+ // Import country code
+ char country_code[3];
+ for (unsigned int i = 0; i < 2; i++) {
+ country_code[i] = dbobj->country_code[i];
+ }
+ country_code[2] = '\0';
+
+ r = loc_network_set_country_code(*network, country_code);
+ if (r)
+ return r;
+
+ // Import ASN
+ r = loc_network_set_asn(*network, be32toh(dbobj->asn));
+ if (r)
+ return r;
+
+ return 0;
+}
+
struct loc_network_tree {
struct loc_ctx* ctx;
int refcount;