195 lines
8.1 KiB
C
195 lines
8.1 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
|
|
*/
|
|
|
|
/*! \file classifier.c
|
|
* \brief Classify IP packets
|
|
* \author Navid Nikaein, Lionel GAUTHIER, Raymond knopp
|
|
* \company Eurecom
|
|
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr, knopp@eurecom.fr
|
|
*/
|
|
|
|
|
|
#include "local.h"
|
|
#include "proto_extern.h"
|
|
#include <net/ip6_fib.h>
|
|
#include <net/route.h>
|
|
#ifdef MPLS
|
|
#include <net/mpls.h>
|
|
#endif
|
|
|
|
|
|
#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
|
|
#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
|
|
#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
|
|
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
|
|
#define IN_MULTICAST(a) IN_CLASSD(a)
|
|
#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
|
|
#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
|
|
/* Address to accept any incoming messages. */
|
|
#define INADDR_ANY ((unsigned long int) 0x00000000)
|
|
/* Address to send to all hosts. */
|
|
#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
|
|
/* Address indicating an error return. */
|
|
#define INADDR_NONE ((unsigned long int) 0xffffffff)
|
|
|
|
|
|
#define NIPADDR(addr) \
|
|
(uint8_t)(addr & 0x000000FF), \
|
|
(uint8_t)((addr & 0x0000FF00) >> 8), \
|
|
(uint8_t)((addr & 0x00FF0000) >> 16), \
|
|
(uint8_t)((addr & 0xFF000000) >> 24)
|
|
|
|
#define NIP6ADDR(addr) \
|
|
ntohs((addr)->s6_addr16[0]), \
|
|
ntohs((addr)->s6_addr16[1]), \
|
|
ntohs((addr)->s6_addr16[2]), \
|
|
ntohs((addr)->s6_addr16[3]), \
|
|
ntohs((addr)->s6_addr16[4]), \
|
|
ntohs((addr)->s6_addr16[5]), \
|
|
ntohs((addr)->s6_addr16[6]), \
|
|
ntohs((addr)->s6_addr16[7])
|
|
|
|
|
|
#define IN6_IS_ADDR_UNSPECIFIED(a) \
|
|
(((__const uint32_t *) (a))[0] == 0 \
|
|
&& ((__const uint32_t *) (a))[1] == 0 \
|
|
&& ((__const uint32_t *) (a))[2] == 0 \
|
|
&& ((__const uint32_t *) (a))[3] == 0)
|
|
|
|
#define IN6_IS_ADDR_LOOPBACK(a) \
|
|
(((__const uint32_t *) (a))[0] == 0 \
|
|
&& ((__const uint32_t *) (a))[1] == 0 \
|
|
&& ((__const uint32_t *) (a))[2] == 0 \
|
|
&& ((__const uint32_t *) (a))[3] == htonl (1))
|
|
|
|
#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
|
|
|
|
#define IN6_IS_ADDR_LINKLOCAL(a) \
|
|
((((__const uint32_t *) (a))[0] & htonl (0xffc00000)) \
|
|
== htonl (0xfe800000))
|
|
|
|
#define IN6_IS_ADDR_SITELOCAL(a) \
|
|
((((__const uint32_t *) (a))[0] & htonl (0xffc00000)) \
|
|
== htonl (0xfec00000))
|
|
|
|
#define IN6_IS_ADDR_V4MAPPED(a) \
|
|
((((__const uint32_t *) (a))[0] == 0) \
|
|
&& (((__const uint32_t *) (a))[1] == 0) \
|
|
&& (((__const uint32_t *) (a))[2] == htonl (0xffff)))
|
|
|
|
#define IN6_IS_ADDR_V4COMPAT(a) \
|
|
((((__const uint32_t *) (a))[0] == 0) \
|
|
&& (((__const uint32_t *) (a))[1] == 0) \
|
|
&& (((__const uint32_t *) (a))[2] == 0) \
|
|
&& (ntohl (((__const uint32_t *) (a))[3]) > 1))
|
|
|
|
#define IN6_ARE_ADDR_EQUAL(a,b) \
|
|
((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \
|
|
&& (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \
|
|
&& (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \
|
|
&& (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
|
|
|
|
#define IN6_IS_ADDR_MC_NODELOCAL(a) \
|
|
(IN6_IS_ADDR_MULTICAST(a) \
|
|
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x1))
|
|
|
|
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
|
|
(IN6_IS_ADDR_MULTICAST(a) \
|
|
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x2))
|
|
|
|
#define IN6_IS_ADDR_MC_SITELOCAL(a) \
|
|
(IN6_IS_ADDR_MULTICAST(a) \
|
|
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x5))
|
|
|
|
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
|
|
(IN6_IS_ADDR_MULTICAST(a) \
|
|
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0x8))
|
|
|
|
#define IN6_IS_ADDR_MC_GLOBAL(a) \
|
|
(IN6_IS_ADDR_MULTICAST(a) \
|
|
&& ((((__const uint8_t *) (a))[1] & 0xf) == 0xe))
|
|
|
|
#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \
|
|
(((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \
|
|
&& ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \
|
|
&& ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \
|
|
&& ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3]))))
|
|
|
|
#define IN_ARE_ADDR_MASKED_EQUAL(a,b,m) \
|
|
(((((__const uint8_t *) (a))[0] & (((__const uint8_t *) (m))[0])) == (((__const uint8_t *) (b))[0] & (((__const uint8_t *) (m))[0]))) \
|
|
&& ((((__const uint8_t *) (a))[1] & (((__const uint8_t *) (m))[1])) == (((__const uint8_t *) (b))[1] & (((__const uint8_t *) (m))[1]))) \
|
|
&& ((((__const uint8_t *) (a))[2] & (((__const uint8_t *) (m))[2])) == (((__const uint8_t *) (b))[2] & (((__const uint8_t *) (m))[2]))) \
|
|
&& ((((__const uint8_t *) (a))[3] & (((__const uint8_t *) (m))[3])) == (((__const uint8_t *) (b))[3] & (((__const uint8_t *) (m))[3]))))
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Find the IP traffic type (UNICAST, MULTICAST, BROADCAST)
|
|
ip_traffic_type_t oai_nw_drv_find_traffic_type(struct sk_buff *skb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
ip_traffic_type_t traffic_type = TRAFFIC_IPVX_TYPE_UNKNOWN;
|
|
|
|
if (skb!=NULL) {
|
|
switch (ntohs(skb->protocol)) {
|
|
case ETH_P_IPV6:
|
|
traffic_type = TRAFFIC_IPV6_TYPE_UNKNOWN;
|
|
#ifdef OAI_DRV_DEBUG_CLASS
|
|
printk("SOURCE ADDR %X:%X:%X:%X:%X:%X:%X:%X",NIP6ADDR(&(ipv6_hdr(skb)->saddr)));
|
|
printk(" DEST ADDR %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&(ipv6_hdr(skb)->daddr)));
|
|
#endif
|
|
|
|
if (IN6_IS_ADDR_MULTICAST(&ipv6_hdr(skb)->daddr.in6_u.u6_addr32[0])) {
|
|
traffic_type = TRAFFIC_IPV6_TYPE_MULTICAST;
|
|
|
|
} else {
|
|
traffic_type = TRAFFIC_IPV6_TYPE_UNICAST;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case ETH_P_IP:
|
|
traffic_type = TRAFFIC_IPV4_TYPE_UNKNOWN;
|
|
|
|
//print_TOOL_pk_ipv4((struct iphdr *)skb->network_header);
|
|
if (IN_MULTICAST(htonl(ip_hdr(skb)->daddr))) {
|
|
traffic_type = TRAFFIC_IPV4_TYPE_MULTICAST;
|
|
} else {
|
|
traffic_type = TRAFFIC_IPV4_TYPE_UNICAST;
|
|
}
|
|
|
|
// TO DO BROADCAST
|
|
|
|
break;
|
|
|
|
case ETH_P_ARP:
|
|
traffic_type = TRAFFIC_IPV4_TYPE_BROADCAST;
|
|
break;
|
|
|
|
default:
|
|
;
|
|
}
|
|
}
|
|
|
|
return traffic_type;
|
|
}
|
|
|