For an implementation of IGMPv3, I
had to extend the socket api
following the draft(s). I had to add
two ioctl commands:
SIO_GET_MULTICAST_FILTER and SIO_SET_MULTICAST_FILTER.
The argument is a
structure that has a variable size.
FreeBSD uses some macros, and the
one I added looks like
#define SIO_SET_MULTICAST_FILTER _IOWR('s', 63, struct ip_msfilter*)
I couldn't use 'struct ip_msfilter'
since this structure has a variable
size. Now this macro makes a unsigned
long from all this, where the
length of the structure is encoded
using sizeof(struct ip_msfilter*).
This makes the ioctl pre-processing
(sys_generic.c) copy 4 bytes from
this pointer into the kernel. But
this data is worthless to me, since it
is the first 4 bytes of the structure
itself. What I want is the pointer
itself. I understand that I can do
this by making people pass the
address of a pointer to ioctl(), but
this is kind of ugly I think. And
besides, the other OS'es don't need
this.
But the good news is that I found a
way around, but the question is if
this is okay. If I follow the code,
I can make the generic ioctl()
preprocessing giving me the datapointer
itself when the length equals
zero. One way to make the length zero
is to change the macro into
#define SIO_SET_MULTICAST_FILTER _IOWR('s', 63, struct {})
since sizeof(struct {}) returns zero.
My question is, is the ioctl()
code in sys_generic.c meant to be
able to handle cases where size = 0,
or is this a dirty 'trick' that probably
won't make it in a next
version. Any reason not do solve it
like this?
- Wilbert

