Generated from Manticore v1.1.5 • 201 packages. View on pkg.go.dev

pdu

import "github.com/TheManticoreProject/Manticore/network/dcerpc/v4/pdu"

Package pdu models connectionless (datagram) DCE/RPC protocol data units (PDUs): the fixed 80-octet common header and the bodies of the connectionless PDU types (request, ping, response, working, nocall, reject, ack, fault, cl_cancel, fack, cancel_ack) ([C706] chapter 12).

The codec is two-layered. The generic PDU type (pdu.go) frames any connectionless PDU as a Header plus an opaque body whose length is the header’s len field; this round-trips every PDU type at the wire level. The bodies that have a defined internal structure get their own typed codecs: FackBody (also used by nocall), CancelBody (cl_cancel), CancelAckBody (cancel_ack), and the status-code body shared by fault and reject (fault.go).

Only the little-endian data representation (the high nibble of drep[0] == 1) is supported, matching the connection-oriented codec under network/dcerpc/v5/pdu; a big-endian drep is rejected on Unmarshal rather than silently mis-parsed. The three header UUIDs are encoded with the standard DCE uuid_t little-endian layout via windows/guid.

References:

Index

Constants

CancelAckBodySize is the size, in octets, of a non-empty cancel_ack body.

const CancelAckBodySize = 9

CancelBodySize is the size, in octets, of a cl_cancel body.

const CancelBodySize = 8

HeaderSize is the size, in bytes, of the connectionless common header.

const HeaderSize = 80

NoHint is the reserved “no hint available” value for the ihint and ahint fields.

const NoHint uint16 = 0xFFFF

StatusBodySize is the size, in octets, of a fault or reject body.

const StatusBodySize = 4

Variables

DataRepresentationLittleEndian is the canonical 3-octet connectionless drep for little-endian integers, ASCII characters, and IEEE floating point. Note the connectionless drep is 3 octets, unlike the 4-octet connection-oriented packed drep.

var DataRepresentationLittleEndian = [3]byte{0x10, 0x00, 0x00}

func MarshalStatusBody

func MarshalStatusBody(status uint32) []byte

MarshalStatusBody encodes the body shared by the fault and reject PDUs: a single NDR unsigned long status code indicating why the operation faulted or why the request was rejected ([C706] section 12.6.4.6 fault, 12.6.4.7 reject).

func UnmarshalStatusBody

func UnmarshalStatusBody(data []byte) (uint32, error)

UnmarshalStatusBody decodes a fault or reject body into its status code.

type CancelAckBody

CancelAckBody is the optional body of a cancel_ack PDU ([C706] section 12.6.4.3, cancel_ack_body_t at body format version 0). A cancel_ack with no body is an orphan acknowledgement; when a body is present it carries the fields below.

Wire layout (little-endian):

0-3  vers                 uint32   (body format version, 0)
4-7  cancel_id            uint32   (cancel event being acknowledged)
8    server_is_accepting  boolean  (non-zero if the server accepts cancels)
type CancelAckBody struct {
    Version           uint32
    CancelID          uint32
    ServerIsAccepting bool
}

func (*CancelAckBody) Marshal

func (b *CancelAckBody) Marshal() ([]byte, error)

Marshal serializes the cancel_ack body into its 9-octet wire form.

func (*CancelAckBody) Unmarshal

func (b *CancelAckBody) Unmarshal(data []byte) (int, error)

Unmarshal parses a cancel_ack body from data and returns the bytes consumed.

type CancelBody

CancelBody is the body of a cl_cancel PDU ([C706] section 12.6.4.4, cancel_body_t at body format version 0).

Wire layout (little-endian):

0-3  vers       uint32  (body format version, 0)
4-7  cancel_id  uint32  (identifies the cancel event)
type CancelBody struct {
    Version  uint32
    CancelID uint32
}

func (*CancelBody) Marshal

func (b *CancelBody) Marshal() ([]byte, error)

Marshal serializes the cl_cancel body into its 8-octet wire form.

func (*CancelBody) Unmarshal

func (b *CancelBody) Unmarshal(data []byte) (int, error)

Unmarshal parses a cl_cancel body from data and returns the bytes consumed.

type FackBody

FackBody is the body of a fack PDU (and the optional body of a nocall PDU), carrying flow-control and selective-acknowledgement information ([C706] section 12.6.4.5, fack_body_t at body format version 0).

Wire layout (little-endian):

0      vers          uint8     (body format version, 0)
1      pad1          uint8     (unused)
2-3    window_size   uint16    (receiver window, in fragments)
4-7    max_tsdu      uint32    (largest local transport service data unit)
8-11   max_frag_size uint32    (largest accepted fragment size)
12-13  serial_num    uint16    (serial number being acknowledged)
14-15  selack_len    uint16    (number of selack elements that follow)
16...  selack[]      uint32[]  (selective-ack bitmasks, selack_len elements)
type FackBody struct {
    Version     uint8
    Pad1        uint8
    WindowSize  uint16
    MaxTSDU     uint32
    MaxFragSize uint32
    SerialNum   uint16
    // SelAck holds the selective-acknowledgement bitmasks. Its length is encoded on
    // the wire as selack_len.
    SelAck []uint32
}

func (*FackBody) Marshal

func (b *FackBody) Marshal() ([]byte, error)

Marshal serializes the fack body into its wire form.

func (*FackBody) Unmarshal

func (b *FackBody) Unmarshal(data []byte) (int, error)

Unmarshal parses a fack body from data and returns the number of bytes consumed.

type Flags1

Flags1 is the first set of connectionless PDU flags (the flags1 field of the common header).

References:

type Flags1 uint8
const (
    // Flags1Reserved01 is reserved for implementations; must be ignored.
    Flags1Reserved01 Flags1 = 0x01
    // Flags1LastFrag marks the last fragment of a multi-PDU transmission.
    Flags1LastFrag Flags1 = 0x02
    // Flags1Frag marks a fragment of a multi-PDU transmission.
    Flags1Frag Flags1 = 0x04
    // Flags1NoFack tells the receiver not to send a fack for this fragment.
    Flags1NoFack Flags1 = 0x08
    // Flags1Maybe marks a "maybe" request (no response expected). Client-to-server.
    Flags1Maybe Flags1 = 0x10
    // Flags1Idempotent marks an idempotent request. Client-to-server.
    Flags1Idempotent Flags1 = 0x20
    // Flags1Broadcast marks a broadcast request. Client-to-server.
    Flags1Broadcast Flags1 = 0x40
    // Flags1Reserved80 is reserved for implementations; must be ignored.
    Flags1Reserved80 Flags1 = 0x80
)

func (Flags1) Has

func (f Flags1) Has(flag Flags1) bool

Has reports whether all bits in flag are set.

func (Flags1) String

func (f Flags1) String() string

String returns a “|”-joined list of set flag names, or “none”.

type Flags2

Flags2 is the second set of connectionless PDU flags (the flags2 field of the common header). Only one bit is defined; the rest are reserved and must be zero.

References:

type Flags2 uint8
const (
    // Flags2Reserved01 is reserved for implementations; must be ignored.
    Flags2Reserved01 Flags2 = 0x01
    // Flags2CancelPending indicates a cancel was pending at the time the call
    // completed.
    Flags2CancelPending Flags2 = 0x02
)

func (Flags2) Has

func (f Flags2) Has(flag Flags2) bool

Has reports whether all bits in flag are set.

func (Flags2) String

func (f Flags2) String() string

String returns a “|”-joined list of set flag names, or “none”.

Header is the connectionless common header present at the start of every PDU ([C706] section 12.6.3.1, IDL type dc_rpc_cl_pkt_hdr_t).

Wire layout (offsets in octets):

0      rpc_vers      uint8     (version in 4 LSBs)
1      ptype         uint8     (type in 5 LSBs)
2      flags1        uint8
3      flags2        uint8
4-6    drep          byte[3]
7      serial_hi     uint8
8-23   object        uuid_t    (16)
24-39  if_id         uuid_t    (16)
40-55  act_id        uuid_t    (16)
56-59  server_boot   uint32
60-63  if_vers       uint32
64-67  seqnum        uint32
68-69  opnum         uint16
70-71  ihint         uint16
72-73  ahint         uint16
74-75  len           uint16    (length of the body that follows)
76-77  fragnum       uint16
78     auth_proto    uint8
79     serial_lo     uint8
type Header struct {
    RPCVersion         uint8
    PacketType         PacketType
    Flags1             Flags1
    Flags2             Flags2
    DataRepresentation [3]byte
    SerialHi           uint8
    ObjectID           guid.GUID
    InterfaceID        guid.GUID
    ActivityID         guid.GUID
    ServerBoot         uint32
    InterfaceVersion   uint32
    SequenceNumber     uint32
    OpNum              uint16
    InterfaceHint      uint16
    ActivityHint       uint16
    // BodyLength is the len field: the size, in octets, of the body following the
    // header. PDU.Marshal sets it from the body length, so callers normally leave it
    // zero.
    BodyLength     uint16
    FragmentNumber uint16
    AuthProto      uint8
    SerialLo       uint8
}

func NewHeader

func NewHeader(pt PacketType) Header

NewHeader returns a header initialized for connectionless protocol version 4 with little-endian data representation, the given packet type, and no interface/activity hint. The caller fills in the UUIDs, sequence number, opnum, and fragmentation fields as needed.

func (*Header) Marshal

func (h *Header) Marshal() ([]byte, error)

Marshal serializes the header into its 80-octet wire form.

func (*Header) Serial

func (h *Header) Serial() uint16

Serial reassembles the 16-bit serial number from its high and low halves, which are stored at opposite ends of the header (serial_hi at octet 7, serial_lo at octet 79).

func (*Header) String

func (h *Header) String() string

String returns a human-readable one-line summary of the header.

func (*Header) Unmarshal

func (h *Header) Unmarshal(data []byte) (int, error)

Unmarshal parses a header from the start of data and returns the bytes consumed (always HeaderSize on success).

type PDU

PDU is a complete connectionless DCE/RPC protocol data unit: the common Header followed by an opaque body of Header.BodyLength octets. It is the generic framing layer that round-trips every connectionless PDU type; the structured contents of the bodies that have a defined layout are parsed by the typed body codecs (FackBody, CancelBody, CancelAckBody) and the fault/reject status helpers.

The ping, ack, and working PDUs carry no body, so Body is nil for them. The request and response bodies are NDR-marshalled stub data (opaque to this layer).

Authentication verifiers are not modelled: a non-zero auth_proto means an auth_verifier trailer follows the body, which this codec does not interpret.

type PDU struct {
    Header Header
    Body   []byte
}

func (*PDU) Marshal

func (p *PDU) Marshal() ([]byte, error)

Marshal serializes the PDU into its wire form. It sets Header.BodyLength from the body length before encoding the header, so callers do not need to maintain it.

func (*PDU) String

func (p *PDU) String() string

String returns a human-readable one-line summary of the PDU.

func (*PDU) Unmarshal

func (p *PDU) Unmarshal(data []byte) (int, error)

Unmarshal parses a complete PDU (header plus the Header.BodyLength body octets that follow) from data and returns the number of bytes consumed. Any trailing bytes beyond the body (for example an authentication verifier when auth_proto is non-zero) are left for the caller.

type PacketType

PacketType identifies the kind of a connectionless DCE/RPC PDU, as carried in the 5 least significant bits of the ptype field of the common header.

The connectionless ptype values differ from the connection-oriented ones (which reuse 0-10 for an overlapping but not identical set and add bind/alter_context at 11+). The values below are the complete connectionless set.

References:

type PacketType uint8
const (
    PacketTypeRequest   PacketType = 0
    PacketTypePing      PacketType = 1
    PacketTypeResponse  PacketType = 2
    PacketTypeFault     PacketType = 3
    PacketTypeWorking   PacketType = 4
    PacketTypeNoCall    PacketType = 5
    PacketTypeReject    PacketType = 6
    PacketTypeAck       PacketType = 7
    PacketTypeClCancel  PacketType = 8
    PacketTypeFack      PacketType = 9
    PacketTypeCancelAck PacketType = 10
)

func (PacketType) String

func (t PacketType) String() string

String returns the mnemonic name of the packet type.