1/* $OpenBSD: opentap.c,v 1.1 2016/09/28 12:40:35 bluhm Exp $ */ 2 3/* 4 * Copyright (c) 2014 Alexander Bluhm <bluhm@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <ctype.h> 20#include <err.h> 21#include <fcntl.h> 22#include <limits.h> 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26 27#include <sys/socket.h> 28 29void usage(void); 30 31void 32usage(void) 33{ 34 fprintf(stderr, "usage: sudo %s fd# tap#\n", getprogname()); 35 fprintf(stderr, " fd# number of file descriptor for fd passing\n"); 36 fprintf(stderr, " tap# number of tap device to open\n"); 37 exit(2); 38} 39 40int 41main(int argc, char *argv[]) 42{ 43 int fd, tap; 44 char dev[FILENAME_MAX]; 45 const char *errstr; 46 struct msghdr msg; 47 struct cmsghdr *cmsg; 48 union { 49 struct cmsghdr hdr; 50 unsigned char buf[CMSG_SPACE(sizeof(int))]; 51 } cmsgbuf; 52 53 if (argc != 3) 54 usage(); 55 56 fd = strtonum(argv[1], 0, INT_MAX, &errstr); 57 if (errstr) 58 errx(2, "file descriptor number %s: %s", errstr, argv[1]); 59 tap = strtonum(argv[2], 0, INT_MAX, &errstr); 60 if (errstr) 61 errx(2, "tap device number %s: %s", errstr, argv[2]); 62 snprintf(dev, FILENAME_MAX, "/dev/tap%d", tap); 63 64 if ((tap = open(dev, O_RDWR)) == -1) 65 err(1, "open %s", dev); 66 67 memset(&msg, 0, sizeof(msg)); 68 msg.msg_control = &cmsgbuf.buf; 69 msg.msg_controllen = sizeof(cmsgbuf.buf); 70 71 cmsg = CMSG_FIRSTHDR(&msg); 72 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 73 cmsg->cmsg_level = SOL_SOCKET; 74 cmsg->cmsg_type = SCM_RIGHTS; 75 *(int *)CMSG_DATA(cmsg) = tap; 76 77 if (sendmsg(fd, &msg, 0) == -1) 78 err(1, "sendmsg %d", fd); 79 80 return 0; 81} 82