Deleted Added
full compact
ieee80211_node.c (148863) ieee80211_node.c (148936)
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 17 unchanged lines hidden (view full) ---

26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 17 unchanged lines hidden (view full) ---

26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_node.c 148863 2005-08-08 18:46:36Z sam $");
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_node.c 148936 2005-08-10 16:22:30Z sam $");
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/mbuf.h>
39#include <sys/malloc.h>
40#include <sys/kernel.h>
41
42#include <sys/socket.h>

--- 213 unchanged lines hidden (view full) ---

256 /* XXX ic_des_chan should be handled with ic_chan_active */
257 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
258 memset(ic->ic_chan_scan, 0, sizeof(ic->ic_chan_scan));
259 setbit(ic->ic_chan_scan,
260 ieee80211_chan2ieee(ic, ic->ic_des_chan));
261 } else
262 memcpy(ic->ic_chan_scan, ic->ic_chan_active,
263 sizeof(ic->ic_chan_active));
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/mbuf.h>
39#include <sys/malloc.h>
40#include <sys/kernel.h>
41
42#include <sys/socket.h>

--- 213 unchanged lines hidden (view full) ---

256 /* XXX ic_des_chan should be handled with ic_chan_active */
257 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
258 memset(ic->ic_chan_scan, 0, sizeof(ic->ic_chan_scan));
259 setbit(ic->ic_chan_scan,
260 ieee80211_chan2ieee(ic, ic->ic_des_chan));
261 } else
262 memcpy(ic->ic_chan_scan, ic->ic_chan_active,
263 sizeof(ic->ic_chan_active));
264 /* NB: hack, setup so next_scan starts with the first channel */
265 if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC)
266 ieee80211_set_chan(ic, ic->ic_bss,
267 &ic->ic_channels[IEEE80211_CHAN_MAX]);
268#ifdef IEEE80211_DEBUG
269 if (ieee80211_msg_scan(ic)) {
270 printf("%s: scan set:", __func__);
271 dump_chanlist(ic->ic_chan_scan);
272 printf(" start chan %u\n",
264#ifdef IEEE80211_DEBUG
265 if (ieee80211_msg_scan(ic)) {
266 printf("%s: scan set:", __func__);
267 dump_chanlist(ic->ic_chan_scan);
268 printf(" start chan %u\n",
273 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
269 ieee80211_chan2ieee(ic, ic->ic_curchan));
274 }
275#endif /* IEEE80211_DEBUG */
276}
277
278/*
279 * Begin an active scan.
280 */
281void

--- 37 unchanged lines hidden (view full) ---

319
320 /*
321 * Insure any previous mgt frame timeouts don't fire.
322 * This assumes the driver does the right thing in
323 * flushing anything queued in the driver and below.
324 */
325 ic->ic_mgt_timer = 0;
326
270 }
271#endif /* IEEE80211_DEBUG */
272}
273
274/*
275 * Begin an active scan.
276 */
277void

--- 37 unchanged lines hidden (view full) ---

315
316 /*
317 * Insure any previous mgt frame timeouts don't fire.
318 * This assumes the driver does the right thing in
319 * flushing anything queued in the driver and below.
320 */
321 ic->ic_mgt_timer = 0;
322
327 chan = ic->ic_bss->ni_chan;
323 chan = ic->ic_curchan;
328 do {
329 if (++chan > &ic->ic_channels[IEEE80211_CHAN_MAX])
330 chan = &ic->ic_channels[0];
331 if (isset(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan))) {
332 clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan));
333 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
334 "%s: chan %d->%d\n", __func__,
324 do {
325 if (++chan > &ic->ic_channels[IEEE80211_CHAN_MAX])
326 chan = &ic->ic_channels[0];
327 if (isset(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan))) {
328 clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan));
329 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
330 "%s: chan %d->%d\n", __func__,
335 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
331 ieee80211_chan2ieee(ic, ic->ic_curchan),
336 ieee80211_chan2ieee(ic, chan));
332 ieee80211_chan2ieee(ic, chan));
337 ieee80211_set_chan(ic, ic->ic_bss, chan);
333 ic->ic_curchan = chan;
334 /*
335 * XXX drivers should do this as needed,
336 * XXX for now maintain compatibility
337 */
338 ic->ic_bss->ni_rates =
339 ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)];
338 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
339 return 1;
340 }
340 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
341 return 1;
342 }
341 } while (chan != ic->ic_bss->ni_chan);
343 } while (chan != ic->ic_curchan);
342 ieee80211_end_scan(ic);
343 return 0;
344}
345
346static __inline void
347copy_bss(struct ieee80211_node *nbss, const struct ieee80211_node *obss)
348{
349 /* propagate useful state */

--- 53 unchanged lines hidden (view full) ---

403 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_des_bssid);
404 else
405 ni->ni_bssid[0] |= 0x02; /* local bit for IBSS */
406 }
407 /*
408 * Fix the channel and related attributes.
409 */
410 ieee80211_set_chan(ic, ni, chan);
344 ieee80211_end_scan(ic);
345 return 0;
346}
347
348static __inline void
349copy_bss(struct ieee80211_node *nbss, const struct ieee80211_node *obss)
350{
351 /* propagate useful state */

--- 53 unchanged lines hidden (view full) ---

405 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_des_bssid);
406 else
407 ni->ni_bssid[0] |= 0x02; /* local bit for IBSS */
408 }
409 /*
410 * Fix the channel and related attributes.
411 */
412 ieee80211_set_chan(ic, ni, chan);
413 ic->ic_curchan = chan;
411 ic->ic_curmode = ieee80211_chan2mode(ic, chan);
412 /*
413 * Do mode-specific rate setup.
414 */
415 if (ic->ic_curmode == IEEE80211_MODE_11G) {
416 /*
417 * Use a mixed 11b/11g rate set.
418 */

--- 366 unchanged lines hidden (view full) ---

785 if (obss != NULL)
786 ieee80211_free_node(obss);
787 /*
788 * Set the erp state (mostly the slot time) to deal with
789 * the auto-select case; this should be redundant if the
790 * mode is locked.
791 */
792 ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan);
414 ic->ic_curmode = ieee80211_chan2mode(ic, chan);
415 /*
416 * Do mode-specific rate setup.
417 */
418 if (ic->ic_curmode == IEEE80211_MODE_11G) {
419 /*
420 * Use a mixed 11b/11g rate set.
421 */

--- 366 unchanged lines hidden (view full) ---

788 if (obss != NULL)
789 ieee80211_free_node(obss);
790 /*
791 * Set the erp state (mostly the slot time) to deal with
792 * the auto-select case; this should be redundant if the
793 * mode is locked.
794 */
795 ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan);
796 ic->ic_curchan = selbs->ni_chan;
793 ieee80211_reset_erp(ic);
794 ieee80211_wme_initparams(ic);
795
796 if (ic->ic_opmode == IEEE80211_M_STA)
797 ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
798 else
799 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
800 return 1;

--- 279 unchanged lines hidden (view full) ---

1080 if (ic->ic_newassoc != NULL)
1081 ic->ic_newassoc(ni, 1);
1082 /* XXX not right for 802.1x/WPA */
1083 ieee80211_node_authorize(ni);
1084 }
1085 return ni;
1086}
1087
797 ieee80211_reset_erp(ic);
798 ieee80211_wme_initparams(ic);
799
800 if (ic->ic_opmode == IEEE80211_M_STA)
801 ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
802 else
803 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
804 return 1;

--- 279 unchanged lines hidden (view full) ---

1084 if (ic->ic_newassoc != NULL)
1085 ic->ic_newassoc(ni, 1);
1086 /* XXX not right for 802.1x/WPA */
1087 ieee80211_node_authorize(ni);
1088 }
1089 return ni;
1090}
1091
1092#ifdef IEEE80211_DEBUG
1093static void
1094dump_probe_beacon(u_int8_t subtype, int isnew,
1095 const u_int8_t mac[IEEE80211_ADDR_LEN],
1096 const struct ieee80211_scanparams *sp)
1097{
1098
1099 printf("[%s] %s%s on chan %u (bss chan %u) ",
1100 ether_sprintf(mac), isnew ? "new " : "",
1101 ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
1102 sp->chan, sp->bchan);
1103 ieee80211_print_essid(sp->ssid + 2, sp->ssid[1]);
1104 printf("\n");
1105
1106 if (isnew) {
1107 printf("[%s] caps 0x%x bintval %u erp 0x%x",
1108 ether_sprintf(mac), sp->capinfo, sp->bintval, sp->erp);
1109 if (sp->country != NULL) {
1110#ifdef __FreeBSD__
1111 printf(" country info %*D",
1112 sp->country[1], sp->country+2, " ");
1113#else
1114 int i;
1115 printf(" country info");
1116 for (i = 0; i < sp->country[1]; i++)
1117 printf(" %02x", sp->country[i+2]);
1118#endif
1119 }
1120 printf("\n");
1121 }
1122}
1123#endif /* IEEE80211_DEBUG */
1124
1125static void
1126saveie(u_int8_t **iep, const u_int8_t *ie)
1127{
1128
1129 if (ie == NULL)
1130 *iep = NULL;
1131 else
1132 ieee80211_saveie(iep, ie);
1133}
1134
1135/*
1136 * Process a beacon or probe response frame.
1137 */
1138void
1139ieee80211_add_scan(struct ieee80211com *ic,
1140 const struct ieee80211_scanparams *sp,
1141 const struct ieee80211_frame *wh,
1142 int subtype, int rssi, int rstamp)
1143{
1144#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1145 struct ieee80211_node_table *nt = &ic->ic_scan;
1146 struct ieee80211_node *ni;
1147 int newnode = 0;
1148
1149 ni = ieee80211_find_node(nt, wh->i_addr2);
1150 if (ni == NULL) {
1151 /*
1152 * Create a new entry.
1153 */
1154 ni = ic->ic_node_alloc(nt);
1155 if (ni == NULL) {
1156 ic->ic_stats.is_rx_nodealloc++;
1157 return;
1158 }
1159 ieee80211_setup_node(nt, ni, wh->i_addr2);
1160 /*
1161 * XXX inherit from ic_bss.
1162 */
1163 ni->ni_authmode = ic->ic_bss->ni_authmode;
1164 ni->ni_txpower = ic->ic_bss->ni_txpower;
1165 ni->ni_vlan = ic->ic_bss->ni_vlan; /* XXX?? */
1166 ieee80211_set_chan(ic, ni, ic->ic_curchan);
1167 ni->ni_rsn = ic->ic_bss->ni_rsn;
1168 newnode = 1;
1169 }
1170#ifdef IEEE80211_DEBUG
1171 if (ieee80211_msg_scan(ic) && (ic->ic_flags & IEEE80211_F_SCAN))
1172 dump_probe_beacon(subtype, newnode, wh->i_addr2, sp);
1173#endif
1174 /* XXX ap beaconing multiple ssid w/ same bssid */
1175 if (sp->ssid[1] != 0 &&
1176 (ISPROBE(subtype) || ni->ni_esslen == 0)) {
1177 ni->ni_esslen = sp->ssid[1];
1178 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1179 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);
1180 }
1181 ni->ni_scangen = ic->ic_scan.nt_scangen;
1182 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
1183 ni->ni_rssi = rssi;
1184 ni->ni_rstamp = rstamp;
1185 memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp));
1186 ni->ni_intval = sp->bintval;
1187 ni->ni_capinfo = sp->capinfo;
1188 ni->ni_chan = &ic->ic_channels[sp->chan];
1189 ni->ni_fhdwell = sp->fhdwell;
1190 ni->ni_fhindex = sp->fhindex;
1191 ni->ni_erp = sp->erp;
1192 if (sp->tim != NULL) {
1193 struct ieee80211_tim_ie *ie =
1194 (struct ieee80211_tim_ie *) sp->tim;
1195
1196 ni->ni_dtim_count = ie->tim_count;
1197 ni->ni_dtim_period = ie->tim_period;
1198 }
1199 /*
1200 * Record the byte offset from the mac header to
1201 * the start of the TIM information element for
1202 * use by hardware and/or to speedup software
1203 * processing of beacon frames.
1204 */
1205 ni->ni_timoff = sp->timoff;
1206 /*
1207 * Record optional information elements that might be
1208 * used by applications or drivers.
1209 */
1210 saveie(&ni->ni_wme_ie, sp->wme);
1211 saveie(&ni->ni_wpa_ie, sp->wpa);
1212
1213 /* NB: must be after ni_chan is setup */
1214 ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT);
1215
1216 if (!newnode)
1217 ieee80211_free_node(ni);
1218#undef ISPROBE
1219}
1220
1221/*
1222 * Do node discovery in adhoc mode on receipt of a beacon
1223 * or probe response frame. Note that for the driver's
1224 * benefit we we treat this like an association so the
1225 * driver has an opportunity to setup it's private state.
1226 */
1227struct ieee80211_node *
1228ieee80211_add_neighbor(struct ieee80211com *ic,
1229 const struct ieee80211_frame *wh,
1230 const struct ieee80211_scanparams *sp)
1231{
1232 struct ieee80211_node *ni;
1233
1234 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);/* XXX alloc_node? */
1235 if (ni != NULL) {
1236 ni->ni_esslen = sp->ssid[1];
1237 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);
1238 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
1239 memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp));
1240 ni->ni_intval = sp->bintval;
1241 ni->ni_capinfo = sp->capinfo;
1242 ni->ni_chan = ic->ic_bss->ni_chan;
1243 ni->ni_fhdwell = sp->fhdwell;
1244 ni->ni_fhindex = sp->fhindex;
1245 ni->ni_erp = sp->erp;
1246 ni->ni_timoff = sp->timoff;
1247 if (sp->wme != NULL)
1248 ieee80211_saveie(&ni->ni_wme_ie, sp->wme);
1249 if (sp->wpa != NULL)
1250 ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa);
1251
1252 /* NB: must be after ni_chan is setup */
1253 ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT);
1254
1255 if (ic->ic_newassoc != NULL)
1256 ic->ic_newassoc(ni, 1);
1257 /* XXX not right for 802.1x/WPA */
1258 ieee80211_node_authorize(ni);
1259 }
1260 return ni;
1261}
1262
1088#define IS_CTL(wh) \
1089 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
1090#define IS_PSPOLL(wh) \
1091 ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
1092/*
1093 * Locate the node for sender, track state, and then pass the
1094 * (referenced) node up to the 802.11 layer for its use. We
1095 * are required to pass some node so we fall back to ic_bss

--- 1057 unchanged lines hidden ---
1263#define IS_CTL(wh) \
1264 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
1265#define IS_PSPOLL(wh) \
1266 ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
1267/*
1268 * Locate the node for sender, track state, and then pass the
1269 * (referenced) node up to the 802.11 layer for its use. We
1270 * are required to pass some node so we fall back to ic_bss

--- 1057 unchanged lines hidden ---