繁体   English   中英

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

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

当我使用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")));
}

结果如下所示:

封包数据: 5 ( wwwwww.google.com

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

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

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

我尝试了几种不同的String编码类型,我认为这不是问题。

我想走哪一步?

我自己解决了。 我需要的答案都在这篇文章中关于笔迹DNS数据包和UDP协议 ,除了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);

并产生如下输出:

头:
IP版本= 4
报头长度= 20
总长度= 59
目的地= 88.88.888.88 / dns.mydns.net
源IP = 10.1.10.1
协议= 17
源端口= 44444
DestPortUdp = 53
QName的= www.google.com
剩余数据:null //出于理智

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM