利用SNIFFER PRO学习TCPIP(一)

    技术2022-05-11  64

     利用SNIFFER PRO学习TCP/IP()

    2003/10/28

    ydzqw 

    :Sniffer Pro应该大家都知道,不知道的到GOOGLE搜索J

    最好手头有本<<TCP/IP详解卷1:协议>> 

    这两天在看<<TCP/IP详解>>,总觉得有些地方理解的不够深。于是写了个小程序,再加上Sniffer,慢慢咀嚼。

    程序如下:

     

    ---------------------Server-----------------------------

    #include<iostream>

    #include<winsock2.h>

    #include<windows.h>

    using namespace std;

     

    void main()

    {

           WORD wVer;

           WSADATA wsaData;

           //WSAStartup

           wVer = MAKEWORD(1, 1);

           if ( WSAStartup(wVer, &wsaData) )

           {

                  cout << "WSAStaup error!";

                  return;

           }

           //SOCKET init

           SOCKET sock;

           if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )

           {

                  cout << "socket error!";

                  return;

           }

           //bind, listen and accept

           sockaddr_in sockadr;

           sockadr.sin_family = AF_INET;

           sockadr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

           sockadr.sin_port = htons(6666);

           if ( bind(sock, (sockaddr*)&sockadr, sizeof(sockadr)) )

           {

                  cout << "bind error!";

                  return;

           }

           if ( listen(sock, 5) )

           {

                  cout << "listen error!";

                  return;

           }

           SOCKET sock_svr;

           sockaddr_in sockadr_svr;

           int iLen = sizeof(sockadr_svr);

           //acceptblocking,如果这时要退出程序,那该如何?

           sock_svr = accept(sock, (sockaddr*)&sockadr_svr, &iLen);

           if ( sock_svr == INVALID_SOCKET )

           {

                  cout << "accetp error!";

                  return;

           }

     

           //select and recv

           fd_set rdfs;

           timeval tv;

           char buf[1024 * 2];

           int retval;

           int recv_err;

           tv.tv_sec = 5;

           tv.tv_usec = 0;

           for(; ;)

           {

                  FD_ZERO(&rdfs);

                  FD_SET(sock_svr, &rdfs);

                  retval = select(0, &rdfs, NULL, NULL, &tv);

                 memset(buf, 0, sizeof(buf));

                  if ( retval > 0 )

                  {

                         recv_err = recv(sock_svr, buf, sizeof(buf), 0);

                         if (recv_err == 0)

                         {

                                closesocket(sock_svr);

                                break;

                         }

                         else

                         {

                                cout << buf;

                         }

                  }

           }

           closesocket(sock);

           WSACleanup();

    }

    -------------------------------------Client-------------------------------------

    #include<iostream>

    #include<winsock2.h>

    #include<windows.h>

    using namespace std;

     

    void main()

    {

           WORD wVer;

           WSADATA wsaData;

           //WSAStartup

           wVer = MAKEWORD(1, 1);

           if ( WSAStartup(wVer, &wsaData) )

           {

                  cout << "WSAStaup error!";

                  return;

           }

           //SOCKET init

           SOCKET sock;

           if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )

           {

                  cout << "socket error!";

                  return;

           }

           //connect and send

           sockaddr_in sockadr;

           sockadr.sin_family = AF_INET;

           //Server在本机时启用环回接口,按理说可以捕捉到数据

           //sniffer却捕捉不到数据,这应该是Windows在底层做了相应处理

           sockadr.sin_addr.S_un.S_addr = inet_addr("192.168.1.81");

           sockadr.sin_port = htons(6666);

           if ( connect(sock, (sockaddr*)&sockadr, sizeof(sockadr)) == SOCKET_ERROR )

           {

                  cout << "connect error!";

                  return;

           }

     

           //分片会在哪里进行?IP?TCP?

           char Test[2000];

           memset(Test, 65, sizeof(Test));

           Test[sizeof(Test) - 1] = 'B';//这样才可看出是否全部传过去了

           if ( send(sock, Test, sizeof(Test), 0) == SOCKET_ERROR )

           {

                  cout << "send error!";

                  return;

           }

           //Sleep(1000);//等待Server的响应包再关闭

           //close and WSACleanup

           if ( closesocket(sock) )

           {

                  cout << "closesocket error!";

                  return;

           }

           if ( WSACleanup() )

           {

                  cout << "WSACleanup error!";

                  return;

           }

    }

    ------------------------------------------------------------------------------------

     

    Client端的192.168.1.81改成运行Server端所在机器的IP地址。ClientServer不能在同一台机器(这一点我也很困惑),不然Sniffer捕捉不到数据。

    Start SnifferPro(Capture->Start),接着运行ServerClient,程序一闪而过就结束了,Stop and Display SnifferPro(Capture->Stop and Display)。程序虽然一闪就结束了,没关系,我们要的东西都被Sniffer Capture了。

    在面板中点击Decode,可以开始了。

    注意上图,从NO.12NO.21(当然,在你的机器执行时不见得是12-21)就是此次发送的全过程。12,13,14是建立连接的三次握手(DDoS攻击就有利用三次握手的漏洞),参见<<详解>>P17615,16是数据传送(这里有个数据分片问题,下面会详细说明)17,19,20,21是终止连接的四次握手,18是响应包,响应15,16的数据传送。因为在我程序中send之后马上就进行closesocket,所以响应包反而到终止连接请求后面了,当然,只要在send之后Sleep(1000),就不会发生这种情况。开始我也疑惑怎么会有五次握手,在这里我没更正回来,就是为了启示大家,要小心分析。

    下面开始分析数据包的结构:


    最新回复(0)