-
Notifications
You must be signed in to change notification settings - Fork 79
/
connectioninfo.c
122 lines (103 loc) · 3.53 KB
/
connectioninfo.c
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
20140131
Jan Mojzis
Public domain.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "e.h"
#include "byte.h"
#include "iptostr.h"
#include "porttostr.h"
#include "env.h"
#include "str.h"
#include "connectioninfo.h"
/*
The connectioninfo_fromfd function gets
informations about TCP connection from
getsockname(), getpeername() libc functions.
*/
static int connectioninfo_fromfd(char *localip, char *localport, char *remoteip, char *remoteport) {
long long i;
struct sockaddr_storage sa;
socklen_t salen;
int fd = 0;
unsigned char ip[16];
unsigned char port[2];
char *ipstr[2];
char *portstr[2];
int (*op[2])(int, struct sockaddr *, socklen_t *) = { getsockname, getpeername };
ipstr[0] = localip; portstr[0] = localport;
ipstr[1] = remoteip; portstr[1] = remoteport;
for (i = 0; i < 2; ++i) {
salen = sizeof sa;
if (op[i](fd, (struct sockaddr *)&sa, &salen) == -1) return 0;
if (sa.ss_family == PF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
byte_copy(ip, 12, "\0\0\0\0\0\0\0\0\0\0\377\377");
byte_copy(ip + 12, 4, &sin->sin_addr);
byte_copy(port, 2, &sin->sin_port);
}
#ifdef PF_INET6
else if (sa.ss_family == PF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
byte_copy(ip, 16, &sin6->sin6_addr);
byte_copy(port, 2, &sin6->sin6_port);
}
#endif
else {
errno = EPROTONOSUPPORT;
return 0;
}
iptostr(ipstr[i], ip);
porttostr(portstr[i], port);
}
return 1;
}
static int env(char *y, long long ylen, const char *e) {
char *x;
x = env_get(e);
if (!x) return 0;
if (!str_copyn(y, ylen, x)) return 0;
return 1;
}
/*
The connectioninfo_fromtcpserverenv function gets
informations about TCP connection from environment.
*/
static int connectioninfo_fromtcpserverenv(char *localip, char *localport, char *remoteip, char *remoteport) {
if (!env(localip, IPTOSTR_LEN, "TCPLOCALIP")) return 0;
if (!env(localport, PORTTOSTR_LEN, "TCPLOCALPORT")) return 0;
if (!env(remoteip, IPTOSTR_LEN, "TCPREMOTEIP")) return 0;
if (!env(remoteport, PORTTOSTR_LEN, "TCPREMOTEPORT")) return 0;
return 1;
}
/*
The connectioninfo_fromcurvecpserverenv function gets
informations about CurveCP connection from environment.
*/
static int connectioninfo_fromcurvecpserverenv(char *localip, char *localport, char *remoteip, char *remoteport) {
if (!env(localip, IPTOSTR_LEN, "CURVECPLOCALIP")) return 0;
if (!env(localport, PORTTOSTR_LEN, "CURVECPLOCALPORT")) return 0;
if (!env(remoteip, IPTOSTR_LEN, "CURVECPREMOTEIP")) return 0;
if (!env(remoteport, PORTTOSTR_LEN, "CURVECPREMOTEPORT")) return 0;
return 1;
}
#define unknown "unknown"
#define port0 "0"
/*
The connectioninfo function gets informations about TCP/CurveCP connection.
*/
void connectioninfo(char *localip, char *localport, char *remoteip, char *remoteport) {
if (connectioninfo_fromtcpserverenv(localip, localport, remoteip, remoteport)) return;
if (connectioninfo_fromcurvecpserverenv(localip, localport, remoteip, remoteport)) return;
if (connectioninfo_fromfd(localip, localport, remoteip, remoteport)) return;
byte_copy(localip, sizeof unknown, unknown);
byte_copy(remoteip, sizeof unknown, unknown);
byte_copy(localport, sizeof port0, port0);
byte_copy(remoteport, sizeof port0, port0);
return;
}