Discussion:
tap interface address
(too old to reply)
Iain Hibbert
2008-08-11 13:23:50 UTC
Permalink
Hi,

Am trying to open a tap(4) device and get the interface address, but
SIOCGIFADDR does not work (though it seems that it should, looking at the
if_tap.c code and ether_ioctl()) No error is produced but nothing is
returned. test program attached, output (with linewraps added) is:

name: tap0
dump:
74 61 70 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

is there a some incantation I must do? There does get printed on the
console a message:

tap0: Ethernet address f2:0b:a4:60:f5:03
tap0: detached

and I worked out how to change the physical address using SIOCSIFPHYADDR
but I wanted to see what the address actually was as reported by ifconfig
(I got lost in the twisty passages there, not sure how it gets it)

the tap(4) manpage mentions a sysctl node but that seems overcomplicated

regards,
iain
Quentin Garnier
2008-08-11 14:37:26 UTC
Permalink
Post by Iain Hibbert
Hi,
Am trying to open a tap(4) device and get the interface address, but
SIOCGIFADDR does not work (though it seems that it should, looking at the
if_tap.c code and ether_ioctl()) No error is produced but nothing is
I... doubt that. tap_dev_ioctl() returns ENOTTY (as it should). I'll
try though, there might be a bug.
Post by Iain Hibbert
and I worked out how to change the physical address using SIOCSIFPHYADDR
That won't work either if you do it on the fd returned by /dev/tap.
Post by Iain Hibbert
but I wanted to see what the address actually was as reported by ifconfig
(I got lost in the twisty passages there, not sure how it gets it)
the tap(4) manpage mentions a sysctl node but that seems overcomplicated
The sysctl is for human, or static boot configuration, because ifconfig
doesn't (didn't? I can't remember the status of that) support changing
the Ethernet address of an interface.

Iain, the way one is supposed to manipulate an interface is through a
socket. So you have to open a socket first (AF_INET is fine to do the
SIOCSIFPHYADDR call, and you can use it later to set an ipv4 address on
the interface and so on), and then do the ioctl calls on it.

I don't think I should blindly let ioctls go to tap_ioctl from the
character device, but I guess I could at least allow my kludgy
SIOCSIFPHYADDR. Though usually if you're playing with a tap interface
you'll need a socket at some point.
--
Quentin Garnier - ***@cubidou.net - ***@NetBSD.org
"See the look on my face from staying too long in one place
[...] every time the morning breaks I know I'm closer to falling"
KT Tunstall, Saving My Face, Drastic Fantastic, 2007.
Iain Hibbert
2008-08-11 18:10:59 UTC
Permalink
Post by Quentin Garnier
Post by Iain Hibbert
Hi,
Am trying to open a tap(4) device and get the interface address, but
SIOCGIFADDR does not work (though it seems that it should, looking at the
if_tap.c code and ether_ioctl()) No error is produced but nothing is
I... doubt that. tap_dev_ioctl() returns ENOTTY (as it should). I'll
try though, there might be a bug.
Mm, maybe you are right, but the program shows no error (is ENOTTY
rewritten to something else in the dev code?)
Post by Quentin Garnier
Post by Iain Hibbert
and I worked out how to change the physical address using SIOCSIFPHYADDR
That won't work either if you do it on the fd returned by /dev/tap.
Sorry - yes, was using a socket (BTPROTO_L2CAP) for that.

If I try the SIOCGIFADDR through that socket I do get ENOTTY.

Interestingly, using socket(PF_INET, SOCK_STREAM, 0) gives EADDRNOTAVAIL
as does (PF_INET, SOCK_DGRAM, 0) but (PF_INET, SOCK_SEQPACKET, 0) is
EOPNOTSUPP.

I thought that the 'i' ioctls were diverted to the network stack?

I wonder if I need to prepare the sockaddr somehow?
Post by Quentin Garnier
Iain, the way one is supposed to manipulate an interface is through a
socket. So you have to open a socket first (AF_INET is fine to do the
SIOCSIFPHYADDR call, and you can use it later to set an ipv4 address on
the interface and so on), and then do the ioctl calls on it.
dhclient will handle all that stuff. I just want to get the address
Post by Quentin Garnier
I don't think I should blindly let ioctls go to tap_ioctl from the
character device, but I guess I could at least allow my kludgy
SIOCSIFPHYADDR. Though usually if you're playing with a tap interface
you'll need a socket at some point.
Well, you need the fd for the IO in any case..

iain

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2008-08-11 19:24:10 UTC
Permalink
Post by Iain Hibbert
Post by Quentin Garnier
I... doubt that. tap_dev_ioctl() returns ENOTTY (as it should).
Mm, maybe you are right, but the program shows no error (is ENOTTY
rewritten to something else in the dev code?)
More likely, it seems to me, is that userland recognizes ENOTTY
specially and doesn't report any error in that case.

Or is "the program" custom code? This guess is based on the assumption
that it's a stock tool like ifconfig or netstat.

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Iain Hibbert
2008-08-11 19:38:20 UTC
Permalink
Post by Iain Hibbert
Interestingly, using socket(PF_INET, SOCK_STREAM, 0) gives EADDRNOTAVAIL
as does (PF_INET, SOCK_DGRAM, 0) but (PF_INET, SOCK_SEQPACKET, 0) is
EOPNOTSUPP.
I thought that the 'i' ioctls were diverted to the network stack?
and they are, when passed through a socket.
Post by Iain Hibbert
I wonder if I need to prepare the sockaddr somehow?
to answer my own question, no

If SIOCGIFADDR is called on a socket, it will get routed to the
PRU_CONTROL code of the socket rather than the ioctl code of the device.
In this case, because there is no INET address associated with the tap
(its just been made) I get an error.

There are no L2CAP ioctl's, so the protocol code returns EPASSTHROUGH
which is translated to ENOTTY.

So, how do I get to the ethernet address? (technically, it does not have
any address family protocol code :)

I'm supposing that SIOCGLIFPHYADDR would be the one (matches the
SIOCSLIFPHYADDR that is used to set the same) -- this is implemented in
gif(4) and gre(4) but I don't see any documentation about it.

iain

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2008-08-11 20:46:53 UTC
Permalink
Post by Iain Hibbert
So, how do I get to the ethernet address? (technically, it does not
have any address family protocol code :)
I thought that's what AF_LINK was for...?

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Iain Hibbert
2008-08-11 20:58:02 UTC
Permalink
Post by der Mouse
Post by Iain Hibbert
Post by Quentin Garnier
I... doubt that. tap_dev_ioctl() returns ENOTTY (as it should).
Mm, maybe you are right, but the program shows no error (is ENOTTY
rewritten to something else in the dev code?)
More likely, it seems to me, is that userland recognizes ENOTTY
specially and doesn't report any error in that case.
Or is "the program" custom code? This guess is based on the assumption
that it's a stock tool like ifconfig or netstat.
"the program" was the minimal test code attached :)

The other program I'm working on is more complex but not quite ready (a
Bluetooth PAN daemon - its fairly complete and I'm using it now, am just
tidying up some loose ends)

This 'implements some of the features of an ethernet bridge' according to
the spec, and I wanted the address of the interface so I can do some half
intelligent routing. Currently, the tap channel is '00:00:00:00:00:00'
which actually doesn't cause much trouble (If I don't see a unicast
address, I broadcast the packet all around) but its not very clean.

Also I was considering rewriting the address and hiding the MAC address of
the tap from the bluetooth clients (with more than one radio, you can't
just set it to the bluetooth MAC address). This would solve a slight
problem where (with my windows mobile phone) the remote device won't seem
to talk to the tap, it will only speak to the 'directly connected' device
address, but I'm not sure that its 'proper' to rewrite addresses in this
way?

iain

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Iain Hibbert
2008-08-11 21:16:53 UTC
Permalink
Post by der Mouse
Post by Iain Hibbert
So, how do I get to the ethernet address? (technically, it does not
have any address family protocol code :)
I thought that's what AF_LINK was for...?
Ok, I admit it.

s = socket(PF_LINK, SOCK_DGRAM, 0);

memset(&iflr, 0, sizeof(iflr));
memcpy(iflr.iflr_name, ifr.ifr_name, IFNAMSIZ);

sdl = (struct sockaddr_dl *)&iflr.addr;
sdl->sdl_family = AF_LINK;
sdl->sdl_len = sizeof(struct sockaddr_dl);
sdl->sdl_alen = ETHER_ADDR_LEN;

if (ioctl(s, SIOCGLIFADDR, &iflr) == -1) {
syslog(LOG_ERR, "Could not get interface address: %m");
exit(EXIT_FAILURE);
}

gives me the address with CLLADDR(sdl), thanks!

iain

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...