📄 iwlib.c
字号:
{ /* Check the interface address type */ if(iw_check_if_addr_type(skfd, ifname) < 0) return(-1); /* Check the interface address type */ if(iw_check_mac_addr_type(skfd, ifname) < 0) return(-1); return(0);}#endif/*------------------------------------------------------------------*//* * Display an Ethernet address in readable format. */voidiw_ether_ntop(const struct ether_addr* eth, char* buf){ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", eth->ether_addr_octet[0], eth->ether_addr_octet[1], eth->ether_addr_octet[2], eth->ether_addr_octet[3], eth->ether_addr_octet[4], eth->ether_addr_octet[5]);}/*------------------------------------------------------------------*//* * Display an Ethernet address in readable format. * Same with a static buffer */char *iw_ether_ntoa(const struct ether_addr* eth){ static char buf[20]; iw_ether_ntop(eth, buf); return buf;}/*------------------------------------------------------------------*//* * Input an Ethernet address and convert to binary. */intiw_ether_aton(const char *orig, struct ether_addr *eth){ const char *bufp; int i; i = 0; for(bufp = orig; *bufp != '\0'; ++bufp) { unsigned int val; unsigned char c = *bufp++; if (isdigit(c)) val = c - '0'; else if (c >= 'a' && c <= 'f') val = c - 'a' + 10; else if (c >= 'A' && c <= 'F') val = c - 'A' + 10; else break; val <<= 4; c = *bufp++; if (isdigit(c)) val |= c - '0'; else if (c >= 'a' && c <= 'f') val |= c - 'a' + 10; else if (c >= 'A' && c <= 'F') val |= c - 'A' + 10; else break; eth->ether_addr_octet[i] = (unsigned char) (val & 0377); if(++i == ETH_ALEN) { /* That's it. Any trailing junk? */ if (*bufp != '\0') {#ifdef DEBUG fprintf(stderr, "iw_ether_aton(%s): trailing junk!\n", orig); errno = EINVAL; return(0);#endif }#ifdef DEBUG fprintf(stderr, "iw_ether_aton(%s): %s\n", orig, ether_ntoa(eth));#endif return(1); } if (*bufp != ':') break; }#ifdef DEBUG fprintf(stderr, "iw_ether_aton(%s): invalid ether address!\n", orig);#endif errno = EINVAL; return(0);}/*------------------------------------------------------------------*//* * Input an Internet address and convert to binary. */intiw_in_inet(char *name, struct sockaddr *sap){ struct hostent *hp; struct netent *np; struct sockaddr_in *sin = (struct sockaddr_in *) sap; /* Grmpf. -FvK */ sin->sin_family = AF_INET; sin->sin_port = 0; /* Default is special, meaning 0.0.0.0. */ if (!strcmp(name, "default")) { sin->sin_addr.s_addr = INADDR_ANY; return(1); } /* Try the NETWORKS database to see if this is a known network. */ if ((np = getnetbyname(name)) != (struct netent *)NULL) { sin->sin_addr.s_addr = htonl(np->n_net); strcpy(name, np->n_name); return(1); } /* Always use the resolver (DNS name + IP addresses) */ if ((hp = gethostbyname(name)) == (struct hostent *)NULL) { errno = h_errno; return(-1); } memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], hp->h_length); strcpy(name, hp->h_name); return(0);}/*------------------------------------------------------------------*//* * Input an address and convert to binary. */intiw_in_addr(int skfd, char * ifname, char * bufp, struct sockaddr *sap){ /* Check if it is a hardware or IP address */ if(index(bufp, ':') == NULL) { struct sockaddr if_address; struct arpreq arp_query; /* Check if we have valid interface address type */ if(iw_check_if_addr_type(skfd, ifname) < 0) { fprintf(stderr, "%-8.8s Interface doesn't support IP addresses\n", ifname); return(-1); } /* Read interface address */ if(iw_in_inet(bufp, &if_address) < 0) { fprintf(stderr, "Invalid interface address %s\n", bufp); return(-1); } /* Translate IP addresses to MAC addresses */ memcpy((char *) &(arp_query.arp_pa), (char *) &if_address, sizeof(struct sockaddr)); arp_query.arp_ha.sa_family = 0; arp_query.arp_flags = 0; /* The following restrict the search to the interface only */ /* For old kernels which complain, just comment it... */ strncpy(arp_query.arp_dev, ifname, IFNAMSIZ); if((ioctl(skfd, SIOCGARP, &arp_query) < 0) || !(arp_query.arp_flags & ATF_COM)) { fprintf(stderr, "Arp failed for %s on %s... (%d)\nTry to ping the address before setting it.\n", bufp, ifname, errno); return(-1); } /* Store new MAC address */ memcpy((char *) sap, (char *) &(arp_query.arp_ha), sizeof(struct sockaddr));#ifdef DEBUG printf("IP Address %s => Hw Address = %s\n", bufp, iw_ether_ntoa((struct ether_addr *) sap->sa_data));#endif } else /* If it's an hardware address */ { /* Check if we have valid mac address type */ if(iw_check_mac_addr_type(skfd, ifname) < 0) { fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n", ifname); return(-1); } /* Get the hardware address */ if(iw_in_ether(bufp, sap) < 0) { fprintf(stderr, "Invalid hardware address %s\n", bufp); return(-1); } }#ifdef DEBUG printf("Hw Address = %s\n", iw_ether_ntoa((struct ether_addr *) sap->sa_data));#endif return(0);}/************************* MISC SUBROUTINES **************************//* Size (in bytes) of various events */static const int priv_type_size[] = { 0, /* IW_PRIV_TYPE_NONE */ 1, /* IW_PRIV_TYPE_BYTE */ 1, /* IW_PRIV_TYPE_CHAR */ 0, /* Not defined */ sizeof(__u32), /* IW_PRIV_TYPE_INT */ sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */ sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */ 0, /* Not defined */};/*------------------------------------------------------------------*//* * Max size in bytes of an private argument. */intiw_get_priv_size(int args){ int num = args & IW_PRIV_SIZE_MASK; int type = (args & IW_PRIV_TYPE_MASK) >> 12; return(num * priv_type_size[type]);}/************************ EVENT SUBROUTINES ************************//* * The Wireless Extension API 14 and greater define Wireless Events, * that are used for various events and scanning. * Those functions help the decoding of events, so are needed only in * this case. */#if WIRELESS_EXT > 13/* Type of headers we know about (basically union iwreq_data) */#define IW_HEADER_TYPE_NULL 0 /* Not available */#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */#define IW_HEADER_TYPE_UINT 4 /* __u32 */#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality *//* Headers for the various requests */static const char standard_ioctl_hdr[] = { IW_HEADER_TYPE_NULL, /* SIOCSIWCOMMIT */ IW_HEADER_TYPE_CHAR, /* SIOCGIWNAME */ IW_HEADER_TYPE_PARAM, /* SIOCSIWNWID */ IW_HEADER_TYPE_PARAM, /* SIOCGIWNWID */ IW_HEADER_TYPE_FREQ, /* SIOCSIWFREQ */ IW_HEADER_TYPE_FREQ, /* SIOCGIWFREQ */ IW_HEADER_TYPE_UINT, /* SIOCSIWMODE */ IW_HEADER_TYPE_UINT, /* SIOCGIWMODE */ IW_HEADER_TYPE_PARAM, /* SIOCSIWSENS */ IW_HEADER_TYPE_PARAM, /* SIOCGIWSENS */ IW_HEADER_TYPE_NULL, /* SIOCSIWRANGE */ IW_HEADER_TYPE_POINT, /* SIOCGIWRANGE */ IW_HEADER_TYPE_NULL, /* SIOCSIWPRIV */ IW_HEADER_TYPE_POINT, /* SIOCGIWPRIV */ IW_HEADER_TYPE_NULL, /* SIOCSIWSTATS */ IW_HEADER_TYPE_POINT, /* SIOCGIWSTATS */ IW_HEADER_TYPE_POINT, /* SIOCSIWSPY */ IW_HEADER_TYPE_POINT, /* SIOCGIWSPY */ IW_HEADER_TYPE_POINT, /* SIOCSIWTHRSPY */ IW_HEADER_TYPE_POINT, /* SIOCGIWTHRSPY */ IW_HEADER_TYPE_ADDR, /* SIOCSIWAP */ IW_HEADER_TYPE_ADDR, /* SIOCGIWAP */ IW_HEADER_TYPE_NULL, /* -- hole -- */ IW_HEADER_TYPE_POINT, /* SIOCGIWAPLIST */ IW_HEADER_TYPE_PARAM, /* SIOCSIWSCAN */ IW_HEADER_TYPE_POINT, /* SIOCGIWSCAN */ IW_HEADER_TYPE_POINT, /* SIOCSIWESSID */ IW_HEADER_TYPE_POINT, /* SIOCGIWESSID */ IW_HEADER_TYPE_POINT, /* SIOCSIWNICKN */ IW_HEADER_TYPE_POINT, /* SIOCGIWNICKN */ IW_HEADER_TYPE_NULL, /* -- hole -- */ IW_HEADER_TYPE_NULL, /* -- hole -- */ IW_HEADER_TYPE_PARAM, /* SIOCSIWRATE */ IW_HEADER_TYPE_PARAM, /* SIOCGIWRATE */ IW_HEADER_TYPE_PARAM, /* SIOCSIWRTS */ IW_HEADER_TYPE_PARAM, /* SIOCGIWRTS */ IW_HEADER_TYPE_PARAM, /* SIOCSIWFRAG */ IW_HEADER_TYPE_PARAM, /* SIOCGIWFRAG */ IW_HEADER_TYPE_PARAM, /* SIOCSIWTXPOW */ IW_HEADER_TYPE_PARAM, /* SIOCGIWTXPOW */ IW_HEADER_TYPE_PARAM, /* SIOCSIWRETRY */ IW_HEADER_TYPE_PARAM, /* SIOCGIWRETRY */ IW_HEADER_TYPE_POINT, /* SIOCSIWENCODE */ IW_HEADER_TYPE_POINT, /* SIOCGIWENCODE */ IW_HEADER_TYPE_PARAM, /* SIOCSIWPOWER */ IW_HEADER_TYPE_PARAM, /* SIOCGIWPOWER */};static const unsigned int standard_ioctl_num = sizeof(standard_ioctl_hdr);/* * Meta-data about all the additional standard Wireless Extension events * we know about. */static const char standard_event_hdr[] = { IW_HEADER_TYPE_ADDR, /* IWEVTXDROP */ IW_HEADER_TYPE_QUAL, /* IWEVQUAL */ IW_HEADER_TYPE_POINT, /* IWEVCUSTOM */ IW_HEADER_TYPE_ADDR, /* IWEVREGISTERED */ IW_HEADER_TYPE_ADDR, /* IWEVEXPIRED */};static const unsigned int standard_event_num = sizeof(standard_event_hdr);/* Size (in bytes) of various events */static const int event_type_size[] = { IW_EV_LCP_LEN, /* IW_HEADER_TYPE_NULL */ 0, IW_EV_CHAR_LEN, /* IW_HEADER_TYPE_CHAR */ 0, IW_EV_UINT_LEN, /* IW_HEADER_TYPE_UINT */ IW_EV_FREQ_LEN, /* IW_HEADER_TYPE_FREQ */ IW_EV_ADDR_LEN, /* IW_HEADER_TYPE_ADDR */ 0, IW_EV_POINT_LEN, /* Without variable payload */ IW_EV_PARAM_LEN, /* IW_HEADER_TYPE_PARAM */ IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */};/*------------------------------------------------------------------*//* * Initialise the struct stream_descr so that we can extract * individual events from the event stream. */voidiw_init_event_stream(struct stream_descr * stream, /* Stream of events */ char * data, int len){ /* Cleanup */ memset((char *) stream, '\0', sizeof(struct stream_descr)); /* Set things up */ stream->current = data; stream->end = data + len;}/*------------------------------------------------------------------*//* * Extract the next event from the event stream. */intiw_extract_event_stream(struct stream_descr * stream, /* Stream of events */ struct iw_event * iwe) /* Extracted event */{ int event_type = 0; unsigned int event_len = 1; /* Invalid */ char * pointer; /* Don't "optimise" the following variable, it will crash */ unsigned cmd_index; /* *MUST* be unsigned */ /* Check for end of stream */ if((stream->current + IW_EV_LCP_LEN) > stream->end) return(0);#if 0 printf("DBG - stream->current = %p, stream->value = %p, stream->end = %p\n", stream->current, stream->value, stream->end);#endif /* Extract the event header (to get the event id). * Note : the event may be unaligned, therefore copy... */ memcpy((char *) iwe, stream->current, IW_EV_LCP_LEN);#if 0 printf("DBG - iwe->cmd = 0x%X, iwe->len = %d\n", iwe->cmd, iwe->len);#endif /* Check invalid events */ if(iwe->len <= IW_EV_LCP_LEN) return(-1); /* Get the type and length of that event */ if(iwe->cmd <= SIOCIWLAST) { cmd_index = iwe->cmd - SIOCIWFIRST; if(cmd_index < standard_ioctl_num) event_type = standard_ioctl_hdr[cmd_index]; } else { cmd_index = iwe->cmd - IWEVFIRST; if(cmd_index < standard_event_num) event_type = standard_event_hdr[cmd_index]; } /* Unknown events -> event_type=0 => IW_EV_LCP_LEN */ event_len = event_type_size[event_type]; /* Check if we know about this event */ if(event_len <= IW_EV_LCP_LEN) { /* Skip to next event */ stream->current += iwe->len; return(2); } event_len -= IW_EV_LCP_LEN; /* Set pointer on data */ if(stream->value != NULL) pointer = stream->value; /* Next value in event */ else pointer = stream->current + IW_EV_LCP_LEN; /* First value in event */#if 0 printf("DBG - event_type = %d, event_len = %d, pointer = %p\n", event_type, event_len, pointer);#endif /* Copy the rest of the event (at least, fixed part) */ if((pointer + event_len) > stream->end) { /* Go to next event */ stream->current += iwe->len; return(-2); } memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len); /* Skip event in the stream */ pointer += event_len; /* Special processing for iw_point events */ if(event_type == IW_HEADER_TYPE_POINT) { /* Check the length of the payload */ if((iwe->len - (event_len + IW_EV_LCP_LEN)) > 0) /* Set pointer on variable part (warning : non aligned) */ iwe->u.data.pointer = pointer; else /* No data */ iwe->u.data.pointer = NULL; /* Go to next event */ stream->current += iwe->len; } else { /* Is there more value in the event ? */ if((pointer + event_len) <= (stream->current + iwe->len)) /* Go to next value */ stream->value = pointer; else { /* Go to next event */ stream->value = NULL; stream->current += iwe->len; } } return(1);}#endif /* WIRELESS_EXT > 13 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -