A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
planetlab-tap-creator.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2012 INRIA
4
*
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation;
9
*
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.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
*
19
* Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20
* Claudio Freire <klaussfreire@sourceforge.net>
21
*
22
*/
23
24
#include <unistd.h>
25
#include <stdint.h>
26
#include <stdlib.h>
27
#include <stdio.h>
28
#include <string>
29
#include <
string.h
>
// for strerror
30
#include <iostream>
31
#include <iomanip>
32
#include <sstream>
33
#include <errno.h>
34
#include <fcntl.h>
35
#include <sys/ioctl.h>
36
#include <sys/types.h>
37
#include <sys/socket.h>
38
#include <sys/un.h>
39
#include <net/if.h>
40
#include <linux/if_tun.h>
41
#include <net/route.h>
42
#include <netinet/in.h>
43
44
#include "
creator-utils.h
"
45
46
#define PLANETLAB_MAGIC 75867
47
48
#define VSYS_TUNTAP "/vsys/fd_tuntap.control"
49
#define VSYS_VIFUP_IN "/vsys/vif_up.in"
50
#define VSYS_VIFUP_OUT "/vsys/vif_up.out"
51
52
using namespace
ns3
;
53
60
int
61
ReceiveVifFd
(
int
fd,
char
*vif_name)
62
{
63
struct
msghdr msg;
64
struct
iovec iov;
65
int
rv;
66
size_t
ccmsg[CMSG_SPACE (
sizeof
(
int
)) /
sizeof
(size_t)];
67
struct
cmsghdr *cmsg;
68
69
/* Use IOV to read interface name */
70
iov.iov_base = vif_name;
71
iov.iov_len = IFNAMSIZ;
72
73
msg.msg_name = 0;
74
msg.msg_namelen = 0;
75
msg.msg_iov = &iov;
76
msg.msg_iovlen = 1;
77
/* old BSD implementations should use msg_accrights instead of
78
* msg_control; the interface is different. */
79
msg.msg_control = ccmsg;
80
msg.msg_controllen =
sizeof
(ccmsg);
81
82
while
(((rv = recvmsg (fd, &msg, 0)) == -1) && errno == EINTR)
83
{
84
}
85
ABORT_IF
(rv == -1,
"Could not receive fd from Vsys"
, 0);
86
ABORT_IF
(!rv,
"Could not receive fd from Vsys (EOF)"
, 0);
87
88
cmsg = CMSG_FIRSTHDR (&msg);
89
ABORT_IF
(!cmsg->cmsg_type == SCM_RIGHTS,
"got control message of unknown type"
<< cmsg->cmsg_type, 0);
90
91
int
* retfd = (
int
*)CMSG_DATA (cmsg);
92
return
*retfd;
93
}
94
104
int
105
TunAlloc
(
int
iftype,
char
*if_name)
106
{
107
int
control_fd;
108
struct
sockaddr_un addr;
109
int
ret;
110
111
control_fd = socket (AF_UNIX, SOCK_STREAM, 0);
112
ABORT_IF
(control_fd == -1,
"Could not create UNIX socket"
, 0);
113
114
memset (&addr, 0,
sizeof
(
struct
sockaddr_un));
115
116
/* Clear structure */
117
addr.sun_family = AF_UNIX;
118
strncpy (addr.sun_path,
VSYS_TUNTAP
,
sizeof
(addr.sun_path) - 1);
119
120
ret = connect (control_fd, (
struct
sockaddr *) &addr,
121
sizeof
(
struct
sockaddr_un));
122
ABORT_IF
(ret == -1,
"Could not connect to Vsys control socket"
, 0);
123
124
/* passing type param */
125
ret = send (control_fd, &iftype,
sizeof
(iftype), 0);
126
ABORT_IF
(ret !=
sizeof
(iftype),
"Could not send parameter to Vsys control socket"
, 0);
127
128
return
ReceiveVifFd
(control_fd, if_name);
129
130
}
131
139
void
140
SetTunUp
(
const
char
*ip,
const
char
*prefix,
const
char
*if_name)
141
{
142
FILE *in;
143
FILE *out;
144
char
errbuff[4096];
145
146
memset(errbuff, 0, 4096);
147
148
in = fopen (
VSYS_VIFUP_IN
,
"a"
);
149
150
if
(in == NULL)
151
{
152
ABORT_IF
(in == NULL,
"Failed to open "
<<
VSYS_VIFUP_IN
, 0);
153
}
154
155
out = fopen (
VSYS_VIFUP_OUT
,
"r"
);
156
157
if
(out == NULL)
158
{
159
ABORT_IF
(out == NULL,
"Failed to open "
<<
VSYS_VIFUP_OUT
, 0);
160
}
161
162
// send input to process
163
fprintf (in,
"%s\n%s\n%s\nsnat=1\n"
, if_name, ip, prefix);
164
165
// close pipe to indicate end parameter passing and flush the fifo
166
fclose (in);
167
168
fread((
void
*)errbuff, 4096, 1, out);
169
170
// the error buffer will not be empty if we read an error
171
ABORT_IF
(strcmp(errbuff,
""
) != 0, errbuff, 0);
172
173
fclose (out);
174
}
175
176
int
177
main (
int
argc,
char
*argv[])
178
{
179
int
c;
180
char
*ip = NULL;
181
char
*prefix = NULL;
182
char
*path = NULL;
183
int
iftype = IFF_TUN;
184
char
if_name[4096];
185
186
memset(if_name, 0, 4096);
187
opterr = 0;
188
189
while
((c = getopt (argc, argv,
"vi:n:tp:"
)) != -1)
190
{
191
switch
(c)
192
{
193
case
'i'
:
194
ip = optarg;
// ip address of the new device
195
break
;
196
case
'n'
:
197
prefix = optarg;
// prefix for the new device
198
break
;
199
case
't'
:
200
iftype = IFF_TAP;
// mode for the device (TAP or TUN)
201
break
;
202
case
'p'
:
203
path = optarg;
// path back to the tap bridge
204
break
;
205
case
'v'
:
206
gVerbose
=
true
;
207
break
;
208
}
209
}
210
211
ABORT_IF
(ip == NULL,
"IP Address is a required argument"
, 0);
212
LOG
(
"Provided IP Address is \""
<< ip <<
"\""
);
213
214
ABORT_IF
(prefix == NULL,
"Prefix is a required argument"
, 0);
215
LOG
(
"Provided prefix \""
<< prefix <<
"\""
);
216
217
ABORT_IF
(path == NULL,
"path is a required argument"
, 0);
218
LOG
(
"Provided path is \""
<< path <<
"\""
);
219
220
LOG
(
"Creating Tap"
);
221
// allocate a TAP device in planetLab
222
int
fd =
TunAlloc
(iftype, if_name);
223
ABORT_IF
(fd == -1,
"main(): Unable to create tap device"
, 1);
224
225
// set the TAP interface up
226
SetTunUp
(ip, prefix, (
const
char
*)if_name);
227
228
//
229
// Send the socket back to the tap net device so it can go about its business
230
//
231
SendSocket
(path, fd,
PLANETLAB_MAGIC
);
232
233
return
0;
234
}
ABORT_IF
#define ABORT_IF(cond, msg, printErrno)
Definition:
creator-utils.h:51
VSYS_TUNTAP
#define VSYS_TUNTAP
Definition:
planetlab-tap-creator.cc:48
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
string.h
ns3::StringValue attribute value declarations.
creator-utils.h
VSYS_VIFUP_OUT
#define VSYS_VIFUP_OUT
Definition:
planetlab-tap-creator.cc:50
PLANETLAB_MAGIC
#define PLANETLAB_MAGIC
Definition:
planetlab-tap-creator.cc:46
ReceiveVifFd
int ReceiveVifFd(int fd, char *vif_name)
Reads vif FD from "fd", writes interface name to vif_name, and returns vif FD.
Definition:
planetlab-tap-creator.cc:61
LOG
#define LOG(x)
Definition:
bench-simulator.cc:35
ns3::gVerbose
int gVerbose
Flag to enable / disable verbose log mode.
Definition:
creator-utils.cc:42
ns3::SendSocket
void SendSocket(const char *path, int fd, const int magic_number)
Send the file descriptor back to the code that invoked the creation.
Definition:
creator-utils.cc:54
TunAlloc
int TunAlloc(int iftype, char *if_name)
Creates a TUN/TAP device on a PlanetLab virtual machine (sliver).
Definition:
planetlab-tap-creator.cc:105
VSYS_VIFUP_IN
#define VSYS_VIFUP_IN
Definition:
planetlab-tap-creator.cc:49
SetTunUp
void SetTunUp(const char *ip, const char *prefix, const char *if_name)
Sets the TAP/TUN interface up.
Definition:
planetlab-tap-creator.cc:140
src
fd-net-device
helper
planetlab-tap-creator.cc
Generated on Fri Oct 1 2021 17:03:03 for ns-3 by
1.8.20