- 论坛徽章:
- 0
|
本帖最后由 heut2009 于 2010-12-21 22:14 编辑
cu 编程大赛第二题, 自己尝试写了一个功能实现版的,第一次写这样的程序,没有经验,一直有段错误啊,希望牛人能给分析一下,给点意见,- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/socket.h>
- #include<netinet/in.h>
- #include<linux/if_ether.h>
- #include<signal.h>
- #include<sys/types.h>
- #include<linux/tcp.h>
- #include<linux/udp.h>
- #include<linux/ip.h>
- [root@bogon ~]# head -20 cu.c
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/socket.h>
- #include<netinet/in.h>
- #include<linux/if_ether.h>
- #include<signal.h>
- #include<sys/types.h>
- #include<linux/tcp.h>
- #include<linux/udp.h>
- #include<linux/ip.h>
- #include<unistd.h>
- #include<signal.h>
- #include<malloc.h>
- #define STREAMSIZE 10000
- #define BUFSIZE 2048
- #define CACHESIZE 20
- /*stream item info struct*/
- typedef struct {
- unsigned short type;/*tcp or udp type */
- unsigned int sport;
- unsigned int dport;
- unsigned int sip;
- unsigned int dip;
- unsigned long count;
- unsigned long bytes;/*total bytes of a stream*/
- }stream;
- /*stream temp cache info struct*/
- typedef struct {
- unsigned int type;
- unsigned int weight;
- unsigned int sport;
- unsigned int dport;
- unsigned int sip;
- unsigned int dip;
- }cache_info;
- cache_info cache_item[CACHESIZE];/*streams last captured to make a queue*/
- stream *item[STREAMSIZE]; /*items are for stream info*/
- char interface[4];
- int capture=1;
- unsigned int item_max=0;/* current total items*/
- unsigned int proto,sip,dip,sport,dport,ip_h_len,n_read=0;
- void report()
- {
- int i=0,j;
- printf(" protocol\tsrc\t\tdest\t sport dport packets\ttotal bytes\n");
- for(i=1;i<=item_max;i++)
- {
- printf("\t%d\t%s\t%s %d %d %d\t\t%d\n",item[i]->type,inet_ntoa(item[i]->sip),inet_ntoa(item[i]->dip),ntohs(item[i]->sport),ntohs(item[i]->dport),item[i]->count,item[i]->bytes);
- free(item[i]);
- }
- }
- void sig_handle(int signo)
- {
- capture=0;
- report();
- exit(1);
- }
- /*function for caching items that did not find in cache queue*/
- void insert_cache_item()
- {
- printf("insert cache_item");
- int i,id=11;
- for(i=0;i<CACHESIZE;i++)
- {
- id=(id < cache_item[i].weight)? id : (cache_item[i].weight);
- if(cache_item[i].weight==0)
- {
- cache_item[i].type=proto;
- printf(" %d\n",i);
- cache_item[i].sport=sport;
- cache_item[i].dport=dport;
- cache_item[i].sip=sip;
- cache_item[i].dip=dip;
- cache_item[i].weight+=2;
- break;
- }
- }
- if(id>0) /*in the cache_item,all weight is great than 0,but we
- find the smallest weight is id,so cache_item[id]will be
- recoverd by the new stream*/
- {
- printf(" %d\n",id);
- cache_item[id].type=proto;
- cache_item[id].sport=sport;
- cache_item[id].dport=dport;
- cache_item[id].sip=sip;
- cache_item[id].dip=dip;
- cache_item[id].weight=+1;
- }
- }
- /*search the stream current captured in our cache_item.
- the cache_item contains an item "weight" to record
- how offen this stream being captured recently.when capture
- a stream,first check it in cache_item,if find a match one,good,we
- need not to search the big item array which contains all
- stream items we captured before.
- the algorithm of the weight is sample,weight is bettween 0-10,
- when first insert into cache_item or the current captured stream
- has been in cache_item,we add 2 to the stream weight.and at the
- same time sub 1 to other stream item's weight.when the cache_item
- is full,the item which has the smallest weight will be coverd.and
- this is done by the insert_cache_item function*/
- int search_cache_item()
- {
- int i,j=-1;
- for(i=0;i<CACHESIZE;++i)
- {
- if(cache_item[i].type=proto&&cache_item[i].sport==sport&&cache_item[i].dport==dport&&cache_item[i].sip==sip&&cache_item[i].dip==dip)
- {
- if(cache_item[i].weight<=10)
- {
- cache_item[i].weight+=2;
- }
- j=i;
- }/*we hava find one that match the current stream*/
- else
- {
- if(cache_item[i].weight>=1)
- cache_item[i].weight-=1;
- }
- }
- printf("search_cache_item result is %d\n",j);
- return j;
- }
- /*function to search the stream current captured
- in the item[] which contains all the streams captured
- before.*/
- int search_item()
- {
- printf(" search in the item \n");
- int i=0,j;
- for(i=0;i<item_max;i++)
- {
- if(item[i]->sip==sip&&item[i]->sport==sport&&item[i]->dport==dport&&item[i]->type==proto&&item[i]->dip==dip)
- {
- item[i]->count+=1;
- item[i]->bytes+=n_read;
- break;
- }
- }
- j=(i<item_max)? 1:-1;
- printf("search in the item result is %d\n",j);
- return j;
- }
- /*function to add the current stream captured to
- the stream struct list*/
- int add_to_item()
- {
- if(item_max<STREAMSIZE)
- {
- printf("item_max is %d\n",item_max);
- item[item_max]=(stream *)(malloc(sizeof(stream)));
- memset(item[item_max],0,sizeof(stream));
- item[item_max]->type=proto;
- item[item_max]->sip=sip;
- item[item_max]->dip=dip;
- item[item_max]->sport=sport;
- item[item_max]->dport=dport;
- item[item_max]->bytes+=n_read;
- item[item_max]->count=+1;
- item_max=item_max+1;
- }
- else
- {
- fprintf(stderr,"stream is to large please change the STREAMSIZE\n");
- exit(1);
- }
- }
- int main(int argc,char *argv[])
- {
- int i,ret,id,sockfd;
- char buf[BUFSIZE];
- struct tcphdr *tcp_head;
- struct udphdr *udp_head;
- struct iphdr *ip_head;
- char *p;
- for(i=0;i<CACHESIZE;i++)
- {
- cache_item[i].weight=0;
- }
- signal(SIGINT,sig_handle);
- if((sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))<0)
- {
- fprintf(stderr,"socket error\n");
- printf("%d","sockfd");
- exit(1);
- }
- while(capture)
- {
- n_read = recvfrom(sockfd,buf,BUFSIZE,0,NULL,NULL);
- ip_head = (struct iphdr *)(buf+14);
- /*14=6 source mac address
- 6 destnation mac address
- 2 type
- */
- proto=ip_head->protocol;
- sip=ip_head->saddr;
- dip=ip_head->daddr;
- ip_h_len=ip_head->ihl<<2;
- if(proto==IPPROTO_TCP)
- {
- tcp_head = (struct tcphdr *)(buf+14+ip_h_len);
- sport=tcp_head->source;
- dport=tcp_head->dest;
- if((id=search_cache_item())>=0)/*current stream is in cache*/
- {
- item[id]->count+=1;
- item[id]->bytes+=n_read;
- printf("use cache info\n");
- }
- else
- {
- insert_cache_item(); /*cache it */
- if((ret=search_item())<0)
- {
- add_to_item();
- }
- }
- }
- else if(proto==IPPROTO_UDP)
- {
- udp_head=(struct udphdr *)(buf+14+ip_h_len);
- sport=udp_head->source;
- dport=udp_head->dest;
- if(id=search_cache_item()>0)
- {
- item[id]->count+=1;
- item[id]->bytes+=n_read;
- }
- else
- {
- insert_cache_item();
- if(search_item()<0)
- add_to_item();
- }
- }
- }
- return 0;
- }
复制代码 |
|