#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;

}


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

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