-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
517 additions
and
54 deletions.
There are no files selected for viewing
3 changes: 0 additions & 3 deletions
3
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/AbstractPcapNgDumper.kt
This file was deleted.
Oops, something went wrong.
40 changes: 36 additions & 4 deletions
40
...dumper/src/main/kotlin/com/jasonernst/packetdumper/filedumper/AbstractFilePacketDumper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,43 @@ | ||
package com.jasonernst.packetdumper.filedumper | ||
|
||
import com.jasonernst.packetdumper.AbstractPacketDumper | ||
import org.slf4j.LoggerFactory | ||
import java.io.File | ||
import java.time.LocalDateTime | ||
import java.util.concurrent.atomic.AtomicBoolean | ||
|
||
abstract class AbstractFilePacketDumper : AbstractPacketDumper() { | ||
abstract var filename: String | ||
/** | ||
* The base class for all file packet dumpers. We leave it as an abstract class so that we don't | ||
* have to implement the dumpBuffer method, and it can be implemented by the specific file dumper. | ||
*/ | ||
abstract class AbstractFilePacketDumper( | ||
path: String, | ||
name: String, | ||
ext: String, | ||
) : AbstractPacketDumper() { | ||
private val logger = LoggerFactory.getLogger(javaClass) | ||
|
||
abstract fun open() | ||
// keep the filename public to make testing easier | ||
val filename: String = "$path/${name}_${LocalDateTime.now()}.$ext" | ||
protected val isOpen = AtomicBoolean(false) | ||
protected lateinit var file: File | ||
protected var loggedError = false | ||
|
||
abstract fun close() | ||
open fun open() { | ||
if (isOpen.get()) { | ||
logger.error("Trying to open a file that is already open") | ||
return | ||
} | ||
file = File(filename) | ||
logger.debug("Opened file $filename") | ||
isOpen.set(true) | ||
} | ||
|
||
open fun close() { | ||
if (!isOpen.get()) { | ||
logger.error("Trying to close a file that is already closed") | ||
return | ||
} | ||
isOpen.set(false) | ||
} | ||
} |
51 changes: 46 additions & 5 deletions
51
...etdumper/src/main/kotlin/com/jasonernst/packetdumper/filedumper/PcapNgFilePacketDumper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,67 @@ | ||
package com.jasonernst.packetdumper.filedumper | ||
|
||
import com.jasonernst.packetdumper.ethernet.EtherType | ||
import com.jasonernst.packetdumper.ethernet.EthernetHeader.Companion.prependDummyHeader | ||
import com.jasonernst.packetdumper.pcapng.PcapNgInterfaceDescriptionBlock | ||
import com.jasonernst.packetdumper.pcapng.PcapNgSectionHeaderBlockLive | ||
import com.jasonernst.packetdumper.pcapng.PcapNgSimplePacketBlock | ||
import java.io.BufferedOutputStream | ||
import java.nio.ByteBuffer | ||
|
||
/** | ||
* Dumps packets to a file in the PCAP-NG format. | ||
* | ||
* @param path The path to the file | ||
* @param name The name of the file | ||
* @param isSimple If true, the file will be written in the simple format. | ||
* If false, it will be written in the enhanced format. | ||
*/ | ||
class PcapNgFilePacketDumper( | ||
override var filename: String, | ||
) : AbstractFilePacketDumper() { | ||
path: String, | ||
name: String, | ||
private val isSimple: Boolean = true, | ||
) : AbstractFilePacketDumper(path, name, "pcapng") { | ||
private lateinit var outputStreamWriter: BufferedOutputStream | ||
|
||
override fun open() { | ||
TODO("Not yet implemented") | ||
super.open() | ||
outputStreamWriter = BufferedOutputStream(file.outputStream()) | ||
outputStreamWriter.write(PcapNgSectionHeaderBlockLive.toBytes()) | ||
outputStreamWriter.flush() | ||
outputStreamWriter.write(PcapNgInterfaceDescriptionBlock().toBytes()) | ||
outputStreamWriter.flush() | ||
} | ||
|
||
override fun close() { | ||
TODO("Not yet implemented") | ||
super.close() | ||
outputStreamWriter.flush() | ||
outputStreamWriter.close() | ||
} | ||
|
||
/** | ||
* Writes a packet to the file. In this case, the address parameter is ignored. | ||
*/ | ||
override fun dumpBuffer( | ||
buffer: ByteBuffer, | ||
offset: Int, | ||
length: Int, | ||
addresses: Boolean, | ||
etherType: EtherType?, | ||
) { | ||
TODO("Not yet implemented") | ||
// optionally prepend the ethernet dummy header | ||
val conversionBuffer = | ||
if (etherType != null) { | ||
prependDummyHeader(buffer, offset, length, etherType) | ||
} else { | ||
buffer | ||
} | ||
|
||
if (isSimple) { | ||
val packetBlock = PcapNgSimplePacketBlock(conversionBuffer.array()) | ||
outputStreamWriter.write(packetBlock.toBytes()) | ||
outputStreamWriter.flush() | ||
} else { | ||
TODO() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/pcapng/AbstractPcapNgDumper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
import com.jasonernst.packetdumper.AbstractPacketDumper | ||
|
||
abstract class AbstractPcapNgDumper : AbstractPacketDumper() |
7 changes: 7 additions & 0 deletions
7
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/pcapng/PcapNgBlock.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
interface PcapNgBlock { | ||
fun size(): UInt | ||
|
||
fun toBytes(): ByteArray | ||
} |
18 changes: 18 additions & 0 deletions
18
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/pcapng/PcapNgBlockType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
// https://www.ietf.org/staging/draft-tuexen-opsawg-pcapng-02.html#name-block-types | ||
enum class PcapNgBlockType( | ||
val value: UInt, | ||
) { | ||
INTERFACE_DESCRIPTION_BLOCK(1u), | ||
SIMPLE_PACKET_BLOCK(3u), | ||
NAME_RESOLUTION_BLOCK(4u), | ||
INTERFACE_STATISTICS_BLOCK(5u), | ||
ENHANCED_PACKET_BLOCK(6u), | ||
SECTION_HEADER_BLOCK(0x0A0D0D0AU), | ||
; | ||
|
||
companion object { | ||
fun fromValue(value: UInt) = entries.first { it.value == value } | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/pcapng/PcapNgEnhancedPacketBlock.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
class PcapNgEnhancedPacketBlock |
12 changes: 12 additions & 0 deletions
12
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/pcapng/PcapNgException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
import java.lang.Exception | ||
|
||
class PcapNgException : Exception { | ||
constructor(message: String?) : super(message) {} | ||
constructor(message: String?, throwable: Throwable?) : super(message, throwable) {} | ||
|
||
companion object { | ||
private const val serialVersionUID = 1L | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
...per/src/main/kotlin/com/jasonernst/packetdumper/pcapng/PcapNgInterfaceDescriptionBlock.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
import java.nio.ByteBuffer | ||
import java.nio.ByteOrder | ||
|
||
/** | ||
* https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-interface-description-block | ||
*/ | ||
class PcapNgInterfaceDescriptionBlock( | ||
private val linkType: PcapNgLinkType = PcapNgLinkType.ETHERNET, | ||
) : PcapNgBlock { | ||
companion object { | ||
// block type (4) + 2x block len (4) + link type (2) + reserved (2) + snap len (4) | ||
private const val HEADER_BLOCK_LENGTH = 20u | ||
|
||
/** | ||
* Reads a section header block from a stream, throws a PcapNgException if the block is not a | ||
* section header live block. | ||
*/ | ||
fun fromStream(stream: ByteBuffer): PcapNgInterfaceDescriptionBlock { | ||
val startingPosition = stream.position() | ||
stream.order(ByteOrder.LITTLE_ENDIAN) | ||
val blockType = stream.int | ||
if (blockType != PcapNgBlockType.INTERFACE_DESCRIPTION_BLOCK.value.toInt()) { | ||
throw PcapNgException( | ||
"Block type is not an interface description block, expected ${PcapNgBlockType.INTERFACE_DESCRIPTION_BLOCK.value} got $blockType", | ||
) | ||
} | ||
val blockLength = stream.int | ||
if (blockLength != HEADER_BLOCK_LENGTH.toInt()) { | ||
throw PcapNgException("Block length is not the expected length") | ||
} | ||
val linkType = stream.short | ||
val reserved = stream.short | ||
val snapLen = stream.int | ||
if (snapLen != 0) { | ||
throw PcapNgException("Snap length is not the expected value") | ||
} | ||
val secondBlockLength = stream.int | ||
if (secondBlockLength != blockLength) { | ||
throw PcapNgException("Second block length is not the expected value") | ||
} | ||
if (stream.position() - startingPosition != HEADER_BLOCK_LENGTH.toInt()) { | ||
throw PcapNgException( | ||
"Stream position is not at the end of the block, expected ${startingPosition + HEADER_BLOCK_LENGTH.toInt()} got ${stream.position()}", | ||
) | ||
} | ||
return PcapNgInterfaceDescriptionBlock(PcapNgLinkType.fromValue(linkType.toUShort())) | ||
} | ||
} | ||
|
||
override fun size(): UInt = HEADER_BLOCK_LENGTH | ||
|
||
override fun toBytes(): ByteArray { | ||
val buffer = ByteBuffer.allocate(HEADER_BLOCK_LENGTH.toInt()) | ||
buffer.order(ByteOrder.LITTLE_ENDIAN) | ||
buffer.putInt(PcapNgBlockType.INTERFACE_DESCRIPTION_BLOCK.value.toInt()) | ||
buffer.putInt(HEADER_BLOCK_LENGTH.toInt()) | ||
|
||
buffer.putShort(linkType.value.toShort()) | ||
buffer.putShort(0) // reserved | ||
buffer.putInt(0) // snap length | ||
|
||
// no options | ||
|
||
buffer.putInt(HEADER_BLOCK_LENGTH.toInt()) | ||
return buffer.array() | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
packetdumper/src/main/kotlin/com/jasonernst/packetdumper/pcapng/PcapNgLinkType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.jasonernst.packetdumper.pcapng | ||
|
||
// https://www.tcpdump.org/linktypes.html | ||
enum class PcapNgLinkType( | ||
val value: UShort, | ||
) { | ||
NULL(0U), | ||
ETHERNET(1U), | ||
AX25(3U), | ||
IEEE802_5(6U), | ||
ARCNET_BSD(7U), | ||
SLIP(8U), | ||
PPP(9U), | ||
FDDI(10U), | ||
PPP_HDLC(50U), | ||
PPP_ETHER(51U), | ||
ATM_RFC1483(100U), | ||
RAW(101U), | ||
C_HDLC(104U), | ||
IEEE802_11(105U), | ||
FRELAY(107U), | ||
LOOP(108U), | ||
LINUX_SLL(113U), | ||
LTALK(114U), | ||
PFLOG(117U), | ||
IEEE802_11_PRISM(119U), | ||
IP_OVER_FC(122U), | ||
SUNATM(123U), | ||
IEEE802_11_RADIOTAP(127U), | ||
ARCNET_LINUX(129U), | ||
APPLE_IP_OVER_IEEE1394(138U), | ||
MTP2_WITH_PHDR(139U), | ||
MTP2(140U), | ||
MTP3(141U), | ||
SCCP(142U), | ||
DOCSIS(143U), | ||
LINUX_IRDA(144U), | ||
; | ||
|
||
companion object { | ||
fun fromValue(value: UShort) = entries.first { it.value == value } | ||
} | ||
} |
Oops, something went wrong.