import java.util.Scanner;

public class IPHeaderAnalyzer {

public static void main(String[] args) {
    System.out.println('请输入一串IP数据包头:');
    System.out.println();

    Scanner sc = new Scanner(System.in);
    String packet = sc.nextLine().replace(' ', '');
    sc.close();

    analyzeIPHeader(packet);
}

public static void analyzeIPHeader(String packet) {
    // 版本号:取字符串的第一个字符,并将其转换为十进制数。
    int version = Integer.parseInt(packet.substring(0, 1), 16);
    // 包头长度:取字符串的第二个字符(表示包头长度的四分之一),并将其乘以4得到包头长度的字节数。
    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');
    }

    // 优先权:取字符串的第三个字符的二进制表示的前3位,并将其转换为十进制数。
    int priority = Integer.parseInt(tmp.substring(0, 3), 2);
    // TOS:根据优先权的值确定TOS的具体含义。
    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');
    }
    // 是否分片:根据标志位的第二位判断是否分片。
    String section = tmp.charAt(1) == '0' ? '可以分片' : '不能分片';
    // 包属于:根据标志位的第三位判断包属于哪个分片
    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 (ProtocolType 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.valueOf(version));
    System.out.println();

    println('包头长度:');
    println(String.valueOf(headerLength));
    System.out.println();

    println('优先权:');
    println(String.valueOf(priority));
    System.out.println();

    println('TOS:');
    println(TOS);
    System.out.println();

    println('包总长:');
    println(String.valueOf(packetLength));
    System.out.println();

    println('标志位:');
    println(String.valueOf(identification));
    System.out.println();

    println('分片:');
    println(section);
    System.out.println();

    println('包属性:');
    println(property);
    System.out.println();

    println('分段偏移:');
    println(fragmentOffset);
    System.out.println();

    println('TTL:');
    println(String.valueOf(ttl));
    System.out.println();

    println('协议号:');
    println(protocolCode + '(' + protocol + ')');
    System.out.println();

    println('头部校验和:');
    println(checkSum);
    System.out.println();

    println('原始地址:');
    println(sourceAddress[0] + '.' + sourceAddress[1] + '.' + sourceAddress[2] + '.' + sourceAddress[3]);
    System.out.println();

    println('目标地址:');
    println(targetAddress[0] + '.' + targetAddress[1] + '.' + targetAddress[2] + '.' + targetAddress[3]);
    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 value;

    ProtocolType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

}

Java IP 数据包头分析器 - 解读网络数据

原文地址: https://www.cveoy.top/t/topic/d82q 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录