diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | regdbdump.c | 79 | ||||
-rw-r--r-- | reglib.c | 69 | ||||
-rw-r--r-- | reglib.h | 9 |
4 files changed, 83 insertions, 76 deletions
@@ -105,7 +105,7 @@ keys-%.c: utils/key2pub.py $(wildcard $(PUBKEY_DIR)/*.pem) $(NQ) ' Trusted pubkeys:' $(wildcard $(PUBKEY_DIR)/*.pem) $(Q)./utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@ -%.o: %.c regdb.h +%.o: %.c regdb.h reglib.h $(NQ) ' CC ' $@ $(Q)$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< diff --git a/regdbdump.c b/regdbdump.c index 9ba806c..6d4cf56 100644 --- a/regdbdump.c +++ b/regdbdump.c @@ -1,94 +1,23 @@ #include <errno.h> -#include <stdlib.h> #include <stdio.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <arpa/inet.h> /* ntohl */ #include "regdb.h" #include "reglib.h" int main(int argc, char **argv) { - int fd; - struct stat stat; - uint8_t *db; - struct regdb_file_header *header; - struct regdb_file_reg_country *countries; - int dblen, siglen, num_countries, i, r = 0; struct ieee80211_regdomain *rd = NULL; + unsigned int idx = 0; if (argc != 2) { fprintf(stderr, "Usage: %s <filename>\n", argv[0]); return 2; } - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - perror("failed to open db file"); - return 2; - } - - if (fstat(fd, &stat)) { - perror("failed to fstat db file"); - return 2; - } - - dblen = stat.st_size; - - db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0); - if (db == MAP_FAILED) { - perror("failed to mmap db file"); - return 2; - } - - header = crda_get_file_ptr(db, dblen, sizeof(*header), 0); - - if (ntohl(header->magic) != REGDB_MAGIC) { - fprintf(stderr, "Invalid database magic\n"); - return 2; - } - - if (ntohl(header->version) != REGDB_VERSION) { - fprintf(stderr, "Invalid database version\n"); - return 2; - } - - siglen = ntohl(header->signature_length); - /* adjust dblen so later sanity checks don't run into the signature */ - dblen -= siglen; - - if (dblen <= (int)sizeof(*header)) { - fprintf(stderr, "Invalid signature length %d\n", siglen); - return 2; - } - - /* verify signature */ - if (!crda_verify_db_signature(db, dblen, siglen)) - return -EINVAL; - - num_countries = ntohl(header->reg_country_num); - countries = crda_get_file_ptr(db, dblen, - sizeof(struct regdb_file_reg_country) * num_countries, - header->reg_country_ptr); - - for (i = 0; i < num_countries; i++) { - struct regdb_file_reg_country *country = countries + i; - - rd = country2rd(db, dblen, country); - if (!rd) { - r = -ENOMEM; - fprintf(stderr, "Could not covert country " - "(%.2s) to rd\n", country->alpha2); - goto out; - } - + reglib_for_each_country(rd, idx, argv[1]) { print_regdom(rd); free(rd); - rd = NULL; - } -out: - return r; + + return 0; } @@ -3,6 +3,13 @@ #include <arpa/inet.h> #include <sys/types.h> #include <dirent.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <fcntl.h> + +#include <arpa/inet.h> /* ntohl */ + #include "reglib.h" #ifdef USE_OPENSSL @@ -212,3 +219,65 @@ struct ieee80211_regdomain *country2rd(uint8_t *db, int dblen, return rd; } + +struct ieee80211_regdomain * +reglib_get_country_idx(unsigned int idx, const char *file) +{ + int fd; + struct stat stat; + uint8_t *db; + struct regdb_file_header *header; + struct regdb_file_reg_country *countries; + int dblen, siglen, num_countries; + struct ieee80211_regdomain *rd = NULL; + struct regdb_file_reg_country *country; + + fd = open(file, O_RDONLY); + + if (fd < 0) + return NULL; + + if (fstat(fd, &stat)) + return NULL; + + dblen = stat.st_size; + + db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0); + if (db == MAP_FAILED) + return NULL; + + header = crda_get_file_ptr(db, dblen, sizeof(*header), 0); + + if (ntohl(header->magic) != REGDB_MAGIC) + return NULL; + + if (ntohl(header->version) != REGDB_VERSION) + return NULL; + + siglen = ntohl(header->signature_length); + /* adjust dblen so later sanity checks don't run into the signature */ + dblen -= siglen; + + if (dblen <= (int)sizeof(*header)) + return NULL; + + /* verify signature */ + if (!crda_verify_db_signature(db, dblen, siglen)) + return NULL; + + num_countries = ntohl(header->reg_country_num); + countries = crda_get_file_ptr(db, dblen, + sizeof(struct regdb_file_reg_country) * num_countries, + header->reg_country_ptr); + + if (idx >= num_countries) + return NULL; + + country = countries + idx; + + rd = country2rd(db, dblen, country); + if (!rd) + return NULL; + + return rd; +} @@ -78,6 +78,15 @@ int crda_verify_db_signature(uint8_t *db, int dblen, int siglen); struct ieee80211_regdomain *country2rd(uint8_t *db, int dblen, struct regdb_file_reg_country *country); +struct ieee80211_regdomain * +reglib_get_country_idx(unsigned int idx, const char *file); + +#define reglib_for_each_country(__rd, __idx, __file) \ + for (__rd = reglib_get_country_idx(__idx, __file); \ + __rd != NULL; \ + __rd = reglib_get_country_idx(__idx, __file), \ + __idx++) + /* reg helpers */ void print_regdom(struct ieee80211_regdomain *rd); |