0

First thing's first, you can find the details of my situation from my previous post

I've spent the past day or so working on a first attempt on a netlink socket program.

And I don't attempt to make it sound like I didn't get all this code from other people's sample code that I found all over the internet because we all know I did just that.

But I've been trying to reverse-engineer my way through the code (see end) and after hours of debugging I finally got it to compile without errors. But after attempting to run it, I get the message "Segmentation Fault (Core Dumped)".

Now I know this error has to do with attempting to read from an invalid memory location but I honestly don't understand half the code I spliced together so if anyone can point out to me where I'm going wrong I would appreciate it.

I would also really really appreciate you if you could explain what I am doing right/wrong in trying to send a message via netlink sockets in general as well. Like, for instance, where would I put the message? Because I really don't know what message I would be sending right now with my code as-is. Any help is appreciated!

#include <sys/socket.h>       /*  socket definitions        */
#include <sys/types.h>        /*  socket types              */
#include <linux/netlink.h>  /* netlink functions */
#include <sys/uio.h>        /* scatter-gather definition for iovec */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


/*  Global constants  */

#define ECHO_PORT          (2002)
#define MAX_LINE           (1000)

int socketHolder; // declare variable to hold Socket

// Set up configuration for destination which holds the socket to be used to communicate with the Kernel
struct sockaddr_nl dest; // declare variable to hold Socket Address
// Set up configuration for the netlink message header
struct nlmsghdr *netlinkHeader; // declare variable to hold message to be sent
// Set up configuration for the scatter-gather function for expediting writing to buffer
struct iovec iov;
// Set up configuration for the message header for simplifying message parameters to be sent
struct msghdr message;

int main()
{

memset(&dest, 0, sizeof(dest)); // set socket Address to all 0
dest.nl_family = AF_NETLINK; // set socket family to AF_NETLINK
dest.nl_pad = 0; // defaults to 0
dest.nl_pid = 0; // set address of netlink socket to 0 because we're going to the kernel
dest.nl_groups = 0; // set to 0 because we're doing unicast

netlinkHeader->nlmsg_pid = 0; // set sender port number to 0 because we're in kernel

iov.iov_base = (caddr_t)netlinkHeader; // set address of buffer
iov.iov_len = netlinkHeader->nlmsg_len; // set length of buffer

message.msg_name = (caddr_t) &dest; // set socket name
message.msg_namelen = sizeof(dest); // set length of name
message.msg_iov = &iov; // I have no idea what this is
message.msg_iovlen = 1; // number of iov blocks
message.msg_control = NULL;  // ignore
message.msg_controllen = 0;  // ignore
message.msg_flags = 0;  //ignore

socketHolder = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); // declare Socket and assign to holder variable

bind(socketHolder, (struct sockaddr *) &dest, sizeof(dest)); // bind the destination settings to socketHolder

int sender = sendmsg(socketHolder, &message, 0); // send the message

}
Community
  • 1
  • 1
thewill2live
  • 215
  • 2
  • 6

2 Answers2

1

I'm not very familiar with netlink, unfortunately. But your error is (very) likely to be here:

netlinkHeader->nlmsg_pid = 0; // set sender port number to 0 because we're in kernel

since you've never initialized netlinkHeader, i.e. made sure the pointer points at memory that you are allowed to read and write, this is undefined behavior. In practice it often results in a segmentation fault since you're accessing some random address and your operating system prevents your process from ruining things.

Not sure why this is a pointer at all, you should perhaps try making it an actual instance of the struct nlmsghdr type, since it sounds as if you want to manipulate the address.

Also, the comment implies that the code is taken from kernel code, and your code is not kernel code which might imply that there are other problems as well.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Thanks! Your suggestion solved my issue. I changed netlinkHeader to an actual instance instead of a pointer (I changed it to a pointer originally to satisfy another error I had while compiling) and just changed the -> to . in a couple lines and boom we're back in business (I think haha). And the code is supposed to talk to the kernel and pass info along to the kernel (like say a string) so that the kernel can write it to the syslog. Though I'm still not positive where that message actually comes in... That's the next task I guess. Anyways, thanks again! – thewill2live Nov 04 '13 at 14:49
1

It would help if you identified the line which is causing the segmentation fault, but from the code you have shown it seems to be the line below.

netlinkHeader->nlmsg_pid = 0;

You have not initialized the netlinkHeader pointer to point to some valid memory location, so when you try to write the value 0 to the attribute netlinkHeader->nlmsg_pid it causes the fault you are seeing.

ajcaruana
  • 505
  • 3
  • 14
  • Thanks for pointing that out! I'm sorry, I would've pointed out where the segmentation fault was but I didn't know where it was being caused. I changed the netlinkHeader declaration to one of an actual instance of nlmsghdr instead of a pointer and that solved it. – thewill2live Nov 04 '13 at 14:47