0

I am using a 4.x linux kernel and have a kernel module where I receive socket information when opening up a socket.

if ((fd = socket(sai.sin_family, skt_type, skt_protocol)) < 0)
    // ...

In this case, I am making use of UDP and before I transmit my first bit of data using sendto(), I would like to be able to pass in a data structure from my client program into my kernel module. I could then add extra information into my protocol and relate this data to the file descriptor. This is not user data, rather, it's intended to control how my protocol will function.

The data structure I would like to pass in and relate to the socket is something like the following.

struct some_tag_info_t {
    int field_t;
    char field_a[MAX_A];
    void *field_b;
};

I have a feeling ioctl might do something for me as it seems to be able to manipulate the underlying device parameters with a file descriptor.

In net/socket.c, ioctl() is:

static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)

And after the function, I see this comment.

/*
 *  With an ioctl, arg may well be a user mode pointer, but we don't know
 *  what to do with it - that's up to the protocol still.
 */

It would appear I could use arg to pass in my struct some_tag_info_t above? Can anyone comment to this? Any thoughts?

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
Ender
  • 1,652
  • 2
  • 25
  • 50
  • 1
    If you're writing your own protocol, you might want to get this info through `setsockopt(2)`, which seems more appropriate. – Marco Bonelli Sep 17 '21 at 22:58
  • Thank you, that does appear to be what I need. If I understand this correctly, the optval of parameter of setsockopt() is acceptable for passing my struct with. And if so, feel free to make this an answer and I'll mark it. – Ender Sep 18 '21 at 00:20

1 Answers1

1

Your understanding is correct, you could pass anything to your ioctl() handler from userspace, it's then up to the kernel module to correctly handle whatever command and argument you pass. However, since you are working with sockets and writing your own protocol, it would be more appropriate to implement this functionality through getsockopt(2)/setsockopt(2). The argument to setsockopt(2) can be anything you want. From userspace you would do something like:

res = setsockopt(sock_fd, &your_struct, sizeof(your_struct));
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128