示例#1
0
extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer)
{
	int ret;
        struct sockaddr_nl nladdr;
        struct iovec iov = {
                .iov_base = answer,
                .iov_len = answer->nlmsghdr.nlmsg_len,
        };
	
	struct msghdr msg = {
                .msg_name = &nladdr,
                .msg_namelen = sizeof(nladdr),
                .msg_iov = &iov,
                .msg_iovlen = 1,
        };
	
        memset(&nladdr, 0, sizeof(nladdr));
        nladdr.nl_family = AF_NETLINK;
        nladdr.nl_pid = 0;
        nladdr.nl_groups = 0;

again:
	ret = recvmsg(handler->fd, &msg, 0);
	if (ret < 0) {
		if (errno == EINTR)
			goto again;
		return -errno;
	}

	if (!ret)
		return 0;

	if (msg.msg_flags & MSG_TRUNC)
		return -EMSGSIZE;

	return ret;
}

extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg)
{
        struct sockaddr_nl nladdr;
        struct iovec iov = {
                .iov_base = (void*)nlmsg,
                .iov_len = nlmsg->nlmsghdr.nlmsg_len,
        };
	struct msghdr msg = {
                .msg_name = &nladdr,
                .msg_namelen = sizeof(nladdr),
                .msg_iov = &iov,
                .msg_iovlen = 1,
        };
	int ret;
	
        memset(&nladdr, 0, sizeof(nladdr));
        nladdr.nl_family = AF_NETLINK;
        nladdr.nl_pid = 0;
        nladdr.nl_groups = 0;

	ret = sendmsg(handler->fd, &msg, 0);
	if (ret < 0) {
		return -errno;
	}

	return ret;
}

#ifndef NLMSG_ERROR
#define NLMSG_ERROR                0x2
#endif
extern int netlink_transaction(struct nl_handler *handler, 
			       struct nlmsg *request, struct nlmsg *answer)
{

	int ret;

	ret = netlink_send(handler, request);
	if (ret < 0)
		return ret;

	ret = netlink_rcv(handler, answer);
	if (ret < 0)
		return ret;

	if (answer->nlmsghdr.nlmsg_type == NLMSG_ERROR) {
		struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer);
		errno = -err->error;
		if (errno)
			perror("Error configuring kernel");
		return -errno;
	}
	
	return 0;
}

extern int netlink_open(struct nl_handler *handler, int protocol)
{
	socklen_t socklen;
        int sndbuf = 32768;
        int rcvbuf = 32768;

        memset(handler, 0, sizeof(*handler));

        handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
        if (handler->fd < 0)
                return -errno;

        if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF, 
		       &sndbuf, sizeof(sndbuf)) < 0)
                return -errno;

        if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF, 
		       &rcvbuf,sizeof(rcvbuf)) < 0)
                return -errno;

        memset(&handler->local, 0, sizeof(handler->local));
        handler->local.nl_family = AF_NETLINK;
        handler->local.nl_groups = 0;

        if (bind(handler->fd, (struct sockaddr*)&handler->local, 
		 sizeof(handler->local)) < 0)
                return -errno;

        socklen = sizeof(handler->local);
        if (getsockname(handler->fd, (struct sockaddr*)&handler->local, 
			&socklen) < 0)
                return -errno;

        if (socklen != sizeof(handler->local))
                return -EINVAL;

        if (handler->local.nl_family != AF_NETLINK)
                return -EINVAL;

	handler->seq = time(NULL);

        return 0;
}

extern int netlink_close(struct nl_handler *handler)
{
	close(handler->fd);
	handler->fd = -1;
	return 0;
}
示例#2
0
extern int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg)
{
	return netlink_rcv(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
}
示例#3
0
文件: rtnl.c 项目: d4s/lxc
extern int rtnetlink_rcv(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg)
{
	return netlink_rcv(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr);
}
int main(int argc, char *argv[])
{

	int argslen, rc, option, i;
	int callback = 0;
	struct sigaction action;

	/* checking for missing arguments */
	if( argc < 2 )
	{
		rc=-EINVAL;
		errno=EINVAL;
		printf(
	"Correct Syntax:./xhw3 job_type infile1 infile2...\n");
		goto out;
	}
	
	task = malloc(sizeof(struct job));
	if(task == NULL){
		rc= -ENOMEM;
		errno= ENOMEM;
		goto out;
	}
	
	task->job_type = 0;
	task->file_opt = 0;	
	task->priority = 0;
	task->algo = 0;
	
	/* getting all arguments */
	while( ( option = getopt( argc, argv, "csprAEDORe:a:" ) ) != -1 )
	{	
 		switch(option)
		{	
		
			case 'c' : 
			callback = 1;
			break;
				
			case 's' : 
			if(task->job_type != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->job_type = CHECKSUM;
			break;

			case 'D' : 
			if(task->job_type != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->job_type = DECRYPT;
			break;

			case 'E' : 
			if(task->job_type != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->job_type = ENCRYPT;
			break;

			case 'p' : 
			if(task->job_type != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->job_type = PRINT;
			break;

			case 'r' : 
			if(task->job_type != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->job_type = REMOVE;
			break;

			case 'A' : 
			if(task->job_type != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->job_type = REMOVEALL;
			break;

			case 'O' : 
			if(task->file_opt != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->file_opt = OVERWRITE;
			break;

			case 'R' : 
			if(task->file_opt != 0){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->file_opt = RENAME;
			break;		

			case 'e' : 
			if((task->priority != 0) ||
				atoi(optarg) > 3 ||
				atoi(optarg) < 1){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->priority = atoi(optarg);
			break;		

			case 'a' : 
			if((task->job_type != ENCRYPT &&
				task->job_type != DECRYPT &&
				task->job_type != CHECKSUM &&
				task->job_type != 0) ||
				atoi(optarg) > 2 ||
				atoi(optarg) < 1){
				rc=-EINVAL;
				errno=EINVAL;
				goto out_free;
			}
			task->algo = atoi(optarg);
			break;		

			case '?' :
			rc=-EINVAL;
			errno=EINVAL;
			perror("Error: Wrong flag(s) entered\nError");
			goto out_free;

		}

	}

	/* checking for missing files */
	if ((argc - optind < 1) && 
		(task->job_type != PRINT && task->job_type != REMOVEALL))
	{
		rc = -EINVAL;
		errno = EINVAL;
		printf("Error: Input filename(s) missing\n");
		goto out_free;
	}
	
	if(task->job_type == 0)
		task->job_type = CHECKSUM;

	if(task->file_opt == 0)
		task->file_opt = RENAME;

	if(task->priority == 0)
		task->priority = 3;

	if(task->algo == 0)
		task->algo = AES;

	if(task->job_type != PRINT){

		if(task->job_type == ENCRYPT || task->job_type == DECRYPT){	
			/* calculating nmuber of input files */
			if(argc-optind-1 != 0){
				/* setting key */
				task->key =  argv[argc-1];
				task->infile_count = argc-optind-1;
			}
			else{
				task->infile_count = argc-optind;
				task->key = malloc(sizeof(char)*5);
				strcat(task->key, "00000");
			}

		}
		else
			task->infile_count = argc-optind;

		/* setting infiles */
		task->infiles=malloc(sizeof(char*)*task->infile_count);
	
		for(i=0;i<task->infile_count;i++)
		{
			task->infiles[i]=argv[optind+i];
		}
	}

	/* setting pid */
	task->pid = getpid();

	void *dummy = task; 
	argslen = sizeof(*task);

	/* system call */
  	rc = syscall(__NR_xjob, dummy, argslen);
	
	/* waiting for callback */
	if (task->job_type != PRINT && 
		task->job_type != REMOVEALL &&
		task->job_type != REMOVE &&
		callback ==1){
		netlink_rcv();	
	}

out_free:
	/* deallocating memory */
	if(task->infiles)
		free(task->infiles);

out:	
	/* printing appropriate message */
	if (rc >= 0){
		printf("%d\n", rc);
	}
	else{
		printf("Error Number: %d\n", errno);
		perror("Error");
	}

	exit(rc);
}