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