00001 #ifndef _BSD_SOURCE 00002 #define _BSD_SOURCE 00003 #endif 00004 00005 #include <sys/types.h> 00006 #include <sys/stat.h> 00007 #include <sys/mman.h> 00008 #include <fcntl.h> 00009 #include <unistd.h> 00010 #include <stdio.h> 00011 #include <endian.h> 00012 #include <errno.h> 00013 #include <string.h> 00014 #include "radiotap_iter.h" 00015 00016 static int fcshdr = 0; 00017 00018 static const struct radiotap_align_size align_size_000000_00[] = { 00019 [0] = { .align = 1, .size = 4, }, 00020 [52] = { .align = 1, .size = 4, }, 00021 }; 00022 00023 static const struct ieee80211_radiotap_namespace vns_array[] = { 00024 { 00025 .oui = 0x000000, 00026 .subns = 0, 00027 .n_bits = sizeof(align_size_000000_00), 00028 .align_size = align_size_000000_00, 00029 }, 00030 }; 00031 00032 static const struct ieee80211_radiotap_vendor_namespaces vns = { 00033 .ns = vns_array, 00034 .n_ns = sizeof(vns_array)/sizeof(vns_array[0]), 00035 }; 00036 00037 static void print_radiotap_namespace(struct ieee80211_radiotap_iterator *iter) 00038 { 00039 switch (iter->this_arg_index) { 00040 case IEEE80211_RADIOTAP_TSFT: 00041 printf("\tTSFT: %llu\n", le64toh(*(unsigned long long *)iter->this_arg)); 00042 break; 00043 case IEEE80211_RADIOTAP_FLAGS: 00044 printf("\tflags: %02x\n", *iter->this_arg); 00045 break; 00046 case IEEE80211_RADIOTAP_RATE: 00047 printf("\trate: %lf\n", (double)*iter->this_arg/2); 00048 break; 00049 case IEEE80211_RADIOTAP_CHANNEL: 00050 case IEEE80211_RADIOTAP_FHSS: 00051 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: 00052 case IEEE80211_RADIOTAP_DBM_ANTNOISE: 00053 case IEEE80211_RADIOTAP_LOCK_QUALITY: 00054 case IEEE80211_RADIOTAP_TX_ATTENUATION: 00055 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: 00056 case IEEE80211_RADIOTAP_DBM_TX_POWER: 00057 case IEEE80211_RADIOTAP_ANTENNA: 00058 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: 00059 case IEEE80211_RADIOTAP_DB_ANTNOISE: 00060 case IEEE80211_RADIOTAP_TX_FLAGS: 00061 break; 00062 case IEEE80211_RADIOTAP_RX_FLAGS: 00063 if (fcshdr) { 00064 printf("\tFCS in header: %.8x\n", 00065 le32toh(*(uint32_t *)iter->this_arg)); 00066 break; 00067 } 00068 printf("\tRX flags: %#.4x\n", 00069 le16toh(*(uint16_t *)iter->this_arg)); 00070 break; 00071 case IEEE80211_RADIOTAP_RTS_RETRIES: 00072 case IEEE80211_RADIOTAP_DATA_RETRIES: 00073 break; 00074 break; 00075 default: 00076 printf("\tBOGUS DATA\n"); 00077 break; 00078 } 00079 } 00080 00081 static void print_test_namespace(struct ieee80211_radiotap_iterator *iter) 00082 { 00083 switch (iter->this_arg_index) { 00084 case 0: 00085 case 52: 00086 printf("\t00:00:00-00|%d: %.2x/%.2x/%.2x/%.2x\n", 00087 iter->this_arg_index, 00088 *iter->this_arg, *(iter->this_arg + 1), 00089 *(iter->this_arg + 2), *(iter->this_arg + 3)); 00090 break; 00091 default: 00092 printf("\tBOGUS DATA - vendor ns %d\n", iter->this_arg_index); 00093 break; 00094 } 00095 } 00096 00097 static const struct radiotap_override overrides[] = { 00098 { .field = 14, .align = 4, .size = 4, } 00099 }; 00100 00101 int main(int argc, char *argv[]) 00102 { 00103 struct ieee80211_radiotap_iterator iter; 00104 struct stat statbuf; 00105 int fd, err, fnidx = 1, i; 00106 void *data; 00107 00108 if (argc != 2 && argc != 3) { 00109 fprintf(stderr, "usage: parse [--fcshdr] <file>\n"); 00110 fprintf(stderr, " --fcshdr: read bit 14 as FCS\n"); 00111 return 2; 00112 } 00113 00114 if (strcmp(argv[1], "--fcshdr") == 0) { 00115 fcshdr = 1; 00116 fnidx++; 00117 } 00118 00119 fd = open(argv[fnidx], O_RDONLY); 00120 if (fd < 0) { 00121 fprintf(stderr, "cannot open file %s\n", argv[fnidx]); 00122 return 2; 00123 } 00124 00125 if (fstat(fd, &statbuf)) { 00126 perror("fstat"); 00127 return 2; 00128 } 00129 00130 data = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); 00131 00132 err = ieee80211_radiotap_iterator_init(&iter, data, statbuf.st_size, &vns); 00133 if (err) { 00134 printf("malformed radiotap header (init returns %d)\n", err); 00135 return 3; 00136 } 00137 00138 if (fcshdr) { 00139 iter.overrides = overrides; 00140 iter.n_overrides = sizeof(overrides)/sizeof(overrides[0]); 00141 } 00142 00143 while (!(err = ieee80211_radiotap_iterator_next(&iter))) { 00144 if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { 00145 printf("\tvendor NS (%.2x-%.2x-%.2x:%d, %d bytes)\n", 00146 iter.this_arg[0], iter.this_arg[1], 00147 iter.this_arg[2], iter.this_arg[3], 00148 iter.this_arg_size - 6); 00149 for (i = 6; i < iter.this_arg_size; i++) { 00150 if (i % 8 == 6) 00151 printf("\t\t"); 00152 else 00153 printf(" "); 00154 printf("%.2x", iter.this_arg[i]); 00155 } 00156 printf("\n"); 00157 } else if (iter.is_radiotap_ns) 00158 print_radiotap_namespace(&iter); 00159 else if (iter.current_namespace == &vns_array[0]) 00160 print_test_namespace(&iter); 00161 } 00162 00163 if (err != -ENOENT) { 00164 printf("malformed radiotap data\n"); 00165 return 3; 00166 } 00167 00168 return 0; 00169 }