我正在尝试拦截通过TUN接口的数据包。 我想将原始数据包信息转换为可读信息,以便我以后可以使用它。
我正在使用以下代码:
int main(){
char tun_name[IFNAMSIZ];
char data[1500];
int nread = 0;
int tun_fd = 0;
/* Connect to the device */
strcpy(tun_name, "tun1");
tun_fd = tun_alloc(tun_name); /* tun interface, no Ethernet headers*/
if(tun_fd < 0){
perror("Allocating interface");
exit(1);
}
/* Now read data coming from the kernel */
int i=0;
int count=0;
char src[INET_ADDRSTRLEN];
u_int8_t protocol;
while(1) {
count ++;
nread = read(tun_fd, data, sizeof(data));
if(nread < 0) {
perror("Reading from interface");
close(tun_fd);
exit(1);
}
struct ip *iphdr = (struct ip *) data;
/* Do whatever with the data */
printf("Packet N° %d\n", count);
printf("Read %d bytes from device %s\n", nread, tun_name);
protocol = iphdr->ip_p;
inet_ntop(AF_INET, &(iphdr->ip_src), src, INET_ADDRSTRLEN);
printf("\nProtocol: %d", protocol);
printf("\nIP source address: %s", src);
printf("\n\n");
}
return 0;
}
似乎我无法读取数据包的协议和ip src地址。我得到了令人满意的结果。
你能帮忙吗?
谢谢!
答案 0 :(得分:0)
问题在于这一行:
tun_fd = tun_alloc(tun_name); /* tun interface, no Ethernet headers*/
这是函数tun_alloc()的定义:
int tun_alloc(char *dev) {
struct ifreq ifr;
int fd, err;
char *clonedev = "/dev/net/tun";
/* open the clone device */
if( (fd = open(clonedev, O_RDWR)) < 0 ) {
return fd;
}
/* preparation of the struct ifr, of type "struct ifreq" */
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */
if (*dev) {
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
/* try to create the device */
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
close(fd);
return err;
}
strcpy(dev, ifr.ifr_name);
return fd;
}
在这里,在创建TUN接口时,我们必须使用“IFF_NO_PI”标志来删除数据包添加信息并仅接收原始数据包。
所以,我们必须使用它:
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
而不只是:
ifr.ifr_flags = IFF_TUN;
希望它有所帮助,谢谢。