github.com/gopacket/gopacket@v1.1.0/layers/usb.go (about)

     1  // Copyright 2014 Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  package layers
     8  
     9  import (
    10  	"encoding/binary"
    11  	"errors"
    12  
    13  	"github.com/gopacket/gopacket"
    14  )
    15  
    16  type USBEventType uint8
    17  
    18  const (
    19  	USBEventTypeSubmit   USBEventType = 'S'
    20  	USBEventTypeComplete USBEventType = 'C'
    21  	USBEventTypeError    USBEventType = 'E'
    22  )
    23  
    24  func (a USBEventType) String() string {
    25  	switch a {
    26  	case USBEventTypeSubmit:
    27  		return "SUBMIT"
    28  	case USBEventTypeComplete:
    29  		return "COMPLETE"
    30  	case USBEventTypeError:
    31  		return "ERROR"
    32  	default:
    33  		return "Unknown event type"
    34  	}
    35  }
    36  
    37  type USBRequestBlockSetupRequest uint8
    38  
    39  const (
    40  	USBRequestBlockSetupRequestGetStatus        USBRequestBlockSetupRequest = 0x00
    41  	USBRequestBlockSetupRequestClearFeature     USBRequestBlockSetupRequest = 0x01
    42  	USBRequestBlockSetupRequestSetFeature       USBRequestBlockSetupRequest = 0x03
    43  	USBRequestBlockSetupRequestSetAddress       USBRequestBlockSetupRequest = 0x05
    44  	USBRequestBlockSetupRequestGetDescriptor    USBRequestBlockSetupRequest = 0x06
    45  	USBRequestBlockSetupRequestSetDescriptor    USBRequestBlockSetupRequest = 0x07
    46  	USBRequestBlockSetupRequestGetConfiguration USBRequestBlockSetupRequest = 0x08
    47  	USBRequestBlockSetupRequestSetConfiguration USBRequestBlockSetupRequest = 0x09
    48  	USBRequestBlockSetupRequestSetIdle          USBRequestBlockSetupRequest = 0x0a
    49  )
    50  
    51  func (a USBRequestBlockSetupRequest) String() string {
    52  	switch a {
    53  	case USBRequestBlockSetupRequestGetStatus:
    54  		return "GET_STATUS"
    55  	case USBRequestBlockSetupRequestClearFeature:
    56  		return "CLEAR_FEATURE"
    57  	case USBRequestBlockSetupRequestSetFeature:
    58  		return "SET_FEATURE"
    59  	case USBRequestBlockSetupRequestSetAddress:
    60  		return "SET_ADDRESS"
    61  	case USBRequestBlockSetupRequestGetDescriptor:
    62  		return "GET_DESCRIPTOR"
    63  	case USBRequestBlockSetupRequestSetDescriptor:
    64  		return "SET_DESCRIPTOR"
    65  	case USBRequestBlockSetupRequestGetConfiguration:
    66  		return "GET_CONFIGURATION"
    67  	case USBRequestBlockSetupRequestSetConfiguration:
    68  		return "SET_CONFIGURATION"
    69  	case USBRequestBlockSetupRequestSetIdle:
    70  		return "SET_IDLE"
    71  	default:
    72  		return "UNKNOWN"
    73  	}
    74  }
    75  
    76  type USBTransportType uint8
    77  
    78  const (
    79  	USBTransportTypeTransferIn  USBTransportType = 0x80 // Indicates send or receive
    80  	USBTransportTypeIsochronous USBTransportType = 0x00 // Isochronous transfers occur continuously and periodically. They typically contain time sensitive information, such as an audio or video stream.
    81  	USBTransportTypeInterrupt   USBTransportType = 0x01 // Interrupt transfers are typically non-periodic, small device "initiated" communication requiring bounded latency, such as pointing devices or keyboards.
    82  	USBTransportTypeControl     USBTransportType = 0x02 // Control transfers are typically used for command and status operations.
    83  	USBTransportTypeBulk        USBTransportType = 0x03 // Bulk transfers can be used for large bursty data, using all remaining available bandwidth, no guarantees on bandwidth or latency, such as file transfers.
    84  )
    85  
    86  type USBDirectionType uint8
    87  
    88  const (
    89  	USBDirectionTypeUnknown USBDirectionType = iota
    90  	USBDirectionTypeIn
    91  	USBDirectionTypeOut
    92  )
    93  
    94  func (a USBDirectionType) String() string {
    95  	switch a {
    96  	case USBDirectionTypeIn:
    97  		return "In"
    98  	case USBDirectionTypeOut:
    99  		return "Out"
   100  	default:
   101  		return "Unknown direction type"
   102  	}
   103  }
   104  
   105  // The reference at http://www.beyondlogic.org/usbnutshell/usb1.shtml contains more information about the protocol.
   106  type USB struct {
   107  	BaseLayer
   108  	ID             uint64
   109  	EventType      USBEventType
   110  	TransferType   USBTransportType
   111  	Direction      USBDirectionType
   112  	EndpointNumber uint8
   113  	DeviceAddress  uint8
   114  	BusID          uint16
   115  	TimestampSec   int64
   116  	TimestampUsec  int32
   117  	Setup          bool
   118  	Data           bool
   119  	Status         int32
   120  	UrbLength      uint32
   121  	UrbDataLength  uint32
   122  
   123  	UrbInterval            uint32
   124  	UrbStartFrame          uint32
   125  	UrbCopyOfTransferFlags uint32
   126  	IsoNumDesc             uint32
   127  }
   128  
   129  func (u *USB) LayerType() gopacket.LayerType { return LayerTypeUSB }
   130  
   131  func (m *USB) NextLayerType() gopacket.LayerType {
   132  	if m.Setup {
   133  		return LayerTypeUSBRequestBlockSetup
   134  	} else if m.Data {
   135  	}
   136  
   137  	return m.TransferType.LayerType()
   138  }
   139  
   140  func decodeUSB(data []byte, p gopacket.PacketBuilder) error {
   141  	d := &USB{}
   142  
   143  	return decodingLayerDecoder(d, data, p)
   144  }
   145  
   146  func (m *USB) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   147  	if len(data) < 40 {
   148  		df.SetTruncated()
   149  		return errors.New("USB < 40 bytes")
   150  	}
   151  	m.ID = binary.LittleEndian.Uint64(data[0:8])
   152  	m.EventType = USBEventType(data[8])
   153  	m.TransferType = USBTransportType(data[9])
   154  
   155  	m.EndpointNumber = data[10] & 0x7f
   156  	if data[10]&uint8(USBTransportTypeTransferIn) > 0 {
   157  		m.Direction = USBDirectionTypeIn
   158  	} else {
   159  		m.Direction = USBDirectionTypeOut
   160  	}
   161  
   162  	m.DeviceAddress = data[11]
   163  	m.BusID = binary.LittleEndian.Uint16(data[12:14])
   164  
   165  	if uint(data[14]) == 0 {
   166  		m.Setup = true
   167  	}
   168  
   169  	if uint(data[15]) == 0 {
   170  		m.Data = true
   171  	}
   172  
   173  	m.TimestampSec = int64(binary.LittleEndian.Uint64(data[16:24]))
   174  	m.TimestampUsec = int32(binary.LittleEndian.Uint32(data[24:28]))
   175  	m.Status = int32(binary.LittleEndian.Uint32(data[28:32]))
   176  	m.UrbLength = binary.LittleEndian.Uint32(data[32:36])
   177  	m.UrbDataLength = binary.LittleEndian.Uint32(data[36:40])
   178  
   179  	m.Contents = data[:40]
   180  	m.Payload = data[40:]
   181  
   182  	if m.Setup {
   183  		m.Payload = data[40:]
   184  	} else if m.Data {
   185  		m.Payload = data[uint32(len(data))-m.UrbDataLength:]
   186  	}
   187  
   188  	// if 64 bit, dissect_linux_usb_pseudo_header_ext
   189  	if false {
   190  		m.UrbInterval = binary.LittleEndian.Uint32(data[40:44])
   191  		m.UrbStartFrame = binary.LittleEndian.Uint32(data[44:48])
   192  		m.UrbDataLength = binary.LittleEndian.Uint32(data[48:52])
   193  		m.IsoNumDesc = binary.LittleEndian.Uint32(data[52:56])
   194  		m.Contents = data[:56]
   195  		m.Payload = data[56:]
   196  	}
   197  
   198  	// crc5 or crc16
   199  	// eop (end of packet)
   200  
   201  	return nil
   202  }
   203  
   204  type USBRequestBlockSetup struct {
   205  	BaseLayer
   206  	RequestType uint8
   207  	Request     USBRequestBlockSetupRequest
   208  	Value       uint16
   209  	Index       uint16
   210  	Length      uint16
   211  }
   212  
   213  func (u *USBRequestBlockSetup) LayerType() gopacket.LayerType { return LayerTypeUSBRequestBlockSetup }
   214  
   215  func (m *USBRequestBlockSetup) NextLayerType() gopacket.LayerType {
   216  	return gopacket.LayerTypePayload
   217  }
   218  
   219  func (m *USBRequestBlockSetup) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   220  	m.RequestType = data[0]
   221  	m.Request = USBRequestBlockSetupRequest(data[1])
   222  	m.Value = binary.LittleEndian.Uint16(data[2:4])
   223  	m.Index = binary.LittleEndian.Uint16(data[4:6])
   224  	m.Length = binary.LittleEndian.Uint16(data[6:8])
   225  	m.Contents = data[:8]
   226  	m.Payload = data[8:]
   227  	return nil
   228  }
   229  
   230  func decodeUSBRequestBlockSetup(data []byte, p gopacket.PacketBuilder) error {
   231  	d := &USBRequestBlockSetup{}
   232  	return decodingLayerDecoder(d, data, p)
   233  }
   234  
   235  type USBControl struct {
   236  	BaseLayer
   237  }
   238  
   239  func (u *USBControl) LayerType() gopacket.LayerType { return LayerTypeUSBControl }
   240  
   241  func (m *USBControl) NextLayerType() gopacket.LayerType {
   242  	return gopacket.LayerTypePayload
   243  }
   244  
   245  func (m *USBControl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   246  	m.Contents = data
   247  	return nil
   248  }
   249  
   250  func decodeUSBControl(data []byte, p gopacket.PacketBuilder) error {
   251  	d := &USBControl{}
   252  	return decodingLayerDecoder(d, data, p)
   253  }
   254  
   255  type USBInterrupt struct {
   256  	BaseLayer
   257  }
   258  
   259  func (u *USBInterrupt) LayerType() gopacket.LayerType { return LayerTypeUSBInterrupt }
   260  
   261  func (m *USBInterrupt) NextLayerType() gopacket.LayerType {
   262  	return gopacket.LayerTypePayload
   263  }
   264  
   265  func (m *USBInterrupt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   266  	m.Contents = data
   267  	return nil
   268  }
   269  
   270  func decodeUSBInterrupt(data []byte, p gopacket.PacketBuilder) error {
   271  	d := &USBInterrupt{}
   272  	return decodingLayerDecoder(d, data, p)
   273  }
   274  
   275  type USBBulk struct {
   276  	BaseLayer
   277  }
   278  
   279  func (u *USBBulk) LayerType() gopacket.LayerType { return LayerTypeUSBBulk }
   280  
   281  func (m *USBBulk) NextLayerType() gopacket.LayerType {
   282  	return gopacket.LayerTypePayload
   283  }
   284  
   285  func (m *USBBulk) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   286  	m.Contents = data
   287  	return nil
   288  }
   289  
   290  func decodeUSBBulk(data []byte, p gopacket.PacketBuilder) error {
   291  	d := &USBBulk{}
   292  	return decodingLayerDecoder(d, data, p)
   293  }