📄 dummy_ipv4.c
字号:
/* dummy_ipv4.c * linqianghe@163.com * 2006-09-04 */#include "log.h"#include "dummy_ipv4.h"#include "af_inet.h"#include "route_dummy.h"#include "myip.h"#include "route.h"#include "dev.h"#include <net/inet_sock.h>#include <net/sock.h>#include <linux/in.h>#include <net/tcp_states.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 table; struct rtable *rt = NULL; sa_family_t family; int err; PR_DEBUG( "send a dummy packet, len: %d\n", len ); family = MY_AF_INET; 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, .nl_u = { .ip4_u = { .daddr = daddr,} }, .uli_u = { .ports = { .sport = inet->sport, .dport = dport } } }; err = myip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags & MSG_DONTWAIT) ); if( rt != NULL ){ printk( KERN_NOTICE "the dst_entry:\n" ); printk( KERN_NOTICE "\tthe dev name: %s\n", rt->u.dst.dev->name); printk( KERN_NOTICE "\tthe error: %u\n", rt->u.dst.error ); printk( KERN_NOTICE "\tthe obsolete: %u\n", rt->u.dst.obsolete ); printk( KERN_NOTICE "\tthe flag: %x\n", rt->u.dst.flags ); printk( KERN_NOTICE "\texpires: %lu, now: %lu\n", rt->u.dst.expires, jiffies ); printk( KERN_NOTICE "\theader len: %u\n", rt->u.dst.header_len ); printk( KERN_NOTICE "rt_flag: %x\n", rt->rt_flags ); printk( KERN_NOTICE "rt_type: %u\n", rt->rt_type ); printk( KERN_NOTICE "rt_dst: %u.%u.%u.%u\n", NIPQUAD(rt->rt_dst) ); printk( KERN_NOTICE "rt_src: %u.%u.%u.%u\n", NIPQUAD(rt->rt_src) ); printk( KERN_NOTICE "rt_iif: %d\n", rt->rt_iif ); printk( KERN_NOTICE "rt_gateway: %u.%u.%u.%u\n", NIPQUAD(rt->rt_gateway) ); printk( KERN_NOTICE "rt_spec_dst: %u.%u.%u.%u\n", NIPQUAD(rt->rt_spec_dst) ); } 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;}int dummy_ioctl(struct sock *sk, int cmd, unsigned long arg){ return -ENOIOCTLCMD;}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, .ioctl = dummy_ioctl, .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 + -