#include #include #include #include #include "dat.h" #include "fns.h" // ========== receive eapol frames Etherstate theEther; static void* newPacket(void) { Packet *p; p = malloc(sizeof(Packet)); if (p == nil) logfatal(1, "could not allocate Packet"); memset(p, 0, sizeof(Packet)); p->b = malloc(Pktlen); if (p->b == nil) logfatal(1, "could not allocate Packet buffer"); p->e = p->b; p->ether = (Ether*)p->b; p->eapol = (Eapol*)p->ether->data; p->eap = (Eap*)p->eapol->data; return p; } Etherstate* initether(void) { Etherstate *e; int i; e = &theEther; memset(e, 0, sizeof(Ether)); e->lastEapId = -1; e->packetc = chancreate(sizeof(Packet*), 0); e->statusc = chancreate(sizeof(int), 0); // e->keyTime = e->startTime; for (i = 0; i < Npkt; i++) e->pktr[i] = newPacket(); e->pktt = newPacket(); return e; } void etherproc(void *arg) { Etherstate *e; Packet *rx; int n; e = arg; for(;;) { rx = e->pktr[e->pkgidx]; loglog("etherproc: waiting for %d into %p", e->fd, rx); // don't do this: we do not reset rx-> for packets not sent over packetc //if (rx->e != rx->b) // logfatal("assertion failed: rx->e != rx->b (n == %ld)", rx->e - rx->b); n = read(e->fd, rx->b, Pktlen); loglog("etherproc: read from %d into %p: %d", e->fd, rx, n); if(n <= 0) break; rx->e = rx->b + n; if (rx->e < rx->ether->data) { logall("etherproc: skipping short packet (ether len=%d)", n); continue; } if (nhgets(rx->ether->t) != ETEAPOL) { logall("etherproc: skipping non-ETEAPOL %x", nhgets(rx->ether->t)); continue; } if (rx->e < rx->eapol->data) { logall("etherproc: skipping short packet (ether len=%d)", n); continue; } if (rx->e < rx->eapol->data + nhgets(rx->eapol->ln)) { logall("etherproc: skipping short packet (ether len=%d)", n); continue; } switch(rx->eapol->tp) { case EapolTpEap: if (rx->e < rx->eap->data) { logall("etherproc: skipping short packet (ether len=%d)", n); continue; } if (rx->e < rx->eapol->data + nhgets(rx->eap->ln)) { logall("etherproc: skipping short packet (ether len=%d)", n); continue; } if (e->lastEapId == rx->eap->id) loglog("etherproc lastEapId==eap->id==%d", rx->eap->id); e->lastEapId = rx->eap->id; switch(rx->eap->code) { case EapRequest: loglog("- - - - Eap Request id=%d - - - - ", rx->eap->id); loglog("etherproc: about to send %p ", rx); send(e->packetc, &rx); loglog("\tetherproc: done send %p ", rx); e->pkgidx = (e->pkgidx+1)%Npkt; break; case EapResponse: loglog("- - - - Eap Response id=%d - - - - ", rx->eap->id); break; case EapSuccess: loglog("- - - - success id=%d - - - -", rx->eap->id); syslog(0, logname, "etherproc: success id=%d", rx->eap->id); e->verdictTime = nsec(); e->eapSuccess = 1; send(e->statusc, nil); clearlog(getKeysbuf()); break; case EapFailure: loglog("- - - - fail id=%d - - - -", rx->eap->id); syslog(0, logname, "etherproc: fail id=%d", rx->eap->id); e->verdictTime = nsec(); e->eapFail = 1; send(e->statusc, nil); clearlog(getKeysbuf()); break; default: loglog("- - - - unknown eap id=%d type=%d - - - - ", rx->eap->id, rx->eap->code); syslog(0, logname, "etherproc: unknown eap id=%d type=%d", rx->eap->id, rx->eap->code); break; } break; case EapolTpStart: logall("etherproc: start (ignored)"); break; case EapolTpLogoff: logall("etherproc: logoff (ignored)"); break; case EapolTpKey: if (e->keyRun || e->eapSuccess) { loglog("- - - - key - - - -"); syslog(0, logname, "etherproc: key"); e->keyTime = nsec(); handleKey(e->cfd, rx->eapol, rx->e - rx->ether->data); e->keyDone = 1; } else logall("etherproc: ignoring key (not authed yet)"); break; case EapolTpAsf: logall("etherproc: asf (ignored)"); break; default: logall("etherproc: unknown type%d", rx->eapol->tp); break; } } logfatal(0, "etherproc: oops read %d...", n); }