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
88
89
90
91
92
93
94
95
96
97
|
#ifndef TUN_H_INCLUDED
#define TUN_H_INCLUDED
#endif
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/if_ether.h>
#include <stddef.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <linux/if_tun.h>
#include <netinet/in.h>
#include <fcntl.h>
#include "mgw_utils.h"
#include "mgw_tun.h"
struct mgw_tun_handle
{
void* logger;
int fd;
};
struct mgw_tun_handle * mgw_tun_init(const char *dev, void *logger)
{
struct ifreq ifr;
int fd, err;
if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
{
MGW_LOG_ERROR(logger, "mgw_tun: Failed at open /dev/net/tun: errno is %d, %s", errno, strerror(errno));
exit(EXIT_FAILURE);
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;//不包含tun包信息
if (*dev)
{
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
{
MGW_LOG_ERROR(logger, "mgw_tun: Failed at ioctl: errno is %d, %s", errno,strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
struct mgw_tun_handle *handle = ALLOC(struct mgw_tun_handle, 1);
handle->fd = fd;
handle->logger = logger;
return handle;
}
void mgw_tun_destroy(struct mgw_tun_handle *handle)
{
close(handle->fd);
FREE(&handle);
}
int mgw_tun_read(struct mgw_tun_handle *handle, char *buff, size_t len)
{
void *logger = handle->logger;
int recv_len = 0;
recv_len = read(handle->fd, buff, len);
if(recv_len < 0)
{
MGW_LOG_ERROR(logger, "mgw_tun: Failed at read from tun, errno is %d, %s\n", errno, strerror(errno));
}
else
{
MGW_LOG_INFO(logger, "mgw_tun: Succeed at read from tun, len is %d", recv_len);
}
return recv_len;
}
int mgw_tun_write(struct mgw_tun_handle *handle, char *buff, size_t len)
{
void *logger = handle->logger;
int send_len = 0 ;
send_len = write(handle->fd, buff, len);
if(send_len < 0)
{
MGW_LOG_ERROR(logger, "mgw_tun: Failed at write to tun, errno is %d, %s", errno, strerror(errno));
}
else
{
if((size_t)send_len < len)
{
MGW_LOG_ERROR(logger, "mgw_tun: Failed at write to tun completely, need send %d but only send %d", (int)len, send_len);
}
else
{
MGW_LOG_INFO(logger, "mgw_tun: Succeed at write to tun, len is %d", send_len);
}
}
return send_len;
}
|