static void list_channels(const char *ifname, int allchans) { struct ieee80211req_chaninfo chans; struct ieee80211req_chaninfo achans; const struct ieee80211_channel *c; int i, half; if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANINFO, &chans, sizeof(chans)) < 0) errx(1, "unable to get channel information"); if (!allchans) { uint8_t active[32]; if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANLIST, &active, sizeof(active)) < 0) errx(1, "unable to get active channel list"); memset(&achans, 0, sizeof(achans)); for (i = 0; i < chans.ic_nchans; i++) { c = &chans.ic_chans[i]; if (isset(active, ieee80211_mhz2ieee(c->ic_freq)) || allchans) achans.ic_chans[achans.ic_nchans++] = *c; } } else achans = chans; half = achans.ic_nchans / 2; if (achans.ic_nchans % 2) half++; for (i = 0; i < achans.ic_nchans / 2; i++) { print_chaninfo(&achans.ic_chans[i]); print_chaninfo(&achans.ic_chans[half + i]); printf("\n"); } if (achans.ic_nchans % 2) { print_chaninfo(&achans.ic_chans[i]); printf("\n"); } }
static int print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags) { union { int8_t i8; u_int8_t u8; int16_t i16; u_int16_t u16; u_int32_t u32; u_int64_t u64; } u, u2, u3, u4; int rc; switch (bit) { case IEEE80211_RADIOTAP_FLAGS: rc = cpack_uint8(s, &u.u8); *flags = u.u8; break; case IEEE80211_RADIOTAP_RATE: case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: case IEEE80211_RADIOTAP_ANTENNA: rc = cpack_uint8(s, &u.u8); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: case IEEE80211_RADIOTAP_DBM_ANTNOISE: rc = cpack_int8(s, &u.i8); break; case IEEE80211_RADIOTAP_CHANNEL: rc = cpack_uint16(s, &u.u16); if (rc != 0) break; rc = cpack_uint16(s, &u2.u16); break; case IEEE80211_RADIOTAP_FHSS: case IEEE80211_RADIOTAP_LOCK_QUALITY: case IEEE80211_RADIOTAP_TX_ATTENUATION: rc = cpack_uint16(s, &u.u16); break; case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: rc = cpack_uint8(s, &u.u8); break; case IEEE80211_RADIOTAP_DBM_TX_POWER: rc = cpack_int8(s, &u.i8); break; case IEEE80211_RADIOTAP_TSFT: rc = cpack_uint64(s, &u.u64); break; case IEEE80211_RADIOTAP_XCHANNEL: rc = cpack_uint32(s, &u.u32); if (rc != 0) break; rc = cpack_uint16(s, &u2.u16); if (rc != 0) break; rc = cpack_uint8(s, &u3.u8); if (rc != 0) break; rc = cpack_uint8(s, &u4.u8); break; default: /* this bit indicates a field whose * size we do not know, so we cannot * proceed. Just print the bit number. */ printf("[bit %u] ", bit); return -1; } if (rc != 0) { printf("[|802.11]"); return rc; } switch (bit) { case IEEE80211_RADIOTAP_CHANNEL: print_chaninfo(u.u16, u2.u16); break; case IEEE80211_RADIOTAP_FHSS: printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff); break; case IEEE80211_RADIOTAP_RATE: if (u.u8 & 0x80) PRINT_HT_RATE("", u.u8, " Mb/s "); else PRINT_RATE("", u.u8, " Mb/s "); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: printf("%ddB signal ", u.i8); break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: printf("%ddB noise ", u.i8); break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: printf("%ddB signal ", u.u8); break; case IEEE80211_RADIOTAP_DB_ANTNOISE: printf("%ddB noise ", u.u8); break; case IEEE80211_RADIOTAP_LOCK_QUALITY: printf("%u sq ", u.u16); break; case IEEE80211_RADIOTAP_TX_ATTENUATION: printf("%d tx power ", -(int)u.u16); break; case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: printf("%ddB tx power ", -(int)u.u8); break; case IEEE80211_RADIOTAP_DBM_TX_POWER: printf("%ddBm tx power ", u.i8); break; case IEEE80211_RADIOTAP_FLAGS: if (u.u8 & IEEE80211_RADIOTAP_F_CFP) printf("cfp "); if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE) printf("short preamble "); if (u.u8 & IEEE80211_RADIOTAP_F_WEP) printf("wep "); if (u.u8 & IEEE80211_RADIOTAP_F_FRAG) printf("fragmented "); if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS) printf("bad-fcs "); break; case IEEE80211_RADIOTAP_ANTENNA: printf("antenna %d ", u.u8); break; case IEEE80211_RADIOTAP_TSFT: printf("%" PRIu64 "us tsft ", u.u64); break; case IEEE80211_RADIOTAP_XCHANNEL: print_chaninfo(u2.u16, u.u32); break; } return 0; }