forked from mwalle/rawsocket
-
Notifications
You must be signed in to change notification settings - Fork 1
/
rawsocket-helper.c
87 lines (72 loc) · 1.5 KB
/
rawsocket-helper.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* Privileged helper binary.
*
* Copyright (c) 2015, Michael Walle <[email protected]>
* See LICENSE for licensing terms.
*
* Quick guide:
* make rawsocket_helper
* chown root:yourgroup rawsocket_helper
* chmod 750 rawsocket_helper
* setcap cap_net_raw+ep rawsocket_helper
*/
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
int send_socket(int fd, int sfd)
{
int rc;
struct iovec iov;
struct msghdr msg = {0};
struct cmsghdr *cmsg;
char buf[CMSG_SPACE(sizeof(int))];
/* dummy write */
iov.iov_base = "";
iov.iov_len = 1;
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
*(int *)CMSG_DATA(cmsg) = sfd;
rc = sendmsg(fd, &msg, 0);
if (rc == -1)
return -1;
return 0;
}
int main(int argc, char **argv)
{
int rc;
int fd, raw_fd;
char *endp;
int family, protocol;
int ret = EXIT_FAILURE;
/* argument parsing */
if (argc != 4)
goto out;
protocol = strtol(argv[3], &endp, 10);
if (*argv[3] && *endp)
goto out;
family = strtol(argv[2], &endp, 10);
if (*argv[2] && *endp)
goto out;
fd = strtol(argv[1], &endp, 10);
if (*argv[1] && *endp)
goto out;
/* open raw socket */
raw_fd = socket(family, SOCK_RAW, protocol);
if (raw_fd == -1)
goto out;
rc = send_socket(fd, raw_fd);
if (rc == -1) {
close(raw_fd);
goto out;
}
ret = EXIT_SUCCESS;
out:
close(fd);
return ret;
}