#include <Ieee80211MgmtAP.h>
Public Types | |
enum | STAStatus { NOT_AUTHENTICATED, AUTHENTICATED, ASSOCIATED } |
typedef std::map< MACAddress, STAInfo, MAC_compare > | STAList |
Protected Member Functions | |
virtual int | numInitStages () const |
virtual void | initialize (int) |
virtual void | handleTimer (cMessage *msg) |
virtual void | handleUpperMessage (cPacket *msg) |
virtual void | handleCommand (int msgkind, cPolymorphic *ctrl) |
virtual void | receiveChangeNotification (int category, const cPolymorphic *details) |
virtual STAInfo * | lookupSenderSTA (Ieee80211ManagementFrame *frame) |
virtual void | sendManagementFrame (Ieee80211ManagementFrame *frame, const MACAddress &destAddr) |
virtual void | sendBeacon () |
Processing of different frame types | |
virtual void | handleDataFrame (Ieee80211DataFrame *frame) |
virtual void | handleAuthenticationFrame (Ieee80211AuthenticationFrame *frame) |
virtual void | handleDeauthenticationFrame (Ieee80211DeauthenticationFrame *frame) |
virtual void | handleAssociationRequestFrame (Ieee80211AssociationRequestFrame *frame) |
virtual void | handleAssociationResponseFrame (Ieee80211AssociationResponseFrame *frame) |
virtual void | handleReassociationRequestFrame (Ieee80211ReassociationRequestFrame *frame) |
virtual void | handleReassociationResponseFrame (Ieee80211ReassociationResponseFrame *frame) |
virtual void | handleDisassociationFrame (Ieee80211DisassociationFrame *frame) |
virtual void | handleBeaconFrame (Ieee80211BeaconFrame *frame) |
virtual void | handleProbeRequestFrame (Ieee80211ProbeRequestFrame *frame) |
virtual void | handleProbeResponseFrame (Ieee80211ProbeResponseFrame *frame) |
Protected Attributes | |
std::string | ssid |
int | channelNumber |
simtime_t | beaconInterval |
int | numAuthSteps |
Ieee80211SupportedRatesElement | supportedRates |
STAList | staList |
list of STAs | |
cMessage * | beaconTimer |
Classes | |
struct | MAC_compare |
struct | STAInfo |
typedef std::map<MACAddress,STAInfo, MAC_compare> Ieee80211MgmtAP::STAList |
virtual int Ieee80211MgmtAP::numInitStages | ( | ) | const [inline, protected, virtual] |
void Ieee80211MgmtAP::initialize | ( | int | stage | ) | [protected, virtual] |
Reimplemented from Ieee80211MgmtAPBase.
00035 { 00036 Ieee80211MgmtAPBase::initialize(stage); 00037 00038 if (stage==0) 00039 { 00040 // read params and init vars 00041 ssid = par("ssid").stringValue(); 00042 beaconInterval = par("beaconInterval"); 00043 numAuthSteps = par("numAuthSteps"); 00044 if (numAuthSteps!=2 && numAuthSteps!=4) 00045 error("parameter 'numAuthSteps' (number of frames exchanged during authentication) must be 2 or 4, not %d", numAuthSteps); 00046 channelNumber = -1; // value will arrive from physical layer in receiveChangeNotification() 00047 WATCH(ssid); 00048 WATCH(channelNumber); 00049 WATCH(beaconInterval); 00050 WATCH(numAuthSteps); 00051 WATCH_MAP(staList); 00052 00053 //TBD fill in supportedRates 00054 00055 // subscribe for notifications 00056 NotificationBoard *nb = NotificationBoardAccess().get(); 00057 nb->subscribe(this, NF_RADIO_CHANNEL_CHANGED); 00058 00059 // start beacon timer (randomize startup time) 00060 beaconTimer = new cMessage("beaconTimer"); 00061 scheduleAt(simTime()+uniform(0,beaconInterval), beaconTimer); 00062 } 00063 }
void Ieee80211MgmtAP::handleTimer | ( | cMessage * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
00066 { 00067 if (msg==beaconTimer) 00068 { 00069 sendBeacon(); 00070 scheduleAt(simTime()+beaconInterval, beaconTimer); 00071 } 00072 else 00073 { 00074 error("internal error: unrecognized timer '%s'", msg->getName()); 00075 } 00076 }
void Ieee80211MgmtAP::handleUpperMessage | ( | cPacket * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
00079 { 00080 // must be an EtherFrame frame arriving from MACRelayUnit, that is, 00081 // bridged from another interface of the AP (probably Ethernet). 00082 EtherFrame *etherframe = check_and_cast<EtherFrame *>(msg); 00083 00084 // check we really have a STA with that dest address 00085 STAList::iterator it = staList.find(etherframe->getDest()); 00086 if (it==staList.end() || it->second.status!=ASSOCIATED) 00087 { 00088 EV << "STA with MAC address " << etherframe->getDest() << " not associated with this AP, dropping frame\n"; 00089 delete etherframe; // XXX count drops? 00090 return; 00091 } 00092 00093 // convert Ethernet frame 00094 Ieee80211DataFrame *frame = convertFromEtherFrame(etherframe); 00095 sendOrEnqueue(frame); 00096 }
void Ieee80211MgmtAP::handleCommand | ( | int | msgkind, | |
cPolymorphic * | ctrl | |||
) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method -- throws an error (no commands supported)
Implements Ieee80211MgmtBase.
void Ieee80211MgmtAP::receiveChangeNotification | ( | int | category, | |
const cPolymorphic * | details | |||
) | [protected, virtual] |
Called by the NotificationBoard whenever a change occurs we're interested in
Implements INotifiable.
00104 { 00105 Enter_Method_Silent(); 00106 printNotificationBanner(category, details); 00107 00108 if (category == NF_RADIO_CHANNEL_CHANGED) 00109 { 00110 EV << "updating channel number\n"; 00111 channelNumber = check_and_cast<RadioState *>(details)->getChannelNumber(); 00112 } 00113 }
Ieee80211MgmtAP::STAInfo * Ieee80211MgmtAP::lookupSenderSTA | ( | Ieee80211ManagementFrame * | frame | ) | [protected, virtual] |
Utility function: return sender STA's entry from our STA list, or NULL if not in there
Referenced by handleAssociationRequestFrame(), handleAuthenticationFrame(), handleDeauthenticationFrame(), handleDisassociationFrame(), and handleReassociationRequestFrame().
00116 { 00117 STAList::iterator it = staList.find(frame->getTransmitterAddress()); 00118 return it==staList.end() ? NULL : &(it->second); 00119 }
void Ieee80211MgmtAP::sendManagementFrame | ( | Ieee80211ManagementFrame * | frame, | |
const MACAddress & | destAddr | |||
) | [protected, virtual] |
Utility function: set fields in the given frame and send it out to the address
Referenced by handleAssociationRequestFrame(), handleAuthenticationFrame(), handleProbeRequestFrame(), and handleReassociationRequestFrame().
00122 { 00123 frame->setFromDS(true); 00124 frame->setReceiverAddress(destAddr); 00125 frame->setAddress3(myAddress); 00126 sendOrEnqueue(frame); 00127 }
void Ieee80211MgmtAP::sendBeacon | ( | ) | [protected, virtual] |
Utility function: creates and sends a beacon frame
Referenced by handleTimer().
00130 { 00131 EV << "Sending beacon\n"; 00132 Ieee80211BeaconFrame *frame = new Ieee80211BeaconFrame("Beacon"); 00133 Ieee80211BeaconFrameBody& body = frame->getBody(); 00134 body.setSSID(ssid.c_str()); 00135 body.setSupportedRates(supportedRates); 00136 body.setBeaconInterval(beaconInterval); 00137 body.setChannelNumber(channelNumber); 00138 00139 frame->setReceiverAddress(MACAddress::BROADCAST_ADDRESS); 00140 frame->setFromDS(true); 00141 00142 sendOrEnqueue(frame); 00143 }
void Ieee80211MgmtAP::handleDataFrame | ( | Ieee80211DataFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00146 { 00147 // check toDS bit 00148 if (!frame->getToDS()) 00149 { 00150 // looks like this is not for us - discard 00151 EV << "Frame is not for us (toDS=false) -- discarding\n"; 00152 delete frame; 00153 return; 00154 } 00155 00156 // handle broadcast frames 00157 if (frame->getAddress3().isBroadcast()) 00158 { 00159 EV << "Handling broadcast frame\n"; 00160 if (hasRelayUnit) 00161 send(convertToEtherFrame((Ieee80211DataFrame *)frame->dup()), "uppergateOut"); 00162 distributeReceivedDataFrame(frame); 00163 return; 00164 } 00165 00166 // look up destination address in our STA list 00167 STAList::iterator it = staList.find(frame->getAddress3()); 00168 if (it==staList.end()) 00169 { 00170 // not our STA -- pass up frame to relayUnit for LAN bridging if we have one 00171 if (hasRelayUnit) 00172 send(convertToEtherFrame(frame), "uppergateOut"); 00173 else { 00174 EV << "Frame's destination address is not in our STA list -- dropping frame\n"; 00175 delete frame; 00176 } 00177 } 00178 else 00179 { 00180 // dest address is our STA, but is it already associated? 00181 if (it->second.status == ASSOCIATED) 00182 distributeReceivedDataFrame(frame); // send it out to the destination STA 00183 else { 00184 EV << "Frame's destination STA is not in associated state -- dropping frame\n"; 00185 delete frame; 00186 } 00187 } 00188 }
void Ieee80211MgmtAP::handleAuthenticationFrame | ( | Ieee80211AuthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00191 { 00192 int frameAuthSeq = frame->getBody().getSequenceNumber(); 00193 EV << "Processing Authentication frame, seqNum=" << frameAuthSeq << "\n"; 00194 00195 // create STA entry if needed 00196 STAInfo *sta = lookupSenderSTA(frame); 00197 if (!sta) 00198 { 00199 MACAddress staAddress = frame->getTransmitterAddress(); 00200 sta = &staList[staAddress]; // this implicitly creates a new entry 00201 sta->address = staAddress; 00202 sta->status = NOT_AUTHENTICATED; 00203 sta->authSeqExpected = 1; 00204 } 00205 00206 // check authentication sequence number is OK 00207 if (frameAuthSeq != sta->authSeqExpected) 00208 { 00209 // wrong sequence number: send error and return 00210 EV << "Wrong sequence number, " << sta->authSeqExpected << " expected\n"; 00211 Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame("Auth-ERROR"); 00212 resp->getBody().setStatusCode(SC_AUTH_OUT_OF_SEQ); 00213 sendManagementFrame(resp, frame->getTransmitterAddress()); 00214 delete frame; 00215 sta->authSeqExpected = 1; // go back to start square 00216 return; 00217 } 00218 00219 // station is authenticated if it made it through the required number of steps 00220 bool isLast = (frameAuthSeq+1 == numAuthSteps); 00221 00222 // send OK response (we don't model the cryptography part, just assume 00223 // successful authentication every time) 00224 EV << "Sending Authentication frame, seqNum=" << (frameAuthSeq+1) << "\n"; 00225 Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame(isLast ? "Auth-OK" : "Auth"); 00226 resp->getBody().setSequenceNumber(frameAuthSeq+1); 00227 resp->getBody().setStatusCode(SC_SUCCESSFUL); 00228 resp->getBody().setIsLast(isLast); 00229 // XXX frame length could be increased to account for challenge text length etc. 00230 sendManagementFrame(resp, frame->getTransmitterAddress()); 00231 00232 delete frame; 00233 00234 // update status 00235 if (isLast) 00236 { 00237 sta->status = AUTHENTICATED; // XXX only when ACK of this frame arrives 00238 EV << "STA authenticated\n"; 00239 } 00240 else 00241 { 00242 sta->authSeqExpected += 2; 00243 EV << "Expecting Authentication frame " << sta->authSeqExpected << "\n"; 00244 } 00245 }
void Ieee80211MgmtAP::handleDeauthenticationFrame | ( | Ieee80211DeauthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00248 { 00249 EV << "Processing Deauthentication frame\n"; 00250 00251 STAInfo *sta = lookupSenderSTA(frame); 00252 delete frame; 00253 00254 if (sta) 00255 { 00256 // mark STA as not authenticated; alternatively, it could also be removed from staList 00257 sta->status = NOT_AUTHENTICATED; 00258 sta->authSeqExpected = 1; 00259 } 00260 }
void Ieee80211MgmtAP::handleAssociationRequestFrame | ( | Ieee80211AssociationRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00263 { 00264 EV << "Processing AssociationRequest frame\n"; 00265 00266 // "11.3.2 AP association procedures" 00267 STAInfo *sta = lookupSenderSTA(frame); 00268 if (!sta || sta->status==NOT_AUTHENTICATED) 00269 { 00270 // STA not authenticated: send error and return 00271 Ieee80211DeauthenticationFrame *resp = new Ieee80211DeauthenticationFrame("Deauth"); 00272 resp->getBody().setReasonCode(RC_NONAUTH_ASS_REQUEST); 00273 sendManagementFrame(resp, frame->getTransmitterAddress()); 00274 delete frame; 00275 return; 00276 } 00277 00278 delete frame; 00279 00280 // mark STA as associated 00281 sta->status = ASSOCIATED; // XXX this should only take place when MAC receives the ACK for the response 00282 00283 // send OK response 00284 Ieee80211AssociationResponseFrame *resp = new Ieee80211AssociationResponseFrame("AssocResp-OK"); 00285 Ieee80211AssociationResponseFrameBody& body = resp->getBody(); 00286 body.setStatusCode(SC_SUCCESSFUL); 00287 body.setAid(0); //XXX 00288 body.setSupportedRates(supportedRates); 00289 sendManagementFrame(resp, sta->address); 00290 }
void Ieee80211MgmtAP::handleAssociationResponseFrame | ( | Ieee80211AssociationResponseFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtAP::handleReassociationRequestFrame | ( | Ieee80211ReassociationRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00298 { 00299 EV << "Processing ReassociationRequest frame\n"; 00300 00301 // "11.3.4 AP reassociation procedures" -- almost the same as AssociationRequest processing 00302 STAInfo *sta = lookupSenderSTA(frame); 00303 if (!sta || sta->status==NOT_AUTHENTICATED) 00304 { 00305 // STA not authenticated: send error and return 00306 Ieee80211DeauthenticationFrame *resp = new Ieee80211DeauthenticationFrame("Deauth"); 00307 resp->getBody().setReasonCode(RC_NONAUTH_ASS_REQUEST); 00308 sendManagementFrame(resp, frame->getTransmitterAddress()); 00309 delete frame; 00310 return; 00311 } 00312 00313 delete frame; 00314 00315 // mark STA as associated 00316 sta->status = ASSOCIATED; // XXX this should only take place when MAC receives the ACK for the response 00317 00318 // send OK response 00319 Ieee80211ReassociationResponseFrame *resp = new Ieee80211ReassociationResponseFrame("ReassocResp-OK"); 00320 Ieee80211ReassociationResponseFrameBody& body = resp->getBody(); 00321 body.setStatusCode(SC_SUCCESSFUL); 00322 body.setAid(0); //XXX 00323 body.setSupportedRates(supportedRates); 00324 sendManagementFrame(resp, sta->address); 00325 }
void Ieee80211MgmtAP::handleReassociationResponseFrame | ( | Ieee80211ReassociationResponseFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtAP::handleDisassociationFrame | ( | Ieee80211DisassociationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00333 { 00334 STAInfo *sta = lookupSenderSTA(frame); 00335 delete frame; 00336 00337 if (sta) 00338 { 00339 sta->status = AUTHENTICATED; 00340 } 00341 }
void Ieee80211MgmtAP::handleBeaconFrame | ( | Ieee80211BeaconFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtAP::handleProbeRequestFrame | ( | Ieee80211ProbeRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00349 { 00350 EV << "Processing ProbeRequest frame\n"; 00351 00352 if (strcmp(frame->getBody().getSSID(),"")!=0 && strcmp(frame->getBody().getSSID(), ssid.c_str())!=0) 00353 { 00354 EV << "SSID `" << frame->getBody().getSSID() << "' does not match, ignoring frame\n"; 00355 dropManagementFrame(frame); 00356 return; 00357 } 00358 00359 MACAddress staAddress = frame->getTransmitterAddress(); 00360 delete frame; 00361 00362 EV << "Sending ProbeResponse frame\n"; 00363 Ieee80211ProbeResponseFrame *resp = new Ieee80211ProbeResponseFrame("ProbeResp"); 00364 Ieee80211ProbeResponseFrameBody& body = resp->getBody(); 00365 body.setSSID(ssid.c_str()); 00366 body.setSupportedRates(supportedRates); 00367 body.setBeaconInterval(beaconInterval); 00368 body.setChannelNumber(channelNumber); 00369 sendManagementFrame(resp, staAddress); 00370 }
void Ieee80211MgmtAP::handleProbeResponseFrame | ( | Ieee80211ProbeResponseFrame * | frame | ) | [protected, virtual] |
std::string Ieee80211MgmtAP::ssid [protected] |
Referenced by handleProbeRequestFrame(), initialize(), and sendBeacon().
int Ieee80211MgmtAP::channelNumber [protected] |
Referenced by handleProbeRequestFrame(), initialize(), receiveChangeNotification(), and sendBeacon().
simtime_t Ieee80211MgmtAP::beaconInterval [protected] |
Referenced by handleProbeRequestFrame(), handleTimer(), initialize(), and sendBeacon().
int Ieee80211MgmtAP::numAuthSteps [protected] |
Referenced by handleAuthenticationFrame(), and initialize().
Ieee80211SupportedRatesElement Ieee80211MgmtAP::supportedRates [protected] |
STAList Ieee80211MgmtAP::staList [protected] |
list of STAs
Referenced by handleAuthenticationFrame(), handleDataFrame(), handleUpperMessage(), initialize(), and lookupSenderSTA().
cMessage* Ieee80211MgmtAP::beaconTimer [protected] |
Referenced by handleTimer(), and initialize().