Is there any way to listen to traffic on a specific port that another program is currently using, through the python socket module? For example:
|--> my program
external request -> Host ->|--> intended program
I am not looking to send back a response to the request, I simply want the traffic. I was looking at using the socket.SO_REUSEADDR method, but I think that's simply to avoid having to wait for the socket's timeout, not to allow another listener.
You can do that with scapy
see http://www.secdev.org/projects/scapy/doc/usage.html#sniffing
to use it in your own python program, you'd have to import the sniff command
from scapy.all import sniff
a=sniff("tcp and port 1337")
sniff has various options (callback functions, timeout, number of packets etc)
The socket.SO_REUSEADDR option helps both applications to be bound to the same port and to receive packets destined for that port. So, I am not sure what you mean by your timeout note in the question. The only catch is that for some of the platforms, including Linux, both the sockets must set SO_REUSEADDR, else, the second socket not be able to bind. So, if you cannot modify the intended program (let us say, it is a standard third-party program), then using SO_REUSEADDR might be a problem.
Related
I have a python socket server that listens on a port, and accepts all incoming connections using:
(conn, address) = socket.accept()
However, I wish to accept connections only from certain ip address.
Currently, I close the connection if the address isn't registered, to accomplish this.
But is there a better way to do this, by directly rejecting connections from unregistered addresses, instead of accepting connections and then closing them?
It's not possible to indicate Connection refused to clients from some IP addresses, and to establish the connection to clients from other IP addresses. This is not a Python limitation, but a lower-level, BSD socket layer limitation. You can't do it even from C.
The closest behavior in general you can do in Python is closing the connection quickly after it has been accepted:
sock, addr = server_socket.accept()
if addr[0] != '12.34.56.78':
sock.close()
return
...
Then the client would see the connection being accepted, and very shortly after that the client would see EOF when reading from it, and it wouldn't be able to write to it.
However it's possible to limit by interface (i.e. network card) at bind time, by using one of:
server_socket.bind(('', 65432)) # Bind on any interface.
server_socket.bind(('127.0.0.1', 65432)) # Bind on loopback (localhost clients only).
server_socket.bind(('34.56.78.91', 65432))
So in the 127.0.0.1 version, telnet 127.0.0.1 65432 (as a client) would work, but telnet myhostname 65432 would yield Connection refused (and the server_socket.accept() call won't get this connection).
If you read the docs you can find the BaseServer.verify_request(request, client_address) which tells you this:
Must return a Boolean value; if the value is True, the request will be processed, and if it’s False, the request will be denied. This function can be overridden to implement access controls for a server. The default implementation always returns True.
Microsoft appears to support this functionality via the SO_CONDITIONAL_ACCEPT socket option
This appears to require usage of WSAAccept to accept connections
This constant does not appear in pythons socket module on my windows 8 machine. I don't think there is an option to use WSAAccept via python's builtin socket module.
If I understand correctly, this will allow your server to respond to SYN packets immediately with RST packets when configured to do so instead of finishing the handshake and exchanging FIN packets. Note that usage of this flag removes responsibility to handle connections from the operating system and places it on the application, so there is plenty of room for errors and performance hits to occur. If a performance boost was the goal, it might not be not worth pursuing
It is possible to do at the C level on windows. Pythons ctypes module allows interfacing with C code, so it is technically possible to do via a python interface. But it likely requires a non trivial amount of effort. If you are certain you require this feature, it may be less effort to find a C socket library that supports this out of the box, then you could make a ctypes wrapper for that.
I am making a SSL server, and I don't use python's library as I want to make some unorthodox changes to the process. Because of that, I cannot simply start a TCP connection since I need to transfer the encryption details with the handshake, which I can't do over sockets. So I am using scapy to make the handshake itself, but after that I would like to continue working with a TCP socket without going through the process of the handshake again. Is that possible?
If I understand your question correctly, you exchanged a few segments using scapy and now want to manufacture a normal full-blown socket out of them.
This is not easily possible: for all practical purposes your TCP is oblivious to whatever you sent in your packets and it doesn't keep any state for this TCP connection: all the state is in your application.
That said, there is a thing called TCP_REPAIR in Linux that lets you put a socket in a given state.
When this option is used, a socket is switched into a special mode, in
which any action performed on it does not result in anything defined
by an appropriate protocol actions, but rather directly puts the
socket into a state, in which the socket is expected to be at the end
of the successfully finished operation.
If you set sequence numbers correctly, the socket should "just work".,
One also needs to restore the TCP sequence numbers. To do so, the
TCP_REPAIR_QUEUE and TCP_QUEUE_SEQ options were introduced.
Of course all this is specific to a modern Linux; other operating systems may or may not have similar mechanisms.
I'm trying to communicate with a device that uses the same protocol whether you're talking to it over a TCP socket or a serial port. Either way, it's an ASCII command-based interface, in which you type your command at a prompt, followed by a newline, you get a response with a newline, and then a new prompt.
> IDENTIFY
DEVICE_TYPE_RESPONSE
> TEST POWER
OK
>
The program can and should block until it gets the new prompt, but there needs to be a timeout so you don't wait forever in case of sudden device death. That timeout should be seconds so as not to falsely flag on a network glitch, but shouldn't force me to wait seconds once I've gotten my prompt character.
I'd love some way to abstract the interface so as to not care about what the underlying communications layer is. Just pass it either an open socket or an open serial port and let everything happen. Is there some good way to do this? Preferably capable of running under Python 2.6.
You could implement the protocol in Twisted which allows you to use TCP or the serial port as a transport without changing your protocol implementation. Twisted also allows you to set timeouts/delayed callbacks.
Python's serial package provides a lot of useful stuff including some serial over TCP/IP bridges. If you want to talk to it using ASCII/Telnet then you probably want the to use the '--convert' option with the Simple Serial to Network (TCP/IP) redirector.
Also you might want to take a look at this other related question on Converting serial port data to TCP/IP in a linux environment
I'm trying to send a message through ICMP packets but I don't know how to do it.
This is the code I currently have, but obviously doesn't work:
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
s.settimeout(3.0)
s.sendto("Hello!" + "\r\n", (server, 7))
msg = s.recvfrom(buff_size)
s.close()
I have to receive an answer from server if string "Hello!" is sent, but I don't get it.
I suppose, that "Hello!" string will be encapsulated into Data field:
In order to construct an ICMP packet, you have to create the whole packet yourself using a raw socket. The struct module is useful for this.
Secondly, in order to even use raw sockets in the first place, you need to have permission to do so—you should be running as root (I know this is a sufficient condition, but I'm not 100% certain that it's a necessary condition). The ping(1) executable is able to do this because it's a setuid executable that runs as root when you run it. Since scripts cannot be made setuid on Linux, you'll have to make a wrapper setuid program in C that just executes your Python script.
I don't think that SOCK_RAW is going an ICMP datagram for you just because you set the protocol field to IPPROTO_ICMP! You have to construct the packet yourself.
Take a look at the source of ping.
There are (at least) two popular packages that provide ping in GNU/Linux operating systems. One is netkit and the other iputils. (netkit-combo is a tarball which has all the netkit utilities in one: telnet, FTP, ...) The *BSD guys probably have their own.
I have a Python application which opens a simple TCP socket to communicate with another Python application on a separate host. Sometimes the program will either error or I will directly kill it, and in either case the socket may be left open for some unknown time.
The next time I go to run the program I get this error:
socket.error: [Errno 98] Address already in use
Now the program always tries to use the same port, so it appears as though it is still open. I checked and am quite sure the program isn't running in the background and yet my address is still in use.
SO, how can I manually (or otherwise) close a socket/address so that my program can immediately re-use it?
Update
Based on Mike's answer I checked out the socket(7) page and looked at SO_REUSEADDR:
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied in a bind(2) call should
allow reuse of local addresses. For AF_INET sockets this means that a socket may bind,
except when there is an active listening socket bound to the address. When the listen‐
ing socket is bound to INADDR_ANY with a specific port then it is not possible to bind
to this port for any local address. Argument is an integer boolean flag.
Assume your socket is named s... you need to set socket.SO_REUSEADDR on the server's socket before binding to an interface... this will allow you to immediately restart a TCP server...
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))
You might want to try using Twisted for your networking. Mike gave the correct low-level answer, SO_REUSEADDR, but he didn't mention that this isn't a very good option to set on Windows. This is the sort of thing that Twisted takes care of for you automatically. There are many, many other examples of this kind of boring low-level detail that you have to pay attention to when using the socket module directly but which you can forget about if you use a higher level library like Twisted.
You are confusing sockets, connections, and ports. Sockets are endpoints of connections, which in turn are 5-tuples {protocol, local-ip, local-port, remote-ip, remote-port}. The killed program's socket has been closed by the OS, and ditto the connection. The only relic of the connection is the peer's socket and the corresponding port at the peer host. So what you should really be asking about is how to reuse the local port. To which the answer is SO_REUSEADDR as per the other answers.