Search Linux Wireless

[RFC 05/11] crda: add new reglib_get_country_alpha2()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This will be used by CRDA to find the alpha2.

Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxxxxxxx>
---
 reglib.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 reglib.h |    3 ++
 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);
 
-- 
1.7.4.15.g7811d

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux