Ticket #858: 010-true_radiotap_parser.diff

File 010-true_radiotap_parser.diff, 4.3 kB (added by xmxwx@asn.pl, 6 years ago)
  • madwifi/net80211/ieee80211_monitor.c

    old new  
    165163                        ph->try0 = 1; 
    166164                break; 
    167165        } 
     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        } 
    168267        case ARPHRD_IEEE80211_ATHDESC: { 
    169268                if (skb->len > ATHDESC_HEADER_SIZE) { 
    170269                        struct ar5212_openbsd_desc *desc = 
     
    182281                } 
    183282                break; 
    184283        }        
    185         case ARPHRD_IEEE80211_RADIOTAP: { 
    186                 if(skb->len >  sizeof(struct ath_tx_radiotap_header)) { 
    187                         struct ath_tx_radiotap_header *wh = (struct ath_tx_radiotap_header *) skb->data; 
    188                         ph->power = wh->wt_txpower; 
    189                         ph->rate0 = wh->wt_rate; 
    190                         ph->try0 = 1; 
    191                         skb_pull(skb, sizeof(struct ath_tx_radiotap_header)); 
    192                 } 
    193                 break; 
    194         } 
    195284        default: 
    196285                break; 
    197286        }