buckyroberts / Python-Packet-Sniffer

Python network packet sniffer.
249 stars 145 forks source link

ValueError: Unknown format code 'x' for object of type 'str' #1

Open urwithajit9 opened 8 years ago

urwithajit9 commented 8 years ago

# Returns MAC as string from bytes (ie AA:BB:CC:DD:EE:FF) def get_mac_addr(mac_raw): byte_str = map('{:02x}'.format, mac_raw) mac_addr = ':'.join(byte_str).upper() return mac_addr After running the above function the sniffer program is throwing below error; ValueError: Unknown format code 'x' for object of type 'str' I am running with sudo command on my Ubuntu machine.

manishkk commented 7 years ago

I am using same code for Django, I am also getting same error from general.py file,

def get_mac_addr(mac_raw): byte_str = map('{:02x}'.format, mac_raw) mac_addr = ':'.join(byte_str).upper() return mac_addr

Exception Type: ValueError Exception Value: Unknown format code 'x' for object of type 'str'

I am also running with sudo command on my Ubuntu machine.

maxvonhippel commented 7 years ago

Is it the same error as this? I haven't really dug into this project much yet, but if you give some more details RE how to replicate your environment and generate the same error I'd be happy to give it a look.

manishkk commented 7 years ago

Hi Max, yes! Error is same! I tried above stack overflow solution but still getting error.

I am using this piece of code form general.py

// Returns MAC as string from bytes (ie AA:BB:CC:DD:EE:FF) def get_mac_addr(mac_raw): byte_str = map('{:02x}'.format, mac_raw) mac_addr = ':'.join(byte_str).upper() return mac_addr

and getting this error:

Exception Type: ValueError Exception Value: Unknown format code 'x' for object of type 'str' Exception Location: /webapp/general.py in get_mac_addr, line 6

maxvonhippel commented 7 years ago

I think this is something I can probably debug without replicating your environment. Can you give me an example of what mac_raw can look like? Like just do a print(mac_raw) and tell me what you get. Also what type is mac_raw to begin with? An int?

manishkk commented 7 years ago

def get_mac_addr(mac_raw):

used in Ethernet.py from there it will unpack the hexadecimal Digits (Not Confirm) & it will be call in Sniffer.py as

print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(eth.dest_mac, eth.src_mac, eth.proto))

Which will return destination & source MAC address in Format of AA:BB:CC:DD:EE:FF

manishkk commented 7 years ago

Hello! When I was running my code, my code was using Python 2.7 by default. so I created virtual environment & installed python 3 in that & issue

@urwithajit9 Please close the issue. I am not able to do @maxvonhippel @buckyroberts Thanks a lot.

maxvonhippel commented 7 years ago

Haha I wasn't helpful at all, you caught me during midterms and I never ended up even trying to replicate the error. But I'm keen to get more involved in this project in the future so feel free to tag me in future issues you want debugged! And I'm glad you figured it out.

manishkk commented 7 years ago

@maxvonhippel Sure, Still I am working on this! Whole Code I am trying to use with Django. and still troubleshooting going on.

manishkk commented 7 years ago

@maxvonhippel Any idea how I can fetch Time Stamp information from this code.

something is there in pcap.py file, but not getting idea that How I should use that.

Thanking you in advance!

maxvonhippel commented 7 years ago

@manishkk the docs on this project are not good. That said, looking at what docs do exist, it looks like the timestamp is embedded inside the data object in the packet. See this code, in which:

# ...
#get data from the packet
    data = packet[h_size:]

    print 'Data : ' + data
    print

Creates output:

Data : HTTP/1.1 502 Bad Gateway
Server: nginx
Date: Tue, 11 Sep 2012 08:56:00 GMT
Content-Type: text/html
Content-Length: 568
Connection: close

If you can reproduce that output, then it shouldn't be hard to parse out the date from that. I agree with you that it looks like cap.py is being used by sniffer.py. The code in cap.py doesn't look that difficult to work with to me. Try this in your terminal:

python
>>> import struct
>>> import time
>>> ts_sec, ts_usec = map(int, str(time.time()).split('.'))
>>> print(ts_sec)
1488520820
>>> print(ts_usec)
49
>>> print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts_sec)))
2017-03-02 23:00:20

In terms of how to get that data elsewhere in the file, I tried just using pcap.py to write a file with just the data 'some data', like this:

>>> class Pcap:
...     def __init__(self, filename, link_type=1):
...         self.pcap_file = open(filename, 'wb')
...         self.pcap_file.write(struct.pack('@ I H H i I I I', 0xa1b2c3d4, 2, 4, 0, 0, 65535, link_type))
...     def write(self, data):
...         ts_sec, ts_usec = map(int, str(time.time()).split('.'))
...         length = len(data)
...         self.pcap_file.write(struct.pack('@ I I I I', ts_sec, ts_usec, length, length))
...         self.pcap_file.write(data)
...     def close(self):
...         self.pcap_file.close()
...
>>> n = Pcap('tst.txt', 1)
>>> n.write('some data')
>>> n.close()

... and I got this:

~ cat tst.txt
��6�X        some data%

The binary for this file is:

screenshot 2017-03-02 23 05 26

Then you can unpack the file and get that original data back:

>>> with open('tst.txt', mode='rb') as file:
...     fileContent = file.read()
...     unpacked = struct.unpack('@ I H H i I I I I I I I', fileContent[:40])
...     print(unpacked)
...
(2712847316, 2, 4, 0, 0, 65535, 1, 1488520758, 1, 9, 9)

Note that the 8th number is ts_sec. I assume you should be able to backwards engineer whatever else you need from here :)

Let me know if I didn't answer your question or if there's anything else I can do to help!

manishkk commented 7 years ago

@maxvonhippel how I should call to ts_sec for time stamp like other attributes print('Source Port: {}, Destination Port: {}'.format(tcp.src_port, tcp.dest_port))

I tried pcap.ts_sec but doesn't work.

maxvonhippel commented 7 years ago

If you're using pcap it should be writing data to files. So open those files and unpack the structs as I demonstrated above. If you want to attach an example file generated by your code to this conversation I'd be happy to show you how to unpack it.

manishkk commented 7 years ago

@maxvonhippel Thanks, May be on Monday I will upload my code on Github then you can get better idea of Code & I can use your suggestion on that.

Thanks :+1:

maxvonhippel commented 7 years ago

It's fairly easy to modify pcap so you can print the value. If that's what you want to do, here's an example of how to do it:

import struct
import time

class Pcap:
    ts_sec = 0
    def __init__(self, filename, link_type=1):
        self.pcap_file = open(filename, 'wb')
        self.pcap_file.write(struct.pack('@ I H H i I I I', 0xa1b2c3d4, 2, 4, 0, 0, 65535, link_type))
        self.ts_sec = None
        self.ts_usec = None
    def write(self, data):
        self.ts_sec, self.ts_usec = map(int, str(time.time()).split('.'))
        length = len(data)
        self.pcap_file.write(struct.pack('@ I I I I', self.ts_sec, self.ts_usec, length, length))
        self.pcap_file.write(data)
    def close(self):
        self.pcap_file.close()
    def date(self):
        print(self.ts_sec)

n = Pcap('tst.txt', 1)
n.write('0'.encode('utf-8'))
n.close()
n.date()

Output:

1488595412