diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-11-06 16:27:42 -0800 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-11-06 16:27:42 -0800 |
commit | bbace1d4c8912a4a02cc0322e2cbed1901c62d96 (patch) | |
tree | c9c56c419b556c51ba05eb6d9f7f37fc1791f1c5 /print-lwapp.c | |
download | tcpdump-bbace1d4c8912a4a02cc0322e2cbed1901c62d96.tar.gz tcpdump-bbace1d4c8912a4a02cc0322e2cbed1901c62d96.tar.bz2 tcpdump-bbace1d4c8912a4a02cc0322e2cbed1901c62d96.zip |
Imported Upstream version 4.3.0upstream/4.3.0
Diffstat (limited to 'print-lwapp.c')
-rw-r--r-- | print-lwapp.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/print-lwapp.c b/print-lwapp.c new file mode 100644 index 0000000..154876f --- /dev/null +++ b/print-lwapp.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Support for the Light Weight Access Point Protocol as per draft-ohara-capwap-lwapp-04 + * + * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-lwapp.c,v 1.1 2007-07-24 16:07:30 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * LWAPP transport (common) header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |VER| RID |C|F|L| Frag ID | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status/WLANs | Payload... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct lwapp_transport_header { + u_int8_t version; + u_int8_t frag_id; + u_int8_t length[2]; + u_int16_t status; +}; + +/* + * LWAPP control header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Seq Num | Msg Element Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Session ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Msg Element [0..N] | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lwapp_control_header { + u_int8_t msg_type; + u_int8_t seq_num; + u_int8_t len[2]; + u_int8_t session_id[4]; +}; + +#define LWAPP_VERSION 0 +#define LWAPP_EXTRACT_VERSION(x) (((x)&0xC0)>>6) +#define LWAPP_EXTRACT_RID(x) (((x)&0x38)>>3) +#define LWAPP_EXTRACT_CONTROL_BIT(x) (((x)&0x04)>>2) + +static const struct tok lwapp_header_bits_values[] = { + { 0x01, "Last Fragment Bit"}, + { 0x02, "Fragment Bit"}, + { 0x04, "Control Bit"}, + { 0, NULL} +}; + +#define LWAPP_MSGTYPE_DISCOVERY_REQUEST 1 +#define LWAPP_MSGTYPE_DISCOVERY_RESPONSE 2 +#define LWAPP_MSGTYPE_JOIN_REQUEST 3 +#define LWAPP_MSGTYPE_JOIN_RESPONSE 4 +#define LWAPP_MSGTYPE_JOIN_ACK 5 +#define LWAPP_MSGTYPE_JOIN_CONFIRM 6 +#define LWAPP_MSGTYPE_CONFIGURE_REQUEST 10 +#define LWAPP_MSGTYPE_CONFIGURE_RESPONSE 11 +#define LWAPP_MSGTYPE_CONF_UPDATE_REQUEST 12 +#define LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE 13 +#define LWAPP_MSGTYPE_WTP_EVENT_REQUEST 14 +#define LWAPP_MSGTYPE_WTP_EVENT_RESPONSE 15 +#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST 16 +#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE 17 +#define LWAPP_MSGTYPE_ECHO_REQUEST 22 +#define LWAPP_MSGTYPE_ECHO_RESPONSE 23 +#define LWAPP_MSGTYPE_IMAGE_DATA_REQUEST 24 +#define LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE 25 +#define LWAPP_MSGTYPE_RESET_REQUEST 26 +#define LWAPP_MSGTYPE_RESET_RESPONSE 27 +#define LWAPP_MSGTYPE_KEY_UPDATE_REQUEST 30 +#define LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE 31 +#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST 32 +#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE 33 +#define LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST 34 +#define LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE 35 +#define LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION 36 +#define LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST 37 +#define LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE 38 +#define LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST 39 +#define LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE 40 + +static const struct tok lwapp_msg_type_values[] = { + { LWAPP_MSGTYPE_DISCOVERY_REQUEST, "Discovery req"}, + { LWAPP_MSGTYPE_DISCOVERY_RESPONSE, "Discovery resp"}, + { LWAPP_MSGTYPE_JOIN_REQUEST, "Join req"}, + { LWAPP_MSGTYPE_JOIN_RESPONSE, "Join resp"}, + { LWAPP_MSGTYPE_JOIN_ACK, "Join ack"}, + { LWAPP_MSGTYPE_JOIN_CONFIRM, "Join confirm"}, + { LWAPP_MSGTYPE_CONFIGURE_REQUEST, "Configure req"}, + { LWAPP_MSGTYPE_CONFIGURE_RESPONSE, "Configure resp"}, + { LWAPP_MSGTYPE_CONF_UPDATE_REQUEST, "Update req"}, + { LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE, "Update resp"}, + { LWAPP_MSGTYPE_WTP_EVENT_REQUEST, "WTP event req"}, + { LWAPP_MSGTYPE_WTP_EVENT_RESPONSE, "WTP event resp"}, + { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST, "Change state event req"}, + { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE, "Change state event resp"}, + { LWAPP_MSGTYPE_ECHO_REQUEST, "Echo req"}, + { LWAPP_MSGTYPE_ECHO_RESPONSE, "Echo resp"}, + { LWAPP_MSGTYPE_IMAGE_DATA_REQUEST, "Image data req"}, + { LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE, "Image data resp"}, + { LWAPP_MSGTYPE_RESET_REQUEST, "Channel status req"}, + { LWAPP_MSGTYPE_RESET_RESPONSE, "Channel status resp"}, + { LWAPP_MSGTYPE_KEY_UPDATE_REQUEST, "Key update req"}, + { LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE, "Key update resp"}, + { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST, "Primary discovery req"}, + { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE, "Primary discovery resp"}, + { LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST, "Data transfer req"}, + { LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE, "Data transfer resp"}, + { LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION, "Clear config ind"}, + { LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST, "Wlan config req"}, + { LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE, "Wlan config resp"}, + { LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST, "Mobile config req"}, + { LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE, "Mobile config resp"}, + { 0, NULL} +}; + +/* + * LWAPP message elements + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | Value ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lwapp_message_header { + u_int8_t type; + u_int8_t length[2]; +}; + +void +lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) { + + const struct lwapp_transport_header *lwapp_trans_header; + const struct lwapp_control_header *lwapp_control_header; + const u_char *tptr; + int tlen; + int msg_tlen; + + tptr=pptr; + + if (has_ap_ident) { + /* check if enough bytes for AP identity */ + if (!TTEST2(*tptr, 6)) + goto trunc; + lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6); + } else { + lwapp_trans_header = (const struct lwapp_transport_header *)pptr; + } + TCHECK(*lwapp_trans_header); + + /* + * Sanity checking of the header. + */ + if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { + printf("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)); + return; + } + + /* non-verbose */ + if (vflag < 1) { + printf("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=EXTRACT_16BITS(lwapp_trans_header->length); + + printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(lwapp_trans_header->version), + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + lwapp_trans_header->frag_id, + tlen); + + if (has_ap_ident) { + printf("\n\tAP identity: %s", + etheraddr_string(tptr)); + tptr+=sizeof(const struct lwapp_transport_header)+6; + } else { + tptr+=sizeof(const struct lwapp_transport_header); + } + + while(tlen>0) { + + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct lwapp_control_header))) + goto trunc; + + lwapp_control_header = (const struct lwapp_control_header *)tptr; + msg_tlen = EXTRACT_16BITS(lwapp_control_header->len); + + /* print message header */ + printf("\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x", + tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type), + lwapp_control_header->msg_type, + lwapp_control_header->seq_num, + msg_tlen, + EXTRACT_32BITS(lwapp_control_header->session_id)); + + /* did we capture enough for fully decoding the message */ + if (!TTEST2(*tptr, msg_tlen)) + goto trunc; + + /* XXX - Decode sub messages for each message */ + switch(lwapp_control_header->msg_type) { + case LWAPP_MSGTYPE_DISCOVERY_REQUEST: + case LWAPP_MSGTYPE_DISCOVERY_RESPONSE: + case LWAPP_MSGTYPE_JOIN_REQUEST: + case LWAPP_MSGTYPE_JOIN_RESPONSE: + case LWAPP_MSGTYPE_JOIN_ACK: + case LWAPP_MSGTYPE_JOIN_CONFIRM: + case LWAPP_MSGTYPE_CONFIGURE_REQUEST: + case LWAPP_MSGTYPE_CONFIGURE_RESPONSE: + case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST: + case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE: + case LWAPP_MSGTYPE_WTP_EVENT_REQUEST: + case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE: + case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST: + case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE: + case LWAPP_MSGTYPE_ECHO_REQUEST: + case LWAPP_MSGTYPE_ECHO_RESPONSE: + case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST: + case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE: + case LWAPP_MSGTYPE_RESET_REQUEST: + case LWAPP_MSGTYPE_RESET_RESPONSE: + case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST: + case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE: + case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST: + case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE: + case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST: + case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE: + case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION: + case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST: + case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE: + case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST: + case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE: + default: + break; + } + + tptr += sizeof(struct lwapp_control_header) + msg_tlen; + tlen -= sizeof(struct lwapp_control_header) + msg_tlen; + } + return; + + trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +void +lwapp_data_print(const u_char *pptr, u_int len) { + + const struct lwapp_transport_header *lwapp_trans_header; + const u_char *tptr; + int tlen; + + tptr=pptr; + + /* check if enough bytes for AP identity */ + if (!TTEST2(*tptr, 6)) + goto trunc; + lwapp_trans_header = (const struct lwapp_transport_header *)pptr; + TCHECK(*lwapp_trans_header); + + /* + * Sanity checking of the header. + */ + if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { + printf("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)); + return; + } + + /* non-verbose */ + if (vflag < 1) { + printf("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=EXTRACT_16BITS(lwapp_trans_header->length); + + printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(lwapp_trans_header->version), + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + lwapp_trans_header->frag_id, + tlen); + + tptr+=sizeof(const struct lwapp_transport_header); + tlen-=sizeof(const struct lwapp_transport_header); + + /* FIX - An IEEE 802.11 frame follows - hexdump for now */ + print_unknown_data(tptr, "\n\t", tlen); + + return; + + trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ |