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;}
 
 
26
#define CERT_ROOT "/conf/conf.d/cryptkeyreq/"
 
 
28
#define CERTFILE CERT_ROOT "client-cert.pem"
 
 
29
#define KEYFILE CERT_ROOT "client-key.pem"
 
 
30
#define CAFILE CERT_ROOT "ca.pem"
 
 
32
gnutls_certificate_credentials_t x509_cred;
 
 
36
  gnutls_session_t session;
 
 
39
  std::cerr << "Initiate certificates\n";
 
 
42
  gnutls_global_init ();
 
 
45
  gnutls_certificate_allocate_credentials (&x509_cred);
 
 
46
  gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE, GNUTLS_X509_FMT_PEM);
 
 
47
  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
 
 
51
  gnutls_init (&session, GNUTLS_CLIENT);
 
 
52
  gnutls_set_default_priority (session);
 
 
53
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
 
 
59
  int udp_sd, tcp_sd, ret;
 
 
61
  struct sockaddr_in6 to;
 
 
62
  struct sockaddr_in6 from;
 
 
63
  gnutls_session_t session;
 
 
65
  struct timeval timeout;
 
 
67
  struct termios t_old, t_new;
 
 
70
  if (tcgetattr (STDIN_FILENO, &t_old) != 0){
 
 
74
  session = initgnutls ();
 
 
77
  std::cerr << "Open ipv6 UDP\n";
 
 
80
  udp_sd = socket(PF_INET6, SOCK_DGRAM, 0);
 
 
81
  SOCKET_ERR(udp_sd,"socket");
 
 
84
  std::cerr << "Open socket with socket nr: " << udp_sd << '\n';
 
 
89
    ret = setsockopt(udp_sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
 
 
90
    SOCKET_ERR(ret,"setsockopt broadcast");
 
 
93
  ret = setsockopt(udp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
 
 
94
  SOCKET_ERR(ret,"setsockopt bindtodevice");
 
 
96
  memset (&to, '\0', sizeof (to));
 
 
97
  to.sin6_family = AF_INET6;
 
 
98
  ret = inet_pton(AF_INET6, "ff02::1" , &to.sin6_addr);
 
 
99
  SOCKET_ERR(ret,"inet_pton");
 
 
100
  to.sin6_port = htons (PORT);  // Server Port number
 
 
102
  struct ifreq network;
 
 
104
  strcpy(network.ifr_name, "eth0");
 
 
106
  ret = ioctl(udp_sd, SIOCGIFFLAGS, &network);
 
 
107
  SOCKET_ERR(ret,"ioctl SIOCGIFFLAGS");
 
 
109
  network.ifr_flags |= IFF_UP;
 
 
111
  ret = ioctl(udp_sd, SIOCSIFFLAGS, &network);
 
 
112
  SOCKET_ERR(ret,"ioctl SIOCSIFFLAGS");
 
 
115
  FD_SET(udp_sd, &rfds_orig);
 
 
116
  FD_SET(STDIN_FILENO, &rfds_orig);
 
 
119
  t_new.c_lflag &= ~ECHO;
 
 
120
  if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
 
 
128
      std::cerr << "Sending Marco on UDP\n";
 
 
130
      ret = sendto(udp_sd, "Marco", 5, 0, reinterpret_cast<const sockaddr*>(&to), sizeof(to));
 
 
135
      fd_set rfds = rfds_orig;
 
 
139
      std::cerr << "Password: ";
 
 
141
      ret = select(udp_sd+1, &rfds, 0, 0, & timeout);
 
 
142
      SOCKET_ERR(udp_sd,"select");
 
 
145
        if (FD_ISSET(STDIN_FILENO, &rfds)){
 
 
147
          std::getline(std::cin, buffer);
 
 
153
        socklen_t from_len = sizeof(from);
 
 
154
        ret = recvfrom(udp_sd,buffer,512,0, reinterpret_cast<sockaddr *>(& from),
 
 
156
        SOCKET_ERR(ret,"recv");
 
 
158
        if (strncmp(buffer,"Polo", 4) == 0){
 
 
166
    tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
 
 
167
    SOCKET_ERR(tcp_sd,"socket");
 
 
169
    setsockopt(tcp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
 
 
170
    SOCKET_ERR(ret,"setsockopt bindtodevice");
 
 
172
    memset(&to,0,sizeof(to));
 
 
173
    to.sin6_family = from.sin6_family;
 
 
174
    to.sin6_port   = from.sin6_port;
 
 
175
    to.sin6_addr   = from.sin6_addr;
 
 
176
    to.sin6_scope_id   = from.sin6_scope_id;
 
 
178
    ret = connect(tcp_sd,reinterpret_cast<struct sockaddr *>(&to),sizeof(to));
 
 
184
    gnutls_transport_set_ptr (session, reinterpret_cast<gnutls_transport_ptr_t> (tcp_sd));
 
 
186
    ret = gnutls_handshake (session);
 
 
190
        std::cerr << "\n*** Handshake failed ***\n";
 
 
196
    ret = gnutls_record_recv (session, buffer, sizeof(buffer));
 
 
198
    write(STDOUT_FILENO,buffer,ret);
 
 
201
    gnutls_bye (session, GNUTLS_SHUT_RDWR);
 
 
203
    gnutls_deinit (session);
 
 
204
    gnutls_certificate_free_credentials (x509_cred);
 
 
205
    gnutls_global_deinit ();
 
 
211
  tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_old);