After allowing my raspberry pi to access port 9999 of my router socketname.bind(96.231.140.202,9999) in python gives me a cannot assign error
To port forward I used:
myfiosgateway.com/#/firewall/portforward (the same method
worked fo my apache server) and I have verified that 96.231.140.202 is my pub ip
You cannot bind to your public IP. Your router is doing that. You instead want to bind to your private IP and port forward traffic destined to 9999 to your bound IP on your pi, this address will fall into the rfc compliant private IP ranges, so it will most likely be something like 192.168.1.12 or something similar.
For example:
socketname.bind(0.0.0.0,9999) #the use of 0.0.0.0 will automatically find your available interface on that raspberry pi.
If you let me know exactly what socket library youa re using I can craft the exact code.
Related
I need my own IP in a small script and in order not to hardcode it, I`ve found a piece of code from here(stackoverflow) that works.
This--
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
--
What is not clear for me is why it only works on UDP and not TCP? It has something to do with the google dns server? Thanks in advance.
This has nothing to do with Google and nothing to do with DNS.
All what this code does is to "connect" a UDP socket to an external IP, so that the OS kernel figures out which local IP address it needs to use in order to reach this external system. This is no real connection, i.e. there is no traffic involved but the OS kernel is only checking routing tables and local interfaces in order to decide which IP address to use as source in case one would actually use the socket to send data.
One could do the same with TCP. But in this case a real TCP connection would be established which means that actual traffic would be exchanged and that the connect would fail if the external system would not be reachable on this port (i.e. no listener, firewall in between etc).
With UDP instead connect will not produce any traffic and would fail only if no route to the destination IP address could be determined. This also means that an arbitrary external IP address and port could be used, i.e. ('1.1.1.1',11) would work the same as ('8.8.8.8',80).
How to set the source IP address for UDP multicast packages to something else than the interface IP?
I am trying to write a small router that selectively routes UDP SSDP packages from one network to another. The plan is to do it in python, although I am flexible on that.
It seems fairly easy to route SSDP NOTIFY messages: I receive them on one interface and decide which interface to re-broadcast them on. However the protocol for M-SEARCH messages require that the source IP is set to the original source of the message as any service that chooses to respond will respond with a unicast message to the source IP and port.
Example (heavily simplified):
Network A: 192.168.10.0/24
Network B: 192.168.11.0/24
My router application runs on a multihomed computer on 192.168.10.2 and 192.168.11.2.
A client on network A with IP 192.168.10.10 sends an M-SEARCH message:
Src IP/Port: 192.168.10.10 port 40000
Dst IP/Port: 239.255.255.250 port 1900
My "router application" on 192.168.10.2 receives the packet and would like to rebroadcast it on network B. However I cannot find any method in the socket API that allows me to set the source IP address. Only to pick the source interface.
Thus the rebroadcasted packet now looks like this:
Src IP/Port: 192.168.11.2 port xxxxx
Dst IP/Port: 239.255.255.250 port 1900
And now the receiving service is unable to unicast back to the client as the original IP and port are lost.
How to set the source IP address for UDP multicast packages to something else than the interface IP?
The only way I know of is to use a RAW socket and construct the IP headers manually. Note that use of RAW sockets is typically restricted to admin users on most platforms.
However I cannot find any method in the socket API that allows me to set the source IP address.
Because there isn't one.
And now the receiving service is unable to unicast back to the client as the original IP and port are lost.
Can't you just have your router remember the original source when it receives the M-SEARCH request, and when it receives the unicast reply then forward it to the original requester? That is how most routers usually work.
I have 2 computers connected with crossover cable and first time I need to start PC1 as server and PC2 as client and then second time PC2 as server and PC1 as client. I use UDP socket and it is on Windows. So I cant just put IP in code, I need the server code to get the IP automatically.
I tried this:
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
But this gives me wrong IP. I need the IP address that I see when I check Ethernet adapter Ethernet in ipconfig/all.
I'm not sure if you understand me sorry. English is not my best skill.
You could try using the netifaces package. Docs are here.
import netifaces
ip = netifaces.ifaddresses('eth0')[netifaces.AF_INET][0]['addr']
print(ip)
eth0 is just an example, you can get the actual interface name from ipconfig
I have a server running by using python's base http server. The host name used is '127.0.0.1' the local host, and the port number is set to 8000. I have the public ip address of the computer operating this server.
If I wanted to send a http get request to this from another computer, what would I type into my browser?
Sounds like you've got your server process running on the wrong interface. 127.0.0.1 is not a hostname but an IP address, specifically the local loopback address. It is not reachable from any other machine (unless something's gone tragically wrong with your network configuration).
You can run anything you like on the 127.0.0.1 interface, and no one else can directly connect to it from a remote machine. That's pretty much the point --- it's for testing programs that use the Internet Protocol, and (in recent years) for starting single-user servers without worrying about security. (Python 2's SimpleHTTPServer does this, as do some personal wikis, and I think iPython Notebook.)
The public address for the host running your Web server is a completely unrelated network interface, with its own hardware and its own port 8000. It doesn't know or care that you've got something listening on some other interface's port 8000, so it should refuse attempts to connect to that port.
Since you didn't post any code, I have no idea what you need to change to get your server running on the correct interface. Assuming you've more or less followed the example in the BaseHTTPServer.HTTPServer docs:
def run(
server_class=BaseHTTPServer.HTTPServer,
handler_class=BaseHTTPServer.BaseHTTPRequestHandler,
):
server_address = ('', 8000) # <----= Replace the string.
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
That server_address tuple is a string containing the IP address ('1.2.101.202' or whatever), followed by an integer port number. So replace the string with your host machine's public-facing IP address.
Note that port 8000 is outside the reserved range (0 up to but not including 1024), so it's possible that some unrelated service is already using that port. (Numerous applications are already squatting port 8000.) If so, you'll just have to choose another port number. You can chose anything from 1024 up to but not including 65536, but as with 8000, someone else might already be using it.
Depending on your operating system and its security setup, you might not have permission to open a socket that listens on an arbitrary port number. If so, that's between you and your ISP or sysadmin.
http://yourip:port/func
yourip is your public ip.
port is 8080
func is your registered function.
and also make sure you port is opened
Hi there sorry for disturbing you guys. But I read something in the Magazine about porting codes to IPV6 so i tried just changing this code (socket.AF_INET6, socket.SOCK_STREAM)
In python it works, but the problem is that the server does not display the client ip.
I expected it to display it like this. Got connection from ('127.0.0.1', 59815).
But for it , it messes up all thing and give me this (Got connection from ('::1', 59815, 0, 0)),
So if I ask were is the client IP here?. and what does the two last zeros(0, 0) really mean?. And what should i do to port my code to IPv6.? Thanks iam using python(geany)
So if I do this(socket.socket(socket.AF_INET6, socket.SOCK_STREAM)) will I have put my code to IPV6, o are there some other things I need to do thanks)
::1 is the IPv6 address for localhost, just like 127.0.0.1 is the IPv4 address for localhost. So you are seeing the client's IPv6 address.
The fields in the socket address are documented in the Python socket documentation. They are:
host
port
flowinfo
scope-id
Flowinfo and scope-id are new for IPv6. Flowinfo contains the Flow Label, which is specified in RFC 6437. If you don't know how to use it you can safely leave it at 0. The scope-id is used when an address is valid in multiple scopes. IPv6 link-local addresses for example are valid on every IPv6 interface, but routing them from one interface to another is not possible. So if you want to communicate with link-local addresses you have to specify which interface to use. The scope-id is the number of the interface.
When porting code to IPv6 you have to think about a few things. The socket handling you already have changed. You should also look at name resolving and use functions that support both IPv4 and IPv6 (i.e. don't use gethostbyname() but use getaddrinfo() etc.) And don't forget to allocate enough space when storing IP addresses. IPv6 addresses take up more space than IPv4 addresses.
PS: The IPy library provides very useful classes for dealing with IP addresses.