1 /**
2 * (C) 2007-20 - ntop.org and contributors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not see see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #include "n2n.h"
20
21 #ifdef __FreeBSD__
22
23 void tuntap_close(tuntap_dev *device);
24
25 /* ********************************** */
26
27 #define N2N_FREEBSD_TAPDEVICE_SIZE 32
tuntap_open(tuntap_dev * device,char * dev,const char * address_mode,char * device_ip,char * device_mask,const char * device_mac,int mtu)28 int tuntap_open(tuntap_dev *device /* ignored */,
29 char *dev,
30 const char *address_mode, /* static or dhcp */
31 char *device_ip,
32 char *device_mask,
33 const char * device_mac,
34 int mtu) {
35 int i;
36 char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE];
37
38 for (i = 0; i < 255; i++) {
39 snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i);
40
41 device->fd = open(tap_device, O_RDWR);
42 if(device->fd > 0) {
43 traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device);
44 break;
45 }
46 }
47
48 if(device->fd < 0) {
49 traceEvent(TRACE_ERROR, "Unable to open tap device");
50 return(-1);
51 } else {
52 char buf[256];
53 FILE *fd;
54
55 device->ip_addr = inet_addr(device_ip);
56
57 if ( device_mac && device_mac[0] != '\0' )
58 {
59 /* FIXME - This is not tested. Might be wrong syntax for OS X */
60
61 /* Set the hw address before bringing the if up. */
62 snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s",
63 i, device_mac);
64 system(buf);
65 }
66
67 snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up",
68 i, device_ip, device_mask, mtu);
69 system(buf);
70
71 traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)",
72 i, device_ip, device_mask);
73
74 /* Read MAC address */
75
76 snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i);
77 /* traceEvent(TRACE_INFO, "%s", buf); */
78
79 fd = popen(buf, "r");
80 if(fd < 0) {
81 tuntap_close(device);
82 return(-1);
83 } else {
84 int a, b, c, d, e, f;
85
86 buf[0] = 0;
87 fgets(buf, sizeof(buf), fd);
88 pclose(fd);
89
90 if(buf[0] == '\0') {
91 traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address");
92 exit(0);
93 }
94
95 traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf);
96 if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) {
97 device->mac_addr[0] = a, device->mac_addr[1] = b;
98 device->mac_addr[2] = c, device->mac_addr[3] = d;
99 device->mac_addr[4] = e, device->mac_addr[5] = f;
100 }
101 }
102 }
103
104
105 /* read_mac(dev, device->mac_addr); */
106 return(device->fd);
107 }
108
109 /* ********************************** */
110
tuntap_read(struct tuntap_dev * tuntap,unsigned char * buf,int len)111 int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) {
112 return(read(tuntap->fd, buf, len));
113 }
114
115 /* ********************************** */
116
tuntap_write(struct tuntap_dev * tuntap,unsigned char * buf,int len)117 int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) {
118 return(write(tuntap->fd, buf, len));
119 }
120
121 /* ********************************** */
122
tuntap_close(struct tuntap_dev * tuntap)123 void tuntap_close(struct tuntap_dev *tuntap) {
124 close(tuntap->fd);
125 }
126
127 /* Fill out the ip_addr value from the interface. Called to pick up dynamic
128 * address changes. */
tuntap_get_address(struct tuntap_dev * tuntap)129 void tuntap_get_address(struct tuntap_dev *tuntap)
130 {
131 }
132
133 #endif /* #ifdef __FreeBSD__ */
134