Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将IP数据包转换为字符串的正确方法是什么?_Java_Android_Udp_Ip_Android Vpn Service - Fatal编程技术网

Java 将IP数据包转换为字符串的正确方法是什么?

Java 将IP数据包转换为字符串的正确方法是什么?,java,android,udp,ip,android-vpn-service,Java,Android,Udp,Ip,Android Vpn Service,当我用Android接收到IP数据包时,我首先读取头(),然后尝试按如下方式打印接收到的数据: int lengthRemaining = packet.remaining(); if (lengthRemaining > 0) { byte[] data = new byte[lengthRemaining]; packet.get(data, packet.arrayOffset(), lengthRemaining); Log.d(TAG, "Packet-D

当我用Android接收到IP数据包时,我首先读取头(),然后尝试按如下方式打印接收到的数据:

int lengthRemaining = packet.remaining();
if (lengthRemaining > 0) {
    byte[] data = new byte[lengthRemaining];
    packet.get(data, packet.arrayOffset(), lengthRemaining);
    Log.d(TAG, "Packet-Data: " + new String(data, Charset.forName("UTF-8")));
}
这会产生如下结果:

数据包数据:����5.��(��������������������万维网�谷歌�通用域名格式������

或来自未加密网页的另一个示例:

数据包:IP版本=4,头长度=20,总长度=60,目标IP=xx.xx.xxx.xx,主机名=yyyy.zzz,源IP=10.1.10.1,协议=17,剩余数据=40

分组数据:N���5.��(@�F�����������������M�波斯蒂米斯�ee������

我尝试过几种不同的字符串编码类型,我认为这不是问题所在


我遗漏了哪一步?

我自己已经解决了这个问题。我需要的答案是关于手写DNS数据包以及UDP头

问题是上面解析的数据仍然包含UDP和DNS头,我们只解析了应用层头

以下代码将从DNS数据包中读取DNS域

int buffer = packet.get();
int ipVersion = buffer >> 4;
int headerLength = buffer & 0x0F;   //the number of 32 bit words in the header
headerLength *= 4;
packet.get();                       //DSCP + EN
int totalLength = packet.getChar(); //Total Length
packet.getChar();                   //Identification
packet.getChar();                   //Flags + Fragment Offset
packet.get();                       //Time to Live
int protocol = packet.get();        //Protocol
packet.getChar();                   //Header checksum

String sourceIP  = "";
sourceIP += packet.get() & 0xFF; //Source IP 1st Octet
sourceIP += ".";
sourceIP += packet.get() & 0xFF; //Source IP 2nd Octet
sourceIP += ".";
sourceIP += packet.get() & 0xFF; //Source IP 3rd Octet
sourceIP += ".";
sourceIP += packet.get() & 0xFF; //Source IP 4th Octet

String destIP  = "";
destIP += packet.get() & 0xFF; //Destination IP 1st Octet
destIP += ".";
destIP += packet.get() & 0xFF; //Destination IP 2nd Octet
destIP += ".";
destIP += packet.get() & 0xFF; //Destination IP 3rd Octet
destIP += ".";
destIP += packet.get() & 0xFF; //Destination IP 4th Octet

//NOTE: RFC diagram showed a byte of zeroes here, but it doesn't appear to match the implementation
//int supposedZeroes = packet.get();
//Log.d(TAG, "Supposed Zeroes: " + supposedZeroes);

int sourcePortUdp = packet.getChar();
int destPortUdp = packet.getChar();
packet.getChar(); //UDP Data Length
packet.getChar(); //UDP Checksum
//NOTE: DNS HEADERS INSIDE UDP DATA - https://routley.io/tech/2017/12/28/hand-writing-dns-messages.html
packet.getChar(); //DNS ID
packet.get(); //OPTIONS: QR + OPCODE + AA + TC + RD
packet.get(); //OPTIONS: Z + RCODE
packet.getChar(); //DNS QDCOUNT //number of entities/questions
packet.getChar(); //DNS ANCOUNT //num answers
packet.getChar(); //DNS NSCOUNT //num auth records
packet.getChar(); //DNS ARCOUNT //num additional records
//NOTE: QNAME is url encoded, in several separated sections, each preceded by an int saying the number of bytes
//NOTE: The QNAME section is terminated with a zero byte (00).
int qnameSectionByteCount = packet.get();
byte[] qnameBytes = new byte[0];
byte[] qnameSectionBytes;
int oldLength;
while (qnameSectionByteCount > 0 && qnameSectionByteCount <= packet.remaining()) {
    qnameSectionBytes = new byte[qnameSectionByteCount];
    packet.get(qnameSectionBytes);
    //insert the bytes from the new section
    oldLength = qnameBytes.length;
    qnameBytes = Arrays.copyOf(qnameBytes, oldLength + qnameSectionBytes.length);
    System.arraycopy(qnameSectionBytes, 0, qnameBytes, oldLength, qnameSectionBytes.length);
    //get the byte that determines if there is another loop iteration
    qnameSectionByteCount = packet.get();
    //add a connecting dot if there will be another loop iteration
    if (qnameSectionByteCount > 0) {
        //add a dot
        byte[] dot = ".".getBytes();
        oldLength = qnameBytes.length;
        qnameBytes = Arrays.copyOf(qnameBytes, oldLength + dot.length);
        System.arraycopy(dot, 0, qnameBytes, oldLength, dot.length);
    }
}
packet.getChar(); //QCLASS
packet.getChar(); //QCLASS

String destHostName;
try {
    InetAddress addr = InetAddress.getByName(destIP);
    destHostName = addr.getHostName();
} catch (UnknownHostException e) {
    destHostName = "Unresolved";
}

int orphanDataLength = packet.remaining();
String dataStr = null;
if (orphanDataLength > 0) {
    byte[] data = new byte[orphanDataLength];
    packet.get(data, packet.arrayOffset(), orphanDataLength);
    dataStr = new String(data, Charset.forName("UTF-8"));
}

Log.v(TAG, "---\nHeaders:\nIP Version=" + ipVersion + "\nHeader-Length=" + headerLength
        + "\nTotal-Length=" + totalLength + "\nDestination=" + destIP + " / "
        + destHostName + "\nSource-IP=" + sourceIP + "\nProtocol=" + protocol
        + "\nSource-Port=" + sourcePortUdp + "\nDestPortUdp=" + destPortUdp + "\nQname="
        + new String(qnameBytes, Charset.forName("UTF-8")) + "\nRemaining-Data: " + dataStr);
int buffer=packet.get();
int ipVersion=缓冲区>>4;
int headerLength=buffer&0x0F;//头中的32位字数
车头长度*=4;
packet.get();//DSCP+EN
int totalLength=packet.getChar();//总长度
packet.getChar();//标识
packet.getChar();//标志+片段偏移量
packet.get();//生存时间
int protocol=packet.get();//协议
packet.getChar();//头校验和
字符串sourceIP=“”;
sourceIP+=packet.get()&0xFF;//源IP第一个八位字节
sourceIP+=”;
sourceIP+=packet.get()&0xFF;//源IP第二个八位字节
sourceIP+=”;
sourceIP+=packet.get()&0xFF;//源IP第三个八位字节
sourceIP+=”;
sourceIP+=packet.get()&0xFF;//源IP第四个八位字节
字符串destp=“”;
destp+=packet.get()&0xFF;//目标IP第一个八位字节
destp+=”;
destp+=packet.get()&0xFF;//目标IP第二个八位字节
destp+=”;
destp+=packet.get()&0xFF;//目标IP第三个八位字节
destp+=”;
destp+=packet.get()&0xFF;//目标IP第四个八位字节
//注意:RFC图在这里显示了一个字节的零,但它似乎与实现不匹配
//int-EssentialdZeroes=packet.get();
//Log.d(标签,“假定零:“+假定零”);
int sourcePortUdp=packet.getChar();
int destPortUdp=packet.getChar();
packet.getChar();//UDP数据长度
packet.getChar();//UDP校验和
//注意:UDP数据内的DNS标头-https://routley.io/tech/2017/12/28/hand-writing-dns-messages.html
packet.getChar();//DNS ID
packet.get();//选项:QR+OPCODE+AA+TC+RD
packet.get();//选项:Z+RCODE
packet.getChar();//DNS QDCOUNT//实体数/问题数
packet.getChar();//DNS ANCOUNT//num answers
packet.getChar();//DNS NSCOUNT//num auth记录
packet.getChar();//DNS ARCOUNT//num其他记录
//注意:QNAME是url编码的,在几个单独的部分中,每个部分前面都有一个表示字节数的int
//注意:QNAME部分以零字节(00)结尾。
int qnameSectionByteCount=packet.get();
字节[]qnameBytes=新字节[0];
字节[]qnameSectionBytes;
整数长度;
而(qnameSectionByteCount>0&&qnameSectionByteCount 0){
//加点
byte[]点=“.”.getBytes();
oldLength=qnameBytes.length;
qnameBytes=Arrays.copyOf(qnameBytes,oldLength+dot.length);
System.arraycopy(点,0,qnameBytes,oldLength,点长度);
}
}
packet.getChar();//QCLASS
packet.getChar();//QCLASS
字符串主机名;
试一试{
InetAddress addr=InetAddress.getByName(destp);
destHostName=addr.getHostName();
}捕获(未知后异常e){
destHostName=“未解决”;
}
int-OrphandDataLength=packet.remaining();
字符串dataStr=null;
如果(数据长度>0){
字节[]数据=新字节[DataLength];
packet.get(数据,packet.arrayOffset(),OrphandDataLength);
dataStr=新字符串(数据,Charset.forName(“UTF-8”);
}
Log.v(标记“---\n标题:\nIP Version=“+ipVersion+”\n标题长度=“+headerLength
+“\n总长度=“+totalLength+”\n目标=“+Destinp+”/”
+destHostName+“\n源IP=“+sourceIP+”\n协议=“+协议
+“\n源端口=“+sourcePortUdp+”\nDestPortUdp=“+destPortUdp+”\nQname=”
+新字符串(qnameBytes,Charset.forName(“UTF-8”))+“\n保留数据:“+dataStr”;
并产生如下输出:

标题:
IP版本=4
标题长度=20
总长度=59
目的地=88.88.888.88/dns.mydns.net
源IP=10.1.10.1
协议=17
源端口=44444
DestPortUdp=53
QName=www.google.com
剩余数据:空//表示正常