编译内核并打印数据包
来源:互联网 发布:python gnu getopt 编辑:程序博客网 时间:2024/06/05 02:06
以下基于CentOS 7 默认内核 3.10。
1. 下载内核并解压
wget https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.11.tar.xz tar -xvJf linux-3.11.tar.xz
2. 编译安装
cp config-3.10.0-327.el7.x86_64 /usr/src/linux-3.11/.config
make menuconfigdate >> /date.log ; make -j 4 ;date >> /date.logcat date.log make modules_installtime make install;shutdown -r now3. 查看编译花费时间
[root@localhost ~]# cat /date.log first:2017年 10月 12日 星期四 10:39:06 CST2017年 10月 12日 星期四 11:22:49 CSTsecond:2017年 10月 12日 星期四 12:25:03 CST2017年 10月 12日 星期四 12:31:56 CST第一次编译花费较长的时间,四十多分钟;第二次不要make clean,系统只编译修改过的文件,只需六七分钟;只需要执行 make && make install 即可
make工具可自动完成编译工作,并且可以只对上次编译后修改过的部分进行编译。
4. 修改 /usr/src/linux-3.11/net/ipv4/tcp.c
在tcp_mark_push() 函数中增加以下代码(有skb的地方即可,此处选择tcp_mark_push()):
printk("start tcp_mark_push() ..................\n"); if (skb) { char *buf = skb->data; int len = skb->len; int i; printk("[%s:%d]Packet length = %#4x\n", __FUNCTION__, __LINE__, len); for (i = 0; i < len; i++){ if (i % 16 == 0) printk("%#4.4x", i); if (i % 2 == 0) printk(" "); printk("%2.2x", ((unsigned char *)buf)[i]); if (i % 16 == 15) printk("\n"); } printk("\n\n\n\n"); }5. 重新编译内核
date >> /date.log ; make -j 4 ;date >> /date.log;make install;shutdown -r now
6. 利用简单的socket程序做测试
server.c
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#define MAXLINE 4096int main(int argc, char** argv){ int listenfd, connfd; struct sockaddr_in servaddr; char buff[4096]; int n; if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(6666); if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } if( listen(listenfd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("======waiting for client's request======\n"); while(1){ if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){ printf("accept socket error: %s(errno: %d)",strerror(errno),errno); continue; } n = recv(connfd, buff, MAXLINE, 0); buff[n] = '/0'; printf("recv msg from client: %s\n", buff); close(connfd); } close(listenfd);}client.c
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#define MAXLINE 4096int main(int argc, char** argv){ int sockfd, n; char recvline[4096], sendline[4096]; struct sockaddr_in servaddr; if( argc != 2){ printf("usage: ./client <ipaddress>\n"); exit(0); } if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("create socket error: %s(errno: %d)\n", strerror(errno),errno); exit(0); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(6666); if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ printf("inet_pton error for %s\n",argv[1]); exit(0); } if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ printf("connect error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("send msg to server: \n"); fgets(sendline, 4096, stdin); if( send(sockfd, sendline, strlen(sendline), 0) < 0) { printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); exit(0); } close(sockfd); exit(0);}
7. 简单地数据收发
[root@localhost ~]# ./server ======waiting for client's request=====recv msg from client: abcdefgh0recv msg from client: abcdefghijklmnopqrstuvwxyz0
[root@localhost ~]# ./client 172.16.20.129send msg to server: abcdefghijklmnopqrstuvwxyz8. 利用cat /proc/kmsg 和wireshark分别查看:
部分kmsg如下
<4>[ 1745.560622] start tcp_recvmsg() ..................<4>[ 2785.322961] start tcp_recvmsg() ..................<4>[ 2793.618616] start tcp_sendmsg() ..................<4>[ 2793.618625] start tcp_mark_push() ..................<4>[ 2793.618628] [tcp_mark_push:601]Packet length = 0x1b<4>[ 2793.618630] 0x0000 6162 6364 6566 6768 696a 6b6c 6d6e 6f70<4>[ 2793.618640] 0x0010 7172 7374 7576 7778 797a 0a
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在 /net/core/dev.c 中netif_rx() 函数中加入:
3232 printk("start netif_rx() print....\n");3233 if (skb)3234 {3235 char *buf = skb->data;3236 int len = skb->len;3237 int i;3238 3239 printk("[%s:%d]Packet length = %#4x\n", __FUNCTION__, __LINE__, len);3240 for (i = 0; i < len; i++){3241 if (i % 16 == 0) printk("%#4.4x", i);3242 if (i % 2 == 0) printk(" ");3243 printk("%2.2x", ((unsigned char *)buf)[i]);3244 if (i % 16 == 15) printk("\n");3245 }3246 printk("\n\n\n\n");3247 }3248 3249 printk("end netif_rx() print....\n");
利用上面提到的server.c 和client.c 执行,发送abcdefghijklmnopqrstuvwxyz
在wireshark中可以看到三次握手之后开始发送数据,最后四次握手断开连接。
在 cat /proc/kmsg 中
<4>[ 2291.276064] start netif_rx() print....<4>[ 2291.276077] [netif_rx:3239]Packet length = 0x3c<4>[ 2291.276080] 0x0000 4500 003c eed2 4000 4006 cac6 ac10 1481 // [syn]<4>[ 2291.276104] 0x0010 ac10 1481 d4e9 1a0a 7095 b4aa 0000 0000 // ac10 1481 是 172.16.20.129 d4e9 和1a0a 分别是端口54505 6666<4>[ 2291.276124] 0x0020 a002 aaaa 8151 0000 0204 ffd7 0402 080a<4>[ 2291.276144] 0x0030 001e 5a78 0000 0000 0103 0307<4>[ 2291.276144] <4>[ 2291.276144] <4>[ 2291.276144] <4>[ 2291.276160] end netif_rx() print....<4>[ 2291.276211] start netif_rx() print....<4>[ 2291.276215] [netif_rx:3239]Packet length = 0x3c<4>[ 2291.276217] 0x0000 4500 003c 0000 4000 4006 b999 ac10 1481 // [syn, ack]<4>[ 2291.276237] 0x0010 ac10 1481 1a0a d4e9 c893 332f 7095 b4ab<4>[ 2291.276257] 0x0020 a012 aaaa 8151 0000 0204 ffd7 0402 080a<4>[ 2291.276277] 0x0030 001e 5a78 001e 5a78 0103 0307<4>[ 2291.276277] <4>[ 2291.276277] <4>[ 2291.276277] <4>[ 2291.276293] end netif_rx() print....<4>[ 2291.276456] start netif_rx() print....<4>[ 2291.276461] [netif_rx:3239]Packet length = 0x34<4>[ 2291.276463] 0x0000 4500 0034 eed3 4000 4006 cacd ac10 1481 // [ack]<4>[ 2291.276483] 0x0010 ac10 1481 d4e9 1a0a 7095 b4ab c893 3330<4>[ 2291.276503] 0x0020 8010 0156 8149 0000 0101 080a 001e 5a79<4>[ 2291.276522] 0x0030 001e 5a78<4>[ 2291.276522] <4>[ 2291.276522] <4>[ 2291.276522] <4>[ 2291.276529] end netif_rx() print....<4>[ 2291.278218] start tcp_recvmsg() ..................<4>[ 2292.056561] start netif_receive_skb() print...<4>[ 2292.056565] [netif_receive_skb:3697]Packet length = 0x2e<4>[ 2292.056566] 0x0000 0001 0800 0604 0001 1c7e e55a f5f2 ac10<4>[ 2292.056573] 0x0010 145b 0000 0000 0000 ac10 145c 0000 0000<4>[ 2292.056578] 0x0020 0000 0000 0000 0000 0000 0000 0000<4>[ 2292.056578] <4>[ 2292.056578] <4>[ 2292.056578] <4>[ 2292.056582] end netif_receive_skb() print...<4>[ 2298.684069] start netif_receive_skb() print...<4>[ 2298.684085] [netif_receive_skb:3697]Packet length = 0x40<4>[ 2298.684090] 0x0000 4500 0040 56b3 4000 4011 627e ac10 14da<4>[ 2298.684101] 0x0010 ac10 1481 cb6f 7532 002c befa 0014 0200<4>[ 2298.684110] 0x0020 0000 0000 0000 000d 6f00 1700 0023 0010<4>[ 2298.684120] 0x0030 fcfa f7c7 417e fcfa f7c7 417e 4abf 3ee7<4>[ 2298.684129] <4>[ 2298.684129] <4>[ 2298.684129] <4>[ 2298.684129] <4>[ 2298.684134] end netif_receive_skb() print...<4>[ 2300.686056] start netif_receive_skb() print...<4>[ 2300.686099] [netif_receive_skb:3697]Packet length = 0x3a<4>[ 2300.686114] 0x0000 4500 003a 56b4 4000 4011 6283 ac10 14da<4>[ 2300.686148] 0x0010 ac10 1481 bed0 7533 0026 5198 0010 0208<4>[ 2300.686179] 0x0020 0000 0000 0016 0023 0010 fcfa f7c7 417e<4>[ 2300.686209] 0x0030 fcfa f7c7 417e 4abf 3ee7<4>[ 2300.686209] <4>[ 2300.686209] <4>[ 2300.686209] <4>[ 2300.686234] end netif_receive_skb() print...<4>[ 2305.099352] start netif_receive_skb() print...<4>[ 2305.099402] [netif_receive_skb:3697]Packet length = 0xb0<4>[ 2305.099417] 0x0000 6000 0000 0088 3aff fe80 0000 0000 0000<4>[ 2305.099451] 0x0010 02e0 0fff fe00 4806 ff02 0000 0000 0000<4>[ 2305.099482] 0x0020 0000 0000 0000 0001 8600 9367 00c0 0000<4>[ 2305.099512] 0x0030 0000 0000 0000 0000 0101 00e0 0f00 4806<4>[ 2305.099543] 0x0040 0501 0000 0000 05dc 0304 40c0 0000 1c20<4>[ 2305.099610] 0x0050 0000 0708 0000 0000 fd32 6df3 2743 0000<4>[ 2305.099640] 0x0060 0000 0000 0000 0000 1803 3000 0000 1c20<4>[ 2305.099671] 0x0070 fd32 6df3 2743 0000 0000 0000 0000 0000<4>[ 2305.099701] 0x0080 1903 0000 0000 0708 fd32 6df3 2743 0000<4>[ 2305.099732] 0x0090 0000 0000 0000 0001 1f03 0000 0000 04b0<4>[ 2305.099762] 0x00a0 036c 616e 0000 0000 0000 0000 0000 0000<4>[ 2305.099792] <4>[ 2305.099792] <4>[ 2305.099792] <4>[ 2305.099792] <4>[ 2305.099808] end netif_receive_skb() print...<4>[ 2305.394138] start tcp_sendmsg() ..................<4>[ 2305.394156] start tcp_mark_push() ..................<4>[ 2305.394162] [tcp_mark_push:602]Packet length = 0x1b<4>[ 2305.394165] 0x0000 6162 6364 6566 6768 696a 6b6c 6d6e 6f70<4>[ 2305.394189] 0x0010 7172 7374 7576 7778 797a 0a<4>[ 2305.394189] <4>[ 2305.394189] <4>[ 2305.394189] <4>[ 2305.394205] end tcp_mark_push() ..................<4>[ 2305.394270] start netif_rx() print....<4>[ 2305.394274] [netif_rx:3239]Packet length = 0x4f<4>[ 2305.394277] 0x0000 4500 004f eed4 4000 4006 cab1 ac10 1481 // [push, ack]<4>[ 2305.394297] 0x0010 ac10 1481 d4e9 1a0a 7095 b4ab c893 3330<4>[ 2305.394317] 0x0020 8018 0156 8164 0000 0101 080a 001e 9192<4>[ 2305.394336] 0x0030 001e 5a78 6162 6364 6566 6768 696a 6b6c<4>[ 2305.394356] 0x0040 6d6e 6f70 7172 7374 7576 7778 797a 0a<4>[ 2305.394356] <4>[ 2305.394356] <4>[ 2305.394356] <4>[ 2305.394375] end netif_rx() print....<4>[ 2305.394443] start netif_rx() print....<4>[ 2305.394446] [netif_rx:3239]Packet length = 0x34<4>[ 2305.394448] 0x0000 4500 0034 eed5 4000 4006 cacb ac10 1481 // [FIN, ACK]<4>[ 2305.394468] 0x0010 ac10 1481 d4e9 1a0a 7095 b4c6 c893 3330<4>[ 2305.394489] 0x0020 8011 0156 8149 0000 0101 080a 001e 9192<4>[ 2305.394509] 0x0030 001e 5a78<4>[ 2305.394509] <4>[ 2305.394509] <4>[ 2305.394509] <4>[ 2305.394516] end netif_rx() print....<4>[ 2305.394779] start netif_rx() print....<4>[ 2305.394784] [netif_rx:3239]Packet length = 0x34<4>[ 2305.394786] 0x0000 4500 0034 6949 4000 4006 5058 ac10 1481 // [ACK]<4>[ 2305.394806] 0x0010 ac10 1481 1a0a d4e9 c893 3330 7095 b4c6<4>[ 2305.394825] 0x0020 8010 0156 8149 0000 0101 080a 001e 9192<4>[ 2305.394845] 0x0030 001e 9192<4>[ 2305.394845] <4>[ 2305.394845] <4>[ 2305.394845] <4>[ 2305.394851] end netif_rx() print....<4>[ 2305.395015] start netif_rx() print....<4>[ 2305.395019] [netif_rx:3239]Packet length = 0x34<4>[ 2305.395021] 0x0000 4500 0034 694a 4000 4006 5057 ac10 1481 //[FIN, ACK]<4>[ 2305.395042] 0x0010 ac10 1481 1a0a d4e9 c893 3330 7095 b4c7<4>[ 2305.395062] 0x0020 8011 0156 8149 0000 0101 080a 001e 9192<4>[ 2305.395082] 0x0030 001e 9192<4>[ 2305.395082] <4>[ 2305.395082] <4>[ 2305.395082] <4>[ 2305.395089] end netif_rx() print....<4>[ 2305.395115] [netif_rx:3239]Packet length = 0x34<4>[ 2305.395117] 0x0000 4500 0034 eed6 4000 4006 caca ac10 1481 // [ACK] <4>[ 2305.395137] 0x0010 ac10 1481 d4e9 1a0a 7095 b4c7 c893 3331<4>[ 2305.395156] 0x0020 8010 0156 8149 0000 0101 080a 001e 9194<4>[ 2305.395176] 0x0030 001e 9192<4>[ 2305.395176] <4>[ 2305.395176] <4>[ 2305.395176] <4>[ 2305.395183] end netif_rx() print....
================================================================
如果 下面添加一句代码:
((unsigned char *)buf)[i]) = ((unsigned char *)buf)[i]) + 1;结果:出现无法上网。
1. 首先判断网络连通性,ping www.baidu.com 可以ping通;(说明:IP层以下没有问题)。
2. 利用nslookup www.hao000.com 发现正常;(说明:DNS和UDP也没有问题)。
3. 利用ssh工具,发现无法使用,基于TCP的应用服务会出现问题。
Connecting to host 172.16.20.129:22...Connected. [16:30:43] Version exchange initiated...
4. 考虑利用简单的基于TCP的socket程序,server.c 和client.c 之间建立通信, client 输入aaa ,server 却收到bbb;
因此可以确定是TCP层出现问题。按照数据包SKB传输顺序发现是函数tcp_mark_push 中作了修改。
- 编译内核并打印数据包
- 在ubuntu上开发编译内核模块,并查看printk打印的消息
- Linux内核构造数据包并发送(二)(dev_queue_xmit方式)
- Linux内核构造数据包并发送(二)(dev_queue_xmit方式)
- Linux内核构造数据包并发送(Netfilter方式)
- 给内核打补丁并编译
- 手动编译ubuntu内核并升级内核
- 编译,加载并卸载一个内核模块
- 下载android kernel内核,并编译。
- 下载并编译Android内核源代码
- 编译2.6.8.1版本内核并从新内核启动
- 编译一个自己的内核模块,并加载进内核
- 实践之从linux内核驱动过滤并punt特定数据包到应用程序
- (OK) 编译 Android, 打印 内核信息 - pr_info - pr_notice
- RAKNET内核 - 数据包的感念
- Linux内核IP Queue机制的分析(二)——用户态处理并回传数据包
- Linux内核IP Queue机制的分析(二)——用户态处理并回传数据包
- Linux内核IP Queue机制的分析(二)——用户态处理并回传数据包
- 重磅报告 | 70页PPT、10大关键词解读中国互联网创新飞跃的五年
- redis key值含有\xac\xed\x00\x05t\x00\x1b
- Tablayout的基础使用
- Winsows下和Linux下创建python虚拟环境virtualenv
- AJAX的功能
- 编译内核并打印数据包
- 奇怪的朋友圈(并查集)
- 《Java从小白到大牛精简版》之第4章 Java语法基础
- C语言实现单链表面试题---进阶
- CF 443D. Andrey and Problem 贪心 or DP
- ThreeJS学习笔记(2)-场景创建
- linux相关命令
- 判断点是否在三角形内
- Unity游戏开发——Unity场景导出XML并且进行加载