typedef unsigned short int sa_family_t;
//Linux includes
#include <sys/types.h>
#define _LINUX_TIME_H
#include <linux/connector.h>
#include <linux/cn_proc.h>
#include <linux/netlink.h>
#include <sys/socket.h>
#include <stdio.h>
//Theses magics come from connector.txt, I will maybe check includes if it's not already in
#define NETLINK_ADD_MEMBERSHIP 1
//#define NETLINK_DROP_MEMBERSHIP 0
#define SOL_NETLINK 270
void show_event(struct proc_event *ev) {
//This function displays the action of the struct proc_event in argument
switch(ev->what) {
case PROC_EVENT_NONE:
return;
break;
case PROC_EVENT_FORK:
printf("fork(from = %d)=%d\n", ev->event_data.fork.parent_pid, ev->event_data.fork.child_pid);
break;
case PROC_EVENT_EXEC:
printf("exec()\n");
break;
case PROC_EVENT_UID:
case PROC_EVENT_GID:
printf("UID/GID\n");
break;
case PROC_EVENT_EXIT:
printf("exit()\n");
break;
}
}
int main(int argc, char **argv, char **envp) {
//All this code is only to open a NetLink socket...
//Isn't it easy?
int s,on;
struct sockaddr_nl l_local;
s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if(!s) {
perror("Couldn't open socket for NETLINK_CONNECTOR");
exit(1);
}
l_local.nl_family=AF_NETLINK;
l_local.nl_groups=0x123456;
l_local.nl_pid = 0;
if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
perror("bind");
close(s);
return -1;
}
//On linux > 2.6.14 wee need this to write on a netlink multicast according to connector.txt
on=l_local.nl_groups;
setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
struct cn_msg message;
//Fullfil the ID of the kernel side
message.id.idx=CN_IDX_PROC;
message.id.val=CN_VAL_PROC;
message.seq=0;
message.ack=15000;
message.len=sizeof(enum proc_cn_mcast_op);
message.flags=0;
//message.data=PROC_CN_MCAST_LISTEN;
*((enum proc_cn_mcast_op*)(message.data))=PROC_CN_MCAST_LISTEN;
send(s, &message, sizeof(message) + sizeof(enum proc_cn_mcast_op), 0);
struct cn_msg *buffer=malloc(sizeof(struct cn_msg)+sizeof(struct proc_event));
int buflen;
//In this program we only get one event, to demonstrate the use of cn we don't need more.
buflen=recv(s, buffer, sizeof(buffer), 0);
if (buflen<0) {
return -1;
}
//let's show the result.
struct proc_event *event=buffer->data;
show_event(event);
}