예제 #1
0
파일: netfilter.c 프로젝트: dailygeek/Webfw
int cb (struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
    struct nfq_data *nfa, void *data)
{
  int id;
  int len;
  int hlen;
  char *pkt;
  struct nfqnl_msg_packet_hdr *ph;
  struct nfqnl_msg_packet_hw *hwph;
  struct timeval tv;

  tv.tv_sec = 0; // init

  if ((ph = nfq_get_msg_packet_hdr(nfa)))
    id = ntohl(ph->packet_id);
  else
    id = 0;

  if ((hwph = nfq_get_packet_hw(nfa)))
    hlen = ntohs(hwph->hw_addrlen);
  else
    hlen = 0;

  /* hole payload ... falls es nicht klappt ... Paket durchreichen */
  if ((len = nfq_get_payload (nfa, (char **) &pkt)) < 0)
    return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);

  nfq_get_timestamp(nfa,&tv);
  return nfq_set_verdict(qh, id, myworker (data, pkt, len,&tv) ? NF_DROP :
                          NF_ACCEPT, 0, NULL);
}
static u_int32_t print_pkt (struct nfq_data *tb)
{
	int id = 0;
	struct nfqnl_msg_packet_hdr *ph;
	struct nfqnl_msg_packet_hw *hwph;
	u_int32_t mark,ifi; 
	int ret;
	char *data;

	ph = nfq_get_msg_packet_hdr(tb);
	if (ph) {
		id = ntohl(ph->packet_id);
		printf("hw_protocol=0x%04x hook=%u id=%u ",
			ntohs(ph->hw_protocol), ph->hook, id);
	}

	hwph = nfq_get_packet_hw(tb);
	if (hwph) {
		int i, hlen = ntohs(hwph->hw_addrlen);

		printf("hw_src_addr=");
		for (i = 0; i < hlen-1; i++)
			printf("%02x:", hwph->hw_addr[i]);
		printf("%02x ", hwph->hw_addr[hlen-1]);
	}

	mark = nfq_get_nfmark(tb);
	if (mark)
		printf("mark=%u ", mark);

	ifi = nfq_get_indev(tb);
	if (ifi)
		printf("indev=%u ", ifi);

	ifi = nfq_get_outdev(tb);
	if (ifi)
		printf("outdev=%u ", ifi);
	ifi = nfq_get_physindev(tb);
	if (ifi)
		printf("physindev=%u ", ifi);

	ifi = nfq_get_physoutdev(tb);
	if (ifi)
		printf("physoutdev=%u ", ifi);

	ret = nfq_get_payload(tb, &data);
	if (ret >= 0) {
		printf("payload_len=%d ", ret);
		//processPacketData (data, ret);
	}
	fputc('\n', stdout);

	return id;
}
예제 #3
0
static int verify_pkt (struct nfq_data *tb) {
  struct nfqnl_msg_packet_hdr *ph;
  struct nfqnl_msg_packet_hw *hwph;
  struct iphdr *iph;
  struct tcphdr *tcph;
  
  ph = nfq_get_msg_packet_hdr(tb);
  if(!ph) return -1;

  // check for IP
  if(ntohs(ph->hw_protocol) != 0x800)
    return -1;

  hwph = nfq_get_packet_hw(tb);
  if(!hwph) return -1;

  // only accept 6 byte hw addresses
  // this may fail with USB net. But we don't want to restricht that
  // anyway
  if(ntohs(hwph->hw_addrlen) != 6)
    return -1;

  // the rest are payload checks
  // error or less than ip+tcp headers
  if(nfq_get_payload(tb, (unsigned char **)&iph) < 40)
    return -1;

  // check for valid ipv4 header
  if((iph->version != 4) || (iph->ihl != 5))
    return -1;

  // don't allow fragmentation
  if((ntohs(iph->frag_off) & 0x1fff) != 0)
    return -1;

  // only deal with tcp
  if(iph->protocol != 6)
    return -1;

  // and take a peak into the tcp header
  tcph = (struct tcphdr*)(((char*)iph)+20);

  // ignore anything that doesn't have a syn flag
  if(!tcph->syn)
    return -1;
  
  return 0;
}
예제 #4
0
int get_info(struct nfq_data *tb, device_t *dev, char *ip_addr, uint16_t *port) {
  struct nfqnl_msg_packet_hw *hwph;
  struct iphdr *iph;
  struct tcphdr *tcph;

  hwph = nfq_get_packet_hw(tb);
  if(!hwph) return -1;
  memcpy(dev->hw_addr, hwph->hw_addr, 6);
  
  if(nfq_get_payload(tb, (unsigned char **)&iph) < 40)
    return -1;
  memcpy(ip_addr, &iph->saddr, 4);
	 
  tcph = (struct tcphdr*)(((char*)iph)+20);
  *port = ntohs(tcph->dest);
  
  return 0;
}
/*
 * Queue an incoming packet to the NKN DPI module
 * Packets that have HTTP data are alone queueud
 */
static u_int32_t queue_pkt_for_url_filtering(struct nfq_q_handle *qh,
	                                     struct nfq_data *nfq_data,
					     int64_t tid)
{
    int id = 0;
    struct nfqnl_msg_packet_hdr *ph;
#if 0
    struct nfqnl_msg_packet_hw *hwph;
#endif
    int64_t ret;
    unsigned char *data;
    nfqueue_dpi_xfer_t *xfer_data;
    struct iphdr *iph;
    struct tcphdr *tcph;

    ph = nfq_get_msg_packet_hdr(nfq_data);
    if (ph)
	id = ntohl(ph->packet_id);

#if 0
    hwph = nfq_get_packet_hw(nfq_data);
    if (hwph) {
	int i, hlen = ntohs(hwph->hw_addrlen);

	printf("hw_src_addr=");
	for (i = 0; i < hlen-1; i++)
	printf("%02x:", hwph->hw_addr[i]);
	printf("%02x ", hwph->hw_addr[hlen-1]);
    }
#endif

    ret = nfq_get_payload(nfq_data, &data);

    iph = (struct iphdr *)data;
    tcph = (struct tcphdr *)(data + (iph->ihl * 4));

    if (ntohs(iph->tot_len) == ((iph->ihl * 4) + (tcph->doff * 4))) {
	nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
	AO_fetch_and_add1(&glob_dpi_filter_non_data_cnt);
	return 0;
#ifdef NFLOOP_NO_PROCESS
    } else {
	nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
	AO_fetch_and_add1(&glob_dpi_filter_non_data_cnt);
	return 0;
#endif
    }

    xfer_data = nkn_calloc_type(1, sizeof(nfqueue_dpi_xfer_t),
				mod_nf_dpi_xfer_t);
    if (!xfer_data) {
	NKN_ASSERT(0);
	nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
	glob_dpi_filter_err_cnt[tid];
	return -1;
    }

    xfer_data->buffer  = data;

    xfer_data->qh      = qh;
    xfer_data->pkt_id  = id;
    xfer_data->pkt_len = ret + sizeof(struct ethhdr);
    xfer_data->ip_src  = ntohl(iph->saddr);
    xfer_data->ip_dst  = ntohl(iph->daddr);

#ifdef PROCESS_IN_NF_THREAD
    nkn_dpi_process_packet(xfer_data, tid);
#else
    NKN_MUTEX_LOCK(&nkn_nf_dpi_xfer_lock[tid]);
    TAILQ_INSERT_TAIL(&nkn_nf_dpi_xfer_list[tid], xfer_data,
		      xfer_entries);
    pthread_cond_signal(&nkn_nf_dpi_xfer_cond[tid]);
    NKN_MUTEX_UNLOCK(&nkn_nf_dpi_xfer_lock[tid]);
#endif

    return 0;
}
예제 #6
0
static int pkt_decision(struct nfq_data *payload)
{
	char *data;
	char *match, *folder, *url;
	PURL current;
	int payload_offset, data_len;
	struct iphdr *iph;
	struct tcphdr *tcp;
#if defined(AEI_VDSL_CUSTOMER_CENTURYLINK)
    char domain[1024+1]="";
#endif
	match = folder = url = NULL;

	data_len = nfq_get_payload(payload, &data);
	if( data_len == -1 )
	{
#ifdef UFD_DEBUG
	printf("data_len == -1!!!!!!!!!!!!!!!, EXIT\n");
#endif
		exit(1);
	}
#ifdef UFD_DEBUG
	printf("data_len=%d ", data_len);
#endif

    iph = (struct iphdr *)data;
    tcp = (struct tcphdr *)(data + (iph->ihl << 2));

	payload_offset = ((iph->ihl)<<2) + (tcp->doff<<2);
	match = (char *)(data + payload_offset);

	if(strstr(match, "GET ") == NULL && strstr(match, "POST ") == NULL && strstr(match, "HEAD ") == NULL)
	{
#ifdef UFD_DEBUG
	printf("****NO HTTP INFORMATION!!!\n");
#endif
		return PKT_ACCEPT;
	}
#if defined(AEI_VDSL_CUSTOMER_CENTURYLINK)
        else{
                AEI_getdomain(match, domain);
        }
#endif


#ifdef UFD_DEBUG
	printf("####payload = %s\n\n", match);
#endif

#if defined (AEI_WLAN_URL_REDIRECT)
        {
            char mac_str[128]={0};
            char url_redirect[256]={0};
            char *pUrl = NULL;
            struct nfqnl_msg_packet_hw *hw = NULL;
            hw = nfq_get_packet_hw(payload);
            if ( tcp->dest == htons (WEB_PORT) && (strstr(match,"GET / HTTP/")||
                        strstr(match,"get / HTTP/")||
                        strstr(match,"GET /"))||
                    strstr(match,"get /") )
            {       
                sprintf(mac_str,"%02x:%02x:%02x:%02x:%02x:%02x",hw->hw_addr[0],hw->hw_addr[1],hw->hw_addr[2],
                        hw->hw_addr[3],hw->hw_addr[4],hw->hw_addr[5]);
                AEI_processSSID234UrlRedirect(mac_str,url_redirect,sizeof(url_redirect)-1,brname,match);
                if (strcmp(url_redirect,"")){
                    AEI_urltrim(url_redirect);
                    pUrl = strstr(url_redirect,"http://");
                    if(pUrl){
                        pUrl = pUrl + 7;
                        if  (strstr(match, pUrl) == NULL) {
//                            status = send_redirect (qh, id, payload, url_redirect);
                            memset(GlbRedirectUrl, 0, sizeof(GlbRedirectUrl)); 
                            sprintf(GlbRedirectUrl, "%s", url_redirect);                           
                            return PKT_REDIRECT;
                        }
                    }else{
                        if  (strstr(match, url_redirect) == NULL) {
//                            status = send_redirect (qh, id, payload, url_redirect);
                            memset(GlbRedirectUrl, 0, sizeof(GlbRedirectUrl)); 
                            sprintf(GlbRedirectUrl, "%s", url_redirect);                           
                            return PKT_REDIRECT;
                        }
                    }
                }

            }
        }
#endif

#if defined (DMP_CAPTIVEPORTAL_1)
#if defined(AEI_VDSL_TR098_QWEST)
	if ((flagOneTimeRedirect == 1) && (tcp->dest == htons (WEB_PORT)))
	{
		if(strstr(match, "GET / HTTP/") || strstr(match, "get HTTP/")) 
		{        
			flagOneTimeRedirect = 2;
			AEI_send_msg_to_set_oneTimeRedirectURLFlag();
			if ((strstr(match, oneTimeRedirectURL) == NULL) && (strstr(oneTimeRedirectIPAdress, inet_ntoa(*(struct in_addr *) &iph->daddr)) == NULL))
			{
				//status = send_redirect (qh, id, payload, oneTimeRedirectURL);
				//return status;
    			memset(GlbRedirectUrl, 0, sizeof(GlbRedirectUrl));
    			sprintf(GlbRedirectUrl, "%s", oneTimeRedirectURL);
				return PKT_REDIRECT;
			}
		}	
	}
	else if ((flagOneTimeRedirect == 2) && (tcp->dest == htons (WEB_PORT)))
	{               
		if ((strstr(match, "GET / HTTP/") || strstr(match, "get / HTTP/")))	
		{           
			if ((strstr(match, oneTimeRedirectURL) == NULL) && (strstr(oneTimeRedirectIPAdress, inet_ntoa(*(struct in_addr *) &iph->daddr)) == NULL))
			{              
				flagOneTimeRedirect = 0;
#if defined(AEI_VDSL_CUSTOMER_CENTURYLINK)
                                if ((flagCaptiveURL == 1) && ((!AEI_checkCaptiveAllowList(captiveAllowList, iph->daddr))
                                        &&(domain[0] && (!AEI_checkCaptiveAllowDomain(captiveAllowDomain, domain)))))
#else
				if ((flagCaptiveURL == 1) && (!AEI_checkCaptiveAllowList(captiveAllowList, iph->daddr)))
#endif
				{            
					if ((strstr(match, captiveURL) == NULL) && (strstr(captiveIPAddr, inet_ntoa(*(struct in_addr *) &iph->daddr)) == NULL))
					{    
			            //status = send_redirect (qh, id, payload, captiveURL);
						//return status;
    					memset(GlbRedirectUrl, 0, sizeof(GlbRedirectUrl));
    					sprintf(GlbRedirectUrl, "%s", captiveURL);
						return PKT_REDIRECT;
					}
				}
			}
		}	
	}
	else	
#endif
	{              
#if defined(AEI_VDSL_CUSTOMER_CENTURYLINK)
                if ((flagCaptiveURL == 1) && (tcp->dest == htons (WEB_PORT)) && ((!AEI_checkCaptiveAllowList(captiveAllowList, iph->daddr))
                        &&(domain[0] && (!AEI_checkCaptiveAllowDomain(captiveAllowDomain, domain)))))
#else
		if ((flagCaptiveURL == 1) && (tcp->dest == htons (WEB_PORT)) && (!AEI_checkCaptiveAllowList(captiveAllowList, iph->daddr)))
#endif
		{               
			if(strstr(match, "GET /") || strstr(match, "get /")) 
			{        
				if ((strstr(match, captiveURL) == NULL) && (strstr(captiveIPAddr, inet_ntoa(*(struct in_addr *) &iph->daddr)) == NULL))
				{
					//status = send_redirect (qh, id, payload, captiveURL);
					flagCaptiveURL = 1;
					//return status;
    				memset(GlbRedirectUrl, 0, sizeof(GlbRedirectUrl));
    				sprintf(GlbRedirectUrl, "%s", captiveURL);
					return PKT_REDIRECT;
				}
			}
		}
#if defined(AEI_VDSL_CUSTOMER_CENTURYLINK)
                else if ((flagCaptiveURL == 2) && (tcp->dest == htons (WEB_PORT)) && ((!AEI_checkCaptiveAllowList(captiveAllowList, iph->daddr))
                        &&(domain[0] && (!AEI_checkCaptiveAllowDomain(captiveAllowDomain, domain)))))
#else
		else if ((flagCaptiveURL == 2) && (tcp->dest == htons (WEB_PORT)) && (!AEI_checkCaptiveAllowList(captiveAllowList, iph->daddr)))
#endif
		{
			if(strstr(match, "GET / HTTP/") || strstr(match, "get / HTTP/")) 
			{
				if ((strstr(match, captiveURL) == NULL) && (strstr(captiveIPAddr, inet_ntoa(*(struct in_addr *) &iph->daddr)) == NULL))
				{
					//status = send_redirect (qh, id, payload, captiveURL);
					flagCaptiveURL = 1;
					//return status;
    				memset(GlbRedirectUrl, 0, sizeof(GlbRedirectUrl));
    				sprintf(GlbRedirectUrl, "%s", captiveURL);
					return PKT_REDIRECT;
				}
			}
		}	
	}	
#endif

#if defined(AEI_VDSL_CUSTOMER_NCS)
    AEI_HandleWebActivityLog(match, iph);
#endif
	for (current = purl; current != NULL; current = current->next)
	{
		if (current->folder[0] != '\0')
		{
			folder = strstr(match, current->folder);
		}

		if ( (url = strstr(match, current->website)) != NULL ) 
		{
			if (strcmp(listtype, "Exclude") == 0) 
			{
				if ( (folder != NULL) || (current->folder[0] == '\0') )
				{
#if defined(AEI_VDSL_CUSTOMER_NCS)
                    if (strstr(current->lanIP, "all") != NULL) {        //block all PCs
                        printf("All####This page is blocked by Exclude list!, into send_redirect\n");
#if defined(AEI_VDSL_CAPTIVE_PAGES)
						return PKT_REDIRECT;
#else                        
                        return PKT_DROP;
#endif                        
                    } else {    //block specific PCs
                        struct in_addr lanIP;
                        inet_aton(current->lanIP, &lanIP);
                        if (lanIP.s_addr == iph->saddr) {
                            printf("IP####This page is blocked by Exclude list!, into send_redirect\n");
#if defined(AEI_VDSL_CAPTIVE_PAGES)
                            return PKT_REDIRECT;
#else                            
                            return PKT_DROP;
#endif                            
                        }
                    }
#else
#ifdef UFD_DEBUG
					printf("####This page is blocked by Exclude list!");
#endif
					return PKT_DROP;
#endif
				}
				else 
				{
#ifdef UFD_DEBUG
					printf("###Website hits but folder no hit in Exclude list! packets pass\n");
#endif
					return PKT_ACCEPT;
				}
			}
			else 
			{
				if ( (folder != NULL) || (current->folder[0] == '\0') )
				{
#ifdef UFD_DEBUG
					printf("####This page is accepted by Include list!");
#endif
					return PKT_ACCEPT;
				}
				else 
				{
#ifdef UFD_DEBUG
					printf("####Website hits but folder no hit in Include list!, packets drop\n");
#endif
					return PKT_DROP;
				}
			}
		}
	}

	if (url == NULL) 
	{
		if (strcmp(listtype, "Exclude") == 0) 
		{
#ifdef UFD_DEBUG
			printf("~~~~No Url hits!! This page is accepted by Exclude list!\n");
#endif
			return PKT_ACCEPT;
		}
		else 
		{
#ifdef UFD_DEBUG
			printf("~~~~No Url hits!! This page is blocked by Include list!\n");
#endif
			return PKT_DROP;
		}
	}

#ifdef UFD_DEBUG
	printf("~~~None of rules can be applied!! Traffic is allowed!!\n");
#endif
	return PKT_ACCEPT;

}