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.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include "includes.h"
  19. #include "common.h"
  20. #include "ipv6-gmp.h"
  21. #include "libnetlink.h"
  22. #include "ll_map.h"
  23. #include "inet.h"
  24. #include "endianness.h"
  25. /*
  26. * inet_ntohl: Converts each element of `data' from network to host order. If
  27. * `family' is equal to AF_INET6, the array is swapped too (on big endian
  28. * machine).
  29. */
  30. void inet_ntohl(u_int *data, int family)
  31. {
  32. #if BYTE_ORDER == LITTLE_ENDIAN
  33. if(family==AF_INET) {
  34. data[0]=ntohl(data[0]);
  35. } else {
  36. int i;
  37. swap_ints(MAX_IP_INT, data, data);
  38. for(i=0; i<MAX_IP_INT; i++)
  39. data[i]=ntohl(data[i]);
  40. }
  41. #endif
  42. }
  43. /*
  44. * inet_htonl: Converts each element of `data' from host to network order. If
  45. * `family' is equal to AF_INET6, the array is swapped too (on big endian
  46. * machine).
  47. */
  48. void inet_htonl(u_int *data, int family)
  49. {
  50. #if BYTE_ORDER == LITTLE_ENDIAN
  51. if(family==AF_INET) {
  52. data[0]=htonl(data[0]);
  53. } else {
  54. int i;
  55. swap_ints(MAX_IP_INT, data, data);
  56. for(i=0; i<MAX_IP_INT; i++)
  57. data[i]=htonl(data[i]);
  58. }
  59. #endif
  60. }
  61. /*
  62. * inet_setip_raw: fills the `ip' inet_prefix struct with `data' and `family'.
  63. */
  64. int inet_setip_raw(inet_prefix *ip, u_int *data, int family)
  65. {
  66. ip->family=family;
  67. setzero(ip->data, sizeof(ip->data));
  68. if(family==AF_INET) {
  69. ip->data[0]=data[0];
  70. ip->len=4;
  71. } else if(family==AF_INET6) {
  72. memcpy(ip->data, data, sizeof(ip->data));
  73. ip->len=16;
  74. } else
  75. fatal(ERROR_MSG "family not supported", ERROR_POS);
  76. ip->bits=ip->len<<3; /* bits=len*8 */
  77. return 0;
  78. }
  79. /*
  80. * inet_setip: fills the `ip' inet_prefix struct with `data' and `family'.
  81. * Note that it does a network to host order conversion on `data'.
  82. */
  83. int inet_setip(inet_prefix *ip, u_int *data, int family)
  84. {
  85. inet_setip_raw(ip, data, family);
  86. inet_ntohl(ip->data, ip->family);
  87. return 0;
  88. }
  89. int inet_setip_bcast(inet_prefix *ip, int family)
  90. {
  91. if(family==AF_INET) {
  92. u_int data[MAX_IP_INT]={0, 0, 0, 0};
  93. data[0]=INADDR_BROADCAST;
  94. inet_setip(ip, data, family);
  95. } else if(family==AF_INET6) {
  96. u_int data[MAX_IP_INT]=IPV6_ADDR_BROADCAST;
  97. inet_setip(ip, data, family);
  98. } else
  99. fatal(ERROR_MSG "family not supported", ERROR_POS);
  100. return 0;
  101. }
  102. int inet_setip_anyaddr(inet_prefix *ip, int family)
  103. {
  104. if(family==AF_INET) {
  105. u_int data[MAX_IP_INT]={0, 0, 0, 0};
  106. data[0]=INADDR_ANY;
  107. inet_setip(ip, data, family);
  108. } else if(family==AF_INET6) {
  109. struct in6_addr ipv6=IN6ADDR_ANY_INIT;
  110. inet_setip(ip, (u_int *)(&ipv6), family);
  111. } else
  112. fatal(ERROR_MSG "family not supported", ERROR_POS);
  113. return 0;
  114. }
  115. int inet_setip_loopback(inet_prefix *ip, int family)
  116. {
  117. if(family==AF_INET) {
  118. u_int data[MAX_IP_INT]={0, 0, 0, 0};
  119. data[0]=LOOPBACK_IP;
  120. inet_setip(ip, data, family);
  121. inet_htonl(ip->data, ip->family);
  122. } else if(family==AF_INET6) {
  123. u_int data[MAX_IP_INT]=LOOPBACK_IPV6;
  124. inet_setip(ip, data, family);
  125. } else
  126. fatal(ERROR_MSG "family not supported", ERROR_POS);
  127. return 0;
  128. }
  129. /*
  130. * inet_setip_localaddr: Restrict the `ip' to a local private class changing the
  131. * first byte of the `ip'. `class' specifies what restricted class is currently
  132. * being used (10.x.x.x or 172.16.x.x). In ipv6 the site local class is the
  133. * default.
  134. */
  135. int inet_setip_localaddr(inet_prefix *ip, int family, int class)
  136. {
  137. if(family==AF_INET) {
  138. if(class == RESTRICTED_10)
  139. ip->data[0] = NTK_RESTRICTED_10_MASK(ip->data[0]);
  140. else
  141. ip->data[0] = NTK_RESTRICTED_172_MASK(ip->data[0]);
  142. } else if(family==AF_INET6) {
  143. ip->data[0] = NTK_RESTRICTED_IPV6_MASK(ip->data[0]);
  144. } else
  145. fatal(ERROR_MSG "family not supported", ERROR_POS);
  146. return 0;
  147. }
  148. /*
  149. * inet_is_ip_local: verifies if `ip' is a local address. If it is, 1 is
  150. * returned. `class' specifies what restricted class is currently
  151. * being used (10.x.x.x or 172.16.x.x). In ipv6 the site local class is the
  152. * default.
  153. */
  154. int inet_is_ip_local(inet_prefix *ip, int class)
  155. {
  156. if(ip->family==AF_INET) {
  157. if(class == RESTRICTED_10)
  158. return ip->data[0] == NTK_RESTRICTED_10_MASK(ip->data[0]);
  159. else
  160. return ip->data[0] == NTK_RESTRICTED_172_MASK(ip->data[0]);
  161. } else if(ip->family==AF_INET6)
  162. return ip->data[0] == NTK_RESTRICTED_IPV6_MASK(ip->data[0]);
  163. else
  164. fatal(ERROR_MSG "family not supported", ERROR_POS);
  165. return 0;
  166. }
  167. void inet_copy(inet_prefix *dst, inet_prefix *src)
  168. {
  169. memcpy(dst, src, sizeof(inet_prefix));
  170. }
  171. /*
  172. * inet_copy_ipdata_raw: copies `ip'->data in `dst_data'.
  173. */
  174. void inet_copy_ipdata_raw(u_int *dst_data, inet_prefix *ip)
  175. {
  176. memcpy(dst_data, ip->data, MAX_IP_SZ);
  177. }
  178. /*
  179. * inet_copy_ipdata: copies `ip'->data in `dst_data' and converts it in network
  180. * order.
  181. */
  182. void inet_copy_ipdata(u_int *dst_data, inet_prefix *ip)
  183. {
  184. inet_prefix tmp_ip;
  185. inet_copy(&tmp_ip, ip);
  186. inet_htonl(tmp_ip.data, tmp_ip.family);
  187. memcpy(dst_data, tmp_ip.data, MAX_IP_SZ);
  188. }
  189. /*
  190. * pack_inet_prefix: packs the `ip' inet_prefix struct and stores it in
  191. * `pack', which must be INET_PREFIX_PACK_SZ bytes big. `pack' will be in
  192. * network order.
  193. */
  194. void pack_inet_prefix(inet_prefix *ip, char *pack)
  195. {
  196. char *buf;
  197. buf=pack;
  198. memcpy(buf, &ip->family, sizeof(u_char));
  199. buf+=sizeof(u_char);
  200. memcpy(buf, &ip->len, sizeof(u_short));
  201. buf+=sizeof(u_short);
  202. memcpy(buf, &ip->bits, sizeof(u_char));
  203. buf+=sizeof(u_char);
  204. memcpy(buf, ip->data, MAX_IP_SZ);
  205. inet_htonl((u_int *)buf, ip->family);
  206. buf+=MAX_IP_SZ;
  207. ints_host_to_network(pack, inet_prefix_iinfo);
  208. }
  209. /*
  210. * unpack_inet_prefix: restores in `ip' the inet_prefix struct contained in `pack'.
  211. * Note that `pack' will be modified during the restoration.
  212. */
  213. void unpack_inet_prefix(inet_prefix *ip, char *pack)
  214. {
  215. char *buf;
  216. buf=pack;
  217. ints_network_to_host(pack, inet_prefix_iinfo);
  218. memcpy(&ip->family, buf, sizeof(u_char));
  219. buf+=sizeof(u_char);
  220. memcpy(&ip->len, buf, sizeof(u_short));
  221. buf+=sizeof(u_short);
  222. memcpy(&ip->bits, buf, sizeof(u_char));
  223. buf+=sizeof(u_char);
  224. memcpy(ip->data, buf, MAX_IP_SZ);
  225. inet_ntohl(ip->data, ip->family);
  226. buf+=MAX_IP_SZ;
  227. }
  228. /*
  229. * inet_addr_match: without hesitating this function was robbed from iproute2.
  230. * It compares a->data wih b->data matching `bits'# bits.
  231. */
  232. int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
  233. {
  234. const uint32_t *a1 = a->data;
  235. const uint32_t *a2 = b->data;
  236. int words = bits >> 0x05;
  237. bits &= 0x1f;
  238. if (words)
  239. if (memcmp(a1, a2, words << 2))
  240. return -1;
  241. if (bits) {
  242. uint32_t w1, w2;
  243. uint32_t mask;
  244. w1 = a1[words];
  245. w2 = a2[words];
  246. mask = htonl((0xffffffff) << (0x20 - bits));
  247. if ((w1 ^ w2) & mask)
  248. return 1;
  249. }
  250. return 0;
  251. }
  252. int ipv6_addr_type(inet_prefix addr)
  253. {
  254. int type;
  255. u_int st;
  256. st = htonl(addr.data[0]);
  257. if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
  258. type = IPV6_ADDR_MULTICAST;
  259. switch((st & htonl(0x00FF0000))) {
  260. case __constant_htonl(0x00010000):
  261. type |= IPV6_ADDR_LOOPBACK;
  262. break;
  263. case __constant_htonl(0x00020000):
  264. type |= IPV6_ADDR_LINKLOCAL;
  265. break;
  266. case __constant_htonl(0x00050000):
  267. type |= IPV6_ADDR_SITELOCAL;
  268. break;
  269. };
  270. return type;
  271. }
  272. type = IPV6_ADDR_UNICAST;
  273. /* Consider all addresses with the first three bits different of
  274. 000 and 111 as finished.
  275. */
  276. if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
  277. (st & htonl(0xE0000000)) != htonl(0xE0000000))
  278. return type;
  279. if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
  280. return (IPV6_ADDR_LINKLOCAL | type);
  281. if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
  282. return (IPV6_ADDR_SITELOCAL | type);
  283. if ((addr.data[0] | addr.data[1]) == 0) {
  284. if (addr.data[2] == 0) {
  285. if (addr.data[3] == 0)
  286. return IPV6_ADDR_ANY;
  287. if (htonl(addr.data[3]) == htonl(0x00000001))
  288. return (IPV6_ADDR_LOOPBACK | type);
  289. return (IPV6_ADDR_COMPATv4 | type);
  290. }
  291. if (htonl(addr.data[2]) == htonl(0x0000ffff))
  292. return IPV6_ADDR_MAPPED;
  293. }
  294. st &= htonl(0xFF000000);
  295. if (st == 0)
  296. return IPV6_ADDR_RESERVED;
  297. st &= htonl(0xFE000000);
  298. if (st == htonl(0x02000000))
  299. return IPV6_ADDR_RESERVED; /* for NSAP */
  300. if (st == htonl(0x04000000))
  301. return IPV6_ADDR_RESERVED; /* for IPX */
  302. return type;
  303. }
  304. /*
  305. * inet_validate_ip: returns 0 is `ip' a valid IP which can be set by
  306. * Netsukuku to a network interface
  307. */
  308. int inet_validate_ip(inet_prefix ip)
  309. {
  310. int type, ipv4;
  311. if(ip.family==AF_INET) {
  312. ipv4=htonl(ip.data[0]);
  313. if(MULTICAST(ipv4) || BADCLASS(ipv4) || ZERONET(ipv4)
  314. || LOOPBACK(ipv4) || NTK_PRIVATE_C(ipv4) ||
  315. (!restricted_mode && NTK_PRIVATE_B(ipv4)))
  316. return -EINVAL;
  317. } else if(ip.family==AF_INET6) {
  318. type=ipv6_addr_type(ip);
  319. if( (type & IPV6_ADDR_MULTICAST) || (type & IPV6_ADDR_RESERVED) ||
  320. (type & IPV6_ADDR_LOOPBACK))
  321. return -EINVAL;
  322. }
  323. if(is_bufzero((char *)ip.data, MAX_IP_SZ))
  324. return -EINVAL;
  325. return 0;
  326. }
  327. /*\
  328. *
  329. * * * Conversion functions... * *
  330. *
  331. \*/
  332. /*
  333. * ipraw_to_str: It returns the string which represents the given ip in host
  334. * order.
  335. */
  336. const char *ipraw_to_str(u_int ip[MAX_IP_INT], int family)
  337. {
  338. struct in_addr src;
  339. struct in6_addr src6;
  340. static char dst[INET_ADDRSTRLEN], dst6[INET6_ADDRSTRLEN];
  341. if(family==AF_INET) {
  342. src.s_addr=htonl(ip[0]);
  343. inet_ntop(family, &src, dst, INET_ADDRSTRLEN);
  344. return dst;
  345. } else if(family==AF_INET6) {
  346. inet_htonl(ip, family);
  347. memcpy(&src6, ip, MAX_IP_SZ);
  348. inet_ntop(family, &src6, dst6, INET6_ADDRSTRLEN);
  349. return dst6;
  350. }
  351. return 0;
  352. }
  353. /*
  354. * inet_to_str: returns the string rapresentation of `ip'
  355. */
  356. const char *inet_to_str(inet_prefix ip)
  357. {
  358. return ipraw_to_str(ip.data, ip.family);
  359. }
  360. /*
  361. * str_to_inet: it converts the IP address string contained in `src' and
  362. * terminated by a `\0' char to an inet_prefix struct. The result is stored in
  363. * `ip'. On error -1 is returned.
  364. */
  365. int str_to_inet(const char *src, inet_prefix *ip)
  366. {
  367. struct in_addr dst;
  368. struct in6_addr dst6;
  369. int family,res;
  370. u_int *data;
  371. setzero(ip, sizeof(inet_prefix));
  372. if(strstr(src, ":")) {
  373. family=AF_INET6;
  374. data=(u_int *)&dst6;
  375. } else {
  376. family=AF_INET;
  377. data=(u_int *)&dst;
  378. }
  379. if((res=inet_pton(family, src, (void *)data)) < 0) {
  380. debug(DBG_NORMAL, ERROR_MSG "error -> %s.",
  381. ERROR_FUNC, strerror(errno));
  382. return -1;
  383. }
  384. if (!res) {
  385. debug(DBG_NORMAL, ERROR_MSG "impossible to convert \"%s\":"
  386. " invalid address.", ERROR_FUNC, src);
  387. return -1;
  388. }
  389. inet_setip(ip, data, family);
  390. return 0;
  391. }
  392. /*
  393. * inet_to_sockaddr: Converts a inet_prefix struct to a sockaddr struct
  394. */
  395. int inet_to_sockaddr(inet_prefix *ip, u_short port, struct sockaddr *dst,
  396. socklen_t *dstlen)
  397. {
  398. port=htons(port);
  399. if(ip->family==AF_INET) {
  400. struct sockaddr_in sin;
  401. setzero(&sin, sizeof(struct sockaddr_in));
  402. sin.sin_family = ip->family;
  403. sin.sin_port = port;
  404. sin.sin_addr.s_addr = htonl(ip->data[0]);
  405. memcpy(dst, &sin, sizeof(struct sockaddr_in));
  406. if(dstlen)
  407. *dstlen=sizeof(struct sockaddr_in);
  408. } else if(ip->family==AF_INET6) {
  409. struct sockaddr_in6 sin6;
  410. setzero(&sin6, sizeof(struct sockaddr_in6));
  411. sin6.sin6_family = ip->family;
  412. sin6.sin6_port = port;
  413. sin6.sin6_flowinfo = 0;
  414. memcpy(&sin6.sin6_addr, ip->data, MAX_IP_SZ);
  415. inet_htonl((u_int *)&sin6.sin6_addr, ip->family);
  416. memcpy(dst, &sin6, sizeof(struct sockaddr_in6));
  417. if(dstlen)
  418. *dstlen=sizeof(struct sockaddr_in6);
  419. } else
  420. fatal(ERROR_MSG "family not supported", ERROR_POS);
  421. return 0;
  422. }
  423. int sockaddr_to_inet(struct sockaddr *ip, inet_prefix *dst, u_short *port)
  424. {
  425. u_short po;
  426. char *p;
  427. setzero(dst, sizeof(inet_prefix));
  428. dst->family=ip->sa_family;
  429. memcpy(&po, &ip->sa_data, sizeof(u_short));
  430. if(port)
  431. *port=ntohs(po);
  432. if(ip->sa_family==AF_INET)
  433. p=(char *)ip->sa_data+sizeof(u_short);
  434. else if(ip->sa_family==AF_INET6)
  435. p=(char *)ip->sa_data+sizeof(u_short)+sizeof(int);
  436. else {
  437. error(ERROR_MSG "family not supported", ERROR_POS);
  438. return -1;
  439. }
  440. inet_setip(dst, (u_int *)p, ip->sa_family);
  441. return 0;
  442. }
  443. /*\
  444. *
  445. * * * Socket operations * *
  446. *
  447. \*/
  448. int new_socket(int sock_type)
  449. {
  450. int sockfd;
  451. if((sockfd=socket(sock_type, SOCK_STREAM, 0)) == -1 ) {
  452. error("Socket SOCK_STREAM creation failed: %s", strerror(errno));
  453. return -1;
  454. }
  455. return sockfd;
  456. }
  457. int new_dgram_socket(int sock_type)
  458. {
  459. int sockfd;
  460. if((sockfd=socket(sock_type, SOCK_DGRAM, 0)) == -1 ) {
  461. error("Socket SOCK_DGRAM creation failed: %s", strerror(errno));
  462. return -1;
  463. }
  464. return sockfd;
  465. }
  466. /*
  467. * inet_close
  468. *
  469. * It closes the `*sk' socket and sets it to zero.
  470. * It always returns 0;
  471. */
  472. int inet_close(int *sk)
  473. {
  474. close(*sk);
  475. return (*sk=0);
  476. }
  477. int inet_getpeername(int sk, inet_prefix *ip, short *port)
  478. {
  479. struct sockaddr_storage saddr_sto;
  480. struct sockaddr *sa=(struct sockaddr *)&saddr_sto;
  481. socklen_t alen;
  482. alen = sizeof(saddr_sto);
  483. setzero(sa, alen);
  484. if(getpeername(sk, sa, &alen) == -1) {
  485. error("Cannot getpeername: %s", strerror(errno));
  486. return -1;
  487. }
  488. return sockaddr_to_inet(sa, ip, port);
  489. }
  490. /*
  491. * join_ipv6_multicast: It adds the membership to the IPV6_ADDR_BROADCAST
  492. * multicast group. The device with index `idx' will be used.
  493. */
  494. int join_ipv6_multicast(int socket, int idx)
  495. {
  496. struct ipv6_mreq mreq6;
  497. const int addr[MAX_IP_INT]=IPV6_ADDR_BROADCAST;
  498. setzero(&mreq6, sizeof(struct ipv6_mreq));
  499. memcpy(&mreq6.ipv6mr_multiaddr, addr, sizeof(struct in6_addr));
  500. mreq6.ipv6mr_interface=idx;
  501. if(setsockopt(socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
  502. sizeof(mreq6)) < 0) {
  503. error("Cannot set IPV6_JOIN_GROUP: %s", strerror(errno));
  504. close(socket);
  505. return -1;
  506. }
  507. return socket;
  508. }
  509. int set_multicast_if(int socket, int idx)
  510. {
  511. /* man ipv6 */
  512. if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_IF,
  513. &idx, sizeof(int)) < 0) {
  514. error("set_multicast_if(): cannot set IPV6_MULTICAST_IF: %s",
  515. strerror(errno));
  516. close(socket);
  517. return -1;
  518. }
  519. return 0;
  520. }
  521. int set_nonblock_sk(int fd)
  522. {
  523. if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
  524. error("set_nonblock_sk(): cannot set O_NONBLOCK: %s",
  525. strerror(errno));
  526. close(fd);
  527. return -1;
  528. }
  529. return 0;
  530. }
  531. int unset_nonblock_sk(int fd)
  532. {
  533. if (fcntl(fd, F_SETFL, 0) < 0) {
  534. error("unset_nonblock_sk(): cannot unset O_NONBLOCK: %s",
  535. strerror(errno));
  536. close(fd);
  537. return -1;
  538. }
  539. return 0;
  540. }
  541. int set_reuseaddr_sk(int socket)
  542. {
  543. int reuseaddr=1, ret;
  544. /*
  545. * SO_REUSEADDR: <<Go ahead and reuse that port even if it is in
  546. * TIME_WAIT state.>>
  547. */
  548. ret=setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int));
  549. if(ret < 0)
  550. error("setsockopt SO_REUSEADDR: %s", strerror(errno));
  551. return ret;
  552. }
  553. int set_bindtodevice_sk(int socket, char *dev)
  554. {
  555. struct ifreq ifr;
  556. int ret=0;
  557. setzero(&ifr, sizeof(ifr));
  558. strncpy(ifr.ifr_name, dev, IFNAMSIZ-1);
  559. ret=setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, dev, strlen(dev)+1);
  560. if(ret < 0)
  561. error("setsockopt SO_BINDTODEVICE: %s", strerror(errno));
  562. return ret;
  563. }
  564. /*
  565. * `loop': 0 = disable, 1 = enable (default)
  566. */
  567. int set_multicast_loop_sk(int family, int socket, u_char loop)
  568. {
  569. int ret=0;
  570. /*
  571. * <<The IPV6_MULTICAST_LOOP option gives the sender explicit control
  572. * over whether or not subsequent datagrams are looped bac.>>
  573. */
  574. if(family==AF_INET6)
  575. ret=setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop));
  576. if(ret < 0)
  577. error("setsockopt IP_MULTICAST_LOOP: %s", strerror(errno));
  578. return ret;
  579. }
  580. int set_broadcast_sk(int socket, int family, inet_prefix *host, short port,
  581. int dev_idx)
  582. {
  583. struct sockaddr_storage saddr_sto;
  584. struct sockaddr *sa=(struct sockaddr *)&saddr_sto;
  585. socklen_t alen;
  586. int broadcast=1;
  587. if(family == AF_INET) {
  588. if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &broadcast,
  589. sizeof(broadcast)) < 0) {
  590. error("Cannot set SO_BROADCAST to socket: %s", strerror(errno));
  591. close(socket);
  592. return -1;
  593. }
  594. } else if(family == AF_INET6) {
  595. if(join_ipv6_multicast(socket, dev_idx) < 0)
  596. return -1;
  597. if(set_multicast_loop_sk(family, socket, 0) < 0)
  598. return -1;
  599. set_multicast_if(socket, dev_idx);
  600. } else
  601. fatal(ERROR_MSG "family not supported", ERROR_POS);
  602. /* What's my name ? */
  603. alen = sizeof(saddr_sto);
  604. setzero(sa, alen);
  605. if (getsockname(socket, sa, &alen) == -1) {
  606. error("Cannot getsockname: %s", strerror(errno));
  607. close(socket);
  608. return -1;
  609. }
  610. /* Let's bind it! */
  611. if(bind(socket, sa, alen) < 0) {
  612. error("Cannot bind the broadcast socket: %s", strerror(errno));
  613. close(socket);
  614. return -1;
  615. }
  616. return socket;
  617. }
  618. int unset_broadcast_sk(int socket, int family)
  619. {
  620. int broadcast=0;
  621. if(family == AF_INET) {
  622. if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
  623. error ("Cannot unset broadcasting: %s", strerror(errno));
  624. return -1;
  625. }
  626. }
  627. return 0;
  628. }
  629. int set_keepalive_sk(int socket)
  630. {
  631. int on=1;
  632. if(setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
  633. sizeof(on)) < 0){
  634. error("Cannot set keepalive socket: %s", strerror(errno));
  635. return -1;
  636. }
  637. return 0;
  638. }
  639. int unset_keepalive_sk(int socket)
  640. {
  641. int off=0;
  642. if(setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (void *)&off,
  643. sizeof(off)) < 0){
  644. error("Cannot unset keepalive socket: %s", strerror(errno));
  645. return -1;
  646. }
  647. return 0;
  648. }
  649. int set_tos_sk(int socket, int lowdelay)
  650. {
  651. int tos = lowdelay ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT;
  652. /* Only for Ipv4 */
  653. if (setsockopt(socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
  654. error("setsockopt IP_TOS %d: %s", tos, strerror(errno));
  655. return -1;
  656. }
  657. return 0;
  658. }
  659. /*\
  660. *
  661. * * * Connection functions * *
  662. *
  663. \*/
  664. int new_tcp_conn(inet_prefix *host, short port, char *dev)
  665. {
  666. int sk;
  667. socklen_t sa_len;
  668. struct sockaddr_storage saddr_sto;
  669. struct sockaddr *sa=(struct sockaddr *)&saddr_sto;
  670. const char *ntop;
  671. ntop=inet_to_str(*host);
  672. if(inet_to_sockaddr(host, port, sa, &sa_len)) {
  673. error("Cannot new_tcp_connect(): %d Family not supported", host->family);
  674. ERROR_FINISH(sk, -1, finish);
  675. }
  676. if((sk = new_socket(host->family)) == -1)
  677. ERROR_FINISH(sk, -1, finish);
  678. if(dev) /* if `dev' is not null bind the socket to it */
  679. if(set_bindtodevice_sk(sk, dev) < 0)
  680. ERROR_FINISH(sk, -1, finish);
  681. if (connect(sk, sa, sa_len) == -1) {
  682. error("Cannot tcp_connect() to %s: %s", ntop, strerror(errno));
  683. ERROR_FINISH(sk, -1, finish);
  684. }
  685. finish:
  686. return sk;
  687. }
  688. int new_udp_conn(inet_prefix *host, short port, char *dev)
  689. {
  690. int sk;
  691. socklen_t sa_len;
  692. struct sockaddr_storage saddr_sto;
  693. struct sockaddr *sa=(struct sockaddr *)&saddr_sto;
  694. const char *ntop;
  695. ntop=inet_to_str(*host);
  696. if(inet_to_sockaddr(host, port, sa, &sa_len)) {
  697. error("Cannot new_udp_connect(): %d Family not supported", host->family);
  698. ERROR_FINISH(sk, -1, finish);
  699. }
  700. if((sk = new_dgram_socket(host->family)) == -1)
  701. ERROR_FINISH(sk, -1, finish);
  702. if(dev) /* if `dev' is not null bind the socket to it */
  703. if(set_bindtodevice_sk(sk, dev) < 0)
  704. ERROR_FINISH(sk, -1, finish);
  705. if (connect(sk, sa, sa_len) == -1) {
  706. error("Cannot connect to %s: %s", ntop, strerror(errno));
  707. ERROR_FINISH(sk, -1, finish);
  708. }
  709. finish:
  710. return sk;
  711. }
  712. int new_bcast_conn(inet_prefix *host, short port, int dev_idx)
  713. {
  714. struct sockaddr_storage saddr_sto;
  715. struct sockaddr *sa=(struct sockaddr *)&saddr_sto;
  716. socklen_t alen;
  717. int sk;
  718. const char *ntop;
  719. if((sk = new_dgram_socket(host->family)) == -1)
  720. return -1;
  721. sk=set_broadcast_sk(sk, host->family, host, port, dev_idx);
  722. /*
  723. * Connect
  724. */
  725. if(inet_to_sockaddr(host, port, sa, &alen)) {
  726. error("set_broadcast_sk: %d Family not supported", host->family);
  727. return -1;
  728. }
  729. if(host->family == AF_INET6) {
  730. struct sockaddr_in6 *sin6=(struct sockaddr_in6 *)sa;
  731. sin6->sin6_scope_id = dev_idx;
  732. }
  733. if(set_bindtodevice_sk(sk, (char *)ll_index_to_name(dev_idx)) < 0)
  734. return -1;
  735. if(connect(sk, sa, alen) == -1) {
  736. ntop=inet_to_str(*host);
  737. error("Cannot connect to the broadcast (%s): %s", ntop,
  738. strerror(errno));
  739. return -1;
  740. }
  741. return sk;
  742. }
  743. /*\
  744. *
  745. * * * Recv/Send functions * *
  746. *
  747. \*/
  748. ssize_t inet_recv(int s, void *buf, size_t len, int flags)
  749. {
  750. ssize_t err;
  751. fd_set fdset;
  752. int ret;
  753. if((err=recv(s, buf, len, flags))==-1) {
  754. switch(errno)
  755. {
  756. default:
  757. /* Probably connection was closed */
  758. debug(DBG_NORMAL, "inet_recv: Cannot recv(): %s",
  759. strerror(errno));
  760. return err;
  761. break;
  762. }
  763. }
  764. return err;
  765. }
  766. /*
  767. * inet_recv_timeout
  768. *
  769. * is the same as inet_recv() but if no reply is received for `timeout'
  770. * seconds it returns -1.
  771. */
  772. ssize_t inet_recv_timeout(int s, void *buf, size_t len, int flags, u_int timeout)
  773. {
  774. struct timeval timeout_t;
  775. fd_set fdset;
  776. int ret;
  777. MILLISEC_TO_TV(timeout*1000, timeout_t);
  778. FD_ZERO(&fdset);
  779. FD_SET(s, &fdset);
  780. ret = select(s+1, &fdset, NULL, NULL, &timeout_t);
  781. if (ret == -1) {
  782. error(ERROR_MSG "select error: %s", ERROR_FUNC, strerror(errno));
  783. return ret;
  784. }
  785. return FD_ISSET(s, &fdset) ? inet_recv(s, buf, len, flags) : -1;
  786. }
  787. ssize_t inet_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
  788. {
  789. ssize_t err;
  790. fd_set fdset;
  791. int ret;
  792. if((err=recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
  793. switch(errno)
  794. {
  795. default:
  796. error("inet_recvfrom: Cannot recv(): %s", strerror(errno));
  797. return err;
  798. break;
  799. }
  800. }
  801. return err;
  802. }
  803. /*
  804. * inet_recvfrom_timeout: is the same as inet_recvfrom() but if no reply is
  805. * received for `timeout' seconds it returns -1.
  806. */
  807. ssize_t inet_recvfrom_timeout(int s, void *buf, size_t len, int flags,
  808. struct sockaddr *from, socklen_t *fromlen, u_int timeout)
  809. {
  810. struct timeval timeout_t;
  811. fd_set fdset;
  812. int ret;
  813. MILLISEC_TO_TV(timeout*1000, timeout_t);
  814. FD_ZERO(&fdset);
  815. FD_SET(s, &fdset);
  816. ret = select(s+1, &fdset, NULL, NULL, &timeout_t);
  817. if (ret == -1) {
  818. error(ERROR_MSG "select error: %s", ERROR_FUNC, strerror(errno));
  819. return ret;
  820. }
  821. if(FD_ISSET(s, &fdset))
  822. return inet_recvfrom(s, buf, len, flags, from, fromlen);
  823. return -1;
  824. }
  825. ssize_t inet_send(int s, const void *msg, size_t len, int flags)
  826. {
  827. ssize_t err;
  828. fd_set fdset;
  829. int ret;
  830. if((err=send(s, msg, len, flags)) < 0) {
  831. switch(errno)
  832. {
  833. case EMSGSIZE:
  834. inet_send(s, msg, len/2, flags);
  835. err=inet_send(s, (const char *)msg+(len/2),
  836. len-(len/2), flags);
  837. break;
  838. default:
  839. error("inet_send: Cannot send(): %s", strerror(errno));
  840. return err;
  841. break;
  842. }
  843. }
  844. return err;
  845. }
  846. /*
  847. * inet_send_timeout: is the same as inet_send() but if the packet isn't sent
  848. * in `timeout' seconds it timeouts and returns -1.
  849. */
  850. ssize_t inet_send_timeout(int s, const void *msg, size_t len, int flags, u_int timeout)
  851. {
  852. struct timeval timeout_t;
  853. fd_set fdset;
  854. int ret;
  855. MILLISEC_TO_TV(timeout*1000, timeout_t);
  856. FD_ZERO(&fdset);
  857. FD_SET(s, &fdset);
  858. ret = select(s+1, NULL, &fdset, NULL, &timeout_t);
  859. if (ret == -1) {
  860. error(ERROR_MSG "select error: %s", ERROR_FUNC, strerror(errno));
  861. return ret;
  862. }
  863. if(FD_ISSET(s, &fdset))
  864. return inet_send(s, msg, len, flags);
  865. return -1;
  866. }
  867. ssize_t inet_sendto(int s, const void *msg, size_t len, int flags,
  868. const struct sockaddr *to, socklen_t tolen)
  869. {
  870. ssize_t err;
  871. fd_set fdset;
  872. int ret;
  873. if((err=sendto(s, msg, len, flags, to, tolen))==-1) {
  874. error("sendto errno: %d err is: %d", errno, err);
  875. switch(errno)
  876. {
  877. case EMSGSIZE:
  878. error("Packet artificially fragmented: %d", stderr);
  879. error("\nData Length: %u", len);
  880. int bytesleft = len;
  881. int sendbuf;
  882. socklen_t optlen;
  883. optlen = sizeof(sendbuf);
  884. int res = getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sendbuf, &optlen);
  885. error("GetSockOpt: %i \n", res);
  886. while(bytesleft != 0) {
  887. if(bytesleft > 64000) {
  888. inet_sendto(s, msg, 64000, flags, to, tolen);
  889. bytesleft -= 64000;
  890. msg += 64000;
  891. //err=inet_sendto(s, ((const char *)msg+(len/2)),
  892. //len-(len/2), flags, to, tolen);
  893. }
  894. else {
  895. err=inet_sendto(s, msg, bytesleft, flags, to, tolen);
  896. bytesleft = 0;
  897. }
  898. }
  899. break;
  900. case EFAULT:
  901. error("The value of to is: %d", to);
  902. default:
  903. error("inet_sendto: Cannot send(): %s", strerror(errno));
  904. return err;
  905. break;
  906. }
  907. }
  908. return err;
  909. }
  910. /*
  911. * inet_sendto_timeout: is the same as inet_sendto() but if the packet isn't sent
  912. * in `timeout' seconds it timeouts and returns -1.
  913. */
  914. ssize_t inet_sendto_timeout(int s, const void *msg, size_t len, int flags,
  915. const struct sockaddr *to, socklen_t tolen, u_int timeout)
  916. {
  917. struct timeval timeout_t;
  918. fd_set fdset;
  919. int ret;
  920. MILLISEC_TO_TV(timeout*1000, timeout_t);
  921. FD_ZERO(&fdset);
  922. FD_SET(s, &fdset);
  923. ret = select(s+1, NULL, &fdset, NULL, &timeout_t);
  924. if (ret == -1) {
  925. error(ERROR_MSG "select error: %s", ERROR_FUNC, strerror(errno));
  926. return ret;
  927. }
  928. if(FD_ISSET(s, &fdset))
  929. return inet_sendto(s, msg, len, flags, to, tolen);
  930. return -1;
  931. }
  932. ssize_t inet_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
  933. {
  934. ssize_t err;
  935. fd_set fdset;
  936. int ret;
  937. if((err=sendfile(out_fd, in_fd, offset, count))==-1)
  938. error("inet_sendfile: Cannot sendfile(): %s", strerror(errno));
  939. return err;
  940. }