A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
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 paramater 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
int
nbytes;
146
147
memset(errbuff, 0, 4096);
148
149
in = fopen (
VSYS_VIFUP_IN
,
"a"
);
150
151
if
(in == NULL)
152
{
153
ABORT_IF
(in == NULL,
"Failed to open "
<<
VSYS_VIFUP_IN
, 0);
154
}
155
156
out = fopen (
VSYS_VIFUP_OUT
,
"r"
);
157
158
if
(out == NULL)
159
{
160
ABORT_IF
(out == NULL,
"Failed to open "
<<
VSYS_VIFUP_OUT
, 0);
161
}
162
163
// send input to process
164
fprintf (in,
"%s\n%s\n%s\nsnat=1\n"
, if_name, ip, prefix);
165
166
// close pipe to indicate end parameter passing and flush the fifo
167
fclose (in);
168
169
nbytes = fread((
void
*)errbuff, 4096, 1, out);
170
171
// the error buffer will not be empty if we read an error
172
ABORT_IF
(strcmp(errbuff,
""
) != 0, errbuff, 0);
173
174
fclose (out);
175
}
176
177
int
178
main
(
int
argc,
char
*argv[])
179
{
180
int
c;
181
char
*ip = NULL;
182
char
*prefix = NULL;
183
char
*path = NULL;
184
int
iftype = IFF_TUN;
185
char
if_name[4096];
186
187
memset(if_name, 0, 4096);
188
opterr = 0;
189
190
while
((c = getopt (argc, argv,
"vi:n:tp:"
)) != -1)
191
{
192
switch
(c)
193
{
194
case
'i'
:
195
ip = optarg;
// ip address of the new device
196
break
;
197
case
'n'
:
198
prefix = optarg;
// prefix for the new device
199
break
;
200
case
't'
:
201
iftype = IFF_TAP;
// mode for the device (TAP or TUN)
202
break
;
203
case
'p'
:
204
path = optarg;
// path back to the tap bridge
205
break
;
206
case
'v'
:
207
gVerbose
=
true
;
208
break
;
209
}
210
}
211
212
ABORT_IF
(ip == NULL,
"IP Address is a required argument"
, 0);
213
LOG
(
"Provided IP Address is \""
<< ip <<
"\""
);
214
215
ABORT_IF
(prefix == NULL,
"Prefix is a required argument"
, 0);
216
LOG
(
"Provided prefix \""
<< prefix <<
"\""
);
217
218
ABORT_IF
(path == NULL,
"path is a required argument"
, 0);
219
LOG
(
"Provided path is \""
<< path <<
"\""
);
220
221
LOG
(
"Creating Tap"
);
222
// allocate a TAP device in planetLab
223
int
fd =
TunAlloc
(iftype, if_name);
224
ABORT_IF
(fd == -1,
"main(): Unable to create tap device"
, 1);
225
226
// set the TAP interface up
227
SetTunUp
(ip, prefix, (
const
char
*)if_name);
228
229
//
230
// Send the socket back to the tap net device so it can go about its business
231
//
232
SendSocket
(path, fd,
PLANETLAB_MAGIC
);
233
234
return
0;
235
}
src
fd-net-device
helper
planetlab-tap-creator.cc
Generated on Fri Aug 30 2013 01:42:50 for ns-3 by
1.8.1.2