understanding the code.
Gunter Burchardt
gbur
Thu Nov 25 09:38:18 PST 2004
> there's a copuple of things I miss..
>
> main initializes one interface.hapd[i] for phisical interface (just one
> for me). this calls init_driver_hostap() which calls driver_init() which calls
> init_sockets() which increments eloop.readers_count. So we have one
> eloop.reader[] for interface, and one eloop.reader[].sock to listen to.
> in eloop_run() we whatch this socket and pass the data it receives to the
> correct handler. right?
Yes. Hostapd is single threaded. Each action is caused by eloop.
Received data on sockets in only one thing a handler function is
called. Secondly you can register functions that will be called after a
specific time!
> upon receival of a frame handlers call each other untill we get
> to 802_1x_receive() that does this:
>
> sta = ap_get_sta(hapd, sa);
> [...]
> eapol_sm_step(sta->eapol_sm);
>
> so we have an authenticator state machine for every station, and a new
> station is initialized with hostapd_new_assoc_sta(), which I guess it is
> exectued at the moment of a new association.
Yes, yes, yes! :)
> back to EAPOL sm: the authenticator state machine (which I
> suppose is the one specified in the standard) changes from the
> connecting to the authenticating state when it receives EAPOL-Start frame.
Yes. Read IEEE802.1x standard. Its free (and very long). You will find
state machine there!
> case IEEE802_1X_TYPE_EAPOL_START:
> [...]
> sta->eapol_sm->auth_pae.eapolStart = TRUE;
> sta->eapol_sm->dot1xAuthEapolStartFramesRx++;
> eapol_sm_step(sta->eapol_sm);
>
> this happens just for EAPOL_START frames. for generic EAP frames we have:
>
> case IEEE802_1X_TYPE_EAP_PACKET:
> [...]
> handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen);
>
> in handle_eap(), as I said before we have:
>
> switch (eap->code) {
> 00712 case EAP_CODE_REQUEST:
> 00713 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (request)\n");
> 00714 return;
> 00715 case EAP_CODE_RESPONSE:
> 00716 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (response)\n");
> 00717 handle_eap_response(hapd, sta, eap, (u8 *) (eap + 1), eap_len);
> 00718 break;
> 00719 case EAP_CODE_SUCCESS:
> 00720 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (success)\n");
> 00721 return;
> 00722 case EAP_CODE_FAILURE:
> 00723 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (failure)\n");
> 00724 return;
> 00725 default:
> 00726 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " (unknown code)\n");
> 00727 return;
>
> which means that we handle EAP_RESPONSES and we don't do anything on
> everything else. in handle_eap_response() we set a few parameters on the
> sm but we don't make it run, neither we send any RADIUS packet. I guess
> the RADIUS packet is sent (shouldn't we forward EAP packets to
> authentication server?) afterwards when something which I still don't know
> makes the sm run.
Well, you set some sm parameters for:
ieee802_1x.c: sm->eapolEap = TRUE;
In ieee802_1x_receive() at the end eapol_sm_step(sta->eapol_sm) is
called for each packet. The sm parameters causes BE_AUTH state machine
to change state (or not).
sm->eapolEAP is TRUE for Response packets.
look at following code in eapol_sm.c:
case BE_AUTH_REQUEST:
if (sm->eapolEap)
SM_ENTER(BE_AUTH, RESPONSE);
else if (sm->be_auth.eapReq)
SM_ENTER(BE_AUTH, REQUEST);
else if (sm->eapTimeout)
SM_ENTER(BE_AUTH, TIMEOUT);
break;
BE_AUTH is in state BE_AUTH_REQUEST (awaiting an answer). If eapolEAP
is set the state is changed to RESPONSE.
> so the question remains: why do we handle just EAP_RESPONSE packets? what
> do we do with the rest?
Which rest do you mean eapol_sm_step() is called for each eap packet. So
the changed sm parameters can cause state change of sm state machine!
> some more: when we initialize a new sm we pass from the states
> initialize->disconnected->restart->connecting almost withouth
> intervention. to pass to the authenticating state we need eapReq=1 and
> I can't see where this is set, since in the code we just set eapolStart.
eapReq is set to TRUE in ieee802_1x.c.
regards
gunter
More information about the Hostap
mailing list