|
NS-仿真实验--FTP(1)
FTP实验总结1.FTP客户端a. FTP配置文件格式(参考init文件) 要登陆的主机的IP地址 用户名 密码 要获取的文件的路径名(绝对路经) 文件存入当前Ftp目录下的文件名 b. 日志文件格式(参考last.log文件) 总共收到的字节数 总共所用时间 传输速率(bytes/second) c. 函数说明 /*ftp_var.h中声明了Systems 结构,封装了配置文件结构*XML:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> typedef strUCt{ char* ipadd; char* user; char* pwd; char* filename; //输入文件名 char* outfilename;//输出文件名 }Systems; extern Systems* sysptr; /*Main.c中定义了sys_next 函数*/ Long sys_next(Systems*sysptr) 根据空白符从文件中读取配置信息到sysptr全局变量中 /*Main.c中定义了cmdscannerHelper函数*/ void cmdscannerHelper () 根据配置文件的设定信息,形成FTP命令,发到服务器。 /*Main.c中定义了cmdsBye函数*/ void cmdsBye () 发送FTP命令BYE,到服务器,结束传送。 /*ftp.c中login函数中自动登陆*/ int login(char * host) 根据配置文件的设定信息,形成FTP命令,发到服务器。 如: strcpy(user,sysptr->user); strcpy(pass,sysptr->pwd); n = command("USER %s", user); if (n == CONTINUE) { n = command("PASS %s", pass); } if (n == CONTINUE) { aflag++; acct = getpass("Account:"); n = command("ACCT %s", acct); } d. FTP客户端,根据init文件的设定,到服务器下载文件到当前的目录中。文件名的前面以P打头,加上进程号,在加上init文件中设定的文件名。(如Process27310-1.tar.gz) e. 注意在init文件中IP 目的地址要设定成服务器的真实地址对应的虚地址。 2.仿真器的配置a. 仿真器的工作脚本 set ns [new Simulator] $ns use-scheduler RealTime set n1 [$ns node] set n2 [$ns node] set n3 [$ns node] $ns map 10.88.88.81 10.88.88.99 $n2 $ns map 10.88.88.81 10.88.88.99 $n3 $ns map 10.88.88.74 21 10.88.88.98 $n1 $ns duplex-link $n2 $n1 10Mb 10ms DropTail $ns duplex-link $n3 $n1 10Mb 10ms DropTail set myfilter [new InThread]; # Create the bpf set dev [$myfilter open readonly eth0] $myfilter filter "dst host 10.88.88.98 or dst host 10.88.88.99" set ipnet2 [new Agent/OutThread]; # Create a Network agent $ipnet2 open writeonly $ns attach-agent $n2 $ipnet2; # Attach agent to the node. $n2 attach $ipnet2 8000 set ipnet3 [new Agent/OutThread]; # Create a Network agent $ipnet3 open writeonly $ns attach-agent $n3 $ipnet3; # Attach agent to the node. $n2 attach $ipnet3 8000 set ipnet1 [new Agent/OutThread]; # Create a Network agent $ipnet1 open writeonly $ns attach-agent $n1 $ipnet1; # Attach agent to the node. $n1 attach $ipnet1 8000 $ns at 432000.0 "finish" proc finish {} { exit 0 } $ns run b. 路由的添加 在FTP客户端所在的主机添加路由route add -host 10.88.88.98 gw 10.88.88.86 在FTP server所在的主机添加路由 route add -host 10.88.88.99 gw 10.88.88.86 c. 真实的网络拓扑环境在仿真器中的模拟 FTP客户端 真实IP 10.88.88.81 虚IP 10.88.88.99 其它客户端…(目前实验只支持两个客户端,两个客户端可以在同一台主机上,也可以在不同的主机上) FTP server 真实IP 10.88.88.81 虚IP 10.88.88.98 NS仿真器 真实IP 10.88.88.86 3.仿真器中FTP协议的修改a. 修改FTP应用层数据 //对应用层进行处理,因为有实用数据时 char *app_header = (char *)tcpheader; app_header += tcpheader->doff*4; char *ptr = app_header; char buff[255]={0},tempbuf[255]={0}; char *servip = (char *)buff;
strncpy(buff,ptr,4); if(!strcmp(buff,"PORT")) { strncpy(buff,ptr+5,91-71); for(int ii=0;ii<4;) { if((*servip)==',') { ii++; *servip='.'; } if(ii==4) break; servip++; } *servip =0; servip=buff; strncpy(tempbuf,ptr+strlen(buff)+5,91-71-strlen(buff)); //printf("tempbuf is %s\n",tempbuf); int count=0; for(int jj=0;true;jj++) { if(tempbuf[jj]==13) { count = jj; break; } } //htable__->printall(); tmpBucket = htable__->lookupr_IP(servip); //获取服务器地址 int diff = strlen(tmpBucket->virhost_ip) - strlen(servip); strcpy(buff,tmpBucket->virhost_ip); //printf("buf is %s\n",buff); servip =(char *)buff; for(int ii=0;*servip;) { if((*servip)=='.') { ii++; *servip=','; } servip++; } //直接拷贝内存到所要到的区域上 memmove(ptr + 5, buff , strlen(buff)); memmove(ptr + 5 + strlen(buff) ,tempbuf,count); ptr[5 + strlen(buff) + count] = 13; ptr[5 + strlen(buff) + count+1] = 10; ch->size() = cc + diff; //修改包长度,以及假包长度 ipheader->ip_len = ipheader->ip_len + diff; } b. 协议的修改过程 if (ipheader->ip_p == 6 && ntohs(tcpheader->dest) == 21){} else if (ipheader->ip_p == 6 && (ntohs(tcpheader->dest) == 20)){} else if(ipheader->ip_p == 6&&ntohs(tcpheader->source) == 21){} else if(ipheader->ip_p == 6&&ntohs(tcpheader->source) == 20){} 主要由以上的四个判断看出一个IP数据包的方向。 目的端口21----〉发往服务器的控制端口 在这种情况下我们要把不在Hash表中的端口插入到哈希表中 并象a那样修改相应的应用层数据 目的端口20 ---〉发往服务器的数据端口 源端口 21 ---〉从服务器返回的控制数据包 原端口 20 ----〉从服务器返回的数据包 其它情况我们只要在Hash表中找到真实IP和虚IP的对应关系就行了。
|