summaryrefslogtreecommitdiff
path: root/cesar/cp/msg/src/field/msg_field_classifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp/msg/src/field/msg_field_classifier.c')
-rw-r--r--cesar/cp/msg/src/field/msg_field_classifier.c563
1 files changed, 563 insertions, 0 deletions
diff --git a/cesar/cp/msg/src/field/msg_field_classifier.c b/cesar/cp/msg/src/field/msg_field_classifier.c
new file mode 100644
index 0000000000..90ccc065da
--- /dev/null
+++ b/cesar/cp/msg/src/field/msg_field_classifier.c
@@ -0,0 +1,563 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}}
+ * \file msg_field_classifier.c
+ * \brief This file provides management functions for classifier_rules field.
+ * \ingroup cp/msg
+ *
+ */
+
+#include "common/std.h"
+#include "lib/swap.h"
+#include "cp/msg/inc/msg_cm_conn.h"
+
+// Private functions declaration
+len_t msg_field_classifier_copy_rule_ethernet_destination_address_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_rule_ethernet_source_address_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_rule_vlan_user_priority_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_rule_vlan_id_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_type_of_service_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_protocol_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_source_address_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_destination_address_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_traffic_class_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_flow_label_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_source_address_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_destination_address_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_tcp_source_port_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_tcp_destination_port_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_udp_source_port_on_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_udp_destination_port_on_stream(u8* stream, classifier_rules_data_t* data);
+
+
+len_t msg_field_classifier_copy_rule_ethernet_destination_address_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_rule_ethernet_source_address_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_rule_vlan_user_priority_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_rule_vlan_id_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_type_of_service_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_protocol_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_source_address_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv4_destination_address_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_traffic_class_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_flow_label_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_source_address_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_ipv6_destination_address_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_tcp_source_port_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_tcp_destination_port_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_udp_source_port_from_stream(u8* stream, classifier_rules_data_t* data);
+len_t msg_field_classifier_copy_udp_destination_port_from_stream(u8* stream, classifier_rules_data_t* data);
+
+
+
+
+
+//////////////////////////////////////////////////////////////
+// Private Type
+
+#define NBR_CLASSIFIER_FIELD 16
+#define FILTER_FIRST_BIT 0x01
+
+typedef len_t ( *copy_classifier_t)(u8* stream, classifier_rules_data_t* data);
+
+copy_classifier_t copy_classifier_from_stream_tb[] =
+{
+ msg_field_classifier_copy_rule_ethernet_destination_address_from_stream,
+ msg_field_classifier_copy_rule_ethernet_source_address_from_stream,
+ msg_field_classifier_copy_rule_vlan_user_priority_from_stream,
+ msg_field_classifier_copy_rule_vlan_id_from_stream,
+ msg_field_classifier_copy_ipv4_type_of_service_from_stream,
+ msg_field_classifier_copy_ipv4_protocol_from_stream,
+ msg_field_classifier_copy_ipv4_source_address_from_stream,
+ msg_field_classifier_copy_ipv4_destination_address_from_stream,
+ msg_field_classifier_copy_ipv6_traffic_class_from_stream,
+ msg_field_classifier_copy_ipv6_flow_label_from_stream,
+ msg_field_classifier_copy_ipv6_source_address_from_stream,
+ msg_field_classifier_copy_ipv6_destination_address_from_stream,
+ msg_field_classifier_copy_tcp_source_port_from_stream,
+ msg_field_classifier_copy_tcp_destination_port_from_stream,
+ msg_field_classifier_copy_udp_source_port_from_stream,
+ msg_field_classifier_copy_udp_destination_port_from_stream
+};
+
+copy_classifier_t copy_classifier_on_stream_tb[] =
+{
+ msg_field_classifier_copy_rule_ethernet_destination_address_on_stream,
+ msg_field_classifier_copy_rule_ethernet_source_address_on_stream,
+ msg_field_classifier_copy_rule_vlan_user_priority_on_stream,
+ msg_field_classifier_copy_rule_vlan_id_on_stream,
+ msg_field_classifier_copy_ipv4_type_of_service_on_stream,
+ msg_field_classifier_copy_ipv4_protocol_on_stream,
+ msg_field_classifier_copy_ipv4_source_address_on_stream,
+ msg_field_classifier_copy_ipv4_destination_address_on_stream,
+ msg_field_classifier_copy_ipv6_traffic_class_on_stream,
+ msg_field_classifier_copy_ipv6_flow_label_on_stream,
+ msg_field_classifier_copy_ipv6_source_address_on_stream,
+ msg_field_classifier_copy_ipv6_destination_address_on_stream,
+ msg_field_classifier_copy_tcp_source_port_on_stream,
+ msg_field_classifier_copy_tcp_destination_port_on_stream,
+ msg_field_classifier_copy_udp_source_port_on_stream,
+ msg_field_classifier_copy_udp_destination_port_on_stream
+};
+typedef struct
+{
+ u32 len;
+ u32 ptr_shift;
+} info_rule_t;
+
+/////////////////////////////////////////////////////////////////////
+//////////////////// Classifier TOOLBOX ////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+
+
+len_t
+msg_field_classifier_copy_rule_ethernet_destination_address_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ethernet_destination_address_t* address = &(data->ethernet_destination_address);
+
+ bcopy((void *)address, stream, 6);
+
+ return 6;
+}
+
+len_t
+msg_field_classifier_copy_rule_ethernet_destination_address_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ethernet_destination_address_t* address = &(data->ethernet_destination_address);
+
+ bcopy(stream, (void *)address, 6);
+
+ return 6;
+}
+
+
+
+len_t
+msg_field_classifier_copy_rule_ethernet_source_address_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ethernet_source_address_t* address = &(data->ethernet_source_address);
+
+ bcopy((void *)address, stream, 6);
+
+ return 6;
+}
+
+len_t
+msg_field_classifier_copy_rule_ethernet_source_address_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ethernet_source_address_t* address = &(data->ethernet_source_address);
+
+ bcopy(stream, (void *)address, 6);
+
+ return 6;
+}
+
+
+
+
+len_t
+msg_field_classifier_copy_rule_vlan_user_priority_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *stream = data->vlan_user_priority;
+
+ return 1;
+}
+
+len_t
+msg_field_classifier_copy_rule_vlan_user_priority_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->vlan_user_priority = *stream;
+
+ return 1;
+}
+
+
+
+
+len_t
+msg_field_classifier_copy_rule_vlan_id_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *(u16*)stream = htons(data->vlan_id);
+
+ return 2;
+}
+
+len_t
+msg_field_classifier_copy_rule_vlan_id_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->vlan_id = ntohs(*(u16*)stream);
+
+ return 2;
+}
+
+
+
+len_t
+msg_field_classifier_copy_ipv4_type_of_service_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *stream = data->ipv4_type_of_service;
+
+ return 1;
+}
+
+len_t
+msg_field_classifier_copy_ipv4_type_of_service_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->ipv4_type_of_service = *stream;
+
+ return 1;
+}
+
+
+
+len_t
+msg_field_classifier_copy_ipv4_protocol_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *stream = data->ipv4_protocol;
+
+ return 1;
+}
+
+len_t
+msg_field_classifier_copy_ipv4_protocol_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->ipv4_protocol = *stream;
+
+ return 1;
+}
+
+
+
+len_t
+msg_field_classifier_copy_ipv4_source_address_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv4_source_address_t* address = &(data->ipv4_source_address);
+
+ bcopy( (void *)address, (void *)stream, 4);
+
+ return 4;
+}
+
+len_t
+msg_field_classifier_copy_ipv4_source_address_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv4_source_address_t* dest = &(data->ipv4_source_address);
+
+ bcopy( stream, (void *)dest, 4);
+
+ return 4;
+}
+
+
+
+len_t
+msg_field_classifier_copy_ipv4_destination_address_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv4_destination_address_t* address = &(data->ipv4_destination_address);
+
+ bcopy( (void*)address, stream, 4);
+
+ return 4;
+}
+
+len_t
+msg_field_classifier_copy_ipv4_destination_address_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv4_destination_address_t* dest = &(data->ipv4_destination_address);
+
+ bcopy( stream, (void*)dest, 4);
+
+ return 4;
+}
+
+
+
+
+len_t
+msg_field_classifier_copy_ipv6_traffic_class_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *stream = data->ipv6_traffic_class;
+
+ return 1;
+}
+
+len_t
+msg_field_classifier_copy_ipv6_traffic_class_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->ipv6_traffic_class = *stream;
+
+ return 1;
+}
+
+
+
+len_t
+msg_field_classifier_copy_ipv6_flow_label_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv6_flow_label_t* flow = &(data->ipv6_flow_label);
+
+ bcopy( (void*)flow, stream, 3);
+
+ return 3;
+}
+
+len_t
+msg_field_classifier_copy_ipv6_flow_label_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv6_flow_label_t* flow = &(data->ipv6_flow_label);
+
+ bcopy( stream, (void*)flow, 3);
+
+ return 3;
+}
+
+
+
+len_t
+msg_field_classifier_copy_ipv6_source_address_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv6_source_address_t* address = &(data->ipv6_source_address);
+
+ bcopy( (void*)address, stream, 16);
+
+ return 16;
+}
+
+len_t
+msg_field_classifier_copy_ipv6_source_address_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv6_source_address_t* address = &(data->ipv6_source_address);
+
+ bcopy( stream, (void*)address, 16);
+
+ return 16;
+}
+
+
+
+
+len_t
+msg_field_classifier_copy_ipv6_destination_address_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv6_destination_address_t* address = &(data->ipv6_destination_address);
+
+ bcopy( (void*)address, stream, 16);
+
+ return 16;
+}
+
+len_t
+msg_field_classifier_copy_ipv6_destination_address_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ ipv6_destination_address_t* address = &(data->ipv6_destination_address);
+
+ bcopy( stream, (void*)address, 16);
+
+ return 16;
+}
+
+
+
+len_t
+msg_field_classifier_copy_tcp_source_port_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *(u16*)stream = htons(data->tcp_source_port);
+
+ return 2;
+}
+
+len_t
+msg_field_classifier_copy_tcp_source_port_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->tcp_source_port = ntohs(*(u16*)stream );
+
+ return 2;
+}
+
+
+
+len_t
+msg_field_classifier_copy_tcp_destination_port_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *(u16*)stream = htons(data->tcp_destination_port);
+
+ return 2;
+}
+
+len_t
+msg_field_classifier_copy_tcp_destination_port_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->tcp_destination_port = ntohs(*(u16*)stream);
+
+ return 2;
+}
+
+
+
+len_t
+msg_field_classifier_copy_udp_source_port_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *(u16*)stream = htons(data->udp_source_port);
+
+ return 2;
+}
+
+len_t
+msg_field_classifier_copy_udp_source_port_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->udp_source_port = ntohs(*(u16*)stream);
+
+ return 2;
+}
+
+
+
+len_t
+msg_field_classifier_copy_udp_destination_port_on_stream(u8* stream, classifier_rules_data_t* data)
+{
+ *(u16*)stream = htons(data->udp_destination_port);
+
+ return 2;
+}
+
+len_t
+msg_field_classifier_copy_udp_destination_port_from_stream(u8* stream, classifier_rules_data_t* data)
+{
+ data->udp_destination_port = ntohs(*(u16*)stream);
+
+ return 2;
+}
+
+////////////////////////////////////////////////////////////////////
+////////////////// Main Classifier Function ////////////////////////
+////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Init a Classifier_rules structures
+ * \param classifier_rules pointer of the data to be initialized
+ *
+ */
+void
+msg_field_classifier_init(classifier_rules_t* classifier_rules)
+{
+ bzero(classifier_rules, sizeof(classifier_rules_t));
+
+}
+
+
+
+/**
+ * Get Classifier from stream
+ * \param stream the source stream
+ * \param classifier_rules destination of the data
+ * \return len the function return the length of the classifier_rules frame on the stream,
+ * this value does not correspond with the reality when the frame contains vendor field
+ *
+ */
+len_t
+msg_field_classifier_get_from_stream (u8* stream, classifier_rules_t* classifier_rules)
+{
+ int nbr_classifier_rules;
+ int rule_index = 0;
+ u8* local_stream;
+ len_t len = 0;
+
+ dbg_assert_ptr (stream);
+ dbg_assert_ptr (classifier_rules);
+
+ // Init
+ classifier_rules->classifier_version = *stream; stream++;
+ nbr_classifier_rules = *stream;stream++;
+
+ local_stream = stream;
+
+ while (rule_index < nbr_classifier_rules)
+ {
+ // get the Classifier Rule Identifier
+ u8 classifier_rule_id = *local_stream;
+ len++;local_stream++;
+
+ dbg_assert_print( (classifier_rule_id < 0x10) || (classifier_rule_id > 0xDF), "Classifier Rule Identifier not valid - received fid: 0x%x", classifier_rule_id);
+
+ classifier_rules->data.classifier_rules_available_block |= (0x01 << classifier_rule_id);
+
+ if (classifier_rule_id > 0xDF)
+ {
+ // Vendor defined Classifier Rule
+ nbr_classifier_rules = rule_index;
+ break;
+ }
+ else
+ {
+ // Homeplug AV Classifier Rule
+ len += copy_classifier_from_stream_tb[classifier_rule_id](local_stream, &(classifier_rules->data));
+ }
+
+
+ local_stream = stream + len;
+ rule_index ++;
+ }
+
+ classifier_rules->nbr_rules = nbr_classifier_rules;
+
+ cp_dbg_classifier_rule(*classifier_rules);
+
+ return len + 2;
+}
+
+
+
+
+/**
+ * set Classifier Rules on stream
+ * \param stream Destination.
+ * \param classifier_rules Source.
+ * \return Length of the data.
+ */
+len_t
+msg_field_classifier_set_on_stream(u8* stream, classifier_rules_t* classifier_rules)
+{
+ u8 index_rules;
+ u8* local_stream;
+ u32 available_rules = classifier_rules->data.classifier_rules_available_block;
+ len_t len = 0;
+
+ dbg_assert_ptr(stream);
+ dbg_assert_ptr(classifier_rules);
+ cp_dbg_classifier_rule(*classifier_rules);
+
+ bcopy( classifier_rules, stream, 2);//Copy of Classifier version and nbr of rules
+
+ stream += 2;
+
+ local_stream = stream;
+ // copy of the rules
+ for(index_rules = 0; index_rules < NBR_CLASSIFIER_FIELD; index_rules++)
+ {
+ u32 shift = available_rules >> index_rules;
+ u32 filtered = shift & FILTER_FIRST_BIT;
+
+ if ( filtered == 0X1)
+ {
+
+ *local_stream = index_rules;
+
+ local_stream++;
+ len ++;
+
+ len += copy_classifier_on_stream_tb[index_rules](local_stream, &(classifier_rules->data));
+ local_stream = stream + len;
+ }
+ }
+
+ return len+2;
+
+}
+
+
+