1

For some reason I can't understand, when I'm parsing the buffer values, I almost never get the version as 4 (which would be the default for IPv4), and most of the time I get some random value like 10 or 0 instead. The same is true with the protocol, even though it is parsing exactly as it is specified on the wiki, it never comes up precisely with something that says it's TCP or UDP, just 0 (which would map to HOPOPT) or a random value. I believe the parsing is at least correct because when I debug, the source address resolves to the DNS I specified (8.8.4.4), which shouldn't happen if I was parsing the wrong way (at least, it seems to me that no).

val (version, internetHeaderLength) = buffer.get().toUByte().split()

// Differentiated Services Code Point, Explicit Congestion Notification (TOS)
val (dscp, ecn) = buffer.get().toUByte().extract(2)

val totalLength = buffer.short.toUShort()
val identification = buffer.short.toUShort()
val (flags, fragmentOffset) = buffer.short.toUShort().extract(3)
val timeToLive = buffer.get().toUByte()
val protocol = buffer.get().toUByte()
val headerChecksum = buffer.short.toUShort()
val sourceAddress = buffer.int
val destinationAddress = buffer.int
val options = buffer.array().sliceArray(0 until internetHeaderLength.toInt() * 4 - 20)
val data =
    buffer.array().sliceArray(internetHeaderLength.toInt() * 4 until totalLength.toInt())

Below is the code I use to get the packet data

fun receivePackets(input: FileInputStream, output: FileOutputStream, buffer: ByteBuffer) {
    val read = input.read(buffer.array())

    if (read > 0) {
        buffer.limit(read)

        val packet = IpDatagram(buffer)

        Log.d(Tag, "Received packet: $packet which is " +
                if (packet.valid) "valid" else "invalid"
        )

(the code I wrote for handling numbers bits)

fun UShort.getBit(position: Int): Int {
    return (this.toInt() shr position) and 1;
}

fun UShort.setBit(position: Int, value: Int): UShort {
    return (this.toInt() or (value shl position)).toUShort();
}

fun UShort.setBit(position: Int, value: Boolean): UShort {
    return (this.toInt() or ((if (value) 1 else 0) shl position)).toUShort();
}

fun UShort.split(): Pair<UShort, UShort> {
    return Pair((this.toInt() shr 4).toUShort(), (this.toInt() and 0x0F).toUShort());
}

fun UShort.extract(count: Int): Pair<UShort, UShort> {
    return Pair(this.extractFirst(count), this.extractLast(count))
}
fun UShort.extractFirst(count: Int): UShort {
    return (this.toInt() shr count).toUShort();
}
fun UShort.extractLast(count: Int): UShort {
    return (this.toInt() and ((1 shl count) - 1)).toUShort();
}

I've been debugging this for a while, and I've already tried some things like decomposing the numbers that result to try to see if there are any errors in the methods I created to decompose the integers or if they present patterns like 0100 that I want for IPv4 identification.

Example of one packet after being parsed:

{
   "destinationAddress":"95.53.97.33",
   "dscp":9,
   "ecn":0,
   "flags":0,
   "fragmentOffset":0,
   "headerChecksum":0,
   "identification":-384,
   "internetHeaderLength":0,
   "options":[],
   "payload":[96],
   "protocol":"HOPOPT" // 0,
   "sourceAddress":"101.94.226.95",
   "timeToLive":0,
   "totalLength":1,
   "valid":true,
   "version":0
}
DiaDeTedio
  • 31
  • 2

0 Answers0