2013-05-31 02:09:37

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 00/40] crda: reglib enhancements

From: "Luis R. Rodriguez" <[email protected]>

I've hinted I've been working towards a regdb regulatory
library. This pushes that idea further as I was inclined
recently to develop a union algorithm and saw we still
had quite a bit of work to be able to share more consistently.

I'll likely be using the intersection code as basis for this
and as such I've cleaned that up and also ran valgrind over
most of the code. I believe I've fixed all reglib memory
related issues the rest of things valgrind bitches about
are due to netlink.

[email protected] ~ $ cat .valgrindrc
--memcheck:leak-check=full
--memcheck:leak-resolution=high
--memcheck:show-reachable=yes
--memcheck:num-callers=50

If this looks OK I'll next start working towards the union
code. The purpose of this is two fold:

Help build regulatory domains out of arbitrary custom
regulatory definitions and to also allow us to build
more thorough world regulatory domains that have passive
scan flags on regulatory rules that are do not fit the
intersection.

Luis R. Rodriguez (40):
crda: make reg_rules_intersect() style match Linux
crda: port over Linux is_valid_reg_rule() change bd05f28e
crda: remove verbose errors out of regdom_intersect()
crda: constify usage of struct ieee80211_regdomain
crda: remove unused BUG_ON() from intersect.c
crda: move regdom_intersect() to reglib
crda: fix regression when using reglib_for_each_country()
crda: move intersection if first attempt failed
crda: do not double count on reglib_for_each_country()
crda: annotate intersection worst case scenerio
crda: fix intersect.c memory management
crda: explicitly munmap() on reglib_get_rd_alpha2()
crda: explicitly close file descriptor and munmap() on failures
crda: separate crda_verify_db_signature() implementations
crda: use gcry_sexp_release() on crda_verify_db_signature()
crda: explicitly use close() and munmap() on reglib_get_rd_alpha2()
crda: use gcry_mpi_release() when using gcry_mpi_scan()
crda: rename world and prev_world on intersect.c
crda: remove verbosity out of intersect.c
crda: rename regdom_intersect() to reglib_intersect_rds()
crda: rename crda_get_file_ptr() to reglib_get_file_ptr()
crda: rename crda_verify_db_signature() to
reglib_verify_db_signature()
crda: rename print_regdom() to reglib_print_regdom()
crda: add regdb_dfs_regions
crda: make print-regdom use internal flags
crda: move reg print helpers to reglib
crda: rename is_world_regdom() to reglib_is_world_regdom()
crda: rename isalpha_upper() to reglib_isalpha_upper()
crda: rename is_alpha2() to reglib_is_alpha2()
crda: rename is_valid_regdom() to reglib_is_valid_regdom()
crda: rename max() to reglib_max()
crda: rename min() to reglib_min()
crda: fix spacing on reglib_for_each_country()
crda: clarify intersect.c only computes an intersection
crda: separate intersecting a full db into a helper
crda: move reglib_intersect_regdb() to reglib
crda: move regdbprint to its own helper
crda: add reglib regdb context helpers:
reglib_(malloc|free)_regdb_ctx()
crda: pass struct reglib_regdb_ctx to country2rd()
crda: make reglib_for_each_country() use the reglib context

Makefile | 4 +-
crda.c | 14 +-
intersect.c | 264 ++---------------------------
print-regdom.c | 81 ---------
regdb.h | 24 ++-
regdbdump.c | 30 +++-
reglib.c | 518 +++++++++++++++++++++++++++++++++++++++++++++-----------
reglib.h | 125 +++++++++++---
8 files changed, 589 insertions(+), 471 deletions(-)
delete mode 100644 print-regdom.c

--
1.7.10.4



2013-05-31 02:10:03

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 06/40] crda: move regdom_intersect() to reglib

From: "Luis R. Rodriguez" <[email protected]>

This will be used later by other code so just share it.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 157 ----------------------------------------------------------
reglib.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
reglib.h | 3 ++
3 files changed, 162 insertions(+), 157 deletions(-)

diff --git a/intersect.c b/intersect.c
index 7352e73..1c00a67 100644
--- a/intersect.c
+++ b/intersect.c
@@ -9,163 +9,6 @@
/* Intersects regulatory domains, this will skip any regulatory marked with
* an alpha2 of '00', which is used to indicate a regulatory domain */

-/* Sanity check on a regulatory rule */
-static int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
-{
- const struct ieee80211_freq_range *freq_range = &rule->freq_range;
- uint32_t freq_diff;
-
- if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0)
- return 0;
-
- if (freq_range->start_freq_khz > freq_range->end_freq_khz)
- return 0;
-
- freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
-
- if (freq_range->end_freq_khz <= freq_range->start_freq_khz ||
- freq_range->max_bandwidth_khz > freq_diff)
- return 0;
-
- return 1;
-}
-
-/* Helper for regdom_intersect(), this does the real
- * mathematical intersection fun */
-static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
- const struct ieee80211_reg_rule *rule2,
- struct ieee80211_reg_rule *intersected_rule)
-{
- const struct ieee80211_freq_range *freq_range1, *freq_range2;
- struct ieee80211_freq_range *freq_range;
- const struct ieee80211_power_rule *power_rule1, *power_rule2;
- struct ieee80211_power_rule *power_rule;
- uint32_t freq_diff;
-
- freq_range1 = &rule1->freq_range;
- freq_range2 = &rule2->freq_range;
- freq_range = &intersected_rule->freq_range;
-
- power_rule1 = &rule1->power_rule;
- power_rule2 = &rule2->power_rule;
- power_rule = &intersected_rule->power_rule;
-
- freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
- freq_range2->start_freq_khz);
- freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
- freq_range2->end_freq_khz);
- freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
- freq_range2->max_bandwidth_khz);
-
- freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
- if (freq_range->max_bandwidth_khz > freq_diff)
- freq_range->max_bandwidth_khz = freq_diff;
-
- power_rule->max_eirp = min(power_rule1->max_eirp,
- power_rule2->max_eirp);
- power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
- power_rule2->max_antenna_gain);
-
- intersected_rule->flags = rule1->flags | rule2->flags;
-
- if (!is_valid_reg_rule(intersected_rule))
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * regdom_intersect - do the intersection between two regulatory domains
- * @rd1: first regulatory domain
- * @rd2: second regulatory domain
- *
- * Use this function to get the intersection between two regulatory domains.
- * Once completed we will mark the alpha2 for the rd as intersected, "98",
- * as no one single alpha2 can represent this regulatory domain.
- *
- * Returns a pointer to the regulatory domain structure which will hold the
- * resulting intersection of rules between rd1 and rd2. We will
- * malloc() this structure for you.
- */
-static struct ieee80211_regdomain *
-regdom_intersect(const struct ieee80211_regdomain *rd1,
- const struct ieee80211_regdomain *rd2)
-{
- int r, size_of_regd;
- unsigned int x, y;
- unsigned int num_rules = 0, rule_idx = 0;
- const struct ieee80211_reg_rule *rule1, *rule2;
- struct ieee80211_reg_rule *intersected_rule;
- struct ieee80211_regdomain *rd;
- /* This is just a dummy holder to help us count */
- struct ieee80211_reg_rule irule;
-
- /* Uses the stack temporarily for counter arithmetic */
- intersected_rule = &irule;
-
- memset(intersected_rule, 0, sizeof(struct ieee80211_reg_rule));
-
- if (!rd1 || !rd2)
- return NULL;
-
- /* First we get a count of the rules we'll need, then we actually
- * build them. This is to so we can malloc() and free() a
- * regdomain once. The reason we use reg_rules_intersect() here
- * is it will return -EINVAL if the rule computed makes no sense.
- * All rules that do check out OK are valid. */
-
- for (x = 0; x < rd1->n_reg_rules; x++) {
- rule1 = &rd1->reg_rules[x];
- for (y = 0; y < rd2->n_reg_rules; y++) {
- rule2 = &rd2->reg_rules[y];
- if (!reg_rules_intersect(rule1, rule2,
- intersected_rule))
- num_rules++;
- memset(intersected_rule, 0,
- sizeof(struct ieee80211_reg_rule));
- }
- }
-
- if (!num_rules)
- return NULL;
-
- size_of_regd = sizeof(struct ieee80211_regdomain) +
- ((num_rules + 1) * sizeof(struct ieee80211_reg_rule));
-
- rd = malloc(size_of_regd);
- if (!rd)
- return NULL;
-
- memset(rd, 0, size_of_regd);
-
- for (x = 0; x < rd1->n_reg_rules; x++) {
- rule1 = &rd1->reg_rules[x];
- for (y = 0; y < rd2->n_reg_rules; y++) {
- rule2 = &rd2->reg_rules[y];
- /* This time around instead of using the stack lets
- * write to the target rule directly saving ourselves
- * a memcpy() */
- intersected_rule = &rd->reg_rules[rule_idx];
- r = reg_rules_intersect(rule1, rule2,
- intersected_rule);
- if (r)
- continue;
- rule_idx++;
- }
- }
-
- if (rule_idx != num_rules) {
- free(rd);
- return NULL;
- }
-
- rd->n_reg_rules = num_rules;
- rd->alpha2[0] = '9';
- rd->alpha2[1] = '9';
-
- return rd;
-}
-
int main(int argc, char **argv)
{
int r = 0;
diff --git a/reglib.c b/reglib.c
index 0b1599b..867e8cf 100644
--- a/reglib.c
+++ b/reglib.c
@@ -359,3 +359,162 @@ out:
close(fd);
return rd;
}
+
+/* Sanity check on a regulatory rule */
+static int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
+{
+ const struct ieee80211_freq_range *freq_range = &rule->freq_range;
+ uint32_t freq_diff;
+
+ if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0)
+ return 0;
+
+ if (freq_range->start_freq_khz > freq_range->end_freq_khz)
+ return 0;
+
+ freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
+
+ if (freq_range->end_freq_khz <= freq_range->start_freq_khz ||
+ freq_range->max_bandwidth_khz > freq_diff)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Helper for regdom_intersect(), this does the real
+ * mathematical intersection fun
+ */
+static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
+ const struct ieee80211_reg_rule *rule2,
+ struct ieee80211_reg_rule *intersected_rule)
+{
+ const struct ieee80211_freq_range *freq_range1, *freq_range2;
+ struct ieee80211_freq_range *freq_range;
+ const struct ieee80211_power_rule *power_rule1, *power_rule2;
+ struct ieee80211_power_rule *power_rule;
+ uint32_t freq_diff;
+
+ freq_range1 = &rule1->freq_range;
+ freq_range2 = &rule2->freq_range;
+ freq_range = &intersected_rule->freq_range;
+
+ power_rule1 = &rule1->power_rule;
+ power_rule2 = &rule2->power_rule;
+ power_rule = &intersected_rule->power_rule;
+
+ freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
+ freq_range2->start_freq_khz);
+ freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
+ freq_range2->end_freq_khz);
+ freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
+ freq_range2->max_bandwidth_khz);
+
+ freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
+ if (freq_range->max_bandwidth_khz > freq_diff)
+ freq_range->max_bandwidth_khz = freq_diff;
+
+ power_rule->max_eirp = min(power_rule1->max_eirp,
+ power_rule2->max_eirp);
+ power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
+ power_rule2->max_antenna_gain);
+
+ intersected_rule->flags = rule1->flags | rule2->flags;
+
+ if (!is_valid_reg_rule(intersected_rule))
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * regdom_intersect - do the intersection between two regulatory domains
+ * @rd1: first regulatory domain
+ * @rd2: second regulatory domain
+ *
+ * Use this function to get the intersection between two regulatory domains.
+ * Once completed we will mark the alpha2 for the rd as intersected, "98",
+ * as no one single alpha2 can represent this regulatory domain.
+ *
+ * Returns a pointer to the regulatory domain structure which will hold the
+ * resulting intersection of rules between rd1 and rd2. We will
+ * malloc() this structure for you.
+ */
+struct ieee80211_regdomain *
+regdom_intersect(const struct ieee80211_regdomain *rd1,
+ const struct ieee80211_regdomain *rd2)
+{
+ int r, size_of_regd;
+ unsigned int x, y;
+ unsigned int num_rules = 0, rule_idx = 0;
+ const struct ieee80211_reg_rule *rule1, *rule2;
+ struct ieee80211_reg_rule *intersected_rule;
+ struct ieee80211_regdomain *rd;
+ /* This is just a dummy holder to help us count */
+ struct ieee80211_reg_rule irule;
+
+ /* Uses the stack temporarily for counter arithmetic */
+ intersected_rule = &irule;
+
+ memset(intersected_rule, 0, sizeof(struct ieee80211_reg_rule));
+
+ if (!rd1 || !rd2)
+ return NULL;
+
+ /* First we get a count of the rules we'll need, then we actually
+ * build them. This is to so we can malloc() and free() a
+ * regdomain once. The reason we use reg_rules_intersect() here
+ * is it will return -EINVAL if the rule computed makes no sense.
+ * All rules that do check out OK are valid. */
+
+ for (x = 0; x < rd1->n_reg_rules; x++) {
+ rule1 = &rd1->reg_rules[x];
+ for (y = 0; y < rd2->n_reg_rules; y++) {
+ rule2 = &rd2->reg_rules[y];
+ if (!reg_rules_intersect(rule1, rule2,
+ intersected_rule))
+ num_rules++;
+ memset(intersected_rule, 0,
+ sizeof(struct ieee80211_reg_rule));
+ }
+ }
+
+ if (!num_rules)
+ return NULL;
+
+ size_of_regd = sizeof(struct ieee80211_regdomain) +
+ ((num_rules + 1) * sizeof(struct ieee80211_reg_rule));
+
+ rd = malloc(size_of_regd);
+ if (!rd)
+ return NULL;
+
+ memset(rd, 0, size_of_regd);
+
+ for (x = 0; x < rd1->n_reg_rules; x++) {
+ rule1 = &rd1->reg_rules[x];
+ for (y = 0; y < rd2->n_reg_rules; y++) {
+ rule2 = &rd2->reg_rules[y];
+ /* This time around instead of using the stack lets
+ * write to the target rule directly saving ourselves
+ * a memcpy() */
+ intersected_rule = &rd->reg_rules[rule_idx];
+ r = reg_rules_intersect(rule1, rule2,
+ intersected_rule);
+ if (r)
+ continue;
+ rule_idx++;
+ }
+ }
+
+ if (rule_idx != num_rules) {
+ free(rd);
+ return NULL;
+ }
+
+ rd->n_reg_rules = num_rules;
+ rd->alpha2[0] = '9';
+ rd->alpha2[1] = '9';
+
+ return rd;
+}
diff --git a/reglib.h b/reglib.h
index e5da38b..b52d717 100644
--- a/reglib.h
+++ b/reglib.h
@@ -87,5 +87,8 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file);

/* reg helpers */
void print_regdom(const struct ieee80211_regdomain *rd);
+struct ieee80211_regdomain *
+regdom_intersect(const struct ieee80211_regdomain *rd1,
+ const struct ieee80211_regdomain *rd2);

#endif
--
1.7.10.4


2013-05-31 02:12:08

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 33/40] crda: fix spacing on reglib_for_each_country()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/reglib.h b/reglib.h
index 8a31e0d..d89fcd5 100644
--- a/reglib.h
+++ b/reglib.h
@@ -76,9 +76,9 @@ int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen);
const struct ieee80211_regdomain *
reglib_get_rd_idx(unsigned int idx, const char *file);

-#define reglib_for_each_country(__rd, __idx, __file) \
+#define reglib_for_each_country(__rd, __idx, __file) \
for (__rd = reglib_get_rd_idx(__idx, __file); \
- __rd != NULL; \
+ __rd != NULL; \
__rd = reglib_get_rd_idx(++__idx, __file)) \

const struct ieee80211_regdomain *
--
1.7.10.4


2013-05-31 02:09:50

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 03/40] crda: remove verbose errors out of regdom_intersect()

From: "Luis R. Rodriguez" <[email protected]>

We want to move this to reglib so nuke all that fluff.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/intersect.c b/intersect.c
index e35f2cc..bd2976f 100644
--- a/intersect.c
+++ b/intersect.c
@@ -110,10 +110,8 @@ static struct ieee80211_regdomain *regdom_intersect(

memset(intersected_rule, 0, sizeof(struct ieee80211_reg_rule));

- if (!rd1 || !rd2) {
- fprintf(stderr, "rd1 or or rd2 is null\n");
+ if (!rd1 || !rd2)
return NULL;
- }

/* First we get a count of the rules we'll need, then we actually
* build them. This is to so we can malloc() and free() a
@@ -133,19 +131,15 @@ static struct ieee80211_regdomain *regdom_intersect(
}
}

- if (!num_rules) {
- fprintf(stderr, "error: num_rules == 0\n");
+ if (!num_rules)
return NULL;
- }

size_of_regd = sizeof(struct ieee80211_regdomain) +
((num_rules + 1) * sizeof(struct ieee80211_reg_rule));

rd = malloc(size_of_regd);
- if (!rd) {
- fprintf(stderr, "no memory left\n");
+ if (!rd)
return NULL;
- }

memset(rd, 0, size_of_regd);

@@ -166,7 +160,6 @@ static struct ieee80211_regdomain *regdom_intersect(
}

if (rule_idx != num_rules) {
- fprintf(stderr, "Error while doing regdom interesection :(\n");
free(rd);
return NULL;
}
--
1.7.10.4


2013-05-31 02:12:12

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 34/40] crda: clarify intersect.c only computes an intersection

From: "Luis R. Rodriguez" <[email protected]>

World regulatory domains should deal with passive scan
flags to account for gaps in the frequency spectrum that
some countries do not rely on but some APs / Cell towers
could be relied upon for determining location.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/intersect.c b/intersect.c
index bc1e63e..baca5f1 100644
--- a/intersect.c
+++ b/intersect.c
@@ -7,7 +7,7 @@
#include "reglib.h"

/* Intersects regulatory domains, this will skip any regulatory marked with
- * an alpha2 of '00', which is used to indicate a regulatory domain */
+ * an alpha2 of '00', which is used to indicate a world regulatory domain */

int main(int argc, char **argv)
{
@@ -67,7 +67,7 @@ int main(int argc, char **argv)
free(prev_rd_intsct);

/* Tada! */
- printf("== World regulatory domain: ==\n");
+ printf("Intersected regulatory domain:\n");
reglib_print_regdom(rd_intsct);

free(rd_intsct);
--
1.7.10.4


2013-05-31 02:10:38

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 12/40] crda: explicitly munmap() on reglib_get_rd_alpha2()

From: "Luis R. Rodriguez" <[email protected]>

Although the region mapped by mmap() is also automatically
unmapped when the process is terminated lets just munmap()
it ourselves to be more tidy.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/reglib.c b/reglib.c
index 867e8cf..bb6f23f 100644
--- a/reglib.c
+++ b/reglib.c
@@ -357,6 +357,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)

out:
close(fd);
+ munmap(db, dblen);
return rd;
}

--
1.7.10.4


2013-05-31 02:09:46

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 02/40] crda: port over Linux is_valid_reg_rule() change bd05f28e

From: "Luis R. Rodriguez" <[email protected]>

This was added upstream:

[email protected] ~/linux-stable (git::master)$ git describe --contains bd05f28e
v2.6.29~3^2~47

commit bd05f28e1a15ae62994fe309a524695fe26dd834
Author: Roel Kluin <[email protected]>
Date: Tue Mar 3 22:55:21 2009 +0100

cfg80211: test before subtraction on unsigned

freq_diff is unsigned, so test before subtraction

Signed-off-by: Roel Kluin <[email protected]>
Signed-off-by: John W. Linville <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/intersect.c b/intersect.c
index aa67dbc..e35f2cc 100644
--- a/intersect.c
+++ b/intersect.c
@@ -30,7 +30,8 @@ static int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)

freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;

- if (freq_diff == 0 || freq_range->max_bandwidth_khz > freq_diff)
+ if (freq_range->end_freq_khz <= freq_range->start_freq_khz ||
+ freq_range->max_bandwidth_khz > freq_diff)
return 0;

return 1;
--
1.7.10.4


2013-05-31 02:11:24

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 23/40] crda: rename print_regdom() to reglib_print_regdom()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 2 +-
print-regdom.c | 2 +-
regdbdump.c | 2 +-
reglib.h | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/intersect.c b/intersect.c
index 51479e4..22b3225 100644
--- a/intersect.c
+++ b/intersect.c
@@ -68,7 +68,7 @@ int main(int argc, char **argv)

/* Tada! */
printf("== World regulatory domain: ==\n");
- print_regdom(rd_intsct);
+ reglib_print_regdom(rd_intsct);

free(rd_intsct);
return r;
diff --git a/print-regdom.c b/print-regdom.c
index abd6488..ab122db 100644
--- a/print-regdom.c
+++ b/print-regdom.c
@@ -70,7 +70,7 @@ static void print_reg_rule(const struct ieee80211_reg_rule *rule)
printf("\n");
}

-void print_regdom(const struct ieee80211_regdomain *rd)
+void reglib_print_regdom(const struct ieee80211_regdomain *rd)
{
unsigned int i;
printf("country %.2s: %s\n", rd->alpha2,
diff --git a/regdbdump.c b/regdbdump.c
index dcbed71..ea14730 100644
--- a/regdbdump.c
+++ b/regdbdump.c
@@ -13,7 +13,7 @@ int main(int argc, char **argv)
}

reglib_for_each_country(rd, idx, argv[1]) {
- print_regdom(rd);
+ reglib_print_regdom(rd);
free((struct ieee80211_regdomain *) rd);
}

diff --git a/reglib.h b/reglib.h
index 2f49a32..4c0ec6d 100644
--- a/reglib.h
+++ b/reglib.h
@@ -85,7 +85,7 @@ const struct ieee80211_regdomain *
reglib_get_rd_alpha2(const char *alpha2, const char *file);

/* reg helpers */
-void print_regdom(const struct ieee80211_regdomain *rd);
+void reglib_print_regdom(const struct ieee80211_regdomain *rd);
struct ieee80211_regdomain *
reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
const struct ieee80211_regdomain *rd2);
--
1.7.10.4


2013-05-31 02:09:59

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 05/40] crda: remove unused BUG_ON() from intersect.c

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 7 -------
1 file changed, 7 deletions(-)

diff --git a/intersect.c b/intersect.c
index 59fd007..7352e73 100644
--- a/intersect.c
+++ b/intersect.c
@@ -9,13 +9,6 @@
/* Intersects regulatory domains, this will skip any regulatory marked with
* an alpha2 of '00', which is used to indicate a regulatory domain */

-#define BUG_ON(foo) do { \
- if (foo) { \
- printf("BUG\n"); \
- exit(-1); \
- } \
- } while (0)
-
/* Sanity check on a regulatory rule */
static int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
{
--
1.7.10.4


2013-05-31 02:10:54

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 16/40] crda: explicitly use close() and munmap() on reglib_get_rd_alpha2()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/reglib.c b/reglib.c
index 634525b..3d13782 100644
--- a/reglib.c
+++ b/reglib.c
@@ -262,33 +262,37 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
if (fd < 0)
return NULL;

- if (fstat(fd, &stat))
+ if (fstat(fd, &stat)) {
+ close(fd);
return NULL;
+ }

dblen = stat.st_size;

db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0);
- if (db == MAP_FAILED)
+ if (db == MAP_FAILED) {
+ close(fd);
return NULL;
+ }

header = crda_get_file_ptr(db, dblen, sizeof(*header), 0);

if (ntohl(header->magic) != REGDB_MAGIC)
- return NULL;
+ goto out;

if (ntohl(header->version) != REGDB_VERSION)
- return NULL;
+ goto out;

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;
+ goto out;

/* verify signature */
if (!crda_verify_db_signature(db, dblen, siglen))
- return NULL;
+ goto out;

num_countries = ntohl(header->reg_country_num);
countries = crda_get_file_ptr(db, dblen,
@@ -296,14 +300,17 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
header->reg_country_ptr);

if (idx >= num_countries)
- return NULL;
+ goto out;

country = countries + idx;

rd = country2rd(db, dblen, country);
if (!rd)
- return NULL;
+ goto out;

+out:
+ close(fd);
+ munmap(db, dblen);
return rd;
}

--
1.7.10.4


2013-05-31 02:11:46

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 28/40] crda: rename isalpha_upper() to reglib_isalpha_upper()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/reglib.h b/reglib.h
index 98aadcc..41827cd 100644
--- a/reglib.h
+++ b/reglib.h
@@ -38,7 +38,7 @@ static inline int reglib_is_world_regdom(const char *alpha2)
return 0;
}

-static inline int isalpha_upper(char letter)
+static inline int reglib_isalpha_upper(char letter)
{
if (letter >= 'A' && letter <= 'Z')
return 1;
@@ -47,7 +47,7 @@ static inline int isalpha_upper(char letter)

static inline int is_alpha2(const char *alpha2)
{
- if (isalpha_upper(alpha2[0]) && isalpha_upper(alpha2[1]))
+ if (reglib_isalpha_upper(alpha2[0]) && reglib_isalpha_upper(alpha2[1]))
return 1;
return 0;
}
--
1.7.10.4


2013-05-31 02:11:37

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 26/40] crda: move reg print helpers to reglib

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
Makefile | 4 +--
print-regdom.c | 80 --------------------------------------------------------
reglib.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 82 deletions(-)
delete mode 100644 print-regdom.c

diff --git a/Makefile b/Makefile
index 1d34bde..7d2e33f 100644
--- a/Makefile
+++ b/Makefile
@@ -113,11 +113,11 @@ crda: reglib.o crda.o
$(NQ) ' LD ' [email protected]
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o [email protected] $^ $(LDLIBS) $(NLLIBS)

-regdbdump: reglib.o regdbdump.o print-regdom.o
+regdbdump: reglib.o regdbdump.o
$(NQ) ' LD ' [email protected]
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o [email protected] $^ $(LDLIBS)

-intersect: reglib.o intersect.o print-regdom.o
+intersect: reglib.o intersect.o
$(NQ) ' LD ' [email protected]
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o [email protected] $^ $(LDLIBS)

diff --git a/print-regdom.c b/print-regdom.c
deleted file mode 100644
index 68c7b4e..0000000
--- a/print-regdom.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <arpa/inet.h>
-
-#include "reglib.h"
-#include "regdb.h"
-
-static const char *dfs_domain_name(enum regdb_dfs_regions region)
-{
- switch (region) {
- case REGDB_DFS_UNSET:
- return "DFS-UNSET";
- case REGDB_DFS_FCC:
- return "DFS-FCC";
- case REGDB_DFS_ETSI:
- return "DFS-ETSI";
- case REGDB_DFS_JP:
- return "DFS-JP";
- default:
- return "DFS-invalid";
- }
-}
-
-static void print_reg_rule(const struct ieee80211_reg_rule *rule)
-{
- const struct ieee80211_freq_range *freq;
- const struct ieee80211_power_rule *power;
-
- freq = &rule->freq_range;
- power = &rule->power_rule;
-
- printf("\t(%.3f - %.3f @ %.3f), ",
- ((float)(freq->start_freq_khz))/1000.0,
- ((float)(freq->end_freq_khz))/1000.0,
- ((float)(freq->max_bandwidth_khz))/1000.0);
-
- printf("(");
-
- if (power->max_antenna_gain)
- printf("%.2f, ", ((float)(power->max_antenna_gain)/100.0));
- else
- printf("N/A, ");
-
- if (power->max_eirp)
- printf("%.2f)", ((float)(power->max_eirp)/100.0));
- else
- printf("N/A)");
-
- if (rule->flags & RRF_NO_OFDM)
- printf(", NO-OFDM");
- if (rule->flags & RRF_NO_CCK)
- printf(", NO-CCK");
- if (rule->flags & RRF_NO_INDOOR)
- printf(", NO-INDOOR");
- if (rule->flags & RRF_NO_OUTDOOR)
- printf(", NO-OUTDOOR");
- if (rule->flags & RRF_DFS)
- printf(", DFS");
- if (rule->flags & RRF_PTP_ONLY)
- printf(", PTP-ONLY");
- if (rule->flags & RRF_PTMP_ONLY)
- printf(", PTMP-ONLY");
- if (rule->flags & RRF_PASSIVE_SCAN)
- printf(", PASSIVE-SCAN");
- if (rule->flags & RRF_NO_IBSS)
- printf(", NO-IBSS");
-
- printf("\n");
-}
-
-void reglib_print_regdom(const struct ieee80211_regdomain *rd)
-{
- unsigned int i;
- printf("country %.2s: %s\n", rd->alpha2,
- dfs_domain_name(rd->dfs_region));
- for (i = 0; i < rd->n_reg_rules; i++)
- print_reg_rule(&rd->reg_rules[i]);
- printf("\n");
-}
diff --git a/reglib.c b/reglib.c
index 316e201..0d258d8 100644
--- a/reglib.c
+++ b/reglib.c
@@ -553,3 +553,76 @@ reglib_intersect_rds(const struct ieee80211_regdomain *rd1,

return rd;
}
+
+static const char *dfs_domain_name(enum regdb_dfs_regions region)
+{
+ switch (region) {
+ case REGDB_DFS_UNSET:
+ return "DFS-UNSET";
+ case REGDB_DFS_FCC:
+ return "DFS-FCC";
+ case REGDB_DFS_ETSI:
+ return "DFS-ETSI";
+ case REGDB_DFS_JP:
+ return "DFS-JP";
+ default:
+ return "DFS-invalid";
+ }
+}
+
+static void print_reg_rule(const struct ieee80211_reg_rule *rule)
+{
+ const struct ieee80211_freq_range *freq;
+ const struct ieee80211_power_rule *power;
+
+ freq = &rule->freq_range;
+ power = &rule->power_rule;
+
+ printf("\t(%.3f - %.3f @ %.3f), ",
+ ((float)(freq->start_freq_khz))/1000.0,
+ ((float)(freq->end_freq_khz))/1000.0,
+ ((float)(freq->max_bandwidth_khz))/1000.0);
+
+ printf("(");
+
+ if (power->max_antenna_gain)
+ printf("%.2f, ", ((float)(power->max_antenna_gain)/100.0));
+ else
+ printf("N/A, ");
+
+ if (power->max_eirp)
+ printf("%.2f)", ((float)(power->max_eirp)/100.0));
+ else
+ printf("N/A)");
+
+ if (rule->flags & RRF_NO_OFDM)
+ printf(", NO-OFDM");
+ if (rule->flags & RRF_NO_CCK)
+ printf(", NO-CCK");
+ if (rule->flags & RRF_NO_INDOOR)
+ printf(", NO-INDOOR");
+ if (rule->flags & RRF_NO_OUTDOOR)
+ printf(", NO-OUTDOOR");
+ if (rule->flags & RRF_DFS)
+ printf(", DFS");
+ if (rule->flags & RRF_PTP_ONLY)
+ printf(", PTP-ONLY");
+ if (rule->flags & RRF_PTMP_ONLY)
+ printf(", PTMP-ONLY");
+ if (rule->flags & RRF_PASSIVE_SCAN)
+ printf(", PASSIVE-SCAN");
+ if (rule->flags & RRF_NO_IBSS)
+ printf(", NO-IBSS");
+
+ printf("\n");
+}
+
+void reglib_print_regdom(const struct ieee80211_regdomain *rd)
+{
+ unsigned int i;
+ printf("country %.2s: %s\n", rd->alpha2,
+ dfs_domain_name(rd->dfs_region));
+ for (i = 0; i < rd->n_reg_rules; i++)
+ print_reg_rule(&rd->reg_rules[i]);
+ printf("\n");
+}
--
1.7.10.4


2013-05-31 02:10:50

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 15/40] crda: use gcry_sexp_release() on crda_verify_db_signature()

From: "Luis R. Rodriguez" <[email protected]>

This fixes 6 of 10 reported valgrind errors when
crda_verify_db_signature() is used through regdbdump.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/reglib.c b/reglib.c
index 17e3f31..634525b 100644
--- a/reglib.c
+++ b/reglib.c
@@ -135,13 +135,14 @@ int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
if (gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))",
20, hash)) {
fprintf(stderr, "Failed to build data S-expression.\n");
- goto out;
+ return ok;
}

if (gcry_sexp_build(&signature, NULL, "(sig-val (rsa (s %b)))",
siglen, db + dblen)) {
fprintf(stderr, "Failed to build signature S-expression.\n");
- goto out;
+ gcry_sexp_release(data);
+ return ok;
}

for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
@@ -161,12 +162,15 @@ int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
}

ok = gcry_pk_verify(signature, data, rsa) == 0;
+ gcry_sexp_release(rsa);
}

if (!ok)
fprintf(stderr, "Database signature verification failed.\n");

out:
+ gcry_sexp_release(data);
+ gcry_sexp_release(signature);
return ok;
}
#endif /* USE_GCRYPT */
--
1.7.10.4


2013-05-31 02:11:07

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 19/40] crda: remove verbosity out of intersect.c

From: "Luis R. Rodriguez" <[email protected]>

No need for such much verbosity, additionally,
we'll move this eventually to reglib.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 33 +++------------------------------
1 file changed, 3 insertions(+), 30 deletions(-)

diff --git a/intersect.c b/intersect.c
index 7903dd7..bce7eb3 100644
--- a/intersect.c
+++ b/intersect.c
@@ -43,48 +43,21 @@ int main(int argc, char **argv)
if (!rd_intsct) {
free(prev_rd_intsct);
free((struct ieee80211_regdomain *) rd);
- fprintf(stderr, "Intersection not possible\n");
return -ENOENT;
}

- if (intersected)
- /* Use UTF-8 Intersection symbol ? (0xE2,0x88,0xA9) :) */
- printf("WW (%d) intersect %c%c (%d) ==> %d rules\n",
- prev_rd_intsct->n_reg_rules,
- rd->alpha2[0],
- rd->alpha2[1],
- rd->n_reg_rules,
- rd_intsct->n_reg_rules);
- else
- printf("%c%c (%d) intersect %c%c (%d) ==> %d rules\n",
- prev_rd_intsct->alpha2[0],
- prev_rd_intsct->alpha2[1],
- prev_rd_intsct->n_reg_rules,
- rd->alpha2[0],
- rd->alpha2[1],
- rd->n_reg_rules,
- rd_intsct->n_reg_rules);
intersected++;
free((struct ieee80211_regdomain *) rd);
}

- if (!idx) {
- printf("Invalid or empty regulatory file, note: "
- "a binary regulatory file should be used.\n");
+ if (!idx)
return -EINVAL;
- }

- if (intersected > 1)
- printf("%d regulatory domains intersected\n", intersected);
- else {
+ if (intersected <= 0) {
rd_intsct = prev_rd_intsct;
prev_rd_intsct = NULL;
- printf("No intersections completed\n");
if (idx > 1) {
- printf("Since more than one regulatory domain is "
- "present and no intersections were possible "
- "no globally allowed spectrum is possible so "
- "consider enabling passive scan flags\n");
+ r = -ENOENT;
free(rd_intsct);
return r;
}
--
1.7.10.4


2013-05-31 02:11:59

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 31/40] crda: rename max() to reglib_max()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 2 +-
reglib.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/reglib.c b/reglib.c
index 0d258d8..57bb22b 100644
--- a/reglib.c
+++ b/reglib.c
@@ -438,7 +438,7 @@ static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
power_rule2 = &rule2->power_rule;
power_rule = &intersected_rule->power_rule;

- freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
+ freq_range->start_freq_khz = reglib_max(freq_range1->start_freq_khz,
freq_range2->start_freq_khz);
freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
freq_range2->end_freq_khz);
diff --git a/reglib.h b/reglib.h
index 8ed94d9..21518d2 100644
--- a/reglib.h
+++ b/reglib.h
@@ -60,7 +60,7 @@ static inline int reglib_is_valid_regdom(const char *alpha2)
return 1;
}

-static inline uint32_t max(uint32_t a, uint32_t b)
+static inline uint32_t reglib_max(uint32_t a, uint32_t b)
{
return (a > b) ? a : b;
}
--
1.7.10.4


2013-05-31 02:11:29

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 24/40] crda: add regdb_dfs_regions

From: "Luis R. Rodriguez" <[email protected]>

These are already in dbparse.py. As it stands silicon
vendor DFS solutions group up DFS compliance requirements
into three categorical groups. Each country that requires
DFS has opted to follow one type of group category set
of rules.

CRDA was already reading the DFS regions but using
nl80211.h definitions for its parsing and printing of
these flags, its best to use our own OS agnostic
definitions.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
regdb.h | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/regdb.h b/regdb.h
index afb7284..4508621 100644
--- a/regdb.h
+++ b/regdb.h
@@ -7,6 +7,10 @@
* WARNING: This file needs to be kept in sync with
* - the parser (dbparse.py)
* - the generator code (db2bin.py)
+ *
+ * As it is only Linux is using these so we have a direct one to
+ * one map for flags. Each respective OS flag is listed where
+ * appropriate.
*/

/* spells "RGDB" */
@@ -61,8 +65,9 @@ struct regdb_file_power_rule {
uint32_t max_eirp;
};

-/* must match <linux/nl80211.h> enum nl80211_reg_rule_flags */
-
+/*
+ * The Linux map defined in <linux/uapi/nl80211.h> enum nl80211_reg_rule_flags
+ */
enum reg_rule_flags {
RRF_NO_OFDM = 1<<0, /* OFDM modulation not allowed */
RRF_NO_CCK = 1<<1, /* CCK modulation not allowed */
@@ -78,6 +83,21 @@ enum reg_rule_flags {
RRF_NO_IBSS = 1<<8, /* IBSS is not allowed */
};

+/**
+ * enum regdb_dfs_regions - regulatory DFS regions
+ *
+ * @REGDB_DFS_UNSET: Country has no DFS master region specified
+ * @REGDB_DFS_FCC: Country follows DFS master rules from FCC
+ * @REGDB_DFS_ETSI: Country follows DFS master rules from ETSI
+ * @REGDB_DFS_JP: Country follows DFS master rules from JP/MKK/Telec
+ */
+enum regdb_dfs_regions {
+ REGDB_DFS_UNSET = 0,
+ REGDB_DFS_FCC = 1,
+ REGDB_DFS_ETSI = 2,
+ REGDB_DFS_JP = 3,
+};
+
struct regdb_file_reg_rule {
/* pointers (offsets) into the file */
uint32_t freq_range_ptr; /* pointer to a struct regdb_file_freq_range */
--
1.7.10.4


2013-05-31 02:10:25

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 09/40] crda: do not double count on reglib_for_each_country()

From: "Luis R. Rodriguez" <[email protected]>

Commit ebcbfcf4 introduced reglib_for_each_country() used
by regdbump and later intersect. This helper however only
increased the index count after we requestd getting a new
regulatory domain, this is incorrect and causes us to iterate
over the same element twice in the beginning. This means
intersection and regdb printing was going over the first
element twice. This has been present since v1.1.

This also requires an adjustment on intersect due to the
way things were being handled before.

[email protected] ~/devel/crda (git::master)$ git describe --contains ebcbfcf4
v1.1.3~9

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 10 +++-------
reglib.h | 3 +--
2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/intersect.c b/intersect.c
index 5cb7d7c..dea9145 100644
--- a/intersect.c
+++ b/intersect.c
@@ -79,16 +79,12 @@ int main(int argc, char **argv)
return -EINVAL;
}

- if (idx == 1) {
- world = (struct ieee80211_regdomain *) rd;
- rd = NULL;
- }
-
-
if (intersected > 1)
printf("%d regulatory domains intersected\n", intersected);
- else
+ else {
+ world = prev_world;
printf("Only one intersection completed\n");
+ }

/* Tada! */
printf("== World regulatory domain: ==\n");
diff --git a/reglib.h b/reglib.h
index b52d717..8bd9e03 100644
--- a/reglib.h
+++ b/reglib.h
@@ -79,8 +79,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file);
#define reglib_for_each_country(__rd, __idx, __file) \
for (__rd = reglib_get_rd_idx(__idx, __file); \
__rd != NULL; \
- __rd = reglib_get_rd_idx(__idx, __file), \
- __idx++)
+ __rd = reglib_get_rd_idx(++__idx, __file)) \

const struct ieee80211_regdomain *
reglib_get_rd_alpha2(const char *alpha2, const char *file);
--
1.7.10.4


2013-05-31 02:12:17

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 35/40] crda: separate intersecting a full db into a helper

From: "Luis R. Rodriguez" <[email protected]>

This should make it easier to review the code and allow
us to stuff it next into reglib. This has no real functional
changes except that of returning NULL in case of any failure
while reading the regdb.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 58 +++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/intersect.c b/intersect.c
index baca5f1..b9e3429 100644
--- a/intersect.c
+++ b/intersect.c
@@ -6,24 +6,25 @@

#include "reglib.h"

-/* Intersects regulatory domains, this will skip any regulatory marked with
- * an alpha2 of '00', which is used to indicate a world regulatory domain */
-
-int main(int argc, char **argv)
+/**
+ * reglib_intersect_regdb - intersects a regulatory database
+ *
+ * @regdb_file: the regulatory database to intersect
+ *
+ * Goes through an entire regulatory database and intersects all regulatory
+ * domains. This will skip any regulatory marked with an alpha2 of '00', which
+ * is used to indicate a world regulatory domain. If intersection is able
+ * to find rules that fit all regulatory domains it return a regulatory
+ * domain with such rules otherwise it returns NULL.
+ */
+const struct ieee80211_regdomain *reglib_intersect_regdb(char *regdb_file)
{
- int r = 0;
const struct ieee80211_regdomain *rd;
struct ieee80211_regdomain *prev_rd_intsct = NULL, *rd_intsct = NULL;
int intersected = 0;
unsigned int idx = 0;

- if (argc != 2) {
- fprintf(stderr, "You must specify a file\n");
- return -EINVAL;
- }
-
- /* We intersect only when we have to rd structures ready */
- reglib_for_each_country(rd, idx, argv[1]) {
+ reglib_for_each_country(rd, idx, regdb_file) {
if (reglib_is_world_regdom((const char *) rd->alpha2)) {
free((struct ieee80211_regdomain *) rd);
continue;
@@ -43,7 +44,7 @@ int main(int argc, char **argv)
if (!rd_intsct) {
free(prev_rd_intsct);
free((struct ieee80211_regdomain *) rd);
- return -ENOENT;
+ return NULL;
}

intersected++;
@@ -51,25 +52,40 @@ int main(int argc, char **argv)
}

if (!idx)
- return -EINVAL;
+ return NULL;

if (intersected <= 0) {
rd_intsct = prev_rd_intsct;
prev_rd_intsct = NULL;
if (idx > 1) {
- r = -ENOENT;
free(rd_intsct);
- return r;
+ return NULL;
}
}

if (prev_rd_intsct)
free(prev_rd_intsct);

- /* Tada! */
- printf("Intersected regulatory domain:\n");
- reglib_print_regdom(rd_intsct);
+ return rd_intsct;
+}
+
+int main(int argc, char **argv)
+{
+ const struct ieee80211_regdomain *rd;
+
+ if (argc != 2) {
+ fprintf(stderr, "You must specify a file\n");
+ return -EINVAL;
+ }
+
+ rd = reglib_intersect_regdb(argv[1]);
+ if (!rd) {
+ fprintf(stderr, "Intersection not possible\n");
+ return -ENOENT;
+ }
+
+ reglib_print_regdom(rd);
+ free((struct ieee80211_regdomain *) rd);

- free(rd_intsct);
- return r;
+ return 0;
}
--
1.7.10.4


2013-05-31 02:10:46

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 14/40] crda: separate crda_verify_db_signature() implementations

From: "Luis R. Rodriguez" <[email protected]>

This will allow us to handle the error codes more cleanly
and in a readible manner. This change should have no
functional change.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/reglib.c b/reglib.c
index cbe9676..17e3f31 100644
--- a/reglib.c
+++ b/reglib.c
@@ -50,14 +50,17 @@ void *crda_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
}

/*
+ * crda_verify_db_signature():
+ *
* Checks the validity of the signature found on the regulatory
* database against the array 'keys'. Returns 1 if there exists
* at least one key in the array such that the signature is valid
* against that key; 0 otherwise.
*/
+
+#ifdef USE_OPENSSL
int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
{
-#ifdef USE_OPENSSL
RSA *rsa;
uint8_t hash[SHA_DIGEST_LENGTH];
unsigned int i;
@@ -105,9 +108,18 @@ int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
}
closedir(pubkey_dir);
}
-#endif
+
+ if (!ok)
+ fprintf(stderr, "Database signature verification failed.\n");
+
+out:
+ return ok;
+}
+#endif /* USE_OPENSSL */

#ifdef USE_GCRYPT
+int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
+{
gcry_mpi_t mpi_e, mpi_n;
gcry_sexp_t rsa, signature, data;
uint8_t hash[20];
@@ -150,18 +162,21 @@ int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)

ok = gcry_pk_verify(signature, data, rsa) == 0;
}
-#endif

-#if defined(USE_OPENSSL) || defined(USE_GCRYPT)
if (!ok)
fprintf(stderr, "Database signature verification failed.\n");

out:
return ok;
-#else
+}
+#endif /* USE_GCRYPT */
+
+#if !defined(USE_OPENSSL) && !defined(USE_GCRYPT)
+int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
+{
return 1;
-#endif
}
+#endif

static void reg_rule2rd(uint8_t *db, int dblen,
uint32_t ruleptr, struct ieee80211_reg_rule *rd_reg_rule)
--
1.7.10.4


2013-05-31 02:10:33

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 11/40] crda: fix intersect.c memory management

From: "Luis R. Rodriguez" <[email protected]>

We didn't free memory in some cases, fix this and
to help with the complexity also simplify the case
where any regdom_intersect() fails by completely
failing. In such cases we need an alternative strategy
to build "world regulatory" domains.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 34 +++++++++++++---------------------
1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/intersect.c b/intersect.c
index 169fe1a..970f4db 100644
--- a/intersect.c
+++ b/intersect.c
@@ -24,8 +24,10 @@ int main(int argc, char **argv)

/* We intersect only when we have to rd structures ready */
reglib_for_each_country(rd, idx, argv[1]) {
- if (is_world_regdom((const char *) rd->alpha2))
+ if (is_world_regdom((const char *) rd->alpha2)) {
+ free((struct ieee80211_regdomain *) rd);
continue;
+ }

if (!prev_world) {
prev_world = (struct ieee80211_regdomain *) rd;
@@ -39,18 +41,10 @@ int main(int argc, char **argv)

world = regdom_intersect(prev_world, rd);
if (!world) {
- /* Could be something else but we'll live with this */
- r = -ENOMEM;
- if (intersected)
- fprintf(stderr, "Could not intersect world "
- "with country (%.2s)\n",
- rd->alpha2);
- else
- fprintf(stderr, "Could not intersect country (%.2s) "
- "with country (%.2s)\n",
- prev_world->alpha2,
- rd->alpha2);
- continue;
+ free(prev_world);
+ free((struct ieee80211_regdomain *) rd);
+ fprintf(stderr, "Intersection not possible\n");
+ return -ENOENT;
}

if (intersected)
@@ -71,6 +65,7 @@ int main(int argc, char **argv)
rd->n_reg_rules,
world->n_reg_rules);
intersected++;
+ free((struct ieee80211_regdomain *) rd);
}

if (!idx) {
@@ -83,28 +78,25 @@ int main(int argc, char **argv)
printf("%d regulatory domains intersected\n", intersected);
else {
world = prev_world;
+ prev_world = NULL;
printf("No intersections completed\n");
if (idx > 1) {
printf("Since more than one regulatory domain is "
"present and no intersections were possible "
"no globally allowed spectrum is possible so "
"consider enabling passive scan flags\n");
+ free(world);
return r;
}
}

+ if (prev_world)
+ free(prev_world);
+
/* Tada! */
printf("== World regulatory domain: ==\n");
print_regdom(world);

- if (!intersected) {
- free(world);
- return r;
- }
- if (intersected > 1) {
- free((struct ieee80211_regdomain *)rd);
- free(prev_world);
- }
free(world);
return r;
}
--
1.7.10.4


2013-05-31 02:10:20

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 08/40] crda: move intersection if first attempt failed

From: "Luis R. Rodriguez" <[email protected]>

The intersection should be able to continue on even if
the first two countries could not be intersected.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/intersect.c b/intersect.c
index 8f826a0..5cb7d7c 100644
--- a/intersect.c
+++ b/intersect.c
@@ -50,7 +50,7 @@ int main(int argc, char **argv)
"with country (%.2s)\n",
prev_world->alpha2,
rd->alpha2);
- goto out;
+ continue;
}

if (intersected)
@@ -94,7 +94,6 @@ int main(int argc, char **argv)
printf("== World regulatory domain: ==\n");
print_regdom(world);

-out:
if (!intersected) {
free(world);
return r;
--
1.7.10.4


2013-05-31 02:10:59

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 17/40] crda: use gcry_mpi_release() when using gcry_mpi_scan()

From: "Luis R. Rodriguez" <[email protected]>

Its not well documented you should do this but I found out
through valgrind. This fixes the last 4 valgrind issues
I was seeing with regdbdump.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/reglib.c b/reglib.c
index 3d13782..72ea78f 100644
--- a/reglib.c
+++ b/reglib.c
@@ -158,10 +158,14 @@ int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
"(public-key (rsa (n %m) (e %m)))",
mpi_n, mpi_e)) {
fprintf(stderr, "Failed to build RSA S-expression.\n");
+ gcry_mpi_release(mpi_e);
+ gcry_mpi_release(mpi_n);
goto out;
}

ok = gcry_pk_verify(signature, data, rsa) == 0;
+ gcry_mpi_release(mpi_e);
+ gcry_mpi_release(mpi_n);
gcry_sexp_release(rsa);
}

--
1.7.10.4


2013-05-31 02:12:29

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 38/40] crda: add reglib regdb context helpers: reglib_(malloc|free)_regdb_ctx()

From: "Luis R. Rodriguez" <[email protected]>

These are used to allow users of reglib to instantiate a
reglib context to be used with reglib without having to
always open the regdb, mmap() it and verify it. It also
allows us to tuck away all that magic from users and put
the responsibility on reglib to do all the sanity work
for users.

To start with consolidate with two users:

reglib_get_rd_idx() and reglib_get_rd_alpha2()

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 206 +++++++++++++++++++++++++++++++-------------------------------
reglib.h | 65 ++++++++++++++++++++
2 files changed, 167 insertions(+), 104 deletions(-)

diff --git a/reglib.c b/reglib.c
index 67f5b2b..6f076ff 100644
--- a/reglib.c
+++ b/reglib.c
@@ -186,6 +186,92 @@ int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen)
}
#endif

+const struct reglib_regdb_ctx *reglib_malloc_regdb_ctx(const char *regdb_file)
+{
+ struct regdb_file_header *header;
+ struct reglib_regdb_ctx *ctx;
+
+ ctx = malloc(sizeof(struct reglib_regdb_ctx));
+ if (!ctx)
+ return NULL;
+
+ memset(ctx, 0, sizeof(struct reglib_regdb_ctx));
+
+ ctx->fd = open(regdb_file, O_RDONLY);
+
+ if (ctx->fd < 0) {
+ free(ctx);
+ return NULL;
+ }
+
+ if (fstat(ctx->fd, &ctx->stat)) {
+ close(ctx->fd);
+ free(ctx);
+ return NULL;
+ }
+
+ ctx->real_dblen = ctx->stat.st_size;
+
+ ctx->db = mmap(NULL, ctx->real_dblen, PROT_READ,
+ MAP_PRIVATE, ctx->fd, 0);
+ if (ctx->db == MAP_FAILED) {
+ close(ctx->fd);
+ free(ctx);
+ return NULL;
+ }
+
+ ctx->header = reglib_get_file_ptr(ctx->db, ctx->dblen,
+ sizeof(struct regdb_file_header),
+ 0);
+ header = ctx->header;
+
+ if (ntohl(header->magic) != REGDB_MAGIC)
+ goto err_out;
+
+ if (ntohl(header->version) != REGDB_VERSION)
+ goto err_out;
+
+ ctx->siglen = ntohl(header->signature_length);
+ /* The actual dblen does not take into account the signature */
+ ctx->dblen = ctx->real_dblen - ctx->siglen;
+
+ if (ctx->dblen <= sizeof(*header))
+ goto err_out;
+
+ /* verify signature */
+ if (!reglib_verify_db_signature(ctx->db, ctx->dblen, ctx->siglen))
+ goto err_out;
+
+ ctx->verified = true;
+ ctx->num_countries = ntohl(header->reg_country_num);
+ ctx->countries = reglib_get_file_ptr(ctx->db,
+ ctx->dblen,
+ sizeof(struct regdb_file_reg_country) * ctx->num_countries,
+ header->reg_country_ptr);
+ return ctx;
+
+err_out:
+ close(ctx->fd);
+ munmap(ctx->db, ctx->real_dblen);
+ free(ctx);
+ return NULL;
+}
+
+void reglib_free_regdb_ctx(const struct reglib_regdb_ctx *regdb_ctx)
+{
+ struct reglib_regdb_ctx *ctx;
+
+ if (!regdb_ctx)
+ return;
+
+ ctx = (struct reglib_regdb_ctx *) regdb_ctx;
+
+ memset(ctx, 0, sizeof(struct reglib_regdb_ctx));
+ close(ctx->fd);
+ munmap(ctx->db, ctx->real_dblen);
+ free(ctx);
+}
+
static void reg_rule2rd(uint8_t *db, int dblen,
uint32_t ruleptr, struct ieee80211_reg_rule *rd_reg_rule)
{
@@ -252,130 +338,43 @@ country2rd(uint8_t *db, int dblen,
const struct ieee80211_regdomain *
reglib_get_rd_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;
- const struct ieee80211_regdomain *rd = NULL;
+ const struct reglib_regdb_ctx *ctx;
struct regdb_file_reg_country *country;
+ const struct ieee80211_regdomain *rd = NULL;

- fd = open(file, O_RDONLY);
-
- if (fd < 0)
- return NULL;
-
- if (fstat(fd, &stat)) {
- close(fd);
- return NULL;
- }
-
- dblen = stat.st_size;
-
- db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0);
- if (db == MAP_FAILED) {
- close(fd);
+ ctx = reglib_malloc_regdb_ctx(file);
+ if (!ctx)
return NULL;
- }
-
- header = reglib_get_file_ptr(db, dblen, sizeof(*header), 0);

- if (ntohl(header->magic) != REGDB_MAGIC)
+ if (idx >= ctx->num_countries)
goto out;

- if (ntohl(header->version) != REGDB_VERSION)
- goto out;
+ country = ctx->countries + idx;

- siglen = ntohl(header->signature_length);
- /* adjust dblen so later sanity checks don't run into the signature */
- dblen -= siglen;
-
- if (dblen <= (int)sizeof(*header))
- goto out;
-
- /* verify signature */
- if (!reglib_verify_db_signature(db, dblen, siglen))
- goto out;
-
- num_countries = ntohl(header->reg_country_num);
- countries = reglib_get_file_ptr(db, dblen,
- sizeof(struct regdb_file_reg_country) * num_countries,
- header->reg_country_ptr);
-
- if (idx >= num_countries)
- goto out;
-
- country = countries + idx;
-
- rd = country2rd(db, dblen, country);
+ rd = country2rd(ctx->db, ctx->dblen, country);
if (!rd)
goto out;

out:
- close(fd);
- munmap(db, dblen);
+ reglib_free_regdb_ctx(ctx);
return rd;
}

const struct ieee80211_regdomain *
reglib_get_rd_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;
+ const struct reglib_regdb_ctx *ctx;
const struct ieee80211_regdomain *rd = NULL;
struct regdb_file_reg_country *country;
- unsigned int i;
bool found_country = false;
+ unsigned int i;

- fd = open(file, O_RDONLY);
-
- if (fd < 0)
- return NULL;
-
- if (fstat(fd, &stat)) {
- close(fd);
- return NULL;
- }
-
- dblen = stat.st_size;
-
- db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0);
- if (db == MAP_FAILED) {
- close(fd);
+ ctx = reglib_malloc_regdb_ctx(file);
+ if (!ctx)
return NULL;
- }
-
- header = reglib_get_file_ptr(db, dblen, sizeof(*header), 0);
-
- if (ntohl(header->magic) != REGDB_MAGIC)
- goto out;
-
- if (ntohl(header->version) != REGDB_VERSION)
- goto out;
-
- siglen = ntohl(header->signature_length);
- /* adjust dblen so later sanity checks don't run into the signature */
- dblen -= siglen;
-
- if (dblen <= (int)sizeof(*header))
- goto out;
-
- /* verify signature */
- if (!reglib_verify_db_signature(db, dblen, siglen))
- goto out;
-
- num_countries = ntohl(header->reg_country_num);
- countries = reglib_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;
+ for (i = 0; i < ctx->num_countries; i++) {
+ country = ctx->countries + i;
if (memcmp(country->alpha2, alpha2, 2) == 0) {
found_country = 1;
break;
@@ -385,13 +384,12 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
if (!found_country)
goto out;

- rd = country2rd(db, dblen, country);
+ rd = country2rd(ctx->db, ctx->dblen, country);
if (!rd)
goto out;

out:
- close(fd);
- munmap(db, dblen);
+ reglib_free_regdb_ctx(ctx);
return rd;
}

diff --git a/reglib.h b/reglib.h
index 2681164..f1bd6b8 100644
--- a/reglib.h
+++ b/reglib.h
@@ -3,6 +3,10 @@

#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+
+#include "regdb.h"

/* Common regulatory structures, functions and helpers */

@@ -31,6 +35,44 @@ struct ieee80211_regdomain {
struct ieee80211_reg_rule reg_rules[];
};

+/**
+ * struct reglib_regdb_ctx - reglib regdb context
+ *
+ * This can be used to interat with reglib without
+ * having to open() / close() / mmap() / munmap()
+ * and check the regdb binary file for integrity and
+ * authorship.
+ *
+ * @fd: file descriptor of the db
+ * @stat: @fd fstat()
+ * @db: mmap() of the db of @real_dblen
+ * @real_dblen: file size in bytes of @fd
+ * @siglen: size in bytes of the signature at the end of the file
+ * @dblen: database lenghth, this is the @real_dblen - @siglen
+ * @verified: whether or not this regdb has been RSA verified.
+ * This value is dependent on whether or not you enabled
+ * signature verification with gcrypt, openssl, or none
+ * at all. If no signature verification was not compiled
+ * in then this will always be true otherwise this will
+ * only be true if the RSA digital signature of the SHA1
+ * sum of the regulatory database at the end of the
+ * regulatory database can be verified with the one of
+ * the trusted public keys.
+ */
+struct reglib_regdb_ctx {
+ int fd;
+ struct stat stat;
+ uint8_t *db;
+ uint32_t real_dblen;
+ uint32_t siglen;
+ uint32_t dblen;
+ bool verified;
+
+ struct regdb_file_header *header;
+ uint32_t num_countries;
+ struct regdb_file_reg_country *countries;
+};
+
static inline int reglib_is_world_regdom(const char *alpha2)
{
if (alpha2[0] == '0' && alpha2[1] == '0')
@@ -73,6 +115,29 @@ static inline uint32_t reglib_min(uint32_t a, uint32_t b)
void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr);
int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen);

+/**
+ * reglib_malloc_regdb_ctx - create a regdb context for usage with reglib
+ *
+ * @regdb_file: file name
+ *
+ * Most operations on reglib iterate over the database somehow and prior
+ * to iterating over it it must check the signature. Use this context helper
+ * to let you query the db within different contexts in your program and
+ * just be sure to call reglib_free_regdb_ctx() when done. This helper will
+ * open the file passed and mmap() it.
+ */
+const struct reglib_regdb_ctx *reglib_malloc_regdb_ctx(const char *regdb_file);
+
+/**
+ * reglib_free_regdb_ctx - free a regdb context used with reglib
+ *
+ * @regdb_ctx: the reglib regdb context created with reglib_malloc_regdb_ctx()
+ *
+ * This will do all the handy work to close up, munmap, and free the
+ * reglib regdb context passed.
+ */
+void reglib_free_regdb_ctx(const struct reglib_regdb_ctx *regdb_ctx);
+
const struct ieee80211_regdomain *
reglib_get_rd_idx(unsigned int idx, const char *file);

--
1.7.10.4


2013-05-31 02:11:04

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 18/40] crda: rename world and prev_world on intersect.c

From: "Luis R. Rodriguez" <[email protected]>

The assumption was that intersect.c was creating a world
regulatory domain for by doing an intersection of all
regulatory domains. This is technically still true however
it does not add passive scan flag'd frequency ranges and
as such to be precise lets just rename the "world" and
"prev_world" variables as intersection variables.

This change introduces no functional changes.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/intersect.c b/intersect.c
index 970f4db..7903dd7 100644
--- a/intersect.c
+++ b/intersect.c
@@ -13,7 +13,7 @@ int main(int argc, char **argv)
{
int r = 0;
const struct ieee80211_regdomain *rd;
- struct ieee80211_regdomain *prev_world = NULL, *world = NULL;
+ struct ieee80211_regdomain *prev_rd_intsct = NULL, *rd_intsct = NULL;
int intersected = 0;
unsigned int idx = 0;

@@ -29,19 +29,19 @@ int main(int argc, char **argv)
continue;
}

- if (!prev_world) {
- prev_world = (struct ieee80211_regdomain *) rd;
+ if (!prev_rd_intsct) {
+ prev_rd_intsct = (struct ieee80211_regdomain *) rd;
continue;
}

- if (world) {
- free(prev_world);
- prev_world = (struct ieee80211_regdomain *) world;
+ if (rd_intsct) {
+ free(prev_rd_intsct);
+ prev_rd_intsct = (struct ieee80211_regdomain *) rd_intsct;
}

- world = regdom_intersect(prev_world, rd);
- if (!world) {
- free(prev_world);
+ rd_intsct = regdom_intersect(prev_rd_intsct, rd);
+ if (!rd_intsct) {
+ free(prev_rd_intsct);
free((struct ieee80211_regdomain *) rd);
fprintf(stderr, "Intersection not possible\n");
return -ENOENT;
@@ -50,20 +50,20 @@ int main(int argc, char **argv)
if (intersected)
/* Use UTF-8 Intersection symbol ? (0xE2,0x88,0xA9) :) */
printf("WW (%d) intersect %c%c (%d) ==> %d rules\n",
- prev_world->n_reg_rules,
+ prev_rd_intsct->n_reg_rules,
rd->alpha2[0],
rd->alpha2[1],
rd->n_reg_rules,
- world->n_reg_rules);
+ rd_intsct->n_reg_rules);
else
printf("%c%c (%d) intersect %c%c (%d) ==> %d rules\n",
- prev_world->alpha2[0],
- prev_world->alpha2[1],
- prev_world->n_reg_rules,
+ prev_rd_intsct->alpha2[0],
+ prev_rd_intsct->alpha2[1],
+ prev_rd_intsct->n_reg_rules,
rd->alpha2[0],
rd->alpha2[1],
rd->n_reg_rules,
- world->n_reg_rules);
+ rd_intsct->n_reg_rules);
intersected++;
free((struct ieee80211_regdomain *) rd);
}
@@ -77,26 +77,26 @@ int main(int argc, char **argv)
if (intersected > 1)
printf("%d regulatory domains intersected\n", intersected);
else {
- world = prev_world;
- prev_world = NULL;
+ rd_intsct = prev_rd_intsct;
+ prev_rd_intsct = NULL;
printf("No intersections completed\n");
if (idx > 1) {
printf("Since more than one regulatory domain is "
"present and no intersections were possible "
"no globally allowed spectrum is possible so "
"consider enabling passive scan flags\n");
- free(world);
+ free(rd_intsct);
return r;
}
}

- if (prev_world)
- free(prev_world);
+ if (prev_rd_intsct)
+ free(prev_rd_intsct);

/* Tada! */
printf("== World regulatory domain: ==\n");
- print_regdom(world);
+ print_regdom(rd_intsct);

- free(world);
+ free(rd_intsct);
return r;
}
--
1.7.10.4


2013-05-31 02:09:42

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 01/40] crda: make reg_rules_intersect() style match Linux

From: "Luis R. Rodriguez" <[email protected]>

This makes reg_rules_intersect() style match exactly
as it is upstream as of next-20130522.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/intersect.c b/intersect.c
index 012750d..aa67dbc 100644
--- a/intersect.c
+++ b/intersect.c
@@ -56,11 +56,11 @@ static int reg_rules_intersect(
power_rule = &intersected_rule->power_rule;

freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
- freq_range2->start_freq_khz);
+ freq_range2->start_freq_khz);
freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
- freq_range2->end_freq_khz);
+ freq_range2->end_freq_khz);
freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
- freq_range2->max_bandwidth_khz);
+ freq_range2->max_bandwidth_khz);

freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
if (freq_range->max_bandwidth_khz > freq_diff)
@@ -71,7 +71,7 @@ static int reg_rules_intersect(
power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
power_rule2->max_antenna_gain);

- intersected_rule->flags = (rule1->flags | rule2->flags);
+ intersected_rule->flags = rule1->flags | rule2->flags;

if (!is_valid_reg_rule(intersected_rule))
return -EINVAL;
--
1.7.10.4


2013-05-31 02:10:29

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 10/40] crda: annotate intersection worst case scenerio

From: "Luis R. Rodriguez" <[email protected]>

In the worst case scenerio of regulatory domain intersections
between a different set of regulatory rules you will end up
without being able to initiate radiation on any frequency
range. Provide a hint as to what needs to be done next in
order to actually build a useful regulatory domain. Currently
we do this manually but building the mathematics would be
even more useful as we grow usage of the spectrum.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/intersect.c b/intersect.c
index dea9145..169fe1a 100644
--- a/intersect.c
+++ b/intersect.c
@@ -83,7 +83,14 @@ int main(int argc, char **argv)
printf("%d regulatory domains intersected\n", intersected);
else {
world = prev_world;
- printf("Only one intersection completed\n");
+ printf("No intersections completed\n");
+ if (idx > 1) {
+ printf("Since more than one regulatory domain is "
+ "present and no intersections were possible "
+ "no globally allowed spectrum is possible so "
+ "consider enabling passive scan flags\n");
+ return r;
+ }
}

/* Tada! */
--
1.7.10.4


2013-05-31 02:11:33

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 25/40] crda: make print-regdom use internal flags

From: "Luis R. Rodriguez" <[email protected]>

Do not rely on nl80211.h for general regulatory db parsing.
Its best to use our own OS agnostic definitions.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
print-regdom.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/print-regdom.c b/print-regdom.c
index ab122db..68c7b4e 100644
--- a/print-regdom.c
+++ b/print-regdom.c
@@ -3,20 +3,19 @@
#include <string.h>
#include <arpa/inet.h>

-#include "nl80211.h"
-
#include "reglib.h"
+#include "regdb.h"

-static const char *dfs_domain_name(enum nl80211_dfs_regions region)
+static const char *dfs_domain_name(enum regdb_dfs_regions region)
{
switch (region) {
- case NL80211_DFS_UNSET:
+ case REGDB_DFS_UNSET:
return "DFS-UNSET";
- case NL80211_DFS_FCC:
+ case REGDB_DFS_FCC:
return "DFS-FCC";
- case NL80211_DFS_ETSI:
+ case REGDB_DFS_ETSI:
return "DFS-ETSI";
- case NL80211_DFS_JP:
+ case REGDB_DFS_JP:
return "DFS-JP";
default:
return "DFS-invalid";
@@ -48,23 +47,23 @@ static void print_reg_rule(const struct ieee80211_reg_rule *rule)
else
printf("N/A)");

- if (rule->flags & NL80211_RRF_NO_OFDM)
+ if (rule->flags & RRF_NO_OFDM)
printf(", NO-OFDM");
- if (rule->flags & NL80211_RRF_NO_CCK)
+ if (rule->flags & RRF_NO_CCK)
printf(", NO-CCK");
- if (rule->flags & NL80211_RRF_NO_INDOOR)
+ if (rule->flags & RRF_NO_INDOOR)
printf(", NO-INDOOR");
- if (rule->flags & NL80211_RRF_NO_OUTDOOR)
+ if (rule->flags & RRF_NO_OUTDOOR)
printf(", NO-OUTDOOR");
- if (rule->flags & NL80211_RRF_DFS)
+ if (rule->flags & RRF_DFS)
printf(", DFS");
- if (rule->flags & NL80211_RRF_PTP_ONLY)
+ if (rule->flags & RRF_PTP_ONLY)
printf(", PTP-ONLY");
- if (rule->flags & NL80211_RRF_PTMP_ONLY)
+ if (rule->flags & RRF_PTMP_ONLY)
printf(", PTMP-ONLY");
- if (rule->flags & NL80211_RRF_PASSIVE_SCAN)
+ if (rule->flags & RRF_PASSIVE_SCAN)
printf(", PASSIVE-SCAN");
- if (rule->flags & NL80211_RRF_NO_IBSS)
+ if (rule->flags & RRF_NO_IBSS)
printf(", NO-IBSS");

printf("\n");
--
1.7.10.4


2013-05-31 02:10:42

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 13/40] crda: explicitly close file descriptor and munmap() on failures

From: "Luis R. Rodriguez" <[email protected]>

Just do this explicitly.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/reglib.c b/reglib.c
index bb6f23f..cbe9676 100644
--- a/reglib.c
+++ b/reglib.c
@@ -307,33 +307,37 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
if (fd < 0)
return NULL;

- if (fstat(fd, &stat))
+ if (fstat(fd, &stat)) {
+ close(fd);
return NULL;
+ }

dblen = stat.st_size;

db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0);
- if (db == MAP_FAILED)
+ if (db == MAP_FAILED) {
+ close(fd);
return NULL;
+ }

header = crda_get_file_ptr(db, dblen, sizeof(*header), 0);

if (ntohl(header->magic) != REGDB_MAGIC)
- return NULL;
+ goto out;

if (ntohl(header->version) != REGDB_VERSION)
- return NULL;
+ goto out;

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;
+ goto out;

/* verify signature */
if (!crda_verify_db_signature(db, dblen, siglen))
- return NULL;
+ goto out;

num_countries = ntohl(header->reg_country_num);
countries = crda_get_file_ptr(db, dblen,
--
1.7.10.4


2013-05-31 02:11:12

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 20/40] crda: rename regdom_intersect() to reglib_intersect_rds()

From: "Luis R. Rodriguez" <[email protected]>

This fits more in line with the reglib prefix usage.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 2 +-
reglib.c | 8 ++++----
reglib.h | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/intersect.c b/intersect.c
index bce7eb3..51479e4 100644
--- a/intersect.c
+++ b/intersect.c
@@ -39,7 +39,7 @@ int main(int argc, char **argv)
prev_rd_intsct = (struct ieee80211_regdomain *) rd_intsct;
}

- rd_intsct = regdom_intersect(prev_rd_intsct, rd);
+ rd_intsct = reglib_intersect_rds(prev_rd_intsct, rd);
if (!rd_intsct) {
free(prev_rd_intsct);
free((struct ieee80211_regdomain *) rd);
diff --git a/reglib.c b/reglib.c
index 72ea78f..333db7a 100644
--- a/reglib.c
+++ b/reglib.c
@@ -417,7 +417,7 @@ static int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
}

/*
- * Helper for regdom_intersect(), this does the real
+ * Helper for reglib_intersect_rds(), this does the real
* mathematical intersection fun
*/
static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
@@ -463,7 +463,7 @@ static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
}

/**
- * regdom_intersect - do the intersection between two regulatory domains
+ * reglib_intersect_rds - do the intersection between two regulatory domains
* @rd1: first regulatory domain
* @rd2: second regulatory domain
*
@@ -476,8 +476,8 @@ static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
* malloc() this structure for you.
*/
struct ieee80211_regdomain *
-regdom_intersect(const struct ieee80211_regdomain *rd1,
- const struct ieee80211_regdomain *rd2)
+reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
+ const struct ieee80211_regdomain *rd2)
{
int r, size_of_regd;
unsigned int x, y;
diff --git a/reglib.h b/reglib.h
index 8bd9e03..529772d 100644
--- a/reglib.h
+++ b/reglib.h
@@ -87,7 +87,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file);
/* reg helpers */
void print_regdom(const struct ieee80211_regdomain *rd);
struct ieee80211_regdomain *
-regdom_intersect(const struct ieee80211_regdomain *rd1,
- const struct ieee80211_regdomain *rd2);
+reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
+ const struct ieee80211_regdomain *rd2);

#endif
--
1.7.10.4


2013-05-31 02:11:20

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 22/40] crda: rename crda_verify_db_signature() to reglib_verify_db_signature()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 12 ++++++------
reglib.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/reglib.c b/reglib.c
index a957f0e..316e201 100644
--- a/reglib.c
+++ b/reglib.c
@@ -50,7 +50,7 @@ void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
}

/*
- * crda_verify_db_signature():
+ * reglib_verify_db_signature():
*
* Checks the validity of the signature found on the regulatory
* database against the array 'keys'. Returns 1 if there exists
@@ -59,7 +59,7 @@ void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
*/

#ifdef USE_OPENSSL
-int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
+int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen)
{
RSA *rsa;
uint8_t hash[SHA_DIGEST_LENGTH];
@@ -118,7 +118,7 @@ out:
#endif /* USE_OPENSSL */

#ifdef USE_GCRYPT
-int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
+int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen)
{
gcry_mpi_t mpi_e, mpi_n;
gcry_sexp_t rsa, signature, data;
@@ -180,7 +180,7 @@ out:
#endif /* USE_GCRYPT */

#if !defined(USE_OPENSSL) && !defined(USE_GCRYPT)
-int crda_verify_db_signature(uint8_t *db, int dblen, int siglen)
+int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen)
{
return 1;
}
@@ -295,7 +295,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
goto out;

/* verify signature */
- if (!crda_verify_db_signature(db, dblen, siglen))
+ if (!reglib_verify_db_signature(db, dblen, siglen))
goto out;

num_countries = ntohl(header->reg_country_num);
@@ -366,7 +366,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
goto out;

/* verify signature */
- if (!crda_verify_db_signature(db, dblen, siglen))
+ if (!reglib_verify_db_signature(db, dblen, siglen))
goto out;

num_countries = ntohl(header->reg_country_num);
diff --git a/reglib.h b/reglib.h
index 3510889..2f49a32 100644
--- a/reglib.h
+++ b/reglib.h
@@ -71,7 +71,7 @@ static inline uint32_t min(uint32_t a, uint32_t b)
}

void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr);
-int crda_verify_db_signature(uint8_t *db, int dblen, int siglen);
+int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen);

const struct ieee80211_regdomain *
reglib_get_rd_idx(unsigned int idx, const char *file);
--
1.7.10.4


2013-05-31 02:11:16

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 21/40] crda: rename crda_get_file_ptr() to reglib_get_file_ptr()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 20 ++++++++++----------
reglib.h | 2 +-
2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/reglib.c b/reglib.c
index 333db7a..a957f0e 100644
--- a/reglib.c
+++ b/reglib.c
@@ -37,7 +37,7 @@
#include "keys-gcrypt.c"
#endif

-void *crda_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
+void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
{
uint32_t p = ntohl(ptr);

@@ -196,9 +196,9 @@ static void reg_rule2rd(uint8_t *db, int dblen,
struct ieee80211_freq_range *rd_freq_range = &rd_reg_rule->freq_range;
struct ieee80211_power_rule *rd_power_rule = &rd_reg_rule->power_rule;

- rule = crda_get_file_ptr(db, dblen, sizeof(*rule), ruleptr);
- freq = crda_get_file_ptr(db, dblen, sizeof(*freq), rule->freq_range_ptr);
- power = crda_get_file_ptr(db, dblen, sizeof(*power), rule->power_rule_ptr);
+ rule = reglib_get_file_ptr(db, dblen, sizeof(*rule), ruleptr);
+ freq = reglib_get_file_ptr(db, dblen, sizeof(*freq), rule->freq_range_ptr);
+ power = reglib_get_file_ptr(db, dblen, sizeof(*power), rule->power_rule_ptr);

rd_freq_range->start_freq_khz = ntohl(freq->start_freq);
rd_freq_range->end_freq_khz = ntohl(freq->end_freq);
@@ -219,11 +219,11 @@ country2rd(uint8_t *db, int dblen,
struct ieee80211_regdomain *rd;
int i, num_rules, size_of_rd;

- rcoll = crda_get_file_ptr(db, dblen, sizeof(*rcoll),
+ rcoll = reglib_get_file_ptr(db, dblen, sizeof(*rcoll),
country->reg_collection_ptr);
num_rules = ntohl(rcoll->reg_rule_num);
/* re-get pointer with sanity checking for num_rules */
- rcoll = crda_get_file_ptr(db, dblen,
+ rcoll = reglib_get_file_ptr(db, dblen,
sizeof(*rcoll) + num_rules * sizeof(uint32_t),
country->reg_collection_ptr);

@@ -279,7 +279,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
return NULL;
}

- header = crda_get_file_ptr(db, dblen, sizeof(*header), 0);
+ header = reglib_get_file_ptr(db, dblen, sizeof(*header), 0);

if (ntohl(header->magic) != REGDB_MAGIC)
goto out;
@@ -299,7 +299,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
goto out;

num_countries = ntohl(header->reg_country_num);
- countries = crda_get_file_ptr(db, dblen,
+ countries = reglib_get_file_ptr(db, dblen,
sizeof(struct regdb_file_reg_country) * num_countries,
header->reg_country_ptr);

@@ -350,7 +350,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
return NULL;
}

- header = crda_get_file_ptr(db, dblen, sizeof(*header), 0);
+ header = reglib_get_file_ptr(db, dblen, sizeof(*header), 0);

if (ntohl(header->magic) != REGDB_MAGIC)
goto out;
@@ -370,7 +370,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
goto out;

num_countries = ntohl(header->reg_country_num);
- countries = crda_get_file_ptr(db, dblen,
+ countries = reglib_get_file_ptr(db, dblen,
sizeof(struct regdb_file_reg_country) * num_countries,
header->reg_country_ptr);

diff --git a/reglib.h b/reglib.h
index 529772d..3510889 100644
--- a/reglib.h
+++ b/reglib.h
@@ -70,7 +70,7 @@ static inline uint32_t min(uint32_t a, uint32_t b)
return (a > b) ? b : a;
}

-void *crda_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr);
+void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr);
int crda_verify_db_signature(uint8_t *db, int dblen, int siglen);

const struct ieee80211_regdomain *
--
1.7.10.4


2013-05-31 02:12:24

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 37/40] crda: move regdbprint to its own helper

From: "Luis R. Rodriguez" <[email protected]>

We'll later move this to reglib but first we have
to clean up the print utility to make it more general.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
regdbdump.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/regdbdump.c b/regdbdump.c
index ea14730..edf3e7c 100644
--- a/regdbdump.c
+++ b/regdbdump.c
@@ -2,26 +2,35 @@
#include <errno.h>
#include "reglib.h"

-int main(int argc, char **argv)
+static int reglib_regdbdump(char *regdb_file)
{
const struct ieee80211_regdomain *rd = NULL;
unsigned int idx = 0;

- if (argc != 2) {
- fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
- return 2;
- }
-
- reglib_for_each_country(rd, idx, argv[1]) {
+ reglib_for_each_country(rd, idx, regdb_file) {
reglib_print_regdom(rd);
free((struct ieee80211_regdomain *) rd);
}

if (!idx) {
- printf("Invalid or empty regulatory file, note: "
+ fprintf(stderr, "Invalid or empty regulatory file, note: "
"a binary regulatory file should be used.\n");
return -EINVAL;
}

return 0;
}
+
+int main(int argc, char **argv)
+{
+ int r;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <regulatory-binary-file>\n", argv[0]);
+ return 2;
+ }
+
+ r = reglib_regdbdump(argv[1]);
+
+ return r;
+}
--
1.7.10.4


2013-05-31 02:11:51

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 29/40] crda: rename is_alpha2() to reglib_is_alpha2()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/reglib.h b/reglib.h
index 41827cd..b7c5d08 100644
--- a/reglib.h
+++ b/reglib.h
@@ -45,7 +45,7 @@ static inline int reglib_isalpha_upper(char letter)
return 0;
}

-static inline int is_alpha2(const char *alpha2)
+static inline int reglib_is_alpha2(const char *alpha2)
{
if (reglib_isalpha_upper(alpha2[0]) && reglib_isalpha_upper(alpha2[1]))
return 1;
@@ -54,7 +54,7 @@ static inline int is_alpha2(const char *alpha2)

static inline int is_valid_regdom(const char *alpha2)
{
- if (!is_alpha2(alpha2) && !reglib_is_world_regdom(alpha2))
+ if (!reglib_is_alpha2(alpha2) && !reglib_is_world_regdom(alpha2))
return 0;

return 1;
--
1.7.10.4


2013-05-31 02:12:20

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 36/40] crda: move reglib_intersect_regdb() to reglib

From: "Luis R. Rodriguez" <[email protected]>

There are no functional changes in this change.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 63 -----------------------------------------------------------
reglib.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
reglib.h | 13 ++++++++++++
3 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/intersect.c b/intersect.c
index b9e3429..56d0d35 100644
--- a/intersect.c
+++ b/intersect.c
@@ -6,69 +6,6 @@

#include "reglib.h"

-/**
- * reglib_intersect_regdb - intersects a regulatory database
- *
- * @regdb_file: the regulatory database to intersect
- *
- * Goes through an entire regulatory database and intersects all regulatory
- * domains. This will skip any regulatory marked with an alpha2 of '00', which
- * is used to indicate a world regulatory domain. If intersection is able
- * to find rules that fit all regulatory domains it return a regulatory
- * domain with such rules otherwise it returns NULL.
- */
-const struct ieee80211_regdomain *reglib_intersect_regdb(char *regdb_file)
-{
- const struct ieee80211_regdomain *rd;
- struct ieee80211_regdomain *prev_rd_intsct = NULL, *rd_intsct = NULL;
- int intersected = 0;
- unsigned int idx = 0;
-
- reglib_for_each_country(rd, idx, regdb_file) {
- if (reglib_is_world_regdom((const char *) rd->alpha2)) {
- free((struct ieee80211_regdomain *) rd);
- continue;
- }
-
- if (!prev_rd_intsct) {
- prev_rd_intsct = (struct ieee80211_regdomain *) rd;
- continue;
- }
-
- if (rd_intsct) {
- free(prev_rd_intsct);
- prev_rd_intsct = (struct ieee80211_regdomain *) rd_intsct;
- }
-
- rd_intsct = reglib_intersect_rds(prev_rd_intsct, rd);
- if (!rd_intsct) {
- free(prev_rd_intsct);
- free((struct ieee80211_regdomain *) rd);
- return NULL;
- }
-
- intersected++;
- free((struct ieee80211_regdomain *) rd);
- }
-
- if (!idx)
- return NULL;
-
- if (intersected <= 0) {
- rd_intsct = prev_rd_intsct;
- prev_rd_intsct = NULL;
- if (idx > 1) {
- free(rd_intsct);
- return NULL;
- }
- }
-
- if (prev_rd_intsct)
- free(prev_rd_intsct);
-
- return rd_intsct;
-}
-
int main(int argc, char **argv)
{
const struct ieee80211_regdomain *rd;
diff --git a/reglib.c b/reglib.c
index 4643fa8..67f5b2b 100644
--- a/reglib.c
+++ b/reglib.c
@@ -554,6 +554,58 @@ reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
return rd;
}

+const struct ieee80211_regdomain *reglib_intersect_regdb(char *regdb_file)
+{
+ const struct ieee80211_regdomain *rd;
+ struct ieee80211_regdomain *prev_rd_intsct = NULL, *rd_intsct = NULL;
+ int intersected = 0;
+ unsigned int idx = 0;
+
+ reglib_for_each_country(rd, idx, regdb_file) {
+ if (reglib_is_world_regdom((const char *) rd->alpha2)) {
+ free((struct ieee80211_regdomain *) rd);
+ continue;
+ }
+
+ if (!prev_rd_intsct) {
+ prev_rd_intsct = (struct ieee80211_regdomain *) rd;
+ continue;
+ }
+
+ if (rd_intsct) {
+ free(prev_rd_intsct);
+ prev_rd_intsct = (struct ieee80211_regdomain *) rd_intsct;
+ }
+
+ rd_intsct = reglib_intersect_rds(prev_rd_intsct, rd);
+ if (!rd_intsct) {
+ free(prev_rd_intsct);
+ free((struct ieee80211_regdomain *) rd);
+ return NULL;
+ }
+
+ intersected++;
+ free((struct ieee80211_regdomain *) rd);
+ }
+
+ if (!idx)
+ return NULL;
+
+ if (intersected <= 0) {
+ rd_intsct = prev_rd_intsct;
+ prev_rd_intsct = NULL;
+ if (idx > 1) {
+ free(rd_intsct);
+ return NULL;
+ }
+ }
+
+ if (prev_rd_intsct)
+ free(prev_rd_intsct);
+
+ return rd_intsct;
+}
+
static const char *dfs_domain_name(enum regdb_dfs_regions region)
{
switch (region) {
diff --git a/reglib.h b/reglib.h
index d89fcd5..2681164 100644
--- a/reglib.h
+++ b/reglib.h
@@ -90,4 +90,17 @@ struct ieee80211_regdomain *
reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
const struct ieee80211_regdomain *rd2);

+/**
+ * reglib_intersect_regdb - intersects a regulatory database
+ *
+ * @regdb_file: the regulatory database to intersect
+ *
+ * Goes through an entire regulatory database and intersects all regulatory
+ * domains. This will skip any regulatory marked with an alpha2 of '00', which
+ * is used to indicate a world regulatory domain. If intersection is able
+ * to find rules that fit all regulatory domains it return a regulatory
+ * domain with such rules otherwise it returns NULL.
+ */
+const struct ieee80211_regdomain *reglib_intersect_regdb(char *regdb_file);
+
#endif
--
1.7.10.4


2013-05-31 02:12:33

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 39/40] crda: pass struct reglib_regdb_ctx to country2rd()

From: "Luis R. Rodriguez" <[email protected]>

This consolidates the number of arguments.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/reglib.c b/reglib.c
index 6f076ff..ff05aaa 100644
--- a/reglib.c
+++ b/reglib.c
@@ -298,18 +298,18 @@ static void reg_rule2rd(uint8_t *db, int dblen,

/* Converts a file regdomain to ieee80211_regdomain, easier to manage */
const static struct ieee80211_regdomain *
-country2rd(uint8_t *db, int dblen,
+country2rd(const struct reglib_regdb_ctx *ctx,
struct regdb_file_reg_country *country)
{
struct regdb_file_reg_rules_collection *rcoll;
struct ieee80211_regdomain *rd;
int i, num_rules, size_of_rd;

- rcoll = reglib_get_file_ptr(db, dblen, sizeof(*rcoll),
- country->reg_collection_ptr);
+ rcoll = reglib_get_file_ptr(ctx->db, ctx->dblen, sizeof(*rcoll),
+ country->reg_collection_ptr);
num_rules = ntohl(rcoll->reg_rule_num);
/* re-get pointer with sanity checking for num_rules */
- rcoll = reglib_get_file_ptr(db, dblen,
+ rcoll = reglib_get_file_ptr(ctx->db, ctx->dblen,
sizeof(*rcoll) + num_rules * sizeof(uint32_t),
country->reg_collection_ptr);

@@ -328,7 +328,7 @@ country2rd(uint8_t *db, int dblen,
rd->n_reg_rules = num_rules;

for (i = 0; i < num_rules; i++) {
- reg_rule2rd(db, dblen, rcoll->reg_rule_ptrs[i],
+ reg_rule2rd(ctx->db, ctx->dblen, rcoll->reg_rule_ptrs[i],
&rd->reg_rules[i]);
}

@@ -351,7 +351,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file)

country = ctx->countries + idx;

- rd = country2rd(ctx->db, ctx->dblen, country);
+ rd = country2rd(ctx, country);
if (!rd)
goto out;

@@ -384,7 +384,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
if (!found_country)
goto out;

- rd = country2rd(ctx->db, ctx->dblen, country);
+ rd = country2rd(ctx, country);
if (!rd)
goto out;

--
1.7.10.4


2013-05-31 02:12:03

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 32/40] crda: rename min() to reglib_min()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
reglib.c | 8 ++++----
reglib.h | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/reglib.c b/reglib.c
index 57bb22b..4643fa8 100644
--- a/reglib.c
+++ b/reglib.c
@@ -440,18 +440,18 @@ static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,

freq_range->start_freq_khz = reglib_max(freq_range1->start_freq_khz,
freq_range2->start_freq_khz);
- freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
+ freq_range->end_freq_khz = reglib_min(freq_range1->end_freq_khz,
freq_range2->end_freq_khz);
- freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
+ freq_range->max_bandwidth_khz = reglib_min(freq_range1->max_bandwidth_khz,
freq_range2->max_bandwidth_khz);

freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
if (freq_range->max_bandwidth_khz > freq_diff)
freq_range->max_bandwidth_khz = freq_diff;

- power_rule->max_eirp = min(power_rule1->max_eirp,
+ power_rule->max_eirp = reglib_min(power_rule1->max_eirp,
power_rule2->max_eirp);
- power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
+ power_rule->max_antenna_gain = reglib_min(power_rule1->max_antenna_gain,
power_rule2->max_antenna_gain);

intersected_rule->flags = rule1->flags | rule2->flags;
diff --git a/reglib.h b/reglib.h
index 21518d2..8a31e0d 100644
--- a/reglib.h
+++ b/reglib.h
@@ -65,7 +65,7 @@ static inline uint32_t reglib_max(uint32_t a, uint32_t b)
return (a > b) ? a : b;
}

-static inline uint32_t min(uint32_t a, uint32_t b)
+static inline uint32_t reglib_min(uint32_t a, uint32_t b)
{
return (a > b) ? b : a;
}
--
1.7.10.4


2013-05-31 02:11:55

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 30/40] crda: rename is_valid_regdom() to reglib_is_valid_regdom()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
crda.c | 2 +-
reglib.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/crda.c b/crda.c
index fc7a25f..2a601eb 100644
--- a/crda.c
+++ b/crda.c
@@ -170,7 +170,7 @@ int main(int argc, char **argv)
return -EINVAL;
}

- if (!is_valid_regdom(env_country)) {
+ if (!reglib_is_valid_regdom(env_country)) {
fprintf(stderr, "COUNTRY environment variable must be an "
"ISO ISO 3166-1-alpha-2 (uppercase) or 00\n");
return -EINVAL;
diff --git a/reglib.h b/reglib.h
index b7c5d08..8ed94d9 100644
--- a/reglib.h
+++ b/reglib.h
@@ -52,7 +52,7 @@ static inline int reglib_is_alpha2(const char *alpha2)
return 0;
}

-static inline int is_valid_regdom(const char *alpha2)
+static inline int reglib_is_valid_regdom(const char *alpha2)
{
if (!reglib_is_alpha2(alpha2) && !reglib_is_world_regdom(alpha2))
return 0;
--
1.7.10.4


2013-05-31 02:12:37

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 40/40] crda: make reglib_for_each_country() use the reglib context

From: "Luis R. Rodriguez" <[email protected]>

This allows users of reglib to iterate over the regdb
with just one open() and mmap() to be kept sharing as
much code as possible. This makes the regdbdump and
intersection code use the context therefore sharing
all that boiler plate code.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 15 +++++++++++++--
regdbdump.c | 28 ++++++++++++++--------------
reglib.c | 23 +++++++++--------------
reglib.h | 11 ++++++-----
4 files changed, 42 insertions(+), 35 deletions(-)

diff --git a/intersect.c b/intersect.c
index 56d0d35..ae9ca1b 100644
--- a/intersect.c
+++ b/intersect.c
@@ -8,21 +8,32 @@

int main(int argc, char **argv)
{
+ const struct reglib_regdb_ctx *ctx;
const struct ieee80211_regdomain *rd;

if (argc != 2) {
- fprintf(stderr, "You must specify a file\n");
+ fprintf(stderr, "Usage: %s <regulatory-binary-file>\n", argv[0]);
return -EINVAL;
}

- rd = reglib_intersect_regdb(argv[1]);
+ ctx = reglib_malloc_regdb_ctx(argv[1]);
+ if (!ctx) {
+ fprintf(stderr, "Invalid or empty regulatory file, note: "
+ "a binary regulatory file should be used.\n");
+ return -EINVAL;
+ }
+
+ rd = reglib_intersect_regdb(ctx);
if (!rd) {
fprintf(stderr, "Intersection not possible\n");
+ reglib_free_regdb_ctx(ctx);
return -ENOENT;
}

reglib_print_regdom(rd);
+
free((struct ieee80211_regdomain *) rd);

+ reglib_free_regdb_ctx(ctx);
return 0;
}
diff --git a/regdbdump.c b/regdbdump.c
index edf3e7c..cc7eb85 100644
--- a/regdbdump.c
+++ b/regdbdump.c
@@ -2,35 +2,35 @@
#include <errno.h>
#include "reglib.h"

-static int reglib_regdbdump(char *regdb_file)
+static void reglib_regdbdump(const struct reglib_regdb_ctx *ctx)
{
const struct ieee80211_regdomain *rd = NULL;
unsigned int idx = 0;

- reglib_for_each_country(rd, idx, regdb_file) {
+ reglib_for_each_country(rd, idx, ctx) {
reglib_print_regdom(rd);
free((struct ieee80211_regdomain *) rd);
}
-
- if (!idx) {
- fprintf(stderr, "Invalid or empty regulatory file, note: "
- "a binary regulatory file should be used.\n");
- return -EINVAL;
- }
-
- return 0;
}

int main(int argc, char **argv)
{
- int r;
+ const struct reglib_regdb_ctx *ctx;

if (argc != 2) {
fprintf(stderr, "Usage: %s <regulatory-binary-file>\n", argv[0]);
- return 2;
+ return -EINVAL;
+ }
+
+ ctx = reglib_malloc_regdb_ctx(argv[1]);
+ if (!ctx) {
+ fprintf(stderr, "Invalid or empty regulatory file, note: "
+ "a binary regulatory file should be used.\n");
+ return -EINVAL;
}

- r = reglib_regdbdump(argv[1]);
+ reglib_regdbdump(ctx);
+ reglib_free_regdb_ctx(ctx);

- return r;
+ return 0;
}
diff --git a/reglib.c b/reglib.c
index ff05aaa..c4d00f8 100644
--- a/reglib.c
+++ b/reglib.c
@@ -336,28 +336,19 @@ country2rd(const struct reglib_regdb_ctx *ctx,
}

const struct ieee80211_regdomain *
-reglib_get_rd_idx(unsigned int idx, const char *file)
+reglib_get_rd_idx(unsigned int idx, const struct reglib_regdb_ctx *ctx)
{
- const struct reglib_regdb_ctx *ctx;
struct regdb_file_reg_country *country;
- const struct ieee80211_regdomain *rd = NULL;

- ctx = reglib_malloc_regdb_ctx(file);
if (!ctx)
return NULL;

if (idx >= ctx->num_countries)
- goto out;
+ return NULL;

country = ctx->countries + idx;

- rd = country2rd(ctx, country);
- if (!rd)
- goto out;
-
-out:
- reglib_free_regdb_ctx(ctx);
- return rd;
+ return country2rd(ctx, country);
}

const struct ieee80211_regdomain *
@@ -552,14 +543,18 @@ reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
return rd;
}

-const struct ieee80211_regdomain *reglib_intersect_regdb(char *regdb_file)
+const struct ieee80211_regdomain *
+reglib_intersect_regdb(const struct reglib_regdb_ctx *ctx)
{
const struct ieee80211_regdomain *rd;
struct ieee80211_regdomain *prev_rd_intsct = NULL, *rd_intsct = NULL;
int intersected = 0;
unsigned int idx = 0;

- reglib_for_each_country(rd, idx, regdb_file) {
+ if (!ctx)
+ return NULL;
+
+ reglib_for_each_country(rd, idx, ctx) {
if (reglib_is_world_regdom((const char *) rd->alpha2)) {
free((struct ieee80211_regdomain *) rd);
continue;
diff --git a/reglib.h b/reglib.h
index f1bd6b8..86087e3 100644
--- a/reglib.h
+++ b/reglib.h
@@ -139,12 +139,12 @@ const struct reglib_regdb_ctx *reglib_malloc_regdb_ctx(const char *regdb_file);
void reglib_free_regdb_ctx(const struct reglib_regdb_ctx *regdb_ctx);

const struct ieee80211_regdomain *
-reglib_get_rd_idx(unsigned int idx, const char *file);
+reglib_get_rd_idx(unsigned int idx, const struct reglib_regdb_ctx *ctx);

-#define reglib_for_each_country(__rd, __idx, __file) \
- for (__rd = reglib_get_rd_idx(__idx, __file); \
+#define reglib_for_each_country(__rd, __idx, __ctx) \
+ for (__rd = reglib_get_rd_idx(__idx, __ctx); \
__rd != NULL; \
- __rd = reglib_get_rd_idx(++__idx, __file)) \
+ __rd = reglib_get_rd_idx(++__idx, __ctx)) \

const struct ieee80211_regdomain *
reglib_get_rd_alpha2(const char *alpha2, const char *file);
@@ -166,6 +166,7 @@ reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
* to find rules that fit all regulatory domains it return a regulatory
* domain with such rules otherwise it returns NULL.
*/
-const struct ieee80211_regdomain *reglib_intersect_regdb(char *regdb_file);
+const struct ieee80211_regdomain *
+reglib_intersect_regdb(const struct reglib_regdb_ctx *ctx);

#endif
--
1.7.10.4


2013-05-31 02:11:42

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 27/40] crda: rename is_world_regdom() to reglib_is_world_regdom()

From: "Luis R. Rodriguez" <[email protected]>

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 2 +-
reglib.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/intersect.c b/intersect.c
index 22b3225..bc1e63e 100644
--- a/intersect.c
+++ b/intersect.c
@@ -24,7 +24,7 @@ int main(int argc, char **argv)

/* We intersect only when we have to rd structures ready */
reglib_for_each_country(rd, idx, argv[1]) {
- if (is_world_regdom((const char *) rd->alpha2)) {
+ if (reglib_is_world_regdom((const char *) rd->alpha2)) {
free((struct ieee80211_regdomain *) rd);
continue;
}
diff --git a/reglib.h b/reglib.h
index 4c0ec6d..98aadcc 100644
--- a/reglib.h
+++ b/reglib.h
@@ -31,7 +31,7 @@ struct ieee80211_regdomain {
struct ieee80211_reg_rule reg_rules[];
};

-static inline int is_world_regdom(const char *alpha2)
+static inline int reglib_is_world_regdom(const char *alpha2)
{
if (alpha2[0] == '0' && alpha2[1] == '0')
return 1;
@@ -54,7 +54,7 @@ static inline int is_alpha2(const char *alpha2)

static inline int is_valid_regdom(const char *alpha2)
{
- if (!is_alpha2(alpha2) && !is_world_regdom(alpha2))
+ if (!is_alpha2(alpha2) && !reglib_is_world_regdom(alpha2))
return 0;

return 1;
--
1.7.10.4


2013-05-31 02:09:54

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 04/40] crda: constify usage of struct ieee80211_regdomain

From: "Luis R. Rodriguez" <[email protected]>

Where we can use const.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
crda.c | 12 ++++++------
intersect.c | 33 ++++++++++++++++++---------------
print-regdom.c | 8 ++++----
regdbdump.c | 4 ++--
reglib.c | 10 +++++-----
reglib.h | 6 +++---
6 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/crda.c b/crda.c
index cdbc69a..fc7a25f 100644
--- a/crda.c
+++ b/crda.c
@@ -116,10 +116,10 @@ static int error_handler(struct sockaddr_nl __attribute__((unused)) *nla,
exit(err->error);
}

-static int put_reg_rule(struct ieee80211_reg_rule *rule, struct nl_msg *msg)
+static int put_reg_rule(const struct ieee80211_reg_rule *rule, struct nl_msg *msg)
{
- struct ieee80211_freq_range *freq_range;
- struct ieee80211_power_rule *power_rule;
+ const struct ieee80211_freq_range *freq_range;
+ const struct ieee80211_power_rule *power_rule;

freq_range = &rule->freq_range;
power_rule = &rule->power_rule;
@@ -149,7 +149,7 @@ int main(int argc, char **argv)
int finished = 0;

struct nlattr *nl_reg_rules;
- struct ieee80211_regdomain *rd = NULL;
+ const struct ieee80211_regdomain *rd = NULL;

const char *regdb_paths[] = {
"/usr/local/lib/crda/regulatory.bin", /* Users/preloads can override */
@@ -199,7 +199,7 @@ int main(int argc, char **argv)

r = nl80211_init(&nlstate);
if (r) {
- free(rd);
+ free((struct ieee80211_regdomain *) rd);
return -EIO;
}

@@ -267,7 +267,7 @@ nla_put_failure:
nlmsg_free(msg);
out:
nl80211_cleanup(&nlstate);
- free(rd);
+ free((struct ieee80211_regdomain *) rd);

return r;
}
diff --git a/intersect.c b/intersect.c
index bd2976f..59fd007 100644
--- a/intersect.c
+++ b/intersect.c
@@ -39,13 +39,14 @@ static int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)

/* Helper for regdom_intersect(), this does the real
* mathematical intersection fun */
-static int reg_rules_intersect(
- struct ieee80211_reg_rule *rule1,
- struct ieee80211_reg_rule *rule2,
- struct ieee80211_reg_rule *intersected_rule)
+static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
+ const struct ieee80211_reg_rule *rule2,
+ struct ieee80211_reg_rule *intersected_rule)
{
- struct ieee80211_freq_range *freq_range1, *freq_range2, *freq_range;
- struct ieee80211_power_rule *power_rule1, *power_rule2, *power_rule;
+ const struct ieee80211_freq_range *freq_range1, *freq_range2;
+ struct ieee80211_freq_range *freq_range;
+ const struct ieee80211_power_rule *power_rule1, *power_rule2;
+ struct ieee80211_power_rule *power_rule;
uint32_t freq_diff;

freq_range1 = &rule1->freq_range;
@@ -93,14 +94,15 @@ static int reg_rules_intersect(
* resulting intersection of rules between rd1 and rd2. We will
* malloc() this structure for you.
*/
-static struct ieee80211_regdomain *regdom_intersect(
- struct ieee80211_regdomain *rd1,
- struct ieee80211_regdomain *rd2)
+static struct ieee80211_regdomain *
+regdom_intersect(const struct ieee80211_regdomain *rd1,
+ const struct ieee80211_regdomain *rd2)
{
int r, size_of_regd;
unsigned int x, y;
unsigned int num_rules = 0, rule_idx = 0;
- struct ieee80211_reg_rule *rule1, *rule2, *intersected_rule;
+ const struct ieee80211_reg_rule *rule1, *rule2;
+ struct ieee80211_reg_rule *intersected_rule;
struct ieee80211_regdomain *rd;
/* This is just a dummy holder to help us count */
struct ieee80211_reg_rule irule;
@@ -174,7 +176,8 @@ static struct ieee80211_regdomain *regdom_intersect(
int main(int argc, char **argv)
{
int r = 0;
- struct ieee80211_regdomain *prev_world = NULL, *rd = NULL, *world = NULL;
+ const struct ieee80211_regdomain *rd;
+ struct ieee80211_regdomain *prev_world = NULL, *world = NULL;
int intersected = 0;
unsigned int idx = 0;

@@ -189,13 +192,13 @@ int main(int argc, char **argv)
continue;

if (!prev_world) {
- prev_world = rd;
+ prev_world = (struct ieee80211_regdomain *) rd;
continue;
}

if (world) {
free(prev_world);
- prev_world = world;
+ prev_world = (struct ieee80211_regdomain *) world;
}

world = regdom_intersect(prev_world, rd);
@@ -235,7 +238,7 @@ int main(int argc, char **argv)
}

if (idx == 1) {
- world = rd;
+ world = (struct ieee80211_regdomain *) rd;
rd = NULL;
}

@@ -255,7 +258,7 @@ out:
return r;
}
if (intersected > 1) {
- free(rd);
+ free((struct ieee80211_regdomain *)rd);
free(prev_world);
}
free(world);
diff --git a/print-regdom.c b/print-regdom.c
index 9c65872..abd6488 100644
--- a/print-regdom.c
+++ b/print-regdom.c
@@ -23,10 +23,10 @@ static const char *dfs_domain_name(enum nl80211_dfs_regions region)
}
}

-static void print_reg_rule(struct ieee80211_reg_rule *rule)
+static void print_reg_rule(const struct ieee80211_reg_rule *rule)
{
- struct ieee80211_freq_range *freq;
- struct ieee80211_power_rule *power;
+ const struct ieee80211_freq_range *freq;
+ const struct ieee80211_power_rule *power;

freq = &rule->freq_range;
power = &rule->power_rule;
@@ -70,7 +70,7 @@ static void print_reg_rule(struct ieee80211_reg_rule *rule)
printf("\n");
}

-void print_regdom(struct ieee80211_regdomain *rd)
+void print_regdom(const struct ieee80211_regdomain *rd)
{
unsigned int i;
printf("country %.2s: %s\n", rd->alpha2,
diff --git a/regdbdump.c b/regdbdump.c
index 6f9592a..26cbef7 100644
--- a/regdbdump.c
+++ b/regdbdump.c
@@ -3,7 +3,7 @@

int main(int argc, char **argv)
{
- struct ieee80211_regdomain *rd = NULL;
+ const struct ieee80211_regdomain *rd = NULL;
unsigned int idx = 0;

if (argc != 2) {
@@ -13,7 +13,7 @@ int main(int argc, char **argv)

reglib_for_each_country(rd, idx, argv[1]) {
print_regdom(rd);
- free(rd);
+ free((struct ieee80211_regdomain *) rd);
}

return 0;
diff --git a/reglib.c b/reglib.c
index 1fafd37..0b1599b 100644
--- a/reglib.c
+++ b/reglib.c
@@ -188,7 +188,7 @@ static void reg_rule2rd(uint8_t *db, int dblen,
}

/* Converts a file regdomain to ieee80211_regdomain, easier to manage */
-static struct ieee80211_regdomain *
+const static struct ieee80211_regdomain *
country2rd(uint8_t *db, int dblen,
struct regdb_file_reg_country *country)
{
@@ -226,7 +226,7 @@ country2rd(uint8_t *db, int dblen,
return rd;
}

-struct ieee80211_regdomain *
+const struct ieee80211_regdomain *
reglib_get_rd_idx(unsigned int idx, const char *file)
{
int fd;
@@ -235,7 +235,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
struct regdb_file_header *header;
struct regdb_file_reg_country *countries;
int dblen, siglen, num_countries;
- struct ieee80211_regdomain *rd = NULL;
+ const struct ieee80211_regdomain *rd = NULL;
struct regdb_file_reg_country *country;

fd = open(file, O_RDONLY);
@@ -288,7 +288,7 @@ reglib_get_rd_idx(unsigned int idx, const char *file)
return rd;
}

-struct ieee80211_regdomain *
+const struct ieee80211_regdomain *
reglib_get_rd_alpha2(const char *alpha2, const char *file)
{
int fd;
@@ -297,7 +297,7 @@ reglib_get_rd_alpha2(const char *alpha2, const char *file)
struct regdb_file_header *header;
struct regdb_file_reg_country *countries;
int dblen, siglen, num_countries;
- struct ieee80211_regdomain *rd = NULL;
+ const struct ieee80211_regdomain *rd = NULL;
struct regdb_file_reg_country *country;
unsigned int i;
bool found_country = false;
diff --git a/reglib.h b/reglib.h
index 9b9bd5c..e5da38b 100644
--- a/reglib.h
+++ b/reglib.h
@@ -73,7 +73,7 @@ static inline uint32_t min(uint32_t a, uint32_t b)
void *crda_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr);
int crda_verify_db_signature(uint8_t *db, int dblen, int siglen);

-struct ieee80211_regdomain *
+const struct ieee80211_regdomain *
reglib_get_rd_idx(unsigned int idx, const char *file);

#define reglib_for_each_country(__rd, __idx, __file) \
@@ -82,10 +82,10 @@ reglib_get_rd_idx(unsigned int idx, const char *file);
__rd = reglib_get_rd_idx(__idx, __file), \
__idx++)

-struct ieee80211_regdomain *
+const struct ieee80211_regdomain *
reglib_get_rd_alpha2(const char *alpha2, const char *file);

/* reg helpers */
-void print_regdom(struct ieee80211_regdomain *rd);
+void print_regdom(const struct ieee80211_regdomain *rd);

#endif
--
1.7.10.4


2013-05-31 02:10:16

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 07/40] crda: fix regression when using reglib_for_each_country()

From: "Luis R. Rodriguez" <[email protected]>

When reglib_for_each_country() was introduced via ebcbfcf4
its users were not updated with the possibility of rd being
NULL due to the fact that the parsed file could be invalid
or empty. The users

[email protected] ~/devel/crda (git::master)$ git describe --contains 7a09f4dd
v1.1.3~8

[email protected] ~/devel/crda (git::master)$ git describe --contains ebcbfcf45
v1.1.3~9

This regression exists since v1.1. Fix this.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
intersect.c | 6 ++++++
regdbdump.c | 7 +++++++
2 files changed, 13 insertions(+)

diff --git a/intersect.c b/intersect.c
index 1c00a67..8f826a0 100644
--- a/intersect.c
+++ b/intersect.c
@@ -73,6 +73,12 @@ int main(int argc, char **argv)
intersected++;
}

+ if (!idx) {
+ printf("Invalid or empty regulatory file, note: "
+ "a binary regulatory file should be used.\n");
+ return -EINVAL;
+ }
+
if (idx == 1) {
world = (struct ieee80211_regdomain *) rd;
rd = NULL;
diff --git a/regdbdump.c b/regdbdump.c
index 26cbef7..dcbed71 100644
--- a/regdbdump.c
+++ b/regdbdump.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <errno.h>
#include "reglib.h"

int main(int argc, char **argv)
@@ -16,5 +17,11 @@ int main(int argc, char **argv)
free((struct ieee80211_regdomain *) rd);
}

+ if (!idx) {
+ printf("Invalid or empty regulatory file, note: "
+ "a binary regulatory file should be used.\n");
+ return -EINVAL;
+ }
+
return 0;
}
--
1.7.10.4


2013-06-30 23:08:38

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 00/40] crda: reglib enhancements

On Thu, May 30, 2013 at 7:08 PM, Luis R. Rodriguez
<[email protected]> wrote:
> From: "Luis R. Rodriguez" <[email protected]>
>
> I've hinted I've been working towards a regdb regulatory
> library. This pushes that idea further as I was inclined
> recently to develop a union algorithm and saw we still
> had quite a bit of work to be able to share more consistently.
>
> I'll likely be using the intersection code as basis for this
> and as such I've cleaned that up and also ran valgrind over
> most of the code. I believe I've fixed all reglib memory
> related issues the rest of things valgrind bitches about
> are due to netlink.
>
> [email protected] ~ $ cat .valgrindrc
> --memcheck:leak-check=full
> --memcheck:leak-resolution=high
> --memcheck:show-reachable=yes
> --memcheck:num-callers=50
>
> If this looks OK I'll next start working towards the union
> code. The purpose of this is two fold:
>
> Help build regulatory domains out of arbitrary custom
> regulatory definitions and to also allow us to build
> more thorough world regulatory domains that have passive
> scan flags on regulatory rules that are do not fit the
> intersection.
>
> Luis R. Rodriguez (40):
> crda: make reg_rules_intersect() style match Linux
> crda: port over Linux is_valid_reg_rule() change bd05f28e
> crda: remove verbose errors out of regdom_intersect()
> crda: constify usage of struct ieee80211_regdomain
> crda: remove unused BUG_ON() from intersect.c
> crda: move regdom_intersect() to reglib
> crda: fix regression when using reglib_for_each_country()
> crda: move intersection if first attempt failed
> crda: do not double count on reglib_for_each_country()
> crda: annotate intersection worst case scenerio
> crda: fix intersect.c memory management
> crda: explicitly munmap() on reglib_get_rd_alpha2()
> crda: explicitly close file descriptor and munmap() on failures
> crda: separate crda_verify_db_signature() implementations
> crda: use gcry_sexp_release() on crda_verify_db_signature()
> crda: explicitly use close() and munmap() on reglib_get_rd_alpha2()
> crda: use gcry_mpi_release() when using gcry_mpi_scan()
> crda: rename world and prev_world on intersect.c
> crda: remove verbosity out of intersect.c
> crda: rename regdom_intersect() to reglib_intersect_rds()
> crda: rename crda_get_file_ptr() to reglib_get_file_ptr()
> crda: rename crda_verify_db_signature() to
> reglib_verify_db_signature()
> crda: rename print_regdom() to reglib_print_regdom()
> crda: add regdb_dfs_regions
> crda: make print-regdom use internal flags
> crda: move reg print helpers to reglib
> crda: rename is_world_regdom() to reglib_is_world_regdom()
> crda: rename isalpha_upper() to reglib_isalpha_upper()
> crda: rename is_alpha2() to reglib_is_alpha2()
> crda: rename is_valid_regdom() to reglib_is_valid_regdom()
> crda: rename max() to reglib_max()
> crda: rename min() to reglib_min()
> crda: fix spacing on reglib_for_each_country()
> crda: clarify intersect.c only computes an intersection
> crda: separate intersecting a full db into a helper
> crda: move reglib_intersect_regdb() to reglib
> crda: move regdbprint to its own helper
> crda: add reglib regdb context helpers:
> reglib_(malloc|free)_regdb_ctx()
> crda: pass struct reglib_regdb_ctx to country2rd()
> crda: make reglib_for_each_country() use the reglib context
>
> Makefile | 4 +-
> crda.c | 14 +-
> intersect.c | 264 ++---------------------------
> print-regdom.c | 81 ---------
> regdb.h | 24 ++-
> regdbdump.c | 30 +++-
> reglib.c | 518 +++++++++++++++++++++++++++++++++++++++++++++-----------
> reglib.h | 125 +++++++++++---
> 8 files changed, 589 insertions(+), 471 deletions(-)
> delete mode 100644 print-regdom.c

I've applied and pushed these given I saw no opposition. Please let me
know if you run into any issues. I may cut a new release soon but I
have a few other ideas I was considering implementing.

Luis