Raw File
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h> // for read...
#include <stdlib.h> // for atoi...
#include "debug.h"
#include "ip.h"
const int BACK_LOG = 5;
int ip_init_server_conn(char *ip, int port) {
char *ip_addr = NULL;
int sSocket = 0, on = 0, rc = 0;
struct sockaddr_in serverName = { 0 };
char * tmp;
LOG_ENTER();
// Handle special case ":<port>"
// Without it, ip_add will be set to port and port will be null
if(ip != NULL) {
if(ip[0] == ':') {
ip = &ip[1];
}
if (strchr(ip, ':') != NULL) {
ip_addr = strtok(ip, ":");
tmp = strtok(NULL,":");
if(tmp != NULL && strlen(tmp) > 0) {
port = (atoi(tmp));
}
} else if(strlen(ip) > 0) {
port = (atoi(ip));
}
}
LOG(LOG_DEBUG, "Creating server socket");
sSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (-1 == sSocket) {
ELOG(LOG_FATAL, "Server socket could not be created");
} else {
/*
* turn off bind address checking, and allow
* port numbers to be reused - otherwise
* the TIME_WAIT phenomenon will prevent
* binding to these addresses.
*/
on = 1;
rc = setsockopt(sSocket,
SOL_SOCKET,
SO_REUSEADDR,
(const char *) &on,
sizeof(on)
);
if (-1 == rc) {
ELOG(LOG_ERROR, "bind address checking could not be turned off");
}
if (ip_addr != NULL && strcmp(ip_addr,"") != 0) { /* changed to strcmp test -04Mar17 gwb */
LOG(LOG_DEBUG, "Using specified ip address '%s'", ip_addr);
serverName.sin_addr.s_addr = inet_addr(ip_addr);
} else {
serverName.sin_addr.s_addr = htonl(INADDR_ANY);
}
serverName.sin_family = AF_INET;
/* network-order */
serverName.sin_port = htons(port);
LOG(LOG_DEBUG, "Binding server socket to port %d", port);
rc = bind(sSocket,
(struct sockaddr *) &serverName,
sizeof(serverName)
);
if (-1 == rc) {
ELOG(LOG_FATAL, "Server socket could not be bound to port");
sSocket = -1;
} else {
LOG(LOG_INFO, "Server socket bound to port");
rc = listen(sSocket, BACK_LOG);
LOG(LOG_INFO, "Server socket listening for connections");
if (-1 == rc) {
ELOG(LOG_FATAL, "Server socket could not listen on port");
sSocket = -1;
}
}
}
LOG_EXIT();
return sSocket;
}
int ip_connect(char *ip) {
struct sockaddr_in pin;
struct in_addr cin_addr;
struct hostent *hp;
int sd = 0;
int port = 23;
char *address;
char *tmp;
LOG_ENTER();
// TODO Can ip be null? If so, fix.
address = strtok(ip, ":");
tmp = strtok(NULL, ":");
if(tmp != NULL && strlen(tmp) > 0) {
port = atoi(tmp);
}
LOG(LOG_DEBUG, "Calling %s", ip);
memset(&pin, 0, sizeof(pin));
/* go find out about the desired host machine */
if((hp = gethostbyname(address)) == 0) {
// well, not a DNS entry... Treat as IP...
if(1 != inet_aton(address, &cin_addr)) {
ELOG(LOG_ERROR, "Host %s was invalid", ip);
return -1;
}
} else {
cin_addr = *((struct in_addr *)(hp->h_addr));
}
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = cin_addr.s_addr;
pin.sin_port = htons(port);
/* grab an Internet domain socket */
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
ELOG(LOG_ERROR, "could not create client socket");
return -1;
}
/* connect to PORT on HOST */
if (connect(sd, (struct sockaddr *)&pin, sizeof(pin)) == -1) {
ELOG(LOG_ERROR, "could not connect to address");
return -1;
}
LOG(LOG_INFO, "Connection to %s established", ip);
LOG_EXIT();
return sd;
}
int ip_accept(int sSocket) {
struct sockaddr_in clientName = { 0 };
socklen_t clientLength = sizeof(clientName);
int cSocket = -1;
LOG_ENTER();
(void) memset(&clientName, 0, sizeof(clientName));
cSocket = accept(sSocket,
(struct sockaddr *)&clientName,
&clientLength
);
if (-1 == cSocket) {
ELOG(LOG_ERROR, "Could not accept incoming connection");
return -1;
}
if(-1 == getpeername(cSocket,
(struct sockaddr *)&clientName,
&clientLength
)) {
ELOG(LOG_WARN, "Could not obtain peer name");
} else {
LOG(LOG_INFO,
"Connection accepted from %s",
inet_ntoa(clientName.sin_addr)
);
}
LOG_EXIT();
return cSocket;
}
int ip_disconnect(int fd) {
if(fd > -1)
close(fd);
return 0;
}
int ip_write(int fd, unsigned char *data, int len) {
log_trace(TRACE_IP_OUT, data, len);
return write(fd, data, len);
}
int ip_read(int fd, unsigned char *data, int len) {
int res;
res = recv(fd, data, len, 0);
if(0 < res)
log_trace(TRACE_IP_IN, data, res);
return res;
}
Generated by GNU Enscript 1.6.6, and GophHub 1.3.