544 lines
28 KiB
C
544 lines
28 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
|
|
*
|
|
* 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.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
#include "TLVEncoder.h"
|
|
#include "TLVDecoder.h"
|
|
#include "TrafficFlowTemplate.h"
|
|
|
|
static int decode_traffic_flow_template_delete_packet(DeletePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int decode_traffic_flow_template_create_tft(CreateNewTft* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int decode_traffic_flow_template_add_packet(AddPacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int decode_traffic_flow_template_replace_packet(ReplacePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
|
|
static int decode_traffic_flow_template_packet_filter_identifiers(PacketFilterIdentifiers* packetfilteridentifiers, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int decode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
|
|
static int encode_traffic_flow_template_delete_packet(DeletePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int encode_traffic_flow_template_create_tft(CreateNewTft* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int encode_traffic_flow_template_add_packet(AddPacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int encode_traffic_flow_template_replace_packet(ReplacePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
|
|
static int encode_traffic_flow_template_packet_filter_identifiers(PacketFilterIdentifiers* packetfilteridentifiers, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
static int encode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len);
|
|
|
|
static void dump_traffic_flow_template_packet_filter_identifiers(PacketFilterIdentifiers* packetfilteridentifiers, uint8_t nbpacketfilters);
|
|
static void dump_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters);
|
|
|
|
int decode_traffic_flow_template(TrafficFlowTemplate *trafficflowtemplate, uint8_t iei, uint8_t *buffer, uint32_t len)
|
|
{
|
|
int decoded = 0;
|
|
int decoded_result = 0;
|
|
uint8_t ielen = 0;
|
|
|
|
if (iei > 0) {
|
|
CHECK_IEI_DECODER(iei, *buffer);
|
|
decoded++;
|
|
}
|
|
|
|
ielen = *(buffer + decoded);
|
|
decoded++;
|
|
CHECK_LENGTH_DECODER(len - decoded, ielen);
|
|
trafficflowtemplate->tftoperationcode = (*(buffer + decoded) >> 5) & 0x7;
|
|
trafficflowtemplate->ebit = (*(buffer + decoded) >> 4) & 0x1;
|
|
trafficflowtemplate->numberofpacketfilters = *(buffer + decoded) & 0xf;
|
|
decoded++;
|
|
|
|
/* Decoding packet filter list */
|
|
if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_DELETE_PACKET) {
|
|
decoded_result = decode_traffic_flow_template_delete_packet(&trafficflowtemplate->packetfilterlist.deletepacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_CREATE) {
|
|
decoded_result = decode_traffic_flow_template_create_tft(&trafficflowtemplate->packetfilterlist.createtft, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_ADD_PACKET) {
|
|
decoded_result = decode_traffic_flow_template_add_packet(&trafficflowtemplate->packetfilterlist.addpacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_REPLACE_PACKET) {
|
|
decoded_result = decode_traffic_flow_template_replace_packet(&trafficflowtemplate->packetfilterlist.replacepacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + decoded), len - decoded);
|
|
}
|
|
|
|
#if defined (NAS_DEBUG)
|
|
dump_traffic_flow_template_xml(trafficflowtemplate, iei);
|
|
#endif
|
|
|
|
if (decoded_result < 0) {
|
|
return decoded_result;
|
|
}
|
|
|
|
return (decoded + decoded_result);
|
|
}
|
|
|
|
int encode_traffic_flow_template(TrafficFlowTemplate *trafficflowtemplate, uint8_t iei, uint8_t *buffer, uint32_t len)
|
|
{
|
|
uint8_t *lenPtr;
|
|
uint32_t encoded = 0;
|
|
/* Checking IEI and pointer */
|
|
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, TRAFFIC_FLOW_TEMPLATE_MINIMUM_LENGTH, len);
|
|
#if defined (NAS_DEBUG)
|
|
dump_traffic_flow_template_xml(trafficflowtemplate, iei);
|
|
#endif
|
|
|
|
if (iei > 0) {
|
|
*buffer = iei;
|
|
encoded++;
|
|
}
|
|
|
|
lenPtr = (buffer + encoded);
|
|
encoded ++;
|
|
*(buffer + encoded) = 0x00 | ((trafficflowtemplate->tftoperationcode & 0x7) << 5) | ((trafficflowtemplate->ebit & 0x1) << 4) | (trafficflowtemplate->numberofpacketfilters & 0xf);
|
|
encoded++;
|
|
|
|
/* Encoding packet filter list */
|
|
if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_DELETE_PACKET) {
|
|
encoded += encode_traffic_flow_template_delete_packet(&trafficflowtemplate->packetfilterlist.deletepacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + encoded), len - encoded);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_CREATE) {
|
|
encoded += encode_traffic_flow_template_create_tft(&trafficflowtemplate->packetfilterlist.createtft, trafficflowtemplate->numberofpacketfilters, (buffer + encoded), len - encoded);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_ADD_PACKET) {
|
|
encoded += encode_traffic_flow_template_add_packet(&trafficflowtemplate->packetfilterlist.addpacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + encoded), len - encoded);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_REPLACE_PACKET) {
|
|
encoded += encode_traffic_flow_template_replace_packet(&trafficflowtemplate->packetfilterlist.replacepacketfilter, trafficflowtemplate->numberofpacketfilters, (buffer + encoded), len - encoded);
|
|
}
|
|
|
|
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
|
|
return encoded;
|
|
}
|
|
|
|
void dump_traffic_flow_template_xml(TrafficFlowTemplate *trafficflowtemplate, uint8_t iei)
|
|
{
|
|
printf("<Traffic Flow Template>\n");
|
|
|
|
if (iei > 0)
|
|
/* Don't display IEI if = 0 */
|
|
printf(" <IEI>0x%X</IEI>\n", iei);
|
|
|
|
printf(" <TFT operation code>%u</TFT operation code>\n", trafficflowtemplate->tftoperationcode);
|
|
printf(" <E bit>%u</E bit>\n", trafficflowtemplate->ebit);
|
|
printf(" <Number of packet filters>%u</Number of packet filters>\n", trafficflowtemplate->numberofpacketfilters);
|
|
|
|
if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_DELETE_PACKET) {
|
|
dump_traffic_flow_template_packet_filter_identifiers(&trafficflowtemplate->packetfilterlist.deletepacketfilter, trafficflowtemplate->numberofpacketfilters);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_CREATE) {
|
|
dump_traffic_flow_template_packet_filters(&trafficflowtemplate->packetfilterlist.createtft, trafficflowtemplate->numberofpacketfilters);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_ADD_PACKET) {
|
|
dump_traffic_flow_template_packet_filters(&trafficflowtemplate->packetfilterlist.addpacketfilter, trafficflowtemplate->numberofpacketfilters);
|
|
} else if (trafficflowtemplate->tftoperationcode == TRAFFIC_FLOW_TEMPLATE_OPCODE_REPLACE_PACKET) {
|
|
dump_traffic_flow_template_packet_filters(&trafficflowtemplate->packetfilterlist.replacepacketfilter, trafficflowtemplate->numberofpacketfilters);
|
|
}
|
|
|
|
printf("</Traffic Flow Template>\n");
|
|
}
|
|
|
|
static int decode_traffic_flow_template_delete_packet(DeletePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return decode_traffic_flow_template_packet_filter_identifiers(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int decode_traffic_flow_template_create_tft(CreateNewTft* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return decode_traffic_flow_template_packet_filters(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int decode_traffic_flow_template_add_packet(AddPacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return decode_traffic_flow_template_packet_filters(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int decode_traffic_flow_template_replace_packet(ReplacePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return decode_traffic_flow_template_packet_filters(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int decode_traffic_flow_template_packet_filter_identifiers(PacketFilterIdentifiers* packetfilteridentifiers, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
int decoded = 0, i;
|
|
|
|
for (i = 0; (i < nbpacketfilters) && (len - decoded > 0); i++) {
|
|
/* Packet filter identifier */
|
|
IES_DECODE_U8(buffer, decoded, (*packetfilteridentifiers)[i].identifier);
|
|
}
|
|
|
|
return decoded;
|
|
}
|
|
|
|
static int decode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
int decoded = 0, i, j;
|
|
|
|
for (i = 0; (i < nbpacketfilters); i++) {
|
|
if (len - decoded <= 0) {
|
|
/* Mismatch between the number of packet filters subfield,
|
|
* and the number of packet filters in the packet filter list */
|
|
return (TLV_DECODE_VALUE_DOESNT_MATCH);
|
|
}
|
|
|
|
/* Initialize the packet filter presence flag indicator */
|
|
(*packetfilters)[i].packetfilter.flags = 0;
|
|
/* Packet filter direction */
|
|
(*packetfilters)[i].direction = *(buffer + decoded) >> 4;
|
|
/* Packet filter identifier */
|
|
(*packetfilters)[i].identifier = *(buffer + decoded) & 0x0f;
|
|
decoded++;
|
|
/* Packet filter evaluation precedence */
|
|
IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].eval_precedence);
|
|
/* Length of the Packet filter contents field */
|
|
uint8_t pkflen;
|
|
IES_DECODE_U8(buffer, decoded, pkflen);
|
|
/* Packet filter contents */
|
|
int pkfstart = decoded;
|
|
|
|
while (decoded - pkfstart < pkflen) {
|
|
/* Packet filter component type identifier */
|
|
uint8_t component_type;
|
|
IES_DECODE_U8(buffer, decoded, component_type);
|
|
|
|
switch (component_type) {
|
|
case TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR:
|
|
/* IPv4 remote address type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG;
|
|
|
|
for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; j++) {
|
|
(*packetfilters)[i].packetfilter.ipv4remoteaddr[j].addr = *(buffer + decoded);
|
|
(*packetfilters)[i].packetfilter.ipv4remoteaddr[j].mask = *(buffer + decoded + TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE);
|
|
decoded++;
|
|
}
|
|
|
|
decoded += TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE;
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR:
|
|
/* IPv6 remote address type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR_FLAG;
|
|
|
|
for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; j++) {
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[j].addr = *(buffer + decoded);
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[j].mask = *(buffer + decoded + TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE);
|
|
decoded++;
|
|
}
|
|
|
|
decoded += TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE;
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER:
|
|
/* Protocol identifier/Next header type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER_FLAG;
|
|
IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.protocolidentifier_nextheader);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT:
|
|
/* Single local port type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG;
|
|
IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.singlelocalport);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE:
|
|
/* Local port range type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG;
|
|
IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.localportrange.lowlimit);
|
|
IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.localportrange.highlimit);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT:
|
|
/* Single remote port type */
|
|
(*packetfilters)[i].packetfilter.flags |=TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG ;
|
|
IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.singleremoteport);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE:
|
|
/* Remote port range type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG;
|
|
IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.remoteportrange.lowlimit);
|
|
IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.remoteportrange.highlimit);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX:
|
|
/* Security parameter index type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG;
|
|
IES_DECODE_U32(buffer, decoded, (*packetfilters)[i].packetfilter.securityparameterindex);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS:
|
|
/* Type of service/Traffic class type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG;
|
|
IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value);
|
|
IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL:
|
|
/* Flow label type */
|
|
(*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG;
|
|
IES_DECODE_U24(buffer, decoded, (*packetfilters)[i].packetfilter.flowlabel);
|
|
break;
|
|
|
|
default:
|
|
/* Packet filter component type identifier is not valid */
|
|
return (TLV_DECODE_UNEXPECTED_IEI);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (len - decoded != 0) {
|
|
/* Mismatch between the number of packet filters subfield,
|
|
* and the number of packet filters in the packet filter list */
|
|
return (TLV_DECODE_VALUE_DOESNT_MATCH);
|
|
}
|
|
|
|
return decoded;
|
|
}
|
|
|
|
static int encode_traffic_flow_template_delete_packet(DeletePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return encode_traffic_flow_template_packet_filter_identifiers(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int encode_traffic_flow_template_create_tft(CreateNewTft* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return encode_traffic_flow_template_packet_filters(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int encode_traffic_flow_template_add_packet(AddPacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return encode_traffic_flow_template_packet_filters(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int encode_traffic_flow_template_replace_packet(ReplacePacketFilter* packetfilter, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
return encode_traffic_flow_template_packet_filters(packetfilter, nbpacketfilters, buffer, len);
|
|
}
|
|
|
|
static int encode_traffic_flow_template_packet_filter_identifiers(PacketFilterIdentifiers* packetfilteridentifiers, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
int encoded = 0, i;
|
|
|
|
for (i = 0; (i < nbpacketfilters) && (len - encoded > 0); i++) {
|
|
/* Packet filter identifier */
|
|
IES_ENCODE_U8(buffer, encoded, (*packetfilteridentifiers)[i].identifier);
|
|
}
|
|
|
|
return encoded;
|
|
}
|
|
|
|
static int encode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
|
|
{
|
|
int encoded = 0, i, j;
|
|
|
|
for (i = 0; (i < nbpacketfilters) && (len - encoded > 0); i++) {
|
|
if (len - encoded <= 0) {
|
|
/* Mismatch between the number of packet filters subfield,
|
|
* and the number of packet filters in the packet filter list */
|
|
return (TLV_DECODE_VALUE_DOESNT_MATCH);
|
|
}
|
|
|
|
/* Packet filter identifier and direction */
|
|
IES_ENCODE_U8(buffer, encoded, (0x00 | ((*packetfilters)[i].direction << 4) | ((*packetfilters)[i].identifier)));
|
|
/* Packet filter evaluation precedence */
|
|
IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].eval_precedence);
|
|
/* Save address of the Packet filter contents field length */
|
|
uint8_t* pkflenPtr = buffer + encoded;
|
|
encoded++;
|
|
/* Packet filter contents */
|
|
int pkfstart = encoded;
|
|
uint16_t flag = TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG;
|
|
|
|
while (flag <= TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG) {
|
|
switch ((*packetfilters)[i].packetfilter.flags & flag) {
|
|
case TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG:
|
|
/* IPv4 remote address type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR);
|
|
|
|
for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; j++) {
|
|
*(buffer + encoded) = (*packetfilters)[i].packetfilter.ipv4remoteaddr[j].addr;
|
|
*(buffer + encoded + TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE) = (*packetfilters)[i].packetfilter.ipv4remoteaddr[j].mask;
|
|
encoded++;
|
|
}
|
|
|
|
encoded += TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE;
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR_FLAG:
|
|
/* IPv6 remote address type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR);
|
|
|
|
for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; j++) {
|
|
*(buffer + encoded) = (*packetfilters)[i].packetfilter.ipv6remoteaddr[j].addr;
|
|
*(buffer + encoded + TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE) = (*packetfilters)[i].packetfilter.ipv6remoteaddr[j].mask;
|
|
encoded++;
|
|
}
|
|
|
|
encoded += TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE;
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER_FLAG:
|
|
/* Protocol identifier/Next header type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER);
|
|
IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].packetfilter.protocolidentifier_nextheader);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG:
|
|
/* Single local port type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT);
|
|
IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.singlelocalport);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG:
|
|
/* Local port range type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE);
|
|
IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.localportrange.lowlimit);
|
|
IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.localportrange.highlimit);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG:
|
|
/* Single remote port type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT);
|
|
IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.singleremoteport);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG:
|
|
/* Remote port range type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE);
|
|
IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.remoteportrange.lowlimit);
|
|
IES_ENCODE_U16(buffer, encoded, (*packetfilters)[i].packetfilter.remoteportrange.highlimit);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG:
|
|
/* Security parameter index type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX);
|
|
IES_ENCODE_U32(buffer, encoded, (*packetfilters)[i].packetfilter.securityparameterindex);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG:
|
|
/* Type of service/Traffic class type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS);
|
|
IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value);
|
|
IES_ENCODE_U8(buffer, encoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask);
|
|
break;
|
|
|
|
case TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG:
|
|
/* Flow label type */
|
|
IES_ENCODE_U8(buffer, encoded, TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL);
|
|
IES_ENCODE_U24(buffer, encoded, (*packetfilters)[i].packetfilter.flowlabel & 0x000fffff);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
flag = flag << 1;
|
|
}
|
|
|
|
/* Length of the Packet filter contents field */
|
|
*pkflenPtr = encoded - pkfstart;
|
|
}
|
|
|
|
return encoded;
|
|
}
|
|
|
|
static void dump_traffic_flow_template_packet_filter_identifiers(PacketFilterIdentifiers* packetfilteridentifiers, uint8_t nbpacketfilters)
|
|
{
|
|
int i;
|
|
printf(" <Packet filter list>\n");
|
|
|
|
for (i = 0; i < nbpacketfilters; i++) {
|
|
printf(" <Identifier>%u</Identifier>\n", (*packetfilteridentifiers)[i].identifier);
|
|
}
|
|
|
|
printf(" </Packet filter list>\n");
|
|
}
|
|
|
|
static void dump_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters)
|
|
{
|
|
int i;
|
|
printf(" <Packet filter list>\n");
|
|
|
|
for (i = 0; i < nbpacketfilters; i++) {
|
|
printf(" <Identifier>%u</Identifier>\n", (*packetfilters)[i].identifier);
|
|
printf(" <Direction>%u</Direction>\n", (*packetfilters)[i].direction);
|
|
printf(" <Evaluation precedence>%u</Evaluation precedence>\n", (*packetfilters)[i].eval_precedence);
|
|
printf(" <Packet filter>\n");
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG) {
|
|
printf(" <IPv4 remote address>%u.%u.%u.%u</IPv4 remote address>\n", (*packetfilters)[i].packetfilter.ipv4remoteaddr[0].addr, (*packetfilters)[i].packetfilter.ipv4remoteaddr[1].addr,
|
|
(*packetfilters)[i].packetfilter.ipv4remoteaddr[2].addr, (*packetfilters)[i].packetfilter.ipv4remoteaddr[3].addr);
|
|
printf(" <IPv4 remote address mask>%u.%u.%u.%u</IPv4 remote address mask>\n", (*packetfilters)[i].packetfilter.ipv4remoteaddr[0].mask,
|
|
(*packetfilters)[i].packetfilter.ipv4remoteaddr[1].mask, (*packetfilters)[i].packetfilter.ipv4remoteaddr[2].mask, (*packetfilters)[i].packetfilter.ipv4remoteaddr[3].mask);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR_FLAG) {
|
|
printf(" <Ipv6 remote address>%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x</Ipv6 remote address>\n", (*packetfilters)[i].packetfilter.ipv6remoteaddr[0].addr,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[1].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[2].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[3].addr,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[4].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[5].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[6].addr,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[7].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[8].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[9].addr,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[10].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[11].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[12].addr,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[13].addr, (*packetfilters)[i].packetfilter.ipv6remoteaddr[14].addr, (*packetfilters)[i].packetfilter.
|
|
ipv6remoteaddr[15].addr);
|
|
printf(" <Ipv6 remote address mask>%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x</Ipv6 remote address mask>\n", (*packetfilters)[i].packetfilter.ipv6remoteaddr[0].mask,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[1].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[2].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[3].mask,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[4].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[5].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[6].mask,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[7].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[8].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[9].mask,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[10].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[11].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[12].mask,
|
|
(*packetfilters)[i].packetfilter.ipv6remoteaddr[13].mask, (*packetfilters)[i].packetfilter.ipv6remoteaddr[14].mask, (*packetfilters)[i].
|
|
packetfilter.ipv6remoteaddr[15].mask);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER_FLAG) {
|
|
printf(" <Protocol identifier - Next header type>%u</Protocol identifier - Next header type>\n", (*packetfilters)[i].packetfilter.protocolidentifier_nextheader);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG) {
|
|
printf(" <Single local port>%u</Single local port>\n", (*packetfilters)[i].packetfilter.singlelocalport);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG) {
|
|
printf(" <Local port range low limit>%u</Local port range low limit>\n", (*packetfilters)[i].packetfilter.localportrange.lowlimit);
|
|
printf(" <Local port range high limit>%u</Local port range high limit>\n", (*packetfilters)[i].packetfilter.localportrange.highlimit);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG) {
|
|
printf(" <Single remote port>%u</Single remote port>\n", (*packetfilters)[i].packetfilter.singleremoteport);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG) {
|
|
printf(" <Remote port range low limit>%u</Remote port range low limit>\n", (*packetfilters)[i].packetfilter.remoteportrange.lowlimit);
|
|
printf(" <Remote port range high limit>%u</Remote port range high limit>\n", (*packetfilters)[i].packetfilter.remoteportrange.highlimit);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG) {
|
|
printf(" <Security parameter index>%u</Security parameter index>\n", (*packetfilters)[i].packetfilter.securityparameterindex);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG) {
|
|
printf(" <Type of service - Traffic class>%u</Type of service - Traffic class>\n", (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value);
|
|
printf(" <Type of service - Traffic class mask>%u</Type of service - Traffic class mask>\n", (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask);
|
|
}
|
|
|
|
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG) {
|
|
printf(" <Flow label>%u</Flow label>\n", (*packetfilters)[i].packetfilter.flowlabel);
|
|
}
|
|
|
|
printf(" </Packet filter>\n");
|
|
}
|
|
|
|
printf(" </Packet filter list>\n");
|
|
}
|
|
|