📄 dummy_ipv4.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 + -