课程设计目的
本章课程设计的目的就是设计一个解析IP数据包的程序,并根据这个程序,说明IP数据包的结构及IP协议的相关问题,从而对IP层的工作原理有更好的理解和认识。
课程设计要求
本设计的目标是捕获网络中的IP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。
程序的具体要求如下:
1)以命令行形式运行:ipparse logfile,其中ipparse是程序名,
而logfile则代表记录结果的日志文件。
2)在标准输出和日志文件中写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容。
3)当程序接收到键盘输入Ctrl+C时退出
我自己写的代码;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct ipaddress{
unsigned char a,
b,
c,
d;
};
struct ip_header{
unsigned char ip_ver_len;
unsigned char ip_tos;
unsigned short ip_total_length;
unsigned short ip_id;
unsigned int ip_flags:4;
unsigned int ip_frag_offset:12;
unsigned char ip_ttl;
unsigned char ip_protocol;
unsigned short ip_header_cksum;
struct ipaddress ip_source;
struct ipaddress ip_destn;
};
int do_promisc(char *nif, int sock){ //抄袭的,知道作用,不过没看懂!
struct ifreq ifr;
strncpy(ifr.ifr_name, nif,strlen(nif)+1);
if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {
perror("ioctl");
exit(2);
}
ifr.ifr_flags |= IFF_PROMISC;
if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) {
perror("ioctl");
exit(3);
}
}
int main(int argc,char *argv[]){
int recv;
int sockfd;
int to_fd,bytes_write;
FILE *to_fp;
unsigned char tmp,ip_version,ip_hdr_length;
struct sockaddr_in ip_from;
int sin_size;
char buf[65535];
struct ip_header *ipheader;
if(argc!=2){
printf("Usage :%s logfile\n",argv[0]);
exit(1);
}
if(-1==(sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP))){
perror("Creat socket error!\n");
exit(1);
}
do_promisc("eth0",sockfd);
while(1){
sin_size=sizeof(struct sockaddr_in);
if(-1==(recv=recvfrom(sockfd,(char *)buf,sizeof(buf),0,(struct sockaddr *)&ip_from,&sin_size))){
printf("Receive error!\n");
exit(1);
}
if(0==recv){
printf("Received nothing!\n");
}
else{ if(-1==(to_fd=open(argv[1],O_WRONLY|O_CREAT|O_APPEND))){
perror("Creat file error!");
exit(1);
}
if(NULL==(to_fp=fdopen(to_fd,"w"))){
perror("fdopen()");
exit(1);
}
buf[recv]=0;
ipheader=(struct ip_header *)buf;
tmp=(*ipheader).ip_ver_len;
ip_version=tmp>>4;
tmp=tmp<<4;
ip_hdr_length=tmp>>4;
printf("-------------------------------------------\n");
fprintf(to_fp,"------------------------------------------\n");
printf("IP version:%d\n",ip_version);
fprintf(to_fp,"IP Version:%d\n",ip_version);
printf("IP head length:%d\n",ip_hdr_length);
fprintf(to_fp,"IP Head Length:%d\n",ip_hdr_length);
printf("Type of service:%d\n",(*ipheader).ip_tos);
fprintf(to_fp,"Type of service:%d\n",(*ipheader).ip_tos);
printf("Total length:%d\n",(*ipheader).ip_total_length);
fprintf(to_fp,"Total Length %d\n",(*ipheader).ip_total_length);
printf("IP identify:%d\n",(*ipheader).ip_id);
fprintf(to_fp,"IP ID:%d\n",(*ipheader).ip_id);
printf("IP flags:%d\n",(*ipheader).ip_flags);
fprintf(to_fp,"IP Flag:%d\n",(*ipheader).ip_flags);
printf("IP frag offset:\n",(*ipheader).ip_frag_offset);
fprintf(to_fp,"IP Frag Offset:%d\n",(*ipheader).ip_frag_offset);
printf("IP time to live:%d\n",(*ipheader).ip_ttl);
fprintf(to_fp,"IP TTL:%dms\n",(*ipheader).ip_ttl);
printf("Procotol :%d\n",(*ipheader).ip_protocol);
fprintf(to_fp,"IP Protocol:%d\n",(*ipheader).ip_protocol);
printf("IP header check sum:%d\n",(*ipheader).ip_header_cksum);
fprintf(to_fp,"IP check sum:%d\n",(*ipheader).ip_header_cksum);
printf("This package is from %d.%d.%d.%d\n",(*ipheader).ip_source.a,(*ipheader).ip_source.b,(*ipheader).ip_source.c,(*ipheader).ip_source.d);
fprintf(to_fp,"This package is from %d.%d.%d.%d\n",(*ipheader).ip_source.a,(*ipheader).ip_source.b,(*ipheader).ip_source.c,(*ipheader).ip_source.d);
printf("iThis package is to %d.%d.%d.%d\n",(*ipheader).ip_destn.a,(*ipheader).ip_destn.b,(*ipheader).ip_destn.c,(*ipheader).ip_destn.d);
fprintf(to_fp,"This package is to %d.%d.%d.%d\n",(*ipheader).ip_destn.a,(*ipheader).ip_destn.b,(*ipheader).ip_destn.c,(*ipheader).ip_destn.d);
fclose(to_fp);
close(to_fd);
fflush(NULL);
}
}
}
请指教啊,写的非常烂,我知道,不过算能交差了!
运行结果如下:
截图:
我心里没底,运行到底正确么?
阅读(1138) | 评论(0) | 转发(0) |