Annotation of embedtools/src/vap.c, revision 1.1.2.8

1.1.2.1   misho       1: #include "global.h"
                      2: #include "dwds.h"
                      3: 
                      4: 
1.1.2.3   misho       5: static inline int
1.1.2.2   misho       6: wifi_getParent(const char *csVAP, char *psParent, size_t plen)
                      7: {
                      8:        char szOID[STRSIZ] = { 0 };
                      9: 
                     10:        FTRACE(5);
                     11: 
                     12:        assert(csVAP);
                     13:        assert(psParent);
                     14: 
                     15:        memset(psParent, 0, plen);
                     16:        snprintf(szOID, STRSIZ, "net.wlan.%s.%%parent", csVAP + 4);
                     17:        if (sysctlbyname(szOID, psParent, &plen, NULL, 0) == -1) {
1.1.2.4   misho      18: //             syslog(LOG_ERR, "Error:: can`t get parent #%d - %s\n", errno, strerror(errno));
1.1.2.2   misho      19:                return -1;
                     20:        } else
                     21:                psParent[plen] = 0;
                     22: 
                     23:        return 0;
                     24: }
                     25: 
1.1.2.6   misho      26: inline int
1.1.2.3   misho      27: wifi_chkIface(const char *csVAP, char **ppsIF, int nIF)
1.1.2.2   misho      28: {
                     29:        char szParent[IFNAMSIZ];
                     30:        register int i;
                     31: 
                     32:        FTRACE(5);
                     33: 
1.1.2.3   misho      34:        assert(csVAP);
1.1.2.2   misho      35: 
1.1.2.3   misho      36:        if (wifi_getParent(csVAP, szParent, IFNAMSIZ) == -1)
1.1.2.7   misho      37:                return 0;
1.1.2.2   misho      38: 
                     39:        for (i = 0; i < nIF; i++)
                     40:                if (!strcasecmp(ppsIF[i], "any") || !strcmp(ppsIF[i], szParent))
                     41:                        return 1; /* OK, vap is child */
                     42: 
1.1.2.7   misho      43:        VERB(2) syslog(LOG_ERR, "Error:: Interface %s parent %s not being monitored", csVAP, szParent);
1.1.2.2   misho      44:        return 0;
                     45: }
                     46: 
1.1.2.3   misho      47: static inline int
1.1.2.2   misho      48: wifi_isWDS(int fd, const char *csVAP)
                     49: {
                     50:        struct ifmediareq ifmr;
                     51: 
                     52:        FTRACE(5);
                     53: 
                     54:        assert(csVAP);
                     55: 
                     56:        memset(&ifmr, 0, sizeof ifmr);
                     57:        strlcpy(ifmr.ifm_name, csVAP, sizeof ifmr.ifm_name);
                     58:        if (ioctl(fd, SIOCGIFMEDIA, &ifmr) == -1) {
                     59:                syslog(LOG_ERR, "Error:: can`t get media for %s #%d - %s\n", csVAP, 
                     60:                                errno, strerror(errno));
                     61:                return -1;
                     62:        }
                     63: 
                     64:        return (ifmr.ifm_current & IFM_IEEE80211_WDS) != 0;
                     65: }
                     66: 
1.1.2.3   misho      67: static inline int
1.1.2.2   misho      68: wifi_getBSSID(int fd, const char *csVAP, uint8_t *psBSSID, int len)
                     69: {
                     70:        struct ieee80211req ireq;
                     71: 
                     72:        FTRACE(5);
                     73: 
                     74:        assert(csVAP);
                     75:        assert(psBSSID);
                     76: 
                     77:        memset(&ireq, 0, sizeof ireq);
                     78:        strlcpy(ireq.i_name, csVAP, sizeof ireq.i_name);
                     79:        ireq.i_type = IEEE80211_IOC_BSSID;
                     80:        ireq.i_data = psBSSID;
                     81:        ireq.i_len = len;
                     82:        if (ioctl(fd, SIOCG80211, &ireq) == -1) {
                     83:                syslog(LOG_ERR, "Error:: can`t get BSSID for %s #%d - %s\n", csVAP, 
                     84:                                errno, strerror(errno));
                     85:                return -1;
                     86:        }
                     87: 
                     88:        return 0;
                     89: }
1.1.2.3   misho      90: 
                     91: struct dwds_if *
                     92: wifi_buildWDS(int fd, char **ppsIF, int nIF)
                     93: {
                     94:        struct dwds_if *p, *wds = NULL;
                     95:        char szVAP[IFNAMSIZ];
                     96:        struct ether_addr bssid;
                     97:        register int i;
                     98: 
1.1.2.7   misho      99:        FTRACE(5);
                    100: 
1.1.2.3   misho     101:        for (i = 0; i < 128; i++) {
                    102:                memset(szVAP, 0, IFNAMSIZ);
                    103:                snprintf(szVAP, IFNAMSIZ, "wlan%d", i);
1.1.2.7   misho     104:                if (wifi_chkIface(szVAP, ppsIF, nIF) && !wifi_isWDS(fd, szVAP)) {
1.1.2.3   misho     105:                        p = malloc(sizeof(struct dwds_if));
                    106:                        if (!p) {
                    107:                                syslog(LOG_ERR, "Error:: can`t allocate memory #%d - %s\n", 
                    108:                                                errno, strerror(errno));
                    109:                                i = -1;
                    110:                                break;
                    111:                        }
                    112:                        strlcpy(p->if_name, szVAP, IFNAMSIZ);
                    113:                        if (wifi_getBSSID(fd, szVAP, p->if_bssid, IEEE80211_ADDR_LEN) == -1) {
1.1.2.7   misho     114:                                syslog(LOG_ERR, "Error:: can`t get BSSID #%d - %s\n", 
                    115:                                                errno, strerror(errno));
1.1.2.3   misho     116:                                i = -1;
                    117:                                break;
                    118:                        }
                    119:                        p->if_next = wds;
                    120:                        wds = p;
                    121: 
                    122:                        memcpy(&bssid, p->if_bssid, ETHER_ADDR_LEN);
                    123:                        syslog(LOG_INFO, "BSSID:%s discover WDS vap %s\n", ether_ntoa(&bssid), szVAP);
                    124:                }
                    125:        }
                    126: 
                    127:        if (i == -1)
                    128:                while ((p = wds)) {
                    129:                        wds = wds->if_next;
                    130:                        free(p);
                    131:                }
                    132: 
                    133:        return wds;
                    134: }
1.1.2.5   misho     135: 
1.1.2.6   misho     136: inline int
1.1.2.5   misho     137: wifi_destroyWDS(const char *csIface, struct dwds_if **wds)
                    138: {
                    139:        struct dwds_if *p, **pp;
                    140: 
1.1.2.7   misho     141:        FTRACE(5);
                    142: 
1.1.2.5   misho     143:        assert(csIface);
                    144:        assert(wds);
                    145: 
                    146:        for (pp = wds; (p = *pp); pp = &p->if_next)
                    147:                if (!strncmp(p->if_name, csIface, IFNAMSIZ))
                    148:                        break;
                    149:        if (p) {
                    150:                *pp = p->if_next;
                    151:                free(p);
1.1.2.6   misho     152:                return 0;
                    153:        }
                    154: 
                    155:        return 1;
                    156: }
                    157: 
                    158: static int
                    159: wifi_vapDestroy(const char *csVAP)
                    160: {
                    161:        struct ieee80211req ifr;
                    162:        int s;
                    163: 
1.1.2.7   misho     164:        FTRACE(5);
                    165: 
1.1.2.6   misho     166:        assert(csVAP);
                    167: 
                    168:        s = socket(PF_INET, SOCK_DGRAM, 0);
                    169:        if (s == -1) {
                    170:                syslog(LOG_ERR, "Error:: destroy socket(vap) %m\n");
                    171:                return -1;
                    172:        }
                    173: 
                    174:        memset(&ifr, 0, sizeof ifr);
                    175:        strlcpy(ifr.i_name, csVAP, IFNAMSIZ);
                    176:        if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) {
                    177:                syslog(LOG_ERR, "Error:: destroy ioctl(vap) %m\n");
                    178:                close(s);
                    179:                return -1;
                    180:        } else
                    181:                close(s);
                    182: 
                    183:        return 0;
                    184: }
                    185: 
                    186: inline int
1.1.2.8 ! misho     187: wifi_leaveWDS(struct ether_addr bssid, struct dwds_if **wds, char *psVAP, int vapLen)
1.1.2.6   misho     188: {
                    189:        struct dwds_if *p, **pp;
                    190: 
1.1.2.7   misho     191:        FTRACE(5);
                    192: 
1.1.2.6   misho     193:        assert(wds);
1.1.2.8 ! misho     194:        assert(psVAP);
1.1.2.6   misho     195: 
                    196:        for (pp = wds; (p = *pp); pp = &p->if_next)
                    197:                if (!memcmp(p->if_bssid, &bssid, IEEE80211_ADDR_LEN))
                    198:                        break;
                    199:        if (p) {
                    200:                *pp = p->if_next;
1.1.2.8 ! misho     201:                strlcpy(psVAP, p->if_name, vapLen);
1.1.2.6   misho     202:                if (wifi_vapDestroy(p->if_name) != -1)
                    203:                       VERB(1) syslog(LOG_INFO, "BSSID:%s WDS VAP %s destroyed\n", 
                    204:                                       ether_ntoa(&bssid), p->if_name); 
                    205:                free(p);
                    206:                return 0;
                    207:        }
                    208: 
                    209:        return 1;
                    210: }
                    211: 
                    212: static int
                    213: wifi_vapCreate(const char *csIface, struct dwds_if *p)
                    214: {
                    215:        struct ieee80211_clone_params cp;
                    216:        struct ifreq ifr;
                    217:        struct ether_addr bssid;
                    218:        int s;
                    219: 
1.1.2.7   misho     220:        FTRACE(5);
                    221: 
1.1.2.6   misho     222:        assert(csIface);
                    223:        assert(p);
                    224: 
                    225:        s = socket(PF_INET, SOCK_DGRAM, 0);
                    226:        if (s == -1) {
                    227:                syslog(LOG_ERR, "Error:: create socket(vap) %m\n");
                    228:                return -1;
                    229:        }
                    230: 
                    231:        memset(&cp, 0, sizeof cp);
                    232:        strlcpy(cp.icp_parent, csIface, IFNAMSIZ);
                    233:        cp.icp_opmode = IEEE80211_M_WDS;
                    234:        memcpy(cp.icp_bssid, p->if_bssid, IEEE80211_ADDR_LEN);
                    235: 
                    236:        memset(&ifr, 0, sizeof ifr);
                    237:        strlcpy(ifr.ifr_name, "wlan", IFNAMSIZ);
                    238:        ifr.ifr_data = (void *) &cp;
                    239: 
                    240:        if (ioctl(s, SIOCIFCREATE2, &ifr) == -1) {
                    241:                memcpy(&bssid, cp.icp_bssid, IEEE80211_ADDR_LEN);
                    242:                syslog(LOG_ERR, "Error:: create ioctl(vap) mode %u flags 0x%x parent %s bssid %s %m\n", 
                    243:                                cp.icp_opmode, cp.icp_flags, cp.icp_parent, ether_ntoa(&bssid));
                    244:                close(s);
                    245:                return -1;
                    246:        } else {
                    247:                strlcpy(p->if_name, ifr.ifr_name, IFNAMSIZ);
                    248:                close(s);
                    249:        }
                    250: 
                    251:        return 0;
                    252: }
                    253: 
                    254: inline int
                    255: wifi_createWDS(const char *csIface, struct ether_addr bssid, struct dwds_if **wds)
                    256: {
                    257:        struct dwds_if *p;
                    258:        char szParent[IFNAMSIZ];
                    259: 
1.1.2.7   misho     260:        FTRACE(5);
                    261: 
1.1.2.6   misho     262:        assert(csIface);
                    263:        assert(wds);
                    264: 
                    265:        for (p = *wds; p; p = p->if_next)
                    266:                if (!memcmp(p->if_bssid, &bssid, IEEE80211_ADDR_LEN)) {
                    267:                        VERB(1) syslog(LOG_INFO, "BSSID:%s WDS VAP already created (%s)\n",
                    268:                            ether_ntoa(&bssid), csIface);
                    269:                        return 1;
                    270:                }
                    271:        if (wifi_getParent(csIface, szParent, IFNAMSIZ) == -1) {
                    272:                syslog(LOG_ERR, "Error:: %s no pointer to parent interface\n", csIface);
                    273:                return -1;
                    274:        }
                    275: 
                    276:        p = malloc(sizeof(struct dwds_if));
                    277:        if (!p) {
                    278:                syslog(LOG_ERR, "Error:: malloc failed: %m\n");
                    279:                return -1;
                    280:        } else
                    281:                memcpy(p->if_bssid, &bssid, IEEE80211_ADDR_LEN);
1.1.2.7   misho     282:        if (wifi_vapCreate(szParent, p) == -1) {
1.1.2.6   misho     283:                free(p);
                    284:                return -1;
                    285:        } else {
                    286:                p->if_next = *wds;
                    287:                *wds = p;
                    288:                VERB(1) syslog(LOG_INFO, "BSSID:%s create WDS VAP %s\n", ether_ntoa(&bssid), p->if_name);
1.1.2.5   misho     289:        }
1.1.2.6   misho     290: 
                    291:        return 0;
1.1.2.5   misho     292: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>