Re: 3 small net80211 fixes

2011-02-21 Thread Damien Bergamini
| Index: ieee80211_input.c
| ===
| RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
| retrieving revision 1.116
| diff -u -p -r1.116 ieee80211_input.c
| --- ieee80211_input.c 7 Jun 2010 16:51:22 -   1.116
| +++ ieee80211_input.c 20 Feb 2011 19:51:24 -
| @@ -789,7 +789,7 @@ ieee80211_deliver_data(struct ieee80211c
|   int error, len;
|  
|   if (ETHER_IS_MULTICAST(eh-ether_dhost)) {
| - m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
| + m1 = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
|   if (m1 == NULL)
|   ifp-if_oerrors++;
|   else

ok


| This one I'm not entirely sure about.
| But the code that receives the 3/4 message seems to expect an RSC for
| both the RSN and WPA cases. Also, this makes the code match up with
| how it's done in ieee80211_send_group_msg1().
| sidebar
| I spotted this one trying to hunt down a phantom bug with replay
| counter
| handling (which in fact seems to be fine).
| On the client side, netstat -W shows TKIP replays for every broadcast
| packet
| sent from the hostap to the station (both running -current).
| Is anyone else seeing this? There might be some driver/hardware
| problem with
| ath(4) that causes the AP to send duplicate frames. Or signal
| reflection
| issues? I tried with both wpi(4) and ral(4) cards on the client side.
| I've given up on trying to fix this, but the diff below felt worth
| keeping.
| /sidebar
| Index: ieee80211_pae_output.c
| ===
| RCS file: /cvs/src/sys/net80211/ieee80211_pae_output.c,v
| retrieving revision 1.16
| diff -u -p -r1.16 ieee80211_pae_output.c
| --- ieee80211_pae_output.c5 Jun 2010 15:54:35 -   1.16
| +++ ieee80211_pae_output.c20 Feb 2011 17:55:51 -
| @@ -417,7 +417,6 @@ ieee80211_send_4way_msg3(struct ieee8021
|   frm = ieee80211_add_rsn(frm, ic, ic-ic_bss);
|   /* encapsulate the GTK */
|   frm = ieee80211_add_gtk_kde(frm, ni, k);
| - LE_WRITE_6(key-rsc, k-k_tsc);
|   /* encapsulate the IGTK if MFP was negotiated */
|   if (ni-ni_flags  IEEE80211_NODE_MFP) {
|   frm = ieee80211_add_igtk_kde(frm,
| @@ -427,6 +426,9 @@ ieee80211_send_4way_msg3(struct ieee8021
|   info |= EAPOL_KEY_ENCRYPTED | EAPOL_KEY_SECURE;
|   } else  /* WPA */
|   frm = ieee80211_add_wpa(frm, ic, ic-ic_bss);
| +
| + /* RSC = last transmit sequence number for the GTK */
| + LE_WRITE_6(key-rsc, k-k_tsc);
|  
|   /* write the key info field */
|   BE_WRITE_2(key-info, info);


nack.  you'll get a null deref with wpa1 (k is not initialized).
with wpa1, message 3/4 of the 4-way handshake does not carry the
group key (it is sent in message 1/2 of the group key handshake
that follows the 4-way handshake instead).
the TSC of the pairwise key is always 0 in our case, which is
the reason why it is not set here, but used when receiving
msg 3/4 since other implementations may use non-zero values.


| This last one is pretty obvious.
| ieee80211_alloc_node() does the same increment already, so the stats
| about node allocation failures are wrong.
| Index: ieee80211_proto.c
| ===
| RCS file: /cvs/src/sys/net80211/ieee80211_proto.c,v
| retrieving revision 1.44
| diff -u -p -r1.44 ieee80211_proto.c
| --- ieee80211_proto.c 7 Aug 2010 03:50:02 -   1.44
| +++ ieee80211_proto.c 6 Feb 2011 15:14:42 -
| @@ -704,7 +704,6 @@ ieee80211_auth_open(struct ieee80211com 
|   if (ni == ic-ic_bss) {
|   ni = ieee80211_alloc_node(ic, wh-i_addr2);
|   if (ni == NULL) {
| - ic-ic_stats.is_rx_nodealloc++;
|   return;
|   }
|   IEEE80211_ADDR_COPY(ni-ni_bssid, ic-ic_bss-ni_bssid);

ok.

Damien



Re: 3 small net80211 fixes

2011-02-21 Thread Stefan Sperling
On Mon, Feb 21, 2011 at 12:57:08PM +0100, Damien Bergamini wrote:
 | Index: ieee80211_pae_output.c
 | ===
 | RCS file: /cvs/src/sys/net80211/ieee80211_pae_output.c,v
 | retrieving revision 1.16
 | diff -u -p -r1.16 ieee80211_pae_output.c
 | --- ieee80211_pae_output.c  5 Jun 2010 15:54:35 -   1.16
 | +++ ieee80211_pae_output.c  20 Feb 2011 17:55:51 -
 | @@ -417,7 +417,6 @@ ieee80211_send_4way_msg3(struct ieee8021
 | frm = ieee80211_add_rsn(frm, ic, ic-ic_bss);
 | /* encapsulate the GTK */
 | frm = ieee80211_add_gtk_kde(frm, ni, k);
 | -   LE_WRITE_6(key-rsc, k-k_tsc);
 | /* encapsulate the IGTK if MFP was negotiated */
 | if (ni-ni_flags  IEEE80211_NODE_MFP) {
 | frm = ieee80211_add_igtk_kde(frm,
 | @@ -427,6 +426,9 @@ ieee80211_send_4way_msg3(struct ieee8021
 | info |= EAPOL_KEY_ENCRYPTED | EAPOL_KEY_SECURE;
 | } else  /* WPA */
 | frm = ieee80211_add_wpa(frm, ic, ic-ic_bss);
 | +
 | +   /* RSC = last transmit sequence number for the GTK */
 | +   LE_WRITE_6(key-rsc, k-k_tsc);
 |  
 | /* write the key info field */
 | BE_WRITE_2(key-info, info);
 
 
 nack.  you'll get a null deref with wpa1 (k is not initialized).
 with wpa1, message 3/4 of the 4-way handshake does not carry the
 group key (it is sent in message 1/2 of the group key handshake
 that follows the 4-way handshake instead).
 the TSC of the pairwise key is always 0 in our case, which is
 the reason why it is not set here, but used when receiving
 msg 3/4 since other implementations may use non-zero values.

Ah, that makes sense. Thanks for clarifying.

I'll commit the others when Miod has acked them.



3 small net80211 fixes

2011-02-20 Thread Stefan Sperling
Here are three small net80211 fixes.
I'm sending them in a batch, but feel free to ok or reject them individually.


The first one is an old bug fix from FreeBSD for AP-bridging encrypted
multicast frames.
http://marc.info/?l=freebsd-currentm=114168135819304w=2
http://svn.freebsd.org/viewvc/base?view=revisionrevision=156367
Index: ieee80211_input.c
===
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.116
diff -u -p -r1.116 ieee80211_input.c
--- ieee80211_input.c   7 Jun 2010 16:51:22 -   1.116
+++ ieee80211_input.c   20 Feb 2011 19:51:24 -
@@ -789,7 +789,7 @@ ieee80211_deliver_data(struct ieee80211c
int error, len;
 
if (ETHER_IS_MULTICAST(eh-ether_dhost)) {
-   m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
+   m1 = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
if (m1 == NULL)
ifp-if_oerrors++;
else


This one I'm not entirely sure about.
But the code that receives the 3/4 message seems to expect an RSC for
both the RSN and WPA cases. Also, this makes the code match up with
how it's done in ieee80211_send_group_msg1().
sidebar
I spotted this one trying to hunt down a phantom bug with replay counter
handling (which in fact seems to be fine).
On the client side, netstat -W shows TKIP replays for every broadcast packet
sent from the hostap to the station (both running -current).
Is anyone else seeing this? There might be some driver/hardware problem with
ath(4) that causes the AP to send duplicate frames. Or signal reflection
issues? I tried with both wpi(4) and ral(4) cards on the client side.
I've given up on trying to fix this, but the diff below felt worth keeping.
/sidebar
Index: ieee80211_pae_output.c
===
RCS file: /cvs/src/sys/net80211/ieee80211_pae_output.c,v
retrieving revision 1.16
diff -u -p -r1.16 ieee80211_pae_output.c
--- ieee80211_pae_output.c  5 Jun 2010 15:54:35 -   1.16
+++ ieee80211_pae_output.c  20 Feb 2011 17:55:51 -
@@ -417,7 +417,6 @@ ieee80211_send_4way_msg3(struct ieee8021
frm = ieee80211_add_rsn(frm, ic, ic-ic_bss);
/* encapsulate the GTK */
frm = ieee80211_add_gtk_kde(frm, ni, k);
-   LE_WRITE_6(key-rsc, k-k_tsc);
/* encapsulate the IGTK if MFP was negotiated */
if (ni-ni_flags  IEEE80211_NODE_MFP) {
frm = ieee80211_add_igtk_kde(frm,
@@ -427,6 +426,9 @@ ieee80211_send_4way_msg3(struct ieee8021
info |= EAPOL_KEY_ENCRYPTED | EAPOL_KEY_SECURE;
} else  /* WPA */
frm = ieee80211_add_wpa(frm, ic, ic-ic_bss);
+
+   /* RSC = last transmit sequence number for the GTK */
+   LE_WRITE_6(key-rsc, k-k_tsc);
 
/* write the key info field */
BE_WRITE_2(key-info, info);



This last one is pretty obvious.
ieee80211_alloc_node() does the same increment already, so the stats
about node allocation failures are wrong.
Index: ieee80211_proto.c
===
RCS file: /cvs/src/sys/net80211/ieee80211_proto.c,v
retrieving revision 1.44
diff -u -p -r1.44 ieee80211_proto.c
--- ieee80211_proto.c   7 Aug 2010 03:50:02 -   1.44
+++ ieee80211_proto.c   6 Feb 2011 15:14:42 -
@@ -704,7 +704,6 @@ ieee80211_auth_open(struct ieee80211com 
if (ni == ic-ic_bss) {
ni = ieee80211_alloc_node(ic, wh-i_addr2);
if (ni == NULL) {
-   ic-ic_stats.is_rx_nodealloc++;
return;
}
IEEE80211_ADDR_COPY(ni-ni_bssid, ic-ic_bss-ni_bssid);