aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli/socket_utils.h
blob: d52b5a0e7c61cb81a6adca1f4fd10ed279eb624f (plain)
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
103
104
105
/*
* (C) 2014,2017 Jack Lloyd
*     2017 René Korthaus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#ifndef BOTAN_CLI_SOCKET_UTILS_H_
#define BOTAN_CLI_SOCKET_UTILS_H_

#include <botan/build.h>
#include "cli_exceptions.h"

#if defined(BOTAN_TARGET_OS_HAS_WINSOCK2)

#include <winsock2.h>
#include <WS2tcpip.h>

typedef SOCKET socket_type;

inline socket_type invalid_socket() { return INVALID_SOCKET; }

typedef size_t ssize_t;
typedef int sendrecv_len_type;

inline void close_socket(socket_type s) { ::closesocket(s); }

#define STDIN_FILENO _fileno(stdin)

inline void init_sockets()
   {
   WSAData wsa_data;
   WORD wsa_version = MAKEWORD(2, 2);

   if(::WSAStartup(wsa_version, &wsa_data) != 0)
      {
      throw Botan_CLI::CLI_Error("WSAStartup() failed: " + std::to_string(WSAGetLastError()));
      }

   if(LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
      {
      ::WSACleanup();
      throw Botan_CLI::CLI_Error("Could not find a usable version of Winsock.dll");
      }
   }

inline void stop_sockets()
   {
   ::WSACleanup();
   }

inline std::string err_to_string(int e)
   {
   // TODO use strerror_s here
   return "Error code " + std::to_string(e);
   }

inline int close(int fd)
   {
   return ::closesocket(fd);
   }

inline int read(int s, void* buf, size_t len)
   {
   return ::recv(s, reinterpret_cast<char*>(buf), static_cast<int>(len), 0);
   }

inline int send(int s, const uint8_t* buf, size_t len, int flags)
   {
   return ::send(s, reinterpret_cast<const char*>(buf), static_cast<int>(len), flags);
   }

#elif defined(BOTAN_TARGET_OS_HAS_POSIX1)

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

typedef int socket_type;
typedef size_t sendrecv_len_type;

inline socket_type invalid_socket() { return -1; }
inline void close_socket(socket_type s) { ::close(s); }

inline void init_sockets() {}
inline void stop_sockets() {}

inline std::string err_to_string(int e)
   {
   return std::strerror(e);
   }

#endif

#if !defined(MSG_NOSIGNAL)
   #define MSG_NOSIGNAL 0
#endif

#endif