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 --- |