diff --git a/src/cw/Makefile b/src/cw/Makefile index 2ed1d49e..2af5a835 100644 --- a/src/cw/Makefile +++ b/src/cw/Makefile @@ -171,8 +171,11 @@ CAPWAPOBJS= \ cw_check_missing_mand.o \ md5sum.o \ format.o \ - cw_in_cisco_add_wlan.o \ - dot11.o + cw_in_cisco_add_wlan.o + +DOT11OBJS = \ + dot11.o \ + dot11_beacon.o # cw_out_ac_descriptor.o \ @@ -290,6 +293,7 @@ OBJS=$(CONNOBJS) $(FRAGOBJS) $(SOCKOBJS) $(CAPWAPOBJS) $(WTPINFOOBJS) \ $(LWAPPCISCOOBJS) \ $(CWACTION) \ $(MAVLOBJS) \ + $(DOT11OBJS) #include $(OBJS:.o=.d) @@ -356,7 +360,7 @@ clean: clean_deps: $(DEPS) -deps: $(SRCS) - $(CC) -MD -E $(SRCS) $(CFLAGS) >/dev/null +deps: + $(CC) -MM -E *.c $(CFLAGS) > .depend --include $(DEPS) +include .depend diff --git a/src/cw/dot11.c b/src/cw/dot11.c index 76753bb2..15d43958 100644 --- a/src/cw/dot11.c +++ b/src/cw/dot11.c @@ -6,6 +6,7 @@ uint64_t dot11_timer_offset=0; +uint8_t dot11_broadcast_address[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; const unsigned char dot11_tab_br[] = diff --git a/src/cw/dot11.h b/src/cw/dot11.h index e215a770..7ff65428 100644 --- a/src/cw/dot11.h +++ b/src/cw/dot11.h @@ -9,19 +9,44 @@ * @{ */ + #include #include #include +#ifdef __FreeBSD__ +#include +#else +#include +#endif + +/** + * @defgroup DOT11_FRAME_TYPES Frame Types + * @brief Definition of frame types + * + * @{ + */ +/** Management Frame */ #define DOT11_T_MGM 0b00 +/** Control Frame */ #define DOT11_T_CTL 0b01 +/** Data Frame **/ #define DOT11_T_DTA 0b10 +/** Reserved Frame Type */ #define DOT11_T_RES 0b11 +/** + * @} + */ -#define dot11_fc_mgm(subtype) (DOT11_T_MGM << 2 | subtype(<<4)) - +#define dot11_fc_mgm(subtype) ((DOT11_T_MGM << 2) |( subtype<<4)) +#define dot11_fc_dta(subtype) ((DOT11_T_DTA << 2) |( subtype<<4)) +/** + * @defgroup DOT11_FRAMES Frame Controls + * + * @{ + */ #define DOT11_FC_ASSOC_REQ dot11_fc_mgm(0b0000) #define DOT11_FC_ASSOC_RESP dot11_fc_mgm(0b0001) #define DOT11_FC_REASSOC_REQ dot11_fc_mgm(0b0010) @@ -32,9 +57,66 @@ #define DOT11_FC_MGM_RES111 dot11_fc_mgm(0b0111) #define DOT11_FC_BEACON dot11_fc_mgm(0b1000) +#define DOT11_FC_DATA dot11_fc_dta(0b0000) + +/** + * @} + */ +/** + * @defgroup DOT11_FC_FLAGS Frame Control Flags + * @{ + */ +#define DOT11_FC_FLAG_TO_DS 0x100 +#define DOT11_FC_FLAG_FROM_DS 0x200 +#define DOT11_FC_FLAG_MOREFRAGS 0x400 +#define DOT11_FC_FLAG_RETRY 0x800 +#define DOT11_FC_FLAG_POWERMGMT 0x1000 +#define DOT11_FC_FLAG_MOREDATA 0x2000 +#define DOT11_FC_FLAG_PROTECTED 0x4000 +#define DOT11_FC_FLAG_ORDER 0x8000 +/** + * @} + */ +/** + * @defgroup DOT11_CAP_FLAGS Capability Flags + * @brief Flags used in the capability field. + * @{ + */ +#define DOT11_CAP_ESS 0x0001 +#define DOT11_CAP_IBSS 0x0002 +#define DOT11_CAP_CF_POLLABLE 0x0004 +#define DOT11_CAP_CF_POLL_REQ 0x0008 +#define DOT11_CAP_PRIVACY 0x0010 +#define DOT11_CAP_SHORT_PREAMBLE 0x0020 +#define DOT11_CAP_PBCC 0x0040 +#define DOT11_CAP_CHANNEL_AGILITY 0x0080 +#define DOT11_CAP_SPEC_MGMT 0x0100 +#define DOT11_CAP_QOS 0x0200 +#define DOT11_CAP_SHORT_SLOT_TIME 0x0400 +#define DOT11_CAP_APSD 0x0800 +#define DOT11_CAP_RADIO_MEASURE 0x1000 +#define DOT11_CAP_DSSS_ODFM 0x2000 +#define DOT11_CAP_DELAYED_BLOCK_ACK 0x4000 +#define DOT11_CAP_IMEDIATE_BLOCK_ACK 0x8000 +/** + * @} + */ + +/** + * @defgroup DOT11_ELEMS + * @{ + */ +#define DOT11_ELEM_SSID 0 +#define DOT11_ELEM_SUPPORTED_RATES 1 +#define DOT11_ELEM_FH_PARAM_SET 2 +#define DOT11_ELEM_DSSS_PARAM_SET 3 +#define DOT11_ELEM_CF_PARAM_SET 4 +/** + * @} + */ extern const uint8_t dot11_tab_br[256]; @@ -42,23 +124,24 @@ extern const uint8_t dot11_tab_br[256]; #define dot11_get_byte(ptr) (*(ptr)) + #define dot11_put_byte(ptr,b) (*(ptr) = b) +#define dot11_put_word(dst,v) ((*((uint16_t*)(dst))=htobe16(v)),2) +#define dot11_put_dword(dst,v) ((*((uint16_t*)(dst))=htobe16(v)),4) +#define dot11_put_qword(dst,v) ((*((uint64_t*)(dst))=htobe64(v)),8) -static inline int dot11_put_word(uint8_t *ptr,uint16_t w) -{ - dot11_put_byte(ptr+1,w&0xff); - dot11_put_byte(ptr,w>>8); - return 2; -} -static inline uint16_t dot11_get_word(uint8_t *ptr) +static inline uint16_t dot11_get_word(uint8_t * ptr) { uint16_t w; - w = dot11_get_byte(ptr+1); - w|= dot11_get_byte(ptr)<<8; + w = dot11_get_byte(ptr + 1); + w |= dot11_get_byte(ptr) << 8; return w; } + + + #define dot11_get_version(frame) ((frame[1])&0x03) #define dot11_get_type(frame) (((frame[1])&0x0c) >> 2) #define dot11_get_subtype(frame) (((frame[1])&0xf0) >> 4) @@ -71,26 +154,21 @@ static inline uint16_t dot11_get_word(uint8_t *ptr) #define dot11_get_duration(frame) dot11_get_word(frame+2) -static inline void dot11_get_address(uint8_t * dst, uint8_t *frame) +static inline void dot11_get_address(uint8_t * dst, uint8_t * frame) { - memcpy(dst,frame,6); + memcpy(dst, frame, 6); } #define dot11_get_address1(dst,frame) dot11_get_address(dst,frame+4) -#define dot11_get_address2(dst,frame) dot11_get_address(dst,frame+4*2*6) -#define dot11_get_address3(dst,frame) dot11_get_address(dst,frame+4*3*6) +#define dot11_get_address2(dst,frame) dot11_get_address(dst,frame+4+1*6) +#define dot11_get_address3(dst,frame) dot11_get_address(dst,frame+4+2*6) #define dot11_get_sequence_control(frame) dot11_get_word(frame+22) -#define DOT11_FC_FLAG_FROM_DS 0x100 -#define DOT11_FC_FLAG_TO_DS 0x200 -#define DOT11_FC_FLAG_MOREFRAGS 0x400 -#define DOT11_FC_FLAG_RETRY 0x800 -#define DOT11_FC_FLAG_POWERMGMT 0x1000 -#define DOT11_FC_FLAG_MOREDATA 0x2000 -#define DOT11_FC_FLAG_PROTECTED 0x4000 -#define DOT11_FC_FLAG_ORDER 0x8000 + + + #define dot11_fc_get_version(fc) ((fc)&0x3) #define dot11_fc_get_type(fc) (((fc)&0x0c)>>2) @@ -102,24 +180,99 @@ static inline void dot11_get_address(uint8_t * dst, uint8_t *frame) #define dot11_fc_put_frame_control(dst,fc) dot11_put_word(dst,fc) +static inline int dot11_put_frame_control(uint8_t * dst, int fctype, int flags) +{ + uint16_t fc = fctype | flags; + return dot11_fc_put_frame_control(dst, fc); +} +/** + * @defgroup DOT11_TIMER Timer + * @{ + */ extern uint64_t dot11_timer_offset; - -static inline uint64_t dot11_timer_get(){ +/** + * Get the current timestamp + * @return current timestamp in microseconds + */ +static inline uint64_t dot11_timer_get() +{ struct timeval tv; gettimeofday(&tv, NULL); return 1000000 * tv.tv_sec + tv.tv_usec - dot11_timer_offset; } -static inline void dot11_timer_set(uint64_t val) { + +static inline void dot11_timer_set(uint64_t val) +{ struct timeval tv; gettimeofday(&tv, NULL); dot11_timer_offset = 1000000 * tv.tv_sec + tv.tv_usec - val; } +/** + * @} + */ + +/** + * Put a timestamp field + * @param dst Destination + * @return number of bytes + * + * The timestamp value is taken from the value returned by #dot11_timer_get. + */ +#define dot11_put_timestamp(dst) (dot11_put_qword(dst,dot11_timer_get())) +#define dot11_put_beacon_interval(dst,v) (dot11_put_word(dst,v)) +#define dot11_put_duration(dst,v) (dot11_put_word(dst,v)) +#define dot11_put_address(dst,addr) (memcpy(dst,addr,6),6) +#define dot11_put_sequence_control(dst,v) (dot11_put_word(dst,v)) +#define dot11_put_capability(dst,v) dot11_put_word(dst,v) +static inline int dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len){ + dot11_put_byte(dst,DOT11_ELEM_SSID); + dot11_put_byte(dst+1,len); + memcpy(dst+2,ssid,len); + return len; + +} + +#define dot11_rate(rate) ((int)(rate*2+0.5)); +static inline int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates){ + uint8_t *d = dst+2; + while(*basic != 0.0){ + *d++ = 0x80 | dot11_rate(*basic); + basic++; + } + while(*rates != 0.0){ + *d++ = dot11_rate(*rates); + rates++; + } + *(dst)=DOT11_ELEM_SUPPORTED_RATES; + *(dst+1) = d-(dst+2); + + return d-dst; +} + + +static inline int dot11_put_dsss_param_set(uint8_t *dst,int ch) { + + dot11_put_byte(dst,DOT11_ELEM_DSSS_PARAM_SET); + dot11_put_byte(dst+1,1); + dot11_put_byte(dst+2,ch); + return 3; +} + +extern int dot11_create_beacon(uint8_t *dst); + + +extern uint8_t dot11_broadcast_address[6]; +#define DOT11_BROADCAST_ADDRESS (dot11_broadcast_address) + + + + /** diff --git a/src/cw/dot11_beacon.c b/src/cw/dot11_beacon.c new file mode 100644 index 00000000..c489277f --- /dev/null +++ b/src/cw/dot11_beacon.c @@ -0,0 +1,34 @@ +#include "dot11.h" + + + + +int dot11_create_beacon(uint8_t *dst) +{ + uint8_t *d = dst; + d+=dot11_put_frame_control(d,DOT11_FC_BEACON,0); + d+=dot11_put_duration(d,0); + d+=dot11_put_address(d,DOT11_BROADCAST_ADDRESS); + uint8_t addr[6]={0x00,0x3a,0x99,0x02,0xfa,0xc0}; + d+=dot11_put_address(d,addr); + d+=dot11_put_address(d,addr); + d+=dot11_put_sequence_control(d,17); + + d+=dot11_put_timestamp(d); + d+=dot11_put_beacon_interval(d,100); + d+=dot11_put_capability(d,DOT11_CAP_ESS | DOT11_CAP_SHORT_PREAMBLE); + d+=dot11_put_ssid(d,(uint8_t*)"Hello Word",10); + + + float brates[] = {2,4,5.5,0.0}; + float rates[] = {1,4,54,0.0}; + + d+=dot11_put_supported_rates(d,brates,rates); + d+=dot11_put_dsss_param_set(d,1); + + + + + return 0; +} +