最近遇到一个raw socket的问题;
所以baidu找了一下,都是讲使用的;
很少涉及内核的实现啊;
有必要学习一下(挖个坑,慢慢填);
SOCK_RAW
socket创建的一篇文章
https://www.cnblogs.com/hyd-desert-camel/p/3536341.html
看完后,就知道socket创建在内核代码中是这样的,用户态代码没有看到;
net\socket.c中
int __sock_create(struct net *net, int family, int type, int protocol,
struct socket **res, int kern)
里面有个security_socket_create,里面调用了函数指针,这有点牙疼,看代码其实比较讨厌看到函数指针的;
int security_socket_create(int family, int type, int protocol, int kern)
{
return security_ops->socket_create(family, type, protocol, kern);
}
后面又会调用这个,看前面的文章,里面有些,这个在net_init里面有初始化了,省去了我很多查找时间,多谢
err = pf->create(net, sock, protocol, kern);
//由前面的inet_init()中的sock_register可知,把inet_family_ops装载进去,而这张表的create成员(也可以叫行为)挂入的是inet_create(),
这个函数再net\ipv4\Af_inet.c里面;
static int inet_create(struct net *net, struct socket *sock, int protocol, int kern);
有几处涉及到raw_socket,水平有限,抄一下上面文章的注释,再次感谢作者
/*由inet_ehash_secret的值看是否有加密字符串,若没有则检查协议类型(只有TCP肯能有加密字符串),如果socket类型不是原始套接字或者数据报型的话,则创建一个加密字符串*/
if (unlikely(!inet_ehash_secret))
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
build_ehash_secret();
/*检查通用性。只有root才有权限使用原始套接字。*/
if (sock->type == SOCK_RAW && !kern &&
!ns_capable(net->user_ns, CAP_NET_RAW))
goto out_rcu_unlock;
/*判断是否是原始套接字,如果是,新建IP头部*/
if (SOCK_RAW == sock->type) {
inet->inet_num = protocol;
if (IPPROTO_RAW == protocol)
inet->hdrincl = 1;
}
建立貌似就这么多了,其他的在接收中有处理吗?
未完待续;预计坑深一万米。
linux内核中socket的创建过程源码分析(总结性质)
https://www.jianshu.com/p/5d82a685b5b6
这个文章也很好,感谢作者 ;
linux内核网络栈---socket调用内核路径
https://blog.csdn.net/codingcs/article/details/77803983
这个有其他的处理路径说明,感谢作者;
问题解决了:最后是网口驱动的问题;