|
|
| version 1.1.2.1, 2010/10/27 15:23:49 | version 1.1.2.5, 2010/10/28 09:08:58 |
|---|---|
| Line 2 | Line 2 |
| #include "dwds.h" | #include "dwds.h" |
| static inline int | |
| wifi_getParent(const char *csVAP, char *psParent, size_t plen) | |
| { | |
| char szOID[STRSIZ] = { 0 }; | |
| FTRACE(5); | |
| assert(csVAP); | |
| assert(psParent); | |
| memset(psParent, 0, plen); | |
| snprintf(szOID, STRSIZ, "net.wlan.%s.%%parent", csVAP + 4); | |
| if (sysctlbyname(szOID, psParent, &plen, NULL, 0) == -1) { | |
| // syslog(LOG_ERR, "Error:: can`t get parent #%d - %s\n", errno, strerror(errno)); | |
| return -1; | |
| } else | |
| psParent[plen] = 0; | |
| return 0; | |
| } | |
| static inline int | |
| wifi_chkIface(const char *csVAP, char **ppsIF, int nIF) | |
| { | |
| char szParent[IFNAMSIZ]; | |
| register int i; | |
| FTRACE(5); | |
| assert(csVAP); | |
| if (wifi_getParent(csVAP, szParent, IFNAMSIZ) == -1) | |
| return -1; | |
| for (i = 0; i < nIF; i++) | |
| if (!strcasecmp(ppsIF[i], "any") || !strcmp(ppsIF[i], szParent)) | |
| return 1; /* OK, vap is child */ | |
| syslog(LOG_ERR, "Error:: Interface %s parent %s not being monitored", csVAP, szParent); | |
| return 0; | |
| } | |
| static inline int | |
| wifi_isWDS(int fd, const char *csVAP) | |
| { | |
| struct ifmediareq ifmr; | |
| FTRACE(5); | |
| assert(csVAP); | |
| memset(&ifmr, 0, sizeof ifmr); | |
| strlcpy(ifmr.ifm_name, csVAP, sizeof ifmr.ifm_name); | |
| if (ioctl(fd, SIOCGIFMEDIA, &ifmr) == -1) { | |
| syslog(LOG_ERR, "Error:: can`t get media for %s #%d - %s\n", csVAP, | |
| errno, strerror(errno)); | |
| return -1; | |
| } | |
| return (ifmr.ifm_current & IFM_IEEE80211_WDS) != 0; | |
| } | |
| static inline int | |
| wifi_getBSSID(int fd, const char *csVAP, uint8_t *psBSSID, int len) | |
| { | |
| struct ieee80211req ireq; | |
| FTRACE(5); | |
| assert(csVAP); | |
| assert(psBSSID); | |
| memset(&ireq, 0, sizeof ireq); | |
| strlcpy(ireq.i_name, csVAP, sizeof ireq.i_name); | |
| ireq.i_type = IEEE80211_IOC_BSSID; | |
| ireq.i_data = psBSSID; | |
| ireq.i_len = len; | |
| if (ioctl(fd, SIOCG80211, &ireq) == -1) { | |
| syslog(LOG_ERR, "Error:: can`t get BSSID for %s #%d - %s\n", csVAP, | |
| errno, strerror(errno)); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| struct dwds_if * | |
| wifi_buildWDS(int fd, char **ppsIF, int nIF) | |
| { | |
| struct dwds_if *p, *wds = NULL; | |
| char szVAP[IFNAMSIZ]; | |
| struct ether_addr bssid; | |
| register int i; | |
| for (i = 0; i < 128; i++) { | |
| memset(szVAP, 0, IFNAMSIZ); | |
| snprintf(szVAP, IFNAMSIZ, "wlan%d", i); | |
| if (wifi_chkIface(szVAP, ppsIF, nIF) > 0 && wifi_isWDS(fd, szVAP) > 0) { | |
| p = malloc(sizeof(struct dwds_if)); | |
| if (!p) { | |
| syslog(LOG_ERR, "Error:: can`t allocate memory #%d - %s\n", | |
| errno, strerror(errno)); | |
| i = -1; | |
| break; | |
| } | |
| strlcpy(p->if_name, szVAP, IFNAMSIZ); | |
| if (wifi_getBSSID(fd, szVAP, p->if_bssid, IEEE80211_ADDR_LEN) == -1) { | |
| free(p); | |
| i = -1; | |
| break; | |
| } | |
| p->if_next = wds; | |
| wds = p; | |
| memcpy(&bssid, p->if_bssid, ETHER_ADDR_LEN); | |
| syslog(LOG_INFO, "BSSID:%s discover WDS vap %s\n", ether_ntoa(&bssid), szVAP); | |
| } | |
| } | |
| if (i == -1) | |
| while ((p = wds)) { | |
| wds = wds->if_next; | |
| free(p); | |
| } | |
| return wds; | |
| } | |
| inline void | |
| wifi_destroyWDS(const char *csIface, struct dwds_if **wds) | |
| { | |
| struct dwds_if *p, **pp; | |
| assert(csIface); | |
| assert(wds); | |
| for (pp = wds; (p = *pp); pp = &p->if_next) | |
| if (!strncmp(p->if_name, csIface, IFNAMSIZ)) | |
| break; | |
| if (p) { | |
| *pp = p->if_next; | |
| free(p); | |
| } | |
| } |