Beispiel #1
0
// dump rules in my format
void my_dump_rule(Rule *rule)
{
	int			i;
	Range		r;

	printf("rule[%4d]:\t", rule->id);

	// dump SIP & DIP
	for (i = 0; i < 2; i++) {
		r = rule->field[i];
		if (r.lo == r.hi) 
			dump_ip(r.lo);
		else if (r.lo == 0 && r.hi == 0xffffffff)
			printf("*");
		else {
			dump_ip(r.lo);
			printf("/%d", 31-MSB(r.hi-r.lo+1));
		}
		printf(",  ");
	}

	// dump SP & DP
	for (i = 2; i < 4; i++) {
		r = rule->field[i];
		if (r.lo == r.hi) 
			printf("%x", r.lo);
		else if (r.lo == 0 && r.hi == 0xffff)
			printf("*");
		else {
			printf("[%x-%x]", r.lo, r.hi);
		}
		printf(",  ");
	}

	// dump proto
	r = rule->field[4];
	if (r.lo == r.hi)
		printf("%d", r.lo);
	else if (r.lo == 0 && r.hi == 0xff)
		printf("*");
	else
		printf("[%d-%d]", r.lo, r.hi);

	printf("\n");
}
/* This dumps a complete udp frame, starting from the eth header */
int dump_udppkt(char *prefix, void *buf, int len, struct TimeInternal *ti)
{
	struct ethhdr *eth = buf;
	struct iphdr *ip = buf + ETH_HLEN;
	struct udphdr *udp = (void *)(ip + 1);
	void *payload = (void *)(udp + 1);

	if (ti)
		dump_time(prefix, ti);
	dump_eth(prefix, eth);
	dump_ip(prefix, ip);
	dump_udp(prefix, udp);
	dump_payload(prefix, payload, len - (payload - buf));
	return 0;
}
Beispiel #3
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;


}