Reputation: 109
I use a security operation 'socket_recvmsg' in the Linux security module.
int (*socket_recvmsg) (struct socket *sock,struct msghdr *msg, int size, int flags)
Msg->msg_name is supposed to point to a struct sockaddr_in, which contains the sin_family, source port and source ip address. msg->msg_namelen indicates the size of data pointed by msg->msg_name. However, the msg->msg->namelen in my socket_recvmsg function is always 112, which is far larger than sizeof(struct sockaddr_in). So I guess msg->msg_name must point to some other data structure, rather than struct sockaddr_in. Does anyone know what data type the msg->msg_name in socket_recvmsg point to?
Also, the msg->msg_name in my sendmsg function always equals to sizeof(struct sockaddr_in), and I can get port and ip address from msg->msg_name in sendmsg function.
Upvotes: 1
Views: 3516
Reputation: 109
socket_recvmsg
is a hook function in security.h
. It provides permission checking for recvmsg
call. However, the hook is a pre-op, which means the hook function occurs before the actual operation recvmsg
. At the stage of socket_recvmsg, the struct msg
has not been set up for any specific sockaddr
.
I tested on centos 6.6. The msg->msg_len
is 112 for udp socket, and is 128 for tcp packet at socket_recvmsg
.
Upvotes: 0
Reputation: 21213
The msg_name
field of struct msghdr
does not necessarily have to point to a struct sockaddr_in
: it points to a generic socket address; the exact structure depends on the socket family: if it's an AF_UNIX
socket, it points to a struct sockaddr_un
, if it's AF_INET
, it points to struct sockaddr_in
, and if it's AF_INET6
it points to struct sockaddr_in6
. All of them share the sa_family
field, which is also the first field, so you can cast msg_name
to struct sockaddr *
, read the sa_family
field, and decide where to go from there.
Keep in mind that there may be other socket families implemented; Linux, for example, has AF_APPLETALK
, AF_X25
, and some others I don't remember right now.
Also, the msg->msg_name in my sendmsg function always equals to sizeof(struct sockaddr_in)
This is true as long as you're using AF_INET
sockets, because ip addresses and port numbers have a fixed length. But the size argument is not always a statically known value. In UNIX sockets (local sockets), the size you pass is not sizeof(struct sockaddr_un)
, but instead it is offsetof(struct sockaddr_un, sa_data)+strlen(pathname)
, where pathname
is the size of the path string in the filesystem where the socket handle lives.
Upvotes: 3