Commit 94858a2f authored by Luis R. Rodriguez's avatar Luis R. Rodriguez

Add conversion utitlies, standardize printing

This adds country2rd() and friends which allows us to
use more friendlier data structures that are not big endian
and standardizes printing this new rd structure.
Signed-off-by: 's avatarLuis R. Rodriguez <lrodriguez@atheros.com>
parent 043a1f9b
......@@ -9,57 +9,6 @@
#include "regdb.h"
#include "reglib.h"
static void print_reg_rule(__u8 *db, int dblen, __be32 ruleptr)
{
struct regdb_file_reg_rule *rule;
struct regdb_file_freq_range *freq;
struct regdb_file_power_rule *power;
__u32 flags;
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);
printf("\t(%.3f - %.3f @ %.3f), ",
((float)ntohl(freq->start_freq))/1000.0,
((float)ntohl(freq->end_freq))/1000.0,
((float)ntohl(freq->max_bandwidth))/1000.0);
printf("(");
if (power->max_antenna_gain)
printf("%.2f, ", ((float)ntohl(power->max_antenna_gain)/100.0));
else
printf("N/A, ");
if (power->max_eirp)
printf("%.2f)", ((float)ntohl(power->max_eirp)/100.0));
else
printf("N/A)");
flags = ntohl(rule->flags);
if (flags & RRF_NO_OFDM)
printf(", NO-OFDM");
if (flags & RRF_NO_CCK)
printf(", NO-CCK");
if (flags & RRF_NO_INDOOR)
printf(", NO-INDOOR");
if (flags & RRF_NO_OUTDOOR)
printf(", NO-OUTDOOR");
if (flags & RRF_DFS)
printf(", DFS");
if (flags & RRF_PTP_ONLY)
printf(", PTP-ONLY");
if (flags & RRF_PTMP_ONLY)
printf(", PTMP-ONLY");
if (flags & RRF_PASSIVE_SCAN)
printf(", PASSIVE-SCAN");
if (flags & RRF_NO_IBSS)
printf(", NO-IBSS");
printf("\n");
}
int main(int argc, char **argv)
{
int fd;
......@@ -67,7 +16,8 @@ int main(int argc, char **argv)
__u8 *db;
struct regdb_file_header *header;
struct regdb_file_reg_country *countries;
int dblen, siglen, num_countries, i, j;
int dblen, siglen, num_countries, i, r = 0;
struct ieee80211_regdomain *rd = NULL;
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
......@@ -124,22 +74,20 @@ int main(int argc, char **argv)
header->reg_country_ptr);
for (i = 0; i < num_countries; i++) {
struct regdb_file_reg_rules_collection *rcoll;
struct regdb_file_reg_country *country = countries + i;
int num_rules;
printf("country %.2s:\n", country->alpha2);
rcoll = crda_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,
sizeof(*rcoll) + num_rules * sizeof(__be32),
country->reg_collection_ptr);
for (j = 0; j < num_rules; j++)
print_reg_rule(db, dblen, rcoll->reg_rule_ptrs[j]);
printf("\n");
}
return 0;
r = country2rd(db, dblen, country, &rd);
if (r) {
fprintf(stderr, "Could not covert country "
"(%.2s) to rd\n", country->alpha2);
goto out;
}
print_regdom(rd);
free(rd);
rd = NULL;
}
out:
return r;
}
#ifndef REG_DB_H
#define REG_DB_H
#include <linux/types.h>
/*
......@@ -120,3 +123,5 @@ static inline void check_db_binary_structs(void)
CHECK_STRUCT(regdb_file_reg_rules_collection, 4);
CHECK_STRUCT(regdb_file_reg_country, 8);
}
#endif
#include <errno.h>
#include <stdio.h>
#include <arpa/inet.h>
#include "reglib.h"
#ifdef USE_OPENSSL
#include <openssl/objects.h>
......@@ -11,7 +13,7 @@
#include <gcrypt.h>
#endif
#include "regdb.h"
#include "reglib.h"
#ifdef USE_OPENSSL
#include "keys-ssl.c"
......@@ -130,3 +132,144 @@ out:
return 1;
#endif
}
void reg_rule2rd(__u8 *db, int dblen,
__be32 ruleptr, struct ieee80211_reg_rule *rd_reg_rule)
{
struct regdb_file_reg_rule *rule;
struct regdb_file_freq_range *freq;
struct regdb_file_power_rule *power;
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);
rd_freq_range->start_freq_khz = ntohl(freq->start_freq);
rd_freq_range->end_freq_khz = ntohl(freq->end_freq);
rd_freq_range->max_bandwidth_khz = ntohl(freq->max_bandwidth);
rd_power_rule->max_antenna_gain = ntohl(power->max_antenna_gain);
rd_power_rule->max_eirp = ntohl(power->max_eirp);
rd_reg_rule->flags = ntohl(rule->flags);
}
/* Converts a file regdomain to ieee80211_regdomain, easier to manage */
int country2rd(__u8 *db, int dblen,
struct regdb_file_reg_country *country,
struct ieee80211_regdomain **rdp)
{
struct regdb_file_reg_rules_collection *rcoll;
struct ieee80211_regdomain *rd;
int i, num_rules, size_of_rd;
rcoll = crda_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,
sizeof(*rcoll) + num_rules * sizeof(__be32),
country->reg_collection_ptr);
size_of_rd = sizeof(struct ieee80211_regdomain) +
num_rules * sizeof(struct ieee80211_reg_rule);
*rdp = malloc(size_of_rd);
if (!*rdp)
return -ENOMEM;
rd = *rdp;
memset(rd, 0, size_of_rd);
rd->alpha2[0] = country->alpha2[0];
rd->alpha2[1] = country->alpha2[1];
rd->n_reg_rules = num_rules;
for (i = 0; i < num_rules; i++) {
reg_rule2rd(db, dblen, rcoll->reg_rule_ptrs[i],
&rd->reg_rules[i]);
}
return 0;
}
/* Sanity check on a regulatory rule */
int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
{
const struct ieee80211_freq_range *freq_range = &rule->freq_range;
__u32 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->max_bandwidth_khz > freq_diff)
return 0;
return 1;
}
void print_reg_rule(struct ieee80211_reg_rule *rule)
{
struct ieee80211_freq_range *freq;
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 print_regdom(struct ieee80211_regdomain *rd)
{
unsigned int i;
printf("country %.2s:\n", rd->alpha2);
for (i = 0; i < rd->n_reg_rules; i++)
print_reg_rule(&rd->reg_rules[i]);
printf("\n");
}
#ifndef REG_LIB_H
#define REG_LIB_H
#include <stdlib.h>
#include <linux/types.h>
/* Common regulatory functions and helpers */
#include "regdb.h"
void *crda_get_file_ptr(__u8 *db, int dblen, int structlen, __be32 ptr);
int crda_verify_db_signature(__u8 *db, int dblen, int siglen);
/* Common regulatory structures, functions and helpers */
/* This matches the kernel's data structures */
struct ieee80211_freq_range {
__u32 start_freq_khz;
__u32 end_freq_khz;
__u32 max_bandwidth_khz;
};
struct ieee80211_power_rule {
__u32 max_antenna_gain;
__u32 max_eirp;
};
struct ieee80211_reg_rule {
struct ieee80211_freq_range freq_range;
struct ieee80211_power_rule power_rule;
__u32 flags;
};
struct ieee80211_regdomain {
__u32 n_reg_rules;
char alpha2[2];
struct ieee80211_reg_rule reg_rules[];
};
static inline int is_world_regdom(const char *alpha2)
{
......@@ -47,3 +73,30 @@ static inline int is_valid_regdom(const char *alpha2)
return 1;
}
static inline __u32 max(__u32 a, __u32 b)
{
return (a > b) ? a : b;
}
static inline __u32 min(__u32 a, __u32 b)
{
return (a > b) ? b : a;
}
void *crda_get_file_ptr(__u8 *db, int dblen, int structlen, __be32 ptr);
int crda_verify_db_signature(__u8 *db, int dblen, int siglen);
/* File reg db entry -> rd converstion utilities */
void reg_rule2rd(__u8 *db, int dblen,
__be32 ruleptr, struct ieee80211_reg_rule *rd_reg_rule);
int country2rd(__u8 *db, int dblen,
struct regdb_file_reg_country *country,
struct ieee80211_regdomain **rdp);
/* reg helpers */
int is_valid_reg_rule(const struct ieee80211_reg_rule *rule);
void print_reg_rule(struct ieee80211_reg_rule *rule);
void print_regdom(struct ieee80211_regdomain *rd);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment