落叶 发表于 2020-6-17 01:34:17

【开源】计算机网络课设-IP数据包头分析

本文内容版权归本人所有,任何人或团体、机构全部转载或者部分转载、摘录,请保留本博客链接或标注来源!
题目要求:      设计一个模拟分析IP数据报头的程序内容要求:      随意输入IP数据报头(二进制形式,20字节),分析该报头各字段的值,并以点分十进制表示输出源地址和目的地址。
时间要求:
6月16日布置题目,确定任务、查找相关资料
6月17日~6月19日功能分析,软件总体设计,拟定详细设计,编写程序,调试程序、运行系统;
6月19日~6月19日答辩后撰写设计报告。


      那么,开始写程序之前自然要准备一下相关数据了,我们来看看IP数据包头的结构如何:

static/image/hrline/4.gif4bits:      ip版本号4bits:      ip报头长度,4个字节为一个单位8bits:      ip数据报服务类型,PPPDTRUU                        PPP:    数据报优先级,很少使用                        D:      0一般延迟,1低延迟                        T:      0一般传输量,1高传输量                        R:      0一般可靠度,1高可靠度                        UU :   保留,尚未被使用       16bits:      ip数据报总长度,包括头部和数据部分,就是总的ip数据报长度,包括被分割的ip数据报16bits:      ip数据报识别码,标记多个被分割的小的ip数据报来自同一个大的ip数据报3bits:      特殊标志,分割or不分割数据报使用,0DM                        D:       0可以分段,1不可分段                        M:       0此ip为最后分段,1此ip为非最后分段13bits:      分段偏移,表示此ip分段,在整个ip数据报中所占的位置8bits:      该数据报的生存时间,0~255,每通过1个路由器,减1,为0时,将被抛弃8bits:      协议代码,ip数据报内数据的种类                        1:ICMP                        2:IGMP                        3:GGP                        4:IP                        6:TCP                        8:EGP                        17:UDP16bits:      报头效验码,检查报头错误32bits:      来源的ip,即发送方的ip32bits:      目标的ip,即接收方的ip32bits:      其他参数+补齐项目。其他参数不足32bits,自动补齐static/image/hrline/4.gif
      好了,结构到手,那程序就简单了! 如下为运行结果截图:
      那么,上代码!
package com.company;

import java.util.Scanner;

public class Main {

      public static void main(String[] args) {
                //45 00 00 2e 13 23 00 00 80 11 5c 99 c0 a8 01 65 3b 37 cd be
               
                System.out.println("请输入一串IP数据包头:");
                System.out.println();

                Scanner sc = new Scanner(System.in);
                String packet = sc.nextLine().replace(" ", "");
                sc.close();
                //得到所有位数据


                //版本号
                final int version = Integer.parseInt(packet.substring(0, 1), 16);
                //包头长度
                final int headerLength = Integer.parseInt(packet.substring(1, 2), 16) * 4;

                StringBuilder tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(2, 4), 16)));
                int len = tmp.length();
                for (int i = 0; i < 8 - len; i++) tmp.insert(0, "0");

                //优先权
                final int priority = Integer.parseInt(tmp.substring(0, 3), 2);
                //最小延时、高吞吐量、最高可靠性、低成本(全为0为普通包,否则只能有一个为1)
                final String TOS;
                if (tmp.charAt(3) == '1') TOS = "最小延迟";
                else if (tmp.charAt(4) == '1') TOS = "最大吞吐量";
                else if (tmp.charAt(5) == '1') TOS = "最高可靠性";
                else if (tmp.charAt(6) == '1') TOS = "低成本";
                else TOS = "一般服务";
                //未使用位
                //IP数据报文总长(包含头部和数据)
                int packetLength = Integer.parseInt(packet.substring(4, 8), 16);
                //标志位(让主机判断这个包属于哪个分组)
                int identification = Integer.parseInt(packet.substring(8, 12), 16);

                tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(12, 16), 16)));
                len = tmp.length();
                for (int i = 0; i < 16 - len; i++) tmp.insert(0, "0");
                //未使用, 必须为0
                //是否分片 0:可以 1:不可以
                String section = tmp.charAt(1) == '0' ? "可以分片" : "不能分片";
                //如果分片, 包属于 0:最后一个分片的包 1:分片中段的包
                String property = tmp.charAt(2) == '0' ? "最后一个分片的包" : "分片中段的包";
                //分段偏移
                String fragmentOffset = tmp.substring(3, 16);

                //TTL值
                int ttl = Integer.parseInt(packet.substring(16, 18), 16);
                //协议号
                int protocolCode = Integer.parseInt(packet.substring(18, 20), 16);
                String protocol = "未知";
                for (var val : protocolType.values()) {
                        if (val.getValue() == protocolCode)
                              protocol = val.name();
                }

                tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(20, 24), 16)));
                len = tmp.length();
                for (int i = 0; i < 16 - len; i++) tmp.insert(0, "0");
                //头部校验和
                String checkSum = tmp.toString();
                //原始地址
                int[] sourceAddress = {
                              Integer.parseInt(packet.substring(24, 26), 16),
                              Integer.parseInt(packet.substring(26, 28), 16),
                              Integer.parseInt(packet.substring(28, 30), 16),
                              Integer.parseInt(packet.substring(30, 32), 16)
                };
                //目标地址
                int[] targetAddress = {
                              Integer.parseInt(packet.substring(32, 34), 16),
                              Integer.parseInt(packet.substring(34, 36), 16),
                              Integer.parseInt(packet.substring(36, 38), 16),
                              Integer.parseInt(packet.substring(38, 40), 16)
                };

                //输出包信息
                println("版本号:");
                println(String.format("%d", version));
                System.out.println();

                println("包头长度:");
                println(String.format("%d", headerLength));
                System.out.println();

                println("优先权:");
                println(String.format("%d", priority));
                System.out.println();

                println("TOS:");
                println(String.format("%s", TOS));
                System.out.println();

                println("包总长:");
                println(String.format("%d", packetLength));
                System.out.println();

                println("标志位:");
                println(String.format("%d", identification));
                System.out.println();

                println("分片:");
                println(String.format("%s", section));
                System.out.println();

                println("包属性:");
                println(String.format("%s", property));
                System.out.println();

                println("分段偏移:");
                println(String.format("%s", fragmentOffset));
                System.out.println();

                println("TTL:");
                println(String.format("%d", ttl));
                System.out.println();

                println("协议号:");
                println(String.format("%d(%s)", protocolCode, protocol));
                System.out.println();

                println("头部校验和:");
                println(String.format("%s", checkSum));
                System.out.println();

                println("原始地址:");
                println(String.format("%d.%d.%d.%d", sourceAddress, sourceAddress, sourceAddress, sourceAddress));
                System.out.println();

                println("目标地址:");
                println(String.format("%d.%d.%d.%d", targetAddress, targetAddress, targetAddress, targetAddress));
                System.out.println();
      }


      static void println(String msg) {
                System.out.printf("%-15s", msg);
      }

      enum protocolType {
                ICMP(1),
                IGMP(2),
                TCP(6),
                UDP(17);

                private final int index;

                protocolType(int index) {
                        this.index = index;
                }

                public int getValue() {
                        return index;
                }
      }
}
Felix2020年6月17日 1:35
页: [1]
查看完整版本: 【开源】计算机网络课设-IP数据包头分析