实验步骤

     练习一:编辑并发送UDP
     1、打开数据包编辑器,在工具栏选择“新建”,建立一个以太网帧;
     2、观察运行结果,获得本机的以太网地址:
        (a)源MAC地址”和“目的MAC地址”字段,注意:当选择的目的主机与本机不在同一
           子网的情况,目的MAC地址该怎样填写
        (b)“类型或长度”字段值应为:0800(即IP协议的类型值)
     3、填写IP协议头信息:
        注意协议字段,即上层协议类型应为17(UDP协议的类型为17);
     4、填写UDP协议信息:
        (a)16位源端口号:自选
        (b)16位目的端口号:自选
        (c)数据字段:可有可无
        (d)16位UDP长度:UDP报头长度(8)与UDP数据长度之和
        (e)校验和:覆盖UDP首部(含伪首部)和数据两部分。请先根据参考原理(3)的内
           容进行手工计算,然后利用数据包编辑器来计算(方法二),比较二者的结果,
           检验手工计算结果的正确性。
           方法一:手工计算。
                   按照参考原理(3)中介绍的内容,计算好UDP伪首部和首部中的各项
                   值,然后按16bit进行反码求和(方法同计算IP校验和),将结果填入相
                   应字段。
           方法二:利用数据包编辑器来计算。步骤为:
                   ①将UDP长度填写到16位UDP校验和字段中作为伪首部中UDP长度字段
                       值;
                   ②选中IP首部中的32位源IP地址和32位目的IP地址作为UDP伪首部中的
                       32位源IP地址和32位目的IP地址;
                   ③选中IP首部中8位的协议字段作为UDP伪首部中的8位的协议字段;
                   ④在8位的协议字段之前选择一个8位的0作为UDP伪首部中的8位0;
                   ⑤再选中UDP首部的及数据各字段;
                   ⑥点击鼠标右键,选择“计算校验和”;
                   ⑦将得到的校验和值填写到16位UDP校验和字段。
                   下面是一个计算UDP校验和的一个例子:
                    一个不含数据部分的UDP数据报的十六进制对照表如下:
                    00 01 02 03 04 05 06 07 08 09 0A 0B 08 00 45 00
                    00 4F 94 48 40 00 80 11 E4 9D C0 A8 00 20 C0 A8
                    00 52 00 00 00 00 00 08 00 08
                    其中黑体部分为用来计算校验和的UDP伪首部和UDP首部,其中:
                    00 11(十进制的17):为UDP伪首部中8位的0和8位的协议字段;
                    C0 A8 00 20:为UDP伪首部中32位源IP地址;
                    C0 A8 00 52:为UDP伪首部中32位目的IP地址;
                    00 00 00 00 00 08 00 08:为8字节的UDP首部;
                    由于缺少伪首部中16位UDP长度,故该值暂时存放在16位UDP校验和字段
                    中,在本例中该值为00 08;
                    对上述选中部分计算校验和即可。
     5、如果要发送多个UDP数据报,可重复上述步骤,并可在多帧编辑器中设置每一帧的发
        送次数和发送每帧的时间间隔;
     6、点击工具栏或菜单栏中的“发送”,在弹出菜单上选择“发送”按钮,发送UDP报文;
     7、在监控机一端截获相应的报文并分析。
     练习二:编辑并发送UDP广播包
     1、实验步骤同上;
          
注意:以太网协议首部中的目的MAC地址应怎样填写?
          IP首部中的目的IP地址该怎样填写?
     2、在监控机一端截获相应的报文并分析。
     练习三:运行netstat命令
     1、在DOS命令行方式下运行:netstat –s 显示每个协议的使用状态,观察UDP协议的
        使用情况。
     2、在DOS命令行方式下运行:netstat –a 显示所有主机的端口号,观察与UDP协议相
        关的内容。  
     练习四:运行ipconfig命令
     1、在DOS命令提示符下运行:
          ipcofig /displaydns
     2、 观察运行结果。
     练习五:运行Winsock网络程序
     设计一个简单的Winsock网络程序,模拟UDP数据报,加深对DNS作用的理解。
     1、启动Visual C++,进入集成开发环境;
     2、 建立一个“Win32 Consol Application”类型的工程,工程名自拟;
     3、 在该工程下,新建一个源程序文件,即选择“C++ Source File”,文件名自拟;
     4、输入以下源程序(注释部分不必输入):
     //////////////////////////////////////////////////////////////////////////
     //本程序的功能为:                                                      //
     //(1)获取本机名(gethostname());                                      //
     //(2)获得给定主机名的IP地址(gethostbyname());                         //
     //(3)获得给定IP地址的主机名(gethostbyaddr()).                         //
     //////////////////////////////////////////////////////////////////////////
     /*头文件*/
     #include <winsock.h>
     #include <stdio.h>
     #include <string.h>
     int main()
     {
     /*初始化 windows sockets API*/
     WORD wVersionRequested = MAKEWORD(1, 1);
     WSADATA wsaData;
     if (WSAStartup(wVersionRequested, &wsaData)) {
         printf("WSAStartup failed %s\n", WSAGetLastError());
         return -1;
     }
     /* 获得本主机名*/
     char hostname[256];
     int res = gethostname(hostname, sizeof(hostname));
     /*错误处理*/
     if (res != 0) {
         printf("Error: %u\n", WSAGetLastError());
         return -1;
     }
     /*打印本主机名字*/
     printf("本主机名为:%s\n", hostname);
     /*输入一个主机的域名,可以为本机也可以为其他主机*/
     printf("请输入一个主机域名:");
     scanf("%s",hostname);
     /* 利用主机名获得主机的地址信息 */
     hostent* pHostent = gethostbyname(hostname);
     /*错误处理*/
     if (pHostent==NULL) {
         printf("Error: %u\n", WSAGetLastError());
         return -1;
     }
     /* 解析返回的主机地址信息:别名、地址类型、地址长度,并打印*/
     hostent& he = *pHostent;
     printf("name=%s\naliases=%s\naddrtype=%d\nlength=%d\n",
         he.h_name, he.h_aliases, he.h_addrtype, he.h_length);
     /*打印主机每一个网卡的IP地址*/
     sockaddr_in sa;
     for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++) {
         memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
         /* 输出机器的 IP地址并以字符 串的形式显示出来.*/
         printf("Address: %s\n", inet_ntoa(sa.sin_addr));
     }
     printf("\n");
     /*输入一个服务器的IP地址*/
     unsigned long addr;
     char hostaddr[50];
     printf("请输入服务器IP地址:");
     scanf("%s",hostaddr);
     /*将IP地址转化为网络字节序*/
     addr=inet_addr(hostaddr);
     /*利用IP地址获得主机名*/
     pHostent=gethostbyaddr((char *)&addr,4,AF_INET);
     /*错误处理*/
     if (pHostent==NULL) {
         printf("Error: %u\n", WSAGetLastError());
         return -1;
     }
     hostent& he1 = *pHostent;
     /*打印返回的地址信息,注意主机名字信息*/
     printf("主机名为:%s\naliases=%s\naddrtype=%d\nlength=%d\n",
         he.h_name, he.h_aliases, he.h_addrtype, he.h_length);
     /* 结束 windows sockets API*/
     WSACleanup();
     return 0;
     }
     6、使用Winsock函数的程序必须与 WS2_32.LIB进行链接,而Visual C++集成开发环
        境的缺省链接库中没有此项,因此要把ws2_32.lib加入到链接库的列表里面。
        具体步骤是:
          (a)选择“工程”菜单下的“设置”项。
          (b)在弹出页面中选择“Link”一项。
          (c)将“ws2_32.lib”加入“L对象/库模块”列表当中。
     7、编译、连接并运行程序。
     8、观察程序运行的结果,体会程序中几个主要函数的作用。
     练习六:反复运行上述程序,可以输入以下域名:
             
www.jlu.edu.cn
             mail.jlu.edu.cn
            
 www.sina.com
             
www.microsoft.com
             ……
             在监控机端捕获数据并分析说明:
             1、名字解析器使用传输层的哪一协议来处理查询请求?
             2、本地名字服务员的IP地址是什么?
             3、名字服务员进程的端口号是什么?
             4、随便输入一个不带后缀的主机名(如:aaa),观察捕获到的数据。

 
思考问题

    1、在监控机一端截获网络中的多个广播报文,观察其源MAC地址及源IP地址,是否都来
       自同一子网?为什么?
    2、分析DNS的工作原理。
    3、域名与IP地址之间是否有一一对应的关系?