| /* |
| * 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.impl; |
| |
| import static org.slf4j.LoggerFactory.getLogger; |
| |
| import java.nio.ByteBuffer; |
| |
| import org.onlab.packet.Ethernet; |
| import org.onlab.packet.Ip4Address; |
| 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; |
| |
| |
| /** |
| * Sample RADIUS Packet Customization. |
| */ |
| public class SamplePacketCustomizer extends PacketCustomizer { |
| private static final String SADIS_NOT_RUNNING = "Sadis is not running."; |
| |
| private final Logger log = getLogger(getClass()); |
| |
| public SamplePacketCustomizer(CustomizationInfo customInfo) { |
| super(customInfo); |
| } |
| |
| /** |
| * Determines if NAS IP Attribute should be updated or not. |
| * |
| * @return true if updating NAS IP is desired |
| */ |
| protected boolean updateNasIp() { |
| return true; |
| } |
| |
| /** |
| * 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); |
| |
| if (customInfo.subscriberService() == null) { |
| log.warn(SADIS_NOT_RUNNING); |
| return inPkt; |
| } |
| |
| 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(); |
| Ip4Address ipAddress = deviceInfo.ipAddress(); |
| if (nasPortId == null || nodeName == null || ipAddress == null) { |
| log.warn("Insufficient data to Customize packet" + |
| " : nasPortId = {}, nodeName = {}, ipAddress = {}", |
| nasPortId, nodeName, ipAddress); |
| return inPkt; |
| } |
| |
| |
| log.info("Setting nasId={} nasPortId{}", nodeName, nasPortId); |
| |
| if (updateNasIp()) { |
| inPkt.updateAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP, |
| deviceInfo.ipAddress().toOctets()); |
| } |
| |
| inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_CALLING_STATION_ID, |
| srcMac.toBytes()); |
| |
| // 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()); |
| |
| inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT, |
| ByteBuffer.allocate(4).putInt((int) p.number().toLong()).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 |
| */ |
| @Override |
| public Ethernet customizeEthernetIPHeaders(Ethernet inPkt, |
| InboundPacket eapPacket) { |
| |
| String serialNo = customInfo.deviceService().getDevice(eapPacket. |
| receivedFrom().deviceId()).serialNumber(); |
| |
| log.info("SampleRadiusCustomzer customizer serial = {}", serialNo); |
| |
| if (customInfo.subscriberService() == null) { |
| log.warn(SADIS_NOT_RUNNING); |
| return inPkt; |
| } |
| |
| SubscriberAndDeviceInformation deviceInfo = customInfo. |
| subscriberService().get(serialNo); |
| |
| if (deviceInfo == null) { |
| log.warn("No Device found with SN {}", serialNo); |
| return inPkt; |
| } |
| |
| MacAddress macAddress = deviceInfo.hardwareIdentifier(); |
| Ip4Address ipAddress = deviceInfo.ipAddress(); |
| if (macAddress == null || ipAddress == null) { |
| log.warn("Insufficient data to Customize Ethernet IP Headers" + |
| " : hardwareIdentifier = {}, ipAddress = {}", |
| macAddress, ipAddress); |
| return inPkt; |
| } |
| inPkt.setSourceMACAddress(macAddress); |
| |
| IPv4 ipv4Packet = (IPv4) inPkt.getPayload(); |
| ipv4Packet.setSourceAddress(ipAddress.toString()); |
| inPkt.setPayload(ipv4Packet); |
| |
| return inPkt; |
| } |
| } |