diff options
-rw-r--r-- | sbin/ifconfig/Makefile | 4 | ||||
-rw-r--r-- | sbin/ifconfig/ifieee80211.c | 45 | ||||
-rw-r--r-- | sbin/ifconfig/regdomain.c | 705 | ||||
-rw-r--r-- | sbin/ifconfig/regdomain.h | 121 |
4 files changed, 11 insertions, 864 deletions
diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index ac7faf9..ed9c205 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -37,8 +37,8 @@ SRCS+= ifgif.c # GIF reversed header workaround SRCS+= sfp.c # SFP/SFP+ information LIBADD+= m -SRCS+= ifieee80211.c regdomain.c # SIOC[GS]IEEE80211 support -LIBADD+= bsdxml sbuf +SRCS+= ifieee80211.c # SIOC[GS]IEEE80211 support +LIBADD+= bsdxml sbuf 80211 SRCS+= carp.c # SIOC[GS]VH support SRCS+= ifgroup.c # ... diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index 628eb190..72145d1 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -90,7 +90,9 @@ #include <stddef.h> /* NB: for offsetof */ #include "ifconfig.h" -#include "regdomain.h" + +#include <lib80211/lib80211_regdomain.h> +#include <lib80211/lib80211_ioctl.h> #ifndef IEEE80211_FIXED_RATE_NONE #define IEEE80211_FIXED_RATE_NONE 0xff @@ -4886,60 +4888,31 @@ end: static int get80211(int s, int type, void *data, int len) { - struct ieee80211req ireq; - (void) memset(&ireq, 0, sizeof(ireq)); - (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); - ireq.i_type = type; - ireq.i_data = data; - ireq.i_len = len; - return ioctl(s, SIOCG80211, &ireq); + return (lib80211_get80211(s, name, type, data, len)); } static int get80211len(int s, int type, void *data, int len, int *plen) { - struct ieee80211req ireq; - (void) memset(&ireq, 0, sizeof(ireq)); - (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); - ireq.i_type = type; - ireq.i_len = len; - assert(ireq.i_len == len); /* NB: check for 16-bit truncation */ - ireq.i_data = data; - if (ioctl(s, SIOCG80211, &ireq) < 0) - return -1; - *plen = ireq.i_len; - return 0; + return (lib80211_get80211len(s, name, type, data, len, plen)); } static int get80211val(int s, int type, int *val) { - struct ieee80211req ireq; - (void) memset(&ireq, 0, sizeof(ireq)); - (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); - ireq.i_type = type; - if (ioctl(s, SIOCG80211, &ireq) < 0) - return -1; - *val = ireq.i_val; - return 0; + return (lib80211_get80211val(s, name, type, val)); } static void set80211(int s, int type, int val, int len, void *data) { - struct ieee80211req ireq; + int ret; - (void) memset(&ireq, 0, sizeof(ireq)); - (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); - ireq.i_type = type; - ireq.i_val = val; - ireq.i_len = len; - assert(ireq.i_len == len); /* NB: check for 16-bit truncation */ - ireq.i_data = data; - if (ioctl(s, SIOCS80211, &ireq) < 0) + ret = lib80211_set80211(s, name, type, val, len, data); + if (ret < 0) err(1, "SIOCS80211"); } diff --git a/sbin/ifconfig/regdomain.c b/sbin/ifconfig/regdomain.c deleted file mode 100644 index 4140289..0000000 --- a/sbin/ifconfig/regdomain.c +++ /dev/null @@ -1,705 +0,0 @@ -/*- - * Copyright (c) 2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef lint -static const char rcsid[] = "$FreeBSD$"; -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/mman.h> -#include <sys/sbuf.h> -#include <sys/stat.h> - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <fcntl.h> -#include <err.h> -#include <unistd.h> - -#include <bsdxml.h> - -#include "regdomain.h" - -#include <net80211/_ieee80211.h> - -#define MAXLEVEL 20 - -struct mystate { - XML_Parser parser; - struct regdata *rdp; - struct regdomain *rd; /* current domain */ - struct netband *netband; /* current netband */ - struct freqband *freqband; /* current freqband */ - struct country *country; /* current country */ - netband_head *curband; /* current netband list */ - int level; - struct sbuf *sbuf[MAXLEVEL]; - int nident; -}; - -struct ident { - const void *id; - void *p; - enum { DOMAIN, COUNTRY, FREQBAND } type; -}; - -static void -start_element(void *data, const char *name, const char **attr) -{ -#define iseq(a,b) (strcasecmp(a,b) == 0) - struct mystate *mt; - const void *id, *ref, *mode; - int i; - - mt = data; - if (++mt->level == MAXLEVEL) { - /* XXX force parser to abort */ - return; - } - mt->sbuf[mt->level] = sbuf_new_auto(); - id = ref = mode = NULL; - for (i = 0; attr[i] != NULL; i += 2) { - if (iseq(attr[i], "id")) { - id = attr[i+1]; - } else if (iseq(attr[i], "ref")) { - ref = attr[i+1]; - } else if (iseq(attr[i], "mode")) { - mode = attr[i+1]; - } else - printf("%*.*s[%s = %s]\n", mt->level + 1, - mt->level + 1, "", attr[i], attr[i+1]); - } - if (iseq(name, "rd") && mt->rd == NULL) { - if (mt->country == NULL) { - mt->rd = calloc(1, sizeof(struct regdomain)); - mt->rd->name = strdup(id); - mt->nident++; - LIST_INSERT_HEAD(&mt->rdp->domains, mt->rd, next); - } else - mt->country->rd = (void *)strdup(ref); - return; - } - if (iseq(name, "defcc") && mt->rd != NULL) { - mt->rd->cc = (void *)strdup(ref); - return; - } - if (iseq(name, "netband") && mt->curband == NULL && mt->rd != NULL) { - if (mode == NULL) { - warnx("no mode for netband at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - return; - } - if (iseq(mode, "11b")) - mt->curband = &mt->rd->bands_11b; - else if (iseq(mode, "11g")) - mt->curband = &mt->rd->bands_11g; - else if (iseq(mode, "11a")) - mt->curband = &mt->rd->bands_11a; - else if (iseq(mode, "11ng")) - mt->curband = &mt->rd->bands_11ng; - else if (iseq(mode, "11na")) - mt->curband = &mt->rd->bands_11na; - else - warnx("unknown mode \"%s\" at line %ld", - __DECONST(char *, mode), - XML_GetCurrentLineNumber(mt->parser)); - return; - } - if (iseq(name, "band") && mt->netband == NULL) { - if (mt->curband == NULL) { - warnx("band without enclosing netband at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - return; - } - mt->netband = calloc(1, sizeof(struct netband)); - LIST_INSERT_HEAD(mt->curband, mt->netband, next); - return; - } - if (iseq(name, "freqband") && mt->freqband == NULL && mt->netband != NULL) { - /* XXX handle inlines and merge into table? */ - if (mt->netband->band != NULL) { - warnx("duplicate freqband at line %ld ignored", - XML_GetCurrentLineNumber(mt->parser)); - /* XXX complain */ - } else - mt->netband->band = (void *)strdup(ref); - return; - } - - if (iseq(name, "country") && mt->country == NULL) { - mt->country = calloc(1, sizeof(struct country)); - mt->country->isoname = strdup(id); - mt->country->code = NO_COUNTRY; - mt->nident++; - LIST_INSERT_HEAD(&mt->rdp->countries, mt->country, next); - return; - } - - if (iseq(name, "freqband") && mt->freqband == NULL) { - mt->freqband = calloc(1, sizeof(struct freqband)); - mt->freqband->id = strdup(id); - mt->nident++; - LIST_INSERT_HEAD(&mt->rdp->freqbands, mt->freqband, next); - return; - } -#undef iseq -} - -static int -decode_flag(struct mystate *mt, const char *p, int len) -{ -#define iseq(a,b) (strcasecmp(a,b) == 0) - static const struct { - const char *name; - int len; - uint32_t value; - } flags[] = { -#define FLAG(x) { #x, sizeof(#x)-1, x } - FLAG(IEEE80211_CHAN_A), - FLAG(IEEE80211_CHAN_B), - FLAG(IEEE80211_CHAN_G), - FLAG(IEEE80211_CHAN_HT20), - FLAG(IEEE80211_CHAN_HT40), - FLAG(IEEE80211_CHAN_ST), - FLAG(IEEE80211_CHAN_TURBO), - FLAG(IEEE80211_CHAN_PASSIVE), - FLAG(IEEE80211_CHAN_DFS), - FLAG(IEEE80211_CHAN_CCK), - FLAG(IEEE80211_CHAN_OFDM), - FLAG(IEEE80211_CHAN_2GHZ), - FLAG(IEEE80211_CHAN_5GHZ), - FLAG(IEEE80211_CHAN_DYN), - FLAG(IEEE80211_CHAN_GFSK), - FLAG(IEEE80211_CHAN_GSM), - FLAG(IEEE80211_CHAN_STURBO), - FLAG(IEEE80211_CHAN_HALF), - FLAG(IEEE80211_CHAN_QUARTER), - FLAG(IEEE80211_CHAN_HT40U), - FLAG(IEEE80211_CHAN_HT40D), - FLAG(IEEE80211_CHAN_4MSXMIT), - FLAG(IEEE80211_CHAN_NOADHOC), - FLAG(IEEE80211_CHAN_NOHOSTAP), - FLAG(IEEE80211_CHAN_11D), - FLAG(IEEE80211_CHAN_FHSS), - FLAG(IEEE80211_CHAN_PUREG), - FLAG(IEEE80211_CHAN_108A), - FLAG(IEEE80211_CHAN_108G), -#undef FLAG - { "ECM", 3, REQ_ECM }, - { "INDOOR", 6, REQ_INDOOR }, - { "OUTDOOR", 7, REQ_OUTDOOR }, - }; - int i; - - for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) - if (len == flags[i].len && iseq(p, flags[i].name)) - return flags[i].value; - warnx("unknown flag \"%.*s\" at line %ld ignored", - len, p, XML_GetCurrentLineNumber(mt->parser)); - return 0; -#undef iseq -} - -static void -end_element(void *data, const char *name) -{ -#define iseq(a,b) (strcasecmp(a,b) == 0) - struct mystate *mt; - int len; - char *p; - - mt = data; - sbuf_finish(mt->sbuf[mt->level]); - p = sbuf_data(mt->sbuf[mt->level]); - len = sbuf_len(mt->sbuf[mt->level]); - - /* <freqband>...</freqband> */ - if (iseq(name, "freqstart") && mt->freqband != NULL) { - mt->freqband->freqStart = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "freqend") && mt->freqband != NULL) { - mt->freqband->freqEnd = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "chanwidth") && mt->freqband != NULL) { - mt->freqband->chanWidth = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "chansep") && mt->freqband != NULL) { - mt->freqband->chanSep = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "flags")) { - if (mt->freqband != NULL) - mt->freqband->flags |= decode_flag(mt, p, len); - else if (mt->netband != NULL) - mt->netband->flags |= decode_flag(mt, p, len); - else { - warnx("flags without freqband or netband at line %ld ignored", - XML_GetCurrentLineNumber(mt->parser)); - } - goto done; - } - - /* <rd> ... </rd> */ - if (iseq(name, "name") && mt->rd != NULL) { - mt->rd->name = strdup(p); - goto done; - } - if (iseq(name, "sku") && mt->rd != NULL) { - mt->rd->sku = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "netband") && mt->rd != NULL) { - mt->curband = NULL; - goto done; - } - - /* <band> ... </band> */ - if (iseq(name, "freqband") && mt->netband != NULL) { - /* XXX handle inline freqbands */ - goto done; - } - if (iseq(name, "maxpower") && mt->netband != NULL) { - mt->netband->maxPower = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "maxpowerdfs") && mt->netband != NULL) { - mt->netband->maxPowerDFS = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "maxantgain") && mt->netband != NULL) { - mt->netband->maxAntGain = strtoul(p, NULL, 0); - goto done; - } - - /* <country>...</country> */ - if (iseq(name, "isocc") && mt->country != NULL) { - mt->country->code = strtoul(p, NULL, 0); - goto done; - } - if (iseq(name, "name") && mt->country != NULL) { - mt->country->name = strdup(p); - goto done; - } - - if (len != 0) { - warnx("unexpected XML token \"%s\" data \"%s\" at line %ld", - name, p, XML_GetCurrentLineNumber(mt->parser)); - /* XXX goto done? */ - } - /* </freqband> */ - if (iseq(name, "freqband") && mt->freqband != NULL) { - /* XXX must have start/end frequencies */ - /* XXX must have channel width/sep */ - mt->freqband = NULL; - goto done; - } - /* </rd> */ - if (iseq(name, "rd") && mt->rd != NULL) { - mt->rd = NULL; - goto done; - } - /* </band> */ - if (iseq(name, "band") && mt->netband != NULL) { - if (mt->netband->band == NULL) { - warnx("no freqbands for band at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - } - if (mt->netband->maxPower == 0) { - warnx("no maxpower for band at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - } - /* default max power w/ DFS to max power */ - if (mt->netband->maxPowerDFS == 0) - mt->netband->maxPowerDFS = mt->netband->maxPower; - mt->netband = NULL; - goto done; - } - /* </netband> */ - if (iseq(name, "netband") && mt->netband != NULL) { - mt->curband = NULL; - goto done; - } - /* </country> */ - if (iseq(name, "country") && mt->country != NULL) { - if (mt->country->code == NO_COUNTRY) { - warnx("no ISO cc for country at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - } - if (mt->country->name == NULL) { - warnx("no name for country at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - } - if (mt->country->rd == NULL) { - warnx("no regdomain reference for country at line %ld", - XML_GetCurrentLineNumber(mt->parser)); - } - mt->country = NULL; - goto done; - } -done: - sbuf_delete(mt->sbuf[mt->level]); - mt->sbuf[mt->level--] = NULL; -#undef iseq -} - -static void -char_data(void *data, const XML_Char *s, int len) -{ - struct mystate *mt; - const char *b, *e; - - mt = data; - - b = s; - e = s + len-1; - for (; isspace(*b) && b < e; b++) - ; - for (; isspace(*e) && e > b; e++) - ; - if (e != b || (*b != '\0' && !isspace(*b))) - sbuf_bcat(mt->sbuf[mt->level], b, e-b+1); -} - -static void * -findid(struct regdata *rdp, const void *id, int type) -{ - struct ident *ip; - - for (ip = rdp->ident; ip->id != NULL; ip++) - if (ip->type == type && strcasecmp(ip->id, id) == 0) - return ip->p; - return NULL; -} - -/* - * Parse an regdomain XML configuration and build the internal representation. - */ -int -lib80211_regdomain_readconfig(struct regdata *rdp, const void *p, size_t len) -{ - struct mystate *mt; - struct regdomain *dp; - struct country *cp; - struct freqband *fp; - struct netband *nb; - const void *id; - int i, errors; - - memset(rdp, 0, sizeof(struct regdata)); - mt = calloc(1, sizeof(struct mystate)); - if (mt == NULL) - return ENOMEM; - /* parse the XML input */ - mt->rdp = rdp; - mt->parser = XML_ParserCreate(NULL); - XML_SetUserData(mt->parser, mt); - XML_SetElementHandler(mt->parser, start_element, end_element); - XML_SetCharacterDataHandler(mt->parser, char_data); - if (XML_Parse(mt->parser, p, len, 1) != XML_STATUS_OK) { - warnx("%s: %s at line %ld", __func__, - XML_ErrorString(XML_GetErrorCode(mt->parser)), - XML_GetCurrentLineNumber(mt->parser)); - return -1; - } - XML_ParserFree(mt->parser); - - /* setup the identifer table */ - rdp->ident = calloc(sizeof(struct ident), mt->nident + 1); - if (rdp->ident == NULL) - return ENOMEM; - free(mt); - - errors = 0; - i = 0; - LIST_FOREACH(dp, &rdp->domains, next) { - rdp->ident[i].id = dp->name; - rdp->ident[i].p = dp; - rdp->ident[i].type = DOMAIN; - i++; - } - LIST_FOREACH(fp, &rdp->freqbands, next) { - rdp->ident[i].id = fp->id; - rdp->ident[i].p = fp; - rdp->ident[i].type = FREQBAND; - i++; - } - LIST_FOREACH(cp, &rdp->countries, next) { - rdp->ident[i].id = cp->isoname; - rdp->ident[i].p = cp; - rdp->ident[i].type = COUNTRY; - i++; - } - - /* patch references */ - LIST_FOREACH(dp, &rdp->domains, next) { - if (dp->cc != NULL) { - id = dp->cc; - dp->cc = findid(rdp, id, COUNTRY); - if (dp->cc == NULL) { - warnx("undefined country \"%s\"", - __DECONST(char *, id)); - errors++; - } - free(__DECONST(char *, id)); - } - LIST_FOREACH(nb, &dp->bands_11b, next) { - id = findid(rdp, nb->band, FREQBAND); - if (id == NULL) { - warnx("undefined 11b band \"%s\"", - __DECONST(char *, nb->band)); - errors++; - } - nb->band = id; - } - LIST_FOREACH(nb, &dp->bands_11g, next) { - id = findid(rdp, nb->band, FREQBAND); - if (id == NULL) { - warnx("undefined 11g band \"%s\"", - __DECONST(char *, nb->band)); - errors++; - } - nb->band = id; - } - LIST_FOREACH(nb, &dp->bands_11a, next) { - id = findid(rdp, nb->band, FREQBAND); - if (id == NULL) { - warnx("undefined 11a band \"%s\"", - __DECONST(char *, nb->band)); - errors++; - } - nb->band = id; - } - LIST_FOREACH(nb, &dp->bands_11ng, next) { - id = findid(rdp, nb->band, FREQBAND); - if (id == NULL) { - warnx("undefined 11ng band \"%s\"", - __DECONST(char *, nb->band)); - errors++; - } - nb->band = id; - } - LIST_FOREACH(nb, &dp->bands_11na, next) { - id = findid(rdp, nb->band, FREQBAND); - if (id == NULL) { - warnx("undefined 11na band \"%s\"", - __DECONST(char *, nb->band)); - errors++; - } - nb->band = id; - } - } - LIST_FOREACH(cp, &rdp->countries, next) { - id = cp->rd; - cp->rd = findid(rdp, id, DOMAIN); - if (cp->rd == NULL) { - warnx("undefined country \"%s\"", - __DECONST(char *, id)); - errors++; - } - free(__DECONST(char *, id)); - } - - return errors ? EINVAL : 0; -} - -static void -cleanup_bands(netband_head *head) -{ - struct netband *nb; - - for (;;) { - nb = LIST_FIRST(head); - if (nb == NULL) - break; - free(nb); - } -} - -/* - * Cleanup state/resources for a previously parsed regdomain database. - */ -void -lib80211_regdomain_cleanup(struct regdata *rdp) -{ - - free(rdp->ident); - rdp->ident = NULL; - for (;;) { - struct regdomain *dp = LIST_FIRST(&rdp->domains); - if (dp == NULL) - break; - LIST_REMOVE(dp, next); - cleanup_bands(&dp->bands_11b); - cleanup_bands(&dp->bands_11g); - cleanup_bands(&dp->bands_11a); - cleanup_bands(&dp->bands_11ng); - cleanup_bands(&dp->bands_11na); - if (dp->name != NULL) - free(__DECONST(char *, dp->name)); - } - for (;;) { - struct country *cp = LIST_FIRST(&rdp->countries); - if (cp == NULL) - break; - LIST_REMOVE(cp, next); - if (cp->name != NULL) - free(__DECONST(char *, cp->name)); - free(cp); - } - for (;;) { - struct freqband *fp = LIST_FIRST(&rdp->freqbands); - if (fp == NULL) - break; - LIST_REMOVE(fp, next); - free(fp); - } -} - -struct regdata * -lib80211_alloc_regdata(void) -{ - struct regdata *rdp; - struct stat sb; - void *xml; - int fd; - - rdp = calloc(1, sizeof(struct regdata)); - - fd = open(_PATH_REGDOMAIN, O_RDONLY); - if (fd < 0) { -#ifdef DEBUG - warn("%s: open(%s)", __func__, _PATH_REGDOMAIN); -#endif - free(rdp); - return NULL; - } - if (fstat(fd, &sb) < 0) { -#ifdef DEBUG - warn("%s: fstat(%s)", __func__, _PATH_REGDOMAIN); -#endif - close(fd); - free(rdp); - return NULL; - } - xml = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (xml == MAP_FAILED) { -#ifdef DEBUG - warn("%s: mmap", __func__); -#endif - close(fd); - free(rdp); - return NULL; - } - if (lib80211_regdomain_readconfig(rdp, xml, sb.st_size) != 0) { -#ifdef DEBUG - warn("%s: error reading regulatory database", __func__); -#endif - munmap(xml, sb.st_size); - close(fd); - free(rdp); - return NULL; - } - munmap(xml, sb.st_size); - close(fd); - - return rdp; -} - -void -lib80211_free_regdata(struct regdata *rdp) -{ - lib80211_regdomain_cleanup(rdp); - free(rdp); -} - -/* - * Lookup a regdomain by SKU. - */ -const struct regdomain * -lib80211_regdomain_findbysku(const struct regdata *rdp, enum RegdomainCode sku) -{ - const struct regdomain *dp; - - LIST_FOREACH(dp, &rdp->domains, next) { - if (dp->sku == sku) - return dp; - } - return NULL; -} - -/* - * Lookup a regdomain by name. - */ -const struct regdomain * -lib80211_regdomain_findbyname(const struct regdata *rdp, const char *name) -{ - const struct regdomain *dp; - - LIST_FOREACH(dp, &rdp->domains, next) { - if (strcasecmp(dp->name, name) == 0) - return dp; - } - return NULL; -} - -/* - * Lookup a country by ISO country code. - */ -const struct country * -lib80211_country_findbycc(const struct regdata *rdp, enum ISOCountryCode cc) -{ - const struct country *cp; - - LIST_FOREACH(cp, &rdp->countries, next) { - if (cp->code == cc) - return cp; - } - return NULL; -} - -/* - * Lookup a country by ISO/long name. - */ -const struct country * -lib80211_country_findbyname(const struct regdata *rdp, const char *name) -{ - const struct country *cp; - int len; - - len = strlen(name); - LIST_FOREACH(cp, &rdp->countries, next) { - if (strcasecmp(cp->isoname, name) == 0) - return cp; - } - LIST_FOREACH(cp, &rdp->countries, next) { - if (strncasecmp(cp->name, name, len) == 0) - return cp; - } - return NULL; -} diff --git a/sbin/ifconfig/regdomain.h b/sbin/ifconfig/regdomain.h deleted file mode 100644 index cfc2be0..0000000 --- a/sbin/ifconfig/regdomain.h +++ /dev/null @@ -1,121 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _LIB80211_H_ -#define _LIB80211_H_ - -#include <sys/cdefs.h> -#include <sys/queue.h> - -#include <net80211/ieee80211_regdomain.h> - -__BEGIN_DECLS - -struct freqband { - uint16_t freqStart; /* starting frequency (MHz) */ - uint16_t freqEnd; /* ending frequency (MHz) */ - uint8_t chanWidth; /* channel width (MHz) */ - uint8_t chanSep; /* channel sepaaration (MHz) */ - uint32_t flags; /* common operational constraints */ - - const void *id; - LIST_ENTRY(freqband) next; -}; - -/* private flags, don't pass to os */ -#define REQ_ECM 0x1 /* enable if ECM set */ -#define REQ_INDOOR 0x2 /* enable only for indoor operation */ -#define REQ_OUTDOOR 0x4 /* enable only for outdoor operation */ - -#define REQ_FLAGS (REQ_ECM|REQ_INDOOR|REQ_OUTDOOR) - -struct netband { - const struct freqband *band; /* channel list description */ - uint8_t maxPower; /* regulatory cap on tx power (dBm) */ - uint8_t maxPowerDFS; /* regulatory cap w/ DFS (dBm) */ - uint8_t maxAntGain; /* max allowed antenna gain (.5 dBm) */ - uint32_t flags; /* net80211 channel flags */ - - LIST_ENTRY(netband) next; -}; -typedef LIST_HEAD(, netband) netband_head; - -struct country; - -struct regdomain { - enum RegdomainCode sku; /* regdomain code/SKU */ - const char *name; /* printable name */ - const struct country *cc; /* country code for 1-1/default map */ - - netband_head bands_11b; /* 11b operation */ - netband_head bands_11g; /* 11g operation */ - netband_head bands_11a; /* 11a operation */ - netband_head bands_11ng;/* 11ng operation */ - netband_head bands_11na;/* 11na operation */ - - LIST_ENTRY(regdomain) next; -}; - -struct country { - enum ISOCountryCode code; -#define NO_COUNTRY 0xffff - const struct regdomain *rd; - const char* isoname; - const char* name; - - LIST_ENTRY(country) next; -}; - -struct ident; - -struct regdata { - LIST_HEAD(, country) countries; /* country code table */ - LIST_HEAD(, regdomain) domains; /* regulatory domains */ - LIST_HEAD(, freqband) freqbands; /* frequency band table */ - struct ident *ident; /* identifier table */ -}; - -#define _PATH_REGDOMAIN "/etc/regdomain.xml" - -struct regdata *lib80211_alloc_regdata(void); -void lib80211_free_regdata(struct regdata *); - -int lib80211_regdomain_readconfig(struct regdata *, const void *, size_t); -void lib80211_regdomain_cleanup(struct regdata *); - -const struct regdomain *lib80211_regdomain_findbysku(const struct regdata *, - enum RegdomainCode); -const struct regdomain *lib80211_regdomain_findbyname(const struct regdata *, - const char *); - -const struct country *lib80211_country_findbycc(const struct regdata *, - enum ISOCountryCode); -const struct country *lib80211_country_findbyname(const struct regdata *, - const char *); - -__END_DECLS - -#endif /* _LIB80211_H_ */ |