VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NAT/getrawsock.c@ 96854

Last change on this file since 96854 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
1/* $Id: getrawsock.c 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * Obtain raw-sockets from a server when debugging unprivileged.
4 */
5
6/*
7 * Copyright (C) 2013-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/un.h>
31#include <netinet/in.h>
32#include <errno.h>
33#include <pwd.h>
34#include <signal.h>
35#include <stdio.h>
36#include <string.h>
37#include <unistd.h>
38
39/* XXX: this should be in a header, but isn't. naughty me. :( */
40int getrawsock(int type);
41
42
43int
44getrawsock(int type)
45{
46 struct sockaddr_un sux; /* because solaris */
47 struct passwd *pw;
48 size_t pathlen;
49 int rawsock, server;
50 struct msghdr mh;
51 struct iovec iov[1];
52 char buf[1];
53 struct cmsghdr *cmh;
54 char cmsg[CMSG_SPACE(sizeof(int))];
55 ssize_t nread, nsent;
56 int status;
57
58 server = -1;
59 rawsock = -1;
60
61 memset(&sux, 0, sizeof(sux));
62 sux.sun_family = AF_UNIX;
63
64 if (geteuid() == 0) {
65 return -1;
66 }
67
68 if (type == AF_INET) {
69 buf[0] = '4';
70 }
71 else if (type == AF_INET6) {
72 buf[0] = '6';
73 }
74 else {
75 return -1;
76 }
77
78 errno = 0;
79 pw = getpwuid(getuid());
80 if (pw == NULL) {
81 perror("getpwuid");
82 return -1;
83 }
84
85 pathlen = snprintf(sux.sun_path, sizeof(sux.sun_path),
86 "/tmp/.vbox-%s-aux/mkrawsock", pw->pw_name);
87 if (pathlen > sizeof(sux.sun_path)) {
88 fprintf(stderr, "socket pathname truncated\n");
89 return -1;
90 }
91
92 server = socket(PF_UNIX, SOCK_STREAM, 0);
93 if (server < 0) {
94 perror("socket");
95 return -1;
96 }
97
98 status = connect(server, (struct sockaddr *)&sux,
99 (sizeof(sux) - sizeof(sux.sun_path)
100 + strlen(sux.sun_path) + 1));
101 if (status < 0) {
102 perror(sux.sun_path);
103 goto out;
104 }
105
106 nsent = send(server, buf, 1, 0);
107 if (nsent != 1) {
108 if (nsent < 0) {
109 perror("send");
110 }
111 else {
112 fprintf(stderr, "failed to contact mkrawsock\n");
113 }
114 goto out;
115 }
116
117 buf[0] = '\0';
118
119 iov[0].iov_base = buf;
120 iov[0].iov_len = 1;
121
122 memset(&mh, 0, sizeof(mh));
123 mh.msg_iov = iov;
124 mh.msg_iovlen = 1;
125 mh.msg_control = cmsg;
126 mh.msg_controllen = sizeof(cmsg);
127
128 nread = recvmsg(server, &mh, 0);
129 if (nread != 1) {
130 if (nread < 0) {
131 perror("recvmsg");
132 }
133 else {
134 fprintf(stderr, "EOF from mkrawsock\n");
135 }
136 goto out;
137 }
138
139 if ((type == AF_INET && buf[0] != '4')
140 || (type == AF_INET6 && buf[0] != '6')
141 || mh.msg_controllen == 0)
142 {
143 goto out;
144 }
145
146 for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
147 if ((cmh->cmsg_level == SOL_SOCKET)
148 && (cmh->cmsg_type == SCM_RIGHTS)
149 && (cmh->cmsg_len == CMSG_LEN(sizeof(rawsock))))
150 {
151 rawsock = *((int *)CMSG_DATA(cmh));
152 break;
153 }
154 }
155
156 out:
157 if (server != -1) {
158 close(server);
159 }
160 if (rawsock != -1) {
161 printf("%s: got ICMPv%c socket %d\n",
162 __func__, type == AF_INET ? '4' : '6', rawsock);
163 }
164 return rawsock;
165}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette