123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- /**************************************
- * AUTHOR: Federico Tomassini *
- * Copyright (C) Federico Tomassini *
- * Contact effetom@gmail.com *
- ***********************************************
- ******* BEGIN 4/2006 ********
- *************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- ************************************************************************/
-
- #include "log.h"
- #include "andns_net.h"
-
- int
- idp_inet_ntop(int family, struct sockaddr *addr, char *buf, int buflen)
- {
- const char *res;
- struct sockaddr_in *saddr;
- struct sockaddr_in6 *saddr6;
-
- switch (family) {
- case AF_INET:
- saddr = (struct sockaddr_in *) addr;
- res =
- inet_ntop(family, (void *) (&(saddr->sin_addr)), buf, buflen);
- break;
- case AF_INET6:
- saddr6 = (struct sockaddr_in6 *) addr;
- res =
- inet_ntop(family, (void *) (&(saddr6->sin6_addr)), buf,
- buflen);
- break;
- default:
- return -1;
- }
- if (!res)
- return -1;
- return 0;
- }
-
- /* Connection Layer */
-
- int
- w_socket(int family, int type, int proto, int die)
- {
- int sk;
- sk = socket(family, type, proto);
- if (sk == -1) {
- if (die)
- fatal("w_socket: %s.", strerror(errno));
- debug(DBG_NORMAL, "w_socket: %s.", strerror(errno));
- return -1;
- }
- return sk;
- }
-
- int
- w_connect(struct addrinfo *ai, int die)
- {
- int sk, res;
- sk = w_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, die);
- res = connect(sk, ai->ai_addr, ai->ai_addrlen);
- if (!res)
- return sk;
- if (die)
- fatal("Unable to connect: %s.", strerror(errno));
- debug(DBG_NORMAL, "w_connect: %s.", strerror(errno));
- close(sk);
- return -1;
- }
-
- int
- serial_connect(struct addrinfo *ai, int die)
- {
- int res;
- struct addrinfo *temp;
-
- temp = ai;
- if (!temp) {
- if (die)
- fatal("Unable to connect: no host specified.");
- debug(DBG_NORMAL, "serial_connect: no host specified.");
- return -1;
- }
- do {
- res = w_connect(temp, 0);
- temp = temp->ai_next;
- } while (res == -1 && temp);
- if (res == -1) {
- if (die)
- fatal("Unable to connect.");
- debug(DBG_NORMAL, "serial_connect: unable to connect.");
- return -1;
- }
- return res;
- }
-
- /*
- * host_connect returns a connected socket to (host,port)
- * endpoint. It is protocol independent.
- * -1 on error.
- */
- int
- host_connect(const char *host, uint16_t port, int type, int die)
- {
- int res;
- char portstr[6];
- struct addrinfo *ai, filter;
-
- memset(&filter, 0, sizeof(struct addrinfo));
- filter.ai_socktype = type;
- if (!host)
- fatal("w_connect: malicious call.");
- memset(portstr, 0, 6);
- res = snprintf(portstr, 6, "%d", port);
- if (res < 0 || res >= 6) {
- printf("Depousceve\n");
- return -1;
- }
- res = getaddrinfo(host, portstr, &filter, &ai);
- if (res != 0) {
- printf("w_connect: error %s.\n", gai_strerror(errno));
- return -1;
- }
- res = serial_connect(ai, die);
- freeaddrinfo(ai);
- return res;
- }
-
- int
- ai_connect(struct addrinfo *ai, int die, int free_ai)
- {
- int res;
-
- res = serial_connect(ai, die);
- if (free_ai)
- freeaddrinfo(ai);
- return res;
- }
-
- /* Communication Layer */
-
- ssize_t
- w_send(int sk, const void *buf, size_t len, int die)
- {
- ssize_t ret;
-
- ret = send(sk, buf, len, 0);
- if (ret != len) {
- if (die)
- fatal("Unable to send(): %s.", strerror(errno));
- debug(DBG_NORMAL, "w_send(): %s.", strerror(errno));
- }
- return ret;
- }
-
- ssize_t
- w_recv(int sk, void *buf, size_t len, int die)
- {
- ssize_t ret;
-
- ret = recv(sk, buf, len, 0);
- if (ret <= 0) {
- if (die)
- fatal("Unable to recv(): %s.", strerror(errno));
- debug(DBG_INSANE, "w_recv(): %s.", strerror(errno));
- }
- return ret;
- }
-
-
- /*
- * These two functions and the MACRO are
- * almost VERBATIM copied from inet.c and inet.h.
- * Functions by AlpT, Andrea Lo Pumo.
- */
-
- #define MILLISEC_TO_TV(x,t) \
- do{ \
- (t).tv_sec=(x)/1000; \
- (t).tv_usec=((x) - ((x)/1000)*1000)*1000; \
- }while(0)
-
- ssize_t
- w_send_timeout(int s, const void *buf, size_t len, int die, int timeout)
- {
- struct timeval timeout_t;
- fd_set fdset;
- int ret;
-
- MILLISEC_TO_TV(timeout * 1000, timeout_t);
-
- FD_ZERO(&fdset);
- FD_SET(s, &fdset);
-
- ret = select(s + 1, &fdset, NULL, NULL, &timeout_t);
- if (ret == -1) {
- if (die)
- fatal("send(): select error.");
- debug(DBG_NORMAL, "send(): select error.");
- return ret;
- }
-
- if (FD_ISSET(s, &fdset))
- return w_send(s, buf, len, die);
- return -1;
- }
-
- ssize_t
- w_recv_timeout(int s, void *buf, size_t len, int die, int timeout)
- {
- struct timeval timeout_t;
- fd_set fdset;
- int ret;
-
- MILLISEC_TO_TV(timeout * 1000, timeout_t);
-
- FD_ZERO(&fdset);
- FD_SET(s, &fdset);
-
- ret = select(s + 1, NULL, &fdset, NULL, &timeout_t);
-
- if (ret == -1) {
- if (die)
- fatal("recv(): select error.");
- debug(DBG_NORMAL, "recv(): select error.");
- return ret;
- }
-
- if (FD_ISSET(s, &fdset))
- return w_recv(s, buf, len, die);
- return -1;
- }
-
-
-
- /* Dialog Layer */
-
- /* "Botta e risposta" */
- ssize_t
- hn_send_recv_close(const char *host, uint16_t port, int type, void *buf,
- size_t buflen, void *anbuf, size_t anlen, int die,
- int timeout)
- {
- ssize_t ret;
- int res;
-
- res = host_connect(host, port, type, die);
- if (res == -1)
- return -1;
- if (timeout)
- ret = w_send_timeout(res, buf, buflen, die, timeout);
- else
- ret = w_send(res, buf, buflen, die);
- if (ret == -1)
- return -2;
- if (timeout)
- ret = w_recv_timeout(res, anbuf, anlen, die, timeout);
- else
- ret = w_recv(res, anbuf, anlen, die);
- if (ret == -1)
- return -3;
- close(res);
- return ret;
- }
-
- /* "Botta e risposta" */
- ssize_t
- ai_send_recv_close(struct addrinfo * ai, void *buf, size_t buflen,
- void *anbuf, size_t anlen, int die, int free_ai,
- int timeout)
- {
- ssize_t ret;
- int res;
-
- res = ai_connect(ai, die, free_ai);
- if (res == -1)
- return -1;
- if (timeout)
- ret = w_send_timeout(res, buf, buflen, die, timeout);
- else
- ret = w_send(res, buf, buflen, die);
- if (ret == -1)
- return -2;
- if (timeout)
- ret = w_recv_timeout(res, anbuf, anlen, die, timeout);
- else
- ret = w_recv(res, anbuf, anlen, die);
- if (ret == -1)
- return -3;
- close(res);
- return ret;
- }
-
- void
- char_print(char *buf, int len)
- {
- int i, count = 0;
-
- printf("Printing %d bytes\n", len);
- for (i = 0; i < len; i++) {
- printf("%02X ", (unsigned char) (buf[i]));
- count++;
- if ((count % 16) == 0)
- printf("\n");
- }
- printf("\n");
- return;
- }
|