7 #include <arpa/inet.h> /* ntohl */
11 static void *get_file_ptr(__u8 *db, int dblen, int structlen, __be32 ptr)
15 if (p > dblen - structlen) {
16 fprintf(stderr, "Invalid database file, bad pointer!\n");
20 return (void *)(db + p);
23 static void print_reg_rule(__u8 *db, int dblen, __be32 ruleptr)
25 struct regdb_file_reg_rule *rule;
26 struct regdb_file_freq_range *freq;
27 struct regdb_file_power_rule *power;
30 rule = get_file_ptr(db, dblen, sizeof(*rule), ruleptr);
31 freq = get_file_ptr(db, dblen, sizeof(*freq), rule->freq_range_ptr);
32 power = get_file_ptr(db, dblen, sizeof(*power), rule->power_rule_ptr);
34 printf("\t(%.3f - %.3f @ %.3f), ",
35 ((float)ntohl(freq->start_freq))/1000.0,
36 ((float)ntohl(freq->end_freq))/1000.0,
37 ((float)ntohl(freq->max_bandwidth))/1000.0);
41 if (power->max_antenna_gain)
42 printf("%.2f, ", ((float)ntohl(power->max_antenna_gain)/100.0));
47 printf("%.2f)", ((float)ntohl(power->max_eirp)/100.0));
51 flags = ntohl(rule->flags);
52 if (flags & RRF_NO_OFDM)
54 if (flags & RRF_NO_CCK)
56 if (flags & RRF_NO_INDOOR)
57 printf(", NO-INDOOR");
58 if (flags & RRF_NO_OUTDOOR)
59 printf(", NO-OUTDOOR");
62 if (flags & RRF_PTP_ONLY)
64 if (flags & RRF_PTMP_ONLY)
65 printf(", PTMP-ONLY");
66 if (flags & RRF_PASSIVE_SCAN)
67 printf(", PASSIVE-SCAN");
68 if (flags & RRF_NO_IBSS)
74 int main(int argc, char **argv)
79 struct regdb_file_header *header;
80 struct regdb_file_reg_country *countries;
81 int dblen, siglen, num_countries, i, j;
84 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
88 fd = open(argv[1], O_RDONLY);
90 perror("failed to open db file");
94 if (fstat(fd, &stat)) {
95 perror("failed to fstat db file");
101 db = mmap(NULL, dblen, PROT_READ, MAP_PRIVATE, fd, 0);
102 if (db == MAP_FAILED) {
103 perror("failed to mmap db file");
107 header = get_file_ptr(db, dblen, sizeof(*header), 0);
109 if (ntohl(header->magic) != REGDB_MAGIC) {
110 fprintf(stderr, "Invalid database magic\n");
114 if (ntohl(header->version) != REGDB_VERSION) {
115 fprintf(stderr, "Invalid database version\n");
119 siglen = ntohl(header->signature_length);
120 /* adjust dblen so later sanity checks don't run into the signature */
123 if (dblen <= sizeof(*header)) {
124 fprintf(stderr, "Invalid signature length %d\n", siglen);
128 /* verify signature */
129 if (!crda_verify_db_signature(db, dblen, siglen))
132 num_countries = ntohl(header->reg_country_num);
133 countries = get_file_ptr(db, dblen,
134 sizeof(struct regdb_file_reg_country) * num_countries,
135 header->reg_country_ptr);
137 for (i = 0; i < num_countries; i++) {
138 struct regdb_file_reg_rules_collection *rcoll;
139 struct regdb_file_reg_country *country = countries + i;
142 printf("country %.2s:\n", country->alpha2);
143 rcoll = get_file_ptr(db, dblen, sizeof(*rcoll), country->reg_collection_ptr);
144 num_rules = ntohl(rcoll->reg_rule_num);
145 /* re-get pointer with sanity checking for num_rules */
146 rcoll = get_file_ptr(db, dblen,
147 sizeof(*rcoll) + num_rules * sizeof(__be32),
148 country->reg_collection_ptr);
149 for (j = 0; j < num_rules; j++)
150 print_reg_rule(db, dblen, rcoll->reg_rule_ptrs[j]);