-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathresolve_name.cpp
More file actions
102 lines (92 loc) · 2.88 KB
/
resolve_name.cpp
File metadata and controls
102 lines (92 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "resolver.h"
#include <exception>
#include <iostream>
/*
* Includes necesarios para `inet_ntoa`
* */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*
* Modo de uso:
*
* ./resolve_name <hostname> [<servname>]
*
* Por ejemplo:
*
* ./resolve_name google.com
* ./resolve_name fi.uba.ar https
*
* El resolver imprime por pantalla la o las IPv4
* que el hostname tiene asociado. Si se pasa un servicio
* también se imprime el puerto TCP.
*
* */
int main(int argc, char *argv[]) { try {
const char *hostname = NULL;
const char *servname = NULL;
if (argc == 2) {
hostname = argv[1];
} else if (argc == 3) {
hostname = argv[1];
servname = argv[2];
} else {
std::cerr <<
"Bad program call. Expected "
<< argv[0]
<< " <hostname> [<servname>]\n";
return -1;
}
/*
* El TDA `Resolver` se encargara de resolver el hostname/service name
* encapsulando todos los detalles que no nos interesan saber.
*
* En particular el TDA se encarga de realizar todos los chequeos de errores
* por nosotros y retornar un único código que en C (así como en Golang)
* tenemos que chequear nosotros.
* */
Resolver resolver(hostname, servname, false);
/*
* Recorda que `Resolver` te da una lista de direcciones
* (que vienen de `getaddrinfo`)
*
* Un mismo nombre puede resolverse a múltiples direcciones que
* sirven como balanceo de carga y redundancia.
*
* Para los fines de `resolve_name`, solo nos interesa imprimir
* la dirección IPv4 con la notación típica `a.b.c.d`.
*
* `inet_ntoa` es solo para direcciones IPv4! Este programa
* no soporta IPv6.
* */
while (resolver.has_next()) {
struct addrinfo *rp = resolver.next();
struct sockaddr_in *skt_addr = (struct sockaddr_in*)rp->ai_addr;
struct in_addr internet_addr = skt_addr->sin_addr;
/*
* Según la documentación de `inet_ntoa`, el puerto (`uint16_t`)
* que esta en la estructura `sockaddr_in` esta en big endian
* no importa el endianness de la máquina.
*
* Para imprimir el número y que tenga sentido hay que
* convertirlo al endianness nativo de la máquina.
*
* network-to-host-short, o `ntohs`.
* */
uint16_t port = ntohs(skt_addr->sin_port);
std::cout << "IPv4: " << inet_ntoa(internet_addr);
if (port)
std::cout << " (port " << port << ")";
std::cout << "\n";
}
return 0;
} catch (const std::exception& err) {
std::cerr
<< "Something went wrong and an exception was caught: "
<< err.what()
<< "\n";
return -1;
} catch (...) {
std::cerr << "Something went wrong and an unknown exception was caught.\n";
return -1;
} }