编译内核并打印数据包

来源:互联网 发布: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 now
3. 查看编译花费时间
[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: abcdefghijklmnopqrstuvwxyz
8. 利用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 中作了修改。


阅读全文
0 0