/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see .
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#include
#include
#include
#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("\n");
if (iei > 0)
/* Don't display IEI if = 0 */
printf(" 0x%X\n", iei);
printf(" %u\n", trafficflowtemplate->tftoperationcode);
printf(" %u\n", trafficflowtemplate->ebit);
printf(" %u\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("\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(" \n");
for (i = 0; i < nbpacketfilters; i++) {
printf(" %u\n", (*packetfilteridentifiers)[i].identifier);
}
printf(" \n");
}
static void dump_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters)
{
int i;
printf(" \n");
for (i = 0; i < nbpacketfilters; i++) {
printf(" %u\n", (*packetfilters)[i].identifier);
printf(" %u\n", (*packetfilters)[i].direction);
printf(" %u\n", (*packetfilters)[i].eval_precedence);
printf(" \n");
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG) {
printf(" %u.%u.%u.%u\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(" %u.%u.%u.%u\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(" %x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x\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(" %x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x\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(" %u\n", (*packetfilters)[i].packetfilter.protocolidentifier_nextheader);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.singlelocalport);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.localportrange.lowlimit);
printf(" %u\n", (*packetfilters)[i].packetfilter.localportrange.highlimit);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.singleremoteport);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.remoteportrange.lowlimit);
printf(" %u\n", (*packetfilters)[i].packetfilter.remoteportrange.highlimit);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.securityparameterindex);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value);
printf(" %u\n", (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask);
}
if ((*packetfilters)[i].packetfilter.flags & TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG) {
printf(" %u\n", (*packetfilters)[i].packetfilter.flowlabel);
}
printf(" \n");
}
printf(" \n");
}