681 lines
23 KiB
C
681 lines
23 KiB
C
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipfirewall_mac.c,v $ $Revision: 1.35.16.2 $
|
|
* $Source: /home/interpeak/CVSRoot/ipfirewall/src/ipfirewall_mac.c,v $
|
|
* $Author: svc-cmnet $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Markus Carlstedt <markus@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
* MAC filter.
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipfirewall_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPFIREWALL_USE_MAC_FILTER
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_shell.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_time.h>
|
|
|
|
#define IPFIREWALL_C
|
|
#include "ipfirewall.h"
|
|
#include "ipfirewall_h.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPFIREWALL_STATS
|
|
*===========================================================================
|
|
* MAC Filter statistics counters
|
|
*/
|
|
#ifdef IPFIREWALL_USE_MAC_STATISTICS
|
|
#define IPFIREWALL_STATS(xentry) ipfirewall->inner.stats.xentry
|
|
#else
|
|
#define IPFIREWALL_STATS(xentry) IP_NOOP
|
|
#endif
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPFIREWALL_MAC_IS_ME
|
|
*===========================================================================
|
|
* Check if MAC frame address is local
|
|
*/
|
|
#define IPFIREWALL_MAC_IS_ME(pktaddr, netif) \
|
|
(netif->link_addr_size == IPFIREWALL_MAC_ADDRESS_LEN && \
|
|
((Ip_u16 *)pktaddr)[0] == ((Ip_u16 *)netif->link_addr)[0] && \
|
|
((Ip_u16 *)pktaddr)[1] == ((Ip_u16 *)netif->link_addr)[1] && \
|
|
((Ip_u16 *)pktaddr)[2] == ((Ip_u16 *)netif->link_addr)[2])
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPFIREWALL_MAC_COMPARE
|
|
*===========================================================================
|
|
* Compare MAC frame address with rule address
|
|
*/
|
|
#define IPFIREWALL_MAC_COMPARE(addr, mask, pktaddr) \
|
|
(((Ip_u16 *)addr)[0] == (((Ip_u16 *)pktaddr)[0] & ((Ip_u16 *)mask)[0]) && \
|
|
((Ip_u16 *)addr)[1] == (((Ip_u16 *)pktaddr)[1] & ((Ip_u16 *)mask)[1]) && \
|
|
((Ip_u16 *)addr)[2] == (((Ip_u16 *)pktaddr)[2] & ((Ip_u16 *)mask)[2]))
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPFIREWALL_MAC_TEST_ADRESS
|
|
*===========================================================================
|
|
* Test MAC address against rule
|
|
*/
|
|
#define IPFIREWALL_MAC_TEST_ADRESS(any, me, not, addr, mask, pktaddr, netif) \
|
|
{ \
|
|
if (any) \
|
|
{ \
|
|
if (not) \
|
|
continue; \
|
|
} \
|
|
else if (me) \
|
|
{ \
|
|
if (IPFIREWALL_MAC_IS_ME(pktaddr, netif)) \
|
|
{ \
|
|
if (not) \
|
|
continue; \
|
|
} \
|
|
else if (!not) \
|
|
continue; \
|
|
} \
|
|
else \
|
|
{ \
|
|
if (IPFIREWALL_MAC_COMPARE(addr, mask, pktaddr)) \
|
|
{ \
|
|
if (not) \
|
|
continue; \
|
|
} \
|
|
else if (!not) \
|
|
continue; \
|
|
} \
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 LOCAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipfirewall_mac_log_pkt
|
|
*===========================================================================
|
|
* Description: Log a packet that matched a MAC filter rule.
|
|
* Parameters: fw_rule - pointer to the rule.
|
|
* netif - pointer to interface.
|
|
* pkt - pointer to packet.
|
|
* Returns: nothing.
|
|
*/
|
|
IP_STATIC void
|
|
ipfirewall_mac_log_pkt(Ipfirewall_rule *fw_rule, Ipcom_netif *netif, Ipcom_pkt *pkt)
|
|
{
|
|
Ipfirewall_mac_log *fw_mac_log;
|
|
struct Ip_timeval logtime;
|
|
|
|
if(fw_rule->inner.log_first == 1 && fw_rule->inner.log_hit == 1)
|
|
{
|
|
IPCOM_LOG2(DEBUG, "ipfirewall_log_pkt() :: MAC rule @%d:%d has already caused a log entry",
|
|
fw_rule->inner.group_no, fw_rule->inner.rule_no);
|
|
return;
|
|
}
|
|
|
|
if(ipfirewall->mac_head_log.size >= IPFIREWALL_MAX_MAC_LOG_ENTRIES)
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipfirewall_mac_log_pkt() :: Maximum number of log entries reached");
|
|
IPFIREWALL_STATS(mac_log_failures++);
|
|
return;
|
|
}
|
|
|
|
fw_mac_log = ipcom_malloc(sizeof(*fw_mac_log));
|
|
if(fw_mac_log == IP_NULL)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipfirewall_mac_log_pkt() :: Could not allocate memory for log entry");
|
|
IPFIREWALL_STATS(mac_log_failures++);
|
|
return;
|
|
}
|
|
ipcom_memset(fw_mac_log, 0, sizeof(*fw_mac_log));
|
|
|
|
/* Populate the log entry */
|
|
ipcom_microtime(&logtime);
|
|
fw_mac_log->inner.tv_sec = (Ip_s32)logtime.tv_sec;
|
|
fw_mac_log->inner.tv_usec = (Ip_s32)logtime.tv_usec;
|
|
ipcom_strcpy((char *)fw_mac_log->inner.ifname, (char *)netif->name);
|
|
fw_mac_log->inner.rule_no = fw_rule->inner.rule_no;
|
|
fw_mac_log->inner.group_no = fw_rule->inner.group_no;
|
|
fw_mac_log->inner.block = fw_rule->inner.block;
|
|
ipcom_memcpy(fw_mac_log->inner.dst, &pkt->data[pkt->start], IPFIREWALL_MAC_ADDRESS_LEN);
|
|
ipcom_memcpy(fw_mac_log->inner.src, &pkt->data[pkt->start+IPFIREWALL_MAC_ADDRESS_LEN], IPFIREWALL_MAC_ADDRESS_LEN);
|
|
ipcom_memcpy(&fw_mac_log->inner.type_n, &pkt->data[pkt->start+IPFIREWALL_MAC_ADDRESS_LEN*2], 2);
|
|
fw_mac_log->inner.length = pkt->end - pkt->start - IPFIREWALL_MAC_HEADER_LEN;
|
|
ipcom_memcpy(fw_mac_log->inner.frame,
|
|
&pkt->data[pkt->start + IPFIREWALL_MAC_HEADER_LEN],
|
|
IP_MIN((Ip_size_t)fw_mac_log->inner.length, sizeof(fw_mac_log->inner.frame)));
|
|
ipcom_list_insert_last(&ipfirewall->mac_head_log, &fw_mac_log->list_log);
|
|
IPCOM_LOG2(DEBUG, "ipfirewall_mac_log_pkt() :: Logged packet from MAC rule @%d:%d",
|
|
fw_rule->inner.group_no, fw_rule->inner.rule_no);
|
|
|
|
if(fw_rule->inner.log_first == 1)
|
|
fw_rule->inner.log_hit = 1;
|
|
|
|
if(fw_rule->inner.block == 1)
|
|
{
|
|
if(fw_rule->inner.in == 1)
|
|
IPFIREWALL_STATS(mac_in_logged_block++);
|
|
else
|
|
IPFIREWALL_STATS(mac_out_logged_block++);
|
|
}
|
|
else
|
|
{
|
|
if(fw_rule->inner.in == 1)
|
|
IPFIREWALL_STATS(mac_in_logged_pass++);
|
|
else
|
|
IPFIREWALL_STATS(mac_out_logged_pass++);
|
|
}
|
|
} /*lint !e429 */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipfirewall_mac_check_rules
|
|
*===========================================================================
|
|
* Description: Check packet against MAC filter rules.
|
|
* Parameters: in - IP_TRUE for incoming packet.
|
|
* netif - pointer to interface.
|
|
* pkt - pointer to packet.
|
|
* Returns: 1 = Block packet.
|
|
* 0 = Pass packet.
|
|
*/
|
|
IP_STATIC Ip_s32
|
|
ipfirewall_mac_check_rules(Ipcom_netif *netif, Ipcom_pkt *pkt, Ip_bool in)
|
|
{
|
|
Ipfirewall_rule *fw_rule;
|
|
Ipfirewall_rule *lastmatch = IP_NULL;
|
|
int current_group = 0;
|
|
Ip_u8 quick_head = 0;
|
|
Ip_u16 mac_type_n;
|
|
Ip_u8 ssap_n = 0;
|
|
Ip_u8 dsap_n = 0;
|
|
|
|
ip_assert(pkt);
|
|
ip_assert(pkt->data);
|
|
ip_assert(pkt->end > pkt->start);
|
|
|
|
if (in == IP_TRUE)
|
|
fw_rule = IPCOM_LIST_FIRST(&ipfirewall->mac_head_rule_input);
|
|
else
|
|
fw_rule = IPCOM_LIST_FIRST(&ipfirewall->mac_head_rule_output);
|
|
|
|
/* Match packet against mac rules */
|
|
for (; fw_rule != IP_NULL; fw_rule = IPCOM_LIST_NEXT(&fw_rule->list_rule))
|
|
{
|
|
if (ipfirewall->inner.mac_num_head_rules)
|
|
{
|
|
if (quick_head && current_group != fw_rule->inner.group_no)
|
|
break;
|
|
if (fw_rule->inner.group_no == 0)
|
|
{
|
|
current_group = 0;
|
|
quick_head = 0;
|
|
}
|
|
}
|
|
|
|
if (current_group == fw_rule->inner.group_no || fw_rule->inner.group_head)
|
|
{
|
|
/* Check direction */
|
|
if (fw_rule->inner.in)
|
|
{
|
|
if (in == IP_FALSE)
|
|
continue; /* Direction does not match */
|
|
}
|
|
else if (in == IP_TRUE)
|
|
{
|
|
continue; /* Direction does not match */
|
|
}
|
|
|
|
/* Check interface */
|
|
if(fw_rule->inner.on)
|
|
{
|
|
#ifdef IPNET_USE_VLAN
|
|
if (fw_rule->inner.in
|
|
&& netif->type != IP_IFT_L2VLAN
|
|
&& ((Ipnet_netif *)netif)->eth != IP_NULL
|
|
&& (ip_ntohs(*(Ip_u16 *)&pkt->data[pkt->start + IPFIREWALL_MAC_ADDRESS_LEN*2]) == 0x8100
|
|
#ifdef IPCOM_USE_HW_VLAN_TAGGING
|
|
|| IP_BIT_ISSET(pkt->flags, IPCOM_PKT_FLAG_VLAN_TAG)
|
|
#endif
|
|
)
|
|
&& ((Ipnet_netif *)netif)->eth->vlan.ifs != IP_NULL)
|
|
{
|
|
/* Find the correct VLAN interface */
|
|
Ipnet_netif *ipnet_netif;
|
|
int vid;
|
|
|
|
#ifdef IPCOM_USE_HW_VLAN_TAGGING
|
|
if (IP_BIT_ISSET(pkt->flags, IPCOM_PKT_FLAG_VLAN_TAG))
|
|
vid = IPNET_ETH_PKT_GET_VLAN_TAG(pkt) & 0x0fff;
|
|
else
|
|
#endif /* IPCOM_USE_HW_VLAN_TAGGING */
|
|
vid = IPNET_ETH_VLAN_GET_VID(*(Ip_u16 *)&pkt->data[pkt->start + IPFIREWALL_MAC_HEADER_LEN]);
|
|
|
|
ipnet_netif = ipcom_hash_get(((Ipnet_netif *)netif)->eth->vlan.ifs, &vid);
|
|
if (ipnet_netif != IP_NULL)
|
|
netif = &ipnet_netif->ipcom;
|
|
}
|
|
#endif
|
|
|
|
#ifdef IPFIREWALL_PHYSICAL_IF_SUPPORT
|
|
/* Check the physical interface before the logical interface */
|
|
if(fw_rule->inner.on_phys &&
|
|
(pkt->physical_netif != IP_NULL) ) {
|
|
if (fw_rule->inner.physical_ifindex)
|
|
{
|
|
/* Fast check */
|
|
IPFIREWALL_TEST_INTERFACE(fw_rule->inner.on_not,
|
|
fw_rule->inner.physical_ifindex,
|
|
pkt->physical_netif->ifindex)
|
|
}
|
|
else
|
|
{
|
|
/* Slow check */
|
|
if (ipfirewall_match_interface(fw_rule,
|
|
pkt->physical_netif) == 0)
|
|
continue; /* Interface does not match */
|
|
}
|
|
}
|
|
#endif
|
|
/* Check interface */
|
|
if (fw_rule->inner.on)
|
|
{
|
|
if (fw_rule->inner.ifindex)
|
|
{
|
|
/* Fast check */
|
|
IPFIREWALL_TEST_INTERFACE(fw_rule->inner.on_not, fw_rule->inner.ifindex, netif->ifindex)
|
|
}
|
|
else
|
|
{
|
|
/* Slow check */
|
|
if (ipfirewall_match_interface(fw_rule, netif) == 0)
|
|
continue; /* Interface does not match */
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Check source and destination address */
|
|
if (fw_rule->inner.from)
|
|
{
|
|
IPFIREWALL_MAC_TEST_ADRESS(fw_rule->inner.src_any, fw_rule->inner.src_me, fw_rule->inner.src_not,
|
|
&fw_rule->inner.mac_src,
|
|
&fw_rule->inner.mac_src_mask,
|
|
&pkt->data[pkt->start + IPFIREWALL_MAC_ADDRESS_LEN],
|
|
netif)
|
|
|
|
IPFIREWALL_MAC_TEST_ADRESS(fw_rule->inner.dst_any, fw_rule->inner.dst_me, fw_rule->inner.dst_not,
|
|
&fw_rule->inner.mac_dst,
|
|
&fw_rule->inner.mac_dst_mask,
|
|
&pkt->data[pkt->start],
|
|
netif)
|
|
}
|
|
|
|
/* Check MAC type */
|
|
if (fw_rule->inner.mac_type)
|
|
{
|
|
#ifdef IPCOM_USE_HW_VLAN_TAGGING
|
|
if (IP_BIT_ISSET(pkt->flags, IPCOM_PKT_FLAG_VLAN_TAG))
|
|
mac_type_n = ip_htons(0x8100);
|
|
else
|
|
#endif
|
|
mac_type_n = *(Ip_u16 *)&pkt->data[pkt->start + IPFIREWALL_MAC_ADDRESS_LEN*2];
|
|
if (fw_rule->inner.the_mac_type_n != mac_type_n)
|
|
|
|
{
|
|
continue; /* MAC type does not match */
|
|
}
|
|
}
|
|
|
|
mac_type_n = *(Ip_u16 *)&pkt->data[pkt->start + IPFIREWALL_MAC_ADDRESS_LEN*2];
|
|
|
|
/* Check for the 802.2 frame type */
|
|
if(fw_rule->inner.frame_802_2 == 1)
|
|
{
|
|
if(ip_ntohs(mac_type_n) > IPFIREWALL_MAC_802_3_MAX_LEN)
|
|
continue; /* Not an 802.2 frame */
|
|
}
|
|
|
|
if(fw_rule->inner.dsap == 1 ||
|
|
fw_rule->inner.ssap == 1 ||
|
|
fw_rule->inner.snap_vendor == 1 ||
|
|
fw_rule->inner.snap_type == 1)
|
|
{
|
|
|
|
if(ip_ntohs(mac_type_n) > IPFIREWALL_MAC_802_3_MAX_LEN)
|
|
continue; /* Not an 802.2 frame */
|
|
|
|
dsap_n = *(Ip_u8 *)&pkt->data[pkt->start +
|
|
IPFIREWALL_MAC_HEADER_LEN];
|
|
ssap_n = *(Ip_u8 *)&pkt->data[pkt->start +
|
|
IPFIREWALL_MAC_HEADER_LEN + 1];
|
|
|
|
}
|
|
|
|
if(fw_rule->inner.dsap == 1)
|
|
{
|
|
IPFIREWALL_TEST_SAP(fw_rule->inner.dsap_not,
|
|
fw_rule->inner.the_dsap_n , dsap_n)
|
|
}
|
|
|
|
if(fw_rule->inner.ssap == 1)
|
|
{
|
|
IPFIREWALL_TEST_SAP(fw_rule->inner.ssap_not,
|
|
fw_rule->inner.the_ssap_n , ssap_n)
|
|
}
|
|
|
|
if(fw_rule->inner.snap_vendor == 1)
|
|
{
|
|
|
|
/* DSAP and SSAP must be 0xaa for a SNAP header
|
|
* to be present */
|
|
if((ssap_n != 0xaa) || (dsap_n != 0xaa))
|
|
continue;
|
|
|
|
IPFIREWALL_TEST_SNAP_VENDOR(fw_rule->inner.snap_vendor_not,
|
|
&fw_rule->inner.the_snap_vendor_n,&pkt->data[pkt->start +
|
|
IPFIREWALL_MAC_HEADER_LEN + IPFIREWALL_LLC_HEADER_LEN])
|
|
}
|
|
|
|
if(fw_rule->inner.snap_type == 1)
|
|
{
|
|
Ip_u16 snap_type_n;
|
|
|
|
/* DSAP and SSAP must be 0xaa for a SNAP header
|
|
* to be present */
|
|
if((ssap_n != 0xaa) || (dsap_n != 0xaa))
|
|
continue;
|
|
|
|
snap_type_n =
|
|
*(Ip_u16 *)&pkt->data[pkt->start +
|
|
IPFIREWALL_MAC_HEADER_LEN + IPFIREWALL_LLC_HEADER_LEN + 3];
|
|
|
|
IPFIREWALL_TEST_SNAP(fw_rule->inner.snap_type_not,
|
|
fw_rule->inner.the_snap_type_n , snap_type_n)
|
|
}
|
|
|
|
/* Packet matched rule - check rate limiting */
|
|
if(fw_rule->inner.limit)
|
|
{
|
|
if (ipfirewall_compare_limit(fw_rule) == 0)
|
|
continue;
|
|
}
|
|
|
|
#ifdef IPFIREWALL_USE_USERDEF
|
|
/* Call user defined function */
|
|
if(fw_rule->inner.userdef && fw_rule->user_match != IP_NULL)
|
|
{
|
|
IPCOM_LOG2(DEBUG2, "ipfirewall_mac_check_rules() :: Calling user defined match function id: %s with paramater string: %s",
|
|
(char *)fw_rule->inner.userdef_id, fw_rule->inner.userdef_param);
|
|
if (fw_rule->user_match(pkt, fw_rule->userdef_cookie, fw_rule->userdef_info) == 0)
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
IPCOM_LOG2(DEBUG, "ipfirewall_mac_check_rules() :: Matched MAC rule @%d:%d", fw_rule->inner.group_no, fw_rule->inner.rule_no);
|
|
lastmatch = fw_rule;
|
|
if(!fw_rule->inner.group_head)
|
|
{
|
|
if (fw_rule->inner.quick)
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
current_group = fw_rule->inner.group_no;
|
|
quick_head = fw_rule->inner.quick;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(lastmatch == IP_NULL)
|
|
{
|
|
if(in == IP_TRUE)
|
|
IPFIREWALL_STATS(mac_in_nomatch++);
|
|
else
|
|
IPFIREWALL_STATS(mac_out_nomatch++);
|
|
#ifdef IPFIREWALL_BLOCK_IF_NO_MAC_MATCH
|
|
/* Return block code */
|
|
return 1;
|
|
#else
|
|
/* Return pass code */
|
|
return 0;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if(lastmatch->inner.log == 1)
|
|
ipfirewall_mac_log_pkt(lastmatch, netif, pkt); /* Log the packet */
|
|
|
|
/* Update statistics */
|
|
if(lastmatch->inner.block)
|
|
{
|
|
if(in == IP_TRUE)
|
|
IPFIREWALL_STATS(mac_in_block++);
|
|
else
|
|
IPFIREWALL_STATS(mac_out_block++);
|
|
/* Return block code */
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if(in == IP_TRUE)
|
|
IPFIREWALL_STATS(mac_in_pass++);
|
|
else
|
|
IPFIREWALL_STATS(mac_out_pass++);
|
|
/* Return pass code */
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipfirewall_mac_internal_get_rule
|
|
*===========================================================================
|
|
* Description: Get MAC filter rule entry.
|
|
* Parameters: ctrl - pointer to control structure.
|
|
* lenp - pointer to length of returned data.
|
|
* in - Rule direction
|
|
* Returns: 0 = success.
|
|
* <0 = fail.
|
|
*/
|
|
IP_GLOBAL Ip_s32
|
|
ipfirewall_mac_internal_get_rule(Ipfirewall_ctrl *ctrl, Ip_socklen_t *lenp, Ip_bool in)
|
|
{
|
|
Ipfirewall_rule *fw_rule;
|
|
Ip_u32 i;
|
|
|
|
/* Get the specified entry */
|
|
if (in == IP_TRUE)
|
|
fw_rule = IPCOM_LIST_FIRST(&ipfirewall->mac_head_rule_input);
|
|
else
|
|
fw_rule = IPCOM_LIST_FIRST(&ipfirewall->mac_head_rule_output);
|
|
|
|
for(i=0; i<ctrl->seqno && fw_rule != IP_NULL; i++)
|
|
fw_rule = IPCOM_LIST_NEXT(&fw_rule->list_rule);
|
|
|
|
/* Check if the entry existed */
|
|
if(fw_rule == IP_NULL)
|
|
{
|
|
*lenp = 0;
|
|
return 0;
|
|
}
|
|
|
|
ipcom_memcpy(&ctrl->type.rule_info, &fw_rule->inner, sizeof(fw_rule->inner));
|
|
*lenp = sizeof(*ctrl);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipfirewall_mac_internal_get_log
|
|
*===========================================================================
|
|
* Description: Get MAC filter log entry.
|
|
* Parameters: ctrl - pointer to control structure.
|
|
* lenp - pointer to length of returned data.
|
|
* Returns: 0 = success.
|
|
* <0 = fail.
|
|
*/
|
|
IP_GLOBAL Ip_s32
|
|
ipfirewall_mac_internal_get_log(Ipfirewall_ctrl *ctrl, Ip_socklen_t *lenp)
|
|
{
|
|
Ipfirewall_mac_log *fw_mac_log;
|
|
Ip_u32 i;
|
|
|
|
/* Get the specified entry */
|
|
fw_mac_log = IPCOM_LIST_FIRST(&ipfirewall->mac_head_log);
|
|
for(i=0; i<ctrl->seqno && fw_mac_log != IP_NULL; i++)
|
|
fw_mac_log = IPCOM_LIST_NEXT(&fw_mac_log->list_log);
|
|
|
|
/* Check if the entry existed */
|
|
if(fw_mac_log == IP_NULL)
|
|
{
|
|
*lenp = 0;
|
|
return 0;
|
|
}
|
|
|
|
ipcom_memcpy(&ctrl->type.mac_log_info, &fw_mac_log->inner, sizeof(fw_mac_log->inner));
|
|
*lenp = sizeof(*ctrl);
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipfirewall_mac_input_hook
|
|
*===========================================================================
|
|
* Description: MAC filter input hook.
|
|
* Parameters: netif - pointer to interface.
|
|
* pkt - pointer to packet.
|
|
* Returns: 1 = Block packet.
|
|
* 0 = Pass packet.
|
|
*/
|
|
IP_PUBLIC Ip_s32
|
|
ipfirewall_mac_input_hook(Ipcom_netif *netif, Ipcom_pkt *pkt)
|
|
{
|
|
Ip_s32 ret;
|
|
|
|
if (ipfirewall->inner.enabled == 0 || ipfirewall->inner.mac_num_in_rules == 0)
|
|
return 0;
|
|
|
|
ret = ipfirewall_mac_check_rules(netif, pkt, IP_TRUE);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipfirewall_mac_output_hook
|
|
*===========================================================================
|
|
* Description: MAC filter output hook.
|
|
* Parameters: netif - pointer to interface.
|
|
* pkt - pointer to packet.
|
|
* Returns: 1 = Block packet.
|
|
* 0 = Pass packet.
|
|
*/
|
|
IP_PUBLIC Ip_s32
|
|
ipfirewall_mac_output_hook(Ipcom_netif *netif, Ipcom_pkt *pkt)
|
|
{
|
|
Ip_s32 ret;
|
|
|
|
if (ipfirewall->inner.enabled == 0 || ipfirewall->inner.mac_num_out_rules == 0)
|
|
return 0;
|
|
|
|
ret = ipfirewall_mac_check_rules(netif, pkt, IP_FALSE);
|
|
return ret;
|
|
}
|
|
|
|
#else
|
|
int ipfirewall_mac_empty_file;
|
|
#endif /* #ifdef IPFIREWALL_USE_MAC_FILTER */
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|