Interesting. I looked at the USB dump a bit and compared it to the RNDIS
structures in the Linux rndis gadget driver... The device is a fullmac
device using 802.3 framing.

Most of the interesting things are apparently done via private OIDs and
variables...

Attached are three files to dump the data. If you have a snoopy pro
export log, use:

./rndis-dump.py < SnoopyProExport.log | less

For other logs, this'll need to be adjusted...
You can also give --xml as a command line parameter, then it'll replace
the <payloadbytes> tag contents only instead of stripping all the xml.

If anyone else wants to reverse engineer this protocol I'll send him my
device. Probably not really too hard to do, but absolutely not what I
expected -- I had expected a custom proprietary access interface to the
registers. I'm not too inclined to look at it much as it's a completely
different device. Based on the variables they send to the device, I'd
think they have their driver running on it.

Have fun,
johannes
import struct

from rndis_oids import *

def print_medium(medium):
  return 'unknown (%d)' % medium

def print_status(status):
  if status == 0x00000000:
    sstr = 'success'
  elif status == 0xc0000001:
    sstr = 'failure'
  elif status == 0xc0010015:
    sstr = 'invalid data'
  elif status == 0xc00000bb:
    sstr = 'not supported'
  elif status == 0x4001000b:
    sstr = 'media connect'
  elif status == 0x4001000c:
    sstr = 'media disconnect'
  else:
    sstr = 'unknown'
  return '%s (0x%.8x)'%(sstr,status)

def print_oid(oid):
  if oid in oids:
    ostr = oids[oid]
  elif oid == 0xfffeda3f:
    ostr = 'Broadcom sub-oid'
  elif oid == 0x0d010217:
    ostr = 'Broadcom scan'
  else:
    ostr = 'unknown'
  return '%s (0x%.8x)'%(ostr,oid)

def print_bytes(bytes):
  if len(bytes) == 0:
    return
  print 'rest:		',
  for byte in bytes:
    print '%.2x'%ord(byte),
  print
  print 'rest (ascii):	',
  for byte in bytes:
    o = ord(byte)
    if o>32 and o<=127:
      print chr(o)+' ',
    else:
      print '. ',
  print

def print_packet(pkt):
  print 'pkt_type:	RNDIS_MSG_PACKET (1)'
  print 'pkt_length:	', len(pkt)
  if len(pkt)<11*4:
    print 'packet too short'
    print_bytes(pkt[4:])
    return
  msg_type, msg_len, data_offset, data_len, oob_data_offset, oob_data_len, num_oob, packet_data_offset, packet_data_len, vc_handle, reserved = struct.unpack('<IIIIIIIIIII', pkt[:4*11])
  print	'msg_len:	', msg_len
  print 'data_offset:	', data_offset
  print 'data_len:	', data_len
  print_bytes(pkt[11*4:])

def print_init(pkt):
  print 'pkt_type:	RNDIS_MSG_INIT (2)'
  print 'pkt_length:	', len(pkt)
  msg_type, msg_len, request_id, major_ver, minor_ver, max_transfer = struct.unpack('<IIIIII', pkt[:4*6])
  print	'msg_len:	', msg_len
  print 'request_id:	', request_id
  print 'major_ver:	', major_ver
  print 'minor_ver:	', minor_ver
  print 'max_transfer:	', max_transfer
  print_bytes(pkt[4*6:])
  pass

query_oids = {}

def print_query(pkt):
  print 'pkt_type:	RNDIS_MSG_QUERY (4)'
  print 'pkt_length:	', len(pkt)
  msg_type, msg_len, request_id, oid, _len, offset, handle, = struct.unpack('<IIIIIII', pkt[:4*7])
  print	'msg_len:	', msg_len
  print 'request_id:	', request_id
  print 'oid:		',print_oid(oid)
  print 'len:		', _len
  print 'offset:		',offset
  print 'handle:		',handle
  query_oids[request_id] = oid
  print_bytes(pkt[4*7:])
  if oid == 0xfffeda3f:
    suboid, = struct.unpack('<I', pkt[4*7:4*7+4])
    print 'sub-oid:	',print_oid(suboid)
  pass

def print_set(pkt):
  print 'pkt_type:	RNDIS_MSG_SET (5)'
  print 'pkt_length:	', len(pkt)
  msg_type, msg_len, request_id, oid, _len, offset, handle, = struct.unpack('<IIIIIII', pkt[:4*7])
  print	'msg_len:	', msg_len
  print 'request_id:	', request_id
  print 'oid:		',print_oid(oid)
  print 'len:		', _len
  print 'offset:		',offset
  print 'handle:		',handle
  print_bytes(pkt[4*7:])
  if oid == OID_GEN_RNDIS_CONFIG_PARAMETER:
    nameoffs, namelen, paramtype, valoff, vallen = struct.unpack('<IIIII', pkt[4*7:4*7+4*5])
    print 'name offset:	',nameoffs
    print 'name length:	', namelen
    print 'param type:	', paramtype
    print 'value offset:	', valoff
    print 'value length:	', vallen
    name = pkt[4*7+nameoffs:4*7+nameoffs+namelen].replace('\0','')
    print 'name:		"'+name+'"'
    val = pkt[4*7+valoff:4*7+valoff+vallen].replace('\0','')
    if name in ["Channel", 'frag', 'rts']:
      val = pkt[4*7+valoff:4*7+valoff+vallen]
      val, = struct.unpack('<I', val)
      print 'value:		%d'%val
    else:
      print 'value:		"'+val+'"'

def print_indicate(pkt):
  print 'pkt_type:	RNDIS_MSG_INDICATE (7)'
  print 'pkt_length:	', len(pkt)
  if len(pkt)<4*5:
    print 'indicate request too short'
    print_bytes(pkt[4:])
    return
  msg_type, msg_len, status, length, offset, = struct.unpack('<IIIII', pkt[:4*5])
  print	'msg_len:	', msg_len
  print 'status:	', print_status(status)
  print 'length:		', length
  print 'offset:		',offset
  print_bytes(pkt[4*7:])
  pass

def print_init_c(pkt):
  print 'pkt_type:		RNDIS_MSG_INIT_C (0x80000002)'
  print 'pkt_length:		', len(pkt)
  msg_type, msg_len, request_id, status, major_ver, minor_ver, device_flags, medium, max_pkts_per_msg, max_transfer, packet_align, af_list_offs, af_list_size = struct.unpack('<IIIIIIIIIIIII', pkt[:4*13])
  print	'msg_len:		', msg_len
  print 'request_id:		', request_id
  print 'status:			', print_status(status)
  print 'major_ver:		', major_ver
  print 'minor_ver:		', minor_ver
  print 'device_flags:		0x%.4x'%device_flags
  print 'medium:			', print_medium(medium)
  print 'max_pkts_per_msg:	', max_pkts_per_msg
  print 'max_transfer:		', max_transfer
  print 'packet_alignment:	', packet_align
  print 'af_list_offset:		', af_list_offs
  print 'af_list_size:		', af_list_size
  print_bytes(pkt[4*13:])
  pass

def print_query_c(pkt):
  print 'pkt_type:	RNDIS_MSG_QUERY_C (0x80000004)'
  print 'pkt_length:	', len(pkt)
  msg_type, msg_len, request_id, status, _len, offset, = struct.unpack('<IIIIII', pkt[:4*6])
  print 'msg_len:	', msg_len
  print 'request_id:	', request_id
  print 'status:		', print_status(status)
  print 'len:		', _len
  print 'offset:		', offset
  print_bytes(pkt[4*6:])
  if request_id in query_oids:
    oid = query_oids[request_id]
    data = pkt[4*6:]
    if oid == OID_GEN_SUPPORTED_LIST:
      print 'supported OIDs:'
      while len(data)>=4:
        suppoid, = struct.unpack('<I', data[:4])
        data = data[4:]
        print '	', print_oid(suppoid)
    elif oid == OID_GEN_MAC_OPTIONS:
      opts, = struct.unpack('<I', data[:4])
      print 'options: see NDIS_MAC_OPTION_* constants'
    elif oid == 0xfffeda3f and _len>=4:
      suboid, = struct.unpack('<I', pkt[4*6:4*6+4])
      print 'sub-oid:	', print_oid(suboid)

def print_set_c(pkt):
  print 'pkt_type:	RNDIS_MSG_SET_C (0x80000005)'
  print 'pkt_length:	', len(pkt)
  msg_type, msg_len, request_id, status = struct.unpack('<IIII', pkt[:4*4])
  print 'msg_len:	', msg_len
  print 'request_id:	', request_id
  print 'status:		', print_status(status)
  print_bytes(pkt[4*4:])
  pass
#!/usr/bin/env python

import sys
import struct
import rndis
import re

xml = '--xml' in sys.argv

payload_re = re.compile(r'<payloadbytes>([^<]*)</payloadbytes>')

for line in sys.stdin:
  m = payload_re.match(line)
  if m is None:
    if len(line.strip())>0 and xml:
      print line,
    continue
  pkthex = m.group(1)
  if len(pkthex) == 0:
    if xml: print line,
    continue
  cur = ''
  pkt = ''
  for c in pkthex:
    cur += c
    if len(cur) == 2:
      pkt += chr(int(cur,16))
      cur = ''

  type, = struct.unpack('<I', pkt[:4])

  tpdict = {
    0x00000001:rndis.print_packet,
    0x00000002:rndis.print_init,
    0x00000004:rndis.print_query,
    0x00000005:rndis.print_set,
    0x00000007:rndis.print_indicate,
    0x80000002:rndis.print_init_c,
    0x80000004:rndis.print_query_c,
    0x80000005:rndis.print_set_c,
  }

  if xml: print '<payloadbytes><![CDATA['

  if type in tpdict:
    tpdict[type](pkt)
  else:
    print 'undecoded or non-rndis:',pkthex

  if xml:
    print ']]></payloadbytes>'
  else:
    print
oids = {
0x00010101:"OID_GEN_SUPPORTED_LIST",
0x00010102:"OID_GEN_HARDWARE_STATUS",
0x00010103:"OID_GEN_MEDIA_SUPPORTED",
0x00010104:"OID_GEN_MEDIA_IN_USE",
0x00010105:"OID_GEN_MAXIMUM_LOOKAHEAD",
0x00010106:"OID_GEN_MAXIMUM_FRAME_SIZE",
0x00010107:"OID_GEN_LINK_SPEED",
0x00010108:"OID_GEN_TRANSMIT_BUFFER_SPACE",
0x00010109:"OID_GEN_RECEIVE_BUFFER_SPACE",
0x0001010A:"OID_GEN_TRANSMIT_BLOCK_SIZE",
0x0001010B:"OID_GEN_RECEIVE_BLOCK_SIZE",
0x0001010C:"OID_GEN_VENDOR_ID",
0x0001010D:"OID_GEN_VENDOR_DESCRIPTION",
0x0001010E:"OID_GEN_CURRENT_PACKET_FILTER",
0x0001010F:"OID_GEN_CURRENT_LOOKAHEAD",
0x00010110:"OID_GEN_DRIVER_VERSION",
0x00010111:"OID_GEN_MAXIMUM_TOTAL_SIZE",
0x00010112:"OID_GEN_PROTOCOL_OPTIONS",
0x00010113:"OID_GEN_MAC_OPTIONS",
0x00010114:"OID_GEN_MEDIA_CONNECT_STATUS",
0x00010115:"OID_GEN_MAXIMUM_SEND_PACKETS",
0x00010116:"OID_GEN_VENDOR_DRIVER_VERSION",
0x00010117:"OID_GEN_SUPPORTED_GUIDS",
0x00010118:"OID_GEN_NETWORK_LAYER_ADDRESSES",
0x00010119:"OID_GEN_TRANSPORT_HEADER_OFFSET",
0x00010201:"OID_GEN_MEDIA_CAPABILITIES",
0x00010202:"OID_GEN_PHYSICAL_MEDIUM",
0x0001021A:"OID_GEN_MACHINE_NAME",
0x0001021B:"OID_GEN_RNDIS_CONFIG_PARAMETER",
0x0001021C:"OID_GEN_VLAN_ID",
0x00020101:"OID_GEN_XMIT_OK",
0x00020102:"OID_GEN_RCV_OK",
0x00020103:"OID_GEN_XMIT_ERROR",
0x00020104:"OID_GEN_RCV_ERROR",
0x00020105:"OID_GEN_RCV_NO_BUFFER",
0x00020201:"OID_GEN_DIRECTED_BYTES_XMIT",
0x00020202:"OID_GEN_DIRECTED_FRAMES_XMIT",
0x00020203:"OID_GEN_MULTICAST_BYTES_XMIT",
0x00020204:"OID_GEN_MULTICAST_FRAMES_XMIT",
0x00020205:"OID_GEN_BROADCAST_BYTES_XMIT",
0x00020206:"OID_GEN_BROADCAST_FRAMES_XMIT",
0x00020207:"OID_GEN_DIRECTED_BYTES_RCV",
0x00020208:"OID_GEN_DIRECTED_FRAMES_RCV",
0x00020209:"OID_GEN_MULTICAST_BYTES_RCV",
0x0002020A:"OID_GEN_MULTICAST_FRAMES_RCV",
0x0002020B:"OID_GEN_BROADCAST_BYTES_RCV",
0x0002020C:"OID_GEN_BROADCAST_FRAMES_RCV",
0x0002020D:"OID_GEN_RCV_CRC_ERROR",
0x0002020E:"OID_GEN_TRANSMIT_QUEUE_LENGTH",
0x0002020F:"OID_GEN_GET_TIME_CAPS",
0x00020210:"OID_GEN_GET_NETCARD_TIME",
0x00020211:"OID_GEN_NETCARD_LOAD",
0x00020212:"OID_GEN_DEVICE_PROFILE",
0x00020213:"OID_GEN_INIT_TIME_MS",
0x00020214:"OID_GEN_RESET_COUNTS",
0x00020215:"OID_GEN_MEDIA_SENSE_COUNTS",
0x00020216:"OID_GEN_FRIENDLY_NAME",
0x00020217:"OID_GEN_MINIPORT_INFO",
0x00020218:"OID_GEN_RESET_VERIFY_PARAMETERS",
0x01010101:"OID_802_3_PERMANENT_ADDRESS",
0x01010102:"OID_802_3_CURRENT_ADDRESS",
0x01010103:"OID_802_3_MULTICAST_LIST",
0x01010104:"OID_802_3_MAXIMUM_LIST_SIZE",
0x01010105:"OID_802_3_MAC_OPTIONS",
0x01020101:"OID_802_3_RCV_ERROR_ALIGNMENT",
0x01020102:"OID_802_3_XMIT_ONE_COLLISION",
0x01020103:"OID_802_3_XMIT_MORE_COLLISIONS",
0x01020201:"OID_802_3_XMIT_DEFERRED",
0x01020202:"OID_802_3_XMIT_MAX_COLLISIONS",
0x01020203:"OID_802_3_RCV_OVERRUN",
0x01020204:"OID_802_3_XMIT_UNDERRUN",
0x01020205:"OID_802_3_XMIT_HEARTBEAT_FAILURE",
0x01020206:"OID_802_3_XMIT_TIMES_CRS_LOST",
0x01020207:"OID_802_3_XMIT_LATE_COLLISIONS",
}

OID_GEN_SUPPORTED_LIST = 0x00010101
OID_GEN_HARDWARE_STATUS = 0x00010102
OID_GEN_MEDIA_SUPPORTED = 0x00010103
OID_GEN_MEDIA_IN_USE = 0x00010104
OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105
OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106
OID_GEN_LINK_SPEED = 0x00010107
OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108
OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109
OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010A
OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010B
OID_GEN_VENDOR_ID = 0x0001010C
OID_GEN_VENDOR_DESCRIPTION = 0x0001010D
OID_GEN_CURRENT_PACKET_FILTER = 0x0001010E
OID_GEN_CURRENT_LOOKAHEAD = 0x0001010F
OID_GEN_DRIVER_VERSION = 0x00010110
OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111
OID_GEN_PROTOCOL_OPTIONS = 0x00010112
OID_GEN_MAC_OPTIONS = 0x00010113
OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114
OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115
OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116
OID_GEN_SUPPORTED_GUIDS = 0x00010117
OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118
OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119
OID_GEN_MACHINE_NAME = 0x0001021A
OID_GEN_RNDIS_CONFIG_PARAMETER = 0x0001021B
OID_GEN_VLAN_ID = 0x0001021C
OID_GEN_MEDIA_CAPABILITIES = 0x00010201
OID_GEN_PHYSICAL_MEDIUM = 0x00010202
OID_GEN_XMIT_OK = 0x00020101
OID_GEN_RCV_OK = 0x00020102
OID_GEN_XMIT_ERROR = 0x00020103
OID_GEN_RCV_ERROR = 0x00020104
OID_GEN_RCV_NO_BUFFER = 0x00020105
OID_GEN_DIRECTED_BYTES_XMIT = 0x00020201
OID_GEN_DIRECTED_FRAMES_XMIT = 0x00020202
OID_GEN_MULTICAST_BYTES_XMIT = 0x00020203
OID_GEN_MULTICAST_FRAMES_XMIT = 0x00020204
OID_GEN_BROADCAST_BYTES_XMIT = 0x00020205
OID_GEN_BROADCAST_FRAMES_XMIT = 0x00020206
OID_GEN_DIRECTED_BYTES_RCV = 0x00020207
OID_GEN_DIRECTED_FRAMES_RCV = 0x00020208
OID_GEN_MULTICAST_BYTES_RCV = 0x00020209
OID_GEN_MULTICAST_FRAMES_RCV = 0x0002020A
OID_GEN_BROADCAST_BYTES_RCV = 0x0002020B
OID_GEN_BROADCAST_FRAMES_RCV = 0x0002020C
OID_GEN_RCV_CRC_ERROR = 0x0002020D
OID_GEN_TRANSMIT_QUEUE_LENGTH = 0x0002020E
OID_GEN_GET_TIME_CAPS = 0x0002020F
OID_GEN_GET_NETCARD_TIME = 0x00020210
OID_GEN_NETCARD_LOAD = 0x00020211
OID_GEN_DEVICE_PROFILE = 0x00020212
OID_GEN_INIT_TIME_MS = 0x00020213
OID_GEN_RESET_COUNTS = 0x00020214
OID_GEN_MEDIA_SENSE_COUNTS = 0x00020215
OID_GEN_FRIENDLY_NAME = 0x00020216
OID_GEN_MINIPORT_INFO = 0x00020217
OID_GEN_RESET_VERIFY_PARAMETERS = 0x00020218
OID_802_3_PERMANENT_ADDRESS = 0x01010101
OID_802_3_CURRENT_ADDRESS = 0x01010102
OID_802_3_MULTICAST_LIST = 0x01010103
OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104
OID_802_3_MAC_OPTIONS = 0x01010105
OID_802_3_RCV_ERROR_ALIGNMENT = 0x01020101
OID_802_3_XMIT_ONE_COLLISION = 0x01020102
OID_802_3_XMIT_MORE_COLLISIONS = 0x01020103
OID_802_3_XMIT_DEFERRED = 0x01020201
OID_802_3_XMIT_MAX_COLLISIONS = 0x01020202
OID_802_3_RCV_OVERRUN = 0x01020203
OID_802_3_XMIT_UNDERRUN = 0x01020204
OID_802_3_XMIT_HEARTBEAT_FAILURE = 0x01020205
OID_802_3_XMIT_TIMES_CRS_LOST = 0x01020206
OID_802_3_XMIT_LATE_COLLISIONS = 0x01020207

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to