简体   繁体   English

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

[英]What is the correct way to convert my IP Packet data into a String?

When I receive an IP Packet with my Android VpnService I read the headers first ( as here ), then I try to print the received data as follows: 当我使用Android VpnService收到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")));
}

This results in out put like the following: 结果如下所示:

Packet-Data: 5 ( www google com 封包数据: 5 ( wwwwww.google.com

Or another example from unencrypted webpage: 或来自未加密网页的另一个示例:

Packet: IP Version=4, Header-Length=20, Total-Length=60, Destination-IP=xx.xx.xxx.xx, Hostname=yyyyy.zzz, Source-IP=10.1.10.1, Protocol=17, Data-Remaining=40 数据包:IP版本= 4,报头长度= 20,总长度= 60,目标IP = xx.xx.xxx.xx,主机名= yyyyy.zzz,源IP = 10.1.10.1,协议= 17,数据-Remaining = 40

Packet-Data: N 5 (@ F m postimees ee 分组数据:N 5 (@ F m postimees ee

I've tried with a couple of different String encoding types, I don't think it is the issue. 我尝试了几种不同的String编码类型,我认为这不是问题。

What step am I missing? 我想走哪一步?

I've solved this myself. 我自己解决了。 The answers I needed were on this article about handwriting DNS packets and the UDP protocol in addition to the UDP headers as discussed here . 我需要的答案都在这篇文章中关于笔迹DNS数据包和UDP协议 ,除了UDP报头为这里讨论

The problem was that the data as parsed above still contained UDP and DNS headers, we had only parsed the application layer headers 问题是上面解析的数据仍然包含UDP和DNS标头,我们只分析了应用层标头

The following code will read DNS Domain from a DNS packet 以下代码将从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);

And produce output something like this: 并产生如下输出:

Headers: 头:
IP Version=4 IP版本= 4
Header-Length=20 报头长度= 20
Total-Length=59 总长度= 59
Destination=88.88.888.88 / dns.mydns.net 目的地= 88.88.888.88 / dns.mydns.net
Source-IP=10.1.10.1 源IP = 10.1.10.1
Protocol=17 协议= 17
Source-Port=44444 源端口= 44444
DestPortUdp=53 DestPortUdp = 53
QName=www.google.com QName的= www.google.com
Remaining-Data: null //for sanity 剩余数据:null //出于理智

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 编写此IP阀的正确方法是什么? - What's the correct way to write this IP valve? 在 Java 中广播 UDP 数据包的正确且有效的方法是什么? - What's the correct and working way to broadcast an UDP packet in Java? 解析数据字符串的正确方法 - Correct way to parse a String of data 将任何原始数据类型转换为字符串的最佳方法是什么 - What is the best way to convert any primitive data type to string 使用任何主机的 IP 地址构造 InetSocketAddress 的正确方法是什么? - What is the correct way to construct InetSocketAddress with any host an IP address? 匹配包含“{}”的字符串。 什么是正确的方法? - Matching string that contains “{}”. What is the correct way? 将数据传递到正在运行的线程的正确方法是什么 - What is the correct way to pass data to a running thread 在 Firestore 中构建此类数据的正确方法是什么? - What is the correct way to structure this kind of data in Firestore? 进行while循环的正确方法是什么? 我的方式不起作用 - What is the correct way to make a while loop?? my way is not working 将Shape转换为Rectangle2D.Double的正确方法是什么? - What is the correct way to convert a Shape to a Rectangle2D.Double?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM