void HandlePacket()
#endif
{
    int status;

    if (iv.drop)
    {
#ifndef IPFW
        status = ipq_set_verdict(ipqh, m->packet_id, NF_DROP, 0, NULL);
        if (status < 0)
        {
            ipq_perror("NF_DROP: ");
        }
#endif
        if (iv.reject)
        {
#ifndef IPFW
	    if(pv.layer2_resets)
	    {
		RejectLayer2(m);
	    }
	    else
#endif
	    {
		RejectSocket();
	    }
        }
    }
#ifndef IPFW
    else if (!iv.replace)
    {
        status = ipq_set_verdict(ipqh, m->packet_id, NF_ACCEPT, 0, NULL);
        if (status < 0)
        {
            ipq_perror("NF_ACCEPT: ");
        }
    }
    else
    {
        status = ipq_set_verdict(ipqh, m->packet_id, NF_ACCEPT, 
                 m->data_len, m->payload);
        if (status < 0)
        {
            ipq_perror("NF_ACCEPT: ");
        }
    }
#endif
}
void * _pkg_reinject()
{
    struct list_head *pos;
    packet_list_t *element;
    int is_first = 1;
    static unsigned int count = 0;
    do {
        usleep(100);
        if (!list_empty(&pkg_list)) {
            if (is_first) {
                is_first = 0;
                //usleep(200000);
                //sleep(2);
                printf("receive number packets in delay: %d\n", count_packet);
            }
            pos = pkg_list.next;
            element = list_entry(pos, packet_list_t, list);
            ipq_set_verdict(h, element->pmsg->packet_id, NF_ACCEPT, 0, NULL);
            printf("Sending packet id = %lu, number packet = %u \n", element->pmsg->packet_id, ++count);
            usleep(5000); // 5ms send 1 pkg
            list_del(pos);
            SAFE_FREE(element);
        }
    } while (1);
}
Example #3
0
File: main.c Project: ebichu/dd-wrt
// This is called randomly, atleast once every 100mS
int BackgroundProcessing(void){

	long PacketAge;
	int Queue, i;
	
	// Get current time
	struct timeval NowTime;
	gettimeofday(&NowTime, NULL);

	// Wait for access to the packet queue
	pthread_mutex_lock(&PacketQueueMutex);

	for(Queue = 0; Queue < PacketQueues; Queue++){

		// Loop
		while(PacketQueueHead[Queue] != PacketQueueTail[Queue]){

			// Work out age in mS
			PacketAge = (NowTime.tv_sec - ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->timestamp_sec) * 1000;
			if(NowTime.tv_usec < ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->timestamp_usec)
				 PacketAge += (1000000 - ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->timestamp_usec + NowTime.tv_usec) / 1000;
			else
				 PacketAge += (NowTime.tv_usec - ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->timestamp_usec) / 1000;

			// If the packet is old
			if(PacketAge > STALETIME){

				// Drop the packet
				ipq_set_verdict(hIpq, ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->packet_id, NF_DROP, 0, NULL);

				// Move the Tail offset
				PacketQueueTail[Queue]++;
				if(PacketQueueTail[Queue] >= Config.Queue)
					PacketQueueTail[Queue] = 0;
			}
			else{
				// As the queue should be chronological, we can assume if this
				// packet is not too old, later ones won't be either
				break;
			}
		}
	}

	// Release access to the packet queue
	pthread_mutex_unlock(&PacketQueueMutex);

	// Delete old connections from contrack
	for(i = 0; i < MaxConTrack; i++){

		// If more than 30s since last packet
		if(Age(ConTrack[i].LastTime) > 30000 && ConTrack[i].Flags & CT_FlagValid){
			// Clear the valid flag
			ConTrack[i].Flags &= ~CT_FlagValid;
		}
	}

	return 1;
}
Example #4
0
int SendPackets(int MaxPackets, int MaxBytes){

	int Queue, Packets, Bytes, PacketBytes;

	// Clear counts
	Packets = 0;
	Bytes = 0;

	// Wait for access to the packet queue
	pthread_mutex_lock(&PacketQueueMutex);

	// Loop thorugh each queue
	for(Queue = 0; Queue < PacketQueues; Queue++){

		// Loop for as many packets/bytes as we're allowed to send
		while(PacketQueueHead[Queue] != PacketQueueTail[Queue]){

			// Check if we'd go over the packet limit
			if(Packets + 1 > MaxPackets)
				break;

			PacketBytes = ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->data_len;

			// Check if we'd go over the byte limit
			if(Bytes + PacketBytes > MaxBytes)
				break;

			// Send the oldest packet
			ipq_set_verdict(hIpq, ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->packet_id, NF_ACCEPT, 0, NULL);

			// Add to running totals
			Packets++;
			Bytes += PacketBytes;

			// Store stats
			ClientStats.Packets[Queue]++;
			ClientStats.Bytes[Queue] += PacketBytes;
			ClientStats.BytesAvg[Queue] += PacketBytes;

			// Move the Tail offset
			PacketQueueTail[Queue]++;
			if(PacketQueueTail[Queue] >= Config.Queue)
				PacketQueueTail[Queue] = 0;
		}
	}

	// Release access to the packet queue
	pthread_mutex_unlock(&PacketQueueMutex);

	return 1;
}
Example #5
0
static void ip_noise_delayer_release_function(ip_noise_message_t * m, void * context)
{
#ifndef __KERNEL__    
    struct ipq_handle * h = (struct ipq_handle *)context;
#else
#define h 5
#endif
    int status;
    status = ipq_set_verdict(h, m->m->packet_id, NF_ACCEPT, 0, NULL);

    if (status < 0)
    {
        die(h);
    }    
    free(m);
}
Example #6
0
static int ipq_receive_peer(ipq_queue_t *q, ipq_peer_msg_t *m,
                            unsigned char type, unsigned int len)
{

	int status = 0;
	int busy;
		
	spin_lock_bh(&q->lock);
	busy = (q->terminate || q->flushing);
	spin_unlock_bh(&q->lock);
	if (busy)
		return -EBUSY;
	if (len < sizeof(ipq_peer_msg_t))
		return -EINVAL;
	switch (type) {
		case IPQM_MODE:
			switch (m->msg.mode.value) {
				case IPQ_COPY_META:
					q->peer.copy_mode = IPQ_COPY_META;
					q->peer.copy_range = 0;
					break;
				case IPQ_COPY_PACKET:
					q->peer.copy_mode = IPQ_COPY_PACKET;
					q->peer.copy_range = m->msg.mode.range;
					if (q->peer.copy_range > 0xFFFF)
						q->peer.copy_range = 0xFFFF;
					break;
				default:
					status = -EINVAL;
			}
			break;
		case IPQM_VERDICT:
			if (m->msg.verdict.value > NF_MAX_VERDICT)
				status = -EINVAL;
			else
				status = ipq_set_verdict(q,
				                         &m->msg.verdict,
				                         len - sizeof(*m));
			break;
		default:
			 status = -EINVAL;
	}
	return status;
}
Example #7
0
int main(int argc, char **argv)
{
	int status;
	unsigned char buf[BUFSIZE];
	struct ipq_handle *h;
            
	h = ipq_create_handle(0, PF_INET);
	if (!h)
		die(h);

	status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
	if (status < 0)
		die(h);

	do {
		status = ipq_read(h, buf, BUFSIZE, 0);
		if (status < 0)
			die(h);

		switch (ipq_message_type(buf)) {
			case NLMSG_ERROR:
				fprintf(stderr, "Received error message %d\n",
					ipq_get_msgerr(buf));
				break;
			case IPQM_PACKET:
				ipq_packet_msg_t *m = ipq_get_packet(buf);
				struct iphdr *ip = (struct iphdr*) m->payload;
				struct tcphdr *tcp = (struct tcphdr*) (m->payload + (4 * ip->ihl));  
				int port = htons(tcp->dest);
				status = ipq_set_verdict(h, m->packet_id,
							 NF_ACCEPT, 0, NULL);
				if (status < 0)
					die(h);
				break;
			default:
				fprintf(stderr, "Unknown message type!\n");
				break;
		}
	} while (1);

	ipq_destroy_handle(h);
	return 0;
}
Example #8
0
ip_noise_arbitrator_packet_logic_t * main_init_module(
        ip_noise_arbitrator_iface_t * * iface_ptr
        )
#endif
{
#ifndef __KERNEL__    
    int status;

    unsigned char message[IP_NOISE_MESSAGE_BUFSIZE];
    struct ipq_handle * h;

    ip_noise_messages_queue_t * packets_to_arbitrate_queue;
#endif
    int terminate = 0;
    
    ip_noise_decide_what_to_do_with_packets_thread_context_t * arbitrator_context;

#ifndef __KERNEL__
    pthread_t decide_what_to_with_packets_thread;
#endif    
    
    ip_noise_release_packets_thread_context_t * release_packets_context;
#ifndef __KERNEL__
    pthread_t release_packets_thread;
#endif
#ifndef __KERNEL__
    int check;
#endif
    ip_noise_delayer_t * delayer;

    ip_noise_arbitrator_data_t * data, * * data_ptr;
    ip_noise_flags_t flags;
    ip_noise_arbitrator_iface_t * arb_iface;
#ifndef __KERNEL__
    pthread_t arb_iface_thread;
#endif

    ip_noise_arbitrator_switcher_t * arb_switcher;
#ifndef __KERNEL__
    pthread_t arb_switcher_thread;
#endif
#ifdef __KERNEL__
    ip_noise_arbitrator_packet_logic_t * packet_logic;
#endif

    printf("IP-Noise Simulator\n");
    printf("Written by Shlomi Fish & Roy Glasberg and supervised by Lavy Libman\n");
    printf("The Technion - Israel Institute of Technolgy\n");
    printf("(c) 2001\n");

#ifndef __KERNEL__
    h = ipq_create_handle(0, PF_INET);
    if (h == NULL)
    {
        die(h);
    }

    status = ipq_set_mode(h, IPQ_COPY_PACKET, sizeof(message));

    if (status < 0)
    {
        die(h);
    }
#endif

#ifndef __KERNEL__
    packets_to_arbitrate_queue = ip_noise_messages_queue_alloc();
#endif

    delayer = ip_noise_delayer_alloc(
            ip_noise_delayer_release_function, 
#ifndef __KERNEL__
            (void *)h
#else
            NULL
#endif            
            );
    
    release_packets_context = malloc(sizeof(ip_noise_release_packets_thread_context_t));
    release_packets_context->delayer = delayer;
    release_packets_context->terminate = &terminate;

#ifndef __KERNEL__
    check = pthread_create(
        &release_packets_thread,
        NULL,
        release_packets_thread_func,
        (void *)release_packets_context
        );

    if (check != 0)
    {
        fprintf(stderr, "Could not create the release packets thread!\n");
        exit(-1);
    }
#endif

    data = ip_noise_arbitrator_data_alloc();
    data_ptr = malloc(sizeof(*data_ptr));
    *data_ptr = data;

    flags.reinit_switcher = 1;

    arb_switcher = ip_noise_arbitrator_switcher_alloc(data_ptr, &flags, &terminate);

#ifndef __KERNEL__
    check = pthread_create(
        &arb_switcher_thread,
        NULL,
        arb_switcher_thread_func,
        (void *)arb_switcher
        );

    if (check != 0)
    {
        fprintf(stderr, "Could not create the arbitrator switcher thread!\n");
        exit(-1);
    }
#endif

    arb_iface = ip_noise_arbitrator_iface_alloc(data_ptr, arb_switcher, &flags);

#ifdef __KERNEL__
    /*
     * We assign arb_iface to iface_ptr so it can later be de-allocated
     * inside the module ip_queue.c.
     *
     * */
    *iface_ptr = arb_iface;
#endif

#ifndef __KERNEL__
    check = pthread_create(
        &arb_iface_thread,
        NULL,
        arb_iface_thread_func,
        (void *)arb_iface
        );

    if (check != 0)
    {
        fprintf(stderr, "Could not create the arbitrator interface thread!\n");
        exit(-1);
    }
#endif


    arbitrator_context = malloc(sizeof(ip_noise_decide_what_to_do_with_packets_thread_context_t));
#ifndef __KERNEL__
    arbitrator_context->queue = packets_to_arbitrate_queue ;
    arbitrator_context->h = h;
#endif    
    arbitrator_context->terminate = &terminate;
    arbitrator_context->delayer = delayer;
    arbitrator_context->data = data_ptr;
    arbitrator_context->flags = &flags;

#ifndef __KERNEL__
    check = pthread_create(
        &decide_what_to_with_packets_thread,
        NULL,
        ip_noise_decide_what_to_do_with_packets_thread_func,
        (void *)arbitrator_context
        );

    if (check != 0)
    {
        fprintf(stderr, "Could not create the arbitrator thread!\n");
        exit(-1);
    }
#else
    packet_logic = ip_noise_arbitrator_packet_logic_alloc(data_ptr, &flags);

    return packet_logic;
    
#endif  

#ifndef __KERNEL__
    do
    {
        status = ipq_read(h, message, sizeof(message), 0);
        if (status < 0)
        {
            /* die(h); */
        }
        switch(ipq_message_type(message))
        {
            case NLMSG_ERROR:
                fprintf(
                    stderr, 
                    "Received error message %d\n",
                    ipq_get_msgerr(message)
                    );
                break;

            case IPQM_PACKET:
            {
                ip_noise_message_t * msg_with_time;
                struct timezone tz;

#if 0
                static int num = 0;
#endif

                msg_with_time = malloc(sizeof(ip_noise_message_t));

                /* We are copying the entire buffer, because otherwise we get
                 * errors, since ipq_get_packet still relies on this buffer
                 * for reference */

                memcpy(msg_with_time->message, message, sizeof(msg_with_time->message));

                msg_with_time->m = ipq_get_packet(msg_with_time->message);
                
                gettimeofday(&(msg_with_time->tv), &tz);
                
                
                ip_noise_messages_queue_enqueue(
                    packets_to_arbitrate_queue,
                    msg_with_time
                    );

#if 0
                printf("Received a message! (%i)\n", num++);
#endif

#if 0
                status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);

                if (status < 0)
                {
                    die(h);
                }
#endif
                break;
            }

            default:
                fprintf(stderr, "Unknown message type!\n");
                break;                        
        }
    } while (1);
#endif

    ipq_destroy_handle(h);

    return 0;
}
int main(int argc, const char ** argv)
{
    static u8 buf[LTP_MAX_BUF_SIZE];
    struct ipq_handle *h = ipq_create_handle(0, NFPROTO_IPV4);

    if (!h) {
        LTP_ERROR_LOG("ipq_create_handle failed\n");
        goto error1;
    }

    int ret = ipq_set_mode(h, IPQ_COPY_PACKET, LTP_MAX_BUF_SIZE);
    if (-1 == ret) {
        LTP_ERROR_LOG("ipq_set_mode failed\n");
        goto error2;
    }

    register_exit_signal_handler();

    while (!g_ltp_daemon_exit) {
        ret = ipq_read(h, buf, LTP_MAX_BUF_SIZE, 0);
        if (ret < 0) {
            LTP_ERROR_LOG("ipq_read failed\n");
            goto error2;
        }
        ret = ipq_message_type(buf);
        if (likely(IPQM_PACKET == ret)) {
            LTP_DEBUG_LOG("Get one packet\n");
            ipq_packet_msg_t *pkt = ipq_get_packet(buf);
            if (likely(pkt)) {
            
                if (LTP_OK != ltp_ipq_rcv(pkt)) {
                    // Need not the error handler
                    LTP_ERROR_LOG("ltp_ipq_rcv failed\n");
                }
                
                ret = ipq_set_verdict(h, pkt->packet_id, NF_DROP, pkt->data_len, pkt->payload);
                if (-1 == ret) {
                    LTP_ERROR_LOG("ipq_set_verdict failed\n");
                    goto error2;
                }
                
            }
            else {
                LTP_ERROR_LOG("ipq_get_packet failed\n");
                goto error2;
            }
        }
        else if (NLMSG_ERROR == ret) {
            LTP_ERROR_LOG("Recevie error msg(%d)\n", ipq_get_msgerr(buf));
            goto error2;
        }
        else {
            LTP_ERROR_LOG("Unknown type\n");
            goto error2;
        }
    }

    ipq_destroy_handle(h);

    return LTP_OK;

error2:
    ipq_destroy_handle(h);
    h = NULL;
error1:
    return LTP_ERR;
}
Example #10
0
void packet_send()
{
	ipq_set_verdict(h, ipq_get_packet(my_pkt_head.head->buf)->packet_id, NF_ACCEPT, 0, NULL);
	printf("%ld packet_id send\n", ipq_get_packet(my_pkt_head.head->buf)->packet_id);
	dequeue();
}
Example #11
0
void *processing(void *t){
	packet_ctx *ctx;
	int status;	

	do{
		/*********************************************
		* process쓰레드 들이 동시에 큐에 달라 붙어서 같은 자료를 처리 할수 있다.
		* 이 경우 어느 한쪽에서 메시지를 처리하고 메모리를 해제하면 나머지 쪽에서 문제가 생길수 있다. 
		* 그래서 큐에서 하나의 쓰레드에만 값을 넘겨 줘야 한다.
		**************************************************/
		pthread_mutex_lock(&queueLock);/*{{{*/
		if(ReadyQueue.currentSize>0){
			ctx = safe_dequeue(&ReadyQueue);
			pthread_mutex_unlock(&queueLock);
		}
		else{
			pthread_mutex_unlock(&queueLock);
			continue;
		}
/*}}}*/

	//에러 처리
		if(ctx==NULL) continue;/*{{{*/
			dlog(0,"processing\n");
			if (status < 0){
				die(ctx->h);
			}
/*}}}*/
                        
			switch (ipq_message_type(ctx->buf)) {
				//에러 처리
				case NLMSG_ERROR:
					dlog(0, "Received error message %d\n",
					ipq_get_msgerr(ctx->buf));
					break;
				case IPQM_PACKET: {
					/**********************
					*초기 변수 설정
					*
					*************************/
					ipq_packet_msg_t *m = ipq_get_packet(ctx->buf);/*{{{*/
					struct tcphdr *tcp=NULL;
					struct iphdr *ip=NULL;
					unsigned char *packet = NULL;
					unsigned char *tcpPayload=NULL;
					module_prototype module= NULL;
					int result=0;
					GListInfo *moduleList;
					sin_packet_info *packetInfo = malloc(sizeof(sin_packet_info));

					memset(packetInfo,0,sizeof(sin_packet_info));
					
					


					dump_ipq(m);/*}}}*/

					if(m->data_len > sizeof(struct iphdr)){
						packet = (unsigned char *)m + sizeof(ipq_packet_msg_t);//sizeof(*m)
					}
					
					ip =(struct iphdr *) packet;
					if(ip->protocol != 6){ //6 is TCP protocol number
						ipq_set_verdict(ctx->h,m->packet_id,NF_ACCEPT,0,NULL);
					}
					
					tcp =(struct tcphdr *) packet + sizeof(struct iphdr);
					dump_ip((struct iphdr *)packet);
					dump((char *)tcp,240);
					
					/***********************************
						packetInfo 설정

					***********************************/
				
					if(strcmp(m->outdev_name,"eth0")==0){
						packetInfo->direction = C2OUT;
					}else if(strcmp(m->indev_name,"eth0")==0){
						packetInfo->direction = OUT2C;
					}
					packetInfo->verdicted = 0;
					packetInfo->modified=0;
					packetInfo->action =SIN_ACCEPT;

				

					/************************
						분류기

					************************/
					/*
					while(0){
						char bound=-1;
						gpointer n;
						if(bound==C2O){//만일 패킷이 클라이언트에서 외부로 나가는 경우이면
							
							n = tree_find(&BWList, ip->daddr, NULL);
							if(n != NULL){
								cond *data = (cond *)n;
								if(data->type==DENY){
									if(data->action == CONNECTION_CLOSE){
										sessionManager(ctx->h,m->packet_id,CONNECTION_CLOSE);
										continue;// 다음 패킷 처리
								}
								}
								if(data->type==ALLOW){
									if(data->action == CONNECTION_ALLOW){
										sessionManager(ctx->h,m->packet_id,CONNECTION_ALLOW);
										continue;// 다음 패킷 처리

									}
								}
							}
						}
					}
					*/
					


							



					/**********************
					*  run modules 
					************************/					
					glist_rewind(&ModuleList);
					while((module=(module_prototype)glist_next(&ModuleList))!=NULL){
						result = (*module)(ctx->h,m,(const char*)tcp,240);
						/**********
						*허용이 아닌 경우 중단으로 해야 한다. 
						*이유는 ACCEPT이지만 다른 종류의 메시지를 보내야 하는 경우도 있기 때문이다.
						*다만 이 경우에 어떻게 하는게 좋을지 아직 모르겠다.
						***********/
						if(result == NF_DROP) break;
					}
					/*********************
					* 위에서 처리 한 결과대로 처리한다.
					* verdict는 한번만 호출되어야 하는것 같다.
					***********************/



					/********************
						윈도우 사이즈 조절
					*******************/
					if(result==NF_ACCEPT && ip->protocol == 6){
						uint16_t win;
						#if __BYTE_ORDER == __LITTLE_ENDIAN
							win = ntohs(tcp->window);
							if(win>MAXIMUM_WINDOW_SIZE){
								tcp->window =htons(MAXIMUM_WINDOW_SIZE);
								packetInfo->modified=1;
								//패킷을 수정 했으니 이것을 verdict 하도록 수정해야한다.

							}
						#elif __BYTE_ORDER == __BIG_ENDIAN
							if(win>MAXIMUM_WINDOW_SIZE) {
								tcp->window = MAXIMUM_WINDOW_SIZE;
								packetInfo->modified=1;
								//패킷을 수정 했으니 이것을 verdict 하도록 수정해야한다. 
						#endif
					}
					if(	packetInfo->modified == 0){
						status = ipq_set_verdict(ctx->h, m->packet_id,result, 0, NULL);
					}else{
						/*******************
							패킷 수정됐으니 체크섬 재계산-_-
						*******************/
						status = ipq_set_verdict(ctx->h, m->packet_id,result, 0,NULL);
					}

					if (status < 0) die(ctx->h);
					break;
        		                }
				default:
					fprintf(stderr, "Unknown message type!\n");
					break;
	}
	} while (1);
        
	ipq_destroy_handle(ctx->h);
	return 0;


}
Example #12
0
static int ipq_daq_acquire (
    void* handle, int cnt, DAQ_Analysis_Func_t callback, void* user)
{
    IpqImpl* impl = (IpqImpl*)handle;

    int n = 0;
    DAQ_PktHdr_t hdr;

    // If cnt is <= 0, don't limit the packets acquired.  However,
    // impl->count = 0 has a special meaning, so interpret accordingly.
    impl->count = (cnt == 0) ? -1 : cnt;
    hdr.device_index = 0;
    hdr.flags = 0;

    while ( impl->count < 0 || n < impl->count )
    {
        int ipqt, status = ipq_read(
            impl->ipqh, impl->buf, MSG_BUF_SIZE, impl->timeout);

        if ( status <= 0 )
        {
            if ( status < 0 )
            {
                DPE(impl->error, "%s: ipq_read=%d error %s",
                    __FUNCTION__, status, ipq_errstr());
                return DAQ_ERROR;
            }
            return 0;
        }

        ipqt = ipq_message_type(impl->buf);

        if ( ipqt == IPQM_PACKET )
        {
            DAQ_Verdict verdict;
            ipq_packet_msg_t* ipqm = ipq_get_packet(impl->buf);
            SetPktHdr(impl, ipqm, &hdr);
            impl->stats.hw_packets_received++;

            if (
                impl->fcode.bf_insns &&
                sfbpf_filter(impl->fcode.bf_insns, ipqm->payload,
                    hdr.caplen, hdr.caplen) == 0
            ) {
                verdict = DAQ_VERDICT_PASS;
                impl->stats.packets_filtered++;
            }
            else
            {
                verdict = callback(user, &hdr, (uint8_t*)ipqm->payload);
                impl->stats.verdicts[verdict]++;
                impl->stats.packets_received++;
            }
            if ( impl->passive ) verdict = DAQ_VERDICT_PASS;

            switch ( verdict ) {
            case DAQ_VERDICT_BLOCK:
            case DAQ_VERDICT_BLACKLIST:
                status = ipq_set_verdict(
                    impl->ipqh, ipqm->packet_id, NF_DROP, 0, NULL);
                break;

            case DAQ_VERDICT_REPLACE:
                status = ipq_set_verdict(
                    impl->ipqh, ipqm->packet_id, NF_ACCEPT,
                    hdr.pktlen, ipqm->payload);
                break;

            case DAQ_VERDICT_PASS:
            case DAQ_VERDICT_WHITELIST:
            case DAQ_VERDICT_IGNORE:
            default:
                status = ipq_set_verdict(
                    impl->ipqh, ipqm->packet_id, NF_ACCEPT, 0, NULL);
                break;
            }
            if ( status < 0 )
            {
                DPE(impl->error, "%s: ipq_set_verdict=%d error %s",
                    __FUNCTION__, status, ipq_errstr());
                return DAQ_ERROR;
            }
            n++;
        }
        else
        {
            // NLMSG_ERROR is supposed to be the only other valid type
            status = ipq_get_msgerr(impl->buf);
            DPE(impl->error, "%s: ipq_message_type=%d error=%d %s",
                __FUNCTION__, ipqt, status, ipq_errstr());
            // ipq_message_type=2 error=1 Timeout
            // keep looping upon timeout or other errors
        }
    }
    return 0;
}
Example #13
0
File: pfilter.c Project: BobBall/sm
int main(int argc, char **argv)
{
        int verdict;
        unsigned char buf[BUFSIZE];
        struct ipq_handle *h;
        int cfd;
        int daemonize = 1;

        if (argc > 1) {
            if (!strcmp(argv[1], "-nd")) {
                daemonize = 0;
            }
        }

        srand(0);

        cfd = make_ipc();
        if ( cfd < 0 )
                exit(1);

        printhelp();

        h = make_ipq();

        if (daemonize) {
                FILE *logfile = 0;
                int pid;

                logfile = fopen(LOGFILE, "a");
                if (!logfile) {
                        perror("Failed to open " LOGFILE);
                        exit(1);
                }

                if ( daemon(0, 0) < 0 ) {
                        perror("Failed to daemonize");
                        exit(1);
                }

                if ( dup2(fileno(logfile), STDERR_FILENO) < 0 )
                        abort();
                fclose(logfile);

                pid = writepid();
                if (pid < 0)
                        return -1;

                /* disable low water mark check for io pages */
                if (setpriority(PRIO_PROCESS, pid, PRIO_SPECIAL_IO)) {
                        perror("Unable to prioritize tapdisk proc");
                        exit(1);
                }
                
                TRACE("Start pfilter PID %d\n", pid);
        }

        do {
                ssize_t status;
                int type;

                status = ipq_read(h, buf, BUFSIZE, 0);
                if (status < 0)
                        fail_retry(&h);

                type = ipq_message_type(buf);
                switch (type) {
                        case NLMSG_ERROR:
                                TRACE("pfilter: Received error message %d\n",
                                      ipq_get_msgerr(buf));
                                break;

                        case IPQM_PACKET: {
                                ipq_packet_msg_t *m = ipq_get_packet(buf);

                                verdict = filter();

                                status = ipq_set_verdict(h, m->packet_id,
                                                         verdict, 0, NULL);
                                if (status < 0)
                                        fail_retry(&h);

                                trace_data(verdict);
                                break;
                        }

                        default:
                                TRACE("pfilter: Unknown message type: %d\n", type);
                                break;
                }
        } while (1);

        ipq_destroy_handle(h);
        return 0;
}
Example #14
0
// This is the main entry point in to the control code
// and will be run in it's own thread
void *ControlRun(void *pParam){

	struct sockaddr_in FromAddr;
	socklen_t SockaddrLen;
	struct timeval	NowTime;
	BYTE PacketBuffer[max(sizeof(MASTERPACKET), sizeof(CLIENTPACKET)) + 2];
	int PacketSize, i, j;
	//pthread_t idWriteStatsFileThread;

	// Clear stats
	memset(&ClientStats, 0, sizeof(ClientStats));
	
	// Open UDP connection to server
	memset(&MasterAddr, 0, sizeof(MasterAddr));
	MasterAddr.sin_family = AF_INET;
	MasterAddr.sin_addr.s_addr = inet_addr(Config.MasterIp);
	MasterAddr.sin_port = htons(Config.MasterPort);

	hControlPort = socket(PF_INET, SOCK_DGRAM, 0);
	if(hControlPort < 0){
		Log(LOG_ERR, "Failed to open client socket");
		return NULL;
	}

	// Bind it to a local port
	memset(&LocalAddr, 0, sizeof(LocalAddr));
	LocalAddr.sin_family = AF_INET;
	LocalAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
	LocalAddr.sin_port = htons(0);

	if(bind(hControlPort, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr)) != 0){
		close(hControlPort);
		Log(LOG_ERR, "Failed to bind to client port");
		return NULL;
	}

	// Get initial wireless data
	GetWirelessState();

	// Store intial background processing time
	gettimeofday(&LastCtrlBackgroundTime, NULL);
	LastCtrlBackgroundTime.tv_sec -= 8;

	// Set the initial status
	ClientStatus = CS_REGISTER;

	// Send register packet
	SendRegisterPacket();

	// Set an initial last Rx time
	gettimeofday(&LastRxActivityTime, NULL);

	// Setup cleanup function (closes the port)
	pthread_cleanup_push((void*)ControlCleanup, NULL);

	// While we should run (helps exit a thread cleanly)
	while(!ExitControlThread){

		struct timeval Timeout;
		fd_set readfds;
		int SelRet;

		FD_ZERO(&readfds);
		FD_SET(hControlPort, &readfds);

		// Wait 2 sec for UDP data
		Timeout.tv_sec = 2;
		Timeout.tv_usec = 0;
		SelRet = select(hControlPort+1, &readfds, NULL, NULL, &Timeout);

		// Error in select
		if(SelRet < 0){

			// Select error
			Log(LOG_ERR, "Error waiting for master packet");
		}
		// Data pending
		else if(SelRet > 0){

			// Get packet from master
			SockaddrLen = sizeof(FromAddr);
			PacketSize = recvfrom(hControlPort, PacketBuffer, sizeof(PacketBuffer), 0, (struct sockaddr *)&FromAddr, &SockaddrLen);

			// Check packet size
			if(PacketSize != sizeof(MASTERPACKET) + 2){

				// Wrong sized packet
				Log(LOG_ERR, "Client got packet of incorrect size");
			}
			else{

				// Check the checksum
				for(i = 0, j = 0; i < sizeof(MASTERPACKET); i++){
					j <<= 8;
					j += PacketBuffer[i];
				}
				if(PacketBuffer[i] != (USHORT)j){

					// Corrupted packet
					Log(LOG_ERR, "Client got corrupted packet");
				}
				else{

					int Packets, Bytes, Queue, k;

					if(ClientStatus != CS_CONNECTED)
						Log(LOG_INFO, "Client registered");

					// Update the status and last activity time
					ClientStatus = CS_CONNECTED;
					gettimeofday(&LastRxActivityTime, NULL);

					// Incriment poll count
					ClientStats.Polls++;

					// Send Packets up to allowed amount
					SendPackets(((MASTERPACKET*)PacketBuffer)->MaxPacketsToSend, ((MASTERPACKET*)PacketBuffer)->MaxBytesToSend);

					// Wait for access to the packet queue
					pthread_mutex_lock(&PacketQueueMutex);

					// Work out packets/bytes left in queues
					Packets = 0;
					Bytes = 0;
					for(Queue = 0; Queue < PacketQueues; Queue++){
						k = PacketQueueTail[Queue];
						while(PacketQueueHead[Queue] != k){
							Packets++;
							Bytes += ((ipq_packet_msg_t *)&PacketQueue[Queue][k * sizeof(struct ipq_packet_msg)])->data_len;
							k++;
							if(k >= Config.Queue)
								k = 0;
						}
					}

					// Release access to the packet queue
					pthread_mutex_unlock(&PacketQueueMutex);

					// Send 'done' packet
					memset(PacketBuffer, 0, sizeof(PacketBuffer));
					((CLIENTPACKET*)PacketBuffer)->TypeId = CLIENTID_END;
					((CLIENTPACKET*)PacketBuffer)->Rate = CurrentRate;
					((CLIENTPACKET*)PacketBuffer)->Signal = CurrentSignal;
					((CLIENTPACKET*)PacketBuffer)->Noise = CurrentNoise;
					((CLIENTPACKET*)PacketBuffer)->PacketsInQueue = Packets;
					((CLIENTPACKET*)PacketBuffer)->BytesInQueue = Bytes;
					for(i = 0, j = 0; i < sizeof(CLIENTPACKET); i++){
						j <<= 8;
						j += PacketBuffer[i];
					}
					PacketBuffer[i] = (USHORT)j;
					sendto(hControlPort, &PacketBuffer, sizeof(CLIENTPACKET)+2, 0, (struct sockaddr *)&MasterAddr, sizeof(MasterAddr));

					// Update the last activity time
					gettimeofday(&LastTxActivityTime, NULL);
				}
			}
		}

		// Do background processing here, this should run at least every 2 sec

		// Get current time
		gettimeofday(&NowTime, NULL);

		// If no Tx or Rx recently
		if(NowTime.tv_sec > LastRxActivityTime.tv_sec + SERVERREREGISTER &&
			NowTime.tv_sec > LastTxActivityTime.tv_sec + SERVERREREGISTER){

			// Reregister
			SendRegisterPacket();
		}

		// If no Rx for ages
		if(NowTime.tv_sec > LastRxActivityTime.tv_sec + SERVERTIMEOUT && ClientStatus != CS_NOSERVER){

			Log(LOG_INFO, "Client lost master connection");

			// Wait for access to the packet queue
			pthread_mutex_lock(&PacketQueueMutex);

			for(i = 0; i < PacketQueues; i++){

				// Send any/all packets in queue
				while(PacketQueueHead[i] != PacketQueueTail[i]){

					// Send the packet
					ipq_set_verdict(hIpq, ((ipq_packet_msg_t *)&PacketQueue[i][PacketQueueTail[i] * sizeof(struct ipq_packet_msg)])->packet_id, NF_ACCEPT, 0, NULL);

					PacketQueueTail[i]++;
					if(PacketQueueTail[i] >= Config.Queue)
						PacketQueueTail[i] = 0;
				}
			}

			// Release access to the packet queue
			pthread_mutex_unlock(&PacketQueueMutex);

			// Update the status to allow packets straight through
			ClientStatus = CS_NOSERVER;
		}

		// If no background processing for 10 sec (approx.)
		if(NowTime.tv_sec >= LastCtrlBackgroundTime.tv_sec + 10){

			// Update wireless data
			GetWirelessState();

			// Store intial background processing time
			gettimeofday(&LastCtrlBackgroundTime, NULL);

			if(Config.StatsFilename[0] != 0x00){
				// Start file write function in own threa
				//idWriteStatsFileThread = 0;
				//pthread_create(&idWriteStatsFileThread, NULL, &WriteStatsFile, NULL);
				// TODO: Figure out why doing it in a thread dies sooner or later (no further updates)
				WriteStatsFile(NULL);
			}

			//Reset poll count
			ClientStats.Polls = 0;
		}
	}

	// Call and clear cleanup function
	pthread_cleanup_pop(1);

	return NULL;
}
int main(int argc, char **argv)
{
   int status, i;
   unsigned int payload_len, payload_offset;
   unsigned char buf[BUFSIZE], listtype[8];
   struct ipq_handle *h;
   unsigned char *match, *folder, *url;
   PURL current;

   strcpy (listtype, argv[1]);
   get_url_info();

   h = ipq_create_handle(0, PF_INET);
   if (!h)
   {
      die(h);
   }

   status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
   if (status < 0)
   {
      die(h);
   }

   do
   {
      memset(buf, 0, sizeof(buf));
      status = ipq_read(h, buf, BUFSIZE, 0);
      if (status < 0)
      {
         die(h);
      }

      switch (ipq_message_type(buf)) 
      {
         case NLMSG_ERROR:
         {
            fprintf(stderr, "Received error message %d\n",
            ipq_get_msgerr(buf));
            break;
         }

         case IPQM_PACKET:  
         {
            ipq_packet_msg_t *m = ipq_get_packet(buf);
            char decision = 'n';
            struct iphdr *iph = ((struct iphdr *)m->payload);
            struct tcphdr *tcp = (struct tcphdr *)(m->payload + (iph->ihl<<2));
            match = folder = url = NULL;
            payload_offset = ((iph->ihl)<<2) + (tcp->doff<<2);
            payload_len = (unsigned int)ntohs(iph->tot_len) - ((iph->ihl)<<2) + (tcp->doff<<2);
            match = (char *)(m->payload + payload_offset);

            if(strstr(match, "GET ") == NULL && strstr(match, "POST ") == NULL && strstr(match, "HEAD ") == NULL)
            {
               status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
//printf("****NO HTTP INFORMATION!!!\n");
               if (status < 0)
               {
                  die(h);
               }
								
               break;		  
            }
	    
            for (current = purl; current != NULL; current = current->next)
            {
               if (current->folder[0] != '\0')
               {
                  folder = strstr(match, current->folder);
               }
//printf("####payload = %s\n\n", match);

               if ( (url = strstr(match, current->website)) != NULL ) 
               {
                  if (strcmp(listtype, "Exclude") == 0) 
                  {
                     if ( (folder != NULL) || (current->folder[0] == '\0') )
                     {
                        status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL);
//printf("####This page is blocked by Exclude list!");
                        decision = 'y';
										
                     }
                     else 
                     {
                        status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
//printf("###Website hits but folder no hit in Exclude list! packets pass\n");
                        decision = 'y';
                     }

                     if (status < 0)
                     {
                        die(h);
                     }
								
                     break;
									
                  }
                  else 
                  {
                     if ( (folder != NULL) || (current->folder[0] == '\0') )
                     {
                        status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
//printf("####This page is accepted by Include list!");
                        decision = 'y';
                     }
                     else 
                     {
                        status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL);
//printf("####Website hits but folder no hit in Include list!, packets drop\n");
                        decision = 'y';
                     }
										
                     if (status < 0)
                     {
                        die(h);
                     }

                     break;
                  }
               }
            }

            if (url == NULL) 
            {
               if (strcmp(listtype, "Exclude") == 0) 
               {
                  status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
//printf("~~~~No Url hits!! This page is accepted by Exclude list!\n");
                  decision = 'y';
               }
               else 
               {
                  status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL);
//printf("~~~~No Url hits!! This page is blocked by Include list!\n");
                  decision = 'y';
               }

               if (status < 0)
               {
                  die(h);
               }
            }
								
            if (decision == 'n') 
            {
               ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
//printf("~~~None of rules can be applied!! Traffic is allowed!!\n");
            }

            break;
         }

         default:
         {
            fprintf(stderr, "Unknown message type!\n");
            break;
         }
      }
   } while (1);

   ipq_destroy_handle(h);
   return 0;
}
Example #16
0
static void packet_input(int fd)
#endif
{
    rt_table_t *fwd_rt, *rev_rt, *repair_rt, *next_hop_rt;
    u_int32_t dest_addr, src_addr;
    u_int8_t rreq_flags = 0;
    unsigned int ifindex;
    struct ip_data *ipd = NULL;

#ifdef NS_PORT
    ifindex = NS_IFINDEX;	// Always use ns interface
    fwd_rt = NULL;		// In case of broadcast we provide no next hop
    ipd = NULL;			// No ICMP messaging

    struct hdr_cmn *ch = HDR_CMN(p);
    struct hdr_ip *ih = HDR_IP(p);

    src_addr = ih->saddr();
    dest_addr = ih->daddr();

    /*
       Any packets with our IP address as destination arriving here are
       packets that weren't caught by any agent attached to the node.
       Throw away those.
     */
    if (dest_addr == DEV_IFINDEX(ifindex).ipaddr) {
        DEBUG(LOG_WARNING, 0,
              "processPacket: Received orphan packet. Throwing it away.");
        Packet::free(p);
        return;
    }

    /* If this is a TCP packet and we don't have a route, we should
       set the gratuituos flag in the RREQ. */
    if (ch->ptype() == PT_TCP) {
        rreq_flags |= RREQ_GRATUITOUS;
    }
#else
    int status;
    char buf[BUFSIZE], *dev_name;
    ipq_packet_msg_t *pkt;
    struct iphdr *ip;
    struct udphdr *udp;
    struct icmphdr *icmp = NULL;

    ipq_read(h, buf, BUFSIZE, 0);

    status = ipq_message_type(buf);

    if (status == NLMSG_ERROR) {
        fprintf(stderr,
                "ERROR packet_input: Check that the ip_queue.o module is loaded.\n");
        die(h);
    }

    pkt = ipq_get_packet(buf);

#ifdef DEBUG_PACKET
    DEBUG(LOG_DEBUG, 0, "Protocol %u indev=%s outdev=%s\n",
          pkt->hw_protocol, pkt->indev_name, pkt->outdev_name);
#endif

    if (pkt->hook == 0)
        dev_name = pkt->indev_name;
    else if (pkt->hook == 3)
        dev_name = pkt->outdev_name;
    else
        dev_name = NULL;

    /* We know from kaodv.c that this is an IP packet */
    ip = (struct iphdr *) pkt->payload;

    dest_addr = ntohl(ip->daddr);
    src_addr = ntohl(ip->saddr);

    switch (ip->protocol) {
    /* Don't process AODV control packets (UDP on port 654). They
       are accounted for on the aodv socket */
    case IPPROTO_UDP:
        udp = (struct udphdr *) ((char *) ip + (ip->ihl << 2));
        if (ntohs(udp->dest) == AODV_PORT || ntohs(udp->source) == AODV_PORT)
            goto accept;
        break;
    /* If this is a TCP packet and we don't have a route, we should
       set the gratuituos flag in the RREQ. */
    case IPPROTO_TCP:
        rreq_flags |= RREQ_GRATUITOUS;
        break;
    /* We set the gratuitous flag also on ICMP ECHO requests, since
       the destination will also need a route back for the reply... */
    case IPPROTO_ICMP:
        icmp = (struct icmphdr *) ((char *) ip + (ip->ihl << 2));
        if (icmp->type == ICMP_ECHO)
            rreq_flags |= RREQ_GRATUITOUS;
#ifdef DEBUG_PACKET
        DEBUG(LOG_INFO, 0, "packet_input: setting G flag for RREQ to %s",
              ip_to_str(dest_addr));
#endif

        break;
    default:
    }

#ifdef DEBUG_PACKET
    DEBUG(LOG_INFO, 0, "packet_input: pkt to %s", ip_to_str(dest_addr));
#endif

    if (dev_name)
        ifindex = if_nametoindex(dev_name);
    else
        ifindex = 0;
#endif				/* NS_PORT */

    /* If the packet is not interesting we just let it go through... */
    if ((dest_addr == AODV_BROADCAST) ||
            (dest_addr == DEV_IFINDEX(ifindex).ipaddr) ||
            (dest_addr == DEV_IFINDEX(ifindex).broadcast) ||
            ((internet_gw_mode && this_host.gateway_mode)
             && ((dest_addr & DEV_IFINDEX(ifindex).netmask) !=
                 DEV_IFINDEX(ifindex).broadcast)))
        goto accept;

    /* Find the entry of the neighboring node and the destination  (if any). */
    rev_rt = rt_table_find_active(src_addr);
    fwd_rt = rt_table_find_active(dest_addr);


    /* If a packet is received on the NF_IP_PRE_ROUTING hook,
       i.e. inbound on the interface and we don't have a route to the
       destination, we should send an RERR to the source and then drop
       the package... */
    /* NF_IP_PRE_ROUTING = 0 */

#ifdef NS_PORT
#define PACKET_IS_INBOUND ch->direction() == hdr_cmn::UP
#else
#define PACKET_IS_INBOUND pkt->hook == 0
#endif

    if ((dest_addr != DEV_IFINDEX(ifindex).ipaddr) &&
            (!fwd_rt && PACKET_IS_INBOUND)) {
        rt_table_t *rt_entry;
        u_int32_t rerr_dest;
        RERR *rerr;

        DEBUG(LOG_DEBUG, 0, "packet_input: Sending RERR for unknown dest %s",
              ip_to_str(dest_addr));

        /* There is an expired entry in the routing table we want to send
           along the seqno in the RERR... */
        rt_entry = rt_table_find(dest_addr);

        if (rt_entry) {
            rerr = rerr_create(0, rt_entry->dest_addr, rt_entry->dest_seqno);
            rt_table_update_timeout(rt_entry, DELETE_PERIOD);
        } else
            rerr = rerr_create(0, dest_addr, 0);

        /* Unicast the RERR to the source of the data transmission if
         * possible, otherwise we broadcast it. */
        if (rev_rt)
            rerr_dest = rev_rt->next_hop;
        else
            rerr_dest = AODV_BROADCAST;

        aodv_socket_send((AODV_msg *) rerr, rerr_dest,
                         RERR_CALC_SIZE(rerr), 1, &DEV_IFINDEX(ifindex));

        if (wait_on_reboot) {
            DEBUG(LOG_DEBUG, 0, "packet_input: Wait on reboot timer reset.");
            timer_add_msec(&worb_timer, DELETE_PERIOD);
        }
#ifdef NS_PORT
        drop(p, DROP_RTR_NO_ROUTE);
#else
        status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);
        if (status < 0)
            die(h);
#endif
        return;
    }
    /* Check if the route is currently in repair. In that case just
       buffer the packet */
    repair_rt = rt_table_find(dest_addr);

    if (repair_rt && (repair_rt->flags & LREPAIR)) {
#ifdef NS_PORT
        packet_queue_add(p, dest_addr);
#else
        packet_queue_add(pkt->packet_id, dest_addr);
#endif
        return;
    }
    /*  update_timers:  */
    /* When forwarding a packet, we update the lifetime of the
       destination's routing table entry, as well as the entry for the
       next hop neighbor (if not the same). AODV draft 10, section
       6.2. */
    if (fwd_rt && dest_addr != DEV_IFINDEX(ifindex).ipaddr) {
        rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);

        next_hop_rt = rt_table_find_active(fwd_rt->next_hop);

        if (next_hop_rt && next_hop_rt->dest_addr != fwd_rt->dest_addr)
            rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);

    }
    /* Also update the reverse route and reverse next hop along the
       path back, since routes between originators and the destination
       are expected to be symmetric. */
    if (rev_rt) {
        rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);

        next_hop_rt = rt_table_find_active(rev_rt->next_hop);

        if (next_hop_rt && next_hop_rt->dest_addr != fwd_rt->dest_addr)
            rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);
    }
#ifdef DEBUG_PACKET
    DEBUG(LOG_INFO, 0, "packet_input: d=%s s=%s",
          ip_to_str(dest_addr), ip_to_str(src_addr));
#endif				/* DEBUG_PACKET */

    if (!fwd_rt || (fwd_rt->hcnt == 1 && (fwd_rt->flags & UNIDIR))) {
        /* Buffer packets... Packets are queued by the ip_queue_aodv.o module
           already. We only need to save the handle id, and return the proper
           verdict when we know what to do... */
#ifdef NS_PORT
        packet_queue_add(p, dest_addr);
#else
        packet_queue_add(pkt->packet_id, dest_addr);

        /* If the request is generated locally by an application, we save
           the IP header + 64 bits of data for sending an ICMP Destination
           Host Unreachable in case we don't find a route... */
        if (src_addr == DEV_IFINDEX(ifindex).ipaddr) {
            ipd = (struct ip_data *) malloc(sizeof(struct ip_data));
            if (ipd < 0) {
                perror("Malloc for IP data failed!");
                exit(-1);
            }
            ipd->len = (ip->ihl << 2) + 8;	/* IP header + 64 bits data (8 bytes) */
            memcpy(ipd->data, ip, ipd->len);
        } else
            ipd = NULL;
#endif
        rreq_route_discovery(dest_addr, rreq_flags, ipd);
        return;
    }

accept:

#ifdef NS_PORT
    if (fwd_rt)
        sendPacket(p, fwd_rt->next_hop, 0.0);
    else
        drop(p, DROP_RTR_NO_ROUTE);
#else
    status = ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 0, NULL);
    if (status < 0)
        die(h);
#endif
    return;
}
Example #17
0
File: main.c Project: ebichu/dd-wrt
// This is called when a packet message is received
int ProcessPacketMessage(ipq_packet_msg_t *pPacketMsg){

	struct timeval NowTime;
	int Queue;

	// If we're acting as a client
	if(Config.Flags & CONFIGFLAGS_CLIENT){

		// If we don't have a server connection
		if(ClientStatus == CS_NOSERVER){

			// Just let the packet straight through (fail safe)
			ipq_set_verdict(hIpq, pPacketMsg->packet_id, NF_ACCEPT, 0, NULL);
			return 1;
		}
	}

	// If we're acting as a self client
	if(Config.Flags & CONFIGFLAGS_SELFCLIENT){

		// If we don't have any clients
		if(ClientCount == 0){

			// Just let the packet straight through (fail safe)
			ipq_set_verdict(hIpq, pPacketMsg->packet_id, NF_ACCEPT, 0, NULL);
			return 1;
		}
	}

	// Note: The timestamp_sec value in struct ipq_packet_msg always appears to be 0,
	// so we will insert our own time stamp for when we got it (not as good, but oh well).

	// Get current time
	gettimeofday(&NowTime, NULL);
	pPacketMsg->timestamp_sec = NowTime.tv_sec;
	pPacketMsg->timestamp_usec = NowTime.tv_usec;

	// Workout queue that packet should go in
	Queue = PacketPriority(pPacketMsg);

	// Wait for access to the packet queue
	pthread_mutex_lock(&PacketQueueMutex);

	// Store packet meta data (including payload size, but not payload
	// itself!) at the head of the queue
	memcpy(&PacketQueue[Queue][PacketQueueHead[Queue] * sizeof(struct ipq_packet_msg)], pPacketMsg, sizeof(struct ipq_packet_msg));

	// Move the head offset
	PacketQueueHead[Queue]++;
	if(PacketQueueHead[Queue] >= Config.Queue)
		PacketQueueHead[Queue] = 0;

	// If we just looped around
	if(PacketQueueHead[Queue] == PacketQueueTail[Queue]){

		// Drop the oldest (overwritten) packet
		ipq_set_verdict(hIpq, ((ipq_packet_msg_t *)&PacketQueue[Queue][PacketQueueTail[Queue] * sizeof(struct ipq_packet_msg)])->packet_id, NF_DROP, 0, NULL);

		// Move the Tail offset
		PacketQueueTail[Queue]++;
		if(PacketQueueTail[Queue] >= Config.Queue)
			PacketQueueTail[Queue] = 0;
	}

	// Release access to the packet queue
	pthread_mutex_unlock(&PacketQueueMutex);

	return 1;
}
Example #18
0
int main(int argc, char **argv)
{
	int status;
	unsigned char buf[BUFSIZE];
	struct ipq_handle *h;
	struct iphdr *iphead;
	h = ipq_create_handle(0, PF_INET);
	if (!h)
		die(h);
		
	status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
	if (status < 0)
		die(h);
		
	do{
		status = ipq_read(h, buf, BUFSIZE, 0);
		if (status < 0)
			die(h);
			
		switch (ipq_message_type(buf)) {
			case NLMSG_ERROR:
				fprintf(stderr, "Received error message %d\\n",
				        ipq_get_msgerr(buf));
				break;
				
			case IPQM_PACKET: {
				ipq_packet_msg_t *m = ipq_get_packet(buf);
				char *dest = NULL;
				struct in_addr daddr;
				iphead = (struct iphdr *)m->payload;

				if(iphead->daddr == inet_addr(TO))
				{
					status = ipq_set_verdict(h,m->packet_id,
							NF_ACCEPT,0,NULL);
					if(status < 0)
						die(h);
					break;
				}
				else
				{
					status = ipq_set_verdict(h,m->packet_id,
							NF_DROP,0,NULL);
					if(status < 0)
						die(h);
					break;
				}			


			//	status = ipq_set_verdict(h, m->packet_id,
			//	                         NF_ACCEPT, 0, NULL);
			//	if (status < 0)
			//		die(h);
			//	break;
			}
			
			default:
				fprintf(stderr, "Unknown message type!\\n");
				break;
		}
	} while (1);
	
	ipq_destroy_handle(h);
	return 0;
}
Example #19
0
static void packet_input(int fd)
#endif
{
    rt_table_t *fwd_rt, *rev_rt, *next_hop_rt = NULL;
    struct in_addr dest_addr, src_addr;
    u_int8_t rreq_flags = 0;
    unsigned int ifindex;
    struct ip_data *ipd = NULL;
    int pkt_flags = 0;

#ifdef NS_PORT
    ifindex = NS_IFINDEX;	/* Always use ns interface */
    fwd_rt = NULL;		/* For broadcast we provide no next hop */
    ipd = NULL;			/* No ICMP messaging */

    struct hdr_cmn *ch = HDR_CMN(p);
    struct hdr_ip *ih = HDR_IP(p);

    src_addr.s_addr = ih->saddr();
    dest_addr.s_addr = ih->daddr();

    /* If this is a TCP packet and we don't have a route, we should
       set the gratuituos flag in the RREQ. */
    if (ch->ptype() == PT_TCP) {
	rreq_flags |= RREQ_GRATUITOUS;
    }
#else
    int status;
    char buf[sizeof(struct nlmsghdr)+sizeof(ipq_packet_msg_t)+BUFSIZE];
    char *dev_name;
    ipq_packet_msg_t *pkt;
    struct iphdr *ip;
    struct udphdr *udp;
    struct icmphdr *icmp = NULL;

    status =  ipq_read(h, buf, sizeof(buf), -1);
    
    if (status < 0) {
	DEBUG(LOG_DEBUG, 0, "%s", ipq_errstr());
	ipq_perror(NULL);
	return;
    }

    if (ipq_message_type(buf) == NLMSG_ERROR) {
	fprintf(stderr,
		"ERROR packet_input: Check that the ip_queue.o module is loaded.\n");
	die(h);
    }

    pkt = ipq_get_packet(buf);

#ifdef DEBUG_PACKET
    DEBUG(LOG_DEBUG, 0, "Protocol %u indev=%s outdev=%s\n",
	  pkt->hw_protocol, pkt->indev_name, pkt->outdev_name);
#endif

    if (pkt->hook == 0)
	dev_name = pkt->indev_name;
    else if (pkt->hook == 3)
	dev_name = pkt->outdev_name;
    else
	dev_name = NULL;

    /* We know from kaodv.c that this is an IP packet */
    ip = (struct iphdr *) pkt->payload;

    dest_addr.s_addr = ip->daddr;
    src_addr.s_addr = ip->saddr;

    switch (ip->protocol) {
	/* Don't process AODV control packets (UDP on port 654). They
	   are accounted for on the aodv socket */
    case IPPROTO_UDP:
	udp = (struct udphdr *) ((char *) ip + (ip->ihl << 2));
	if (ntohs(udp->dest) == AODV_PORT || ntohs(udp->source) == AODV_PORT)
	    goto accept;
	break;
	/* If this is a TCP packet and we don't have a route, we should
	   set the gratuituos flag in the RREQ. */
    case IPPROTO_TCP:
	rreq_flags |= RREQ_GRATUITOUS;
	break;
	/* We set the gratuitous flag also on ICMP ECHO requests, since
	   the destination will also need a route back for the reply... */
    case IPPROTO_ICMP:
	icmp = (struct icmphdr *) ((char *) ip + (ip->ihl << 2));
	if (icmp->type == ICMP_ECHO)
	    rreq_flags |= RREQ_GRATUITOUS;
#ifdef DEBUG_PACKET
	DEBUG(LOG_INFO, 0, "setting G flag for RREQ to %s",
	      ip_to_str(dest_addr));
#endif

	break;
#ifdef CONFIG_GATEWAY
    case IPPROTO_MIPE:
	if (internet_gw_mode) {
	    
	    ip = ip_pkt_decapsulate(ip);

	    if (ip == NULL) {
	      DEBUG(LOG_ERR, 0, "Decapsulation failed...");
	      exit(-1);
	    }
	    pkt_flags |= PKT_DEC;
	}
	break;
#endif /* CONFIG_GATEWAY */
    }

#ifdef DEBUG_PACKET
    DEBUG(LOG_INFO, 0, "pkt to %s", ip_to_str(dest_addr));
#endif

    if (dev_name) {
	ifindex = name2index(dev_name);
	if (ifindex < 0) {
	    DEBUG(LOG_ERR, 0, "name2index error!");
	    return;
	}
    } else
	ifindex = 0;
#endif				/* NS_PORT */

    /* If the packet is not interesting we just let it go through... */
    if (dest_addr.s_addr == AODV_BROADCAST ||
	dest_addr.s_addr == DEV_IFINDEX(ifindex).broadcast.s_addr) {
#ifdef NS_PORT
	/* Limit Non AODV broadcast packets (Rolf Winter
	 * <[email protected]). */
	ih->ttl() = ih->ttl() - 1;                
       
	if(ih->ttl() < 1)        
	    Packet::free(p);                
	else
	    sendPacket(p, dest_addr, 0.0);
	return;
#else
	goto accept;
#endif
    }
    
    /* Find the entry of the neighboring node and the destination  (if any). */
    rev_rt = rt_table_find(src_addr);
    fwd_rt = rt_table_find(dest_addr);

#ifdef CONFIG_GATEWAY
    /* Check if we have a route and it is an Internet destination (Should be
     * encapsulated and routed through the gateway). */
    if (fwd_rt && (fwd_rt->state == VALID) && 
	(fwd_rt->flags & RT_INET_DEST)) {
	/* The destination should be relayed through the IG */

	rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);
#ifdef NS_PORT
	p = pkt_encapsulate(p, fwd_rt->next_hop);

	if (p == NULL) {
	    DEBUG(LOG_ERR, 0, "IP Encapsulation failed!");
	   return;	    
	}
	/* Update pointers to headers */
	ch = HDR_CMN(p);
	ih = HDR_IP(p);
#else
	ip = ip_pkt_encapsulate(ip, fwd_rt->next_hop, BUFSIZE);

	if (ip == NULL) {
	    DEBUG(LOG_ERR, 0, "Minimal IP Encapsulation failed!");
	    exit(-1);	    
	}
#endif
	dest_addr = fwd_rt->next_hop;
	fwd_rt = rt_table_find(dest_addr);
	pkt_flags |= PKT_ENC;
    }
#endif /* CONFIG_GATEWAY */

    /* UPDATE TIMERS on active forward and reverse routes...  */

    /* When forwarding a packet, we update the lifetime of the
       destination's routing table entry, as well as the entry for the
       next hop neighbor (if not the same). AODV draft 10, section
       6.2. */
    if (fwd_rt && fwd_rt->state == VALID &&
	dest_addr.s_addr != DEV_IFINDEX(ifindex).ipaddr.s_addr) {

	rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);

	next_hop_rt = rt_table_find(fwd_rt->next_hop);
	
	if (next_hop_rt && next_hop_rt->state == VALID && 
	    next_hop_rt->dest_addr.s_addr != fwd_rt->dest_addr.s_addr)
	    rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);

    }
    /* Also update the reverse route and reverse next hop along the
       path back, since routes between originators and the destination
       are expected to be symmetric. */
    if (rev_rt && rev_rt->state == VALID) {
	
	rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);

	next_hop_rt = rt_table_find(rev_rt->next_hop);

	if (next_hop_rt && next_hop_rt->state == VALID &&
	    rev_rt && next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr)
	    rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);

	/* Update HELLO timer of next hop neighbor if active */   
	if (!llfeedback && next_hop_rt->hello_timer.used) {
	    struct timeval now;
	
	    gettimeofday(&now, NULL);
	    hello_update_timeout(next_hop_rt, &now, 
				 ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
	}
    }

    /* OK, the timeouts have been updated. Now see if either: 1. The
       packet is for this node -> ACCEPT. 2. The packet is not for this
       node -> Send RERR (someone want's this node to forward packets
       although there is no route) or Send RREQ. */

    /* If the packet is destined for this node, then just accept it. */
    if (memcmp(&dest_addr, &DEV_IFINDEX(ifindex).ipaddr, 
	       sizeof(struct in_addr)) == 0) {

#ifdef NS_PORT
	ch->size() -= IP_HDR_LEN;    // cut off IP header size 4/7/99 -dam
	target_->recv(p, (Handler*)0);
	p = 0;
	return;
#else
	goto accept;
#endif
    }
    if (!fwd_rt || fwd_rt->state == INVALID ||
	(fwd_rt->hcnt == 1 && (fwd_rt->flags & RT_UNIDIR))) {

	/* Check if the route is marked for repair or is INVALID. In
	 * that case, do a route discovery. */
	if (fwd_rt && (fwd_rt->flags & RT_REPAIR))
	    goto route_discovery;

	/* If a packet is received on the NF_IP_PRE_ROUTING hook,
	   i.e. inbound on the interface and we don't have a route to
	   the destination, we should send an RERR to the source and
	   then drop the package... */
	/* NF_IP_PRE_ROUTING = 0 */
#ifdef NS_PORT
#define PACKET_IS_INBOUND ch->direction() == hdr_cmn::UP
#else
#define PACKET_IS_INBOUND pkt->hook == 0
#endif

	if (PACKET_IS_INBOUND) {

	    struct in_addr rerr_dest;
	    RERR *rerr;
#ifdef NS_PORT
	    struct in_addr nh;
	    nh.s_addr = ch->prev_hop_;
	    
	    DEBUG(LOG_DEBUG, 0,
		  "No route, src=%s dest=%s prev_hop=%s - DROPPING!",
		  ip_to_str(src_addr), ip_to_str(dest_addr),
		  ip_to_str(nh));
#endif
	    if (fwd_rt) {
		rerr = rerr_create(0, fwd_rt->dest_addr,
				   fwd_rt->dest_seqno);

		rt_table_update_timeout(fwd_rt, DELETE_PERIOD);
	    } else
		rerr = rerr_create(0, dest_addr, 0);
	    
	    DEBUG(LOG_DEBUG, 0, "Sending RERR to prev hop %s for unknown dest %s", ip_to_str(src_addr), ip_to_str(dest_addr));
	    
	    /* Unicast the RERR to the source of the data transmission
	     * if possible, otherwise we broadcast it. */
	    
	    if (rev_rt && rev_rt->state == VALID)
		rerr_dest = rev_rt->next_hop;
	    else
		rerr_dest.s_addr = AODV_BROADCAST;

	    aodv_socket_send((AODV_msg *) rerr, rerr_dest,
			     RERR_CALC_SIZE(rerr), 1, &DEV_IFINDEX(ifindex));

	    if (wait_on_reboot) {
		DEBUG(LOG_DEBUG, 0, "Wait on reboot timer reset.");
		timer_set_timeout(&worb_timer, DELETE_PERIOD);
	    }
#ifdef NS_PORT
	    /* DEBUG(LOG_DEBUG, 0, "Dropping pkt uid=%d", ch->uid()); */
	    drop(p, DROP_RTR_NO_ROUTE);
#else
	    status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);
	    
	    if (status < 0)
		die(h);
#endif
	    return;
	}

      route_discovery:
	/* Buffer packets... Packets are queued by the ip_queue.o
	   module already. We only need to save the handle id, and
	   return the proper verdict when we know what to do... */

#ifdef NS_PORT
	packet_queue_add(p, dest_addr);
#else
	packet_queue_add(pkt->packet_id, dest_addr, ip);
	
#ifdef CONFIG_GATEWAY
	/* In gateway mode we handle packets in userspace */
	ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);
#endif
	/* Already seeking the destination? Then do not allocate any
	   memory or generate a RREQ. */
	if (seek_list_find(dest_addr))
	    return;

	/* If the request is generated locally by an application, we save
	   the IP header + 64 bits of data for sending an ICMP Destination
	   Host Unreachable in case we don't find a route... */
	if (src_addr.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr && ip &&
	    pkt->data_len >= (ip->ihl << 2) + 8) {
	    ipd = (struct ip_data *) malloc(sizeof(struct ip_data));
	    if (ipd == NULL) {
		perror("Malloc for IP data failed!");
		exit(-1);
	    }
	    /* IP header + 64 bits data (8 bytes) */
	    ipd->len = (ip->ihl << 2) + 8;
	    memcpy(ipd->data, ip, ipd->len);
	} else
	    ipd = NULL;
#endif
	if (fwd_rt && (fwd_rt->flags & RT_REPAIR))
	    rreq_local_repair(fwd_rt, src_addr, ipd);
	else
	    rreq_route_discovery(dest_addr, rreq_flags, ipd);

	return;

    } else {

#ifdef NS_PORT
	/* DEBUG(LOG_DEBUG, 0, "Sending pkt uid=%d", ch->uid()); */
	sendPacket(p, fwd_rt->next_hop, 0.0);
#else	
      accept:

	if (pkt_flags & PKT_ENC || (pkt_flags & PKT_DEC))
	    status = ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 
				     ntohs(ip->tot_len), (unsigned char *)ip);
	else
	    status = ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 0, NULL);
	
	if (status < 0)
	    die(h);

#endif
	/* When forwarding data, make sure we are sending HELLO messages */
	gettimeofday(&this_host.fwd_time, NULL);

	if (!llfeedback && optimized_hellos)
	    hello_start();
    }
}
Example #20
0
static void * ip_noise_decide_what_to_do_with_packets_thread_func (void * void_context)
{
    ip_noise_decide_what_to_do_with_packets_thread_context_t * context;      
    ip_noise_messages_queue_t * packets_to_arbitrate_queue;
    int * terminate;
    ip_noise_message_t * msg_with_time;
    int status;
    struct ipq_handle * h;
#ifdef DEBUG
    static int num;
#endif
    ip_noise_verdict_t verdict;
    ip_noise_delayer_t * delayer;
    ip_noise_arbitrator_data_t * * data;
    ip_noise_flags_t * flags;
    ip_noise_arbitrator_packet_logic_t * packet_logic;

    context = (ip_noise_decide_what_to_do_with_packets_thread_context_t * )void_context;

    packets_to_arbitrate_queue = context->queue;
    terminate = context->terminate;
    h = context->h;
    delayer = context->delayer;
    data = context->data;
    flags = context->flags;

    free(context);


    packet_logic = ip_noise_arbitrator_packet_logic_alloc(data, flags);
    
    /* As long as another thread did not instruct us to terminate - loop!
     *
     */
    while (! (*terminate))
    {
        /* 
         * Inside the loop, we dequeue an item from the queue,
         * decide what to do with it. If it should be dropped or released,
         * it is done immidiately. Else, it is placed in the delayer's priority
         * queue for release in the future.
         * */
        msg_with_time = ip_noise_messages_queue_dequeue(packets_to_arbitrate_queue);
        if (msg_with_time == NULL)
        {
            usleep(500);
            continue;
        }

#if 0
        verdict = decide_what_to_do_with_packet(msg_with_time->m);
#endif
        verdict = ip_noise_arbitrator_packet_logic_decide_what_to_do_with_packet(packet_logic, msg_with_time->m);
        
        if (verdict.action == IP_NOISE_VERDICT_ACCEPT)
        {
#ifdef DEBUG
#if 0
            printf("Release Packet! (%i)\n", num++);
#endif
#endif
            status = ipq_set_verdict(h, msg_with_time->m->packet_id, NF_ACCEPT, 0, NULL);

            if (status < 0)
            {
                die(h);
            }

            free(msg_with_time);
        }
        else if (verdict.action == IP_NOISE_VERDICT_DROP)
        {
#ifdef DEBUG
            printf("Dropping Packet! (%i)\n", num++);
#endif
            status = ipq_set_verdict(h, msg_with_time->m->packet_id, NF_DROP, 0, NULL);

            if (status < 0)
            {
                die(h);
            }

            free(msg_with_time);
        }
        else if (verdict.action == IP_NOISE_VERDICT_DELAY)
        {
#ifdef DEBUG
            printf("Delaying Packet! (%i)\n", num++);
#endif
            ip_noise_delayer_delay_packet(
                delayer,
                msg_with_time,
                msg_with_time->tv,
                verdict.delay_len
                );
        }
        else
        {
            *terminate = 1;
            fprintf(stderr, "Unknown Action!\n");
            return NULL;
        }
    }

    return NULL;
}
Example #21
0
int doingDetection()
{
   int status;
   struct nlmsghdr *nlh;
   struct ndpi_ethher *ethernet;
   struct ndpi_iphdr *iph;
   ipq_packet_msg_t *ipq_packet;
   int ip_len;
   struct ndpi_id_struct *src, *dst;
   struct ndpi_flow *flow;
   struct ndpi_flow_struct *ndpi_flow = NULL;
   u_int32_t protocol = 0;
   u_int8_t proto;
   u_int64_t time;
   static u_int64_t lasttime=0;
   unsigned char payload[1024*1024];
	 while(1)
   {
     status = ipq_read(h, buf, sizeof(buf),0);
     if(status==0||status==-1)continue;
     memset(payload, 0x00, sizeof(payload));
     if(status > sizeof(struct nlmsghdr))
     {
       nlh = (struct nlmsghdr *)buf;//测试是否和ndpi_ethher一致。
       ipq_packet = ipq_get_packet(buf);
       ip_len=ipq_packet->data_len;
       time = ((uint64_t) ipq_packet->timestamp_sec) * detection_tick_resolution +ipq_packet->timestamp_usec / (1000000 / detection_tick_resolution);
			 memcpy(payload + ETH_HDRLEN, ipq_packet->payload, ip_len);
// 			printf("2\n");
 			 if(lasttime > time) {
        time = lasttime;
       }
       lasttime = time;
       iph = (struct ndpi_iphdr *)(&(ipq_packet->payload[0]));//需要测试是否和pcap来的一致
       if(iph)
			 {
//				 printf("before get_ndpi_flow\n");
         flow = get_ndpi_flow(iph, ip_len,&src, &dst, &proto);
//				 printf("after get_ndpi_flow\n");
			 }
			 if(flow != NULL) 
       {
         ndpi_flow = flow->ndpi_flow;
         flow->packets++, flow->bytes += ip_len;
       } else
         continue;
//			 printf("3\n");
       ip_packet_count++;
       total_bytes+=ip_len+24;
       if(flow->detection_completed) 
			 {
				 /*ipq_set_verdict(h, ipq_packet->packet_id, NF_ACCEPT,ipq_packet->data_len,payload + ETH_HDRLEN);*/
				 ipq_set_mark(h,ipq_packet->packet_id,1);
				 continue;
			 }
       protocol = (const u_int32_t)ndpi_detection_process_packet(ndpi_struct, ndpi_flow,(char *)iph,ip_len, time, src, dst);
//			 printf("4\n");
       if((flow->detected_protocol != NDPI_PROTOCOL_UNKNOWN)
           || ((proto == IPPROTO_UDP) && (flow->packets > 8))
           || ((proto == IPPROTO_TCP) && (flow->packets > 10)))
       {
         if(flow->detected_protocol==NDPI_PROTOCOL_UNKNOWN)
				 		flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_struct,
							   flow->protocol,
							   ntohl(flow->lower_ip),
							   ntohs(flow->lower_port),
							   ntohl(flow->upper_ip),
							   ntohs(flow->upper_port));
         flow->detection_completed = 1;
				 protocol_counter[flow->detected_protocol]+=flow->packets;
				 protocol_flows[flow->detected_protocol]++;
				 protocol_counter_bytes[flow->detected_protocol]+=flow->bytes;
         snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name);
       }
			 ipq_set_verdict(h, ipq_packet->packet_id, NF_ACCEPT,ipq_packet->data_len,payload + ETH_HDRLEN);
       snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name);
	    }
   }
}
Example #22
0
/* returns a bound socket matching a connection request *
 * sets verdict on request packet if ipq or nfq was used and the port is already bound *
 * in the latter case, -1 is returned */
int get_boundsock(struct sockaddr_in *server_addr, uint16_t port, int type) {
    int fd, sockopt;
#ifdef USE_IPQ_MON
    int status;
#endif

    if ((type != SOCK_DGRAM) && (type != SOCK_STREAM)) {
        logmsg(LOG_ERR, 1, "Error - Socket type %d not supported.\n", type);
        exit(EXIT_FAILURE);
    }

    if (!(fd = socket(AF_INET, type, 0))) {
        logmsg(LOG_ERR, 1, "Error - Could not create socket: %m.\n");
        exit(EXIT_FAILURE);
    }

    sockopt = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) < 0)
        logmsg(LOG_WARN, 1, "Warning - Unable to set SO_REUSEADDR for server socket.\n");

    bzero((char *) server_addr, sizeof(struct sockaddr_in));
    server_addr->sin_family		= AF_INET;
    server_addr->sin_addr.s_addr	= bind_address.s_addr;
    server_addr->sin_port		= port;
    if ((bind(fd, (struct sockaddr *) server_addr, sizeof(struct sockaddr_in))) != 0) {
        /* we already got one server process */
        logmsg(LOG_DEBUG, 1, "Unable to bind to port %u/tcp: %m.\n", ntohs(port));
#ifdef USE_IPQ_MON
        /* hand packet processing back to the kernel */
        if ((status = ipq_set_verdict(h, packet->packet_id, NF_ACCEPT, 0, NULL)) < 0) {
            logmsg(LOG_ERR, 1, "Error - Could not set verdict on packet: %s.\n", ipq_errstr());
            ipq_destroy_handle(h);
            exit(EXIT_FAILURE);
        }
        logmsg(LOG_DEBUG, 1, "IPQ - Successfully set verdict on packet.\n");
        return(-1);
#else
#ifdef USE_NFQ_MON
        /* hand packet processing back to the kernel */
        /* nfq_set_verdict()'s return value is undocumented,
         * but digging the source of libnetfilter_queue and libnfnetlink reveals
         * that it's just the passed-through value of a sendmsg() */
        if (nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL) == -1) {
            logmsg(LOG_ERR, 1, "Error - Could not set verdict on packet.\n");
            nfq_destroy_queue(qh);
            exit(EXIT_FAILURE);
        }
        logmsg(LOG_DEBUG, 1, "NFQ - Successfully set verdict on packet.\n");

        /* a dynamic server is already present */
        close(fd);
        return(-1);
#else
        /* if bind() did not fail for 'port already in use' but for some other reason,
         *  we're in troubles and want a verbose error message */
        if (errno != 98) logmsg(LOG_NOISY, 1, "Warning - Could not bind to port %u/tcp: %m.\n", ntohs(port));
        exit(EXIT_FAILURE);
#endif
#endif
    }
    logmsg(LOG_DEBUG, 1, "Socket created, file descriptor is %d.\n", fd);

    return(fd);
}