Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pc:laboratoare:11 [2022/05/14 02:40]
bogdan_costel.mocanu [Protocoalele SMTP, POP3 și IMAP]
pc:laboratoare:11 [2023/05/07 17:56] (current)
dorinel.filip [Exerciții] New domain
Line 137: Line 137:
  
 Dacă totuși domeniul se află la distanță, iar local nu este disponibilă nici o informație despre el, atunci serverul de nume trimite un mesaj de cerere către serverul de nume de pe primul nivel al domeniului solicitat. De menționat că metoda de interogare este recursivă (recursive query), deoarece fiecare server care nu are informația cerută o caută în altă parte și raportează. Dacă totuși domeniul se află la distanță, iar local nu este disponibilă nici o informație despre el, atunci serverul de nume trimite un mesaj de cerere către serverul de nume de pe primul nivel al domeniului solicitat. De menționat că metoda de interogare este recursivă (recursive query), deoarece fiecare server care nu are informația cerută o caută în altă parte și raportează.
 +
 +=== API DNS ===
 +
 +== gethostbyname() și gethostbyaddr() ==
 +
 +Până de curând, pentru a afla un nume pe baza unei adrese IP și o adresă pe baza unui nume, se foloseau funcțiile [[https://​linux.die.net/​man/​3/​gethostbyname|gethostbyname()]] și [[https://​linux.die.net/​man/​3/​gethostbyaddr|gethostbyaddr()]],​ împreună cu structura //​hostent//​. Între timp, acest API pentru DNS a fost scos din uz.
 +
 +== getaddrinfo() ==
 +
 +<code C>
 +#include <​sys/​types.h>​
 +#include <​sys/​socket.h>​
 +#include <​netdb.h>​
 +
 +int getaddrinfo(const char *node, const char *service,
 +                const struct addrinfo *hints, struct addrinfo **res);
 +</​code>​
 +
 +Funcția [[https://​linux.die.net/​man/​3/​getaddrinfo|getaddrinfo()]] primește informații despre numele unei gazde și al unui serviciu Internet, și returnează adresa sau adresele corespunzătoare. Parametrul //node// reprezintă numele simbolic (sub forma unui șir de caractere) al mașinii căreia vrem sa-i aflăm adresa (de exemplu, node poate fi “www.google.com”). Mai poate de asemenea fi reprezentat ca un șir care conține o adresă IPv4 sau IPv6.
 +
 +Parametrul //service// specifică portul returnat în output, și poate fi pus pe NULL (caz în care portul din output rămâne neinițializat) sau poate fi dat ca un nume de serviciu (de exemplu, “http”) sau ca o valoare numerică (“80”).
 +
 +Parametrul //hints// reprezintă criterii pentru filtrarea adreselor întoarse de apelul funcției //​getaddrinfo()//​. Este de tipul //struct addrinfo//, definit mai jos:
 +
 +<code C>
 +struct addrinfo {
 +    int              ai_flags;
 +    int              ai_family;
 +    int              ai_socktype;​
 +    int              ai_protocol;​
 +    socklen_t ​       ai_addrlen;
 +    struct sockaddr *ai_addr;
 +    char            *ai_canonname;​
 +    struct addrinfo *ai_next;
 +};
 +</​code>​
 +
 +În cazul în care se dorește filtrarea, se pot completa unul sau mai multe din următoarele câmpuri (restul punându-se pe 0):
 +
 +  * //​ai_family//​ - se specifică familia de adrese pentru valorile returnate, putând fi setată ca AF_INET (pentru IPv4), AF_INET6 (pentru IPv6) sau AF_UNSPEC (pentru ambele)
 +  * //​ai_socktype//​ - se filtrează după tipul de socket (SOCK_DGRAM sau SOCK_STREAM,​ de exemplu)
 +  * //​ai_protocol//​ - se specifică protocolul setat în adresele returnate de funcția //​getaddrinfo()//​
 +  * //​ai_flags//​ - se pot seta o serie de flag-uri.
 +
 +În final, rezultatul este pus în parametrul //res//, fiind reprezentat ca o listă înlănțuită de structuri de tipul //​addrinfo//,​ care se parcurge prin intermediul câmpului //​ai_next//​. Din câmpul //ai_addr// al rezultatului,​ se pot citi informațiile despre adresa și portul stației gazdă căutate (prin cast la //struct sockaddr_in//,​ de exemplu).
 +
 +În caz de succes, funcția întoarce 0, iar în caz de eroare întoarce o valoare negativă, care poate fi interpretată prin intermediul funcției //​gai_strerror()//:​
 +
 +<code C>
 +const char *gai_strerror(int errcode);
 +</​code>​
 +
 +<note important>​
 +Parametrul //res// este alocat de către funcția //​getaddrinfo()//,​ însă el trebuie dezalocat explicit de către utilizator prin intermediul funcției //​freeaddrinfo()//:​
 +
 +<code C>
 +void freeaddrinfo(struct addrinfo *res);
 +</​code>​
 +</​note>​
 +
 +Pentru a afișa adresa IP (v4 sau v6) corespunzătoare numelui simbolic din parametrul //node//, se poate utiliza funcția //​inet_ntop()//:​
 +
 +<code C>
 +#include <​arpa/​inet.h>​
 +
 +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
 +</​code>​
 +
 +Primul parametrul specifică familia de protocoale (AF_INET sau AF_INET6), al doilea parametru reprezintă structura de adresă (adică, de exemplu, câmpurile //​sin_addr//​ sau //​sin6_addr//​ din structurile //​sockaddr_in//​ pentru IPv4 sau //​sockaddr_in6//​ pentru IPv6), al treilea parametru reprezintă un șir de caractere unde va fi scrisă adresa sub formă de string, iar ultimul parametru reprezintă dimensiunea șirului de caractere în octeți. Valoarea de retur a funcției este un pointer la un șir de caractere identic cu cel din parametrul //dst//, sau NULL în caz de eroare.
 +
 +== getnameinfo() ==
 +
 +
 +<code C>
 +#include <​sys/​socket.h>​
 +#include <​netdb.h>​
 +
 +int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *host,
 +                socklen_t hostlen, char *serv, socklen_t servlen, int flags);
 +</​code>​
 +
 +Funcția [[https://​linux.die.net/​man/​3/​getnameinfo|getnameinfo()]] realizează operația inversă față de //​getaddrinfo()//​. Mai precis, primește o adresă și returnează numele simbolic și serviciul specifice adresei respective. Primii doi parametri reprezintă adresa IP (v4 sau v6) care este căutată. Se trimit structuri specifice protocolului dorit (//​sockaddr_in//​ sau //​sockaddr_in6//​) și dimensiunea lor. Rezultatele apelului sunt puse în șirurile de caractere //host// și //serv//, care sunt alocate de către utilizator. Parametrii //hostlen// și //servlen// reprezintă dimensiunile celor două șiruri de caractere.
 +
 +Funcția returnează 0 dacă s-a reușit cererea DNS, sau o valoare negativă interpretată cu //​gai_strerror()//​ în caz contrar.
 +
 +=== Cereri DNS în Linux ===
 +
 +În Linux, pentru a obține adresele IP ale unei gazde, putem folosi unul din utilitarele //host// sau //​nslookup//:​
 +
 +<​code>​
 +$ host google.com
 +google.com has address 172.217.20.14
 +google.com has IPv6 address 2a00:​1450:​400d:​804::​200e
 +google.com mail is handled by 30 alt2.aspmx.l.google.com.
 +google.com mail is handled by 50 alt4.aspmx.l.google.com.
 +google.com mail is handled by 20 alt1.aspmx.l.google.com.
 +google.com mail is handled by 10 aspmx.l.google.com.
 +google.com mail is handled by 40 alt3.aspmx.l.google.com.
 +</​code>​
 +
 +<​code>​
 +$ nslookup google.com
 +Server:​ 192.168.100.1
 +Address:​ 192.168.100.1#​53
 +
 +Non-authoritative answer:
 +Name:​ google.com
 +Address: 172.217.20.14
 +</​code>​
 +
 +Pentru aflarea unui nume pe baza unei adrese IP, se pot folosi tot //host// sau //​nslookup//:​
 +
 +<​code>​
 +$ host 8.8.8.8
 +8.8.8.8.in-addr.arpa domain name pointer dns.google.
 +</​code>​
 +
 +<​code>​
 +$ nslookup 8.8.8.8
 +8.8.8.8.in-addr.arpa name = dns.google.
 +
 +Authoritative answers can be found from:
 +in-addr.arpa nameserver = a.in-addr-servers.arpa.
 +in-addr.arpa nameserver = b.in-addr-servers.arpa.
 +in-addr.arpa nameserver = c.in-addr-servers.arpa.
 +in-addr.arpa nameserver = e.in-addr-servers.arpa.
 +in-addr.arpa nameserver = d.in-addr-servers.arpa.
 +in-addr.arpa nameserver = f.in-addr-servers.arpa.
 +</​code>​
 +
 +Un exemplu de output //tcpdump// pentru comanda //host// este mai jos (unde 53 este portul implicit pentru DNS):
 +
 +<​code>​
 +$ sudo tcpdump port 53
 +tcpdump: data link type PKTAP
 +tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
 +listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
 +
 +08:​12:​17.446368 IP 192.168.100.4.63991 > 192.168.100.1.domain:​ 31461+ A? google.com. (28)
 +08:​12:​17.450412 IP 192.168.100.1.domain > 192.168.100.4.63991:​ 31461 1/0/0 A 172.217.16.110 (44)
 +08:​12:​18.455598 IP 192.168.100.4.58146 > 192.168.100.1.domain:​ 4039+ AAAA? google.com. (28)
 +08:​12:​18.463761 IP 192.168.100.1.domain > 192.168.100.4.58146:​ 4039 1/0/0 AAAA 2a00:​1450:​400d:​803::​200e (56)
 +08:​12:​19.467330 IP 192.168.100.4.53016 > 192.168.100.1.domain:​ 58519+ MX? google.com. (28)
 +08:​12:​19.514778 IP 192.168.100.1.domain > 192.168.100.4.53016:​ 58519 5/0/0 MX alt3.aspmx.l.google.com. 40,
 +MX alt4.aspmx.l.google.com. 50, MX aspmx.l.google.com. 10, MX alt1.aspmx.l.google.com. 20,
 +MX alt2.aspmx.l.google.com. 30 (136)
 +</​code>​
 +
  
 === Utilitarul dig === === Utilitarul dig ===
Line 472: Line 620:
 ==== Suportul de laborator ==== ==== Suportul de laborator ====
  
-===I. Email=== + 
-Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/Email|aici]] un cod sursă schelet pentru realizarea unui client de email SMTP scris in C. Veți folosi un server SMTP acre rulează local. Acesta poate fi creat folosind un utilitar existent în Python, numit //smtpd//. Rularea acestui utiliar pe portul 25 se face astfel:+===I. DNS=== 
 +Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​master/​lab11|aici]] un cod sursă schelet pentru realizarea unei aplicații in C care utilizează API-ul DNS 
 + 
 +===II. Email=== 
 +Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/-/​tree/​master/​lab11|aici]] un cod sursă schelet pentru realizarea unui client de email SMTP scris in C. Veți folosi un server SMTP acre rulează local. Acesta poate fi creat folosind un utilitar existent în Python, numit //smtpd//. Rularea acestui utiliar pe portul 25 se face astfel:
  
 <​code>​ <​code>​
Line 483: Line 635:
 </​note>​ </​note>​
  
-===II. DNS=== 
-Va oferim [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/​dns|aici]] un cod sursă schelet pentru realizarea unei aplicații in C care utilizează API-ul DNS.  
  
  
 ==== Exerciții ==== ==== Exerciții ====
  
-===I. E-mail=== +===I. DNS===
-Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/​Email|aici]],​ implementați următoatrea cerință:+
  
-1. Implementați un client SMTP peste TCP prin care să trimiteți către serverul //smtpd// un e-mail care conține niște text și un fișier dat ca parametru sub forma unui atașament de tip //​text/​plain//​ (API-ul necesar pentru conexiunea TCP cu server-ul este detaliat în [[https://​ocw.cs.pub.ro/​courses/​pc/​laboratoare/​07|laboratorul 7]]). +Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​master/​lab11|aici]], implementați următoatrea cerință:
- +
-== Bonus == +
- +
-  - Folosind instrucțiunile de [[https://​www.dropbox.com/​s/​d382g7f705uo6bq/​SMTP_Google.pdf?​dl=0|aici]],​ trimiteți un e-mail către asistent prin intermediul serverului SMTP de la Google. +
- +
-===II. DNS=== +
- +
-Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​bogdan_costel.mocanu-master-patch-08393/dns|aici]], implementați următoatrea cerință:+
  
 1. Scrieți un program care să afișeze numele și adresele IP pentru un host. Programul poate primi ca parametru fie numele (caz în care se va afișa adresa), fie adresa IP (caz în care se va afișa numele). Testați-va programul folosind informațiile din tabelul de mai jos. Exemplu de apel: <​code>​ 1. Scrieți un program care să afișeze numele și adresele IP pentru un host. Programul poate primi ca parametru fie numele (caz în care se va afișa adresa), fie adresa IP (caz în care se va afișa numele). Testați-va programul folosind informațiile din tabelul de mai jos. Exemplu de apel: <​code>​
Line 513: Line 654:
 ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^ ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^
 |  **Pentru single-v4 există o singură adresă IPv4** ​                                                                  ||||| |  **Pentru single-v4 există o singură adresă IPv4** ​                                                                  |||||
-|  A      |  single-v4.protocoale.xyz   |  127.0.0.1 ​                       |  300                                         |+|  A      |  single-v4.protocoale.life   |  127.0.0.1 ​                       |  300                                         |
 |  **Pentru single-v4 există o singură adresă IPv6** ​                                                                  ||||| |  **Pentru single-v4 există o singură adresă IPv6** ​                                                                  |||||
-|  AAAA   ​| ​ single-v6.protocoale.xyz   |  ::1                              |  300                                         |+|  AAAA   ​| ​ single-v6.protocoale.life   |  ::1                              |  300                                         |
 |  ** Pentru single se definesc 2 adrese (una IPv4 si una IPv6)** ​                                                     ||||| |  ** Pentru single se definesc 2 adrese (una IPv4 si una IPv6)** ​                                                     |||||
-|  A      |  single.protocoale.xyz      ​| ​ 127.0.0.1 ​                       |  300                                         | +|  A      |  single.protocoale.life      ​| ​ 127.0.0.1 ​                       |  300                                         | 
-|  AAAA   ​| ​ single.protocoale.xyz      ​| ​ ::1                              |  300                                         | +|  AAAA   ​| ​ single.protocoale.life      ​| ​ ::1                              |  300                                         | 
-|  **Spațiul dorinel.protocoale.xyz este delegat către un alt server de nume ce rulează la adresa potato.dfilip.xyz** ​ ||||| +|  **Spațiul dorinel.protocoale.life este delegat către un alt server de nume ce rulează la adresa potato.dfilip.xyz** ​ ||||| 
-|  NS     ​| ​ dorinel.protocoale.xyz     |  potato.dfilip.xyz ​               |  300                                         |+|  NS     ​| ​ dorinel.protocoale.life     |  potato.dfilip.xyz ​               |  300                                         |
 |  **Pentru multi-v4 există 4 adrese IPv4** ​                                                                           ||||| |  **Pentru multi-v4 există 4 adrese IPv4** ​                                                                           |||||
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.1.1.1 ​                       |  300                                         | +|  A      |  multi-v4.protocoale.life    ​| ​ 127.1.1.1 ​                       |  300                                         | 
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.2.2.2 ​                       |  300                                         | +|  A      |  multi-v4.protocoale.life    ​| ​ 127.2.2.2 ​                       |  300                                         | 
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.3.3.3 ​                       |  300                                         | +|  A      |  multi-v4.protocoale.life    ​| ​ 127.3.3.3 ​                       |  300                                         | 
-|  A      |  multi-v4.protocoale.xyz    ​| ​ 127.4.4.4 ​                       |  300                                         |+|  A      |  multi-v4.protocoale.life    ​| ​ 127.4.4.4 ​                       |  300                                         |
 |  **Pentru multi-v6 există 4 adrese IPv6** ​                                                                           ||||| |  **Pentru multi-v6 există 4 adrese IPv6** ​                                                                           |||||
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::1                              |  300                                         | +|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::1                              |  300                                         | 
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::2                              |  300                                         | +|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::2                              |  300                                         | 
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::3                              |  300                                         | +|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::3                              |  300                                         | 
-|  AAAA   ​| ​ multi-v6.protocoale.xyz    ​| ​ ::4                              |  300                                         |+|  AAAA   ​| ​ multi-v6.protocoale.life    ​| ​ ::4                              |  300                                         |
 |  **Pentru multi se definesc 8 adrese (4 de IPv4 și 4 de IPv6)** ​                                                     ||||| |  **Pentru multi se definesc 8 adrese (4 de IPv4 și 4 de IPv6)** ​                                                     |||||
-|  A      |  multi.protocoale.xyz       |  127.1.1.1 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.1.1.1 ​                       |  300                                         | 
-|  A      |  multi.protocoale.xyz       |  127.2.2.2 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.2.2.2 ​                       |  300                                         | 
-|  A      |  multi.protocoale.xyz       |  127.3.3.3 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.3.3.3 ​                       |  300                                         | 
-|  A      |  multi.protocoale.xyz       |  127.4.4.4 ​                       |  300                                         | +|  A      |  multi.protocoale.life       |  127.4.4.4 ​                       |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::1                              |  300                                         | +|  AAAA   ​| ​ multi.protocoale.life       |  ::1                              |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::2                              |  300                                         | +|  AAAA   ​| ​ multi.protocoale.life       |  ::2                              |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::3                              |  300                                         | +|  AAAA   ​| ​ multi.protocoale.life       |  ::3                              |  300                                         | 
-|  AAAA   ​| ​ multi.protocoale.xyz       |  ::4                              |  300                                         ​|  ​+|  AAAA   ​| ​ multi.protocoale.life       |  ::4                              |  300                                         ​|  ​
 |  **Adresele pc->​pcom->​protocoale definesc un șir de nume canonice care are la capăt o adresă IPv4** ​                 ||||| |  **Adresele pc->​pcom->​protocoale definesc un șir de nume canonice care are la capăt o adresă IPv4** ​                 |||||
-|  CNAME  |  pc.protocoale.xyz          ​| ​ pcom.protocoale.xyz              ​| ​ 300                                         | +|  CNAME  |  pc.protocoale.life          ​| ​ pcom.protocoale.life              ​| ​ 300                                         | 
-|  CNAME  |  pcom.protocoale.xyz        ​| ​ protocoale.protocoale.xyz        ​| ​ 300                                         | +|  CNAME  |  pcom.protocoale.life        ​| ​ protocoale.protocoale.life        ​| ​ 300                                         | 
-|  A      |  protocoale.protocoale.xyz  ​| ​ 127.42.42.42 ​                    ​| ​ 300                                         |+|  A      |  protocoale.protocoale.life  ​| ​ 127.42.42.42 ​                    ​| ​ 300                                         |
 |  **Emailul este deservit de 3 servere SMTP cu priorități diferite** ​                                                 ||||| |  **Emailul este deservit de 3 servere SMTP cu priorități diferite** ​                                                 |||||
-|  MX     ​| ​ protocoale.xyz             |  alt1.gmail-smtp-in.l.google.com ​ |  300  |  10                                  | +|  MX     ​| ​ protocoale.life             |  alt1.gmail-smtp-in.l.google.com ​ |  300  |  10                                  | 
-|  MX     ​| ​ protocoale.xyz             |  alt2.gmail-smtp-in.l.google.com ​ |  300  |  20                                  | +|  MX     ​| ​ protocoale.life             |  alt2.gmail-smtp-in.l.google.com ​ |  300  |  20                                  | 
-|  MX     ​| ​ protocoale.xyz             |  alt3.gmail-smtp-in.l.google.com ​ |  300  |  30                                  |+|  MX     ​| ​ protocoale.life             |  alt3.gmail-smtp-in.l.google.com ​ |  300  |  30                                  |
 ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^ ^  Tip    ^  Gazdă ​                     ^  Răspuns ​                         ^  TTL  ^  Prioritate ​                         ^
 </​spoiler>​ </​spoiler>​
  
  
 +===II. E-mail===
 +Pornind de la codul disponibil [[https://​gitlab.cs.pub.ro/​protocoale-de-comunicatie/​pcom-laboratoare-public/​-/​tree/​master/​lab11|aici]],​ implementați următoatrea cerință:
 +
 +1. Implementați un client SMTP peste TCP prin care să trimiteți către serverul //smtpd// un e-mail care conține niște text și un fișier dat ca parametru sub forma unui atașament de tip //​text/​plain//​ (API-ul necesar pentru conexiunea TCP cu server-ul este detaliat în [[https://​ocw.cs.pub.ro/​courses/​pc/​laboratoare/​07|laboratorul 7]]).
 +
 +== Bonus ==
 +
 +  - Folosind instrucțiunile de [[https://​www.dropbox.com/​s/​d382g7f705uo6bq/​SMTP_Google.pdf?​dl=0|aici]],​ trimiteți un e-mail către asistent prin intermediul serverului SMTP de la Google.
pc/laboratoare/11.1652485214.txt.gz · Last modified: 2022/05/14 02:40 by bogdan_costel.mocanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0