1 / 39

Chapter 4

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

baakir
Download Presentation

Chapter 4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 4 net_py

  2. 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.

  3. 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 NetworkManager domain newpaltz.edu search cs.newpaltz.edu acsl.newpaltz.edu newpaltz.edu nameserver 137.140.1.98 nameserver 137.140.1.102

  4. 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.camonly.

  5. 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.

  6. 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.

  7. 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

  8. 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.

  9. 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')

  10. 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.

  11. 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.

  12. 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

  13. 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))]

  14. 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))]

  15. net_py Alternative Methods: • Older methods are hard-wired for IPv4 so should be avoided. gethostbyname() getfqdn() gethostnbyaddr() getprotobyname(0 getservbyname() getservbyport() socket.gethostbyname(socket.getfqdn()) # gives you the primary IP address of this machine

  16. 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)

  17. net_py Using getaddrinfo() and getsockaddr(): info = infolist[0] # per standard recommendation, try the first one socket_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'

  18. net_py Just to be sure 1: #!/usr/bin/env python # Foundations of Python Network Programming - Chapter 4 - forward_reverse.py import 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 addresses canonical = info[3] socketname = info[4] ip = socketname[0]

  19. 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', ip print 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)

  20. 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'

  21. net_py Domain Name: List of labels in path of nodes DNS used for reverse (addr->name) lookup

  22. net_py Reverse lookup [pletcha@archimedes 04]$ host 137.140.1.48 48.1.140.137.in-addr.arpa domain name pointer www.newpaltz.edu.

  23. net_py DNS Packet

  24. net_py DNS Packet Q/R: 0/1 Opcode: Name or pointer AA: Answer is authoritative(1) TC: truncated RD: Recursion desired (1) RA: Recursion available (1) rcode: ) - ok, 3 – invalid name from AA

  25. net_py DNS Query

  26. net_py Wireshark look

  27. net_py DNS Query Response

  28. net_py Wireshark look:

  29. 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

  30. 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

  31. 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.

  32. net_py Email Servers: What protocols are involved in email. “your” mail server “their” mail server SMTP POP3 or IMAP SMTP their client: perhaps not running right now your client: browser, thunderbird

  33. net_py Email Servers: How to by-pass your local mail server. “your” mail server “their” mail server SMTP POP3 or IMAP SMTP SMTP their client: perhaps not running right now your client: a python program that knows how to send an email to a remote mail server (Chapter 13)

  34. 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).

  35. 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)

  36. 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

  37. 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])

  38. 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.

  39. net_py Sending a simple email message: [pletcha@archimedes 13]$ cat simple.py #!/usr/bin/env python # Basic SMTP transmission - Chapter 13 - simple.py import sys, smtplib if 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: %s From: %s Subject: Test Message from simple.py Hello, This is a test message sent to you from the simple.py program in 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)

More Related