summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@frijolero.org>2012-01-18 17:04:33 -0800
committerLuis R. Rodriguez <mcgrof@frijolero.org>2012-01-18 17:51:24 -0800
commit7ce0874d14662275c38b50aa9dee7c841b593862 (patch)
treec63fab9042bdebff1942ee1366ee12de5de3c4fa
parent1b201cde7dd9ec708f33098a2468a01104b35784 (diff)
downloadcrda-7ce0874d14662275c38b50aa9dee7c841b593862.tar.gz
crda-7ce0874d14662275c38b50aa9dee7c841b593862.tar.bz2
crda-7ce0874d14662275c38b50aa9dee7c841b593862.zip
crda: add new reglib_get_country_alpha2()
This will be used by CRDA to find the alpha2. Signed-off-by: Luis R. Rodriguez <mcgrof@frijolero.org>
-rw-r--r--reglib.c74
-rw-r--r--reglib.h3
2 files changed, 77 insertions, 0 deletions
diff --git a/reglib.c b/reglib.c
index 0cef7a5..642f907 100644
--- a/reglib.c
+++ b/reglib.c
@@ -7,6 +7,8 @@
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
+#include <stdbool.h>
+#include <unistd.h>
#include <arpa/inet.h> /* ntohl */
@@ -281,3 +283,75 @@ reglib_get_country_idx(unsigned int idx, const char *file)
return rd;
}
+
+struct ieee80211_regdomain *
+reglib_get_country_alpha2(const char *alpha2, 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;
+ unsigned int i;
+ bool found_country = false;
+
+ 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);
+
+ for (i = 0; i < num_countries; i++) {
+ country = countries + i;
+ if (memcmp(country->alpha2, alpha2, 2) == 0) {
+ found_country = 1;
+ break;
+ }
+ }
+
+ if (!found_country)
+ goto out;
+
+ rd = country2rd(db, dblen, country);
+ if (!rd)
+ goto out;
+
+out:
+ close(fd);
+ return rd;
+}
diff --git a/reglib.h b/reglib.h
index ef85fac..d76ec52 100644
--- a/reglib.h
+++ b/reglib.h
@@ -87,6 +87,9 @@ reglib_get_country_idx(unsigned int idx, const char *file);
__rd = reglib_get_country_idx(__idx, __file), \
__idx++)
+struct ieee80211_regdomain *
+reglib_get_country_alpha2(const char *alpha2, const char *file);
+
/* reg helpers */
void print_regdom(struct ieee80211_regdomain *rd);