0

I'm using python to enumerate information in a dot1x exchange but I'm having trouble parsing the Ethernet protocol. I know the Ethernet type field is two bytes and dot1x uses "888e". I've confirmed "888e" is being passed via Wireshark but I'm getting the below output. Why is it showing "36488" instead of "888e"?

Destination MAC : 01:80:c2:00:00:03 Source MAC : c2:04:17:9c:f1:03 Protocol : 36488
Destination MAC : 01:80:c2:00:00:03 Source MAC : 08:00:27:83:5b:8b Protocol : 36488
Destination MAC : 01:80:c2:00:00:03 Source MAC : c2:04:17:9c:f1:03 Protocol : 36488
Destination MAC : 01:80:c2:00:00:03 Source MAC : 08:00:27:83:5b:8b Protocol : 36488
Destination MAC : 01:80:c2:00:00:03 Source MAC : c2:04:17:9c:f1:03 Protocol : 36488

My code:

import socket, sys
from struct import *

#Convert a string of 6 characters of ethernet address into a dash separated hex string
def eth_addr (a) :
    b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % (ord(a[0]) , ord(a[1]) , ord(a[2]), ord(a[3]), ord(a[4]) , ord(a[5]))
    return b

#create a AF_PACKET type raw socket (thats basically packet level)
#define ETH_P_ALL    0x0003          /* Every packet (be careful!!!) */
try:
    s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
except socket.error , msg:
    print 'Socket could not be created. Error Code : ' + str(msg[0]) + '   Message ' + msg[1]
    sys.exit()

# receive a packet
while True:
    packet = s.recvfrom(65565)

    #packet string from tuple
    packet = packet[0]

    #parse ethernet header
    eth_length = 14

    eth_header = packet[:eth_length]
    eth = unpack('!6s6sH' , eth_header)
    eth_protocol = socket.ntohs(eth[2])
    print 'Destination MAC : ' + eth_addr(packet[0:6]) + ' Source MAC : ' +  eth_addr(packet[6:12]) + ' Protocol : ' + str(eth_protocol)
madhead
  • 31,729
  • 16
  • 153
  • 201
doby
  • 3
  • 2

1 Answers1

0

It is just a matter of hexadecimal and decimal representation.

36488 is 8e88 in hexadecimal. Also you are doing a ntohs() translation to get the eth_protocol which basically changes the byte order i.e. translates 888e to 8e88.

If you want your program to print hexadecimal number check string formatting specs at Python docs.

sk11
  • 1,779
  • 1
  • 17
  • 29
  • Can't belive I missed that. Thank you. I ended up substituting the line "eth_protocol = socket.ntohs(eth[2])" with "eth_protocol = hex(eth[2])". – doby Aug 27 '15 at 23:06
  • @doby Glad to help, if this answer solved your problem please mark it as accepted by clicking the check mark next to the answer. See: [How does accepting an answer work?](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) for more information – sk11 Aug 28 '15 at 06:15
  • I am using same line in my program: s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003)) and getting error that .. _sock = _realsocket(family, type, proto) socket.error: [Errno 1] Operation not permitted .. what should I use instead of these parameters? –  Jan 04 '17 at 23:30