You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

andns_net.c 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /**************************************
  2. * AUTHOR: Federico Tomassini *
  3. * Copyright (C) Federico Tomassini *
  4. * Contact effetom@gmail.com *
  5. ***********************************************
  6. ******* BEGIN 4/2006 ********
  7. *************************************************************************
  8. * *
  9. * This program is free software; you can redistribute it and/or modify *
  10. * it under the terms of the GNU General Public License as published by *
  11. * the Free Software Foundation; either version 2 of the License, or *
  12. * (at your option) any later version. *
  13. * *
  14. * This program is distributed in the hope that it will be useful, *
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  17. * GNU General Public License for more details. *
  18. * *
  19. ************************************************************************/
  20. #include "log.h"
  21. #include "andns_net.h"
  22. int
  23. idp_inet_ntop(int family, struct sockaddr *addr, char *buf, int buflen)
  24. {
  25. const char *res;
  26. struct sockaddr_in *saddr;
  27. struct sockaddr_in6 *saddr6;
  28. switch (family) {
  29. case AF_INET:
  30. saddr = (struct sockaddr_in *) addr;
  31. res =
  32. inet_ntop(family, (void *) (&(saddr->sin_addr)), buf, buflen);
  33. break;
  34. case AF_INET6:
  35. saddr6 = (struct sockaddr_in6 *) addr;
  36. res =
  37. inet_ntop(family, (void *) (&(saddr6->sin6_addr)), buf,
  38. buflen);
  39. break;
  40. default:
  41. return -1;
  42. }
  43. if (!res)
  44. return -1;
  45. return 0;
  46. }
  47. /* Connection Layer */
  48. int
  49. w_socket(int family, int type, int proto, int die)
  50. {
  51. int sk;
  52. sk = socket(family, type, proto);
  53. if (sk == -1) {
  54. if (die)
  55. fatal("w_socket: %s.", strerror(errno));
  56. debug(DBG_NORMAL, "w_socket: %s.", strerror(errno));
  57. return -1;
  58. }
  59. return sk;
  60. }
  61. int
  62. w_connect(struct addrinfo *ai, int die)
  63. {
  64. int sk, res;
  65. sk = w_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, die);
  66. res = connect(sk, ai->ai_addr, ai->ai_addrlen);
  67. if (!res)
  68. return sk;
  69. if (die)
  70. fatal("Unable to connect: %s.", strerror(errno));
  71. debug(DBG_NORMAL, "w_connect: %s.", strerror(errno));
  72. close(sk);
  73. return -1;
  74. }
  75. int
  76. serial_connect(struct addrinfo *ai, int die)
  77. {
  78. int res;
  79. struct addrinfo *temp;
  80. temp = ai;
  81. if (!temp) {
  82. if (die)
  83. fatal("Unable to connect: no host specified.");
  84. debug(DBG_NORMAL, "serial_connect: no host specified.");
  85. return -1;
  86. }
  87. do {
  88. res = w_connect(temp, 0);
  89. temp = temp->ai_next;
  90. } while (res == -1 && temp);
  91. if (res == -1) {
  92. if (die)
  93. fatal("Unable to connect.");
  94. debug(DBG_NORMAL, "serial_connect: unable to connect.");
  95. return -1;
  96. }
  97. return res;
  98. }
  99. /*
  100. * host_connect returns a connected socket to (host,port)
  101. * endpoint. It is protocol independent.
  102. * -1 on error.
  103. */
  104. int
  105. host_connect(const char *host, uint16_t port, int type, int die)
  106. {
  107. int res;
  108. char portstr[6];
  109. struct addrinfo *ai, filter;
  110. memset(&filter, 0, sizeof(struct addrinfo));
  111. filter.ai_socktype = type;
  112. if (!host)
  113. fatal("w_connect: malicious call.");
  114. memset(portstr, 0, 6);
  115. res = snprintf(portstr, 6, "%d", port);
  116. if (res < 0 || res >= 6) {
  117. printf("Depousceve\n");
  118. return -1;
  119. }
  120. res = getaddrinfo(host, portstr, &filter, &ai);
  121. if (res != 0) {
  122. printf("w_connect: error %s.\n", gai_strerror(errno));
  123. return -1;
  124. }
  125. res = serial_connect(ai, die);
  126. freeaddrinfo(ai);
  127. return res;
  128. }
  129. int
  130. ai_connect(struct addrinfo *ai, int die, int free_ai)
  131. {
  132. int res;
  133. res = serial_connect(ai, die);
  134. if (free_ai)
  135. freeaddrinfo(ai);
  136. return res;
  137. }
  138. /* Communication Layer */
  139. ssize_t
  140. w_send(int sk, const void *buf, size_t len, int die)
  141. {
  142. ssize_t ret;
  143. ret = send(sk, buf, len, 0);
  144. if (ret != len) {
  145. if (die)
  146. fatal("Unable to send(): %s.", strerror(errno));
  147. debug(DBG_NORMAL, "w_send(): %s.", strerror(errno));
  148. }
  149. return ret;
  150. }
  151. ssize_t
  152. w_recv(int sk, void *buf, size_t len, int die)
  153. {
  154. ssize_t ret;
  155. ret = recv(sk, buf, len, 0);
  156. if (ret <= 0) {
  157. if (die)
  158. fatal("Unable to recv(): %s.", strerror(errno));
  159. debug(DBG_INSANE, "w_recv(): %s.", strerror(errno));
  160. }
  161. return ret;
  162. }
  163. /*
  164. * These two functions and the MACRO are
  165. * almost VERBATIM copied from inet.c and inet.h.
  166. * Functions by AlpT, Andrea Lo Pumo.
  167. */
  168. #define MILLISEC_TO_TV(x,t) \
  169. do{ \
  170. (t).tv_sec=(x)/1000; \
  171. (t).tv_usec=((x) - ((x)/1000)*1000)*1000; \
  172. }while(0)
  173. ssize_t
  174. w_send_timeout(int s, const void *buf, size_t len, int die, int timeout)
  175. {
  176. struct timeval timeout_t;
  177. fd_set fdset;
  178. int ret;
  179. MILLISEC_TO_TV(timeout * 1000, timeout_t);
  180. FD_ZERO(&fdset);
  181. FD_SET(s, &fdset);
  182. ret = select(s + 1, &fdset, NULL, NULL, &timeout_t);
  183. if (ret == -1) {
  184. if (die)
  185. fatal("send(): select error.");
  186. debug(DBG_NORMAL, "send(): select error.");
  187. return ret;
  188. }
  189. if (FD_ISSET(s, &fdset))
  190. return w_send(s, buf, len, die);
  191. return -1;
  192. }
  193. ssize_t
  194. w_recv_timeout(int s, void *buf, size_t len, int die, int timeout)
  195. {
  196. struct timeval timeout_t;
  197. fd_set fdset;
  198. int ret;
  199. MILLISEC_TO_TV(timeout * 1000, timeout_t);
  200. FD_ZERO(&fdset);
  201. FD_SET(s, &fdset);
  202. ret = select(s + 1, NULL, &fdset, NULL, &timeout_t);
  203. if (ret == -1) {
  204. if (die)
  205. fatal("recv(): select error.");
  206. debug(DBG_NORMAL, "recv(): select error.");
  207. return ret;
  208. }
  209. if (FD_ISSET(s, &fdset))
  210. return w_recv(s, buf, len, die);
  211. return -1;
  212. }
  213. /* Dialog Layer */
  214. /* "Botta e risposta" */
  215. ssize_t
  216. hn_send_recv_close(const char *host, uint16_t port, int type, void *buf,
  217. size_t buflen, void *anbuf, size_t anlen, int die,
  218. int timeout)
  219. {
  220. ssize_t ret;
  221. int res;
  222. res = host_connect(host, port, type, die);
  223. if (res == -1)
  224. return -1;
  225. if (timeout)
  226. ret = w_send_timeout(res, buf, buflen, die, timeout);
  227. else
  228. ret = w_send(res, buf, buflen, die);
  229. if (ret == -1)
  230. return -2;
  231. if (timeout)
  232. ret = w_recv_timeout(res, anbuf, anlen, die, timeout);
  233. else
  234. ret = w_recv(res, anbuf, anlen, die);
  235. if (ret == -1)
  236. return -3;
  237. close(res);
  238. return ret;
  239. }
  240. /* "Botta e risposta" */
  241. ssize_t
  242. ai_send_recv_close(struct addrinfo * ai, void *buf, size_t buflen,
  243. void *anbuf, size_t anlen, int die, int free_ai,
  244. int timeout)
  245. {
  246. ssize_t ret;
  247. int res;
  248. res = ai_connect(ai, die, free_ai);
  249. if (res == -1)
  250. return -1;
  251. if (timeout)
  252. ret = w_send_timeout(res, buf, buflen, die, timeout);
  253. else
  254. ret = w_send(res, buf, buflen, die);
  255. if (ret == -1)
  256. return -2;
  257. if (timeout)
  258. ret = w_recv_timeout(res, anbuf, anlen, die, timeout);
  259. else
  260. ret = w_recv(res, anbuf, anlen, die);
  261. if (ret == -1)
  262. return -3;
  263. close(res);
  264. return ret;
  265. }
  266. void
  267. char_print(char *buf, int len)
  268. {
  269. int i, count = 0;
  270. printf("Printing %d bytes\n", len);
  271. for (i = 0; i < len; i++) {
  272. printf("%02X ", (unsigned char) (buf[i]));
  273. count++;
  274. if ((count % 16) == 0)
  275. printf("\n");
  276. }
  277. printf("\n");
  278. return;
  279. }