我在Linux安全模块中使用安全操作'socket_recvmsg'。
int (*socket_recvmsg) (struct socket *sock,struct msghdr *msg, int size, int flags)
Msg-> msg_name应该指向struct sockaddr_in,它包含sin_family,源端口和源IP地址。 msg-> msg_namelen表示msg-> msg_name指向的数据大小。但是,我的socket_recvmsg函数中的msg-> msg-> namelen总是112,远远大于sizeof(struct sockaddr_in)。所以我猜msg-> msg_name必须指向其他一些数据结构,而不是struct sockaddr_in。有谁知道socket_recvmsg中的msg-> msg_name指向哪种数据类型?
此外,我的sendmsg函数中的msg-> msg_name总是等于sizeof(struct sockaddr_in),我可以从sendmsg函数中的msg-> msg_name获取端口和IP地址。
答案 0 :(得分:0)
msg_name
的{{1}}字段不一定必须指向struct msghdr
:它指向通用套接字地址;确切的结构取决于套接字族:如果它是struct sockaddr_in
套接字,则它指向AF_UNIX
,如果它是struct sockaddr_un
,则它指向AF_INET
1}},如果它struct sockaddr_in
指向AF_INET6
。它们共享struct sockaddr_in6
字段,这也是第一个字段,因此您可以将sa_family
转换为msg_name
,阅读struct sockaddr *
字段,并决定从哪里开始那里。
请记住,可能还有其他套接字系列已实现;例如,Linux有sa_family
,AF_APPLETALK
和其他一些我现在不记得的。
此外,我的sendmsg函数中的msg-> msg_name始终等于 sizeof(struct sockaddr_in)
只要您使用AF_X25
套接字就行,这是正确的,因为IP地址和端口号具有固定长度。但是size参数并不总是一个静态已知的值。在UNIX套接字(本地套接字)中,传递的大小不是AF_INET
,而是sizeof(struct sockaddr_un)
,其中offsetof(struct sockaddr_un, sa_data)+strlen(pathname)
是文件系统中套接字句柄的路径字符串的大小住。
答案 1 :(得分:0)
socket_recvmsg
是security.h
中的钩子函数。它为recvmsg
电话提供权限检查。但是,钩子是一个pre-op,这意味着钩子函数在实际操作recvmsg
之前发生。在socket_recvmsg阶段,尚未为任何特定struct msg
设置sockaddr
。
我在centos 6.6上测试过。对于udp套接字,msg->msg_len
为112,对于socket_recvmsg
的tcp数据包为{128}。