1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include <sys/types.h>
#include <sys/socket.h> /* old netlink.h is broken */
#include <sys/un.h>
/* For sa_family_t needed by <linux/netlink.h> */
#include <netinet/in.h>
#include <linux/netlink.h>
#include <stdlib.h>
#include "compat.h"
#include "net.h"
#include "maps.h" // page_rand
#include "random.h"
#include "sanitise.h"
#include "utils.h" // ARRAY_SIZE
#include "compat.h"
/* Current highest netlink socket. Supports some older kernels. */
#ifdef NETLINK_CRYPTO
#define _NETLINK_MAX NETLINK_CRYPTO
#else
#ifdef NETLINK_RDMA
#define _NETLINK_MAX NETLINK_RDMA
#else
#define _NETLINK_MAX NETLINK_ECRYPTFS
#endif /* NETLINK_RDMA */
#endif /* NETLINK_CRYPTO */
void netlink_gen_sockaddr(struct sockaddr **addr, socklen_t *addrlen)
{
struct sockaddr_nl *nl;
nl = malloc(sizeof(struct sockaddr_nl));
if (nl == NULL)
return;
nl->nl_family = PF_NETLINK;
nl->nl_pid = get_pid();
nl->nl_groups = rand32();
*addr = (struct sockaddr *) nl;
*addrlen = sizeof(struct sockaddr_nl);
}
void netlink_rand_socket(struct socket_triplet *st)
{
if (rand_bool())
st->type = SOCK_RAW;
else
st->type = SOCK_DGRAM;
st->protocol = rand() % (_NETLINK_MAX + 1);
}
#define SOL_NETLINK 270
#define NR_SOL_NETLINK_OPTS ARRAY_SIZE(netlink_opts)
static const unsigned int netlink_opts[] = {
NETLINK_ADD_MEMBERSHIP, NETLINK_DROP_MEMBERSHIP, NETLINK_PKTINFO, NETLINK_BROADCAST_ERROR,
NETLINK_NO_ENOBUFS, NETLINK_RX_RING, NETLINK_TX_RING };
void netlink_setsockopt(struct sockopt *so)
{
unsigned char val;
so->level = SOL_NETLINK;
val = rand() % NR_SOL_NETLINK_OPTS;
so->optname = netlink_opts[val];
}
|