[SEBA-836] BBSim Reflector
Change-Id: Ib4ae5a2c24880dc62209bebb81188eca5f57865d
diff --git a/internal/bbsim/responders/eapol/eapol.go b/internal/bbsim/responders/eapol/eapol.go
index f31a068..c13aa69 100644
--- a/internal/bbsim/responders/eapol/eapol.go
+++ b/internal/bbsim/responders/eapol/eapol.go
@@ -17,6 +17,7 @@
package eapol
import (
+ "context"
"crypto/md5"
"errors"
"github.com/google/gopacket"
@@ -72,6 +73,17 @@
return ret
}
+func createEAPChallengeRequest(eapId uint8, payload []byte) *layers.EAP {
+ eap := layers.EAP{
+ Code: layers.EAPCodeRequest,
+ Id: eapId,
+ Length: 22,
+ Type: layers.EAPTypeOTP,
+ TypeData: payload,
+ }
+ return &eap
+}
+
func createEAPChallengeResponse(eapId uint8, payload []byte) *layers.EAP {
eap := layers.EAP{
Code: layers.EAPCodeResponse,
@@ -83,6 +95,15 @@
return &eap
}
+func createEAPIdentityRequest(eapId uint8) *layers.EAP {
+ eap := layers.EAP{Code: layers.EAPCodeRequest,
+ Id: eapId,
+ Length: 9,
+ Type: layers.EAPTypeIdentity,
+ TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
+ return &eap
+}
+
func createEAPIdentityResponse(eapId uint8) *layers.EAP {
eap := layers.EAP{Code: layers.EAPCodeResponse,
Id: eapId,
@@ -92,6 +113,16 @@
return &eap
}
+func createEAPSuccess(eapId uint8) *layers.EAP {
+ eap := layers.EAP{
+ Code: layers.EAPCodeSuccess,
+ Id: eapId,
+ Length: 9,
+ Type: layers.EAPTypeNone,
+ TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
+ return &eap
+}
+
func createEAPOLPkt(eap *layers.EAP, onuId uint32, intfId uint32) []byte {
buffer := gopacket.NewSerializeBuffer()
options := gopacket.SerializeOptions{}
@@ -121,6 +152,30 @@
return eap, nil
}
+func extractEAPOL(pkt gopacket.Packet) (*layers.EAPOL, error) {
+ layerEAPOL := pkt.Layer(layers.LayerTypeEAPOL)
+ eap, _ := layerEAPOL.(*layers.EAPOL)
+ if eap == nil {
+ return nil, errors.New("Cannot extract EAPOL")
+ }
+ return eap, nil
+}
+
+func sendEapolPktOut(client openolt.OpenoltClient, intfId uint32, onuId uint32, pkt []byte) error {
+ onuPacket := openolt.OnuPacket{
+ IntfId: intfId,
+ OnuId: onuId,
+ PortNo: onuId,
+ GemportId: 1,
+ Pkt: pkt,
+ }
+
+ if _, err := client.OnuPacketOut(context.Background(), &onuPacket); err != nil {
+ return err
+ }
+ return nil
+}
+
func updateAuthFailed(onuId uint32, ponPortId uint32, serialNumber string, onuStateMachine *fsm.FSM) error {
if err := onuStateMachine.Event("auth_failed"); err != nil {
eapolLogger.WithFields(log.Fields{
@@ -210,22 +265,58 @@
return nil
}
-func HandleNextPacket(onuId uint32, ponPortId uint32, serialNumber string, portNo uint32, onuStateMachine *fsm.FSM, recvpkt gopacket.Packet, stream openolt.Openolt_EnableIndicationServer) {
+func HandleNextPacket(onuId uint32, ponPortId uint32, serialNumber string, portNo uint32, onuStateMachine *fsm.FSM, pkt gopacket.Packet, stream openolt.Openolt_EnableIndicationServer, client openolt.OpenoltClient) {
- eap, err := extractEAP(recvpkt)
- if err != nil {
- eapolLogger.Errorf("%s", err)
+ eap, eapErr := extractEAP(pkt)
+
+ eapol, eapolErr := extractEAPOL(pkt)
+
+ if eapErr != nil && eapolErr != nil {
+ log.Fatalf("Failed to Extract EAP: %v - %v", eapErr, eapolErr)
+ return
}
- log.WithFields(log.Fields{
- "eap.Code": eap.Code,
- "eap.Type": eap.Type,
- "OnuId": onuId,
- "IntfId": ponPortId,
- "OnuSn": serialNumber,
- }).Tracef("HandleNextPacket")
+ fields := log.Fields{}
+ if eap != nil {
+ fields = log.Fields{
+ "Code": eap.Code,
+ "Type": eap.Type,
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ }
+ } else if eapol != nil {
+ fields = log.Fields{
+ "Type": eapol.Type,
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ }
+ }
- if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeIdentity {
+ log.WithFields(fields).Tracef("Handle Next EAPOL Packet")
+
+ if eapol != nil && eapol.Type == layers.EAPOLTypeStart {
+ identityRequest := createEAPIdentityRequest(1)
+ pkt := createEAPOLPkt(identityRequest, onuId, ponPortId)
+
+ if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
+ log.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ "error": err,
+ }).Errorf("Error while sending EAPIdentityRequest packet")
+ return
+ }
+
+ log.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ }).Infof("Sent EAPIdentityRequest packet")
+ return
+ } else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeIdentity {
reseap := createEAPIdentityResponse(eap.Id)
pkt := createEAPOLPkt(reseap, onuId, ponPortId)
@@ -250,6 +341,27 @@
}).Errorf("Error while transitioning ONU State %v", err)
}
+ } else if eap.Code == layers.EAPCodeResponse && eap.Type == layers.EAPTypeIdentity {
+ senddata := getMD5Data(eap)
+ senddata = append([]byte{0x10}, senddata...)
+ challengeRequest := createEAPChallengeRequest(eap.Id, senddata)
+ pkt := createEAPOLPkt(challengeRequest, onuId, ponPortId)
+
+ if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
+ log.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ "error": err,
+ }).Errorf("Error while sending EAPChallengeRequest packet")
+ return
+ }
+ log.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ }).Infof("Sent EAPChallengeRequest packet")
+ return
} else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeOTP {
senddata := getMD5Data(eap)
senddata = append([]byte{0x10}, senddata...)
@@ -276,6 +388,33 @@
"OnuSn": serialNumber,
}).Errorf("Error while transitioning ONU State %v", err)
}
+ } else if eap.Code == layers.EAPCodeResponse && eap.Type == layers.EAPTypeOTP {
+ eapSuccess := createEAPSuccess(eap.Id)
+ pkt := createEAPOLPkt(eapSuccess, onuId, ponPortId)
+
+ if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
+ log.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ "error": err,
+ }).Errorf("Error while sending EAPSuccess packet")
+ return
+ }
+
+ log.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ }).Infof("Sent EAP Success packet")
+
+ if err := onuStateMachine.Event("send_dhcp_flow"); err != nil {
+ eapolLogger.WithFields(log.Fields{
+ "OnuId": onuId,
+ "IntfId": ponPortId,
+ "OnuSn": serialNumber,
+ }).Errorf("Error while transitioning ONU State %v", err)
+ }
} else if eap.Code == layers.EAPCodeSuccess && eap.Type == layers.EAPTypeNone {
eapolLogger.WithFields(log.Fields{
"OnuId": onuId,