[Listener] Fix radiotap alignment bug

The fields in the radiotap header are naturally aligned, which was not
taken into account by the parser.
This commit is contained in:
Matteo Cypriani 2013-04-23 18:50:41 -04:00
parent 6f0d5c8da5
commit a046dcd3fb
2 changed files with 57 additions and 15 deletions

View File

@ -198,6 +198,16 @@ enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ;
//#define RTAP_EXT 31
/*
* Returns the number of bytes needed to jump after a (radiotap) field of
* length 'FIELD_LEN' that should sit at the position 'OFFSET' in the
* buffer, taking into account alignment considerations.
*/
#define SKIP_FIELD(OFFSET, FIELD_LEN) \
((FIELD_LEN) + nat_align((OFFSET), (FIELD_LEN)))
/* Function headers */
int initialise_configuration(int argc, char **argv) ;
int parse_config_file(int argc, char **argv) ;
@ -225,6 +235,7 @@ void extract_packet_numbers(const u_char *pkt_data,
void extract_radiotap_data(const u_char *pkt_data,
owl_captured_request *request,
owl_bool rtap_fields[15]) ;
uint_fast16_t nat_align(uint_fast16_t offset, uint_fast8_t field_len) ;
void get_mac_addr(char *eth, uint8_t mac_bytes[ETHER_ADDR_LEN]) ;
void get_ip_addr(char *eth, char *ip_bytes) ;

View File

@ -1311,27 +1311,32 @@ void extract_radiotap_data(const u_char *pkt_data,
{
case RTAP_MACTS:
rtap_fields[RTAP_MACTS] = owl_true ;
rtap_position += RTAP_L_MACTS ;
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_MACTS) ;
break ;
case RTAP_FLAGS:
rtap_fields[RTAP_FLAGS] = owl_true;
rtap_position += RTAP_L_FLAGS ;
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_FLAGS) ;
break ;
case RTAP_RATE:
rtap_fields[RTAP_RATE] = owl_true;
rtap_position += RTAP_L_RATE ;
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_RATE) ;
break ;
case RTAP_CHANNEL:
rtap_fields[RTAP_CHANNEL] = owl_true ;
rtap_position += RTAP_L_CHANNEL ;
rtap_position += RTAP_L_CHANNELTYPE ;
// The channel field is actually two fields that must be
// aligned independently
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_CHANNEL) ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_CHANNELTYPE) ;
break ;
case RTAP_FHSS:
rtap_fields[RTAP_FHSS] = owl_true;
rtap_position += RTAP_L_FHSS ;
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_FHSS) ;
break ;
case RTAP_ANTENNASIGNALDBM:
rtap_fields[RTAP_ANTENNASIGNALDBM] = owl_true ;
rtap_position += nat_align(rtap_position,
RTAP_L_ANTENNASIGNALDBM) ;
memcpy(&request->ss_dbm,
&pkt_data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ;
if (VERBOSE_INFO)
@ -1341,39 +1346,46 @@ void extract_radiotap_data(const u_char *pkt_data,
break ;
case RTAP_ANTENNANOISEDBM:
rtap_fields[RTAP_ANTENNANOISEDBM] = owl_true;
rtap_position += RTAP_L_ANTENNANOISEDBM ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_ANTENNANOISEDBM) ;
break ;
case RTAP_LOCKQUALITY:
rtap_fields[RTAP_LOCKQUALITY] = owl_true;
rtap_position += RTAP_L_LOCKQUALITY ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_LOCKQUALITY) ;
break ;
case RTAP_TXATTENUATION:
rtap_fields[RTAP_TXATTENUATION] = owl_true;
rtap_position += RTAP_L_TXATTENUATION ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_TXATTENUATION) ;
break ;
case RTAP_TXATTENUATIONDB:
rtap_fields[RTAP_TXATTENUATIONDB] = owl_true;
rtap_position += RTAP_L_TXATTENUATIONDB ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_TXATTENUATIONDB) ;
break ;
case RTAP_TXATTENUATIONDBM:
rtap_fields[RTAP_TXATTENUATIONDBM] = owl_true;
rtap_position += RTAP_L_TXATTENUATIONDBM ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_TXATTENUATIONDBM) ;
break ;
case RTAP_ANTENNA:
rtap_fields[RTAP_ANTENNA] = owl_true;
rtap_position += RTAP_L_ANTENNA ;
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_ANTENNA) ;
break ;
case RTAP_ANTENNASIGNALDB:
rtap_fields[RTAP_ANTENNASIGNALDB] = owl_true;
rtap_position += RTAP_L_ANTENNASIGNALDB ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_ANTENNASIGNALDB) ;
break ;
case RTAP_ANTENNANOISEDB:
rtap_fields[RTAP_ANTENNANOISEDB] = owl_true;
rtap_position += RTAP_L_ANTENNANOISEDB ;
rtap_position += SKIP_FIELD(rtap_position,
RTAP_L_ANTENNANOISEDB) ;
break ;
case RTAP_FCS:
rtap_fields[RTAP_FCS] = owl_true;
rtap_position += RTAP_L_FCS ;
rtap_position += SKIP_FIELD(rtap_position, RTAP_L_FCS) ;
break ;
default:
fprintf(stderr, "Warning! Radiotap field not handled: bit"
@ -1386,6 +1398,25 @@ void extract_radiotap_data(const u_char *pkt_data,
/*
* Computes the number of padding bytes required to achieve natural
* alignment of a field of length 'field_len', given the position
* 'offset' it should normally be at in the buffer. The aligned
* position is the sum of 'offset' and the returned value.
*
* To advance to the next available position, you can also use the macro
* SKIP_FIELD(), which is a simple wrapper around this function.
*/
uint_fast16_t nat_align(uint_fast16_t offset, uint_fast8_t field_len)
{
uint_fast8_t alignment = offset % field_len ;
if (alignment == 0)
return 0 ;
return field_len - alignment ;
}
/*
* Get our own MAC address and copy it to 'mac_bytes'.
*/