- 浏览: 1444556 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (691)
- linux (207)
- shell (33)
- java (42)
- 其他 (22)
- javascript (33)
- cloud (16)
- python (33)
- c (48)
- sql (12)
- 工具 (6)
- 缓存 (16)
- ubuntu (7)
- perl (3)
- lua (2)
- 超级有用 (2)
- 服务器 (2)
- mac (22)
- nginx (34)
- php (2)
- 内核 (2)
- gdb (13)
- ICTCLAS (2)
- mac android (0)
- unix (1)
- android (1)
- vim (1)
- epoll (1)
- ios (21)
- mysql (3)
- systemtap (1)
- 算法 (2)
- 汇编 (2)
- arm (3)
- 我的数据结构 (8)
- websocket (12)
- hadoop (5)
- thrift (2)
- hbase (1)
- graphviz (1)
- redis (1)
- raspberry (2)
- qemu (31)
- opencv (4)
- socket (1)
- opengl (1)
- ibeacons (1)
- emacs (6)
- openstack (24)
- docker (1)
- webrtc (11)
- angularjs (2)
- neutron (23)
- jslinux (18)
- 网络 (13)
- tap (9)
- tensorflow (8)
- nlu (4)
- asm.js (5)
- sip (3)
- xl2tp (5)
- conda (1)
- emscripten (6)
- ffmpeg (10)
- srt (1)
- wasm (5)
- bert (3)
- kaldi (4)
- 知识图谱 (1)
最新评论
-
wahahachuang8:
我喜欢代码简洁易读,服务稳定的推送服务,前段时间研究了一下go ...
websocket的helloworld -
q114687576:
http://www.blue-zero.com/WebSoc ...
websocket的helloworld -
zhaoyanzimm:
感谢您的分享,给我提供了很大的帮助,在使用过程中发现了一个问题 ...
nginx的helloworld模块的helloworld -
haoningabc:
leebyte 写道太NB了,期待早日用上Killinux!么 ...
qemu+emacs+gdb调试内核 -
leebyte:
太NB了,期待早日用上Killinux!
qemu+emacs+gdb调试内核
tapper.c
#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <linux/if.h> #include <linux/if_tun.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/select.h> #include <err.h> #include <arpa/inet.h> /* inet_addr() & co. */ #include <netinet/in.h> /* INET_ADDRSTRLEN */ /* for uint16_t */ #include <stdint.h> #define ERR_CANT_TAP 1 #define ERR_OPEN_ERR 2 #define ERR_READ_ERR 3 #define ERR_WRITE_ERR 4 static int primary_fd; /* a copy of the filedescriptor for tap device */ static int enable_tuntap_headers = 0; /* CLI option - will we permit tuntap protocol headers */ static int enable_tapper_headers = 0; /* CLI option - will we enable tapper's headers */ static int enable_verbose = 0; /* CLI option - print out extra debug info on stderr */ //static const char DEFAULT_IP[] = "10.0.2.2"; static const char DEFAULT_IP[] = "10.0.2.1"; static const char DEFAULT_NETMASK[] = "255.255.0.0"; #define VERBOSE(x, ...) if(enable_verbose >= 1) { warnx("NOTE: " x, ##__VA_ARGS__); } #define DEBUG(x, ...) if(enable_verbose >= 2) { warnx("DEBUG: " x, ##__VA_ARGS__); } /* following function creates a tap device */ /* it also returns device name in 'newdev' */ int createTap(char *newdev, int bufferlen) { struct ifreq ifr; int fd=open("/dev/net/tun", O_RDWR); /* open the tap device */ if(fd<0) /* handle error */ err(ERR_CANT_TAP, "Could not create a TAP device"); memset(&ifr, 0, sizeof(ifr)); /* initialize the structure specifying data about net device */ ifr.ifr_flags=IFF_TAP; /* we want a tap device, not a tun device */ if(!enable_tuntap_headers) /* by default we won't include tuntap driver's headers */ ifr.ifr_flags|=IFF_NO_PI; if((ioctl(fd, TUNSETIFF, (void*)&ifr))<0) /* tell our device what we want it to do */ { close(fd); /* if we failed close and abort */ err(ERR_CANT_TAP, "Could not create a TAP device because of ioctl()"); } strncpy(newdev, ifr.ifr_name, bufferlen-1); /* return the generated device name */ newdev[bufferlen-1] = '\0'; return fd; } /* when we exit we want to clean up */ void atex(void) { close(primary_fd); /* close the tap network device */ } /* usage */ void usage(void) { printf("usage:\n" "\n" " ./tapper [--tuntap-headers] [--tapper-headers]" " [--ip-address %s] [--netmask %s] [--randomize-ip]" " [-v] [stdinfile stdoutfile]\n" "\n", DEFAULT_IP, DEFAULT_NETMASK); exit(0); } int main(int argc, char ** argv) { #define BUFFERSIZE 2000 /* must be larger than MTU - 1500 */ #define DEVNAMESIZE 25 int fd; /* file descriptor of the tap device; shorthand for primary_fd */ char devname[DEVNAMESIZE]={0}; /* initialize device name (where we'll pick up the generated dev name) to zeros so it doesn't look like we're sending a device name in*/ char buf[BUFFERSIZE]; /* buffer for receiving stuff */ in_addr_t ip = inet_addr(DEFAULT_IP); in_addr_t netmask = inet_addr(DEFAULT_NETMASK); char ip_s[INET_ADDRSTRLEN]; char netmask_s[INET_ADDRSTRLEN]; int argoff; /* argument offset; used for parsing CLI */ for(argoff = 1; argoff < argc; argoff++) { if(!strcmp(argv[argoff], "-h")) usage(); else if(!strcmp(argv[argoff], "--tuntap-headers")) enable_tuntap_headers = 1; else if(!strcmp(argv[argoff], "--tapper-headers")) enable_tapper_headers = 1; else if(!strcmp(argv[argoff], "-v")) enable_verbose++; else if(!strcmp(argv[argoff], "--ip-address")){ if(argoff == argc-1) usage(); ip = inet_addr(argv[++argoff]); if(ip == INADDR_NONE) errx(12, "%s: malformed ip address", argv[argoff]); DEBUG("ip address: %s", inet_ntoa(*(struct in_addr*)&ip)); }else if(!strcmp(argv[argoff], "--netmask")){ if(argoff == argc-1) usage(); netmask = inet_addr(argv[++argoff]); if(netmask == INADDR_NONE) errx(13, "%s: malformed netmask address", argv[argoff]); DEBUG("netmask: %s", inet_ntoa(*(struct in_addr*)&netmask)); }else if(!strcmp(argv[argoff], "--randomize-ip")){ srand(time(NULL)+devname[3]); /* we want our ip address to depend on time, and on last symbol in device name. dev name is always a three-letter 'tap' + number, and let's just presume it's a single digit num */ uint32_t *ip_int = (uint32_t*)&ip; uint32_t *netmask_int = (uint32_t*)&netmask; uint32_t local = (uint32_t)rand() & ~*netmask_int; if(local == 0) local = 1; *ip_int |= local; DEBUG("randomized ip address: %s", inet_ntoa(*(struct in_addr*)&ip)); } else break; } VERBOSE("verbosity: %d", enable_verbose); if(enable_tuntap_headers) VERBOSE("permitting tuntap headers"); if(enable_tapper_headers) VERBOSE("using tapper headers"); if(argc - argoff >= 2) { /* we can receive two arguments: - file we'll use for reading in place of stdin - file we'll use for writing in place of stdout */ close(0); close(1); VERBOSE("using %s for input and %s for output", argv[argoff], argv[argoff+1]); if(!fopen(argv[argoff], "r")) err(10, "fopen(%s, r)", argv[argoff]); if(!fopen(argv[argoff+1], "w")) err(11, "fopen(%s, w)", argv[argoff+1]); } /* get ip address and netmask as strings */ inet_ntop(AF_INET, &ip, ip_s, INET_ADDRSTRLEN); inet_ntop(AF_INET, &netmask, netmask_s, INET_ADDRSTRLEN); ip_s[INET_ADDRSTRLEN-1] = '\0'; netmask_s[INET_ADDRSTRLEN-1] = '\0'; /* let's create a tap device */ primary_fd=createTap(devname, DEVNAMESIZE); /* configure ip address and netmask */ snprintf(buf, sizeof(buf), "ifconfig %s inet %s netmask %s up", devname, ip_s, netmask_s); VERBOSE("configuring ip and netmask: %s", buf); system(buf); fd=primary_fd; /* store primary_fd into a shorthand */ if (fd<0) /* error with creating tap? tough luck, let's bail out */ err(ERR_OPEN_ERR, "open()"); atexit(atex); /* when the loop is aborted, cleanup */ while(1){ int readies, i; /* since we're trying to create a twoway tunnel between stdio and the tap device we need to do monitoring via select(). we simply don't know which one will send us data first. */ fd_set fds; FD_ZERO(&fds); /* init set of file descriptors */ FD_SET(fd,&fds); /* add tap device to set */ FD_SET(0,&fds); /* add stdin to set */ readies=select(fd+1, &fds, NULL, NULL, NULL); /* monitor the set. the first param is max fd we monitor +1 (as usual with select()). here that's fd. */ if(readies<=0) err(readies, "Not ready"); /* we passed a timeoutless select() with 0 active fds? ouch. */ for(i=0;i<2;i++){ /* some arcane magic to make the loop simple. i was lazy to cut paste code. basically first the fd_int is stdin (0) and fd_oth is our tap device (fd). then the fd_int is tap device (fd) and fd_oth is the stdout (1). */ int fd_int=i*fd; int fd_oth=abs(fd-i*fd); if(!fd_oth) fd_oth=1; /* is the currently monitored fd_int (first stdin, then tap) actually the one causing select() to unblock? */ if(FD_ISSET(fd_int, &fds)){ if(!enable_tapper_headers || fd_int != 0){ /* yay! that one has something to say. let's read as much as possible for our buffer. num of actually read bytes is stored in ret, unless it's -1 which is error */ ssize_t ret = read(fd_int, buf, BUFFERSIZE); if (!ret) { errx(100, "read(): nothing to read expecting data"); continue; } if (ret < 0) err(ERR_READ_ERR, "read(%d) for data", fd_int); /* using headers? then the fd_oth is the stdout. first, send the number of bytes we'll dispatch */ if(enable_tapper_headers){ uint16_t size = (uint16_t)htons(ret); /* copying because we want to do one write, not two */ char * with_headers = malloc(sizeof(size) + ret); memcpy(with_headers, &size, sizeof(size)); memcpy(with_headers + sizeof(size), buf, ret); if(write(fd_oth, with_headers, sizeof(size) + ret)<0) err(ERR_WRITE_ERR, "write(%d)", fd_oth); DEBUG("wrote %lu bytes", sizeof(size) + ret); free(with_headers); }else{ /* write ret bytes into fd_oth; that's all the bytes we read */ if(write(fd_oth, buf, ret)<0) err(ERR_WRITE_ERR, "write(%d)", fd_oth); } }else{ /* new codepath: buffer stdin until filled with enough data */ /* only executed for stdin, and if tapper headers are enabled */ static uint16_t expected_size = 0; static size_t current_buffer_content_size = 0; if(!expected_size){ ssize_t ret = read(fd_int, &expected_size, sizeof(uint16_t)); if(!ret) { errx(101, "read(): nothing to read expecting message size"); continue; } if (ret < 0) err(ERR_READ_ERR, "read(%d) for message size", fd_int); expected_size = ntohs(expected_size); DEBUG("now expecting %d bytes", expected_size); }else{ size_t bytes_left = expected_size - current_buffer_content_size; ssize_t ret = read(fd_int, buf + current_buffer_content_size, bytes_left); if(!ret){ errx(102, "read(): nothing to read expecting buffer content"); continue; } if (ret < 0) err(ERR_READ_ERR, "read(%d) for buffer content", fd_int); current_buffer_content_size += ret; DEBUG("received %lu bytes; buffer now %lu/%hu", ret, current_buffer_content_size, expected_size); if(current_buffer_content_size == expected_size){ DEBUG("got all content"); /* write ret bytes into fd_oth; that's all the bytes we read */ if(write(fd_oth, buf, ret)<0) err(ERR_WRITE_ERR, "write(%d)", fd_oth); current_buffer_content_size = 0; expected_size = 0; } } } } } } /* never happens */ return 0; }
发表评论
-
sdl笔记
2019-01-31 17:19 686sdl教程教程 https://github.com/Twin ... -
tinyemu
2019-01-24 17:59 1399参考https://bellard.org/jslinux/t ... -
jslinux总结帖
2019-01-04 21:33 1017注意个问题: chrome不要用两个tab页,否则ping不通 ... -
br0和tap0的互相影响
2019-01-02 19:17 773转载 http://www.cnblogs.com/wlei/ ... -
emscripten asm.js的helloworld
2018-03-01 20:15 1067mac下安装: brew install SDL2 SDL2_ ... -
nginx代理wss和https
2018-02-27 15:34 3859nginx启用ssl yum install openssl ... -
M版openstack(ovs,dvr,动态迁移)
2017-06-09 10:30 1712主要内容 1.先搭建三个节点的环境,dvr模式 2.建一个vm ... -
M版本的openstack的例子(linuxbridge)
2017-05-23 15:05 526做两个节点控制节点和计算节点 mcontroller521 ... -
jslinux-deobfuscated-network
2017-02-13 22:37 613基础知识 查看网络包 tcpdump -i eth0 -e ... -
用buildroot为jslinux建立最小rootfs
2016-11-18 17:59 1207############################### ... -
jslinux带网络功能的内核
2016-11-15 15:35 750想重新编译jslinux-network 的内核,其实就是比f ... -
Tunnels with iproute2
2016-11-14 15:22 511copy from http://members.ferrar ... -
nginx rewrite替代apache rewrite
2016-10-18 20:30 786清理chrome的缓存 chrome://appcache-i ... -
vxlan多台主机的vm之间不同网段互通
2016-09-19 21:06 4228组播: 试验: 在三台机器上 192.168.139.251 ... -
vxlan多台主机的vm之间相同网段互通
2016-09-19 16:30 2201三台机器 建立namespace ... -
qemu用tap方式启动vm的网络试验(ip route)
2016-09-14 11:29 2674ip route add 192.168.8.0/24 via ... -
openstack的M版本的neutron的实验
2016-09-01 20:00 3053试验步骤: 1.创建内部 ... -
socket的方式使用qemu建立虚拟机
2016-06-24 17:54 1800qemu的-net参数 -net nic 必须有,基本配置mo ... -
tap的方式使用qemu建立虚拟机NAT网络
2016-06-23 18:03 9499基本概念: vm:虚拟机 ... -
qemu用nat的方式使用tap建立虚拟机
2016-06-23 16:15 11普通桥接参考 http://haoningabc.iteye. ...
相关推荐
异步编程是C#5.0的一个重要改进,...编译器最终会用Task类创建代码。 1、创建任务 建立一个同步方法Greeting,该方法在等待一段时间后,返回一个字符串。 private string Greeting(int delay, string name) { Sys
为了使阐述的内容更加具体,本教程中的每个实验均选用Altera FPGA (型号为Cyclone Ⅱ EP2C35F672C8)实现,并在革新科技公司专业级实验平台GXSOC/SOPC运行通过。 本书可作为电子信息、自动控制、计算机工程类大学...
用于MATLAB:registered:的Jenkins:trade_mark:插件使您能够运行MATLAB和Simulink:registered:测试并生成工件,例如PDF测试报告,JUnit和TAP测试结果以及Cobertura代码或模型覆盖率报告。 您也可以使用该插件导出...
我保持醒着状态-Erykah Badu建立包容性的工作环境对于健康,支持和富有生产力的文化以及每个人都感到受欢迎和包容的环境势在必行。 woke是一个文本文件分析工具,可以在源代码中查找包含非包容性语言的位置,并建议...
DOME-面向设计的极简... > brew tap domeengine/tap > brew install dome 建立 最后,如果您想自己构建DOME,进行修改或其他原因,请遵循以下说明。 确保首先在系统上安装了共享的SDL2库,然后进行构建,运行: > m
为了使阐述的内容更加具体,本教程中的每个实验均选用Altera FPGA (型号为Cyclone Ⅱ EP2C35F672C8)实现,并在革新科技公司专业级实验平台GXSOC/SOPC运行通过。 本书可作为电子信息、自动控制、计算机工程类大学...
为了使阐述的内容更加具体,本教程中的每个实验均选用Altera FPGA (型号为Cyclone Ⅱ EP2C35F672C8)实现,并在革新科技公司专业级实验平台GXSOC/SOPC运行通过。 本书可作为电子信息、自动控制、计算机工程类大学...
为了使阐述的内容更加具体,本教程中的每个实验均选用Altera FPGA (型号为Cyclone Ⅱ EP2C35F672C8)实现,并在革新科技公司专业级实验平台GXSOC/SOPC运行通过。 本书可作为电子信息、自动控制、计算机工程类大学...
书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法帮助你掌握TCP/IP实现。本书不仅说明了插口API和协议族的关系以及主机实现与路由器实现的差别。还介绍了4.4BSD-Lite版的新的特点,如多播、长肥...
书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法帮助你掌握TCP/IP实现。本书不仅说明了插口API和协议族的关系以及主机实现与路由器实现的差别。还介绍了4.4BSD-Lite版的新的特点,如多播、长肥...
书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法帮助你掌握TCP/IP实现。本书不仅说明了插口API和协议族的关系以及主机实现与路由器实现的差别。还介绍了4.4BSD-Lite版的新的特点,如多播、长肥...
该文件共分12个压缩包,必须下载到同一个文件夹后解压才可以用哦~~ 简介: 《TCP/IP详解,卷1:协议》是一本完整而详细的...附录C sock程序 378 附录D 部分习题的解答 381 附录E 配置选项 395 附录F 可以免费获得...
adb 的运行原理是 PC 端的 adb server 与手机端的守护进程 adbd 建立连接,然后 PC 端的 adb client 通过 adb server 转发命令,adbd 接收命令后解析运行。 所以如果 adbd 以普通权限执行,有些需要 root 权限才能...
1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 1.2.2 印刷约定 2 1.3 历史 2 1.4 应用编程接口 3 1.5 程序示例 4 1.6 系统调用和库函数 6 1.7 网络实现概述 6 1.8 描述符 7 1.9 mbuf与输出处理 11 1.9.1 包含插口地址...
1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 1.2.2 印刷约定 2 1.3 历史 2 1.4 应用编程接口 3 1.5 程序示例 4 1.6 系统调用和库函数 6 1.7 网络实现概述 6 1.8 描述符 7 1.9 mbuf与输出处理 11 1.9.1 包含插口地址...
1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 1.2.2 印刷约定 2 1.3 历史 2 1.4 应用编程接口 3 1.5 程序示例 4 1.6 系统调用和库函数 6 1.7 网络实现概述 6 1.8 描述符 7 1.9 mbuf与输出处理 11 1.9.1 包含插口地址...
1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 1.2.2 印刷约定 2 1.3 历史 2 1.4 应用编程接口 3 1.5 程序示例 4 1.6 系统调用和库函数 6 1.7 网络实现概述 6 1.8 描述符 7 1.9 mbuf与输出处理 11 1.9.1 包含插口地址...
1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 1.2.2 印刷约定 2 1.3 历史 2 1.4 应用编程接口 3 1.5 程序示例 4 1.6 系统调用和库函数 6 1.7 网络实现概述 6 1.8 描述符 7 1.9 mbuf与输出处理 11 1.9.1 包含插口地址...
1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 1.2.2 印刷约定 2 1.3 历史 2 1.4 应用编程接口 3 1.5 程序示例 4 1.6 系统调用和库函数 6 1.7 网络实现概述 6 1.8 描述符 7 1.9 mbuf与输出处理 11 1.9.1 包含插口地址...