#include <linux/module.h>
#include <linux/init.h>
#include <linux/net.h>
#include <net/sock.h>
#define PF_MYFAMILY 28
static void stream_csk_destroy_sock(struct sock * sk)
{
skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_error_queue);
skb_queue_purge(&sk->sk_write_queue);
sock_put(sk);
}
static void my_proto_close(struct sock *sk, long timeout)
{
lock_sock(sk);
sock_hold(sk); /* increment sk_refcnt */
sock_orphan(sk); /* set sk_flag SOCK_DEAD flag */
release_sock(sk);
local_bh_disable(); /* close current cpu softirq */
bh_lock_sock(sk); /* spin_lock */
stream_csk_destroy_sock(sk);
bh_unlock_sock(sk);
local_bh_enable(); /* spin_unlock */
sock_put(sk); /* if sk_refcnt = 0, call sk_free(sk) */
printk(KERN_ALERT "my_proto_close ok/n");
}
struct my_priv_struct
{
struct sock sk;
int flag;
};
static struct proto my_proto =
{
.name = "my_proto",
.owner = THIS_MODULE,
.close = my_proto_close,
.obj_size = sizeof(struct my_priv_struct),
};
static int my_release(struct socket *sock)
{
struct sock *sk = sock->sk;
sock->sk = NULL;
sk->sk_prot->close(sk, 0);
printk(KERN_ALERT "my_release ok/n");
return 0;
}
static struct proto_ops my_ops =
{
.family = PF_MYFAMILY,
.owner = THIS_MODULE,
.release = my_release,
};
static int family_create(struct socket *sock, int protocol)
{
struct sock *sk;
sock->state = SS_UNCONNECTED;
sock->ops = &my_ops;
sk = sk_alloc(PF_MYFAMILY, GFP_KERNEL, &my_proto, 1);
if (!sk)
{
printk(KERN_NOTICE "sk_alloc failure/n");
goto alloc_err;
}
sock_init_data(sock, sk);
return 0;
alloc_err:
return -1;
}
static struct net_proto_family family =
{
.family = PF_MYFAMILY,
.create = family_create,
.owner = THIS_MODULE,
};
static int __init private_init(void)
{
int ret;
ret = proto_register(&my_proto, 1);
if (ret < 0)
{
printk(KERN_ALERT "proto_register failure/n");
goto proto_err;
}
ret = sock_register(&family);
if (ret < 0)
{
printk(KERN_NOTICE "sock_register failure/n");
goto sock_err;
}
printk(KERN_NOTICE "sock_register success/n");
return 0;
sock_err:
proto_unregister(&my_proto);
proto_err:
return -1;
}
static void __exit private_exit(void)
{
sock_unregister(PF_MYFAMILY);
}
module_init(private_init);
module_exit(private_exit);
MODULE_LICENSE("GPL");
自定义协议族
最新推荐文章于 2025-06-17 10:09:18 发布