Ieee80211MgmtAP Class Reference

#include <Ieee80211MgmtAP.h>

Inheritance diagram for Ieee80211MgmtAP:

Ieee80211MgmtAPBase Ieee80211MgmtBase PassiveQueueBase INotifiable IPassiveQueue

List of all members.


Detailed Description

Used in 802.11 infrastructure mode: handles management frames for an access point (AP). See corresponding NED file for a detailed description.

Author:
Andras Varga

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

Member Typedef Documentation


Member Enumeration Documentation

State of a STA

Enumerator:
NOT_AUTHENTICATED 
AUTHENTICATED 
ASSOCIATED 


Member Function Documentation

virtual int Ieee80211MgmtAP::numInitStages (  )  const [inline, protected, virtual]

Reimplemented from Ieee80211MgmtAPBase.

00066 {return 2;}

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.

00099 {
00100     error("handleCommand(): no commands supported");
00101 }

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]

Implements Ieee80211MgmtBase.

00293 {
00294     dropManagementFrame(frame);
00295 }

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]

Implements Ieee80211MgmtBase.

00328 {
00329     dropManagementFrame(frame);
00330 }

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]

Implements Ieee80211MgmtBase.

00344 {
00345     dropManagementFrame(frame);
00346 }

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]

Implements Ieee80211MgmtBase.

00373 {
00374     dropManagementFrame(frame);
00375 }


Member Data Documentation

std::string Ieee80211MgmtAP::ssid [protected]

simtime_t Ieee80211MgmtAP::beaconInterval [protected]

Ieee80211SupportedRatesElement Ieee80211MgmtAP::supportedRates [protected]

cMessage* Ieee80211MgmtAP::beaconTimer [protected]

Referenced by handleTimer(), and initialize().


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5