2002-07-11 19:45:19

by Shipman, Jeffrey E

[permalink] [raw]
Subject: ioctl between user/kernel space

I'm not sure if this is the right place to ask this, but
I have a question about ioctl(). I have a situation where
I need to parse a file and build a hash table out of the
information in user space. Then, I must pass that hash
table into my module that's in kernel space. My question
is: is ioctl() the way to go about this? I really don't
know much about the function, but some people have mentioned
it to me as the way to pass information between user and
kernel space.

If anyone has advice on if this is the way to go about it
or how we could go about doing this would be greatly
appreciated. Also, if anyone knows of any websites which
may be helpful in this area, we'd appreciate that as
well.

Thanks.

Jeff Shipman - CCD
Sandia National Laboratories
(505) 844-1158 / MS-1372


2002-07-11 20:07:43

by Richard B. Johnson

[permalink] [raw]
Subject: Re: ioctl between user/kernel space

On Thu, 11 Jul 2002, Shipman, Jeffrey E wrote:

> I'm not sure if this is the right place to ask this, but
> I have a question about ioctl(). I have a situation where
> I need to parse a file and build a hash table out of the
> information in user space. Then, I must pass that hash
> table into my module that's in kernel space. My question
> is: is ioctl() the way to go about this? I really don't
> know much about the function, but some people have mentioned
> it to me as the way to pass information between user and
> kernel space.
>
> If anyone has advice on if this is the way to go about it
> or how we could go about doing this would be greatly
> appreciated. Also, if anyone knows of any websites which
> may be helpful in this area, we'd appreciate that as
> well.
>
> Thanks.
>
> Jeff Shipman - CCD
> Sandia National Laboratories
> (505) 844-1158 / MS-1372

That's what ioctl() is/was designed for. In user-space, you have

int ioctl(fd, FUNCTION_NR, parameter);

... where fd is your open file-handle, FUNCTION_NR is whatever you want
to define a specific control for your device, and parameter is usually
a pointer to some parameters (like a buffer).

In the module, you have.

int any_name(struct inode *ip, struct file *fp, unsigned int command,
unsigned long arg);

'ip' and 'fp' will probably be ignored in your module.
'command' is your FUNCTION_NR, and 'arg' is your parameter.
You cast 'arg' to a pointer of your choice if the user-mode
code supplies a pointer.

The address (pointer) of your function goes into the
'struct file_operations' (7th member) that you pass a pointer
to when you initialize your device (register_xxxdev()).

The normal return code is 0. You return a -ERRNO if any errors
are encountered in your function.

Typically, you do:

switch(command)
{
case FIRST_FUNCTION:
....
break;
default:
return -ESPIPE; // Invalid stuff, lets you still test with
// standard text tools (od, hexdump, etc).
}

Cheers,
Dick Johnson

Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).

Windows-2000/Professional isn't.

2002-07-11 20:36:53

by Shipman, Jeffrey E

[permalink] [raw]
Subject: RE: ioctl between user/kernel space

Thanks for your answers. I do have a couple more questions,
however:

1) I'm not dealing with any hardware. Is it still ok to
call some sort of register_xxxdev() function? If so, where can
I find the definitions of these register functions and which
one would you think be appropriate for a module which simply
does packet manipulation via Netfilter?

2) What if my module is not in the kernel? Does ioctl()
just return an error code?

Thanks again.

Jeff Shipman - CCD
Sandia National Laboratories
(505) 844-1158 / MS-1372


-----Original Message-----
From: Richard B. Johnson [mailto:[email protected]]
Sent: Thursday, July 11, 2002 2:14 PM
To: Shipman, Jeffrey E
Cc: '[email protected]'
Subject: Re: ioctl between user/kernel space


On Thu, 11 Jul 2002, Shipman, Jeffrey E wrote:

> I'm not sure if this is the right place to ask this, but
> I have a question about ioctl(). I have a situation where
> I need to parse a file and build a hash table out of the
> information in user space. Then, I must pass that hash
> table into my module that's in kernel space. My question
> is: is ioctl() the way to go about this? I really don't
> know much about the function, but some people have mentioned
> it to me as the way to pass information between user and
> kernel space.
>
> If anyone has advice on if this is the way to go about it
> or how we could go about doing this would be greatly
> appreciated. Also, if anyone knows of any websites which
> may be helpful in this area, we'd appreciate that as
> well.
>
> Thanks.
>
> Jeff Shipman - CCD
> Sandia National Laboratories
> (505) 844-1158 / MS-1372

That's what ioctl() is/was designed for. In user-space, you have

int ioctl(fd, FUNCTION_NR, parameter);

... where fd is your open file-handle, FUNCTION_NR is whatever you want
to define a specific control for your device, and parameter is usually
a pointer to some parameters (like a buffer).

In the module, you have.

int any_name(struct inode *ip, struct file *fp, unsigned int command,
unsigned long arg);

'ip' and 'fp' will probably be ignored in your module.
'command' is your FUNCTION_NR, and 'arg' is your parameter.
You cast 'arg' to a pointer of your choice if the user-mode
code supplies a pointer.

The address (pointer) of your function goes into the
'struct file_operations' (7th member) that you pass a pointer
to when you initialize your device (register_xxxdev()).

The normal return code is 0. You return a -ERRNO if any errors
are encountered in your function.

Typically, you do:

switch(command)
{
case FIRST_FUNCTION:
....
break;
default:
return -ESPIPE; // Invalid stuff, lets you still test with
// standard text tools (od, hexdump, etc).
}

Cheers,
Dick Johnson

Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).

Windows-2000/Professional isn't.


2002-07-12 11:37:03

by Richard B. Johnson

[permalink] [raw]
Subject: RE: ioctl between user/kernel space

On Thu, 11 Jul 2002, Shipman, Jeffrey E wrote:

> Thanks for your answers. I do have a couple more questions,
> however:
>
> 1) I'm not dealing with any hardware. Is it still ok to
> call some sort of register_xxxdev() function? If so, where can
> I find the definitions of these register functions and which
> one would you think be appropriate for a module which simply
> does packet manipulation via Netfilter?
>

In that case, you want to look at ../ipv4/netfilter/ip_fw_compat.c and
../ipv4/netfilter/ip_chains_core.c.

You can see that these network things don't generally use ioctl(),
although a device driver can. Instead, you probably should use
setsockopt() from user-space and enable it in you driver with:
nf_register_sockopt(struct nf_sock_ops *);

Your function address is put into the 6th member of nf_sock_ops. Just
check out existing code in netfilter. It's quite straight-forward.

setsockopt(int s, int level, int name, void *val, int len);
The void *val can be a pointer to your table of parameters and
it's length is put into len.

> 2) What if my module is not in the kernel? Does ioctl()
> just return an error code?
>

Well, if it's not in the kernel, you can do anything you want,
passing parameters using shared-memory to Morse-Code, and everything
in-between.

> Thanks again.
>
> Jeff Shipman - CCD
> Sandia National Laboratories
> (505) 844-1158 / MS-1372



Cheers,
Dick Johnson

Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).

Windows-2000/Professional isn't.