Question

I'm a student, and I'm trying to understand the idea behind IP addresses. I learn that typing in a url is the same as typing in the corresponding IP address - either way, we'll be directed to the same web page.

I used the ping command to find the IP address of howstuffworks.com . I then typed that IP address in my browser ( google chrome ) but got this error :

The requested URL was not found on this server.

Why? I tried the same with google.com IP, and it worked fine.

Also, the IP addresses that I found using the ping command were IPv4 ( for google, it was 173.194.40.80) . Why did it not show an IPv6 address??

Was it helpful?

Solution

The relation between FQDNs (e.g. www.stackoverflow.com) and IP addresses (e.g. 198.252.206.140) is not necessarily a one-to-one relation. For instance, if I do a DNS lookup for www.stackoverflow.com, I get 198.252.206.140. So, the website for www.stackoverflow.com is hosted on a web server with the IP address 198.252.206.140. But, it's possible that there may be other web sites hosted at 198.252.206.140 as well.

That's why we have the Host command in the http protocol. After the browser makes a connection to the web server on port 80, the browser sends the host command to indicate which site on the web server it is attempting to connect to. See http://blog.tonycode.com/tech-stuff/http-notes/making-http-requests-via-telnet for a good tutorial on how this works. Copied below is a telnet session with 198.252.206.140, where an http connection is made, and the host command is issued to select www.stackoverflow.com, and the default response for www.stackoverflow.com is returned (which in this case is a 301 redirect to stackoverflow.com):

$ telnet 198.252.206.140 80
Trying 198.252.206.140...
Connected to 198.252.206.140.
Escape character is '^]'.
GET / HTTP/1.1
Host: www.stackoverflow.com

HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Location: http://stackoverflow.com/
Date: Tue, 04 Mar 2014 10:58:36 GMT
Content-Length: 148

<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a   
HREF="http://stackoverflow.com/">here</a></body>

OTHER TIPS

The host name is roughly equivalent to the IP address up to the moment when your browser reaches the remote server.

But the HTTP/1.1 protocol specifies that the client (the browser) must pass the host name as an header, as in:

Host: www.howstuffworks.com

This is very useful, as it allows several sites to be hosted on the same server, or anyway to be reachable from the same IP address.

You can find this out using the utility command curl:

curl -v http://54.236.73.243/ -H 'Host: www.howstuffworks.com'

Or using your browser with some plugin that allows to set custom headers.

To answer the second part of your question:

The ping command chooses one of the addresses to ping when the hostname has multiple addresses. On Windows systems ping can be used both for IPv4 and IPv6. On Unix-like systems you have to use ping6 for IPv6.

If you want to look what is in the DNS you'll have to use a tool that is made for that purpose such as host or dig (when on Unix-like system) or nslookup (when on a Windows system). For example:

$ dig google.com any

; <<>> DiG 9.8.3-P1 <<>> google.com any
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42780
;; flags: qr rd ra; QUERY: 1, ANSWER: 19, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.com.            IN  ANY

;; ANSWER SECTION:
google.com.     299 IN  A   173.194.65.138
google.com.     299 IN  A   173.194.65.100
google.com.     299 IN  A   173.194.65.101
google.com.     299 IN  A   173.194.65.113
google.com.     299 IN  A   173.194.65.139
google.com.     299 IN  A   173.194.65.102
google.com.     299 IN  AAAA    2a00:1450:4013:c00::8b
google.com.     599 IN  MX  10 aspmx.l.google.com.
google.com.     599 IN  MX  20 alt1.aspmx.l.google.com.
google.com.     599 IN  MX  30 alt2.aspmx.l.google.com.
google.com.     599 IN  MX  40 alt3.aspmx.l.google.com.
google.com.     599 IN  MX  50 alt4.aspmx.l.google.com.
google.com.     21599   IN  NS  ns1.google.com.
google.com.     21599   IN  NS  ns2.google.com.
google.com.     21599   IN  NS  ns3.google.com.
google.com.     21599   IN  NS  ns4.google.com.
google.com.     3599    IN  TXT "v=spf1 include:_spf.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all"
google.com.     21599   IN  SOA ns1.google.com. dns-admin.google.com. 2014021800 7200 1800 1209600 300
google.com.     21599   IN  TYPE257 \# 19 0005697373756573796D616E7465632E636F6D

;; Query time: 27 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Feb 28 23:53:29 2014
;; MSG SIZE  rcvd: 497

As you can see there is more in the DNS than A and AAAA records :-)

And to make this answer at least a little on-topic for StackOverflow, here is how you can properly deal with name resolving in a dual-stack environment. Write the code in such a way that it automatically uses whatever protocol is available. This is an example in Python:

#!/usr/bin/python
import sys, socket

# Get the hostname from the command line
if len(sys.argv) == 2:
    host = sys.argv[1]
else:
    print("Usage: {} <hostname>".format(sys.argv[0]))
    sys.exit(1)

# Set the parameters for the getaddrinfo call
service = "http"
family = socket.AF_UNSPEC
socktype = socket.SOCK_STREAM
protocol = socket.SOL_TCP
flags = 0

# Call getaddrinfo, it will give back a list of possible parameter-sets
try:
    resultset = socket.getaddrinfo(host, service, family, socktype, protocol, flags)
except socket.error:
    print("I'm sorry, but {} doesn't seem to exist".format(host))
    sys.exit(1)

# Now try to connect to them one by one
sock = None
for family, socktype, protocol, canonname, sockaddr in resultset:
    print("Trying to connect to {}".format(sockaddr))

    try:
        # Create a socket with the given parameters
        sock = socket.socket(family, socktype, protocol)
    except socket.error:
        # Failed to create a socket, try the next one
        continue

    try:
        # We have a socket, now use it to connect
        sock.connect(sockaddr)
    except socket.error:
        # The connection failed, close the socket
        sock.close()
        sock = None

        # And try the next one
        continue

    # Wonderful, we have a socket, and it is now connected!
    # Stop retrying
    break

if sock is None:
    print("None of the available addresses worked")
    sys.exit(1)

print("That one worked!")
my_addr = sock.getsockname()
remote_addr = sock.getpeername()
print("There is now a connection from {} to {}".format(my_addr, remote_addr))

# And close the connection nicely
sock.close()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top