2010-07-29 23:41:48

by Guram Z. Savinov

[permalink] [raw]
Subject: Get interface MAC address in sys_accept4() syscall

Hi all,

in net/socket.c is syscall sys_accept4(). In it syscall I need to get
MAC address of interface, from connection is come.
For example it is two interfaces eth0 and eth1. I want to know, from
what interface connection is come to sys_accept4().
Please help me, how I can do it.

Thank's for attention for my question.


2010-07-29 23:51:11

by Guram Z. Savinov

[permalink] [raw]
Subject: Re: Get interface MAC address in sys_accept4() syscall

30.07.2010 03:42, Guram Z. Savinov пишет:
> Hi all,
>
> in net/socket.c is syscall sys_accept4(). In it syscall I need to get
> MAC address of interface, from connection is come.
> For example it is two interfaces eth0 and eth1. I want to know, from
> what interface connection is come to sys_accept4().
> Please help me, how I can do it.
>
> Thank's for attention for my question.
I forget tell: kernel version: 2.6.28
Here is code of sys_accept4() syscall, in it I need get MAC address of
interface:

/*
* For accept, we attempt to create a new socket, set up the link
* with the client, wake up the client, then return the new
* connected fd. We collect the address of the connector in kernel
* space and move it to user at the very end. This is unclean because
* we open the socket then return an error.
*
* 1003.1g adds the ability to recvmsg() to query connection pending
* status to recvmsg. We need to add that support in a way thats
* clean when we restucture accept also.
*/

asmlinkage long sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
int __user *upeer_addrlen, int flags)
{
struct socket *sock, *newsock;
struct file *newfile;
int err, len, newfd, fput_needed;
struct sockaddr_storage address;

if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
return -EINVAL;

if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;

sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (!sock)
goto out;

err = -ENFILE;
if (!(newsock = sock_alloc()))
goto out_put;

newsock->type = sock->type;
newsock->ops = sock->ops;

/*
* We don't need try_module_get here, as the listening socket (sock)
* has the protocol module (sock->ops->owner) held.
*/
__module_get(newsock->ops->owner);

newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC);
if (unlikely(newfd < 0)) {
err = newfd;
sock_release(newsock);
goto out_put;
}

err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK);
if (err < 0)
goto out_fd_simple;

err = security_socket_accept(sock, newsock);
if (err)
goto out_fd;

err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0)
goto out_fd;

if (upeer_sockaddr) {
if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
&len, 2) < 0) {
err = -ECONNABORTED;
goto out_fd;
}
err = move_addr_to_user((struct sockaddr *)&address,
len, upeer_sockaddr, upeer_addrlen);
if (err < 0)
goto out_fd;
}

/* File flags are not inherited via accept() unlike another OSes. */

fd_install(newfd, newfile);
err = newfd;

security_socket_post_accept(sock, newsock);

out_put:
fput_light(sock->file, fput_needed);
out:
return err;
out_fd_simple:
sock_release(newsock);
put_filp(newfile);
put_unused_fd(newfd);
goto out_put;
out_fd:
fput(newfile);
put_unused_fd(newfd);
goto out_put;
}

2010-07-30 07:13:09

by Cong Wang

[permalink] [raw]
Subject: Re: Get interface MAC address in sys_accept4() syscall

On Fri, Jul 30, 2010 at 03:42:14AM +0400, Guram Z. Savinov wrote:
>Hi all,
>
>in net/socket.c is syscall sys_accept4(). In it syscall I need to get
>MAC address of interface, from connection is come.
>For example it is two interfaces eth0 and eth1. I want to know, from
>what interface connection is come to sys_accept4().
>Please help me, how I can do it.
>

It is not obtained from accept(2), you get it with ioctl SIOCGIFHWADDR.

2010-07-30 09:59:43

by Cong Wang

[permalink] [raw]
Subject: Re: Get interface MAC address in sys_accept4() syscall

On Fri, Jul 30, 2010 at 01:56:06PM +0400, Гурам Савинов wrote:
>I want to change syscall sys_accept4(), to return MAC address.
>It is possible to get MAC from incomming socket in sys_accept4(), with help
>ioctl SIOCGIFHWADDR?
>

The problem is that it doesn't make sense to do this.

accept(2) works on high level sockets, should not bother low level
MAC addresses.

2010-07-30 10:22:57

by Guram Z. Savinov

[permalink] [raw]
Subject: Re: Get interface MAC address in sys_accept4() syscall

Yes, I know, but sys_accept4() have int fd argument, that is socket
descriptor, can I work with it like raw socket and get MAC from
ethernet frame?

2010/7/30 Américo Wang <[email protected]>
>
> On Fri, Jul 30, 2010 at 01:56:06PM +0400, Гурам Савинов wrote:
> >I want to change syscall sys_accept4(), to return MAC address.
> >It is possible to get MAC from incomming socket in sys_accept4(), with help
> >ioctl SIOCGIFHWADDR?
> >
>
> The problem is that it doesn't make sense to do this.
>
> accept(2) works on high level sockets, should not bother low level
> MAC addresses.
>

2010-07-30 16:15:58

by Miquel van Smoorenburg

[permalink] [raw]
Subject: Re: Get interface MAC address in sys_accept4() syscall

In article <[email protected]> you write:
>Yes, I know, but sys_accept4() have int fd argument, that is socket
>descriptor, can I work with it like raw socket and get MAC from
>ethernet frame?

You can do getsockname(2) on the socket and you'll get the IP address
of the local interface.

You can then use getifaddrs(3) to get a list of local interfaces,
loop over all of them, and compare the IP address to the one you got
from getsockame().

Once you have the name of the interface, loop over the results
from getifaddrs() again, and find the AF_PACKET address of that
interface. The AF_PACKET address has the MAC address. See packet(7).

Mike.