2007-03-04 10:23:57

by Andy Green

[permalink] [raw]
Subject: Question about PRISM2 header rate field

Hi folks -

I can decode captured Monitor Mode PRISM2 headers in a reasonable way,
except for the rate field.

On a capture of a broadcast which I believe was at 54Mbps, I see the
PRISM2 / ieee80211_frame_info field "datarate" is set to 0xf0, or 240
decimal. I looked around at the various different ways of talking about
tx rate in the stack and drivers, but none that I found use 0xf0 for
54Mbps. Is it 48Mbps in units of 200kHz? Or 54Mbps in units of 225kHz
(!!) Or...?

I am trying to reissue this captured packet using the management
interface (which I can now conjure up) with a rate that I can control,
but I did not find any information on the coding for this field.

-Andy


2007-03-05 16:55:14

by Jouni Malinen

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

On Mon, Mar 05, 2007 at 12:34:07PM +0100, Johannes Berg wrote:

> But if you want to do injection over monitor interfaces we'll need to
> have the stupid mgmt interface hack around forever for the userspace
> MLME so it can receive only management traffic (even the non-promisc
> monitor iface we should have gets *far* too much traffic for a userspace
> MLME)

I'm probably fine with this with Linux socket filter. I haven't verified
this, but I would assume it can match on the 802.11 header frace control
field to select only management frames. I don't think I would like to
see variable length pseudo-header before the 802.11 header, though, in
this case.. It might be possible to parse that in the filter byte code,
but it would certainly be easier if the filter code can just refer to
the beginning of the 802.11 header.

It has been too long since I last used LSF and I think it was only for
matching things in the IP header, so I don't remember what exactly can
be matched in the headers before the IP headert and how easy this would
be in case of monitoring headers. Before throughing away the management
interface, someone would need to verify that this can indeed be done
reasonably.

> Besides, to userspace, this is almost identical. In both cases it opens
> a socket, binds to something (either raw socket bound to netdev or
> netlink socket bound to nl80211) and then stuffs frames into that socket
> with some fixed header format (for most apps anyway)

Well, almost identical still means a change to the kernel-user space
interface.. Though, I think I would be willing to live with the
consequencies in this case assuming we come up with a solution that is
likely to stick for next several years without incompatible changes.

--
Jouni Malinen PGP id EFC895FA

2007-03-05 11:24:31

by Johannes Berg

[permalink] [raw]
Subject: non-promisc monitor interfaces [was: Re: Question about PRISM2 header rate field]

On Sun, 2007-03-04 at 22:10 -0500, Michael Wu wrote:

> Note that modifying the management interface to do this is possible, but it
> would break hostap (and probably wpa_supplicant w/ MLME). Doing packet
> injection on monitor interfaces instead is safer in that regard.

I just thought about monitor interfaces unrelated to this. We really
should allow monitor interfaces to switch between soft and hard monitor
modes by toggling the promisc bit so that you can have a soft monitor
interface (to see what's going on between you and the AP) without the
power penalty.

johannes


Attachments:
signature.asc (190.00 B)
This is a digitally signed message part

2007-03-05 21:21:01

by Andy Green

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

Jouni Malinen wrote:
> On Mon, Mar 05, 2007 at 12:34:07PM +0100, Johannes Berg wrote:
>
>> But if you want to do injection over monitor interfaces we'll need to
>> have the stupid mgmt interface hack around forever for the userspace
>> MLME so it can receive only management traffic (even the non-promisc
>> monitor iface we should have gets *far* too much traffic for a userspace
>> MLME)
>
> I'm probably fine with this with Linux socket filter. I haven't verified
> this, but I would assume it can match on the 802.11 header frace control
> field to select only management frames. I don't think I would like to
> see variable length pseudo-header before the 802.11 header, though, in
> this case.. It might be possible to parse that in the filter byte code,
> but it would certainly be easier if the filter code can just refer to
> the beginning of the 802.11 header.
>
> It has been too long since I last used LSF and I think it was only for
> matching things in the IP header, so I don't remember what exactly can
> be matched in the headers before the IP headert and how easy this would
> be in case of monitoring headers. Before throughing away the management
> interface, someone would need to verify that this can indeed be done
> reasonably.

libpcap at least allows you to express presumably kernel-side filters like

"radio[0x4a:4]==0x13223344"

which means that the u32 at +0x4a bytes from the radio header (this is
for Prism2) must match the constant.

What I saw earlier when wandering through some related code (ipw3945 or
iwlwifi I think) was that other folks have adopted a hybrid system: they
used variable length radiotap headers alright but padded them to 0x40
bytes length. It's not the most beautiful architectural concept but
since mac80211 will be filling in the monitor side with a canned set of
radiotap elements it is in a position to guarantee no violation of it.
For the injection side variable length incoming radiotap headers are
probably no issue, since there is a length field at a fixed place near
the start of the radiotap stuff and the BPF syntax isn't being applied.

>> Besides, to userspace, this is almost identical. In both cases it opens
>> a socket, binds to something (either raw socket bound to netdev or
>> netlink socket bound to nl80211) and then stuffs frames into that socket
>> with some fixed header format (for most apps anyway)
>
> Well, almost identical still means a change to the kernel-user space
> interface.. Though, I think I would be willing to live with the
> consequencies in this case assuming we come up with a solution that is
> likely to stick for next several years without incompatible changes.

My guess is that whoever has to work with that management mode ioctl
forest, with one half of it in userspace or the other half in kernel out
of his control, will jump at the chance to replace it with a nice clean
reliable packet injection mechanism where if the driver only honours the
injection parameters, the usermode guy is in control of the whole
association protocol "soup to nuts" and can monitor everything from
tcpdump too.

-Andy

2007-03-05 13:46:44

by Andy Green

[permalink] [raw]
Subject: Re: Filtering in Monitor Mode (was Question about PRISM2 header rate field)

Johannes Berg wrote:

> The power save mode argument still holds though, we might address that
> with non-promisc monitor interfaces even though they do have a couple of
> problems (you need to be associated on a different virtual netdev for it
> to make sense...)

Hi Johannes -

Yes non-hardware promisc is an interesting combination for the userspace
MLME plan, since you have everything you need already without needing
hardware promisc. I guess the best way is to define a new MODE_ enum
for MONITOR_LOCAL or something.

-Andy

2007-03-04 16:35:41

by Andy Green

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

Andy Green wrote:

> On a capture of a broadcast which I believe was at 54Mbps, I see the
> PRISM2 / ieee80211_frame_info field "datarate" is set to 0xf0, or 240
> decimal. I looked around at the various different ways of talking about
> tx rate in the stack and drivers, but none that I found use 0xf0 for
> 54Mbps. Is it 48Mbps in units of 200kHz? Or 54Mbps in units of 225kHz
> (!!) Or...?
>
> I am trying to reissue this captured packet using the management
> interface (which I can now conjure up) with a rate that I can control,
> but I did not find any information on the coding for this field.

Well, I discover in fact you need to inject starting only from the
IEEE802.11 header... and indeed that does work if you do it on the
"Management Interface". I found this from hostapd sources, since
wpa_supplicant doesn't seem to inject packets from userspace, it seems
to trigger the stack to do canned packets by a huge range of IOCTLs. So
I have unencrypted packets in both directions now without patching
anything on the kernel side :-D But, there is a but...

The packet seems to go out at a default rate, in my case 1Mbps. Is
there in fact a method for requesting the rate for injected packets, or
is there at the moment a simple equivalence that all broadcasts will go
out at 1Mbps?

-Andy

2007-03-05 13:05:44

by Johannes Berg

[permalink] [raw]
Subject: Re: Filtering in Monitor Mode (was Question about PRISM2 header rate field)

On Mon, 2007-03-05 at 13:00 +0000, Andy Green wrote:

> I used the libpcap filter stuff to limit what I saw to just the packets
> of interest. This is the filtering that tcpdump uses to do the
> conditional filters like "port 22" or "host 192.168.0.1". The filter
> uses something called BPF (Berkeley Packet Filter) which is done
> kernelside (at least libpcap is doing the filter install with ioctls in
> pcap-bpf.c). So the cost of drinking from a Monitor firehose is much
> less than it sounds.

Actually, I think the cost can be significant, especially for embedded
systems. You traverse into userspace for each packet at least once, and
a management entity in userspace will not be concerned with data packets
at all. Also, a monitor interface currently always disables power save
mode for many drivers.

johannes


Attachments:
signature.asc (190.00 B)
This is a digitally signed message part

2007-03-05 13:18:37

by Andy Green

[permalink] [raw]
Subject: Re: Filtering in Monitor Mode (was Question about PRISM2 header rate field)

Johannes Berg wrote:
> On Mon, 2007-03-05 at 13:00 +0000, Andy Green wrote:
>
>> I used the libpcap filter stuff to limit what I saw to just the packets
>> of interest. This is the filtering that tcpdump uses to do the
>> conditional filters like "port 22" or "host 192.168.0.1". The filter
>> uses something called BPF (Berkeley Packet Filter) which is done
>> kernelside (at least libpcap is doing the filter install with ioctls in
>> pcap-bpf.c). So the cost of drinking from a Monitor firehose is much
>> less than it sounds.
>
> Actually, I think the cost can be significant, especially for embedded
> systems. You traverse into userspace for each packet at least once, and
> a management entity in userspace will not be concerned with data packets
> at all. Also, a monitor interface currently always disables power save
> mode for many drivers.

Not sure I explained well enough: looking at libpcap sources, it
compiles the filter you request into a bytecode and then gives it to the
kernelside using an ioctl. When you recv() or select() on the monitor
interface after that, you block until something matching your filter
definition turns up. Userspace doesn't hear about the rest of it.

Filter definitions include stuff like testing specific offsets of the
header or payload and boolean operators.

pcap-bpf.c:

static int
pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
{
...
/*
* Try to install the kernel filter.
*/
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
return (-1);
}
p->md.use_bpf = 1; /* filtering in the kernel */
...
}

From the README.linux on libpcap:

''In addition, there is an option that, in 2.2 and later kernels, will
allow packet capture filters specified to programs such as tcpdump to be
executed in the kernel, so that packets that don't pass the filter won't
be copied from the kernel to the program, rather than having all packets
copied to the program and libpcap doing the filtering in user mode.

Copying packets from the kernel to the program consumes a significant
amount of CPU, so filtering in the kernel can reduce the overhead of
capturing packets if a filter has been specified that discards a
significant number of packets. (If no filter is specified, it makes no
difference whether the filtering isn't performed in the kernel or isn't
performed in user mode. :-))

The option for this is the CONFIG_FILTER option''

-Andy

2007-03-05 13:00:09

by Andy Green

[permalink] [raw]
Subject: Re: Filtering in Monitor Mode (was Question about PRISM2 header rate field)

Johannes Berg wrote:
> On Sun, 2007-03-04 at 22:10 -0500, Michael Wu wrote:
>> Note that modifying the management interface to do this is possible, but it
>> would break hostap (and probably wpa_supplicant w/ MLME). Doing packet
>> injection on monitor interfaces instead is safer in that regard.
>
> But if you want to do injection over monitor interfaces we'll need to
> have the stupid mgmt interface hack around forever for the userspace
> MLME so it can receive only management traffic (even the non-promisc
> monitor iface we should have gets *far* too much traffic for a userspace
> MLME)

I used the libpcap filter stuff to limit what I saw to just the packets
of interest. This is the filtering that tcpdump uses to do the
conditional filters like "port 22" or "host 192.168.0.1". The filter
uses something called BPF (Berkeley Packet Filter) which is done
kernelside (at least libpcap is doing the filter install with ioctls in
pcap-bpf.c). So the cost of drinking from a Monitor firehose is much
less than it sounds.

> Besides, to userspace, this is almost identical. In both cases it opens
> a socket, binds to something (either raw socket bound to netdev or
> netlink socket bound to nl80211) and then stuffs frames into that socket
> with some fixed header format (for most apps anyway)

I'm guessing the concern is to leave the crufty scary
not-very-well-known Management Interface monster asleep lest it wake up
while being edited and eat everyone :-)

-Andy

2007-03-05 00:16:09

by Johannes Berg

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field


> Well, I discover in fact you need to inject starting only from the
> IEEE802.11 header... and indeed that does work if you do it on the
> "Management Interface". I found this from hostapd sources, since
> wpa_supplicant doesn't seem to inject packets from userspace,

Never versions of wpa_supplicant should do this in the userspace MLME
part.

> it seems
> to trigger the stack to do canned packets by a huge range of IOCTLs. So
> I have unencrypted packets in both directions now without patching
> anything on the kernel side :-D But, there is a but...

:)

> The packet seems to go out at a default rate, in my case 1Mbps. Is
> there in fact a method for requesting the rate for injected packets, or
> is there at the moment a simple equivalence that all broadcasts will go
> out at 1Mbps?

Looks like you're right, there doesn't seem to be a way. I always
thought this was possible.

I think you should raise this point on the mailing list again. I've
proposed doing this through nl80211 to allow extensibility of the meta
information (frame rate, ....) for an injected frame instead of
conjuring up yet another meta information framework that transports
frame across netdevs, but Michael strongly opposes the idea of
transporting frames via anything but a netdev.

I could post some code for nl80211 inject that doesn't control any meta
information yet but at least has the capability of carrying it over to
the stack.

johannes


Attachments:
signature.asc (190.00 B)
This is a digitally signed message part

2007-03-05 11:34:36

by Johannes Berg

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

On Sun, 2007-03-04 at 22:10 -0500, Michael Wu wrote:
>
> Note that modifying the management interface to do this is possible, but it
> would break hostap (and probably wpa_supplicant w/ MLME). Doing packet
> injection on monitor interfaces instead is safer in that regard.

But if you want to do injection over monitor interfaces we'll need to
have the stupid mgmt interface hack around forever for the userspace
MLME so it can receive only management traffic (even the non-promisc
monitor iface we should have gets *far* too much traffic for a userspace
MLME)

Besides, to userspace, this is almost identical. In both cases it opens
a socket, binds to something (either raw socket bound to netdev or
netlink socket bound to nl80211) and then stuffs frames into that socket
with some fixed header format (for most apps anyway)

johannes


Attachments:
signature.asc (190.00 B)
This is a digitally signed message part

2007-03-05 08:10:52

by Andy Green

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

Michael Wu wrote:

Hi Michael -

> On Sunday 04 March 2007 20:02, Andy Green wrote:
>> How about for injection on the Management interface, it expects to find
>> a PRISM2 header prepended to the ieee80211 one and the payload, in
>> exactly the same format as is delivered by Monitor Mode? The PRISM2
>> capture header structure has a bunch of fields for things like rate and
>> antenna selection already. This has the satisfying aspect that you can
>> literally replay the whole Monitor Mode packet capture down the
>> Management Interface and get it to go out at the same rate.
>>
> Isn't this what aircrack does? I think many other drivers that support frame
> injection do it in a similar way (TX AVS frame on monitor interface), and
> this is also the way I prefer the frame injection interface. It does have the
> nice property of being able to directly replay captured traffic as you
> mentioned. Just note that AVS/prism2 is planned to be removed in favor of
> radiotap which is more extensible. Radiotap should also work for frame
> injection, though it isn't as easy as using a fixed length header format.

Radiotap is fine for me too. PRISM2 has a 32-bit magic at the start, I
guess you can just check the first byte (Magic 0x1e for PRISM2, Version
0x00 for Radiotap) to find out what you have been given. Just returning
-ENOSUPP or something else unique for an unsupported header will allow
easy adaptation in userspace to what header system a given kernel will
support for tx.

Radiotap also has better documentation in the form of the old stack
header file at least. It's clear there's more than enough capability
defined for my needs anyway, it will allow optional specification of
antenna and even tx power too. It doesn't make any difference for me
that it is variable length.

> Note that modifying the management interface to do this is possible, but it
> would break hostap (and probably wpa_supplicant w/ MLME). Doing packet
> injection on monitor interfaces instead is safer in that regard.

Basing it around Monitor Mode interfaces will suit all the potential
users I think, since they might already have one floating around, and
they are easier to spawn than Management anyway.

-Andy

2007-03-05 13:23:07

by Johannes Berg

[permalink] [raw]
Subject: Re: Filtering in Monitor Mode (was Question about PRISM2 header rate field)

On Mon, 2007-03-05 at 13:18 +0000, Andy Green wrote:

> Not sure I explained well enough: looking at libpcap sources, it
> compiles the filter you request into a bytecode and then gives it to the
> kernelside using an ioctl. When you recv() or select() on the monitor
> interface after that, you block until something matching your filter
> definition turns up. Userspace doesn't hear about the rest of it.

Uh eh right, I'm confused :)

The power save mode argument still holds though, we might address that
with non-promisc monitor interfaces even though they do have a couple of
problems (you need to be associated on a different virtual netdev for it
to make sense...)

johannes


Attachments:
signature.asc (190.00 B)
This is a digitally signed message part

2007-03-05 03:11:10

by Michael Wu

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

On Sunday 04 March 2007 20:02, Andy Green wrote:
> How about for injection on the Management interface, it expects to find
> a PRISM2 header prepended to the ieee80211 one and the payload, in
> exactly the same format as is delivered by Monitor Mode? The PRISM2
> capture header structure has a bunch of fields for things like rate and
> antenna selection already. This has the satisfying aspect that you can
> literally replay the whole Monitor Mode packet capture down the
> Management Interface and get it to go out at the same rate.
>
Isn't this what aircrack does? I think many other drivers that support frame
injection do it in a similar way (TX AVS frame on monitor interface), and
this is also the way I prefer the frame injection interface. It does have the
nice property of being able to directly replay captured traffic as you
mentioned. Just note that AVS/prism2 is planned to be removed in favor of
radiotap which is more extensible. Radiotap should also work for frame
injection, though it isn't as easy as using a fixed length header format.

Note that modifying the management interface to do this is possible, but it
would break hostap (and probably wpa_supplicant w/ MLME). Doing packet
injection on monitor interfaces instead is safer in that regard.

-Michael Wu


Attachments:
(No filename) (1.26 kB)
(No filename) (189.00 B)
Download all attachments

2007-03-05 01:02:54

by Andy Green

[permalink] [raw]
Subject: Re: Question about PRISM2 header rate field

Johannes Berg wrote:

Hi Johannes -

>> Well, I discover in fact you need to inject starting only from the
>> IEEE802.11 header... and indeed that does work if you do it on the
>> "Management Interface". I found this from hostapd sources, since
>> wpa_supplicant doesn't seem to inject packets from userspace,
>
> Never versions of wpa_supplicant should do this in the userspace MLME
> part.

I was looking at 0.5.7 but it can easily be I missed it.

> Looks like you're right, there doesn't seem to be a way. I always
> thought this was possible.
>
> I think you should raise this point on the mailing list again. I've
> proposed doing this through nl80211 to allow extensibility of the meta
> information (frame rate, ....) for an injected frame instead of
> conjuring up yet another meta information framework that transports
> frame across netdevs, but Michael strongly opposes the idea of
> transporting frames via anything but a netdev.

Hmm, right.

> I could post some code for nl80211 inject that doesn't control any meta
> information yet but at least has the capability of carrying it over to
> the stack.

These injected broadcasts will ultimately be used for bulk data
transfer: I have had 300kBytes/sec using the addressless file transfer
protocol on the patched wireless drivers. In such a case, it is
critical that netdev-like stuff especially select() and tx blocking down
in usermode works properly: the progress of the usermode transmission
thread must be regulated only by the driver and stack managing the
descriptors and blocking when things are getting backed up. If the
nl80211 injection "side channel" for sending packets doesn't inherit the
interface stop and start stuff in a clean way from whatever it calls
through to then it could get messy getting the netdev interfaces and the
side channel to block in sync I can imagine.

Here are a couple of ideas to consider anyway.

#1 The rate and so on metadata for the sending action has to belong
unambiguously with the payload, because multiple packet rates can be in
use at the same time as part of an anonymous selfconfiguring rate
optimization scheme, and so it would be no good selecting the injection
rate asynchronously on some ioctl or via another nl80211 api separate
from the payload.

How about for injection on the Management interface, it expects to find
a PRISM2 header prepended to the ieee80211 one and the payload, in
exactly the same format as is delivered by Monitor Mode? The PRISM2
capture header structure has a bunch of fields for things like rate and
antenna selection already. This has the satisfying aspect that you can
literally replay the whole Monitor Mode packet capture down the
Management Interface and get it to go out at the same rate.

#2 The whole management interface magic summoning hoodoo is a bit
strange compared to echo -n newinterfacename >
/sys/class/whatever/add_iface. How about regularizing the situation by
allowing one or more normal mac80211 interfaces to be added and then set
like iwconfig wmgmt0 mode Management. Perhaps it can then be possible
to associate the interface with a rate, like iwconfig wmgmt0 rate 54M or
iwconfig wmgmt1 rate 11M. Depending on which one you send your packet
to, it goes out at the rate associated with the interface. There can
still only be one real Management Interface per physical device if that
is important, the others are just thin wrappers over the single good one
to hold the rate (and antenna if possible) info. In this way there are
no new magic headers needed, it is all done as a netdev and the
situation for Management Interface creation is normalized a bit. The
drawback is that it is not quite as flexible as being able to specify
the rate and which antenna packet by packet.

-Andy