3 * Copyright 2008 Free Software Foundation, Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * setuid root program that opens a socket using (PF_PACKET, SOCK_RAW,
21 * htons(0xBEEF)), and sends the resulting file descriptor by way of
22 * of the file descriptor specified as the first command line argument.
28 #include <sys/types.h>
29 #include <sys/socket.h>
36 #ifdef HAVE_ARPA_INET_H
37 #include <arpa/inet.h>
38 #elif defined(HAVE_NETINET_IN_H)
39 #include <netinet/in.h>
44 write_fd(int fd, const void *ptr, size_t nbytes, int sendfd)
49 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
52 char control[CMSG_SPACE(sizeof(int))];
54 struct cmsghdr *cmptr;
56 msg.msg_control = control_un.control;
57 msg.msg_controllen = sizeof(control_un.control);
59 cmptr = CMSG_FIRSTHDR(&msg);
60 cmptr->cmsg_len = CMSG_LEN(sizeof(int));
61 cmptr->cmsg_level = SOL_SOCKET;
62 cmptr->cmsg_type = SCM_RIGHTS;
63 *((int *) CMSG_DATA(cmptr)) = sendfd;
65 msg.msg_accrights = (char *) &sendfd;
66 msg.msg_accrightslen = sizeof(int);
72 iov[0].iov_base = const_cast<void *>(ptr);
73 iov[0].iov_len = nbytes;
77 return sendmsg(fd, &msg, 0);
83 if (setgid(getgid()) < 0){
88 if (setuid(getuid()) < 0){
100 fprintf(stderr, "usage: usrp2_socket_opener file-descriptor\n");
105 main(int argc, char **argv)
111 int unix_domain_fd = strtol(argv[1], &endptr, 0);
115 // FIXME get client credentials from unix_domain_fd using SCM_CREDENTIALS
117 // open the raw socket
118 int socket_fd = socket(PF_PACKET, SOCK_RAW, htons(0xBEEF));
119 if (socket_fd == -1){
120 perror("socket(PF_PACKET, SOCK_RAW, htons(0xBEEF))");
121 // printf("errno = %d\n", errno);
122 if (errno == EACCES || errno == ESPIPE){
123 fprintf(stderr, "usrp2_socket_opener must be setuid root to open the socket using SOCK_RAW.\n");
124 fprintf(stderr, "Running as root, please execute: \n");
125 fprintf(stderr, " # chown root:usrp usrp2_socket_opener\n");
126 fprintf(stderr, " # chmod 04750 usrp2_socket_opener\n");
133 fprintf(stderr, "Can't drop root permissions\n");
137 if (write_fd(unix_domain_fd, "", 1, socket_fd) != 1){