am930mgr.c
来自「Linux Wireless LAN Project 的目标是开发一个完整的」· C语言 代码 · 共 2,470 行 · 第 1/5 页
C
2,470 行
return; } /* Basic Rate Check */ if ( !am930mgr_rates_basicissubset( mgr, (wlan_ie_supp_rates_t*)mgr->mac->oprates, f.supp_rates) ) { /* mismatch in basic rates */ pb = am930mgr_mkfrm_assocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_ASSOC_DENIED_RATES, 0, /* AID */ (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Made it! we're now ready to handle success! */ if ( (sta->sta.listen_int = ieee2host16(*f.listen_int)) ) { sta->sta.info |= WLAN_STA_INFO_PSMODE; } if ( WLAN_GET_MGMT_CAP_INFO_PRIVACY(ieee2host16(*f.cap_info)) ) { sta->sta.info |= WLAN_STA_INFO_WEPON; } sta->sta.rate = sta->sta.max_rate = am930mgr_rates_max(f.supp_rates); sta->sta.info |= WLAN_STA_INFO_ASSOC; pb = am930mgr_mkfrm_assocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_SUCCESS, sta->sta.aid | BIT14 | BIT15, (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_assocresp_rx** Handle incoming association response frames** returns: nothing for now----------------------------------------------------------------*/void am930mgr_assocresp_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ wlan_fr_assocresp_t f; DBFENTER; /* We better be assoc pending, otherwise ignore it */ if ( mgr->mac->state == AM930_MACSTATE_ASSOCPENDING ) { /* decode the frame */ f.len = rxpb->p80211buflen - WLAN_CRC_LEN; f.buf = rxpb->p80211buf; wlan_mgmt_decode_assocresp(&f); /* save values and set mode */ if ( ieee2host16(*(f.status)) == WLAN_MGMT_STATUS_SUCCESS ) { mgr->curr_aid = ieee2host16(*(f.aid)); mgr->mac->state = AM930_MACSTATE_ASSOC; if ( (mgr->curr_aid >> 14) != (BIT0 | BIT1) ) { WLAN_LOG_WARNING0("AID from AP, has two msb clear.\n"); } WLAN_LOG_NOTICE1( "Association Successful, AID=%d.\n", mgr->curr_aid & ~(BIT14|BIT15)); am930llc_cmdcomplete(mgr->mac->llc, 0); } else { /* jump back to the auth state and indicate the error */ mgr->mac->state = AM930_MACSTATE_AUTH; am930mgr_prstatus(mgr, ieee2host16(*(f.status)) ); am930llc_cmdcomplete(mgr->mac->llc, ieee2host16(*(f.status)) ); } } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_auth_begin_sta** Start the station authentication procedure. Namely, send an* auth frame to the AP.** returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen_begin_sta(am930mgr_t *mgr, UINT16 authalg){ wlan_fr_authen_t *f; wlan_pb_t *pb; DBFENTER; /* initial setup of frame */ pb = am930shim_pballoc(); if (pb != NULL ) { f = kmalloc( sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN, GFP_ATOMIC ); if ( f != NULL ) { memset( f, 0, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN); f->buf = ((UINT8*)f) + sizeof(wlan_fr_authen_t); f->len = WLAN_AUTHEN_FR_MAXLEN; wlan_mgmt_encode_authen(f); /* insert values */ f->hdr->a3.fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)); memcpy( f->hdr->a3.a1, mgr->curr_bssid, WLAN_BSSID_LEN); memcpy( f->hdr->a3.a2, mgr->hw->addr, WLAN_ADDR_LEN); memcpy( f->hdr->a3.a3, mgr->curr_bssid, WLAN_BSSID_LEN); *(f->auth_alg) = host2ieee16(authalg); *(f->auth_seq) = host2ieee16(1); /* now copy the constructed frame to a pb and tx */ am930shim_pballoc_p80211( pb, f->len); /* bogus: add 4 because pballoc assumes rx+FCS and subtracts 4 */ pb->p80211_payloadlen += 4; if ( pb->p80211hostbuf != NULL ) /* note silent failure */ { memcpy( pb->p80211buf, f->buf, f->len); /* send the frame */ am930mac_txmac( mgr->mac, pb); mgr->mac->state = AM930_MACSTATE_AUTHPENDING; } else { am930shim_pbfree( pb ); } /* the response(s) will be handled in auth_rx */ kfree_s( f, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN); } } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_authen_stop** Clear the auth pending state.** returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen_stop( am930mgr_t *mgr ){ mgr->mac->state = AM930_MACSTATE_NOAUTH;}/*----------------------------------------------------------------* am930mgr_authen_rx** Handle incoming authentication frames** returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ wlan_fr_authen_t f; DBFENTER; /* we better be an AP or a STA in AUTHPENDING otherwise ignore */ if ( !(mgr->mac->mode == AM930_MACMODE_ESS_AP || mgr->mac->state == AM930_MACSTATE_AUTHPENDING) ) { return; } /* OK, we're in an OK mode and state, if it's encrypted, decrypt */ if ( rxpb->wep_iscrypt ) { if ( (rxpb = am930mac_wep_decrypt( mgr->mac, rxpb)) == NULL ) { WLAN_LOG_NOTICE0("authen_rx: rx'd undecryptable frame\n"); return; } } /* decode the frame */ f.len = rxpb->p80211buflen - WLAN_CRC_LEN; f.buf = rxpb->p80211buf; wlan_mgmt_decode_authen(&f); switch ( ieee2host16(*(f.auth_seq )) ) { case 1: am930mgr_authen1_rx( mgr, &f); break; case 2: am930mgr_authen2_rx( mgr, &f); break; case 3: am930mgr_authen3_rx( mgr, &f); break; case 4: am930mgr_authen4_rx( mgr, &f); break; default: WLAN_LOG_WARNING1("f.auth_seq not in [1234], seq = %d\n", ieee2host16(*(f.auth_seq))); break; } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_authen1_rx** Handles incoming authen frames with sequence 1. Currently * assumes we're an AP. So far, no one appears to use authentication* in Ad-Hoc mode.** returns: nothing.----------------------------------------------------------------*/void am930mgr_authen1_rx( am930mgr_t *mgr, wlan_fr_authen_t *f ){ wlan_stable_item_t *sta; wlan_pb_t *pb; DBFENTER; /* Check to make sure we support the requested alg */ if ( ((ieee2host16(*(f->auth_alg)) == WLAN_AUTH_ALG_SHAREDKEY) && (mgr->mac->privacy_invoked == 0)) || ((ieee2host16(*(f->auth_alg)) != WLAN_AUTH_ALG_SHAREDKEY) && (ieee2host16(*(f->auth_alg)) != WLAN_AUTH_ALG_OPENSYSTEM)) ) { /* we haven't any wep keys and can't do SHAREDKEY _or_ */ /* the STA has asked for an alg we know nothing about */ pb = am930mgr_mkfrm_auth( mgr, f->hdr->a3.a2, ieee2host16(*(f->auth_alg)), 2, WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG, NULL ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Check for the sender station in our stable */ sta = am930mgr_stable_lookup( mgr, f->hdr->a3.a2); if ( sta != NULL ) { /* Change it's state to PENDING and mark authenticated */ sta->sta.state = WLAN_STA_STATE_PENDING_ACTIVE; sta->sta.info |= WLAN_STA_INFO_AUTH; sta->sta.timeout = jiffies + mgr->mgmt_trans_timeout; sta->sta.timer_state = WLAN_STA_TSTATE_AUTH; } else { /* It's a new one, allocate and add to stable */ sta = kmalloc( sizeof(wlan_stable_item_t), GFP_ATOMIC); if ( sta != NULL ) { memset( sta, 0, sizeof(wlan_stable_item_t)); memcpy( sta->sta.addr, f->hdr->a3.a2, WLAN_ADDR_LEN); sta->sta.state = WLAN_STA_STATE_PENDING_ACTIVE; sta->sta.info |= WLAN_STA_INFO_AUTH; sta->sta.timeout = jiffies + mgr->mgmt_trans_timeout; if ( (sta->sta.aid = am930mgr_stable_alloc_aid(mgr, sta)) > 0 ) { am930mgr_stable_insert( mgr, sta); } else { /* Can't alloc an AID, tell the STA it can't authenticate */ pb = am930mgr_mkfrm_auth( mgr, f->hdr->a3.a2, ieee2host16(*(f->auth_alg)), 2, WLAN_MGMT_STATUS_UNSPEC_FAILURE, NULL ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } am930shim_free(sta, sizeof(wlan_stable_item_t)); return; } } } /* At this point, we've got a sta in the stable and we support the alg */ /* time to send a SUCCESS response */ if (ieee2host16(*(f->auth_alg)) == WLAN_AUTH_ALG_OPENSYSTEM ) { pb = am930mgr_mkfrm_auth( mgr, f->hdr->a3.a2, ieee2host16(*(f->auth_alg)), 2, WLAN_MGMT_STATUS_SUCCESS, NULL ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } /* No more pending, this guy's authenticated */ sta->sta.state = WLAN_STA_STATE_ACTIVE; sta->sta.timeout = jiffies; sta->sta.timer_state = 0; } else { UINT8 ctext[WLAN_CHALLENGE_LEN]; /* Shared key (alg num validated previously) */ am930mgr_mkchallengetext( mgr, ctext, WLAN_CHALLENGE_LEN, mgr->challengekey, sizeof(mgr->challengekey)); pb = am930mgr_mkfrm_auth( mgr, f->hdr->a3.a2, ieee2host16(*(f->auth_alg)), 2, WLAN_MGMT_STATUS_SUCCESS, ctext ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_authen2_rx** Handles incoming auth frames with sequence number 2. Currently* assumes we're a station.** returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen2_rx( am930mgr_t *mgr, wlan_fr_authen_t *f ){ DBFENTER; switch (ieee2host16(*(f->auth_alg))) { case WLAN_AUTH_ALG_OPENSYSTEM: if ( ieee2host16(*(f->status)) == WLAN_MGMT_STATUS_SUCCESS ) { WLAN_LOG_NOTICE0("802.11 Authen (OPEN) Successful.\n"); mgr->mac->state = AM930_MACSTATE_AUTH; am930llc_cmdcomplete(mgr->mac->llc, ieee2host16(*(f->status))); } else { WLAN_LOG_NOTICE0("802.11 Authen (OPEN) Failed.\n"); am930mgr_prstatus(mgr, ieee2host16(*(f->status)) ); mgr->mac->state = AM930_MACSTATE_NOAUTH; am930llc_cmdcomplete(mgr->mac->llc, ieee2host16(*(f->status))); } break;#ifdef TODO_WEP case WLAN_AUTH_ALG_SHAREDKEY: { wlan_fr_authen_t *reply; wlan_pb_t *pb; /* Initial setup of response frame */ pb = am930shim_pballoc(); if (pb != NULL ) { reply = kmalloc( sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN, GFP_ATOMIC ); if ( reply != NULL ) { memset( reply, 0, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN); /* Set up the reply frame */ reply->buf = ((UINT8*)reply) + sizeof(wlan_fr_authen_t); reply->len = WLAN_AUTHEN_FR_MAXLEN; wlan_mgmt_encode_authen(reply); /* insert values */ reply->hdr->a3.fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)); memcpy( reply->hdr->a3.a1, f->hdr->a3.a2, WLAN_BSSID_LEN); memcpy( reply->hdr->a3.a2, mgr->hw->addr, WLAN_ADDR_LEN); memcpy( reply->hdr->a3.a3, mgr->curr_bssid, WLAN_BSSID_LEN); *(reply->auth_alg) = *(f->auth_alg); *(reply->auth_seq) = host2ieee16(3); *(reply->status) = host2ieee16(WLAN_MGMT_STATUS_SUCCESS); reply->challenge = (wlan_ie_challenge_t*)reply->buf + reply->len; reply->len += WLAN_CHALLENGE_IE_LEN; reply->challenge->eid = WLAN_EID_CHALLENGE; reply->challenge->len = WLAN_CHALLENGE_LEN; memcpy( reply->challenge->challenge, f->challenge->challenge, WLAN_CHALLENGE_LEN); /* now copy the constructed frame to a pb and tx */ am930shim_pballoc_p80211( pb, reply->len); if ( pb->p80211hostbuf != NULL ) /* note silent failure */ { memcpy( pb->p80211buf, reply->buf, reply->len); am930mac_wep_encrypt( mgr->mac, pb ); /* send the frame */ am930mac_txmac( mgr->mac, pb); } else { am930shim_pbfree( pb ); } /* discard the buffer */ kfree_s( reply, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN); } } break; }#endif /* TODO_WEP */ default: WLAN_LOG_WARNING1("rx'd auth.seq = 2 unknown auth_alg=%d\n", ieee2host16(*(f->auth_alg)) ); break; } DBFEXIT;}/*----------------------------------------------------------------* am930mgr_authen3_rx** Handles incoming authen frames with sequence 3. Currently * assumes we're an AP. This function assumes the frame has* already been successfully decrypted.** returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen3_rx( am930mgr_t *mgr, wlan_fr_authen_t *f ){ UINT8 ctext[WLAN_CHALLENGE_LEN]; wlan_pb_t *pb; wlan_stable_item_t *sta; DBFENTER; /* First, find out if we're in a auth exchange w/ sender */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?