github.com/pkg/sftp@v1.13.6/internal/encoding/ssh/filexfer/init_packets.go (about)

     1  package sshfx
     2  
     3  // InitPacket defines the SSH_FXP_INIT packet.
     4  type InitPacket struct {
     5  	Version    uint32
     6  	Extensions []*ExtensionPair
     7  }
     8  
     9  // MarshalBinary returns p as the binary encoding of p.
    10  func (p *InitPacket) MarshalBinary() ([]byte, error) {
    11  	size := 1 + 4 // byte(type) + uint32(version)
    12  
    13  	for _, ext := range p.Extensions {
    14  		size += ext.Len()
    15  	}
    16  
    17  	b := NewBuffer(make([]byte, 4, 4+size))
    18  	b.AppendUint8(uint8(PacketTypeInit))
    19  	b.AppendUint32(p.Version)
    20  
    21  	for _, ext := range p.Extensions {
    22  		ext.MarshalInto(b)
    23  	}
    24  
    25  	b.PutLength(size)
    26  
    27  	return b.Bytes(), nil
    28  }
    29  
    30  // UnmarshalBinary unmarshals a full raw packet out of the given data.
    31  // It is assumed that the uint32(length) has already been consumed to receive the data.
    32  // It is also assumed that the uint8(type) has already been consumed to which packet to unmarshal into.
    33  func (p *InitPacket) UnmarshalBinary(data []byte) (err error) {
    34  	buf := NewBuffer(data)
    35  
    36  	*p = InitPacket{
    37  		Version: buf.ConsumeUint32(),
    38  	}
    39  
    40  	for buf.Len() > 0 {
    41  		var ext ExtensionPair
    42  		if err := ext.UnmarshalFrom(buf); err != nil {
    43  			return err
    44  		}
    45  
    46  		p.Extensions = append(p.Extensions, &ext)
    47  	}
    48  
    49  	return buf.Err
    50  }
    51  
    52  // VersionPacket defines the SSH_FXP_VERSION packet.
    53  type VersionPacket struct {
    54  	Version    uint32
    55  	Extensions []*ExtensionPair
    56  }
    57  
    58  // MarshalBinary returns p as the binary encoding of p.
    59  func (p *VersionPacket) MarshalBinary() ([]byte, error) {
    60  	size := 1 + 4 // byte(type) + uint32(version)
    61  
    62  	for _, ext := range p.Extensions {
    63  		size += ext.Len()
    64  	}
    65  
    66  	b := NewBuffer(make([]byte, 4, 4+size))
    67  	b.AppendUint8(uint8(PacketTypeVersion))
    68  	b.AppendUint32(p.Version)
    69  
    70  	for _, ext := range p.Extensions {
    71  		ext.MarshalInto(b)
    72  	}
    73  
    74  	b.PutLength(size)
    75  
    76  	return b.Bytes(), nil
    77  }
    78  
    79  // UnmarshalBinary unmarshals a full raw packet out of the given data.
    80  // It is assumed that the uint32(length) has already been consumed to receive the data.
    81  // It is also assumed that the uint8(type) has already been consumed to which packet to unmarshal into.
    82  func (p *VersionPacket) UnmarshalBinary(data []byte) (err error) {
    83  	buf := NewBuffer(data)
    84  
    85  	*p = VersionPacket{
    86  		Version: buf.ConsumeUint32(),
    87  	}
    88  
    89  	for buf.Len() > 0 {
    90  		var ext ExtensionPair
    91  		if err := ext.UnmarshalFrom(buf); err != nil {
    92  			return err
    93  		}
    94  
    95  		p.Extensions = append(p.Extensions, &ext)
    96  	}
    97  
    98  	return nil
    99  }