ffalcinelli / pydivert

A Python binding for WinDivert driver
GNU Lesser General Public License v3.0
202 stars 36 forks source link

[WinError 18] There are no more files. #48

Closed Kasea closed 5 years ago

Kasea commented 5 years ago

Not sure what happened, I got it working, proceeded to restart the project a few times to play around with somethings and the next thing I knew whenever it would receive a packet and resend it, it would crash the entire program.

Python: 3.6.8 64 bit Windows 10 64 bit

Traceback:

Traceback (most recent call last):
  File "divert.py", line 176, in <module>
    main()
  File "divert.py", line 172, in main
    network.start()
  File "D:\Programming\Projects\Networking\divert\network.py", line 58, in start
    w.send(packet)
  File "C:\Python36\lib\site-packages\pydivert\windivert.py", line 227, in send
    packet.recalculate_checksums()
  File "C:\Python36\lib\site-packages\pydivert\packet\__init__.py", line 308, in recalculate_checksums
    num = windivert_dll.WinDivertHelperCalcChecksums(ctypes.byref(buff_), len(self.raw), flags)
  File "C:\Python36\lib\site-packages\pydivert\windivert_dll\__init__.py", line 54, in wrapper
    raise err
FileNotFoundError: [WinError 18] There are no more files.

Press any key to continue . . .

This is a snippet of how the code looks at Networking\divert\network.py", line 58, in start

    def start(self):
        @atexit.register
        def force_closed():
            w.close()

        local_filter = ""
        if type(self._local_ip) == list:
            local_filter = "(ip.SrcAddr >= {0} and ip.SrcAddr <= {1}) or (ip.DstAddr >= {0} and ip.DstAddr <= {1})".format(str(self.ip2int(self._local_ip[0])), str(self.ip2int(self._local_ip[1])))
        else:
            local_filter = "ip.SrcAddr == {0} or ip.DstAddr == {0}".format(str(self.ip2int(self._local_ip)))

        remote_filter = ""
        if type(self._remote_ip) == list:
            remote_filter = "(ip.SrcAddr >= {0} and ip.SrcAddr <= {1}) or (ip.DstAddr >= {0} and ip.DstAddr <= {1})".format(str(self.ip2int(self._remote_ip[0])), str(self.ip2int(self._remote_ip[1])))
        else:
            remote_filter = "ip.SrcAddr == {0} or ip.DstAddr == {0}".format(str(self.ip2int(self._remote_ip)))

        win_filter = "tcp.PayloadLength > 0 and ({0}) and ({1})".format(local_filter, remote_filter)

        w = pydivert.WinDivert(win_filter)
        # packets will be captured from now on
        w.open()

        while True:
            # get the packet
            packet = w.recv()

            # get the new payload
            try:
                new_payload, close = self._callback(packet.payload)
            except Exception as e:
                print(e)
                traceback.print_stack()
                new_payload = packet.payload

            # if we're sending the payload
            if new_payload is not None:
                packet.payload = new_payload
                packet.tcp.payload = new_payload
                w.send(packet) # Threw error here <<<

            # if we closed
            if close:
                break

        w.close() # stop capturing packets
Kasea commented 5 years ago

it seems like everytime I print the packet it works, so __repr__. Surely enough calling repr on the object makes it work.

I believe it's most likely to setting the payload wrong and this line in repr fixes it

if k == "payload" and v and len(v) > 20:
    v = v[:20] + b"..."