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

📄 dummy_ipv4.c

📁 一个基于linux的TCP/IP协议栈的实现
💻 C
字号:
/* dummy_ipv4.c * linqianghe@163.com * 2006-09-04 */#include <net/inet_sock.h>#include <net/sock.h>#include <linux/in.h>#include <net/tcp_states.h>#include "log.h"#include "dummy_ipv4.h"#include "af_inet.h"#include "route_dummy.h"#include "myip.h"static struct sock *dummy_sock;static int dummy_init( struct sock *sk ){	PR_DEBUG( "initialize the dummy sock!\n" );	return 0;}static void dummy_hash( struct sock *sk ){	dummy_sock = sk;	PR_DEBUG( "hash the dummy sock!\n" );}static void dummy_unhash( struct sock *sk ){	dummy_sock = NULL;	PR_DEBUG( "unhash the dummy sock!\n");}static void dummy_close(struct sock *sk, long timeout){	PR_DEBUG( "close the dummy sock!\n");	sk_common_release(sk);}static int dummy_sendmsg(struct kiocb *iocb, struct sock *sk, 				struct msghdr *msg, size_t len){	struct inet_sock *inet = inet_sk(sk);	int connected = 0;	u32 daddr;	u16 dport;	struct rtable *rt = NULL;	sa_family_t family;	int err;	PR_DEBUG( "send a dummy packet, len: %d\n", len );#ifdef MYIPV4_DEBUG	family = DEBUG_AF_INET;#else	family = AF_INET;#endif	if( len > 0xFF ){		PR_ERR( "the max size of packet is 0xFF in dummy protocol!\n" );		return -EMSGSIZE;	}	if( msg->msg_flags & MSG_OOB ){		PR_ERR( "not support MSG_OOB in dummy protocol!\n");		return -EOPNOTSUPP;	}	if( msg->msg_name ){		struct sockaddr_in * usin = (struct sockaddr_in*)msg->msg_name;		if( msg->msg_namelen < sizeof(*usin) ){			PR_ERR( "invalid argument!, the msg len is: %d\n", msg->msg_namelen );			return -EINVAL;		}		if( usin->sin_family != family ){			if (usin->sin_family != AF_UNSPEC){				PR_ERR( "not support the family: %d\n", usin->sin_family );				return -EAFNOSUPPORT;			}		}		daddr = usin->sin_addr.s_addr;		dport = usin->sin_port;	}else{		if (sk->sk_state != TCP_ESTABLISHED){			PR_ERR( "require destination address!\n" );			return -EDESTADDRREQ;		}		daddr = inet->daddr;		dport = inet->dport;		connected = 1;  	}	{		struct flowi fl = {					 .proto = IPPROTO_DUMMY,					 .uli_u = { .ports =							 { .sport = inet->sport, .dport = dport } } };		err = ip_route_output_flow_dummy(&rt, &fl, sk, !(msg->msg_flags & MSG_DONTWAIT) );		if (err)			goto out;	}	ip_append_data_dummy( sk, msg->msg_iov, len, DUMMY_HEADER_LEN, rt, msg->msg_flags );	err =  ip_push_pending_frames_dummy( sk );out:	return err;}static int dummy_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,				size_t len, int noblock, int flags, int *addr_len){	struct sk_buff *skb;	int err = -EINVAL;	int copied;	PR_DEBUG( "dummy_recvmsg!\n" );	skb = skb_recv_datagram(sk, flags, noblock, &err);	if( !skb )		goto out;	PR_DEBUG( "get the skb: %p\n", skb );	copied = skb->len - DUMMY_HEADER_LEN;	if (copied > len) {		copied = len;		msg->msg_flags |= MSG_TRUNC;	}	err = skb_copy_datagram_iovec(skb, DUMMY_HEADER_LEN, msg->msg_iov, copied);	skb_free_datagram(sk, skb);out:  	return err;}static int dummy_get_port(struct sock *sk, unsigned short snum){	unsigned short port = 2048;	struct inet_sock *inet = inet_sk(sk);		PR_DEBUG( "get the port of dummy sock: 2048\n");	inet->num = port;	return 0;}struct proto dummy_prot = {	.name = "dummy",	.owner = THIS_MODULE,	.init = dummy_init,	.hash = dummy_hash,	.unhash = dummy_unhash,	.close = dummy_close,	.sendmsg =	dummy_sendmsg,	.recvmsg =	dummy_recvmsg,	.get_port =	dummy_get_port,		.obj_size =	sizeof( struct inet_sock ),};static struct sock *dummy_v4_lookup( void ){	if( dummy_sock != NULL )		return dummy_sock;	return NULL;}int dummy_rcv( struct sk_buff *skb ){	struct sock *sk;	PR_DEBUG( "dummy_rcv!\n" );		sk = dummy_v4_lookup();	if (sk != NULL) {		if( sock_queue_rcv_skb(sk, skb)<0 ){			kfree_skb( skb );			return -1;		}		PR_DEBUG( "get the socket!\n" );		return 0;	}	PR_ERR( "can't find the socket to receive the data!\n");	kfree_skb( skb );	return -1;}EXPORT_SYMBOL_GPL( dummy_prot );EXPORT_SYMBOL_GPL( dummy_rcv );

⌨️ 快捷键说明

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