VOL-149: Configure RADIUS Attributes as per subscriber information
VOL-148: RADIUS VLAN ID configurable

Change-Id: I2a51dbf316637e685b7e3c36595a27922c79b23c
diff --git a/src/main/java/org/opencord/aaa/SamplePacketCustomizer.java b/src/main/java/org/opencord/aaa/SamplePacketCustomizer.java
new file mode 100755
index 0000000..5e1bad5
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/SamplePacketCustomizer.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.aaa;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.RADIUSAttribute;
+
+
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Port;
+import org.onosproject.net.packet.InboundPacket;
+
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+
+/**
+ * Sample RADIUS Packet Customization.
+ *
+ */
+public class  SamplePacketCustomizer extends PacketCustomizer {
+
+    private final Logger log = getLogger(getClass());
+
+    public SamplePacketCustomizer(CustomizationInfo customInfo) {
+        super(customInfo);
+    }
+
+    /**
+     * Customize the packet as per specific Setup or RADIUS
+     * server requirements.
+     *
+     * @param inPkt RADIUS packet to be customized
+     * @param eapPacket Incoming packet containing EAP for which this the
+     *                  RADIUS message is being created
+     * @return Customized RADIUS packet
+     */
+    @Override
+    public RADIUS customizePacket(RADIUS inPkt, InboundPacket eapPacket) {
+        Port p = customInfo.deviceService().getPort(eapPacket.receivedFrom());
+
+        String id = p.annotations().value(AnnotationKeys.PORT_NAME);
+
+        log.info("Customizing packet Port received for {}", id);
+
+        SubscriberAndDeviceInformation subscriber = customInfo.
+                subscriberService().get(id);
+
+        if (subscriber == null) {
+            log.warn("No subscriber found with id {}", id);
+            return inPkt;
+        }
+
+        String nasPortId = subscriber.nasPortId();
+
+        Ethernet ethPkt = eapPacket.parsed();
+        MacAddress srcMac = ethPkt.getSourceMAC();
+
+        // Get the nasId from subscriber service using the Serial Number
+        String serialNo = customInfo.deviceService().getDevice(eapPacket.
+                receivedFrom().deviceId()).serialNumber();
+
+        log.info("SampleRadiusCustomizer serial = {}", serialNo);
+        SubscriberAndDeviceInformation deviceInfo = customInfo.
+                subscriberService().get(serialNo);
+
+        if (deviceInfo == null) {
+            log.warn("No Device found with SN {}", serialNo);
+            return inPkt;
+        }
+        String nodeName = deviceInfo.nasId();
+
+        log.info("Setting user={} nasId={} nasPort{}", srcMac, nodeName,
+                nasPortId);
+        inPkt.updateAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
+                srcMac.toString().getBytes());
+
+        inPkt.updateAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
+                deviceInfo.ipAddress().toOctets());
+
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_CALLING_STATION_ID,
+                srcMac.toString().getBytes());
+
+        // Check value - 16 was used in PoC2, as per PoC3 TS value should be 15
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT_TYPE,
+                ByteBuffer.allocate(4).putInt(15).array());
+
+        // Check - This may not be needed but was used in PoC2
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT,
+                ByteBuffer.allocate(4).putInt(46178304).array());
+        // Check - If this is needed, worked with this value in PoC2
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_ACCT_SESSION_ID,
+                "023:27:46:00000".getBytes());
+
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_ID,
+                nodeName.getBytes());
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT_ID,
+                nasPortId.getBytes());
+
+        return inPkt;
+    }
+
+    /**
+     * Customize the Ethernet header as per specific Setup or RADIUS
+     * server requirements.
+     *
+     * @param inPkt Ethernet packet to be changed
+     * @param eapPacket Incoming packet containing EAP for which this the
+     *                  RADIUS message is being created
+     * @return Changed Ethernet packet
+     */
+    public Ethernet customizeEthernetIPHeaders(Ethernet inPkt,
+                                               InboundPacket eapPacket) {
+
+        String serialNo = customInfo.deviceService().getDevice(eapPacket.
+                receivedFrom().deviceId()).serialNumber();
+
+        log.info("SampleRadiusCustomzer customizer serial = {}", serialNo);
+        SubscriberAndDeviceInformation deviceInfo = customInfo.
+                subscriberService().get(serialNo);
+
+        if (deviceInfo == null) {
+            log.warn("No Device found with SN {}", serialNo);
+            return inPkt;
+        }
+
+        inPkt.setSourceMACAddress(deviceInfo.hardwareIdentifier());
+
+        IPv4 ipv4Packet = (IPv4) inPkt.getPayload();
+        ipv4Packet.setSourceAddress(deviceInfo.ipAddress().toString());
+        inPkt.setPayload(ipv4Packet);
+
+        return inPkt;
+    }
+}