From patchwork Wed Jan 26 14:30:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 743 Return-Path: Received: from nm2-vm0.bullet.mail.ukl.yahoo.com (nm2-vm0.bullet.mail.ukl.yahoo.com [217.146.183.226]) by open-mesh.org (Postfix) with SMTP id B2E0B15448A for ; Wed, 26 Jan 2011 15:33:45 +0100 (CET) Received: from [217.146.183.216] by nm2.bullet.mail.ukl.yahoo.com with NNFMP; 26 Jan 2011 14:33:45 -0000 Received: from [217.146.183.33] by tm9.bullet.mail.ukl.yahoo.com with NNFMP; 26 Jan 2011 14:33:45 -0000 Received: from [127.0.0.1] by omp1022.mail.ukl.yahoo.com with NNFMP; 26 Jan 2011 14:33:45 -0000 X-Yahoo-Newman-Id: 112717.89552.bm@omp1022.mail.ukl.yahoo.com Received: (qmail 54867 invoked from network); 26 Jan 2011 14:33:45 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.de; h=DKIM-Signature:Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Cc:Subject:Date:Message-Id:X-Mailer; b=FU5Up5m9TEp0xSxJaeHi1mEYjUchm1T37h/su9/gLrr3p4L9I+oZ0qzjfbIEdn28bxuIzpLXSBnKZDgwpnOY3Kyg6OE3S3cwyIB93m95KyaV5IjJSzfd8AmW/AAVNFKxP0fbNse4wrbmnKFy4PEjOq6mBgN/kGOnleZPUZKQ7Iw= ; DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s1024; t=1296052425; bh=HI3TIIiIf9NKhey6fvvV7ju7V1GO8CZkULyskmsZtm8=; h=Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Cc:Subject:Date:Message-Id:X-Mailer; b=3SeaxBmpqmBGY+3/CCr8hrK4+HhdeJGcpVy+QhjomLuZdjQIupk/8HD+BsfQEaq+tWrzlVVUShJfkeCr/zbHF8TU4QAq65rDZWE1AcrhTo3T1l3vIhrqAhzVR99a+Fc1fpomoKGZNXOKBEft/KHZSMkdzaGYgG6vZRAjJt1Q1Io= Received: from localhost (lindner_marek@81.57.254.118 with plain) by smtp127.mail.ukl.yahoo.com with SMTP; 26 Jan 2011 14:33:41 +0000 GMT X-Yahoo-SMTP: tW.h3tiswBBMXO2coYcbPigGD5Lt6zY_.Zc- X-YMail-OSG: BRE7uBoVM1lEo43n.JuH48V4JG.3pRCp4kHlKRhsqZnZcWb 2vBp8ywCmtgjUbRN1Uq1B3BNrB3qJj5HAVCTNqrHYxzojpQj_hkJNvzFd7qL V6njRFbHYUNYiiuhKjqyziTHbqeo6Mkd0gaucVh5euP99fDFWMlUWEF6frHt aHVt5c.QkYLecu3C6TEuqGU2fs7eUH.9GQTQR5gdEneaBj6LDCpqkZIWZoSU e4rsm7ZOiVu1lcU0Qr2DA9VoT2PJgk8BWRtA4tkkVap0wE7S4PMVKz1S.RBR fUpFVEBD83VfxbTI- X-Yahoo-Newman-Property: ymail-3 From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Wed, 26 Jan 2011 15:30:08 +0100 Message-Id: <1296052208-6041-1-git-send-email-lindner_marek@yahoo.de> X-Mailer: git-send-email 1.7.2.3 Cc: Marek Lindner Subject: [B.A.T.M.A.N.] [PATCH] batctl: add raw wifi packet decapsulation support X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Jan 2011 14:33:46 -0000 Signed-off-by: Marek Lindner --- batctl/tcpdump.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++- batctl/tcpdump.h | 49 +++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 1 deletions(-) diff --git a/batctl/tcpdump.c b/batctl/tcpdump.c index 4bff970..bdf81bc 100644 --- a/batctl/tcpdump.c +++ b/batctl/tcpdump.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -458,6 +459,75 @@ static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read } } +static void parse_wifi_hdr(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) +{ + struct ether_header *eth_hdr; + struct ieee80211_hdr *wifi_hdr; + unsigned char *shost, *dhost; + uint16_t fc; + int hdr_len; + + if (buff_len <= (ssize_t)PRISM_HEADER_LEN) + return; + + buff_len -= PRISM_HEADER_LEN; + packet_buff += PRISM_HEADER_LEN; + + /* we assume a minimum size of 38 bytes + * (802.11 data frame + LLC) + * before we calculate the real size */ + if (buff_len <= 38) + return; + + wifi_hdr = (struct ieee80211_hdr *)packet_buff; + fc = wifi_hdr->frame_control; + + /* not carrying payload */ + if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) + return; + + /* encrypted packet */ + if (fc & IEEE80211_FCTL_PROTECTED) + return; + + shost = wifi_hdr->addr2; + if (fc & IEEE80211_FCTL_FROMDS) + shost = wifi_hdr->addr3; + else if (fc & IEEE80211_FCTL_TODS) + shost = wifi_hdr->addr4; + + dhost = wifi_hdr->addr1; + if (fc & IEEE80211_FCTL_TODS) + dhost = wifi_hdr->addr3; + + hdr_len = 24; + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) + hdr_len = 30; + + if (fc & IEEE80211_STYPE_QOS_DATA) + hdr_len += 2; + + /* LLC */ + hdr_len += 8; + hdr_len -= sizeof(struct ether_header); + + if (buff_len <= hdr_len) + return; + + buff_len -= hdr_len; + packet_buff += hdr_len; + + eth_hdr = (struct ether_header *)packet_buff; + memmove(eth_hdr->ether_shost, shost, ETH_ALEN); + memmove(eth_hdr->ether_dhost, dhost, ETH_ALEN); + + /* printf("parse_wifi_hdr(): ether_type: 0x%04x\n", ntohs(eth_hdr->ether_type)); + printf("parse_wifi_hdr(): shost: %s\n", ether_ntoa_long((struct ether_addr *)eth_hdr->ether_shost)); + printf("parse_wifi_hdr(): dhost: %s\n", ether_ntoa_long((struct ether_addr *)eth_hdr->ether_dhost)); */ + + parse_eth_hdr(packet_buff, buff_len, read_opt, time_printed); +} + int tcpdump(int argc, char **argv) { struct ifreq req; @@ -526,6 +596,27 @@ int tcpdump(int argc, char **argv) memset(&req, 0, sizeof (struct ifreq)); strncpy(req.ifr_name, dump_if->dev, IFNAMSIZ); + res = ioctl(dump_if->raw_sock, SIOCGIFHWADDR, &req); + if (res < 0) { + printf("Error - can't create raw socket (SIOCGIFHWADDR): %s\n", strerror(errno)); + close(dump_if->raw_sock); + goto out; + } + + dump_if->hw_type = req.ifr_hwaddr.sa_family; + + switch (dump_if->hw_type) { + case ARPHRD_ETHER: + case ARPHRD_IEEE80211_PRISM: + break; + default: + printf("Error - interface '%s' is of unknown type: %i\n", dump_if->dev, dump_if->hw_type); + goto out; + } + + memset(&req, 0, sizeof (struct ifreq)); + strncpy(req.ifr_name, dump_if->dev, IFNAMSIZ); + res = ioctl(dump_if->raw_sock, SIOCGIFINDEX, &req); if (res < 0) { @@ -588,7 +679,18 @@ int tcpdump(int argc, char **argv) continue; } - parse_eth_hdr(packet_buff, read_len, read_opt, 0); + switch (dump_if->hw_type) { + case ARPHRD_ETHER: + parse_eth_hdr(packet_buff, read_len, read_opt, 0); + break; + case ARPHRD_IEEE80211_PRISM: + parse_wifi_hdr(packet_buff, read_len, read_opt, 0); + break; + default: + /* should not happen */ + break; + } + fflush(stdout); } diff --git a/batctl/tcpdump.h b/batctl/tcpdump.h index f98d63f..f4276dc 100644 --- a/batctl/tcpdump.h +++ b/batctl/tcpdump.h @@ -23,6 +23,10 @@ #include #include "list-batman.h" +#ifndef ARPHRD_IEEE80211_PRISM +#define ARPHRD_IEEE80211_PRISM 802 +#endif + #define DUMP_TYPE_BATOGM 1 #define DUMP_TYPE_BATICMP 2 #define DUMP_TYPE_BATUCAST 4 @@ -31,11 +35,21 @@ #define DUMP_TYPE_BATFRAG 32 #define DUMP_TYPE_NONBAT 64 +#define IEEE80211_FCTL_FTYPE 0x000c +#define IEEE80211_FCTL_TODS 0x0100 +#define IEEE80211_FCTL_FROMDS 0x0200 +#define IEEE80211_FCTL_PROTECTED 0x4000 + +#define IEEE80211_FTYPE_DATA 0x0008 + +#define IEEE80211_STYPE_QOS_DATA 0x0080 + struct dump_if { struct list_head list; char *dev; int32_t raw_sock; struct sockaddr_ll addr; + int32_t hw_type; }; struct vlanhdr { @@ -43,4 +57,39 @@ struct vlanhdr { u_int16_t ether_type; } __attribute__ ((packed)); +struct ieee80211_hdr { + u_int16_t frame_control; + u_int16_t duration_id; + u_int8_t addr1[6]; + u_int8_t addr2[6]; + u_int8_t addr3[6]; + u_int16_t seq_ctrl; + u_int8_t addr4[6]; +} __attribute__ ((packed)); + +struct prism_item { + u_int32_t did; + u_int16_t status; + u_int16_t len; + u_int32_t data; +}; + +struct prism_header { + u_int32_t msgcode; + u_int32_t msglen; + u_int8_t devname[16]; + struct prism_item hosttime; + struct prism_item mactime; + struct prism_item channel; + struct prism_item rssi; + struct prism_item sq; + struct prism_item signal; + struct prism_item noise; + struct prism_item rate; + struct prism_item istx; + struct prism_item frmlen; +}; + +#define PRISM_HEADER_LEN sizeof(struct prism_header) + int tcpdump(int argc, char **argv);