基于Linux下的VIM、Mac下的idea实现的协议分析软件

一、任务概述

1.1 设计目的

使学生深入理解和掌握计算机网络的基本理论及工作原理,熟悉计算机网络和互联网的组成,运用计算机网络知识设计协议分析软件,并进行网络协议分析,最后通过网页呈现,加深对计算机网络系统的认知、设计与应用开发能力,同时培养学生运用计算机网络技术解决实际问题的能力。

1.2 项目任务和要求

要求学生掌握计算机网络协议原理、协议分析方法及协议分析软件的开发。理解网络协议的层次结构及网络协议的工作过程,掌握网络协议的分析方法及网络协议的设计与应用。

1.3 参考资料

·《计算机网络》,谢希仁,电子工业出版社,2017 年 1 月第 7 版。

· 通过因特网查阅资料(CSDN 博客网站等)。

二、开发环境

运行的操作系统:Linux 抓包服务器;Mac 分析客户端

编程工具:Linux 下的 VIM、Mac 下的 idea

集成开发环境:VIM 和 idea

Linux:服务器 IP:192.168.43.173

Mac 客户端 IP:192.168.43.172

组员分工:

赵侍书抓包服务器、数据库连接和维护
任豆豆抓包服务器、数据库创建
桑展IP、TCP 协议分析、网页设计
强倩雯UDP、ICMP 协议分析

三、项目需求分析

界面管理模块的主要功能是方便用户对网络协议分析的管理,网络数据包捕获模块是系统的开始部分,它的重要性在于数据包捕获的准确性和及时性,不可丢包,否则将影响整个系统的性能。协议解析模块主要是完成对捕获的数据包进行详细的分析,在此基础上由协议分析模块进一。步分析网络协议。存储模块的主要功能是存储捕获来的、并进行协议分析后的网络信息,以便事后分析网络性能。

四、项目设计和实现

4.1 总体设计

关键类:libcap 函数库;serverlet;JSP 的页面设计

4.2 功能设计

4.2.1 通信协议的定义:
4.2.1.1 IP 协议:

IP 地址表现由一组 32 位 2 进制数组成,每 8 位为一个段,共分为 4 段,以‘.’间隔。含义由网络地址(NetID)和主机地址(HostID)两部分组成。网络地址表示其属于互联网中的哪一个网络,而主机地址则表示其属于该网络中的哪一台主机,两者之间是主从关系。IP 地址对应应用于网络层,基于 IP 协议的网络地址就是 IP 地址。

4.2.1.2 ICMP 协议:

是一个网络层协议。 一个新搭建好的网络,往往需要先进行一个简单的测试,来验证网络是否畅通;但是 IP 协议并不提供可靠传输。如果丢包了,IP 协议并不能通知传输层是否丢包以及丢包的原因。 所以我们就需要一种协议来完成这样的功能——ICMP 协议。

ICMP 的报文格式:

ICMP 报文包含在 IP 数据报中,IP 报头在 ICMP 报文的最前面。一个 ICMP 报文包括 IP 报头(至少 20 字节)、ICMP 报头(至少八字节)和 ICMP 报文(属于 ICMP 报文的数据部分)。当 IP 报头中的协议字段值为 1 时,就说明这是一个 ICMP 报文。

ICMP 报头如下图所示:

字段说明:

类型说明
类型占一字节,标识 ICMP 报文的类型,从类型值来看 ICMP 报文可以分为两大类。第一类是取值为 1~127 的差错报文,第 2 类是取值 128 以上的信息报文
代码占一字节,标识对应 ICMP 报文的代码。它与类型字段一起共同标识了 ICMP 报文的详细类型
校验和这是对包括 ICMP 报文数据部分在内的整个 ICMP 数据报的校验和,以检验报文在传输过程中是否出现了差错(其计算方法与在我们介绍 IP 报头中的校验和计算方法是一样的)
4.2.1.3 TCP 协议:

TCP 协议是 TCP/IP 协议体系中非常复杂的一个协议。它是面向连接的运输层协议,每一条 TCP 连接只能有两个端点(endpoint),每一条 TCP 连接只能是点对点的(一对一)。TCP 提供可靠交付的服务,通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达。TCP 提供全双工通信,面向字节流,TCP 中的“流”(stream)指的是流入到进程或从进程流出的字节序列。TCP 连接是一条虚连接(也就是逻辑链接),而不是一条真正的物理连接。TCP 并不关心应用进程一次把多长的报文发送到 TCP 的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节。

4.2.1.4 UDP 协议:

UDP 是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,UDP 在 IP 报文的协议号是 17。UDP 协议全称是用户数据报协议,在网络中它与 TCP 协议一样用于处理数据包,是一种无连接的协议。在 OSI 模型中,在第四层—传输层,处于 IP 协议的上一层。面向报文,UDP 对应用程序交付的报文,添加 UDP 首部后直接交给 IP 层。UDP 首部开销较小,8 字节(TCP 为 20 字节、IP 为 20 字节)。

4.2.2 功能设计

抓包功能:

  1. 可以无限循环的捕获数据包,无次数限制,随时终止抓包。
  2. 可以过滤数据包,只向数据库写入需要的数据包。
  3. 在多台主机在同一个局域网内的条件下,多台主机可同时抓取数据包并写入数据库,使软件功能更广泛。

4.3 系统实现

抓包实现:

  1. 首先在 Linux 下引入 libcap 函数库,通过 pcap_findalldevs 函数遍历本机的网卡设备,先找到可以捕获到数据包的物理网卡 ens33,并用函数 pcap_open_live 将该网卡进行探测。
  2. 调用函数库中的 pcap_loop 抓包函数,循环抓取流经网卡的各种协议的数据包,记录当前包的大小和次序。
  3. 选择需要的包,使用 pcap_compile 函数将抓的包进行过滤,用 mysql_query 函数将数据包写入连接的数据库中,数据库将保存每个数据包的内容和写入时间。

五、程序的运行和测试结果

抓包:

图中上半部分为数据库的部分内容,此时里面包括数据包及插入它们的时间,下部分为执行抓包程序后,捕获一次数据包时打印的内容,并代表此时往数据库中插入了一条数据。

最终对数据包的分析结果以网页界面形式显示:

分析后的结果通过 serverlet 连接后,以网页界面显示,点击表格中【详细分析】按钮跳转页面,弹出分析弹窗对数据包进行详细的分析。

跳转页面:

六、设计中的问题及心得

6.1 试验中遇到的问题及解决:

针对个人负责的模块而言,我主要遇到的问题是:抓包与数据库的连接与写入等方面的问题,在这里主要概括几点进行详细介绍。

  1. 数据抓包问题:
问题解决
(1)由于采取的的探测网卡的函数 pcap_lookupdev()每次只会探测第一个,所以它每次探测的都是一个虚拟网卡,没有数据包流过,导致捕获不到数据包。先通过 ifconfig 查看所有的网卡,然后遍历网卡设备列表,选择真实的物理网卡 ens33 进行抓包。
(2)抓包过程中会出现段错误,导致抓包中断。使用了一个全局变量 MYSQ*conn_ptr;,导致线程安全问题,最后将全局变量改成了局部变量。
(3)第一阶段使用的 fork 创建了子进程,导致进程阻塞使得程序 Linux 上的双进程难以控制。在第二阶段改成将将数据包写入 Mac 系统中的数据库,而后从数据库中抓包进行分析。
(4)抓包函数抓不到 udp 的数据包。未将网卡设置成为混杂模式,混杂模式是抓取流经网卡的所有数据包。

2.数据库的连接与写入问题

(1)由于使用写入数据到数据库的函数 mysql_query 的向数据库写入的参数只能是一个常量,导致代码中为一个变量的数据包无法写入到数据库。定义一个临时数组 insert,通过 sprintf 将数据包写入这个数组,然后再使用 mysql_query 函数进行插入。
(2)在数据库连接过程中,申请的访问的主机被拒绝访问。数据库的主机中未将申请访问的主机的 IP 地址加入 root 用户表里,使用语句:GRANTALPRIVILEGES ON . TO ‘root’@’申请访问的主机号’IDENTIFIED BY ‘password’再使用语句 flush privileges;刷新一下更改即可。

3.客户端问题:

问题解决
客户端页面设计为动态但一直为静态转用 serverlet 来连接页面与 Java 代码的联系

4.页面报 500 错误

问题解决
页面报 500 错误配置问题,已解决

6.2 改进:

能有页面供用户选择想使用的网卡,想抓哪个网卡的数据包,而不是反复地抓同一个网卡的数据包。

页面展示时的跳转可以将展示的内容放在一个弹窗上,而不是部分一个弹窗,不便于查看数据。

七、附录

7.1 程序清单

·抓包:

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
#include<mysql/mysql.h>

MYSQL *conn_ptr;                           
unsigned int timeout = 7;   //超时时间7秒
#define PORT 3333
#define BACKLOG 1
#define MAXRECVLEN 65535
char trans[MAXRECVLEN];
void change(int i,char tmp[])
{
  int low=i%16;
  int high=i/16;
  if(low<=9)
  {
    tmp[1]='0'+low;                        
  }
  else
  {
    tmp[1]='a'+low-10;                    
  }
  if(high<=9)
  {
    tmp[0]='0'+high;
  }
  else{
    tmp[0]='a'+high-10;               
  }        
}

void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
  int ret = 0;
  conn_ptr = mysql_init(NULL);//初始化                                            
  if(!conn_ptr)
  {
    printf("mysql_init failed!\n");
    return ;
  }
  ret = mysql_options(conn_ptr,MYSQL_OPT_CONNECT_TIMEOUT,(const char*)&timeout);//设置超时>    选项
  if(ret) 
  {
    printf("Options Set ERRO!\n");                        
  }
  conn_ptr = mysql_real_connect(conn_ptr,"192.168.43.172","root","root","Packet",0,NULL,0);//连接MySQ
  if(conn_ptr)
  {
    printf("Connection Succeed!\n");         
  }
  int *count = (int *)arg;          
  printf("Packet Count: %d\n", ++(*count));
  printf("Received Packet Size: %d\n", pkthdr->len);
  printf("Payload:\n");
  int i=0;
  int j=0;
  char tmp[2];
  memset(trans,0,MAXRECVLEN);
  for( i=0; i < pkthdr->len; ++i)
  {
    change((int)packet[i],tmp);
    trans[j++]=tmp[0];
    trans[j++]=tmp[1];
    trans[j++]=' ';
    printf("%02x ", packet[i]);
    if ((i + 1) % 16 == 0)
      printf("\n"); 
  }
  printf("transInProcess=%s\n\n",trans);
  char sql_insert[2000];
  sprintf(sql_insert,"insert into Packet(id,time,packet) VALUES(2,now(),'%s');",trans);                  
  mysql_query(conn_ptr,sql_insert);
  if(!ret)
  {
  printf("Inserted %lu rows\n",(unsigned long)mysql_affected_rows(conn_ptr));//返回上次UPDATE更改行数
  }
  else
  {
    printf("Connect Erro:%d %s\n",mysql_errno(conn_ptr),mysql_error(conn_ptr));//返回错误代码、错误消息
  
  }
}
int Get()
{
  char errBuf[PCAP_ERRBUF_SIZE], * devStr;
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int i=0;
  char errbuf[PCAP_ERRBUF_SIZE];
  /* 获取本地机器设备列表 */
  if (pcap_findalldevs( &alldevs, errbuf    ) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
    exit(1);                                                                
  }
  for(d= alldevs; d != NULL; d= d->next)
  {
    if(strcmp(d->name,"ens33")==0)
    {   
      printf("%d. %s", ++i, d->name);
      break;
    }
  }
  devStr=d->name;
  if (devStr)
    printf("success: device: %s\n", devStr);
  else
  {
    printf("error: %s\n", errBuf);
    exit(1);
  }
  /* open a device, wait until a packet arrives */
  pcap_t * device = pcap_open_live(devStr, 65535, 1, 0, errBuf);
  if (!device)
  {
    printf("error: pcap_open_live(): %s\n", errBuf);
    exit(1);                                                   
  }
  /* construct a filter */
  struct bpf_program filter;
  pcap_compile(device, &filter, "ip", 1, 0);
  pcap_setfilter(device, &filter);
  int count = 0;
  /*Loop forever & call processPacket() for every received pa      cket.*/
  pcap_loop(device, 1, processPacket, (u_char *)&count);
  printf("transInGet=%s\n\n",trans);
  pcap_close(device);                                                                return 0; 
}  

int main(int argc, char *argv[])
{
   Get();
   return 0;
}

·客户端主程序:

package agreement;
import binaryToDecimalism.BinaryToDecimalish;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import static agreement.UDP.Length;
import static binaryToDecimalism.BinaryToDecimalish.binaryToDecimalish;
import static binaryToDecimalism.BinaryToDecimalish.hexadecimalbinary;
@WebServlet("/协议分析")
public class ServletTest extends javax.servlet.http.HttpServlet {
    public static String packet=null;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        List<Packages> list = new LinkedList<>();
        int i = 0;
        while (i < 42) {
            try {
                int id = -1;
                Class.forName("com.mysql.jdbc.Driver");
                Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/Packet?useSSL=false", "root", "root");
                Statement statement = connection.createStatement();
                ResultSet s = statement.executeQuery("select * from Info where id in(select max(id) from Info) ");
                while (s.next()) {
                    packet = s.getString("packet");
                    id = s.getInt("id");
                }
                statement.close();
                Statement statement1 = connection.createStatement();
                int row = statement1.executeUpdate("delete from Info where id = " + id + "");
                statement.close();
                connection.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            byte[ ] bytes = hexadecimalbinary(packet);
            byte[ ] mac = Arrays.copyOfRange(bytes, 0, 112);
            //ip层协议分析
            int agreementnumber=binaryToDecimalish(Arrays.copyOfRange(bytes,112,116));
            if(agreementnumber!=4){
                continue;
            }
            int iplength = binaryToDecimalish(Arrays.copyOfRange(bytes, 116, 120))*32;
            int ipbegin = 112;
            int ipend = 112+ iplength;
            byte[] ipArr = Arrays.copyOfRange(bytes, ipbegin, ipend);
            int upperLayerProtocol = binaryToDecimalish(Arrays.copyOfRange(bytes, ipbegin + 72, ipbegin + 80));
            IP.ip(ipArr);
            //TCP协议分析
            if (upperLayerProtocol == 6) {
                int tcplength = binaryToDecimalish(Arrays.copyOfRange(bytes, ipend + 96, ipend + 96 + 4)) * 32;
                int tcpbegin = ipend;
                int tcpend = ipend + tcplength;
                byte[] tcpArr = Arrays.copyOfRange(bytes, tcpbegin, tcpend);
                TCP.tcp(tcpArr);
            } else if (upperLayerProtocol == 1) {
                //ICMP
                byte[] icmpArr = Arrays.copyOfRange(bytes, ipend, ipend + 32);
                ICMP.icmp(icmpArr);
            } else if (upperLayerProtocol == 17) {
                //UDP
                byte[] udpArr = Arrays.copyOfRange(bytes, ipend, ipend + 64);
                UDP.udp(udpArr);
            }

            Packages p = new Packages( BinaryToDecimalish.length, IP.versions,IP.headLength,
                    IP.totalLength, IP.identificationNumber, IP.signnumber,
                    IP.SliceOffsetNUmber,IP.agreement, IP.headCheckSum,
                    IP.destinationaddress, IP.sourceaddress, ICMP.Type,
                    ICMP.code, ICMP.Checksum, TCP.sourcePort,
                    TCP.destinationPort, TCP.serialNumber, TCP.confirmationNumber,
                    TCP.windowSize, UDP.sourcePort, UDP.destinationPort,
                    UDP.Length,UDP.Checksum,packet);
            list.add(p);
            i++;
        }
        for (Packages z:list) {
            System.out.println(z.Length);
        }
        request.setAttribute("list",list);
        request.getRequestDispatcher("index.jsp").forward(request,response);
    }
}

·IP 协议分析:

package agreement;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import static binaryToDecimalism.BinaryToDecimalish.binaryToDecimalish;
public class IP {
    public static String versions;
    public static int headLength;
    public static int totalLength;
    public static int identificationNumber;
    public static int signnumber;
    public static int SliceOffsetNUmber;
    public static String agreement;
    public static int headCheckSum;
    public static String destinationaddress;
    public static String sourceaddress;

    public static void ip(byte[] bytes) throws UnsupportedEncodingException {

        byte[] versionsarr = Arrays.copyOfRange(bytes, 0, 4);
        int versionsnum = binaryToDecimalish(versionsarr);
        if (versionsnum == 4) {
            versions = "IPV4";
        }
        if (versionsnum == 6) {
            versions = "IPV6";
        }
        //System.out.println("版本:"+versions);
        byte[] head = Arrays.copyOfRange(bytes, 4, 8);
        headLength = binaryToDecimalish(head);
        //System.out.println("首部长度:"+headLength);
        byte[] Length = Arrays.copyOfRange(bytes, 16, 32);
        totalLength = binaryToDecimalish(Length);
        //System.out.println("总长度:"+totalLength);
        byte[] identification = Arrays.copyOfRange(bytes, 32, 48);
        identificationNumber = binaryToDecimalish(identification);
        //System.out.println("标识:"+identificationNumber);
        byte[] sign = Arrays.copyOfRange(bytes, 48, 51);
        signnumber = binaryToDecimalish(sign);
        //System.out.println("标志:"+signnumber);
        byte[] SliceOffset = Arrays.copyOfRange(bytes, 51, 64);
        SliceOffsetNUmber = binaryToDecimalish(SliceOffset);
        //System.out.println("片偏移:"+SliceOffsetNUmber);
        byte[] Agreement = Arrays.copyOfRange(bytes, 72, 80);
        int agreementnum = binaryToDecimalish(Agreement);
        if (agreementnum == 1) {
            agreement = "ICMP";
        } else 
        if (agreementnum == 6) {
            agreement = "TCP";
        } else 
        if (agreementnum == 17) {
            agreement = "UDP";
        } else {
            agreement = "IP";
        }

        byte[] headChecknum = Arrays.copyOfRange(bytes, 80, 96);
        headCheckSum = binaryToDecimalish(headChecknum);
        //System.out.println("首部校验和:"+headCheckSum);
        int[] sourceAddress = new int[4];
        sourceAddress[0] = binaryToDecimalish(Arrays.copyOfRange(bytes, 96, 104));
        sourceAddress[1] = binaryToDecimalish(Arrays.copyOfRange(bytes, 104, 112));
        sourceAddress[2] = binaryToDecimalish(Arrays.copyOfRange(bytes, 112, 120));
        sourceAddress[3] = binaryToDecimalish(Arrays.copyOfRange(bytes, 120, 128));
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            if (i == 3) {
                sb.append(sourceAddress[i]);
                break;
            }
            sb.append(sourceAddress[i]);
            sb.append(":");
        }
        sourceaddress = sb.toString();

        int[] destinationAddress = new int[4];
        destinationAddress[0] = binaryToDecimalish(Arrays.copyOfRange(bytes, 128, 136));
        destinationAddress[1] = binaryToDecimalish(Arrays.copyOfRange(bytes, 136, 144));
        destinationAddress[2] = binaryToDecimalish(Arrays.copyOfRange(bytes, 144, 152));
        destinationAddress[3] = binaryToDecimalish(Arrays.copyOfRange(bytes, 152, 160));
        StringBuffer sb1 = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            if (i == 3) {
                sb1.append(destinationAddress[i]);
                break;
            }
            sb1.append(destinationAddress[i]);
            sb1.append(":");
        }
        destinationaddress = sb1.toString();

    }
}

·packages 类:

package agreement;

import binaryToDecimalism.BinaryToDecimalish;

public class Packages {
    public String response; //拿到的包
    public int Length;
    public String ipversions;
    public int ipheadLength;
    public int iptotalLength;
    public int ipidentificationNumber;
    public int ipsignnumber;
    public int ipSliceOffsetNUmber;
    public String ipagreement;
    public int ipheadCheckSum;
    public String ipdestinationaddress;
    public String ipsourceaddress;
    public String icmpType;
    public String icmpcode;
    public int icmpChecksum;
    public int tcpsourcePort;
    public int tcpdestinationPort;
    public int tcpserialNumber;
    public int tcpconfirmationNumber;
    public int tcpwindowSize;
    public int udpsourcePort;
    public int udpdestinationPort;
    public int udpLength;
    public int udpChecksum;

    public Packages(int length, String versions, int headLength, int totalLength, int identificationNumber, int signnumber, int SliceOffsetNUmber, String agreement, int headCheckSum, String destinationaddress, String sourceaddress, String Type, String code, int Checksum, int sourcePort, int destinationPort, int serialNumber, int confirmationNumber, int windowSize, int udsourcePort, int uddestinationPort, int udLength, int udChecksum, String Response) {
        response = ServletTest.packet;
        Length = BinaryToDecimalish.length;
        ipversions = IP.versions;
        ipheadLength = IP.headLength;
        iptotalLength = IP.totalLength;
        ipidentificationNumber = IP.identificationNumber;
        ipsignnumber = IP.signnumber;
        ipSliceOffsetNUmber = IP.SliceOffsetNUmber;
        ipagreement = IP.agreement;
        ipheadCheckSum = IP.headCheckSum;
        ipdestinationaddress = IP.destinationaddress;
        ipsourceaddress = IP.sourceaddress;
        icmpType = ICMP.Type;
        icmpcode = ICMP.code;
        icmpChecksum = ICMP.Checksum;
        tcpsourcePort = TCP.sourcePort;
        tcpdestinationPort = TCP.destinationPort;
        tcpserialNumber = TCP.serialNumber;
        tcpconfirmationNumber = TCP.confirmationNumber;
        tcpwindowSize = TCP.windowSize;
        udpsourcePort = UDP.sourcePort;
        udpdestinationPort = UDP.destinationPort;
        udpLength = UDP.Length;
        udpChecksum = UDP.Checksum;

    }
}

·ICMP 协议分析:

package agreement;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import static binaryToDecimalism.BinaryToDecimalish.binaryToDecimalish;

public class ICMP {
    public static String Type;
    public static String code;
    public static int Checksum;
    public static void icmp(byte[]icmpArr) throws UnsupportedEncodingException {
        byte[]type= Arrays.copyOfRange(icmpArr,0,8);
        int Typenum=binaryToDecimalish(type);
        if(Typenum==3){
           Type="终点不可达";
        }
        if(Typenum==11){
            Type="时间超过";
        }
        if(Typenum==12){
           Type="参数问题";
        }
        if(Typenum==5){
            Type="改变路由";
        }
        if(Typenum==8||Typenum==0){
            Type="回送请求或回答";
        }
        if(Typenum==13||Typenum==14){
            Type="时间戳请求或回答";
        }

        code=new String(icmpArr,8,16-8,"UTF-8");
        //System.out.println(code);

        byte[]checksum=Arrays.copyOfRange(icmpArr,16,32);
        Checksum=binaryToDecimalish(checksum);
        //System.out.println("校验和:"+Checksum);

    }
}

·TCP 协议分析:

package agreement;

import java.util.Arrays;

import static binaryToDecimalism.BinaryToDecimalish.binaryToDecimalish;

public class TCP {
    public static int sourcePort;
    public static int destinationPort;
    public static int serialNumber;
    public static int confirmationNumber;
    public static int windowSize;
    public static void tcp(byte[]bytes) {
        byte[]source= Arrays.copyOfRange(bytes,0,16);
        sourcePort=binaryToDecimalish(source);
        //System.out.println("源端口:"+sourcePort);

        byte[]destination=Arrays.copyOfRange(bytes,16,32);
        destinationPort=binaryToDecimalish(destination);
        //System.out.println("目的端口:"+destinationPort);

        byte[] serial=Arrays.copyOfRange(bytes,32,64);
        serialNumber=binaryToDecimalish(serial);
        //System.out.println("序号:"+serialNumber);

        byte[]confirmation=Arrays.copyOfRange(bytes,64,96);
        confirmationNumber=binaryToDecimalish(confirmation);
        //System.out.println("确认号:"+confirmationNumber);

        byte[]window=Arrays.copyOfRange(bytes,112,128);
        windowSize=binaryToDecimalish(window);
        //System.out.println("窗口大小:"+windowSize);

    }
}

·UDP 协议分析:

package agreement;

import java.util.Arrays;

import static binaryToDecimalism.BinaryToDecimalish.binaryToDecimalish;

public class UDP{
public static int sourcePort;
public static int destinationPort;
public static int Length;
public static int Checksum;
public static void udp(byte[]udparr){
byte[]sourceport=Arrays.copyOfRange(udparr,0,16);
sourcePort=binaryToDecimalish(sourceport);
//System.out.println("源端口:"+udpsourcePort);

byte[]destinationport=Arrays.copyOfRange(udparr,16,32);
destinationPort=binaryToDecimalish(destinationport);
//System.out.println("目的端口:"+udpdestinationPort);

byte[]length=Arrays.copyOfRange(udparr,32,48);
Length=binaryToDecimalish(length);
//System.out.println("长度:"+udpLength);

byte[]checksum=Arrays.copyOfRange(udparr,48,64);
Checksum=binaryToDecimalish(checksum);
//System.out.println("校验和:"+udpChecksum);
}
}

·网页界面设计:

<%@page import="agreement.Packages"%>
<%@page import="java.util.List"%><%--
Created by IntelliJ IDEA.
User:sangzhan
Date:2019-12-25
Time:16:36
To change this template use File|Settings|File Templates.
--%>
<%@page contentType="text/html;charset=UTF-8"language="java"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎使用KingShark</title>
</head>

<body>
<center>
<h1>WireShark Pro</h1>
</center>

<table width="100%"border="1">
<tr>
<th>versions</th>
<th>Source</th>
<th>destination</th>
<th>Protocol</th>
<th>Length</th>
<th>start analyze</th>
</tr>
<%List<Packages>list=(List<Packages>)request.getAttribute("list");%>
<%for(Packages items:list){%>
<tr>
<td><%=items.ipversions%></td>
<td><%=items.ipsourceaddress%></td>
<td><%=items.ipdestinationaddress%></td>
<td><%=items.ipagreement%></td>
<td><%=items.Length%></td>
<td><button onclick="particularAnalyst()">详细分析</button></td>
<script>
function particularAnalyst(){
alert("IP协议分析:\n\n版本:<%=items.ipversions%>\n首部长度:<%=items.ipheadLength%>\n总长度:"
+"<%=items.iptotalLength%>\n标识:<%=items.ipidentificationNumber%>\n标志:<%=items.ipsignnumber%>"
+"\n片偏移:<%=items.ipSliceOffsetNUmber%>\n协议:<%=items.ipagreement%>\n首部校验和:<%=items.ipheadCheckSum%>"
+"\n源地址:<%=items.ipsourceaddress%>\n目的地址:<%=items.ipdestinationaddress%>");

<%if(items.ipagreement=="TCP"){%>

alert("TCP协议分析:\n源端口:<%=items.tcpsourcePort%>\n目的端口:<%=items.tcpdestinationPort%>\n序号:"
+"<%=items.tcpserialNumber%>\n确认号:<%=items.tcpconfirmationNumber%>\n窗口大小:<%=items.tcpwindowSize%>");
<%}%>
<%if(items.ipagreement=="ICMP"){%>

alert("ICMP协议分析:\n\n类型:<%=items.icmpType%>\n代码:<%=items.icmpcode%>\n校验和:<%=items.icmpChecksum%>");
<%}%>
<%if(items.ipagreement=="UDP"){%>

alert("UDP协议分析:\n\n源端口:<%=items.udpsourcePort%>\n目的端口:<%=items.udpdestinationPort%>"
+"\n长度:<%=items.udpLength%>\n校验和:<%=items.udpChecksum%>");
<%}%>
alert("数据包:<%=items.response%>");

}
</script>
<%}%>
</tr>

</table>
</body>
</html>

7.2 其他需要说明的内容

本次网络数据捕获和协议分析软件在实际应用中还有一定的局限性,由于对于 Linux 操作系统还是没有 Windows 熟悉,所以本次在 Linux 下面实现抓包选择了引入第三方函数库 libcap,在以后的优化过程中,我将会进行手动编写抓包函数,彻底理解抓包的底层实现。此外,由于对于进程的把控不足,所以导致前期的尝试过多,影响了项目的完成时间,接下来我将会深入网络编程,继续完善一个进程抓包,一个进程分析的双进程服务器。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
包括源程序和详细的使用说明个,同时内付相关的软件 编程环境: 操作系统:Windows XP SP2 开发语言:C++ / MFC 编译环境:MS Visual C++6.0 第3方函数库:Winpcap3.1 使用说明: 1. 启动: 程序启动后首先出现网卡选择对话框,如图1所示,在设备列表中选择需要进行捕获的网卡。 2. 界面: 选择网卡后出现程序主界面,界面设计主要参照了一款比较优秀的网络协议分析工具Iris的图形化界面,采用切分窗口风格,整个程序界面分为三部分:左侧为树形视图,右侧上半部分为列表视图,右侧下半部分为编辑视图 3. 功能: 1) 如果不做任何设置,程序默认为混杂模式,点击按钮① 后,程序开始捕获网络上传输的所有数据包,并将它们显示在列表视图中。点击按钮② 停止捕获。 2) 点击列表视图中的某一行后,对应于该数据包的详细字段分析和原始数据将分别显示在左侧树形视图和右下的编辑视图中,如图2所示。 3) 列表视图中显示的最大数据包数量为2000条,超过后列表视图将清空并重新开始。另外程序还提供了在任意时刻清空当前列表视图中所有数据包的命令(提供该命令的原因是经常会有这样的情况:即列表视图中已经有了很多消息了,但目前只需要关注从即刻起之后到来的消息,这时以前的消息就不再有用并且会影响我们对所要消息的选择)。要使用该命令请在列表视图中任意位置单击鼠标右键,在弹出的菜单中选择“全部清空”
### 回答1: 在Linux下配置Vim,可以按照以下步骤进行: 1. 安装Vim:在终端中输入命令sudo apt-get install vim,即可安装Vim。 2. 配置Vim:在终端中输入命令vim ~/.vimrc,即可打开Vim的配置文件。在该文件中可以设置Vim的各种参数,如设置行号、设置自动缩进、设置颜色等。 3. 安装插件:Vim支持插件,可以通过安装插件来增强其功能。常用的插件有Vundle、Pathogen、NERDTree等。安装插件的方法可以参考插件的官方文档。 4. 配置快捷键:Vim的快捷键非常多,可以根据自己的习惯进行配置。在配置文件中可以设置自定义快捷键,如设置Ctrl+S为保存文件、设置Ctrl+Z为撤销等。 5. 学习VimVim是一款非常强大的文本编辑器,但也有一定的学习曲线。建议初学者可以通过在线教程或者书籍来学习Vim的使用方法。 ### 回答2: 在Linux操作系统中,vim是一款非常强大的文本编辑器。在没有进行任何配置的情况下,vim可能并不能满足我们的需求。因此,在使用vim的时候,我们需要对其进行适当的配置,以便让其更好地满足我们的需求。 一般来说,vim的配置需要在~/.vimrc文件中进行。下面是几个常见的配置项: 1. 显示行号:在编辑大型文件时,行号是非常重要的。我们可以在~/.vimrc文件中加上一行代码,让vim显示行号。具体的代码为: set number 2. 显示括号匹配:对于编写大型程序而言,括号匹配是非常重要的。我们可以让vim在括号匹配时高亮显示,方便我们快速找到匹配的括号。在~/.vimrc文件中加上如下代码即可: set showmatch 3. 显示空格和Tab:在编辑文本时,空格和Tab是非常重要的。我们可以让vim在编辑时显示空格和Tab,方便我们进行调整。具体的方法如下: set listchars=tab:→\ ,trail:• 4. 设置缩进:在编写程序时,缩进是非常重要的。我们可以使用如下代码对缩进进行配置: set shiftwidth=4 其中,4表示缩进的空格数。 5. 设置自动换行:在编辑文本文件时,如果一行太长,就会使得编辑器的界面变得很繁琐。我们可以设置自动换行,使得文本自动分行显示。具体的方法如下: set wrap 以上是一些常用的vim配置项。当然,在实际使用中,我们也可以根据自己的需要进行一些其他的配置。总之,对于使用vim的用户来说,良好的配置是非常必要的,因为只有这样才能让vim更好地满足我们的需求。 ### 回答3: Vim是一个强大的文本编辑器,在Linux系统中广泛使用。对于Vim的使用者来说,对Vim进行一些配置是必不可少的。让我们来看看如何在Linux下配置Vim。 首先,为了方便日常操作,我们应该让Vim自动保存当前的编辑进度。这样可以节省不少时间,将以下配置加入vimrc文件即可: set autowrite 接下来是缩进,通常我们需要缩进来提高代码的可读性。常用的缩进方式是Tab或者空格。在Vim中,有一些选项可以控制缩进方式,如下所示: set tabstop=4 set expandtab set shiftwidth=4 以上选项分别表示Tab键的缩进空格数、将Tab转换为空格、缩进的宽度。我们可以根据自己的喜好来进行设置。 接下来是颜色主题。颜色主题是用于区分代码不同状态、不同模块、不同注释等等的。我们可以下载自己喜欢的颜色主题,引入vimrc中,如下所示: colorscheme dracula 更多的颜色主题可以在GitHub上查找 https://github.com/topics/vim-colorscheme 很多人在使用Vim写代码时会常常需要查找某个字符串或者将某个字符串替换为其他字符串。使用Vim的搜索和替换功能可以方便我们的日常工作,如下所示: set incsearch set hlsearch set smartcase 以上选项分别表示增量搜索,高亮搜索结果,智能大小写搜索的开启。这样我们就可以更加方便地查找和替换字符串了。 以上就是Vim配置的主要选项,当然还有其他更多的选项可以进行配置。希望本文可以帮助到大家。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值