2
#include <sys/types.h> // getaddrinfo, gai_strerror, socket, inet_pton
4
#include <sys/socket.h> // getaddrinfo, gai_strerror, socket, inet_pton
6
#include <unistd.h> // close, STDIN_FILENO, STDOUT_FILENO
7
#include <netdb.h> // getaddrinfo, gai_strerror
8
#include <arpa/inet.h> // inet_pton
9
#include <sys/select.h> // select
10
#include <gnutls/gnutls.h>
11
#include <sys/ioctl.h> // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
12
#include <net/if.h> // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
13
#include <termios.h> // struct termios, tcsetattr, tcgetattr, TCSAFLUSH, ECHO
16
#include <cerrno> // perror
17
#include <cstring> // memset
18
#include <string> // std::string, std::getline
19
#include <iostream> // cin, cout, cerr
20
#include <ostream> // <<
22
#define SOCKET_ERR(err,s) if(err<0) {perror(s); status = 1; goto quit;}
24
#define CERTFILE "/conf/conf.d/cryptkeyreq/client-cert.pem"
25
#define KEYFILE "/conf/conf.d/cryptkeyreq/client-key.pem"
26
#define CAFILE "/conf/conf.d/cryptkeyreq/ca.pem"
28
gnutls_certificate_credentials_t x509_cred;
32
gnutls_session_t session;
35
std::cerr << "Initiate certificates\n";
38
gnutls_global_init ();
41
gnutls_certificate_allocate_credentials (&x509_cred);
42
gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE, GNUTLS_X509_FMT_PEM);
43
gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
47
gnutls_init (&session, GNUTLS_CLIENT);
48
gnutls_set_default_priority (session);
49
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
55
int udp_sd, tcp_sd, ret;
57
struct sockaddr_in6 to;
58
struct sockaddr_in6 from;
59
gnutls_session_t session;
61
struct timeval timeout;
63
struct termios t_old, t_new;
66
session = initgnutls ();
69
std::cerr << "Open ipv6 UDP\n";
72
udp_sd = socket(PF_INET6, SOCK_DGRAM, 0);
73
SOCKET_ERR(udp_sd,"socket");
76
std::cerr << "Open socket with socket nr: " << udp_sd << '\n';
81
ret = setsockopt(udp_sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
82
SOCKET_ERR(ret,"setsockopt broadcast");
85
ret = setsockopt(udp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
86
SOCKET_ERR(ret,"setsockopt bindtodevice");
88
memset (&to, '\0', sizeof (to));
89
to.sin6_family = AF_INET6;
90
ret = inet_pton(AF_INET6, "ff02::1" , &to.sin6_addr);
91
SOCKET_ERR(ret,"inet_pton");
92
to.sin6_port = htons (PORT); // Server Port number
96
strcpy(network.ifr_name, "eth0");
98
ret = ioctl(udp_sd, SIOCGIFFLAGS, &network);
99
SOCKET_ERR(ret,"ioctl SIOCGIFFLAGS");
101
network.ifr_flags |= IFF_UP;
103
ret = ioctl(udp_sd, SIOCSIFFLAGS, &network);
104
SOCKET_ERR(ret,"ioctl SIOCSIFFLAGS");
107
FD_SET(udp_sd, &rfds_orig);
108
FD_SET(STDIN_FILENO, &rfds_orig);
111
if (tcgetattr (STDIN_FILENO, &t_old) != 0){
115
t_new.c_lflag &= ~ECHO;
116
if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
124
std::cerr << "Sending Marco on UDP\n";
126
ret = sendto(udp_sd, "Marco", 5, 0, reinterpret_cast<const sockaddr*>(&to), sizeof(to));
131
fd_set rfds = rfds_orig;
135
std::cerr << "Password: ";
137
ret = select(udp_sd+1, &rfds, 0, 0, & timeout);
138
SOCKET_ERR(udp_sd,"select");
141
if (FD_ISSET(STDIN_FILENO, &rfds)){
143
std::getline(std::cin, buffer);
149
socklen_t from_len = sizeof(from);
150
ret = recvfrom(udp_sd,buffer,512,0, reinterpret_cast<sockaddr *>(& from),
152
SOCKET_ERR(ret,"recv");
154
if (strncmp(buffer,"Polo", 4) == 0){
162
tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
163
SOCKET_ERR(tcp_sd,"socket");
165
setsockopt(tcp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
166
SOCKET_ERR(ret,"setsockopt bindtodevice");
168
memset(&to,0,sizeof(to));
169
to.sin6_family = from.sin6_family;
170
to.sin6_port = from.sin6_port;
171
to.sin6_addr = from.sin6_addr;
172
to.sin6_scope_id = from.sin6_scope_id;
174
ret = connect(tcp_sd,reinterpret_cast<struct sockaddr *>(&to),sizeof(to));
180
gnutls_transport_set_ptr (session, reinterpret_cast<gnutls_transport_ptr_t> (tcp_sd));
182
ret = gnutls_handshake (session);
186
std::cerr << "\n*** Handshake failed ***\n";
192
ret = gnutls_record_recv (session, buffer, sizeof(buffer));
194
write(STDOUT_FILENO,buffer,ret);
197
gnutls_bye (session, GNUTLS_SHUT_RDWR);
199
gnutls_deinit (session);
200
gnutls_certificate_free_credentials (x509_cred);
201
gnutls_global_deinit ();
207
tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_old);