⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snoop.c

📁 一种无线拥塞控制协议
💻 C
📖 第 1 页 / 共 3 页
字号:
	cs->tail = 1;	cs->sock->daddr = 0;	cs->sock->saddr = 0;	cs->sock->dest = 0;	cs->sock->source = 0;	up(&cs->mutex);	if (SNOOP_DEBUG) printk ("\nSNOOP:...done cleaning connection [%3d]. \n", conn_id);}//============ SNOOP CLEAN CONTROL - removes all data and frees memory =====/* * This function is invoked when the module is unloaded from the kernel.   * It traverses through the cstate array of the snoop_control data structure.  *  For every connection container, it clears the allocated memory by  *  calling snoop_free_packet(.).  After all the packet containers are  *  freed, the connection container is freed by using the kfree(.) macro  *  available in the kernel.  In the end, the connection controller is cleared. */void snoop_clean_conrol(){ // perfectly functional	int i, j;	snoop_cs_t *cs;	if (SNOOP_DEBUG) printk("SNOOP: Removing snoop components and data structures...");	// Delocate the buffer for each connection state	for (i = 0; i < SNOOP_MAXCONN; i++) {		cs = snoop_control.cstate[i];		// Delocate memory for all packets for all connections		for (j = 0; cs && (j < SNOOP_MAXWINDOW); j++) {			if (cs->pkts[j]->skb)snoop_free_skb(cs->pkts[j]->skb);			kfree (cs->pkts[j]);		}		if (cs->sock) kfree(cs->sock);		kfree(cs);		if (SNOOP_DEBUG) printk(".[%d].", i);	}	if (SNOOP_DEBUG) printk("...components removed.\n");}//============ SNOOP GET CONN - returns the conn id if it exists ===========/* * The snoop buffer is passed to this function for the function to * determine which connection the packet belongs to, and to identify * whether the packet is from a fixed, or a mobile host. It traverses * through the different connections, and matches their sockets against * the one in the snoop buffer, and based on the findings, it returns its * result. */int snoop_getconn(struct snoop_buffer *snb, char *origin){	int conn_id;	snoop_cs_t *test;	for (conn_id = 0; conn_id < SNOOP_MAXCONN; conn_id++) {		test = snoop_control.cstate[conn_id];		// Whether packet is from Mobile Host (host which initiates the connection)				if (test && test->sock->daddr == snb->sock->daddr &&			test->sock->saddr == snb->sock->saddr &&			test->sock->source == snb->sock->source &&			test->sock->dest == snb->sock->dest)		{			*origin = SNOOP_MH;			return conn_id;		}		// Packet is from the fixed host (ip / port numbers are flipped)		else if (test && test->sock->daddr == snb->sock->saddr &&			test->sock->saddr == snb->sock->daddr &&			test->sock->source == snb->sock->dest &&			test->sock->dest == snb->sock->source)		{			*origin = SNOOP_FH;			return conn_id;		}	}	return SNOOPE_NOTFOUND;}//============ SNOOP ERROR - prints debugging statements ===================/* * This funciton prints error messages when called upon with certain * parameters */void snoop_error (char error_id, char function[40]){	if (!SNOOP_DEBUG) return;	printk ("SNOOP_DEBUG: %s - ", function);	switch (error_id) {		case (SNOOPE_NOTFOUND) :			printk("item not found.\n");break;		case (SNOOPE_PKTFULL) :			printk("packet buffer is full.\n");break;		case (SNOOPE_CONFULL) :			printk("max # of connection reached.\n");break;		case (SNOOPE_NOMEM) :			printk("out of memory - can't allocate.\n");break;		case (SNOOPE_FORWARD) :			printk("forward - pass packet on.\n");break;	}}//============ SNOOP PREPARE BUFFER - fills in the snoop buffer ============/* * This is the first funciton which is called by snoop_main, and is very * critical for the entire module to funciton.  This function is passed * the original packet_buffer, and using the original buffer, this * function extracts the necessary data.  The socket, to identify the packet * is then created, and a structure containing the packet's flags is then * created. * * The most important contribution of this function is that it makes a copy * of the buffer, and prepares the buffer to make its tcp header readable. * Since we can't modify the original buffer if we intend to pass them down  * to the kernel again, different containgers - socket, flags, etc are  * used to contin the infomration. */struct snoop_buffer *snoop_prepare_buffer (struct sk_buff *skb_original) {	struct sk_buff *skb;	struct snoop_socket *sock;	struct snoop_flags *flags;	struct snoop_buffer *snb;	if ((snb = (struct snoop_buffer *) snoop_malloc (sizeof (struct snoop_buffer))) && (skb = snoop_skb_clone(skb_original))) {		__skb_pull(skb, skb->nh.iph->ihl*4);		skb->h.raw = skb->data;		snb->skb = skb_original;		if ((sock = (struct snoop_socket *) snoop_malloc (sizeof (struct snoop_socket)))) {			sock->daddr = ntohl(skb->nh.iph->daddr);			sock->saddr = ntohl(skb->nh.iph->saddr);			sock->dest = ntohs(skb->h.th->dest);			sock->source = ntohs(skb->h.th->source);			snb->sock = sock;		}		else{		       if (SNOOP_DEBUG) printk("SNOOP: Can't allocate memory for snoop socket.\n");	       	       return 0;		}		if ((flags = (struct snoop_flags *) snoop_malloc (sizeof (struct snoop_flags)))){			flags->syn = skb->h.th->syn;			flags->ack = skb->h.th->ack;			flags->fin = skb->h.th->fin;			flags->rst = skb->h.th->rst;			snb->flags = flags;		}		else{		       if (SNOOP_DEBUG) printk("SNOOP: Can't allocate memory for snoop flags.\n");	       	       return 0;		}		snb->seq = ntohl(skb->h.th->seq);		snb->ack_seq = ntohl(skb->h.th->ack_seq);		snb->size = ntohl(skb->len);	}	else{		if (SNOOP_DEBUG) printk("SNOOP: Can't allocate memory for snoop buffer or sk_buff.\n");       	       return 0;	}	snoop_free_skb(skb);	return snb;}//============ Main function mapped to SNOOP_PACKET_HANDLER ================/* * The snoop_main(.)is mapped to the hook symbol.  Thus, this function  * gets invoked every time a packet traverses through the ip_forward.c  * pipe in the kernel.  The hook calls up this function and passes it a  * pointer to the the sk_buff  for the packet.   * * When a packet is received, first a snoop buffer for that packet is  * created using snoop_prepare_buffer().  Then this function calls  * snoop_getconn(.), which, based on the packet's source and destination  * IP Addresses and port numbers determines whether a connection state for  * that connection exists.  If a connection state exists, it determines  * whether the packet is from FH, or from MH. * * If a connection does not exist for this packet, then a connection is  * created with the function snoop_init_conn(.), based on the information  * from the snoop_buffer. If the maximum number of connections is full,  * new connection is not created, the packet is plainly forwarded, and no  * action is taken.  * * If a packet received has only its syn flag set, and the connection  * container for that packet already exists in the Snoop controller,  * the old matching connection container is cleared, and a new connection  * is created.  This way, Snoop does not confuse old connections with  * the old connections. * * If the packet is received with its fin flag set, the connection container  * which the packet belongs to is cleared using snoop_clean_conn(.).   * The packet buffers are emptied, all the variables are initialized back  * to the empty state.  * * If the packet is a normal packet, and the connection container for the  * packet is identified, the timeout value for the connection container  * is reset.  This ensures that any activity on a connection would start  * the idle timer all over again.   The maximum idle time value is defined  * as a constant in the snoop.h header file. * After the timer reset, it is determined whether the packet is from the  * FH, or the MH.  If the packet is from a fixed host, snoop_data(.) is called,  * and passes it the sk_buff and the connid of the connection container  * which the packet belongs to.  If the packet is from MH, the sk_buff and  * the connid are passed to snoop_ack(.).   */int snoop_main(struct sk_buff *skb){	int conn_id;	int status;	char origin;	snoop_cs_t *cs;	struct snoop_buffer *snb;	if (skb->nh.iph->protocol != IPPROTO_TCP) { // if not TCP		return SNOOPE_SUCCESS;	// let it continue on its path	}	if (!(snb = snoop_prepare_buffer (skb))) return 0;//	printk ("SNOOP: Socket: [sip: %x | sp: %u | dip: %x | dp: %u ]\n",//			snb->sock->saddr, snb->sock->source, snb->sock->daddr, snb->sock->dest);//	printk ("SNOOP: Flags:  [S: %d | A: %d | F: %d | R: %d]\n",//			snb->flags->syn, snb->flags->ack, snb->flags->fin, snb->flags->rst);	// Get Connection ID based on the origin of the packet	conn_id = snoop_getconn (snb, &origin);	// Only create snoop connections when connection is initiated by MH	if (!snb->flags->ack && snb->flags->syn != 0) {		if (conn_id != SNOOPE_NOTFOUND) snoop_clean_conn(conn_id);		if ((conn_id = snoop_init_conn(snb)) < SNOOPE_SUCCESS){			snoop_error (conn_id, "snoop_main->snoop_init_conn");			return SNOOPE_SUCCESS;		}	}	if (conn_id == SNOOPE_NOTFOUND){		return SNOOPE_SUCCESS;	}	if (snb->flags->rst || snb->flags->fin) {		if (conn_id != SNOOPE_NOTFOUND  && origin == SNOOP_FH) snoop_clean_conn(conn_id);		return SNOOPE_SUCCESS;	}	cs = snoop_control.cstate[conn_id];	mod_timer (&cs->timeout, (jiffies + (SNOOP_CONN_TIMEOUT * HZ)));	if (origin == SNOOP_FH){	// receiver mobile		if ((status = snoop_data(snb, conn_id)) != SNOOPE_SUCCESS){			snoop_error (status, "snoop_main->snoop_data");		}	}else {				// sender is mobile		if ((status = snoop_ack(snb, conn_id)) != SNOOPE_SUCCESS){			snoop_error (status, "snoop_main->snoop_ack");		}	}	return SNOOPE_SUCCESS;}//============ INIT FUNCTION - initializes the module on load===============/* * A kernel module is installed by using the command insmod <module name>.  * The funtion init_module() is invoked at the module installation time,  * and executes whatever is declared in the function when as the module  * gets loaded.  Hence, it can also be used to run other functions which  * initialize the module at load time.  This function facilitates the  * initialization of the entire Snoop module.  It calls the function  * snoop_init_control().  It also maps the symbol snoop_ip_forward, the  * hook to the snoop_main function of the agent.  Thus, whenever kernel  * passes anything to the hook, the hook passes that data to snoop_main. */int init_module() { /* INITIALIZE MODULE */	int status;	EXPORT_NO_SYMBOLS;	// Initialize snoop on load	if ((status = snoop_init_control()) != SNOOPE_SUCCESS){		snoop_error(status, "init_module->snoop_init_control");		printk ("SNOOP: Module loading failed.\n");		return 0;	}	snoop_ip_forward = snoop_main;	//maps snoop main to the forward hook	printk("SNOOP: Snoop module has been successfully installed. Snoop is now active!\n");	return 0;}//============ CLEANUP FUNCTION - cleans memory on unload ==================/* * The cleanup_module() function is a standard function which must be  * implemented for each module.  Whenever rmmod <module name> is executed  * on the command line, this function is invoked.  This function can thus  * be used to trigger the unloading of the Snoop data structures, which  * include the freeing the memory allocated for connection containers,  * packet containers, and resetting the hook.   * * The cleanup_module() function invokes the snoop_clean_control() function  * to free up the memory, that snoop had allocated for itself. */void cleanup_module() { /* CLEANUP MODULE */	snoop_clean_conrol();	snoop_ip_forward = 0;	printk("SNOOP: Snoop module has been successfully uninstalled\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -