print-lwapp.c 13 KB

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