Date: Wed, 28 Jun 2000 12:21:03 -0700 From: Wilbert de Graaf <wilbertdg@hetnet.nl> To: freebsd-hackers@freebsd.org Subject: Getting the plain void* through the generic ioctl processing Message-ID: <395A501F.50CA476E@hetnet.nl>
next in thread | raw e-mail | index | archive | help
--------------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 <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <font face="Courier New,Courier">Could anybody advise me on this:</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">For an implementation of IGMPv3, I had to extend the socket api</font> <br><font face="Courier New,Courier">following the draft(s). I had to add two ioctl commands:</font> <br><font face="Courier New,Courier">SIO_GET_MULTICAST_FILTER and SIO_SET_MULTICAST_FILTER. The argument is a</font> <br><font face="Courier New,Courier">structure that has a variable size. FreeBSD uses some macros, and the</font> <br><font face="Courier New,Courier">one I added looks like</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">#define SIO_SET_MULTICAST_FILTER _IOWR('s', 63, struct ip_msfilter*)</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">I couldn't use 'struct ip_msfilter' since this structure has a variable</font> <br><font face="Courier New,Courier">size. Now this macro makes a unsigned long from all this, where the</font> <br><font face="Courier New,Courier">length of the structure is encoded using sizeof(struct ip_msfilter*).</font> <br><font face="Courier New,Courier">This makes the ioctl pre-processing (sys_generic.c) copy 4 bytes from</font> <br><font face="Courier New,Courier">this pointer into the kernel. But this data is worthless to me, since it</font> <br><font face="Courier New,Courier">is the first 4 bytes of the structure itself. What I want is the pointer</font> <br><font face="Courier New,Courier">itself. I understand that I can do this by making people pass the</font> <br><font face="Courier New,Courier">address of a pointer to ioctl(), but this is kind of ugly I think. And</font> <br><font face="Courier New,Courier">besides, the other OS'es don't need this.</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">But the good news is that I found a way around, but the question is if</font> <br><font face="Courier New,Courier">this is okay. If I follow the code, I can make the generic ioctl()</font> <br><font face="Courier New,Courier">preprocessing giving me the datapointer itself when the length equals</font> <br><font face="Courier New,Courier">zero. One way to make the length zero is to change the macro into</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">#define SIO_SET_MULTICAST_FILTER _IOWR('s', 63, struct {})</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">since sizeof(struct {}) returns zero. My question is, is the ioctl()</font> <br><font face="Courier New,Courier">code in sys_generic.c meant to be able to handle cases where size = 0,</font> <br><font face="Courier New,Courier">or is this a dirty 'trick' that probably won't make it in a next</font> <br><font face="Courier New,Courier">version. Any reason not do solve it like this?</font><font face="Courier New,Courier"></font> <p><font face="Courier New,Courier">- Wilbert</font> <br><font face="Courier New,Courier"></font> <br> </html> --------------651756F39847F164F7E0CB33-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?395A501F.50CA476E>