Documentation
¶
Overview ¶
Package osdp decodes OSDP (Open Supervised Device Protocol) packets — the SIA / IEC 60839-11-5 serial protocol that modern physical-access- control readers speak to their controllers (the secure successor to Wiegand). An OSDP bus dump is a sequence of these packets; dissecting them shows the poll/reply traffic, the card-read replies, the secure-channel handshake and any integrity failures — the staple of an access-control pentest / bus tap.
Wrap-vs-native judgement ¶
Native. The OSDP packet is a fixed little-endian frame — optional 0xFF driver mark, 0x53 start-of-message, address byte (bit 7 = reply direction, low 7 = PD address), 16-bit length, a control byte (2-bit sequence number, CRC-vs-checksum flag, security-block flag), an optional security control block, the command/reply code, the data, and a trailer that is either a CRC-16/AUG-CCITT (poly 0x1021, init 0x1D0F) or a 1-byte two's-complement checksum. All of that is pure byte-field extraction plus one standard CRC, so it is reimplemented here from the libosdp reference rather than wrapped — no new dependency, no shell-out.
What this covers ¶
- The full packet frame: mark / SOM / address (+ direction + PD address) / length / control (sequence number, CRC-or-checksum mode, secure-channel-block presence).
- The security control block (length + type + type meaning) when present — the secure-channel handshake markers SCS_11..SCS_18.
- The command (CP->PD) and reply (PD->CP) code with its name.
- NAK replies: the error code with its meaning.
- Trailer integrity: the CRC-16/AUG-CCITT or checksum is recomputed and reported as valid / invalid.
- Typed reply payloads for the codes with a well-defined plaintext layout: osdp_RAW (card-read reader / format / bit-count / card data — the actual badge), osdp_PDID (vendor / model / version / serial / firmware device fingerprint), osdp_COM (address + baud rate), osdp_KEYPAD (PIN key presses) and osdp_LSTATR (tamper + power). Their wire layouts are ported from the libosdp reference reply builder; see payload.go.
Deliberately deferred ¶
Command (CP->PD) payload field decode (osdp_LED / BUZ / OUT / TEXT parameters) is not broken out — the data is surfaced as hex and the code name identifies it. Secure-channel-encrypted payloads (SCS_17/18) cannot be decrypted without the session keys and are surfaced as ciphertext.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CardRead ¶ added in v0.535.0
type CardRead struct {
ReaderNo int `json:"reader_no"`
Format int `json:"format"`
FormatName string `json:"format_name"`
BitCount int `json:"bit_count"`
CardDataHex string `json:"card_data_hex,omitempty"`
}
CardRead is the osdp_RAW (0x50) card-read reply payload.
type ComConfig ¶ added in v0.535.0
ComConfig is the osdp_COM (0x54) communication-configuration reply.
type DeviceID ¶ added in v0.535.0
type DeviceID struct {
VendorCode string `json:"vendor_code"` // 24-bit OUI
Model int `json:"model"`
Version int `json:"version"`
SerialNumber uint32 `json:"serial_number"`
FirmwareVersion string `json:"firmware_version"`
}
DeviceID is the osdp_PDID (0x45) device-identification reply payload.
type Keypad ¶ added in v0.535.0
type Keypad struct {
ReaderNo int `json:"reader_no"`
Length int `json:"length"`
KeysHex string `json:"keys_hex,omitempty"`
KeysASCII string `json:"keys_ascii,omitempty"`
}
Keypad is the osdp_KEYPAD (0x53) key-press reply payload.
type LocalStatus ¶ added in v0.535.0
LocalStatus is the osdp_LSTATR (0x48) local-status reply payload.
type Result ¶
type Result struct {
HasMark bool `json:"has_mark"`
AddressByte string `json:"address_byte"`
PDAddress int `json:"pd_address"`
Broadcast bool `json:"broadcast"`
Direction string `json:"direction"` // "command (CP->PD)" / "reply (PD->CP)"
Length int `json:"length"`
SequenceNumber int `json:"sequence_number"`
CheckMode string `json:"check_mode"` // "crc" / "checksum"
SecureBlock *SecureBlock `json:"secure_block,omitempty"`
Code string `json:"code"`
CodeName string `json:"code_name"`
DataHex string `json:"data_hex,omitempty"`
NAKError *int `json:"nak_error_code,omitempty"`
NAKErrorName string `json:"nak_error_name,omitempty"`
// Decoded reply payloads (PD->CP), when the code has a well-defined
// plaintext layout (ported from the libosdp reference; see payload.go).
CardRead *CardRead `json:"card_read,omitempty"`
DeviceID *DeviceID `json:"device_id,omitempty"`
ComConfig *ComConfig `json:"com_config,omitempty"`
Keypad *Keypad `json:"keypad,omitempty"`
LocalStatus *LocalStatus `json:"local_status,omitempty"`
TrailerHex string `json:"trailer_hex"`
TrailerComputed string `json:"trailer_computed"`
TrailerValid bool `json:"trailer_valid"`
Notes []string `json:"notes,omitempty"`
}
Result is the decoded view of one OSDP packet.