Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu,...

39
net_py Chapter 4

Transcript of Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu,...

Page 1: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Chapter 4

Page 2: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Domains

Top-level Domains: .edu, .com., .ca, etc

Domain Name: newpaltz.edu, etc

Fully Qualified Domain Name: wyvern.cs.newpaltz.edu. Owning a domain name gives you the right to create FQDNs with your Domain Name at the end. Technically any name that ends with a '.' is also considered fully qualified.

Hostname: wyvern.

Page 3: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

/etc/resolv.conf

How domain name searches start:

If your search name is not fully qualified search begins by searching for using the name servers specified.

<your search name> <your search name>.cs.newpaltz.edu <your search name>.acsl.newpaltz.edu <your search name>.newpaltz.edu

(GeoIP)[pletcha@archimedes pypcap-1.1]$ cat /etc/resolv.conf # Generated by NetworkManagerdomain newpaltz.edusearch cs.newpaltz.edu acsl.newpaltz.edu newpaltz.edunameserver 137.140.1.98nameserver 137.140.1.102

Page 4: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Example:

Searching for my.website.cam will search for

my.website.cam my.website.cam.cs.newpaltz.edu my.website.cam.acsl.newpaltz.edu my.website.cam.newpaltz.edu

But searching for my.website.cam. will search for

my.website.cam

only.

Page 5: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Example 2:

Searching for argos searches for:

argos.cs.newpaltz.edu # fails argos.acsl.newpaltz.edu # fails argos.newpaltz.edu # succeeds

This is why you can use host names only on campus.

Page 6: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Socket Names Used By:

mysocket.accept(): returns a tuple whose 2nd entry is a remote address

mysocket.bind(address): binds to a local address so outgoing packets have this source address.

mysocket.connect(address): indicates the remote address that packets using this connection must either go to or come from.

mysocket.getpeername(): Returns the remote address the socket is connected to

mysocket.getsocketname(): returns the address of this socket

mysocket.recvfrom(): UDP: returns data and the address of the sender

mysocket.sendto(data,address): UDP, indicates the receiver address.

Page 7: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Five Socket Properties:

socket.AF_INET: Internet Address Family => kind of network and transport – UDP or TCP.

socket.AF_UNIX: like the internet but between processes on the same host

socket.SOCK_DGRAM: packet service (UDP for AF_INET)

socket.SOCK_STREAM: stream service (TCP for AF_INET)

3rd argument, not used n this book

socket.IPPROTO_TCP: use TCP for SOCK_STREAM.

socket.IPPROTO_UDP: use TCP for SOCK_DGRAM

Page 8: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

IPv6:

Will replace IPv4 when we run our ot IPv4 IP addresses.

IPv6 has more services than IPv4.

>>> import socket>>> print socket.has_ipv6()# tells you if your machine is capable of ipv6; not # if it is enabled.

Page 9: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Address Resolution:

One way of avoiding specifying destination IP addresses, etc, is to let the socket module tell you what you need to know.

We are asking, “How can we connect to the web server on host gatech.edu?”

>>> import socket>>> infolist = socket.getaddrinfo('gatech.edu','www')>>> pprint infolist[(1,2,6,'',('130.207.244.244','80'), (1,2,17,'',('130.207.244.244','80')# all the interfaces on .244.244 associated with 'www'>>> ftpca = infolist[0] # == (1,2,6,'',('130.207.244.244','80')>>> ftp = ftpca[0:3] # == (2,1,6)>>> s = socket.socket(*ftp) # unpack a list with *# s = socket.socket(ftp[0],ftp[1]) would do just as well>>> s.connect(ftpca[4]) # ('130.207.244.244','80')

Page 10: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

NOTE:

HTTPD officially supports TCP (6) and UDP (17).

gatech.edu is an alias for this host. It also has a “cannonical” name. but we didn't ask for this so it wasn't returned.

Calling socket.getaddrinfo() we don't need to use socket.AF_INET, etc, in our code.

Page 11: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Asking socket.getaddrinfo() for help in binding.

Problem: Provide an address for bind() without deciding this yourself.

Example: Suppose you want to open a server (passive) using port 1060

>>> from socket import getaddrinfo>>> import socket>>> getaddrinfo(None,1060,0,socket.SOCK_STREAM,0,socket.AI_PASSIVE)[(2, 1, 6, '', ('0.0.0.0', 1060)), (10, 1, 6, '', ('::', 1060, 0, 0))]>>> getaddrinfo(None,1060,0,socket.SOCK_DGRAM,0,socket.AI_PASSIVE)[(2, 2, 17, '', ('0.0.0.0', 1060)), (10, 2, 17, '', ('::', 1060, 0, 0))]

# we are asking here, where to bind to. We get an IPv4 and an IPv6 answer# in both cases, TCP and UDP.

Page 12: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Asking socket.getaddrinfo() for help in binding.

Problem: Want a particular address for bind().

Example: Suppose you want to open a server (passive) using port 1060 and a known local IP address.

>>> from socket import getaddrinfo>>> import socket>>> getaddrinfo('127.0.0.1',1060,0,socket.SOCK_STREAM,0)[(2, 1, 6, '', ('127.0.0.1', 1060))]>>> getaddrinfo(localhost,1060,0,socket.SOCK_STREAM,0)[(2, 1, 6, '', ('::1', 1060,0,0)), (2, 1,6, '', ('127.0.0.1', 1060))]

# we are asking here, where to bind to. We get an IPv4 and an IPv6 answer

Page 13: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Asking getaddrinfo() about services

The rest of the uses of getaddrinfo() are outward looking.

socket.AI_ADDRCONFIG: filter out things you can't use

socket.AI_AI_V4MAPPED: get IPV4 only

If you don't specify certain address types you get multiple addresses

>>> getaddrinfo('ftp.kernel.org','ftp',0,socket.SOCK_STREAM,0,... socket.AI_ADDRCONFIG | socket.AI_V4MAPPED)[(2, 1, 6, '', ('149.20.4.69', 21))]

>>> getaddrinfo('iana.org','www',0,socket.SOCK_STREAM,0)[(2, 1, 6, '', ('192.0.43.8', 80)), (10, 1, 6, '', ('2001:500:88:200::8', 80, 0, 0))]

Page 14: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Asking getaddrinfo() about services

The rest of the uses of getaddrinfo() are outward looking.

socket.AI_ADDRCONFIG: filter out things you can't use

socket.AI_AI_V4MAPPED: get IPV4 only

If you don't specify certain address types you get multiple addresses

>>> getaddrinfo('ftp.kernel.org','ftp',0,socket.SOCK_STREAM,0,... socket.AI_ADDRCONFIG | socket.AI_V4MAPPED)[(2, 1, 6, '', ('149.20.4.69', 21))]

>>> getaddrinfo('iana.org','www',0,socket.SOCK_STREAM,0)[(2, 1, 6, '', ('192.0.43.8', 80)), (10, 1, 6, '', ('2001:500:88:200::8', 80, 0, 0))]

Page 15: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Alternative Methods:

Older methods are hard-wired for IPv4 so should be avoided.

gethostbyname()getfqdn()gethostnbyaddr()getprotobyname(0getservbyname()getservbyport()

socket.gethostbyname(socket.getfqdn())# gives you the primary IP address of this machine

Page 16: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Using getaddrinfo() and getsockaddr():

#!/usr/bin/env python# Foundations of Python Network Programming - Chapter 4 - www_ping.py# Find the WWW service of an arbitrary host using getaddrinfo().

import socket, sys

if len(sys.argv) != 2: print >>sys.stderr, 'usage: www_ping.py <hostname_or_ip>' sys.exit(2)

hostname_or_ip = sys.argv[1]

try: infolist = socket.getaddrinfo( hostname_or_ip, 'www', 0, socket.SOCK_STREAM, 0, socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME, )except socket.gaierror, e: print 'Name service failure:', e.args[1] sys.exit(1)

Page 17: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Using getaddrinfo() and getsockaddr():

info = infolist[0] # per standard recommendation, try the first onesocket_args = info[0:3]address = info[4]s = socket.socket(*socket_args)try: s.connect(address)except socket.error, e: print 'Network failure:', e.args[1]else: print 'Success: host', info[3], 'is listening on port 80'

Page 18: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Just to be sure 1:

#!/usr/bin/env python# Foundations of Python Network Programming - Chapter 4 - forward_reverse.pyimport socket, sys

if len(sys.argv) != 2: print >>sys.stderr, 'usage: forward_reverse.py <hostname>' sys.exit(2)hostname = sys.argv[1]try: infolist = socket.getaddrinfo( hostname, 0, 0, socket.SOCK_STREAM, 0, socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME )except socket.gaierror, e: print 'Forward name service failure:', e.args[1] sys.exit(1)

info = infolist[0] # choose the first, if there are several addressescanonical = info[3]socketname = info[4]ip = socketname[0]

Page 19: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Just to be sure 2:

if not canonical: print 'WARNING! The IP address', ip, 'has no reverse name' sys.exit(1)

print hostname, 'has IP address', ipprint ip, 'has the canonical hostname', canonical

# Lowercase for case-insensitive comparison, and chop off hostnames.

forward = hostname.lower().split('.')reverse = canonical.lower().split('.')

if forward == reverse: print 'Wow, the names agree completely!' sys.exit(0)

Page 20: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Just to be sure 3:

# Truncate the domain names, which now look like ['www', mit', 'edu'],# to the same length and compare. Failing that, be willing to try a# compare with the first element (the hostname?) lopped off if both of# they are the same length.

length = min(len(forward), len(reverse))if (forward[-length:] == reverse[-length:] or (len(forward) == len(reverse) and forward[-length+1:] == reverse[-length+1:] and len(forward[-2]) > 2)): # avoid thinking '.co.uk' means a match! print 'The forward and reverse names have a lot in common'else: print 'WARNING! The reverse name belongs to a different organization'

Page 21: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

DNSDomain Name:List of labels in path of nodes

used for reverse(addr->name) lookup

Page 22: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Reverse lookup

[pletcha@archimedes 04]$ host 137.140.1.4848.1.140.137.in-addr.arpa domain name pointer www.newpaltz.edu.

Page 23: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

DNS Packet

Page 24: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

DNS Packet

Q/R: 0/1Opcode: Name or pointerAA: Answer is authoritative(1)TC: truncatedRD: Recursion desired (1)RA: Recursion available (1)rcode: ) - ok, 3 – invalid name from AA

Page 25: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

DNS Query

Page 26: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Wireshark look

Page 27: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

DNS Query Response

Page 28: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Wireshark look:

Page 29: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

How to Interpret Previous Slide:

Blue area is the entire response packet.

Bytes 2D-35 are the number of Questions (1), Answers (1), Authoritative Answers (2), Additional Answers(2).

Byte 36 is the length of the first label in the string

Query Type: 00 0C

Query Class: 00 01 (ends on byte 54)

And so on ...

48.1.140.137.in-addr.arpa

Page 30: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Handling Repeated Strings:

Bytes 55 and 56 ought to be the beginning of the same IP address string repeated. Instead there are two bytes – C0 0C.

When you see most significant four bits of a byte as C this indicates that the next 12 bits are a pointer into the response packet.

In our case the pointer is 0C. So count C bytes into the packet and guess where this gets you – right to the beginning of the original version of

namely, 02 34 38 01 31 03 31 34 30 03 ...

And so on ...

48.1.140.137.in-addr.arpa

Page 31: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

When to use DNS directly:

The authors of our text suggest we stick to getaddrinfo() for all our addressing needs except one – find the mail server for a remote email address.

Suppose you want to send an email to someone but your own mail server is down. Since you normally use your own email server to route the email to the destination mail server, your email can't be sent unless you can by-pass your own email server.

Page 32: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Email Servers: What protocols are involved in email.

SMTP

SMTP

POP3 orIMAP

“your” mail server “their” mail server

your client:browser,thunderbird

their client:perhaps not running rightnow

Page 33: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Email Servers: How to by-pass your local mail server.

SMTP

SMTP

POP3 orIMAP

“your” mail server “their” mail server

your client:a python program that knows how tosend an email to aremote mail server(Chapter 13)

their client:perhaps not running rightnow

SMTP

Page 34: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

How to send an email without your local email server:

Ask the DNS server for a remote domain name for the MX resource.

The reply should come back with the domain name and/or IP address of the mail server for that domain.

Build up your email message with the necessary header fields and send it off to the remote email server (port numbers: 25 and 465).

Page 35: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

How to find a remote Mail Server:

Ask the DNS server for a remote domain name for the MX resource.

[pletcha@archimedes 04]$ cat dns_mx.py#!/usr/bin/env python# Foundations of Python Network Programming - Chapter 4 - dns_mx.py# Looking up a mail domain - the part of an email address after the `@`

import sys, DNS

if len(sys.argv) != 2: print >>sys.stderr, 'usage: dns_basic.py <hostname>' sys.exit(2)

Page 36: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

def resolve_hostname(hostname, indent=0): """Print an A or AAAA record for `hostname`; follow CNAMEs if necessary.""" indent = indent + 4 istr = ' ' * indent request = DNS.Request() reply = request.req(name=sys.argv[1], qtype=DNS.Type.A) if reply.answers: for answer in reply.answers: print istr, 'Hostname', hostname, '= A', answer['data'] return reply = request.req(name=sys.argv[1], qtype=DNS.Type.AAAA) if reply.answers: for answer in reply.answers: print istr, 'Hostname', hostname, '= AAAA', answer['data'] return reply = request.req(name=sys.argv[1], qtype=DNS.Type.CNAME) if reply.answers: cname = reply.answers[0]['data'] print istr, 'Hostname', hostname, 'is an alias for', cname resolve_hostname(cname, indent) return print istr, 'ERROR: no records for', hostname

Page 37: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

def resolve_email_domain(domain): """Print mail server IP addresses for an email address @ `domain`.""" request = DNS.Request() reply = request.req(name=sys.argv[1], qtype=DNS.Type.MX) if reply.answers: print 'The domain %r has explicit MX records!' % (domain,) print 'Try the servers in this order:' datalist = [ answer['data'] for answer in reply.answers ] datalist.sort() # lower-priority integers go first for data in datalist: priority = data[0] hostname = data[1] print 'Priority:', priority, ' Hostname:', hostname resolve_hostname(hostname) else: print 'Drat, this domain has no explicit MX records' print 'We will have to try resolving it as an A, AAAA, or CNAME' resolve_hostname(domain)

DNS.DiscoverNameServers()resolve_email_domain(sys.argv[1])

Page 38: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Send a simple email:

Following slide, from Chapter 13, sends a simple email directly to the remote email server.

Exercise: Combine the previous two programs.

Page 39: Net_py Chapter 4. net_py Domains Top-level Domains:.edu,.com.,.ca, etc Domain Name: newpaltz.edu, etc Fully Qualified Domain Name: wyvern.cs.newpaltz.edu.

net_py

Sending a simple email message:

[pletcha@archimedes 13]$ cat simple.py #!/usr/bin/env python# Basic SMTP transmission - Chapter 13 - simple.pyimport sys, smtplibif len(sys.argv) < 4: print "usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0] sys.exit(2)server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:]message = """To: %sFrom: %sSubject: Test Message from simple.py

Hello,

This is a test message sent to you from the simple.py programin Foundations of Python Network Programming.""" % (', '.join(toaddrs), fromaddr)

s = smtplib.SMTP(server)s.sendmail(fromaddr, toaddrs, message)print "Message successfully sent to %d recipient(s)" % len(toaddrs)