Skip to content

Commit

Permalink
WiP: txtfile packet dumper + start of tests
Browse files Browse the repository at this point in the history
  • Loading branch information
compscidr committed Aug 8, 2024
1 parent 6fb1d00 commit ad39a47
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.jasonernst.packetdumper.filedumper

import com.jasonernst.packetdumper.EtherType
import com.jasonernst.packetdumper.stringdumper.StringPacketDumper
import org.slf4j.LoggerFactory
import java.io.BufferedWriter
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.time.LocalDateTime
import java.util.concurrent.atomic.AtomicBoolean

/**
* Dumps buffers into hexdump text files that can be imported by wireshark. The format is as follows:
*
* offset(hex) up to 16 bytes of data per line, separated by a space, ending in a newline
* offset(hex) up to 16 bytes of data per line, separated by a space, ending in a newline
*
* offset(hex) up to 16 bytes of data per line, separated by a space, ending in a newline
* offset(hex) up to 16 bytes of data per line, separated by a space, ending in a newline
*
* Each block of offsets is separated by a blank newline, and represents a new packet / dump. When
* the new dump starts, the offset can restart at 0.
*/
class TextFilePacketDumper(private val path: String, private val name: String) : AbstractFilePacketDumper() {
private val logger = LoggerFactory.getLogger(javaClass)
private val stringDumper = StringPacketDumper()

private val isOpen = AtomicBoolean(false)
override lateinit var filename: String
private lateinit var file: File
private lateinit var bufferedWriter: BufferedWriter
private var loggedError = false

override fun open() {
if (isOpen.get()) {
logger.error("Trying to open a file that is already open")
return
}
filename = "$path/${name}_${LocalDateTime.now()}.dump"
file = File(filename)
bufferedWriter = file.bufferedWriter()
logger.debug("TextFilePacketDumper opened file $filename")
isOpen.set(true)
}

override fun close() {
if (!isOpen.get()) {
logger.error("Trying to close a file that is already closed")
return
}
try {
bufferedWriter.flush()
} catch (e: Exception) {
logger.error("Error flushing dump file", e)
}
try {
bufferedWriter.close()
} catch (e: Exception) {
logger.error("Error closing dump file", e)
}
isOpen.set(false)
}

override fun dumpBuffer(
buffer: ByteBuffer,
offset: Int,
length: Int,
addresses: Boolean,
etherType: EtherType?,
) {
if (!isOpen.get()) {
if (!loggedError) {
logger.error("Trying to dump to a file that is not open")
loggedError = true
}
return
}
val output = stringDumper.dumpBufferToString(buffer, offset, length, addresses, etherType)
logger.debug("Intermediary output: $output")
try {
bufferedWriter.write(output)
bufferedWriter.write("\n")
bufferedWriter.flush()
} catch (e: IOException) {
if (!loggedError) {
logger.error("Error writing to dump file", e)
loggedError = true
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.jasonernst.packetdumper.filedumper

import com.jasonernst.packetdumper.EtherType
import com.jasonernst.packetdumper.stringdumper.StringPacketDumper
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.slf4j.LoggerFactory
import java.io.File
import java.nio.ByteBuffer

class TestTextFilePacketDumper {
private val logger = LoggerFactory.getLogger(javaClass)
private val dumper = TextFilePacketDumper("/tmp", "test")

/**
* Dumps a buffer to a file using the dumper, closes the file. Opens it back up and reads the
* buffer back and returns it.
*
* If the addresses flag is true, strip the addresses before returning the buffer.
* If the etherType is not null, strip the dummy ethernet header before returning the buffer.
*
* If either of those two things are present during the write, but not present during the read,
* throw an Exception.
*/
private fun writeReadBuffer(
buffer: ByteBuffer,
addresses: Boolean = false,
etherType: EtherType? = null,
): ByteBuffer {
dumper.dumpBuffer(buffer, 0, buffer.limit(), addresses, etherType)
dumper.close()

// re-open the file
val file = File(dumper.filename)
val fileLines = file.readLines()
val readBuffer = ByteBuffer.wrap(fileLines.joinToString().toByteArray())

if (etherType != null) {
TODO() // need to strip the dummy ethernet header
}

if (addresses) {
TODO() // need to strip them
}

return readBuffer
}

@AfterEach fun tearDown() {
// just in case a test fails, we want to make sure the file is closed
dumper.close()

// delete the file created for the test to cleanup
try {
// File(dumper.filename).delete()
logger.debug("Deleted file ${dumper.filename}")
} catch (e: Exception) {
// ignore
}
}

@Test fun testOpenClose() {
dumper.open()
dumper.close()
}

@Disabled("This is broken atm")
@Test fun testDumpBuffer() {
dumper.open()
val stringDumper = StringPacketDumper()
val buffer = ByteBuffer.wrap("Hello, World!".toByteArray())
logger.debug("write buffer: ${stringDumper.dumpBufferToString(buffer, 0, buffer.limit())}")
val readBuffer = writeReadBuffer(buffer)
logger.debug("read buffer: ${stringDumper.dumpBufferToString(readBuffer, 0, readBuffer.limit())}")
assertEquals(buffer, readBuffer)
}
}

0 comments on commit ad39a47

Please sign in to comment.