You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
freshtomato-arm/release/src-rt-6.x.4708/router/hotplug2/hotplug2_utils.c

97 lines
2.4 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include "hotplug2_utils.h"
/**
* A trivial function that reads kernel seqnum from sysfs.
*
* Returns: Seqnum as read from sysfs
*/
inline event_seqnum_t get_kernel_seqnum() {
FILE *fp;
char filename[64];
char seqnum[64];
strcpy(filename, sysfs_seqnum_path);
fp = fopen(filename, "r");
if (fp == NULL)
return 0;
fread(seqnum, 1, 64, fp);
fclose(fp);
return strtoull(seqnum, NULL, 0);
}
/**
* Opens a PF_NETLINK socket into the kernel, to read uevents.
*
* @1 Specifies type of socket (whether we bind or whether we connect)
*
* Returns: Socket fd if succesful, -1 otherwise.
*/
inline int init_netlink_socket(int type) {
int netlink_socket;
struct sockaddr_nl snl;
int buffersize = 16 * 1024 * 1024;
memset(&snl, 0x00, sizeof(struct sockaddr_nl));
snl.nl_family = AF_NETLINK;
snl.nl_pid = getpid();
snl.nl_groups = 1;
netlink_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
if (netlink_socket == -1) {
ERROR("opening netlink","Failed socket: %s.", strerror(errno));
return -1;
}
/*
* We're trying to override buffer size. If we fail, we attempt to set a big buffer and pray.
*/
if (setsockopt(netlink_socket, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize))) {
ERROR("opening netlink","Failed setsockopt: %s. (non-critical)", strerror(errno));
/* Somewhat safe default. */
buffersize = 106496;
if (setsockopt(netlink_socket, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize))) {
ERROR("opening netlink","Failed setsockopt: %s. (critical)", strerror(errno));
}
}
/*
* hotplug2-dnode performs connect, while hotplug2 daemon binds
*/
switch (type) {
case NETLINK_CONNECT:
if (connect(netlink_socket, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl))) {
ERROR("opening netlink","Failed connect: %s.", strerror(errno));
close(netlink_socket);
return -1;
}
default:
if (bind(netlink_socket, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl))) {
ERROR("opening netlink","Failed bind: %s.", strerror(errno));
close(netlink_socket);
return -1;
}
}
return netlink_socket;
}