go-tpkt is a small, idiomatic Go library that implements TPKT framing for
RFC 1006 and
RFC 2126 transport profiles.
TPKT is a simple header + payload packet format used to carry ISO transport protocol data units (TPDUs) over a TCP byte stream. This package focuses only on TPKT framing and validation; it does not interpret TPDUs or implement the broader ITOT / Class 0/2 transport profile of RFC 2126.
- Scope
- Repository structure
- Install
- Getting started
- Relation to higher-level protocols
- License
- API reference
- Architecture
- Testing
- Limitations
-
In scope:
- TPKT header construction and parsing (RFC 1006 §6, RFC 2126 §4.3/§6.10)
EncodePacket/DecodePacketfor complete buffers- Streaming
Reader/Writeroverio.Reader/io.Writer - Validation of version and length (min=7, max=65535)
- Configurable receive size limit via
ReaderConfig - Reserved octet: written as 0; ignored on input
-
Out of scope:
- COTP / CR/CC/DT TPDU parsing
- Dual TCP expedited-data connections
- TSAP / NSAPA addressing or ISO session/presentation
- S7comm, MMS, IEC 61850, or any application protocol logic
- TCP dial, listen, or port binding
go-tpkt is a foundation for higher-level stacks such as COTP over RFC 1006.
go-tpkt/
├── . Public package `tpkt` (flat root)
│ ├── tpkt.go EncodePacket / DecodePacket
│ ├── reader.go Streaming Reader / ReadPacket
│ ├── writer.go Streaming Writer / WritePacket
│ ├── errors.go Exported sentinels
│ ├── doc.go Package overview
│ └── *_test.go Unit, fuzz, bench, and example tests
├── spec/ RFC 1006 / RFC 2126 reference texts
├── API.md Public API reference (wire format, ownership, EOF)
├── ARCHITECTURE.md Layers, goroutine and ownership model
├── TESTING.md Test tiers, coverage policy, fuzz regressions
├── LIMITATIONS.md Scope limits and what has not been verified
├── RELEASE.md Release history
├── CONTRIBUTING.md Contribution / test guidance
└── SECURITY.md Vulnerability reporting
There is no internal/ or cmd/ tree: buffer and stream APIs live in the same
package, split across focused files. Buffer ownership and stream contracts are
documented in API.md.
go get github.com/otfabric/go-tpkt@v1.0.1Requires Go 1.23 or newer.
The examples below cover the most common entry points. For the complete public API — wire format, errors, EOF semantics, and the requirements matrix — see API.md.
package main
import (
"log"
"github.com/otfabric/go-tpkt"
)
func main() {
payload := []byte{0x02, 0xf0, 0x80}
pkt, err := tpkt.EncodePacket(payload)
if err != nil {
log.Fatalf("encode: %v", err)
}
decoded, err := tpkt.DecodePacket(pkt)
if err != nil {
log.Fatalf("decode: %v", err)
}
_ = decoded // use TPDU bytes in a higher-level protocol
}package main
import (
"bytes"
"log"
"github.com/otfabric/go-tpkt"
)
func main() {
pkt, _ := tpkt.EncodePacket([]byte{0x01, 0x02, 0x03})
r, err := tpkt.NewReader(bytes.NewReader(pkt), tpkt.ReaderConfig{})
if err != nil {
log.Fatal(err)
}
payload, err := r.ReadPacket()
if err != nil {
log.Fatalf("read: %v", err)
}
_ = payload // TPDU bytes for a higher-level protocol
}For net.Conn usage, EOF semantics, and ReaderConfig.MaxPacketLength, see
Stream API in API.md.
package main
import (
"bytes"
"log"
"github.com/otfabric/go-tpkt"
)
func main() {
var buf bytes.Buffer
w, err := tpkt.NewWriter(&buf)
if err != nil {
log.Fatal(err)
}
payload := []byte{0x01, 0x02, 0x03}
if err := w.WritePacket(payload); err != nil {
log.Fatalf("write: %v", err)
}
_ = buf.Bytes() // complete TPKT packet on the wire
}This package intentionally stops at TPKT framing. Protocols such as COTP, S7comm, and MMS can be implemented on top of the opaque payloads read and written through this library.
See Usage patterns in API.md.
This project is licensed under the MIT License. See LICENSE.