【开源】计算机网络课设-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]