Home | History | Annotate | Line # | Download | only in dist
print-lwapp.c revision 1.7
      1 /*
      2  * Copyright (c) 1998-2007 The TCPDUMP project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that: (1) source code
      6  * distributions retain the above copyright notice and this paragraph
      7  * in its entirety, and (2) distributions including binary code include
      8  * the above copyright notice and this paragraph in its entirety in
      9  * the documentation or other materials provided with the distribution.
     10  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
     11  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
     12  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     13  * FOR A PARTICULAR PURPOSE.
     14  *
     15  * Original code by Carles Kishimoto <carles.kishimoto (at) gmail.com>
     16  */
     17 
     18 /* \summary: Light Weight Access Point Protocol (LWAPP) printer */
     19 
     20 /* specification: RFC 5412 */
     21 
     22 #include <sys/cdefs.h>
     23 #ifndef lint
     24 __RCSID("$NetBSD: print-lwapp.c,v 1.7 2017/02/05 04:05:05 spz Exp $");
     25 #endif
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include "config.h"
     29 #endif
     30 
     31 #include <netdissect-stdinc.h>
     32 
     33 #include "netdissect.h"
     34 #include "extract.h"
     35 #include "addrtoname.h"
     36 
     37 /*
     38  * LWAPP transport (common) header
     39  *      0                   1                   2                   3
     40  *     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
     41  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     42  *    |VER| RID |C|F|L|    Frag ID    |            Length             |
     43  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     44  *    |          Status/WLANs         |   Payload...  |
     45  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     46  *
     47  */
     48 
     49 struct lwapp_transport_header {
     50     uint8_t  version;
     51     uint8_t  frag_id;
     52     uint8_t  length[2];
     53     uint16_t status;
     54 };
     55 
     56 /*
     57  * LWAPP control header
     58  *      0                   1                   2                   3
     59  *      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
     60  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     61  *     |  Message Type |    Seq Num    |      Msg Element Length       |
     62  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     63  *     |                           Session ID                          |
     64  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     65  *     |      Msg Element [0..N]       |
     66  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     67  */
     68 
     69 struct lwapp_control_header {
     70     uint8_t  msg_type;
     71     uint8_t  seq_num;
     72     uint8_t  len[2];
     73     uint8_t  session_id[4];
     74 };
     75 
     76 #define LWAPP_VERSION 0
     77 #define	LWAPP_EXTRACT_VERSION(x) (((x)&0xC0)>>6)
     78 #define	LWAPP_EXTRACT_RID(x) (((x)&0x38)>>3)
     79 #define LWAPP_EXTRACT_CONTROL_BIT(x) (((x)&0x04)>>2)
     80 
     81 static const struct tok lwapp_header_bits_values[] = {
     82     { 0x01, "Last Fragment Bit"},
     83     { 0x02, "Fragment Bit"},
     84     { 0x04, "Control Bit"},
     85     { 0, NULL}
     86 };
     87 
     88 #define	LWAPP_MSGTYPE_DISCOVERY_REQUEST			1
     89 #define	LWAPP_MSGTYPE_DISCOVERY_RESPONSE		2
     90 #define	LWAPP_MSGTYPE_JOIN_REQUEST			3
     91 #define LWAPP_MSGTYPE_JOIN_RESPONSE			4
     92 #define LWAPP_MSGTYPE_JOIN_ACK				5
     93 #define LWAPP_MSGTYPE_JOIN_CONFIRM			6
     94 #define LWAPP_MSGTYPE_CONFIGURE_REQUEST			10
     95 #define LWAPP_MSGTYPE_CONFIGURE_RESPONSE		11
     96 #define LWAPP_MSGTYPE_CONF_UPDATE_REQUEST		12
     97 #define LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE		13
     98 #define LWAPP_MSGTYPE_WTP_EVENT_REQUEST			14
     99 #define LWAPP_MSGTYPE_WTP_EVENT_RESPONSE		15
    100 #define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST	16
    101 #define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE	17
    102 #define LWAPP_MSGTYPE_ECHO_REQUEST			22
    103 #define LWAPP_MSGTYPE_ECHO_RESPONSE			23
    104 #define LWAPP_MSGTYPE_IMAGE_DATA_REQUEST		24
    105 #define LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE		25
    106 #define LWAPP_MSGTYPE_RESET_REQUEST			26
    107 #define LWAPP_MSGTYPE_RESET_RESPONSE			27
    108 #define LWAPP_MSGTYPE_KEY_UPDATE_REQUEST		30
    109 #define LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE		31
    110 #define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST		32
    111 #define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE	33
    112 #define LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST		34
    113 #define LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE		35
    114 #define LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION		36
    115 #define LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST		37
    116 #define LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE		38
    117 #define LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST		39
    118 #define LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE		40
    119 
    120 static const struct tok lwapp_msg_type_values[] = {
    121     { LWAPP_MSGTYPE_DISCOVERY_REQUEST, "Discovery req"},
    122     { LWAPP_MSGTYPE_DISCOVERY_RESPONSE, "Discovery resp"},
    123     { LWAPP_MSGTYPE_JOIN_REQUEST, "Join req"},
    124     { LWAPP_MSGTYPE_JOIN_RESPONSE, "Join resp"},
    125     { LWAPP_MSGTYPE_JOIN_ACK, "Join ack"},
    126     { LWAPP_MSGTYPE_JOIN_CONFIRM, "Join confirm"},
    127     { LWAPP_MSGTYPE_CONFIGURE_REQUEST, "Configure req"},
    128     { LWAPP_MSGTYPE_CONFIGURE_RESPONSE, "Configure resp"},
    129     { LWAPP_MSGTYPE_CONF_UPDATE_REQUEST, "Update req"},
    130     { LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE, "Update resp"},
    131     { LWAPP_MSGTYPE_WTP_EVENT_REQUEST, "WTP event req"},
    132     { LWAPP_MSGTYPE_WTP_EVENT_RESPONSE, "WTP event resp"},
    133     { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST, "Change state event req"},
    134     { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE, "Change state event resp"},
    135     { LWAPP_MSGTYPE_ECHO_REQUEST, "Echo req"},
    136     { LWAPP_MSGTYPE_ECHO_RESPONSE, "Echo resp"},
    137     { LWAPP_MSGTYPE_IMAGE_DATA_REQUEST, "Image data req"},
    138     { LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE, "Image data resp"},
    139     { LWAPP_MSGTYPE_RESET_REQUEST, "Channel status req"},
    140     { LWAPP_MSGTYPE_RESET_RESPONSE, "Channel status resp"},
    141     { LWAPP_MSGTYPE_KEY_UPDATE_REQUEST, "Key update req"},
    142     { LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE, "Key update resp"},
    143     { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST, "Primary discovery req"},
    144     { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE, "Primary discovery resp"},
    145     { LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST, "Data transfer req"},
    146     { LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE, "Data transfer resp"},
    147     { LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION, "Clear config ind"},
    148     { LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST, "Wlan config req"},
    149     { LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE, "Wlan config resp"},
    150     { LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST, "Mobile config req"},
    151     { LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE, "Mobile config resp"},
    152     { 0, NULL}
    153 };
    154 
    155 /*
    156  * LWAPP message elements
    157  *
    158  * 0                   1                   2                   3
    159  * 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
    160  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    161  * |      Type     |             Length            |   Value ...   |
    162  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    163  */
    164 struct lwapp_message_header {
    165     uint8_t type;
    166     uint8_t length[2];
    167 };
    168 
    169 void
    170 lwapp_control_print(netdissect_options *ndo,
    171                     const u_char *pptr, u_int len, int has_ap_ident)
    172 {
    173     const struct lwapp_transport_header *lwapp_trans_header;
    174     const struct lwapp_control_header *lwapp_control_header;
    175     const u_char *tptr;
    176     int  tlen;
    177     int  msg_tlen;
    178 
    179     tptr=pptr;
    180 
    181     if (has_ap_ident) {
    182         /* check if enough bytes for AP identity */
    183         ND_TCHECK2(*tptr, 6);
    184         lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6);
    185     } else {
    186         lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    187     }
    188     ND_TCHECK(*lwapp_trans_header);
    189 
    190     /*
    191      * Sanity checking of the header.
    192      */
    193     if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
    194 	ND_PRINT((ndo, "LWAPP version %u packet not supported",
    195                LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)));
    196 	return;
    197     }
    198 
    199     /* non-verbose */
    200     if (ndo->ndo_vflag < 1) {
    201         ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u",
    202                LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
    203                LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
    204                bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
    205                len));
    206         return;
    207     }
    208 
    209     /* ok they seem to want to know everything - lets fully decode it */
    210     tlen=EXTRACT_16BITS(lwapp_trans_header->length);
    211 
    212     ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u",
    213            LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
    214            LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
    215            LWAPP_EXTRACT_RID(lwapp_trans_header->version),
    216            bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
    217 	   lwapp_trans_header->frag_id,
    218 	   tlen));
    219 
    220     if (has_ap_ident) {
    221         ND_PRINT((ndo, "\n\tAP identity: %s", etheraddr_string(ndo, tptr)));
    222         tptr+=sizeof(const struct lwapp_transport_header)+6;
    223     } else {
    224         tptr+=sizeof(const struct lwapp_transport_header);
    225     }
    226 
    227     while(tlen>0) {
    228 
    229         /* did we capture enough for fully decoding the object header ? */
    230         ND_TCHECK2(*tptr, sizeof(struct lwapp_control_header));
    231 
    232         lwapp_control_header = (const struct lwapp_control_header *)tptr;
    233 	msg_tlen = EXTRACT_16BITS(lwapp_control_header->len);
    234 
    235 	/* print message header */
    236         ND_PRINT((ndo, "\n\t  Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x",
    237                tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type),
    238                lwapp_control_header->msg_type,
    239                lwapp_control_header->seq_num,
    240                msg_tlen,
    241                EXTRACT_32BITS(lwapp_control_header->session_id)));
    242 
    243         /* did we capture enough for fully decoding the message */
    244         ND_TCHECK2(*tptr, msg_tlen);
    245 
    246 	/* XXX - Decode sub messages for each message */
    247         switch(lwapp_control_header->msg_type) {
    248         case LWAPP_MSGTYPE_DISCOVERY_REQUEST:
    249         case LWAPP_MSGTYPE_DISCOVERY_RESPONSE:
    250         case LWAPP_MSGTYPE_JOIN_REQUEST:
    251         case LWAPP_MSGTYPE_JOIN_RESPONSE:
    252         case LWAPP_MSGTYPE_JOIN_ACK:
    253         case LWAPP_MSGTYPE_JOIN_CONFIRM:
    254         case LWAPP_MSGTYPE_CONFIGURE_REQUEST:
    255         case LWAPP_MSGTYPE_CONFIGURE_RESPONSE:
    256         case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST:
    257         case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE:
    258         case LWAPP_MSGTYPE_WTP_EVENT_REQUEST:
    259         case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE:
    260         case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST:
    261         case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE:
    262         case LWAPP_MSGTYPE_ECHO_REQUEST:
    263         case LWAPP_MSGTYPE_ECHO_RESPONSE:
    264         case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST:
    265         case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE:
    266         case LWAPP_MSGTYPE_RESET_REQUEST:
    267         case LWAPP_MSGTYPE_RESET_RESPONSE:
    268         case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST:
    269         case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE:
    270         case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST:
    271         case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE:
    272         case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST:
    273         case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE:
    274         case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION:
    275         case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST:
    276         case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE:
    277         case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST:
    278         case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE:
    279         default:
    280             break;
    281         }
    282 
    283         tptr += sizeof(struct lwapp_control_header) + msg_tlen;
    284         tlen -= sizeof(struct lwapp_control_header) + msg_tlen;
    285     }
    286     return;
    287 
    288  trunc:
    289     ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
    290 }
    291 
    292 void
    293 lwapp_data_print(netdissect_options *ndo,
    294                  const u_char *pptr, u_int len)
    295 {
    296     const struct lwapp_transport_header *lwapp_trans_header;
    297     const u_char *tptr;
    298     int tlen;
    299 
    300     tptr=pptr;
    301 
    302     /* check if enough bytes for AP identity */
    303     ND_TCHECK2(*tptr, 6);
    304     lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    305     ND_TCHECK(*lwapp_trans_header);
    306 
    307     /*
    308      * Sanity checking of the header.
    309      */
    310     if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
    311         ND_PRINT((ndo, "LWAPP version %u packet not supported",
    312                LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)));
    313         return;
    314     }
    315 
    316     /* non-verbose */
    317     if (ndo->ndo_vflag < 1) {
    318         ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u",
    319                LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
    320                LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
    321                bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
    322                len));
    323         return;
    324     }
    325 
    326     /* ok they seem to want to know everything - lets fully decode it */
    327     tlen=EXTRACT_16BITS(lwapp_trans_header->length);
    328 
    329     ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id  %u, Flags [%s], Frag-id  %u, length %u",
    330            LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
    331            LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
    332            LWAPP_EXTRACT_RID(lwapp_trans_header->version),
    333            bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
    334            lwapp_trans_header->frag_id,
    335            tlen));
    336 
    337     tptr+=sizeof(const struct lwapp_transport_header);
    338     tlen-=sizeof(const struct lwapp_transport_header);
    339 
    340     /* FIX - An IEEE 802.11 frame follows - hexdump for now */
    341     print_unknown_data(ndo, tptr, "\n\t", tlen);
    342 
    343     return;
    344 
    345  trunc:
    346     ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
    347 }
    348 
    349 /*
    350  * Local Variables:
    351  * c-style: whitesmith
    352  * c-basic-offset: 8
    353  * End:
    354  */
    355