print-802_11.c

来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 1,302 行 · 第 1/3 页

C
1,302
字号
/* * Copyright (c) 2001 *	Fortress Technologies, Inc.  All rights reserved. *      Charlie Lenahan (clenahan@fortresstech.com) * * 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, (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, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * 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. */#ifndef lintstatic const char rcsid[] _U_ =    "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.47.2.2 2007-12-29 23:25:28 guy Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <tcpdump-stdinc.h>#include <stdio.h>#include <pcap.h>#include <string.h>#include "interface.h"#include "addrtoname.h"#include "ethertype.h"#include "extract.h"#include "cpack.h"#include "ieee802_11.h"#include "ieee802_11_radio.h"#define PRINT_SSID(p) \	switch (p.ssid_status) { \	case TRUNCATED: \		return 0; \	case PRESENT: \		printf(" ("); \		fn_print(p.ssid.ssid, NULL); \		printf(")"); \		break; \	case NOT_PRESENT: \		break; \	}#define PRINT_RATE(_sep, _r, _suf) \	printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)#define PRINT_RATES(p) \	switch (p.rates_status) { \	case TRUNCATED: \		return 0; \	case PRESENT: \		do { \			int z; \			const char *sep = " ["; \			for (z = 0; z < p.rates.length ; z++) { \				PRINT_RATE(sep, p.rates.rate[z], \					(p.rates.rate[z] & 0x80 ? "*" : "")); \				sep = " "; \			} \			if (p.rates.length != 0) \				printf(" Mbit]"); \		} while (0); \		break; \	case NOT_PRESENT: \		break; \	}#define PRINT_DS_CHANNEL(p) \	switch (p.ds_status) { \	case TRUNCATED: \		return 0; \	case PRESENT: \		printf(" CH: %u", p.ds.channel); \		break; \	case NOT_PRESENT: \		break; \	} \	printf("%s", \	    CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};#define NUM_AUTH_ALGS	(sizeof auth_alg_text / sizeof auth_alg_text[0])static const char *status_text[] = {	"Succesful",  /*  0  */	"Unspecified failure",  /*  1  */	"Reserved",	  /*  2  */	"Reserved",	  /*  3  */	"Reserved",	  /*  4  */	"Reserved",	  /*  5  */	"Reserved",	  /*  6  */	"Reserved",	  /*  7  */	"Reserved",	  /*  8  */	"Reserved",	  /*  9  */	"Cannot Support all requested capabilities in the Capability Information field",	  /*  10  */	"Reassociation denied due to inability to confirm that association exists",	  /*  11  */	"Association denied due to reason outside the scope of the standard",	  /*  12  */	"Responding station does not support the specified authentication algorithm ",	  /*  13  */	"Received an Authentication frame with authentication transaction " \		"sequence number out of expected sequence",	  /*  14  */	"Authentication rejected because of challenge failure",	  /*  15 */	"Authentication rejected due to timeout waiting for next frame in sequence",	  /*  16 */	"Association denied because AP is unable to handle additional associated stations",	  /*  17 */	"Association denied due to requesting station not supporting all of the " \		"data rates in BSSBasicRateSet parameter",	  /*  18 */};#define NUM_STATUSES	(sizeof status_text / sizeof status_text[0])static const char *reason_text[] = {	"Reserved", /* 0 */	"Unspecified reason", /* 1 */	"Previous authentication no longer valid",  /* 2 */	"Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */	"Disassociated due to inactivity", /* 4 */	"Disassociated because AP is unable to handle all currently associated stations", /* 5 */	"Class 2 frame received from nonauthenticated station", /* 6 */	"Class 3 frame received from nonassociated station", /* 7 */	"Disassociated because sending station is leaving (or has left) BSS", /* 8 */	"Station requesting (re)association is not authenticated with responding station", /* 9 */};#define NUM_REASONS	(sizeof reason_text / sizeof reason_text[0])static intwep_print(const u_char *p){	u_int32_t iv;	if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))		return 0;	iv = EXTRACT_LE_32BITS(p);	printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),	    IV_KEYID(iv));	return 1;}static voidparse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset){	/*	 * We haven't seen any elements yet.	 */	pbody->challenge_status = NOT_PRESENT;	pbody->ssid_status = NOT_PRESENT;	pbody->rates_status = NOT_PRESENT;	pbody->ds_status = NOT_PRESENT;	pbody->cf_status = NOT_PRESENT;	pbody->tim_status = NOT_PRESENT;	for (;;) {		if (!TTEST2(*(p + offset), 1))			return;		switch (*(p + offset)) {		case E_SSID:			/* Present, possibly truncated */			pbody->ssid_status = TRUNCATED;			if (!TTEST2(*(p + offset), 2))				return;			memcpy(&pbody->ssid, p + offset, 2);			offset += 2;			if (pbody->ssid.length != 0) {				if (pbody->ssid.length >				    sizeof(pbody->ssid.ssid) - 1)					return;				if (!TTEST2(*(p + offset), pbody->ssid.length))					return;				memcpy(&pbody->ssid.ssid, p + offset,				    pbody->ssid.length);				offset += pbody->ssid.length;			}			pbody->ssid.ssid[pbody->ssid.length] = '\0';			/* Present and not truncated */			pbody->ssid_status = PRESENT;			break;		case E_CHALLENGE:			/* Present, possibly truncated */			pbody->challenge_status = TRUNCATED;			if (!TTEST2(*(p + offset), 2))				return;			memcpy(&pbody->challenge, p + offset, 2);			offset += 2;			if (pbody->challenge.length != 0) {				if (pbody->challenge.length >				    sizeof(pbody->challenge.text) - 1)					return;				if (!TTEST2(*(p + offset), pbody->challenge.length))					return;				memcpy(&pbody->challenge.text, p + offset,				    pbody->challenge.length);				offset += pbody->challenge.length;			}			pbody->challenge.text[pbody->challenge.length] = '\0';			/* Present and not truncated */			pbody->challenge_status = PRESENT;			break;		case E_RATES:			/* Present, possibly truncated */			pbody->rates_status = TRUNCATED;			if (!TTEST2(*(p + offset), 2))				return;			memcpy(&(pbody->rates), p + offset, 2);			offset += 2;			if (pbody->rates.length != 0) {				if (pbody->rates.length > sizeof pbody->rates.rate)					return;				if (!TTEST2(*(p + offset), pbody->rates.length))					return;				memcpy(&pbody->rates.rate, p + offset,				    pbody->rates.length);				offset += pbody->rates.length;			}			/* Present and not truncated */			pbody->rates_status = PRESENT;			break;		case E_DS:			/* Present, possibly truncated */			pbody->ds_status = TRUNCATED;			if (!TTEST2(*(p + offset), 3))				return;			memcpy(&pbody->ds, p + offset, 3);			offset += 3;			/* Present and not truncated */			pbody->ds_status = PRESENT;			break;		case E_CF:			/* Present, possibly truncated */			pbody->cf_status = TRUNCATED;			if (!TTEST2(*(p + offset), 8))				return;			memcpy(&pbody->cf, p + offset, 8);			offset += 8;			/* Present and not truncated */			pbody->cf_status = PRESENT;			break;		case E_TIM:			/* Present, possibly truncated */			pbody->tim_status = TRUNCATED;			if (!TTEST2(*(p + offset), 2))				return;			memcpy(&pbody->tim, p + offset, 2);			offset += 2;			if (!TTEST2(*(p + offset), 3))				return;			memcpy(&pbody->tim.count, p + offset, 3);			offset += 3;			if (pbody->tim.length <= 3)				break;			if (pbody->tim.length - 3 > (int)sizeof pbody->tim.bitmap)				return;			if (!TTEST2(*(p + offset), pbody->tim.length - 3))				return;			memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),			    (pbody->tim.length - 3));			offset += pbody->tim.length - 3;			/* Present and not truncated */			pbody->tim_status = PRESENT;			break;		default:#if 0			printf("(1) unhandled element_id (%d)  ",			    *(p + offset) );#endif			if (!TTEST2(*(p + offset), 2))				return;			if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))				return;			offset += *(p + offset + 1) + 2;			break;		}	}}/********************************************************************************* * Print Handle functions for the management frame types *********************************************************************************/static inthandle_beacon(const u_char *p){	struct mgmt_body_t pbody;	int offset = 0;	memset(&pbody, 0, sizeof(pbody));	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +	    IEEE802_11_CAPINFO_LEN))		return 0;	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);	offset += IEEE802_11_TSTAMP_LEN;	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);	offset += IEEE802_11_BCNINT_LEN;	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);	offset += IEEE802_11_CAPINFO_LEN;	parse_elements(&pbody, p, offset);	PRINT_SSID(pbody);	PRINT_RATES(pbody);	printf(" %s",	    CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");	PRINT_DS_CHANNEL(pbody);	return 1;}static inthandle_assoc_request(const u_char *p){	struct mgmt_body_t pbody;	int offset = 0;	memset(&pbody, 0, sizeof(pbody));	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))		return 0;	pbody.capability_info = EXTRACT_LE_16BITS(p);	offset += IEEE802_11_CAPINFO_LEN;	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);	offset += IEEE802_11_LISTENINT_LEN;	parse_elements(&pbody, p, offset);	PRINT_SSID(pbody);	PRINT_RATES(pbody);	return 1;}static inthandle_assoc_response(const u_char *p){	struct mgmt_body_t pbody;	int offset = 0;	memset(&pbody, 0, sizeof(pbody));	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +	    IEEE802_11_AID_LEN))		return 0;	pbody.capability_info = EXTRACT_LE_16BITS(p);	offset += IEEE802_11_CAPINFO_LEN;	pbody.status_code = EXTRACT_LE_16BITS(p+offset);	offset += IEEE802_11_STATUS_LEN;	pbody.aid = EXTRACT_LE_16BITS(p+offset);	offset += IEEE802_11_AID_LEN;	parse_elements(&pbody, p, offset);	printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,	    CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",	    (pbody.status_code < NUM_STATUSES		? status_text[pbody.status_code]		: "n/a"));	return 1;}static inthandle_reassoc_request(const u_char *p){	struct mgmt_body_t pbody;	int offset = 0;	memset(&pbody, 0, sizeof(pbody));	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +	    IEEE802_11_AP_LEN))		return 0;	pbody.capability_info = EXTRACT_LE_16BITS(p);	offset += IEEE802_11_CAPINFO_LEN;	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);	offset += IEEE802_11_LISTENINT_LEN;	memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);	offset += IEEE802_11_AP_LEN;	parse_elements(&pbody, p, offset);	PRINT_SSID(pbody);	printf(" AP : %s", etheraddr_string( pbody.ap ));	return 1;}static inthandle_reassoc_response(const u_char *p){	/* Same as a Association Reponse */	return handle_assoc_response(p);}static inthandle_probe_request(const u_char *p){	struct mgmt_body_t  pbody;	int offset = 0;	memset(&pbody, 0, sizeof(pbody));	parse_elements(&pbody, p, offset);	PRINT_SSID(pbody);	PRINT_RATES(pbody);	return 1;}static inthandle_probe_response(const u_char *p){	struct mgmt_body_t  pbody;	int offset = 0;	memset(&pbody, 0, sizeof(pbody));	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +	    IEEE802_11_CAPINFO_LEN))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?