| | 166 | case ARPHRD_IEEE80211_RADIOTAP: { |
|---|
| | 167 | struct ieee80211_frame *wh = NULL; |
|---|
| | 168 | struct ieee80211_radiotap_header *rh = |
|---|
| | 169 | (struct ieee80211_radiotap_header *)skb->data; |
|---|
| | 170 | u_int32_t present, present_ext; |
|---|
| | 171 | u_int16_t len; |
|---|
| | 172 | u_int8_t *start = skb->data + sizeof(struct ieee80211_radiotap_header); |
|---|
| | 173 | u_int8_t *p = start; |
|---|
| | 174 | u_int8_t *end = skb->data + skb->len; |
|---|
| | 175 | u_int8_t bit, flags = 0; |
|---|
| | 176 | |
|---|
| | 177 | if (skb->len < sizeof(*rh) || rh->it_version != 0) |
|---|
| | 178 | break; |
|---|
| | 179 | |
|---|
| | 180 | present_ext = present = le32_to_cpu(rh->it_present); |
|---|
| | 181 | len = le16_to_cpu(rh->it_len); |
|---|
| | 182 | |
|---|
| | 183 | if (skb->len < len) |
|---|
| | 184 | break; |
|---|
| | 185 | |
|---|
| | 186 | /* skip the chain of additional bitmaps following it_present */ |
|---|
| | 187 | while (present_ext & (1 << IEEE80211_RADIOTAP_EXT)) { |
|---|
| | 188 | if (p+4 > end) { |
|---|
| | 189 | /* An extended bitmap would now follow, but there is |
|---|
| | 190 | * no place for it. Stop parsing. */ |
|---|
| | 191 | present = 0; |
|---|
| | 192 | break; |
|---|
| | 193 | } |
|---|
| | 194 | present_ext = le32_to_cpu(*(u_int32_t*)p); |
|---|
| | 195 | p += 4; |
|---|
| | 196 | } |
|---|
| | 197 | |
|---|
| | 198 | for (bit = 0; present && p < end; present >>= 1, bit++) { |
|---|
| | 199 | if ((present & 1) == 0) |
|---|
| | 200 | continue; |
|---|
| | 201 | switch (bit) { |
|---|
| | 202 | case IEEE80211_RADIOTAP_RATE: |
|---|
| | 203 | ph->rate0 = *p; |
|---|
| | 204 | p++; |
|---|
| | 205 | break; |
|---|
| | 206 | |
|---|
| | 207 | case IEEE80211_RADIOTAP_DBM_TX_POWER: |
|---|
| | 208 | ph->power = *p; |
|---|
| | 209 | p++; |
|---|
| | 210 | break; |
|---|
| | 211 | |
|---|
| | 212 | case IEEE80211_RADIOTAP_FLAGS: |
|---|
| | 213 | flags = *p; |
|---|
| | 214 | p++; |
|---|
| | 215 | break; |
|---|
| | 216 | |
|---|
| | 217 | case IEEE80211_RADIOTAP_DB_ANTSIGNAL: |
|---|
| | 218 | case IEEE80211_RADIOTAP_DB_ANTNOISE: |
|---|
| | 219 | case IEEE80211_RADIOTAP_ANTENNA: |
|---|
| | 220 | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: |
|---|
| | 221 | case IEEE80211_RADIOTAP_DBM_ANTNOISE: |
|---|
| | 222 | /* 8-bit */ |
|---|
| | 223 | p++; |
|---|
| | 224 | break; |
|---|
| | 225 | |
|---|
| | 226 | case IEEE80211_RADIOTAP_FHSS: |
|---|
| | 227 | /* 2 x 8-bit */ |
|---|
| | 228 | p += 2; |
|---|
| | 229 | break; |
|---|
| | 230 | |
|---|
| | 231 | case IEEE80211_RADIOTAP_LOCK_QUALITY: |
|---|
| | 232 | case IEEE80211_RADIOTAP_TX_ATTENUATION: |
|---|
| | 233 | case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: |
|---|
| | 234 | /* 16-bit */ |
|---|
| | 235 | p = start + roundup(p - start, 2) + 2; |
|---|
| | 236 | break; |
|---|
| | 237 | |
|---|
| | 238 | case IEEE80211_RADIOTAP_CHANNEL: |
|---|
| | 239 | /* 2 x 16-bit */ |
|---|
| | 240 | p = start + roundup(p - start, 2) + 4; |
|---|
| | 241 | break; |
|---|
| | 242 | |
|---|
| | 243 | case IEEE80211_RADIOTAP_FCS: |
|---|
| | 244 | /* 32-bit */ |
|---|
| | 245 | p = start + roundup(p - start, 4) + 4; |
|---|
| | 246 | break; |
|---|
| | 247 | |
|---|
| | 248 | case IEEE80211_RADIOTAP_TSFT: |
|---|
| | 249 | /* 64-bit */ |
|---|
| | 250 | p = start + roundup(p - start, 8) + 8; |
|---|
| | 251 | break; |
|---|
| | 252 | |
|---|
| | 253 | default: |
|---|
| | 254 | present = 0; |
|---|
| | 255 | break; |
|---|
| | 256 | } |
|---|
| | 257 | } |
|---|
| | 258 | skb_pull(skb, len); |
|---|
| | 259 | if (flags & IEEE80211_RADIOTAP_F_FCS) |
|---|
| | 260 | /* Remove FCS from the end of frames to transmit */ |
|---|
| | 261 | skb_trim(skb, skb->len - IEEE80211_CRC_LEN); |
|---|
| | 262 | wh = (struct ieee80211_frame *)skb->data; |
|---|
| | 263 | if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) |
|---|
| | 264 | ph->try0 = 1; |
|---|
| | 265 | break; |
|---|
| | 266 | } |
|---|