4
4
#include <sys/socket.h> // getaddrinfo, gai_strerror, socket, inet_pton
6
#include <unistd.h> // close, STDIN_FILENO, STDOUT_FILENO
6
#include <unistd.h> // close
7
7
#include <netdb.h> // getaddrinfo, gai_strerror
8
8
#include <arpa/inet.h> // inet_pton
9
9
#include <sys/select.h> // select
10
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
13
#include <cstdio> // fprintf
16
14
#include <cerrno> // perror
17
15
#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;}
17
#define SOCKET_ERR(err,s) if(err<0) {perror(s);return(1);}
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"
19
#define CERTFILE "client-cert.pem"
20
#define KEYFILE "client-key.pem"
21
#define CAFILE "ca.pem"
32
23
gnutls_certificate_credentials_t x509_cred;
59
int udp_sd, tcp_sd, ret;
61
48
struct sockaddr_in6 to;
62
49
struct sockaddr_in6 from;
63
50
gnutls_session_t session;
65
52
struct timeval timeout;
67
struct termios t_old, t_new;
70
if (tcgetattr (STDIN_FILENO, &t_old) != 0){
74
54
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';
56
sd = socket(PF_INET6, SOCK_DGRAM, 0);
57
SOCKET_ERR(sd,"socket");
89
ret = setsockopt(udp_sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
61
ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
90
62
SOCKET_ERR(ret,"setsockopt broadcast");
93
ret = setsockopt(udp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
65
setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
94
66
SOCKET_ERR(ret,"setsockopt bindtodevice");
96
68
memset (&to, '\0', sizeof (to));
97
69
to.sin6_family = AF_INET6;
98
70
ret = inet_pton(AF_INET6, "ff02::1" , &to.sin6_addr);
99
SOCKET_ERR(ret,"inet_pton");
71
SOCKET_ERR(ret,"setsockopt bindtodevice");
100
72
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");
114
74
FD_ZERO(&rfds_orig);
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){
75
FD_SET(sd, &rfds_orig);
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 ();
82
sendto(sd, "Marco", 5, 0, reinterpret_cast<const sockaddr*>(&to), sizeof(to));
84
fd_set rfds = rfds_orig;
86
ret = select(sd+1, &rfds, 0, 0, & timeout);
87
SOCKET_ERR(sd,"select");
90
socklen_t from_len = sizeof(from);
91
ret = recvfrom(sd,buffer,512,0, reinterpret_cast<sockaddr *>(& from),
93
SOCKET_ERR(ret,"recv");
95
if (strncmp(buffer,"Polo", 4) == 0){
211
tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_old);
109
sd = socket(PF_INET6, SOCK_STREAM, 0);
110
SOCKET_ERR(sd,"socket");
112
setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
113
SOCKET_ERR(ret,"setsockopt bindtodevice");
115
memset(&to,0,sizeof(to));
116
to.sin6_family = from.sin6_family;
117
to.sin6_port = from.sin6_port;
118
to.sin6_addr = from.sin6_addr;
119
to.sin6_scope_id = from.sin6_scope_id;
121
ret = connect(sd,reinterpret_cast<struct sockaddr *>(&to),sizeof(to));
122
SOCKET_ERR(ret,"connect");
124
gnutls_transport_set_ptr (session, reinterpret_cast<gnutls_transport_ptr_t> (sd));
126
ret = gnutls_handshake (session);
130
fprintf (stderr, "*** Handshake failed\n");
134
printf ("- Handshake was completed\n");
136
//message to be seent
137
gnutls_record_send (session, "The secret message is \"squeamish ossifrage\"\n", 44);
140
gnutls_bye (session, GNUTLS_SHUT_RDWR);
142
gnutls_deinit (session);
143
gnutls_certificate_free_credentials (x509_cred);
144
gnutls_global_deinit ();