IP数据包头解析工具 - 在线分析 IP 数据包头信息
IP 数据包头解析工具
本工具可以帮助您解析 IP 数据包头信息,并以易于理解的方式展示关键参数。
输入 IP 数据包头
请输入您想要分析的 IP 数据包头,例如:
45 00 00 2e 13 23 00 00 80 11 5c 99 c0 a8 01 65 3b 37 cd be
解析结果
版本号: 4 包头长度: 20 字节 优先权: 0 TOS: 一般服务 包总长: 584 字节 标志位: 3523 分片: 可以分片 包属性: 最后一个分片的包 分段偏移: 0 TTL: 1 协议号: 6 (TCP) 头部校验和: 80115c99c0a8 原始地址: 192.168.1.101 目标地址: 59.193.190.230
代码实现
Java 代码
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[0], sourceAddress[1], sourceAddress[2], sourceAddress[3]));
System.out.println();
println('目标地址:');
println(String.format('%d.%d.%d.%d', 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 index;
protocolType(int index) {
this.index = index;
}
public int getValue() {
return index;
}
}
}
C 代码
#include <stdio.h>
#include <string.h>
typedef enum {
ICMP = 1,
IGMP = 2,
TCP = 6,
UDP = 17
} ProtocolType;
void println(const char* msg) {
printf('%-15s', msg);
}
int main() {
//45 00 00 2e 13 23 00 00 80 11 5c 99 c0 a8 01 65 3b 37 cd be
printf('请输入一串IP数据包头:\n\n');
char packet[40];
scanf('%s', packet);
//去除空格
for (int i = 0, j = 0; i < strlen(packet); i++) {
if (packet[i] != ' ') {
packet[j++] = packet[i];
}
}
packet[strlen(packet)] = '\0';
//版本号
const int version = packet[0] - '0';
//包头长度
const int headerLength = (packet[1] - '0') * 4;
//优先权
const int priority = (packet[2] - '0') >> 5;
//最小延时、高吞吐量、最高可靠性、低成本(全为0为普通包,否则只能有一个为1)
const char* TOS;
switch ((packet[2] - '0') & 0x1F) {
case 0:
TOS = '一般服务';
break;
case 1:
TOS = '最小延迟';
break;
case 2:
TOS = '最大吞吐量';
break;
case 4:
TOS = '最高可靠性';
break;
case 8:
TOS = '低成本';
break;
default:
TOS = '未知';
break;
}
//未使用位
//IP数据报文总长(包含头部和数据)
int packetLength = (packet[4] - '0') * 16 * 16 * 16 + (packet[5] - '0') * 16 * 16 + (packet[6] - '0') * 16 + (packet[7] - '0');
//标志位(让主机判断这个包属于哪个分组)
int identification = (packet[8] - '0') * 16 * 16 * 16 + (packet[9] - '0') * 16 * 16 + (packet[10] - '0') * 16 + (packet[11] - '0');
//是否分片 0:可以 1:不可以
const char* section = (packet[12] - '0') & 0x02 ? '不能分片' : '可以分片';
//如果分片, 包属于 0:最后一个分片的包 1:分片中段的包
const char* property = (packet[12] - '0') & 0x04 ? '分片中段的包' : '最后一个分片的包';
//分段偏移
int fragmentOffset = ((packet[12] - '0') & 0x1F) * 16 * 16 + (packet[13] - '0') * 16 + (packet[14] - '0');
//TTL值
int ttl = packet[16] - '0';
//协议号
int protocolCode = packet[18] - '0';
const char* protocol = '未知';
switch (protocolCode) {
case ICMP:
protocol = 'ICMP';
break;
case IGMP:
protocol = 'IGMP';
break;
case TCP:
protocol = 'TCP';
break;
case UDP:
protocol = 'UDP';
break;
}
//头部校验和
char checkSum[17];
strncpy(checkSum, &packet[20], 16);
checkSum[16] = '\0';
//原始地址
int sourceAddress[4];
for (int i = 0; i < 4; i++) {
sourceAddress[i] = (packet[24 + i * 2] - '0') * 16 + (packet[25 + i * 2] - '0');
}
//目标地址
int targetAddress[4];
for (int i = 0; i < 4; i++) {
targetAddress[i] = (packet[32 + i * 2] - '0') * 16 + (packet[33 + i * 2] - '0');
}
//输出包信息
println('版本号:');
println('%d', version);
printf('\n');
println('包头长度:');
println('%d', headerLength);
printf('\n');
println('优先权:');
println('%d', priority);
printf('\n');
println('TOS:');
println('%s', TOS);
printf('\n');
println('包总长:');
println('%d', packetLength);
printf('\n');
println('标志位:');
println('%d', identification);
printf('\n');
println('分片:');
println('%s', section);
printf('\n');
println('包属性:');
println('%s', property);
printf('\n');
println('分段偏移:');
println('%d', fragmentOffset);
printf('\n');
println('TTL:');
println('%d', ttl);
printf('\n');
println('协议号:');
println('%d(%s)', protocolCode, protocol);
printf('\n');
println('头部校验和:');
println('%s', checkSum);
printf('\n');
println('原始地址:');
println('%d.%d.%d.%d', sourceAddress[0], sourceAddress[1], sourceAddress[2], sourceAddress[3]);
printf('\n');
println('目标地址:');
println('%d.%d.%d.%d', targetAddress[0], targetAddress[1], targetAddress[2], targetAddress[3]);
printf('\n');
return 0;
}
注意事项
- 请确保输入的 IP 数据包头信息正确且完整,否则解析结果可能不准确。
- 本工具仅解析 IP 数据包头信息,不解析数据包的有效负载。
- IP 数据包头解析结果仅供参考,具体含义请参考相关网络协议文档。
原文地址: https://www.cveoy.top/t/topic/fkWp 著作权归作者所有。请勿转载和采集!