From a27354c9021a8423ef8c7d2bffad49cbf639eec1 Mon Sep 17 00:00:00 2001 From: Roman Yeryomin Date: Thu, 13 Sep 2012 00:40:35 +0300 Subject: Add realtek target files Signed-off-by: Roman Yeryomin --- .../linux/realtek/files/net/bridge/lan_restrict.c | 442 ++++++++++++++++++ .../linux/realtek/files/net/bridge/lan_restrict.h | 10 + .../linux/realtek/files/net/bridge/pocket_filter.c | 505 +++++++++++++++++++++ 3 files changed, 957 insertions(+) create mode 100644 target/linux/realtek/files/net/bridge/lan_restrict.c create mode 100644 target/linux/realtek/files/net/bridge/lan_restrict.h create mode 100644 target/linux/realtek/files/net/bridge/pocket_filter.c (limited to 'target/linux/realtek/files/net/bridge') diff --git a/target/linux/realtek/files/net/bridge/lan_restrict.c b/target/linux/realtek/files/net/bridge/lan_restrict.c new file mode 100644 index 000000000..8f09a9409 --- /dev/null +++ b/target/linux/realtek/files/net/bridge/lan_restrict.c @@ -0,0 +1,442 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lan_restrict.h" + +static char lan_restrict_flag[1024]; +int8 enable_lanrestrict = FALSE; +static struct proc_dir_entry *res=NULL; + +static inline int _strncasecmp(const char *s1, const char *s2, unsigned int n) +{ + if (n == 0) + return 0; + + while ((n-- != 0) + && (tolower(*(unsigned char *) s1) == + tolower(*(unsigned char *) s2))) { + if (n == 0 || *s1 == '\0' || *s2 == '\0') + return 0; + s1++; + s2++; + } + + return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); +} + +int lan_restrict_rcv(struct sk_buff *skb, struct net_device *dev) +{ + int32 found = FAILED; + ether_addr_t *macAddr; +// int8 port_num; + int32 column; + int32 SrcBlk; + + if ((memcmp(skb->dev->name, RTL_PS_BR0_DEV_NAME, 3) ==0) || (memcmp(skb->dev->name, RTL_PS_LAN_P0_DEV_NAME, 4) ==0) ) + { + macAddr = (ether_addr_t *)(eth_hdr(skb)->h_source); + found = rtl_check_fdb_entry_check_exist(RTL_LAN_FID, macAddr, FDB_DYNAMIC); +/* printk("\nrecv packet from dev:%s\n", skb->dev->name);*/ + /*can found in asic , do noting here , in linux fdb module , it can be authed*/ + if (found == SUCCESS ) + { +#if 0 + port_num = rtl865x_ConvertPortMasktoPortNum(fdbEntry.memberPortMask); + + if (lan_restrict_tbl[port_num].enable == TRUE) + { + if ((lan_restrict_tbl[port_num].curr_num < lan_restrict_tbl[port_num].max_num)) + { +/* printk("\nPASS:lan_restrict_tbl[%d] current number is %d\n", port_num, lan_restrict_tbl[port_num].curr_num);*/ + return NET_RX_SUCCESS; + } + else + { + if (fdbEntry.auth == TRUE) + { +/* printk("\nPASS1:lan_restrict_tbl[%d] current number is %d\n", port_num, lan_restrict_tbl[port_num].curr_num);*/ + return NET_RX_SUCCESS; + } + else + { +/* printk("\nDROP:lan_restrict_tbl[%d] current number is %d\n", port_num, lan_restrict_tbl[port_num].curr_num);*/ + l2temp_entry.l2type = (fdbEntry.nhFlag==0)?RTL865x_L2_TYPEI: RTL865x_L2_TYPEII; + l2temp_entry.process = FDB_TYPE_FWD; + l2temp_entry.memberPortMask = fdbEntry.memberPortMask; + l2temp_entry.auth = FALSE; + l2temp_entry.SrcBlk = TRUE; + memcpy(&(l2temp_entry.macAddr), macAddr, sizeof(ether_addr_t)); + rtl865x_addAuthFilterDatabaseEntryExtension(fdbEntry.fid, &l2temp_entry); + return NET_RX_AUTH_BLOCK; + } + } + } + else + { + return NET_RX_SUCCESS; + } +#endif + return NET_RX_SUCCESS; + } + else + { +/* printk(" \nnot found in hw table, src port is %d\n", skb->srcPort);*/ + if (lan_restrict_tbl[skb->srcPort].enable == TRUE) + { + /*found in sw l2 table*/ + if(rtl_check_fdb_entry_check_srcBlock(0, macAddr, &SrcBlk) == SUCCESS) + { + if (SrcBlk == TRUE)/*sw block*/ + { + return NET_RX_AUTH_BLOCK; + } + else + { + return NET_RX_SUCCESS; + } + } + else /*not found in sw l2 table*/ + { +/* printk(" \nnot found ind hw and sw table\n");*/ + if ((lan_restrict_tbl[skb->srcPort].curr_num < lan_restrict_tbl[skb->srcPort].max_num)) + { + /*try to add into sw l2 table*/ +/* printk("\ntry to add into sw l2 table\n");*/ + rtl865x_addAuthFDBEntry((unsigned char *)macAddr, TRUE, skb->srcPort); + return NET_RX_SUCCESS; + } + else + { + return NET_RX_AUTH_BLOCK; + } + } + + } + else + { +/* printk("dev name is %s\n", skb->dev->name);*/ + return NET_RX_SUCCESS; + } + } + } + else + { + return NET_RX_SUCCESS; + } +} +#if 0 +static struct packet_type lan_restrict_packet_type = { + .type = __constant_htons(ETH_P_ALL), + .func = lan_restrict_rcv, +}; +#endif +static int lan_restrict_tbl_int(void) +{ + uint8 i; + + for (i=0; i < LAN_RESTRICT_PORT_NUMBER; i++ ) + { + lan_restrict_tbl[i].port_num = 0; + lan_restrict_tbl[i].enable = FALSE; + lan_restrict_tbl[i].max_num = 0; + lan_restrict_tbl[i].curr_num = 0; + } + return TRUE; +} + +static int lan_restrict_tbl_reset(void) +{ + uint8 i; + + for (i=0; i < LAN_RESTRICT_PORT_NUMBER; i++ ) + { + lan_restrict_tbl[i].port_num = 0; + lan_restrict_tbl[i].enable = FALSE; + lan_restrict_tbl[i].max_num = 0; + lan_restrict_tbl[i].curr_num = 0; + } + return TRUE; +} + + +static int lan_restrict_set_singleport(uint8 portnum , int8 enable, int32 max_num) +{ + int32 ret; + if (enable == TRUE) + { + lan_restrict_tbl[portnum].max_num = max_num; + } + else + { + lan_restrict_tbl[portnum].max_num = 0; + } + + ret =rtl865x_setRestrictPortNum(portnum, enable, max_num); + return ret; +} + +static int lan_restrict_perport_setting(void) +{ + int i; + for (i=0; i < LAN_RESTRICT_PORT_NUMBER; i++ ) + { + lan_restrict_set_singleport(lan_restrict_tbl[i].port_num, lan_restrict_tbl[i].enable, lan_restrict_tbl[i].max_num); + } + return TRUE; +} + +static int lan_restrict_enable(void) +{ + /* + enable + */ + rtl865x_enableLanPortNumRestrict(TRUE); + lan_restrict_perport_setting(); + return TRUE; +} + +static int lan_restrict_disable(void) +{ + /* + disable + */ + rtl865x_enableLanPortNumRestrict(FALSE); + lan_restrict_tbl_reset(); + lan_restrict_perport_setting(); + return TRUE; +} +/* +int32 lanrestrict_addfdbentry(const unsigned char *addr) +{ + int32 found = FAILED; + ether_addr_t *macAddr; + int32 ret=FAILED; + int8 port_num; + int32 column; + rtl865x_tblAsicDrv_l2Param_t fdbEntry; + rtl865x_filterDbTableEntry_t l2temp_entry; + + macAddr = (ether_addr_t *)(addr); + found = rtl865x_Lookup_fdb_entry(0, macAddr, FDB_DYNAMIC, &column, &fdbEntry); + if (found == SUCCESS ) + { + port_num = rtl865x_ConvertPortMasktoPortNum(fdbEntry.memberPortMask); + + if (rtl865x_lookup_FilterDatabaseEntry(fdbEntry.fid, macAddr) != SUCCESS) + { + l2temp_entry.l2type = (fdbEntry.nhFlag==0)?RTL865x_L2_TYPEI: RTL865x_L2_TYPEII; + l2temp_entry.process = FDB_TYPE_FWD; + l2temp_entry.memberPortMask = fdbEntry.memberPortMask; + l2temp_entry.auth = TRUE; + l2temp_entry.SrcBlk = FALSE; + memcpy(&(l2temp_entry.macAddr), macAddr, sizeof(ether_addr_t)); + ret =rtl865x_addAuthFilterDatabaseEntryExtension(fdbEntry.fid, &l2temp_entry); + } + } + return ret; +} +*/ + +int32 lan_restrict_getBlockAddr(int32 port , const unsigned char *swap_addr) +{ + int32 ret = FAILED; + + if (lan_restrict_tbl[port].enable == TRUE) + { + ret = rtl865x_check_authfdbentry_Byport(port , swap_addr); + } + + return ret; +} + +int32 lan_restrict_CheckStatusByport(int32 port) +{ + if (lan_restrict_tbl[port].enable == TRUE) + { + if (lan_restrict_tbl[port].curr_num < lan_restrict_tbl[port].max_num) + { + return TRUE; + } + else + { + return FALSE; + } + } + else + { + return FAILED; + } +} +static int lan_restrict_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len, i ; + len = sprintf(page, "%s\n", "lan restrict table:"); + if (len <= off+count) + *eof = 1; + + for (i = 0; i < LAN_RESTRICT_PORT_NUMBER; i++) + { + len += sprintf(page + len, " PORT[%d] ", i); + len += sprintf(page + len,"%6s %6d %6d ",lan_restrict_tbl[i].enable?"ON":"OFF", lan_restrict_tbl[i].max_num, lan_restrict_tbl[i].curr_num); + len += sprintf(page + len,"\n"); + } + + return len; +} + +static int lan_restrict_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char tmpbuf[1024]; + char *entryPtr, *portnumPtr, *enablePtr, *maxnumPtr, *strptr=tmpbuf; + int8 port, port_enable, maxnum; + + if (count < 2) + return -EFAULT; + /* + format: entry1;entry2;entry3 + entry format: port_num enable max_num curr_num; + port_num: 0,1,2... + enable: on/off + max_num: 0,1,2... + curr_num: 0,1,2..., can not write, can only read from proc file and write again, just for display + */ + + memset(lan_restrict_flag,0,strlen(lan_restrict_flag)); + if (buffer && !copy_from_user(tmpbuf, buffer, count)) + { + if(memcmp(strptr,"enable", strlen("enable")) == 0) + { + lan_restrict_enable(); + enable_lanrestrict = TRUE; +/* printk("Fun[%s][%d]\n", __FUNCTION__, __LINE__);*/ + printk("enable lan restrict FUNC.....\n"); + } + else if(memcmp(strptr,"disable", strlen("enable")) == 0) + { + lan_restrict_disable(); + enable_lanrestrict = FALSE; +/* printk("Fun[%s][%d]\n", __FUNCTION__, __LINE__);*/ + printk("disable lan restrict FUNC.....\n"); + } + else + { + if (lan_restrict_enable == FALSE) + return count; + + /* + format: entry1;entry2;entry3 + entry format: port_num enable max_num curr_num; + port_num: 0,1,2... + enable: on/off + max_num: 0,1,2... + curr_num: 0,1,2..., can not write, can only read from proc file and write again, just for display + */ + entryPtr = strsep(&strptr,";"); + while (entryPtr != NULL) + { + /*1. port_num*/ + portnumPtr = strsep(&entryPtr," "); + if(portnumPtr == NULL) + { + printk("lan restrict setting format error1\n"); + break; + } + port = simple_strtol(portnumPtr,NULL,0); + printk("set port num is %d\n", port); + + /*2. enable or not*/ + enablePtr = strsep(&entryPtr," "); + if(enablePtr == NULL) + { + printk("lan restrict setting format error2\n"); + break; + } + if(_strncasecmp(enablePtr,"OFF",3) == 0) + { + port_enable = FALSE; + } + else if (_strncasecmp(enablePtr,"ON",3) == 0) + { + port_enable = TRUE; + } + else + { + printk("lan restrict setting format error3\n"); + break; + } + printk("port_enable is %d\n", port_enable); + + /*3max num*/ + maxnumPtr = strsep(&entryPtr," "); + if(maxnumPtr == NULL) + { + printk("lan restrict setting format error4\n"); + break; + } + maxnum = simple_strtol(maxnumPtr,NULL,0); + printk("set max num is %d\n", maxnum); + + lan_restrict_tbl[port].enable = port_enable; + lan_restrict_tbl[port].max_num = maxnum; + /* + set Asic + */ + lan_restrict_set_singleport(port, port_enable, maxnum); + } + } + } + + return count; +} + +static int lan_restrict_proc_init(void) +{ + res = create_proc_entry("lan_restrict_info",0,NULL); + if(res) + { + res->read_proc = lan_restrict_read_proc; + res->write_proc = lan_restrict_write_proc; + lanrestrict_unRegister_event(); + lanrestrict_register_event(); + return TRUE; + } + return FALSE; +} + +int __init lan_restrict_init(void) +{ + lan_restrict_tbl_int(); +// dev_add_pack(&lan_restrict_packet_type); + lan_restrict_proc_init(); + return 0; +} + + diff --git a/target/linux/realtek/files/net/bridge/lan_restrict.h b/target/linux/realtek/files/net/bridge/lan_restrict.h new file mode 100644 index 000000000..0ad313b47 --- /dev/null +++ b/target/linux/realtek/files/net/bridge/lan_restrict.h @@ -0,0 +1,10 @@ +//#include +#include +#include +#include +#include + +int32 lan_restrict_getBlockAddr(int32 port , const unsigned char *swap_addr); +extern int __init lan_restrict_init(void); +extern int lan_restrict_rcv(struct sk_buff *skb, struct net_device *dev); +extern int32 lan_restrict_CheckStatusByport(int32 port); diff --git a/target/linux/realtek/files/net/bridge/pocket_filter.c b/target/linux/realtek/files/net/bridge/pocket_filter.c new file mode 100644 index 000000000..05c2d809a --- /dev/null +++ b/target/linux/realtek/files/net/bridge/pocket_filter.c @@ -0,0 +1,505 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_HTTP_FILE_SERVER_SUPPORT) +extern void get_lan_ip_mask(void); +#endif +#define OPT_CODE 0 +#define OPT_LEN 1 +#define OPT_DATA 2 +#define OPTION_FIELD 0 +#define FILE_FIELD 1 +#define SNAME_FIELD 2 +/* DHCP option codes (partial list) */ +#define DHCP_PADDING 0x00 +#define DHCP_SUBNET 0x01 +#define DHCP_TIME_OFFSET 0x02 +#define DHCP_ROUTER 0x03 +#define DHCP_TIME_SERVER 0x04 +#define DHCP_NAME_SERVER 0x05 +#define DHCP_DNS_SERVER 0x06 +#define DHCP_LOG_SERVER 0x07 +#define DHCP_COOKIE_SERVER 0x08 +#define DHCP_LPR_SERVER 0x09 +#define DHCP_HOST_NAME 0x0c +#define DHCP_BOOT_SIZE 0x0d +#define DHCP_DOMAIN_NAME 0x0f +#define DHCP_SWAP_SERVER 0x10 +#define DHCP_ROOT_PATH 0x11 +#define DHCP_IP_TTL 0x17 +#define DHCP_MTU 0x1a +#define DHCP_BROADCAST 0x1c +#define DHCP_STATIC_ROUTE 0x21 +#define DHCP_NTP_SERVER 0x2a +#define DHCP_WINS_SERVER 0x2c +#define DHCP_REQUESTED_IP 0x32 +#define DHCP_LEASE_TIME 0x33 +#define DHCP_OPTION_OVER 0x34 +#define DHCP_MESSAGE_TYPE 0x35 +#define DHCP_SERVER_ID 0x36 +#define DHCP_PARAM_REQ 0x37 +#define DHCP_MESSAGE 0x38 +#define DHCP_MAX_SIZE 0x39 +#define DHCP_T1 0x3a +#define DHCP_T2 0x3b +#define DHCP_VENDOR 0x3c +#define DHCP_CLIENT_ID 0x3d +#define DHCP_NETBIOS_NODETYPE 0x2e +#define DHCP_NETBIOS_SCOPE 0x2F +#define DHCP_END 0xFF +int br_filter_mangle_udp_packet(struct sk_buff **skb, unsigned int match_offset,unsigned int match_len,unsigned char *rep_buffer, unsigned int rep_len); +struct proc_dir_entry *filter_root=NULL; +static struct proc_dir_entry *res1=NULL; +static struct proc_dir_entry *res2=NULL; +int enable_filter=0; +static unsigned char filter_config[256]; +int dut_br0_ip=0; +unsigned char dut_br0_mac[6]={0}; +unsigned char Filter_State=0; +struct dhcpMessage { + unsigned char op; + unsigned char htype; + unsigned char hlen; + unsigned char hops; + unsigned int xid; + unsigned short secs; + unsigned short flags; + unsigned int ciaddr; + unsigned int yiaddr; + unsigned int siaddr; + unsigned int giaddr; + unsigned char chaddr[16]; + unsigned char sname[64]; + unsigned char file[128]; + unsigned int cookie; + unsigned char options[308]; /* 312 - cookie */ +}; + +struct udp_dhcp_packet { + struct iphdr ip; + struct udphdr udp; + struct dhcpMessage data; +}; + +static int br_filter_resize_packet(struct sk_buff **skb, int new_size) +{ + struct iphdr *iph; + + + + if (new_size > (*skb)->len + skb_tailroom(*skb)) { + struct sk_buff *newskb; + newskb = skb_copy_expand(*skb, skb_headroom(*skb), new_size - (*skb)->len,GFP_ATOMIC); + + if (!newskb) { + return 0; + } else { + kfree_skb(*skb); + *skb = newskb; + } + } + + return 1; +} + +int br_filter_mangle_udp_packet(struct sk_buff **skb, unsigned int match_offset,unsigned int match_len,unsigned char *rep_buffer, unsigned int rep_len) +{ + //struct iphdr *iph = (*skb)->nh.iph; + struct iphdr *iph = (struct iphdr *)skb_network_header(*skb); + struct udphdr *udph = (void *)iph + iph->ihl * 4; + unsigned char *data; + u_int32_t udplen, newlen, newudplen; + + udplen = (*skb)->len - iph->ihl*4; + newudplen = udplen - match_len + rep_len; + newlen = iph->ihl*4 + newudplen; + + /* UDP helpers might accidentally mangle the wrong packet */ + if (udplen < sizeof(*udph) + match_offset + match_len) { + return 0; + } + + if (newlen > 65535) { + return 0; + } + + if ((*skb)->len != newlen) { + if (!br_filter_resize_packet(skb, newlen)) { + return 0; + } + } + + /* skb may be copied !! */ + //iph = (*skb)->nh.iph; + iph = (struct iphdr *)skb_network_header(*skb); + udph = (void *)iph + iph->ihl*4; + data = (void *)udph + sizeof(struct udphdr); + + if (rep_len != match_len) + /* move post-replacement */ + memmove(data + match_offset + rep_len, + data + match_offset + match_len, + (*skb)->tail - (data + match_offset + match_len)); + + /* insert data from buffer */ + memcpy(data + match_offset, rep_buffer, rep_len); + + /* update skb info */ + if (newlen > (*skb)->len) { + + skb_put(*skb, newlen - (*skb)->len); + } else { + + skb_trim(*skb, newlen); + } + + /* update the length of the UDP and IP packets to the new values*/ + udph->len = htons((*skb)->len - iph->ihl*4); + iph->tot_len = htons(newlen); + + /* fix udp checksum if udp checksum was previously calculated */ + if (udph->check != 0) { + udph->check = 0; + udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, + newudplen, IPPROTO_UDP, + csum_partial((char *)udph, + newudplen, 0)); + } + ip_send_check(iph); + + return 1; +} +unsigned char *br_filter_get_dhcp_option(struct dhcpMessage *packet, int code) +{ + int i, length; + unsigned char *optionptr=NULL; + int over = 0, done = 0, curr = OPTION_FIELD; + + optionptr = packet->options; + i = 0; + length = 308; + while (!done) { + if (i >= length) { + return NULL; + } + if (optionptr[i + OPT_CODE] == code) { + if (i + 1 + optionptr[i + OPT_LEN] >= length) { + return NULL; + } + return optionptr + i + 2; + } + switch (optionptr[i + OPT_CODE]) { + case DHCP_PADDING: + i++; + break; + case DHCP_OPTION_OVER: + if (i + 1 + optionptr[i + OPT_LEN] >= length) { + return NULL; + } + over = optionptr[i + 3]; + i += optionptr[OPT_LEN] + 2; + break; + case DHCP_END: + if (curr == OPTION_FIELD && over & FILE_FIELD) { + optionptr = packet->file; + i = 0; + length = 128; + curr = FILE_FIELD; + } else if (curr == FILE_FIELD && over & SNAME_FIELD) { + optionptr = packet->sname; + i = 0; + length = 64; + curr = SNAME_FIELD; + } else done = 1; + break; + default: + i += optionptr[OPT_LEN + i] + 2; + } + } + return NULL; +} +int br_filter_enter(struct sk_buff *skb) +{ + struct iphdr *iph; + struct udphdr *udph; + unsigned char *data_start; + struct udp_dhcp_packet *dhcp_packet=NULL; + //iph = skb->nh.iph; + iph = (struct iphdr *)skb_network_header(skb); + int i; + unsigned int match_offset=0; + unsigned int match_len=0; + unsigned char replace_buffer[6]={0}; + unsigned char option_len=0,*temp; + if(enable_filter==0) + return 0; + else{ + + udph=(void *) iph + iph->ihl*4; + //panic_printk("start to trace dhcp packet, dst port=%d\n",udph->dest); + if(iph->protocol==IPPROTO_UDP &&(udph->dest ==67 || udph->dest ==68)){ + if(udph->dest ==67){//from Client host in dhcp + //panic_printk("start to trace dhcp packet:client packet from :%s\n",skb->dev->name); + if(!strcmp(skb->dev->name, RTL_PS_LAN_P0_DEV_NAME)){ + if(Filter_State==0){ + //panic_printk("in this state, we drop client packet:Filter_State=%d\n",Filter_State); + return 1; + } + } + + } + + if(udph->dest ==68){//from server host in dhcp + if(Filter_State==1 || Filter_State==0){ //our dut has got ip address + dhcp_packet =(struct udp_dhcp_packet *)skb->data; + if ((temp = br_filter_get_dhcp_option(&(dhcp_packet->data), DHCP_DNS_SERVER))) + { + int roop=0; + unsigned char *router_temp, *subnet_temp; + + router_temp = br_filter_get_dhcp_option(&(dhcp_packet->data), DHCP_ROUTER); + + subnet_temp = br_filter_get_dhcp_option(&(dhcp_packet->data), DHCP_SUBNET); + +#if 0 //debug for domain name query +printk("\r\n DHCP_ROUTER=[%x.%x.%x.%x]__[%s-%u]\r\n",(unsigned char *)router_temp[0], +(unsigned char *)router_temp[1], (unsigned char *)router_temp[2], (unsigned char *)router_temp[3], __FILE__,__LINE__); + +printk("\r\n DHCP_SUBNET=[%x.%x.%x.%x]__[%s-%u]\r\n",(unsigned char *)subnet_temp[0], +(unsigned char *)subnet_temp[1], (unsigned char *)subnet_temp[2], (unsigned char *)subnet_temp[3], __FILE__,__LINE__); + + +printk("\r\n dut_br0_ip=[%x.%x.%x.%x]__[%s-%u]\r\n",((unsigned char *)&dut_br0_ip)[0], +((unsigned char *)&dut_br0_ip)[1], ((unsigned char *)&dut_br0_ip)[2], ((unsigned char *)&dut_br0_ip)[3], __FILE__,__LINE__); + +printk("\r\n router_temp & subnet_temp=[%x],__[%s-%u]\r\n",((*(unsigned int*)router_temp) & (*(unsigned int*)subnet_temp)),__FILE__,__LINE__); +printk("\r\n dut_br0_ip & subnet_temp=[%x],__[%s-%u]\r\n",(dut_br0_ip & (*(unsigned int*)subnet_temp)),__FILE__,__LINE__); +#endif //#if 0 //debug for domain name query + + if(((*(unsigned int*)router_temp) & (*(unsigned int*)subnet_temp)) != (dut_br0_ip & (*(unsigned int*)subnet_temp))) + { + //printk("\r\n dut ip does not in the client's subnet. __[%s-%u]\r\n",__FILE__,__LINE__); + return 0; + } + + option_len = (temp-1)[0]; + match_offset=(temp-2)-(unsigned char *)&(dhcp_packet->data); + match_len = option_len+2; + + replace_buffer[0]= DHCP_DNS_SERVER; + replace_buffer[1]=4; + replace_buffer[2]=((unsigned char *)&dut_br0_ip)[0]; + replace_buffer[3]=((unsigned char *)&dut_br0_ip)[1]; + replace_buffer[4]=((unsigned char *)&dut_br0_ip)[2]; + replace_buffer[5]=((unsigned char *)&dut_br0_ip)[3]; + if(replace_buffer[2] != 0 || replace_buffer[3] != 0 || replace_buffer[4] != 0 || replace_buffer[5] != 0){ + //panic_printk("in this state, we mangle dhcp server packet, dns ip =%02X%02X%02X%02X\n",replace_buffer[2],replace_buffer[3],replace_buffer[4],replace_buffer[5]); + br_filter_mangle_udp_packet(&skb, match_offset, match_len, replace_buffer, 6); + } + } + } + + + } + } + return 0; + } +} + + +static int en_filter_proc_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + + int len=0; + + len = sprintf(page, "%d\n", enable_filter); + + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + + return len; + +} + +static int filter_conf_proc_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + + int len=0; + + len = sprintf(page, "%s\n", filter_config); + + + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; + +} + +static int _is_hex_br_filter(char c) +{ + if(((c >= '0') && (c <= '9')) ||((c >= 'A') && (c <= 'F')) ||((c >= 'a') && (c <= 'f'))) + return 1; + else + return 0; +} +static int en_filter_proc_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char tmpbuf[80]; + + + if (count < 2) + return -EFAULT; + + if (buffer && !copy_from_user(tmpbuf, buffer, 80)) { + if (tmpbuf[0] == '0'){ + enable_filter = 0; + }else if (tmpbuf[0] == '1'){ + enable_filter = 1; + } + return count; + } + return -EFAULT; +} +int br_filter_string_to_hex(char *string, unsigned char *key, int len) +{ + char tmpBuf[4]; + int idx, ii=0; + for (idx=0; idxread_proc = en_filter_proc_read; + res1->write_proc = en_filter_proc_write; + } + + res2 = create_proc_entry("filter_conf", 0, filter_root); + if (res2) { + res2->read_proc = filter_conf_proc_read; + res2->write_proc = filter_conf_proc_write; + } + +#endif // CONFIG_PROC_FS + return 0; +} + +void __exit br_filter_exit(void) +{ +#if defined(CONFIG_PROC_FS) + if (res1) { + remove_proc_entry("en_filter", filter_root); + res2 = NULL; + } + if (res2) { + remove_proc_entry("filter_conf", filter_root); + res2 = NULL; + } + + remove_proc_entry("pocket",NULL); +#endif // CONFIG_PROC_FS +} + + -- cgit v1.2.3