Raw File
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <netinet/in.h>
4 #include <arpa/inet.h>
5 #include <netdb.h>
6 #include <unistd.h> // for read...
7 #include <stdlib.h> // for atoi...
8
9 #include "debug.h"
10 #include "ip.h"
11
12 const int BACK_LOG = 5;
13
14 int ip_init_server_conn(char *ip, int port) {
15 char *ip_addr = NULL;
16 int sSocket = 0, on = 0, rc = 0;
17 struct sockaddr_in serverName = { 0 };
18 char * tmp;
19
20 LOG_ENTER();
21
22 // Handle special case ":<port>"
23 // Without it, ip_add will be set to port and port will be null
24
25 if(ip != NULL) {
26 if(ip[0] == ':') {
27 ip = &ip[1];
28 }
29 if (strchr(ip, ':') != NULL) {
30 ip_addr = strtok(ip, ":");
31 tmp = strtok(NULL,":");
32 if(tmp != NULL && strlen(tmp) > 0) {
33 port = (atoi(tmp));
34 }
35 } else if(strlen(ip) > 0) {
36 port = (atoi(ip));
37 }
38 }
39
40 LOG(LOG_DEBUG, "Creating server socket");
41
42 sSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
43 if (-1 == sSocket) {
44 ELOG(LOG_FATAL, "Server socket could not be created");
45 } else {
46
47 /*
48 * turn off bind address checking, and allow
49 * port numbers to be reused - otherwise
50 * the TIME_WAIT phenomenon will prevent
51 * binding to these addresses.
52 */
53
54 on = 1;
55
56 rc = setsockopt(sSocket,
57 SOL_SOCKET,
58 SO_REUSEADDR,
59 (const char *) &on,
60 sizeof(on)
61 );
62 if (-1 == rc) {
63 ELOG(LOG_ERROR, "bind address checking could not be turned off");
64 }
65
66 if (ip_addr != NULL && strcmp(ip_addr,"") != 0) { /* changed to strcmp test -04Mar17 gwb */
67 LOG(LOG_DEBUG, "Using specified ip address '%s'", ip_addr);
68 serverName.sin_addr.s_addr = inet_addr(ip_addr);
69 } else {
70 serverName.sin_addr.s_addr = htonl(INADDR_ANY);
71 }
72 serverName.sin_family = AF_INET;
73
74 /* network-order */
75 serverName.sin_port = htons(port);
76
77 LOG(LOG_DEBUG, "Binding server socket to port %d", port);
78 rc = bind(sSocket,
79 (struct sockaddr *) &serverName,
80 sizeof(serverName)
81 );
82
83 if (-1 == rc) {
84 ELOG(LOG_FATAL, "Server socket could not be bound to port");
85 sSocket = -1;
86 } else {
87 LOG(LOG_INFO, "Server socket bound to port");
88
89 rc = listen(sSocket, BACK_LOG);
90 LOG(LOG_INFO, "Server socket listening for connections");
91 if (-1 == rc) {
92 ELOG(LOG_FATAL, "Server socket could not listen on port");
93 sSocket = -1;
94 }
95 }
96 }
97 LOG_EXIT();
98 return sSocket;
99 }
100
101 int ip_connect(char *ip) {
102 struct sockaddr_in pin;
103 struct in_addr cin_addr;
104 struct hostent *hp;
105 int sd = 0;
106 int port = 23;
107 char *address;
108 char *tmp;
109
110 LOG_ENTER();
111 // TODO Can ip be null? If so, fix.
112 address = strtok(ip, ":");
113 tmp = strtok(NULL, ":");
114 if(tmp != NULL && strlen(tmp) > 0) {
115 port = atoi(tmp);
116 }
117
118 LOG(LOG_DEBUG, "Calling %s", ip);
119 memset(&pin, 0, sizeof(pin));
120
121 /* go find out about the desired host machine */
122 if((hp = gethostbyname(address)) == 0) {
123 // well, not a DNS entry... Treat as IP...
124 if(1 != inet_aton(address, &cin_addr)) {
125 ELOG(LOG_ERROR, "Host %s was invalid", ip);
126 return -1;
127 }
128 } else {
129 cin_addr = *((struct in_addr *)(hp->h_addr));
130 }
131
132 pin.sin_family = AF_INET;
133 pin.sin_addr.s_addr = cin_addr.s_addr;
134 pin.sin_port = htons(port);
135
136 /* grab an Internet domain socket */
137 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
138 ELOG(LOG_ERROR, "could not create client socket");
139 return -1;
140 }
141
142 /* connect to PORT on HOST */
143 if (connect(sd, (struct sockaddr *)&pin, sizeof(pin)) == -1) {
144 ELOG(LOG_ERROR, "could not connect to address");
145 return -1;
146 }
147 LOG(LOG_INFO, "Connection to %s established", ip);
148 LOG_EXIT();
149 return sd;
150 }
151
152 int ip_accept(int sSocket) {
153 struct sockaddr_in clientName = { 0 };
154 socklen_t clientLength = sizeof(clientName);
155 int cSocket = -1;
156
157 LOG_ENTER();
158 (void) memset(&clientName, 0, sizeof(clientName));
159
160 cSocket = accept(sSocket,
161 (struct sockaddr *)&clientName,
162 &clientLength
163 );
164 if (-1 == cSocket) {
165 ELOG(LOG_ERROR, "Could not accept incoming connection");
166 return -1;
167 }
168
169 if(-1 == getpeername(cSocket,
170 (struct sockaddr *)&clientName,
171 &clientLength
172 )) {
173 ELOG(LOG_WARN, "Could not obtain peer name");
174 } else {
175 LOG(LOG_INFO,
176 "Connection accepted from %s",
177 inet_ntoa(clientName.sin_addr)
178 );
179 }
180 LOG_EXIT();
181 return cSocket;
182 }
183
184 int ip_disconnect(int fd) {
185 if(fd > -1)
186 close(fd);
187 return 0;
188 }
189
190 int ip_write(int fd, unsigned char *data, int len) {
191 log_trace(TRACE_IP_OUT, data, len);
192 return write(fd, data, len);
193 }
194
195 int ip_read(int fd, unsigned char *data, int len) {
196 int res;
197
198 res = recv(fd, data, len, 0);
199 if(0 < res)
200 log_trace(TRACE_IP_IN, data, res);
201 return res;
202 }
203
Generated by GNU Enscript 1.6.6, and GophHub 1.3.