From owner-freebsd-hackers Wed Jun 28 12:21:15 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from griffin.aciri.org (griffin.aciri.org [192.150.187.12]) by hub.freebsd.org (Postfix) with ESMTP id 0C65F37C0EB for ; Wed, 28 Jun 2000 12:21:07 -0700 (PDT) (envelope-from wilbertdg@hetnet.nl) Received: from hetnet.nl (localhost.aciri.org [127.0.0.1]) by griffin.aciri.org (8.9.3/8.9.3) with ESMTP id MAA86341 for ; Wed, 28 Jun 2000 12:21:03 -0700 (PDT) (envelope-from wilbertdg@hetnet.nl) Message-ID: <395A501F.50CA476E@hetnet.nl> Date: Wed, 28 Jun 2000 12:21:03 -0700 From: Wilbert de Graaf X-Mailer: Mozilla 4.73 [en] (X11; U; Linux 2.0.36 i386) X-Accept-Language: en MIME-Version: 1.0 To: freebsd-hackers@freebsd.org Subject: Getting the plain void* through the generic ioctl processing Content-Type: multipart/alternative; boundary="------------651756F39847F164F7E0CB33" Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --------------651756F39847F164F7E0CB33 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Could anybody advise me on this: 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 --------------651756F39847F164F7E0CB33 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit Could anybody advise me on this:

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
 
  --------------651756F39847F164F7E0CB33-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message