INET Framework for OMNeT++/OMNEST
|
#include <Ieee80211MgmtAP.h>
Classes | |
struct | MAC_compare |
struct | STAInfo |
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 |
Used in 802.11 infrastructure mode: handles management frames for an access point (AP). See corresponding NED file for a detailed description.
typedef std::map<MACAddress,STAInfo, MAC_compare> Ieee80211MgmtAP::STAList |
State of a STA
void Ieee80211MgmtAP::handleAssociationRequestFrame | ( | Ieee80211AssociationRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Processing AssociationRequest frame\n"; // "11.3.2 AP association procedures" STAInfo *sta = lookupSenderSTA(frame); if (!sta || sta->status==NOT_AUTHENTICATED) { // STA not authenticated: send error and return Ieee80211DeauthenticationFrame *resp = new Ieee80211DeauthenticationFrame("Deauth"); resp->getBody().setReasonCode(RC_NONAUTH_ASS_REQUEST); sendManagementFrame(resp, frame->getTransmitterAddress()); delete frame; return; } delete frame; // mark STA as associated sta->status = ASSOCIATED; // XXX this should only take place when MAC receives the ACK for the response // send OK response Ieee80211AssociationResponseFrame *resp = new Ieee80211AssociationResponseFrame("AssocResp-OK"); Ieee80211AssociationResponseFrameBody& body = resp->getBody(); body.setStatusCode(SC_SUCCESSFUL); body.setAid(0); //XXX body.setSupportedRates(supportedRates); sendManagementFrame(resp, sta->address); }
void Ieee80211MgmtAP::handleAssociationResponseFrame | ( | Ieee80211AssociationResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtAP::handleAuthenticationFrame | ( | Ieee80211AuthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ int frameAuthSeq = frame->getBody().getSequenceNumber(); EV << "Processing Authentication frame, seqNum=" << frameAuthSeq << "\n"; // create STA entry if needed STAInfo *sta = lookupSenderSTA(frame); if (!sta) { MACAddress staAddress = frame->getTransmitterAddress(); sta = &staList[staAddress]; // this implicitly creates a new entry sta->address = staAddress; sta->status = NOT_AUTHENTICATED; sta->authSeqExpected = 1; } // check authentication sequence number is OK if (frameAuthSeq != sta->authSeqExpected) { // wrong sequence number: send error and return EV << "Wrong sequence number, " << sta->authSeqExpected << " expected\n"; Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame("Auth-ERROR"); resp->getBody().setStatusCode(SC_AUTH_OUT_OF_SEQ); sendManagementFrame(resp, frame->getTransmitterAddress()); delete frame; sta->authSeqExpected = 1; // go back to start square return; } // station is authenticated if it made it through the required number of steps bool isLast = (frameAuthSeq+1 == numAuthSteps); // send OK response (we don't model the cryptography part, just assume // successful authentication every time) EV << "Sending Authentication frame, seqNum=" << (frameAuthSeq+1) << "\n"; Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame(isLast ? "Auth-OK" : "Auth"); resp->getBody().setSequenceNumber(frameAuthSeq+1); resp->getBody().setStatusCode(SC_SUCCESSFUL); resp->getBody().setIsLast(isLast); // XXX frame length could be increased to account for challenge text length etc. sendManagementFrame(resp, frame->getTransmitterAddress()); delete frame; // update status if (isLast) { sta->status = AUTHENTICATED; // XXX only when ACK of this frame arrives EV << "STA authenticated\n"; } else { sta->authSeqExpected += 2; EV << "Expecting Authentication frame " << sta->authSeqExpected << "\n"; } }
void Ieee80211MgmtAP::handleBeaconFrame | ( | Ieee80211BeaconFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtAP::handleCommand | ( | int | msgkind, |
cPolymorphic * | ctrl | ||
) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method -- throws an error (no commands supported)
Implements Ieee80211MgmtBase.
{
error("handleCommand(): no commands supported");
}
void Ieee80211MgmtAP::handleDataFrame | ( | Ieee80211DataFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ // check toDS bit if (!frame->getToDS()) { // looks like this is not for us - discard EV << "Frame is not for us (toDS=false) -- discarding\n"; delete frame; return; } // handle broadcast frames if (frame->getAddress3().isBroadcast()) { EV << "Handling broadcast frame\n"; if (hasRelayUnit) send(convertToEtherFrame((Ieee80211DataFrame *)frame->dup()), "uppergateOut"); distributeReceivedDataFrame(frame); return; } // look up destination address in our STA list STAList::iterator it = staList.find(frame->getAddress3()); if (it==staList.end()) { // not our STA -- pass up frame to relayUnit for LAN bridging if we have one if (hasRelayUnit) send(convertToEtherFrame(frame), "uppergateOut"); else { EV << "Frame's destination address is not in our STA list -- dropping frame\n"; delete frame; } } else { // dest address is our STA, but is it already associated? if (it->second.status == ASSOCIATED) distributeReceivedDataFrame(frame); // send it out to the destination STA else { EV << "Frame's destination STA is not in associated state -- dropping frame\n"; delete frame; } } }
void Ieee80211MgmtAP::handleDeauthenticationFrame | ( | Ieee80211DeauthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Processing Deauthentication frame\n"; STAInfo *sta = lookupSenderSTA(frame); delete frame; if (sta) { // mark STA as not authenticated; alternatively, it could also be removed from staList sta->status = NOT_AUTHENTICATED; sta->authSeqExpected = 1; } }
void Ieee80211MgmtAP::handleDisassociationFrame | ( | Ieee80211DisassociationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ STAInfo *sta = lookupSenderSTA(frame); delete frame; if (sta) { sta->status = AUTHENTICATED; } }
void Ieee80211MgmtAP::handleProbeRequestFrame | ( | Ieee80211ProbeRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Processing ProbeRequest frame\n"; if (strcmp(frame->getBody().getSSID(),"")!=0 && strcmp(frame->getBody().getSSID(), ssid.c_str())!=0) { EV << "SSID `" << frame->getBody().getSSID() << "' does not match, ignoring frame\n"; dropManagementFrame(frame); return; } MACAddress staAddress = frame->getTransmitterAddress(); delete frame; EV << "Sending ProbeResponse frame\n"; Ieee80211ProbeResponseFrame *resp = new Ieee80211ProbeResponseFrame("ProbeResp"); Ieee80211ProbeResponseFrameBody& body = resp->getBody(); body.setSSID(ssid.c_str()); body.setSupportedRates(supportedRates); body.setBeaconInterval(beaconInterval); body.setChannelNumber(channelNumber); sendManagementFrame(resp, staAddress); }
void Ieee80211MgmtAP::handleProbeResponseFrame | ( | Ieee80211ProbeResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtAP::handleReassociationRequestFrame | ( | Ieee80211ReassociationRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Processing ReassociationRequest frame\n"; // "11.3.4 AP reassociation procedures" -- almost the same as AssociationRequest processing STAInfo *sta = lookupSenderSTA(frame); if (!sta || sta->status==NOT_AUTHENTICATED) { // STA not authenticated: send error and return Ieee80211DeauthenticationFrame *resp = new Ieee80211DeauthenticationFrame("Deauth"); resp->getBody().setReasonCode(RC_NONAUTH_ASS_REQUEST); sendManagementFrame(resp, frame->getTransmitterAddress()); delete frame; return; } delete frame; // mark STA as associated sta->status = ASSOCIATED; // XXX this should only take place when MAC receives the ACK for the response // send OK response Ieee80211ReassociationResponseFrame *resp = new Ieee80211ReassociationResponseFrame("ReassocResp-OK"); Ieee80211ReassociationResponseFrameBody& body = resp->getBody(); body.setStatusCode(SC_SUCCESSFUL); body.setAid(0); //XXX body.setSupportedRates(supportedRates); sendManagementFrame(resp, sta->address); }
void Ieee80211MgmtAP::handleReassociationResponseFrame | ( | Ieee80211ReassociationResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtAP::handleTimer | ( | cMessage * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
{ if (msg==beaconTimer) { sendBeacon(); scheduleAt(simTime()+beaconInterval, beaconTimer); } else { error("internal error: unrecognized timer '%s'", msg->getName()); } }
void Ieee80211MgmtAP::handleUpperMessage | ( | cPacket * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
{ // must be an EtherFrame frame arriving from MACRelayUnit, that is, // bridged from another interface of the AP (probably Ethernet). EtherFrame *etherframe = check_and_cast<EtherFrame *>(msg); // check we really have a STA with that dest address STAList::iterator it = staList.find(etherframe->getDest()); if (it==staList.end() || it->second.status!=ASSOCIATED) { EV << "STA with MAC address " << etherframe->getDest() << " not associated with this AP, dropping frame\n"; delete etherframe; // XXX count drops? return; } // convert Ethernet frame Ieee80211DataFrame *frame = convertFromEtherFrame(etherframe); sendOrEnqueue(frame); }
void Ieee80211MgmtAP::initialize | ( | int | stage | ) | [protected, virtual] |
Reimplemented from Ieee80211MgmtAPBase.
{ Ieee80211MgmtAPBase::initialize(stage); if (stage==0) { // read params and init vars ssid = par("ssid").stringValue(); beaconInterval = par("beaconInterval"); numAuthSteps = par("numAuthSteps"); if (numAuthSteps!=2 && numAuthSteps!=4) error("parameter 'numAuthSteps' (number of frames exchanged during authentication) must be 2 or 4, not %d", numAuthSteps); channelNumber = -1; // value will arrive from physical layer in receiveChangeNotification() WATCH(ssid); WATCH(channelNumber); WATCH(beaconInterval); WATCH(numAuthSteps); WATCH_MAP(staList); //TBD fill in supportedRates // subscribe for notifications NotificationBoard *nb = NotificationBoardAccess().get(); nb->subscribe(this, NF_RADIO_CHANNEL_CHANGED); // start beacon timer (randomize startup time) beaconTimer = new cMessage("beaconTimer"); scheduleAt(simTime()+uniform(0,beaconInterval), beaconTimer); } }
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().
virtual int Ieee80211MgmtAP::numInitStages | ( | ) | const [inline, protected, virtual] |
Reimplemented from Ieee80211MgmtAPBase.
{return 2;}
void Ieee80211MgmtAP::receiveChangeNotification | ( | int | category, |
const cPolymorphic * | details | ||
) | [protected, virtual] |
Called by the NotificationBoard whenever a change occurs we're interested in
Implements INotifiable.
{ Enter_Method_Silent(); printNotificationBanner(category, details); if (category == NF_RADIO_CHANNEL_CHANGED) { EV << "updating channel number\n"; channelNumber = check_and_cast<RadioState *>(details)->getChannelNumber(); } }
void Ieee80211MgmtAP::sendBeacon | ( | ) | [protected, virtual] |
Utility function: creates and sends a beacon frame
Referenced by handleTimer().
{ EV << "Sending beacon\n"; Ieee80211BeaconFrame *frame = new Ieee80211BeaconFrame("Beacon"); Ieee80211BeaconFrameBody& body = frame->getBody(); body.setSSID(ssid.c_str()); body.setSupportedRates(supportedRates); body.setBeaconInterval(beaconInterval); body.setChannelNumber(channelNumber); frame->setReceiverAddress(MACAddress::BROADCAST_ADDRESS); frame->setFromDS(true); sendOrEnqueue(frame); }
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().
{ frame->setFromDS(true); frame->setReceiverAddress(destAddr); frame->setAddress3(myAddress); sendOrEnqueue(frame); }
simtime_t Ieee80211MgmtAP::beaconInterval [protected] |
Referenced by handleProbeRequestFrame(), handleTimer(), initialize(), and sendBeacon().
cMessage* Ieee80211MgmtAP::beaconTimer [protected] |
Referenced by handleTimer(), and initialize().
int Ieee80211MgmtAP::channelNumber [protected] |
Referenced by handleProbeRequestFrame(), initialize(), receiveChangeNotification(), and sendBeacon().
int Ieee80211MgmtAP::numAuthSteps [protected] |
Referenced by handleAuthenticationFrame(), and initialize().
std::string Ieee80211MgmtAP::ssid [protected] |
Referenced by handleProbeRequestFrame(), initialize(), and sendBeacon().
STAList Ieee80211MgmtAP::staList [protected] |
list of STAs
Referenced by handleAuthenticationFrame(), handleDataFrame(), handleUpperMessage(), initialize(), and lookupSenderSTA().
Ieee80211SupportedRatesElement Ieee80211MgmtAP::supportedRates [protected] |