📄 lib80211.c
字号:
}/*! \fn void getPortType(const char *iface) \brief Uses getWord to get the port type. \param iface The name of the interface \return The current port type of the specified interface The port type is also called (operational) mode.\n 1 = BSS (client)\n 2 = semi ad-hoc, obsolete\n 3 = ad-hoc\n 4 = IBSS master (ad-hoc)\n 5 = unspecified\n 6 = HostAP\n It is recommended only modes 1, 3 and 6 are used.*/int getPortType(const char *iface) { return getWord(iface, WI_RID_PORTTYPE);}/*! \fn int getWEPkey(const char *iface, int keynr, char *ptr, int *len) \brief Retrieves the value of a certain WEP key on this interface \param iface The name of the interface \param keynr The (zero based) index to the list of available keys \param ptr A pointer to an allocated chunk of memory for storing the key \param len A pointer to an integer for storing the size of the retrieved WEP key \note Maximum key size is 13 (104 bits for 128 bit WEP encryption) \note These values should also be available with an SIOCG80211 call, but are not: only zero's are returned. \note Code has been partly ripped from wicontrol.c On exit, the chunk of memory at ptr contains the WEP key, and len contains the size of this key. In general only sizes of 0, 5 or 13 are valid (for no key, 40 bits key or 104 bits key).*/int getWEPkey(const char *iface, int keynr, char *ptr, int *len) { struct wi_req wreq; struct wi_ltv_keys *keys; bzero((char *) &wreq, sizeof(wreq)); wreq.wi_len = WI_MAX_DATALEN; wreq.wi_type = WI_RID_DEFLT_CRYPT_KEYS; getVal(iface, &wreq); keys = (struct wi_ltv_keys *) &wreq; memcpy(ptr, keys->wi_keys[keynr].wi_keydat, keys->wi_keys[keynr].wi_keylen); *len = keys->wi_keys[keynr].wi_keylen; return 0;}/******************************************************************** * next you'll find four functions used for setting an interface * up or down, and reading it's status (up/down) *//*! \fn long getIfFlags(const char *iface) \brief Reads the 32 bit flag field of the specified interface \param iface The name of the interface \note The flags are specified in if.h \note Interface is not necessarily wireless*/long getIfFlags(const char *iface) { struct ifreq ireq; int s; long flags; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) err(1, "socket"); strlcpy(ireq.ifr_name, iface, sizeof(ireq.ifr_name)); if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ireq) < 0) err(1, "SIOCGIFFLAGS"); if (close(s) < 0) err(1, "close socket"); flags = (ireq.ifr_flagshigh & 0xffff) << 16; flags += ireq.ifr_flags & 0xffff; return flags;}/*! \fn void setIfFlags(const char *iface, long flags) \brief Sets the 32 bit flag field of the specified interface \param iface The name of the interface \param flags The flags field to be set on the interface \note The flags are specified in if.h \note Interface is not necessarily wireless*/void setIfFlags(const char *iface, long flags) { struct ifreq ireq; int s; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) err(1, "socket"); // update flags ireq.ifr_flags = flags & 0xffff; ireq.ifr_flagshigh = flags >> 16; strlcpy(ireq.ifr_name, iface, sizeof(ireq.ifr_name)); /* try to set this update */ if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ireq) < 0) err(1, "SIOCSIFFLAGS"); if (close(s) < 0) err(1, "close socket");}/*! \fn int getIfAdminStatus(const char *iface) \brief Gets the operational state of the interface \param iface The name of the interface \return 1 when interface is up \return 2 otherwise (interface is down)*/int getIfAdminStatus(const char *iface) { return getIfFlags(iface) & IFF_UP ? 1 : 2;}/*! \fn void setIfUp(const char *iface) \brief Enables the specified interface \param iface The name of the interface*/void setIfUp(const char *iface) { setIfFlags(iface, getIfFlags(iface) | IFF_UP);}/*! \fn void setIfDown(const char *iface) \brief Disables the specified interface \param iface The name of the interface*/void setIfDown(const char *iface) { setIfFlags(iface, getIfFlags(iface) & ~IFF_UP);}/******************************************************************** * Below this line you'll find various functions for getting * basic 80211 values. They all use the ioctl call SIOCG80211. *//*! \fn void get80211(const char *iface, int i_type, struct ieee80211req *req) \brief This function performs the ioctl SIOCG80211 call \param iface The name of the interface \param i_type The request type \param req Structure used in ioctl call for data transfer \warning Memory is allocated, and should be freed by caller. Whis function performs a request, specified in i_type, by an ioctl call to SIOCG80211. It allocates a chunk of memory to use in the ioctl call. Results will be put in this memory chunk by the kernel.*/void get80211(const char *iface, int i_type, struct ieee80211req *req) { int s; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) err(1, "socket"); strlcpy(req->i_name, iface, sizeof(req->i_name)); req->i_type = i_type; req->i_data = (void *) malloc(100); //that should do it if (ioctl(s, SIOCG80211, req) < 0) err(1, "SIOCG80211"); if (close(s) < 0) err(1, "close socket"); }void getCurrentSSID(const char *iface, char *ptr, int *len) { getSSID(iface, -1, ptr, len);}void getSSID(const char *iface, int num, char *ptr, int *len) { struct ieee80211req req; req.i_val = num; get80211(iface, IEEE80211_IOC_SSID, &req); //req now contains the ssid //copy to our own string and free req.i_data memcpy(ptr, req.i_data, req.i_len); *len = req.i_len; free(req.i_data);}void getStationname(const char *iface, char *ptr, int *len) { struct ieee80211req req; get80211(iface, IEEE80211_IOC_STATIONNAME, &req); memcpy(ptr, req.i_data, req.i_len); *len = req.i_len;// ptr[req.i_len] = 0; //null-terminated free(req.i_data);}/*! \fn int getInteger(const char *iface, int i_type) \brief Uses get80211 to specifically read an integer value \param iface The name of the interface \param i_type The request type \return The requested integer value*/int getInteger(const char *iface, int i_type) { struct ieee80211req req; int val; get80211(iface, i_type, &req); val = req.i_val; free(req.i_data); //although we don't use this variable, it's allocated anyway and should be freed return val;}int getNumSSIDs(const char *iface) { return getInteger(iface, IEEE80211_IOC_NUMSSIDS);}int getChannel(const char *iface) { return getInteger(iface, IEEE80211_IOC_CHANNEL);}int getPowersave(const char *iface) { return getInteger(iface, IEEE80211_IOC_POWERSAVE);}int getPowersavesleep(const char *iface) { return getInteger(iface, IEEE80211_IOC_POWERSAVESLEEP);}int getAuthmode(const char *iface) { return getInteger(iface, IEEE80211_IOC_AUTHMODE);}int getWEPmode(const char *iface) { return getInteger(iface, IEEE80211_IOC_WEP);}int getNumWEPkeys(const char *iface) { return getInteger(iface, IEEE80211_IOC_NUMWEPKEYS);}int getWEPtxkey(const char *iface) { return getInteger(iface, IEEE80211_IOC_WEPTXKEY) + 1;}/******************************************************************** * the set functions below have been largely based on the ifieee80211.c * file *//*! \fn void set80211(const char *iface, int type, int val, int len, u_int8_t *data) \brief This function performs the ioctl call to SIOCS80211 \param iface The name of the interface \param type The request type \param val The integer value (e.g. channel nr, ssid nr) \param len The data length (in case of a byte string) \param data Pointer to the byte string \note This code is based on ifieee80211.c file*/void set80211(const char *iface, int type, int val, int len, u_int8_t *data){ struct ieee80211req ireq; int s; (void) memset(&ireq, 0, sizeof(ireq)); (void) strncpy(ireq.i_name, iface, sizeof(ireq.i_name)); ireq.i_type = type; ireq.i_val = val; ireq.i_len = len; ireq.i_data = data; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) err(1, "socket"); if (ioctl(s, SIOCS80211, &ireq) < 0) err(1, "SIOCS80211"); if (close(s) < 0) err(1, "close socket");}void setSSID(const char *iface, int nr, const char *val){ set80211(iface, IEEE80211_IOC_SSID, nr, strlen(val), val);}void setStationname(const char *iface, const char *val){ set80211(iface, IEEE80211_IOC_STATIONNAME, 0, strlen(val), val);}void setChannel(const char *iface, int d){ set80211(iface, IEEE80211_IOC_CHANNEL, d, 0, NULL);}void setWEPtxkey(const char *iface, int val){ set80211(iface, IEEE80211_IOC_WEPTXKEY, val-1, 0, NULL);}void setAuthmode(const char *iface, int val){ set80211(iface, IEEE80211_IOC_AUTHMODE, val, 0, NULL);}void setPowersave(const char *iface, const char *val){ int mode; if (strcasecmp(val, "off") == 0) { mode = IEEE80211_POWERSAVE_OFF; } else if (strcasecmp(val, "on") == 0) { mode = IEEE80211_POWERSAVE_ON; } else if (strcasecmp(val, "cam") == 0) { mode = IEEE80211_POWERSAVE_CAM; } else if (strcasecmp(val, "psp") == 0) { mode = IEEE80211_POWERSAVE_PSP; } else if (strcasecmp(val, "psp-cam") == 0) { mode = IEEE80211_POWERSAVE_PSP_CAM; } else { err(1, "unknown powersavemode"); } set80211(iface, IEEE80211_IOC_POWERSAVE, mode, 0, NULL);}void setPowersavesleep(const char *iface, int d){ set80211(iface, IEEE80211_IOC_POWERSAVESLEEP, d, 0, NULL);}void setWEPmode(const char *iface, const char *val){ int mode; if (strcasecmp(val, "off") == 0) { mode = IEEE80211_WEP_OFF; } else if (strcasecmp(val, "on") == 0) { mode = IEEE80211_WEP_ON; } else if (strcasecmp(val, "mixed") == 0) { mode = IEEE80211_WEP_MIXED; } else { err(1, "unknown wep mode"); } set80211(iface, IEEE80211_IOC_WEP, mode, 0, NULL);}void setWEPkey(const char *iface, const char *val, int nr){ set80211(iface, IEEE80211_IOC_WEPKEY, nr, strlen(val), val);}/*! \fn char *tostring(int val, int type, char *buf) \brief Converts an integer value to a corresponding human readable text \param val The value to be converted \param type The request type \param buf Pointer to an allocated memory space, large enough to contain the text \return Pointer to the allocated memory space (unchanged) This function takes the integer value and prints the 'meaning' of it, according to the specified request type. For example, when the authentication mode is requested, a value of two (2) means "shared".*/char *tostring(int val, int type, char *buf) { if (val == -1) { sprintf(buf, "undefined"); return buf; } switch(type) { case IEEE80211_IOC_POWERSAVE: switch(val) { case IEEE80211_POWERSAVE_NOSUP: sprintf(buf, "nosup"); break; case IEEE80211_POWERSAVE_OFF: sprintf(buf, "off"); break; case IEEE80211_POWERSAVE_CAM: sprintf(buf, "cam"); break; case IEEE80211_POWERSAVE_PSP: sprintf(buf, "psp"); break; case IEEE80211_POWERSAVE_PSP_CAM: sprintf(buf, "psp-cam"); break; } break; case IEEE80211_IOC_WEP: switch(val) { case IEEE80211_WEP_NOSUP: sprintf(buf, "nosup"); break; case IEEE80211_WEP_ON: sprintf(buf, "on"); break; case IEEE80211_WEP_OFF: sprintf(buf, "off"); break; case IEEE80211_WEP_MIXED: sprintf(buf, "mixed"); break; } break; case IEEE80211_IOC_AUTHMODE: switch(val) { case IEEE80211_AUTH_NONE: sprintf(buf, "none"); break; case IEEE80211_AUTH_OPEN: sprintf(buf, "open"); break; case IEEE80211_AUTH_SHARED: sprintf(buf, "shared"); break; } break; case IEEE80211_IOC_POWERSAVESLEEP: sprintf(buf, "%d msec", val); break; default: sprintf(buf, "%d", val); break; } return buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -