NS-仿真实验--FTP

                       FTP 实验总结

1.FTP 客户端

a.       FTP 配置文件格式 ( 参考 init 文件 )

要登陆的主机的 IP 地址

用户名

密码

要获取的文件的路径名 ( 绝对路经 )

文件存入当前 Ftp 目录下的文件名

b.       日志文件格式(参考 last.log 文件)

总共收到的字节数

总共所用时间

传输速率( bytes/second

c.       函数说明

/*ftp_var.h 中声明了 Systems 结构,封装了配置文件结构 *

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 的对应关系就行了。

 

转载自:http://blog.csdn.net/zzg_px/archive/2004/12/21/224585.aspx

posted @ 2011-02-28 17:18  wangicter的博客  阅读(242)  评论(0编辑  收藏  举报