📄 my_inet.c
字号:
{ struct inet_sock *inet; /* We may need to bind the socket. */ lock_sock(sk); inet = inet_sk(sk); if (!inet->num) { if (sk->sk_prot->get_port(sk, 0)) { release_sock(sk); return -EAGAIN; } inet->sport = htons(inet->num); } release_sock(sk); return 0;}int myinet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size){ struct sock *sk = sock->sk; if (!inet_sk(sk)->num && myinet_autobind(sk)) return -EAGAIN; return sk->sk_prot->sendmsg(iocb, sk, msg, size);}int myinet_dgram_connect(struct socket *sock, struct sockaddr * uaddr, int addr_len, int flags){ struct sock *sk = sock->sk; if (uaddr->sa_family == AF_UNSPEC) return sk->sk_prot->disconnect(sk, flags); if( !inet_sk(sk)->num && myinet_autobind(sk) ) return -EAGAIN; return sk->sk_prot->connect(sk, (struct sockaddr *)uaddr, addr_len);}static ssize_t myinet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags){ return 0;}struct proto_ops myinet_stream_ops = { .family = MY_PF_INET, .owner = THIS_MODULE, .release = myinet_release, .bind = myinet_bind, .connect = myinet_stream_connect, .socketpair = sock_no_socketpair, .accept = myinet_accept, .getname = myinet_getname, .poll = mytcp_poll, .ioctl = myinet_ioctl, .listen = myinet_listen, .shutdown = myinet_shutdown, .setsockopt = sock_common_setsockopt, .getsockopt = sock_common_getsockopt, .sendmsg = myinet_sendmsg, .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = mytcp_sendpage};struct proto_ops myinet_dgram_ops = { .family = MY_PF_INET, .owner = THIS_MODULE, .release = myinet_release, .bind = myinet_bind, .connect = myinet_dgram_connect, .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = myinet_getname, .poll = myudp_poll, .ioctl = myinet_ioctl, .listen = sock_no_listen, .shutdown = myinet_shutdown, .setsockopt = sock_common_setsockopt, .getsockopt = sock_common_getsockopt, .sendmsg = myinet_sendmsg, .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = myinet_sendpage,};static struct proto_ops myinet_sockraw_ops = { .family = MY_PF_INET, .owner = THIS_MODULE, .release = myinet_release, .bind = myinet_bind, .connect = myinet_dgram_connect, .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = myinet_getname, .poll = datagram_poll, .ioctl = myinet_ioctl, .listen = sock_no_listen, .shutdown = myinet_shutdown, .setsockopt = sock_common_setsockopt, .getsockopt = sock_common_getsockopt, .sendmsg = myinet_sendmsg, .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = myinet_sendpage,};static struct list_head myinetsw[SOCK_MAX];static DEFINE_SPINLOCK(myinetsw_lock);static struct inet_protosw myinetsw_array[] ={ { .type = SOCK_STREAM, .protocol = MY_IPPROTO_TCP, .prot = &mytcp_prot, .ops = &myinet_stream_ops, .capability = -1, .no_check = 0, .flags = INET_PROTOSW_PERMANENT, }, { .type = SOCK_DGRAM, .protocol = MY_IPPROTO_UDP, .prot = &myudp_prot, .ops = &myinet_dgram_ops, .capability = -1, .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_PERMANENT, }, { .type = SOCK_RAW, .protocol = IPPROTO_IP, /* wild card */ .prot = &myraw_prot, .ops = &myinet_sockraw_ops, .capability = CAP_NET_RAW, .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_REUSE, }};#define MYINETSW_ARRAY_LEN (sizeof(myinetsw_array) / sizeof(struct inet_protosw))static int myinet_create(struct socket *sock, int protocol){ struct sock *sk; struct inet_protosw *answer; struct list_head *p; struct inet_sock *inet; struct proto *answer_prot; unsigned char answer_flags; char answer_no_check; int err; sock->state = SS_UNCONNECTED; answer = NULL; rcu_read_lock(); list_for_each_rcu(p, &myinetsw[sock->type]) { answer = list_entry(p, struct inet_protosw, list); if (protocol == answer->protocol) { if (protocol != IPPROTO_IP) break; }else{ if (IPPROTO_IP == protocol) { protocol = answer->protocol; break; } if (IPPROTO_IP == answer->protocol) break; } answer = NULL; } err = -ESOCKTNOSUPPORT; if (!answer) goto out_rcu_unlock; err = -EPERM; if (answer->capability > 0 && !capable(answer->capability)) goto out_rcu_unlock; err = -EPROTONOSUPPORT; if (!protocol) goto out_rcu_unlock; sock->ops = answer->ops; answer_prot = answer->prot; answer_no_check = answer->no_check; answer_flags = answer->flags; rcu_read_unlock(); BUG_TRAP(answer_prot->slab != NULL); err = -ENOBUFS; sk = sk_alloc(MY_PF_INET, GFP_KERNEL, answer_prot, 1); if (sk == NULL) goto out; err = 0; sk->sk_no_check = answer_no_check; if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse = 1; inet = inet_sk(sk); if (SOCK_RAW == sock->type) { inet->num = protocol; if (IPPROTO_RAW == protocol) inet->hdrincl = 1; } if (ipv4_config.no_pmtu_disc) inet->pmtudisc = IP_PMTUDISC_DONT; else inet->pmtudisc = IP_PMTUDISC_WANT; inet->id = 0; sock_init_data(sock, sk); sk->sk_destruct = myinet_sock_destruct; sk->sk_family = MY_PF_INET; sk->sk_protocol = protocol; sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv; inet->uc_ttl = -1; inet->mc_loop = 1; inet->mc_ttl = 1; inet->mc_index = 0; inet->mc_list = NULL;#ifdef INET_REFCNT_DEBUG atomic_inc(&myinet_sock_nr);#endif if (inet->num) { inet->sport = htons(inet->num); sk->sk_prot->hash(sk); } if (sk->sk_prot->init) { err = sk->sk_prot->init(sk); if (err) sk_common_release(sk); }out: return err;out_rcu_unlock: rcu_read_unlock(); goto out; }static struct net_proto_family myinet_family_ops = { .family = MY_PF_INET, .create = myinet_create, .owner = THIS_MODULE,};void myinet_register_protosw(struct inet_protosw *p){ struct list_head *lh; struct inet_protosw *answer; int protocol = p->protocol; struct list_head *last_perm; spin_lock_bh(&myinetsw_lock); if (p->type >= SOCK_MAX) goto out_illegal; answer = NULL; last_perm = &myinetsw[p->type]; list_for_each(lh, &myinetsw[p->type]) { answer = list_entry(lh, struct inet_protosw, list); if (INET_PROTOSW_PERMANENT & answer->flags) { if( protocol == answer->protocol ) break; last_perm = lh; } answer = NULL; } if (answer) goto out_permanent; list_add_rcu(&p->list, last_perm);out: spin_unlock_bh(&myinetsw_lock); synchronize_net(); return;out_permanent: printk( KERN_ERR "Attempt to override permanent protocol %d.\n", protocol ); goto out;out_illegal: printk( KERN_ERR "Ignoring attempt to register invalid socket type %d.\n", p->type ); goto out;}void myinet_unregister_protosw(struct inet_protosw *p){ if (INET_PROTOSW_PERMANENT & p->flags) { printk(KERN_ERR "Attempt to unregister permanent protocol %d.\n", p->protocol); }else{ spin_lock_bh(&myinetsw_lock); list_del_rcu(&p->list); spin_unlock_bh(&myinetsw_lock); synchronize_net(); }}static struct packet_type myip_packet_type = { .type = __constant_htons(ETH_P_IP), .func = myip_rcv,};int myinet_sk_rebuild_header(struct sock *sk){ return 0;}static int __init myinet_init(void){ struct list_head *r; struct inet_protosw *q; int rc = -EINVAL; rc = proto_register(&mytcp_prot, 1); if (rc) goto out; rc = proto_register(&myudp_prot, 1); if (rc) goto out_unregister_tcp_proto; rc = proto_register(&myraw_prot, 1); if (rc) goto out_unregister_udp_proto; (void)sock_register( &myinet_family_ops ); if (myinet_add_protocol(&myicmp_protocol, MY_IPPROTO_ICMP) < 0) printk(KERN_CRIT "myinet_init: Cannot add ICMP protocol\n"); if (myinet_add_protocol(&myudp_protocol, MY_IPPROTO_UDP) < 0) printk(KERN_CRIT "myinet_init: Cannot add UDP protocol\n"); if (myinet_add_protocol(&mytcp_protocol, MY_IPPROTO_TCP) < 0) printk(KERN_CRIT "myinet_init: Cannot add TCP protocol\n");#ifdef CONFIG_IP_MULTICAST if (myinet_add_protocol(&myigmp_protocol, MY_IPPROTO_IGMP) < 0) printk(KERN_CRIT "myinet_init: Cannot add IGMP protocol\n");#endif for (r = &myinetsw[0]; r < &myinetsw[SOCK_MAX]; ++r) INIT_LIST_HEAD(r); for (q = myinetsw_array; q < &myinetsw_array[MYINETSW_ARRAY_LEN]; ++q) myinet_register_protosw(q); myarp_init(); myip_init(); mytcp_v4_init(); mytcp_init(); myicmp_init(&myinet_family_ops);#if defined(CONFIG_IP_MROUTE) myip_mr_init();#endif if( myinit_ipv4_mibs() ) printk(KERN_CRIT "myinet_init: Cannot init ipv4 mibs\n"); ; myipv4_proc_init(); myipfrag_init(); dev_add_pack(&myip_packet_type); rc = 0;out: return rc;out_unregister_udp_proto: proto_unregister(&myudp_prot);out_unregister_tcp_proto: proto_unregister(&mytcp_prot); goto out; }static void __exit myinet_exit(void){ dev_remove_pack( &myip_packet_type ); myipfrag_exit(); myexit_ipv4_mibs();#if defined(CONFIG_IP_MROUTE) myip_mr_exit();#endif myicmp_exit(); mytcp_exit(); mytcp_v4_exit(); myip_exit(); myarp_exit(); proto_unregister(&myudp_prot); proto_unregister(&mytcp_prot); proto_unregister(&myraw_prot); myinet_del_protocol(&myicmp_protocol, MY_IPPROTO_ICMP ); myinet_del_protocol(&myudp_protocol, MY_IPPROTO_UDP ); myinet_del_protocol(&mytcp_protocol, MY_IPPROTO_TCP );#ifdef CONFIG_IP_MULTICAST myinet_del_protocol(&myigmp_protocol, MY_IPPROTO_IGMP);#endif (void)sock_unregister( MY_PF_INET );}module_init( myinet_init )module_exit( myinet_exit )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -