Lines 19-31
Link Here
|
19 |
|
19 |
|
20 |
#ifdef linux |
20 |
#ifdef linux |
21 |
#include <linux/if_tun.h> |
21 |
#include <linux/if_tun.h> |
22 |
#define TUNDEV "/dev/net/tun" |
22 |
#define TUNINT "tun0" |
|
|
23 |
#define TUNDEVNODE "/dev/net/tun" |
23 |
#else |
24 |
#else |
24 |
# include <net/if_tun.h> |
25 |
# include <net/if_tun.h> |
|
|
26 |
# define TUNINT "NULL?" |
25 |
# if __FreeBSD_version < 500000 |
27 |
# if __FreeBSD_version < 500000 |
26 |
# define TUNDEV "/dev/tun2" |
28 |
# define TUNDEVNODE "/dev/tun2" |
27 |
# else |
29 |
# else |
28 |
# define TUNDEV "/dev/tun" |
30 |
# define TUNDEVNODE "/dev/tun" |
29 |
# endif |
31 |
# endif |
30 |
#endif |
32 |
#endif |
31 |
|
33 |
|
Lines 33-159
Link Here
|
33 |
|
35 |
|
34 |
#define MAXPKT 2000 |
36 |
#define MAXPKT 2000 |
35 |
|
37 |
|
36 |
#define TAPDEV "/dev/tap0" |
38 |
#define TAPINT "tap0" |
|
|
39 |
#define TAPDEVNODE "/dev/net/tun" |
37 |
|
40 |
|
38 |
int tfd = -1, nfd = -1; |
41 |
int tfd = -1, nfd = -1; |
39 |
static char dev[IFNAMSIZ+1]; |
42 |
static char dev[IFNAMSIZ+1]; |
40 |
|
43 |
|
41 |
static int tun_alloc (const char *path); |
44 |
static int tun_alloc (const char * interface, const char * device_node); |
|
|
45 |
static int tap_alloc (const char * interface, const char * device_node); |
46 |
|
42 |
#ifdef linux |
47 |
#ifdef linux |
43 |
static int tap_alloc (const char *path); |
48 |
static int tuntap_alloc_linux(const char * interface, const char * device_node, |
|
|
49 |
int mode); |
50 |
#else |
51 |
static int tun_alloc_bsd(const char * interface, const char * device_node); |
44 |
#endif |
52 |
#endif |
45 |
|
53 |
|
46 |
void |
54 |
void |
47 |
open_tuntap(const char *device) |
55 |
open_tuntap(const char * interface, const char * device_node, int tun) |
48 |
{ |
56 |
{ |
49 |
int tunerr; |
57 |
int err; |
50 |
#ifdef linux |
58 |
|
51 |
int taperr; |
59 |
if (!interface) |
52 |
#endif |
60 |
interface = (tun ? TUNINT : TAPINT); |
|
|
61 |
|
62 |
if (!device_node) |
63 |
device_node = (tun ? TUNDEVNODE : TAPDEVNODE); |
64 |
|
65 |
fprintf(stderr, "Opening %s interface %s at %s... ", tun ? "tun" : "tap", |
66 |
interface, device_node); |
67 |
|
68 |
err = (tun ? tun_alloc(interface, device_node) : tap_alloc(interface, |
69 |
device_node)); |
70 |
|
71 |
if (!err) { |
72 |
fprintf(stderr, "using interface %s\n", dev); |
73 |
|
74 |
if (tun) |
75 |
fprintf(stderr, "you will now need to assign an ip and routing to " |
76 |
"this interface\n"); |
77 |
else |
78 |
fprintf(stderr, "you will now need to add bridging or other rules " |
79 |
"to this interface\n"); |
80 |
return; |
81 |
} |
53 |
|
82 |
|
54 |
fprintf(stderr, "Opening tun/tap-device... "); |
83 |
fprintf(stderr, "failed! (%s)\n", strerror(err)); |
55 |
if ((tunerr = tun_alloc(device ? device : TUNDEV)) |
84 |
|
|
|
85 |
fprintf(stderr, "Diagnostics: "); |
86 |
|
87 |
if (err == EPERM) |
88 |
fprintf(stderr, "you usually have to be root to use nstx.\n"); |
89 |
else if (err == ENOENT) |
90 |
fprintf(stderr, "maybe you need kernel support -- did you modprobe " |
91 |
"tap?\n"); |
92 |
else if (err == ENODEV) |
93 |
fprintf(stderr, "maybe you need kernel support -- did you modprobe " |
94 |
"tap?\n"); |
56 |
#ifdef linux |
95 |
#ifdef linux |
57 |
&& (taperr = tap_alloc(device ? device : TAPDEV)) |
96 |
#else |
|
|
97 |
else if ((err == EINVAL) && !tun) |
98 |
fprintf(stderr, "tap support is only available under linux\n"); |
58 |
#endif |
99 |
#endif |
59 |
) { |
100 |
else |
60 |
fprintf(stderr, "failed!\n" |
101 |
fprintf(stderr, "none, sorry\n"); |
61 |
"Diagnostics:\nTun ("TUNDEV"): "); |
102 |
|
62 |
switch (tunerr) { |
103 |
exit(EXIT_FAILURE); |
63 |
case EPERM: |
104 |
} |
64 |
fprintf(stderr, "Permission denied. You usually have to " |
105 |
|
65 |
"be root to use nstx.\n"); |
106 |
int tun_alloc(const char * interface, const char * device_node) |
66 |
break; |
107 |
{ |
67 |
case ENOENT: |
|
|
68 |
fprintf(stderr, TUNDEV " not found. Please create /dev/net/ and\n" |
69 |
" mknod /dev/net/tun c 10 200 to use the tun-device\n"); |
70 |
break; |
71 |
case ENODEV: |
72 |
fprintf(stderr, "Device not available. Make sure you have " |
73 |
"kernel-support\n for the tun-device. Under linux, you " |
74 |
"need tun.o (Universal tun/tap-device)\n"); |
75 |
break; |
76 |
default: |
77 |
perror("Unexpected error"); |
78 |
break; |
79 |
} |
80 |
fprintf(stderr, "Tap ("TAPDEV"):\n(only available under linux)\n"); |
81 |
#ifdef linux |
108 |
#ifdef linux |
82 |
switch (taperr) { |
109 |
return tuntap_alloc_linux(interface, device_node, IFF_TUN); |
83 |
case EPERM: |
110 |
#else |
84 |
fprintf(stderr, "Permission denied. You generally have to " |
111 |
return tun_alloc_bsd(interface, device_node); |
85 |
"be root to use nstx.\n"); |
|
|
86 |
break; |
87 |
case ENOENT: |
88 |
fprintf(stderr, TAPDEV " not found. Please\n" |
89 |
" mknod /dev/tap0 c 36 16 to use the tap-device\n"); |
90 |
break; |
91 |
case ENODEV: |
92 |
fprintf(stderr, "Device not available. Make sure you have kernel-support\n" |
93 |
" for the tap-device. Under linux, you need netlink_dev.o and ethertap.o\n"); |
94 |
break; |
95 |
default: |
96 |
fprintf(stderr, "Unexpected error: %s\n", strerror(taperr)); |
97 |
break; |
98 |
} |
99 |
#endif |
112 |
#endif |
100 |
exit(EXIT_FAILURE); |
|
|
101 |
} |
102 |
|
103 |
fprintf(stderr, "using device %s\n" |
104 |
"Please configure this device appropriately (IP, routes, etc.)\n", dev); |
105 |
} |
113 |
} |
106 |
|
114 |
|
107 |
int |
115 |
int tap_alloc(const char * interface, const char * device_node) |
108 |
tun_alloc (const char *path) |
|
|
109 |
{ |
116 |
{ |
110 |
#ifdef linux |
117 |
#ifdef linux |
111 |
struct ifreq ifr; |
118 |
return tuntap_alloc_linux(interface, device_node, IFF_TAP); |
112 |
#else |
119 |
#else |
113 |
struct stat st; |
120 |
return EINVAL; |
114 |
#endif |
121 |
#endif |
115 |
|
122 |
} |
116 |
if ((tfd = open(path, O_RDWR)) < 0) |
|
|
117 |
return errno; |
118 |
|
123 |
|
119 |
#ifdef linux |
124 |
#ifdef linux |
120 |
memset(&ifr, 0, sizeof(ifr)); |
125 |
|
|
|
126 |
int tuntap_alloc_linux(const char * interface, const char * device_node, |
127 |
int mode) |
128 |
{ |
129 |
struct ifreq ifr; |
130 |
|
131 |
if ((tfd = open(device_node, O_RDWR)) < 0) |
132 |
return errno; |
133 |
|
134 |
memset(&ifr, 0, sizeof(ifr)); |
121 |
|
135 |
|
122 |
ifr.ifr_flags = IFF_TUN|IFF_NO_PI; |
136 |
ifr.ifr_flags = mode | IFF_NO_PI; |
|
|
137 |
strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); |
138 |
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0; |
123 |
|
139 |
|
124 |
if (ioctl(tfd, TUNSETIFF, (void *) &ifr) < 0) |
140 |
if (ioctl(tfd, TUNSETIFF, (void *) &ifr) < 0) { |
125 |
{ |
141 |
close(tfd); |
126 |
close(tfd); |
142 |
tfd = -1; |
127 |
tfd = -1; |
143 |
return errno; |
128 |
return errno; |
144 |
} |
129 |
} |
145 |
|
130 |
strncpy(dev, ifr.ifr_name, IFNAMSIZ+1); |
146 |
strncpy(dev, ifr.ifr_name, IFNAMSIZ+1); |
131 |
#else |
|
|
132 |
fstat(tfd, &st); |
133 |
strncpy(dev, devname(st.st_rdev, S_IFCHR), IFNAMSIZ+1); |
134 |
#endif |
135 |
|
147 |
|
136 |
return 0; |
148 |
return 0; |
137 |
} |
149 |
} |
138 |
|
150 |
|
|
|
151 |
#else /* bsd */ |
139 |
|
152 |
|
140 |
#ifdef linux |
153 |
int tun_alloc_bsd(const char * interface, const char * device_node) |
141 |
int |
|
|
142 |
tap_alloc(const char *path) |
143 |
{ |
154 |
{ |
144 |
char *ptr; |
155 |
struct stat st; |
145 |
|
156 |
|
146 |
if ((tfd = open(path, O_RDWR)) < 0) |
157 |
if ((tfd = open(device_node, O_RDWR)) < 0) |
147 |
return errno; |
158 |
return errno; |
148 |
|
159 |
|
149 |
if ((ptr = strrchr(path, '/'))) |
160 |
fstat(tfd, &st); |
150 |
strncpy(dev, ptr+1, IFNAMSIZ+1); |
161 |
strncpy(dev, devname(st.st_rdev, S_IFCHR), IFNAMSIZ+1); |
151 |
else |
|
|
152 |
strncpy(dev, path, IFNAMSIZ+1); |
153 |
|
162 |
|
154 |
return 0; |
163 |
return 0; |
155 |
} |
164 |
} |
156 |
#endif |
165 |
|
|
|
166 |
#endif /* linux/bsd */ |
157 |
|
167 |
|
158 |
void |
168 |
void |
159 |
open_ns(const char *ip) |
169 |
open_ns(const char *ip) |