BAddr.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /**
  2. * @file BAddr.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the author nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * @section DESCRIPTION
  30. *
  31. * Network address abstractions.
  32. */
  33. #ifndef BADVPN_SYSTEM_BADDR_H
  34. #define BADVPN_SYSTEM_BADDR_H
  35. #include <stdint.h>
  36. #include <limits.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <stdio.h>
  40. #ifdef BADVPN_USE_WINAPI
  41. #include <ws2tcpip.h>
  42. #else
  43. #include <sys/types.h>
  44. #include <sys/socket.h>
  45. #include <netdb.h>
  46. #include <netinet/in.h>
  47. #endif
  48. #include <misc/byteorder.h>
  49. #include <misc/debug.h>
  50. #include <misc/print_macros.h>
  51. #include <misc/read_write_int.h>
  52. #include <misc/compare.h>
  53. #define BADDR_TYPE_NONE 0
  54. #define BADDR_TYPE_IPV4 1
  55. #define BADDR_TYPE_IPV6 2
  56. #ifdef BADVPN_LINUX
  57. #define BADDR_TYPE_PACKET 5
  58. #endif
  59. #define BADDR_MAX_ADDR_LEN 128
  60. #define BIPADDR_MAX_PRINT_LEN 40
  61. #define BADDR_MAX_PRINT_LEN 120
  62. #define BADDR_PACKET_HEADER_TYPE_ETHERNET 1
  63. #define BADDR_PACKET_PACKET_TYPE_HOST 1
  64. #define BADDR_PACKET_PACKET_TYPE_BROADCAST 2
  65. #define BADDR_PACKET_PACKET_TYPE_MULTICAST 3
  66. #define BADDR_PACKET_PACKET_TYPE_OTHERHOST 4
  67. #define BADDR_PACKET_PACKET_TYPE_OUTGOING 5
  68. typedef struct {
  69. int type;
  70. union {
  71. uint32_t ipv4;
  72. uint8_t ipv6[16];
  73. };
  74. } BIPAddr;
  75. static void BIPAddr_InitInvalid (BIPAddr *addr);
  76. static void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip);
  77. static void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip);
  78. static void BIPAddr_Assert (BIPAddr *addr);
  79. static int BIPAddr_IsInvalid (BIPAddr *addr);
  80. static int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve) WARN_UNUSED;
  81. static int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2);
  82. /**
  83. * Converts an IP address to human readable form.
  84. *
  85. * @param addr IP address to convert
  86. * @param out destination buffer. Must be at least BIPADDR_MAX_PRINT_LEN characters long.
  87. */
  88. static void BIPAddr_Print (BIPAddr *addr, char *out);
  89. /**
  90. * Socket address - IP address and transport protocol port number
  91. */
  92. typedef struct {
  93. int type;
  94. union {
  95. struct {
  96. uint32_t ip;
  97. uint16_t port;
  98. } ipv4;
  99. struct {
  100. uint8_t ip[16];
  101. uint16_t port;
  102. } ipv6;
  103. struct {
  104. uint16_t phys_proto;
  105. int interface_index;
  106. int header_type;
  107. int packet_type;
  108. uint8_t phys_addr[8];
  109. } packet;
  110. };
  111. } BAddr;
  112. /**
  113. * Makes an invalid address.
  114. */
  115. static BAddr BAddr_MakeNone (void);
  116. /**
  117. * Makes an IPv4 address.
  118. *
  119. * @param ip IP address in network byte order
  120. * @param port port number in network byte order
  121. */
  122. static BAddr BAddr_MakeIPv4 (uint32_t ip, uint16_t port);
  123. /**
  124. * Makes an IPv6 address.
  125. *
  126. * @param ip IP address (16 bytes)
  127. * @param port port number in network byte order
  128. */
  129. static BAddr BAddr_MakeIPv6 (const uint8_t *ip, uint16_t port);
  130. /**
  131. * Makes an address from a BIPAddr and port number.
  132. *
  133. * @param ipaddr the BIPAddr
  134. * @param port port number in network byte order
  135. */
  136. static BAddr BAddr_MakeFromIpaddrAndPort (BIPAddr ipaddr, uint16_t port);
  137. /**
  138. * Deprecated, use BAddr_MakeNone.
  139. */
  140. static void BAddr_InitNone (BAddr *addr);
  141. /**
  142. * Deprecated, use BAddr_MakeIPv4.
  143. */
  144. static void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port);
  145. /**
  146. * Deprecated, use BAddr_MakeIPv6.
  147. */
  148. static void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port);
  149. /**
  150. * Deprecated, use BAddr_MakeFromIpaddrAndPort.
  151. */
  152. static void BAddr_InitFromIpaddrAndPort (BAddr *addr, BIPAddr ipaddr, uint16_t port);
  153. /**
  154. * Initializes a packet socket (data link layer) address.
  155. * Only Ethernet addresses are supported.
  156. *
  157. * @param addr the object
  158. * @param phys_proto identifier for the upper protocol, network byte order (EtherType)
  159. * @param interface_index network interface index
  160. * @param header_type data link layer header type. Must be BADDR_PACKET_HEADER_TYPE_ETHERNET.
  161. * @param packet_type the manner in which packets are sent/received. Must be one of
  162. * BADDR_PACKET_PACKET_TYPE_HOST, BADDR_PACKET_PACKET_TYPE_BROADCAST,
  163. * BADDR_PACKET_PACKET_TYPE_MULTICAST, BADDR_PACKET_PACKET_TYPE_OTHERHOST,
  164. * BADDR_PACKET_PACKET_TYPE_OUTGOING.
  165. * @param phys_addr data link layer address (MAC address)
  166. */
  167. static void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr);
  168. /**
  169. * Does nothing.
  170. *
  171. * @param addr the object
  172. */
  173. static void BAddr_Assert (BAddr *addr);
  174. /**
  175. * Determines whether the address is an invalid address.
  176. *
  177. * @param addr the object
  178. * @return 1 if invalid, 0 if invalid
  179. **/
  180. static int BAddr_IsInvalid (BAddr *addr);
  181. /**
  182. * Returns the port number in the address.
  183. *
  184. * @param addr the object
  185. * Must be an IPv4 or IPv6 address.
  186. * @return port number, in network byte order
  187. */
  188. static uint16_t BAddr_GetPort (BAddr *addr);
  189. /**
  190. * Returns the IP address in the address.
  191. *
  192. * @param addr the object
  193. * @param ipaddr IP address will be returned here. If \a addr is not
  194. * an IPv4 or IPv6 address, an invalid address will be
  195. * returned.
  196. */
  197. static void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr);
  198. /**
  199. * Sets the port number in the address.
  200. *
  201. * @param addr the object
  202. * Must be an IPv4 or IPv6 address.
  203. * @param port port number, in network byte order
  204. */
  205. static void BAddr_SetPort (BAddr *addr, uint16_t port);
  206. /**
  207. * Converts an IP address to human readable form.
  208. *
  209. * @param addr address to convert
  210. * @param out destination buffer. Must be at least BADDR_MAX_PRINT_LEN characters long.
  211. */
  212. static void BAddr_Print (BAddr *addr, char *out);
  213. /**
  214. * Resolves an address string.
  215. * Format is "addr:port" for IPv4, "[addr]:port" for IPv6.
  216. * addr is be a numeric address or a name.
  217. * port is a numeric port number.
  218. *
  219. * @param addr output address
  220. * @param name if not NULL, the name portion of the address will be
  221. * stored here
  222. * @param name_len if name is not NULL, the size of the name buffer
  223. * @param noresolve only accept numeric addresses. Avoids blocking the caller.
  224. * @return 1 on success, 0 on parse error
  225. */
  226. static int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve) WARN_UNUSED;
  227. /**
  228. * Resolves an address string.
  229. * IPv4 input format is "a.b.c.d:p", where a.b.c.d is the IP address
  230. * and d is the port number.
  231. * IPv6 input format is "[addr]:p", where addr is an IPv6 addres in
  232. * standard notation and p is the port number.
  233. *
  234. * @param addr output address
  235. * @param name if not NULL, the name portion of the address will be
  236. * stored here
  237. * @param name_len if name is not NULL, the size of the name buffer
  238. * @return 1 on success, 0 on parse error
  239. */
  240. static int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len) WARN_UNUSED;
  241. static int BAddr_Compare (BAddr *addr1, BAddr *addr2);
  242. static int BAddr_CompareOrder (BAddr *addr1, BAddr *addr2);
  243. void BIPAddr_InitInvalid (BIPAddr *addr)
  244. {
  245. addr->type = BADDR_TYPE_NONE;
  246. }
  247. void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip)
  248. {
  249. addr->type = BADDR_TYPE_IPV4;
  250. addr->ipv4 = ip;
  251. }
  252. void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip)
  253. {
  254. addr->type = BADDR_TYPE_IPV6;
  255. memcpy(addr->ipv6, ip, 16);
  256. }
  257. void BIPAddr_Assert (BIPAddr *addr)
  258. {
  259. switch (addr->type) {
  260. case BADDR_TYPE_NONE:
  261. case BADDR_TYPE_IPV4:
  262. case BADDR_TYPE_IPV6:
  263. return;
  264. default:
  265. ASSERT(0);
  266. }
  267. }
  268. int BIPAddr_IsInvalid (BIPAddr *addr)
  269. {
  270. BIPAddr_Assert(addr);
  271. return (addr->type == BADDR_TYPE_NONE);
  272. }
  273. int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve)
  274. {
  275. int len = strlen(str);
  276. char *addr_start;
  277. int addr_len;
  278. // determine address type
  279. if (len >= 1 && str[0] == '[' && str[len - 1] == ']') {
  280. addr->type = BADDR_TYPE_IPV6;
  281. addr_start = str + 1;
  282. addr_len = len - 2;
  283. } else {
  284. addr->type = BADDR_TYPE_IPV4;
  285. addr_start = str;
  286. addr_len = len;
  287. }
  288. // copy
  289. char addr_str[BADDR_MAX_ADDR_LEN + 1];
  290. if (addr_len > BADDR_MAX_ADDR_LEN) {
  291. return 0;
  292. }
  293. memcpy(addr_str, addr_start, addr_len);
  294. addr_str[addr_len] = '\0';
  295. // initialize hints
  296. struct addrinfo hints;
  297. memset(&hints, 0, sizeof(hints));
  298. switch (addr->type) {
  299. case BADDR_TYPE_IPV6:
  300. hints.ai_family = AF_INET6;
  301. break;
  302. case BADDR_TYPE_IPV4:
  303. hints.ai_family = AF_INET;
  304. break;
  305. }
  306. if (noresolve) {
  307. hints.ai_flags |= AI_NUMERICHOST;
  308. }
  309. // call getaddrinfo
  310. struct addrinfo *addrs;
  311. int res;
  312. if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) {
  313. return 0;
  314. }
  315. // set address
  316. switch (addr->type) {
  317. case BADDR_TYPE_IPV6:
  318. memcpy(addr->ipv6, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6));
  319. break;
  320. case BADDR_TYPE_IPV4:
  321. addr->ipv4 = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr;
  322. break;
  323. }
  324. freeaddrinfo(addrs);
  325. return 1;
  326. }
  327. int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2)
  328. {
  329. BIPAddr_Assert(addr1);
  330. BIPAddr_Assert(addr2);
  331. if (addr1->type != addr2->type) {
  332. return 0;
  333. }
  334. switch (addr1->type) {
  335. case BADDR_TYPE_NONE:
  336. return 0;
  337. case BADDR_TYPE_IPV4:
  338. return (addr1->ipv4 == addr2->ipv4);
  339. case BADDR_TYPE_IPV6:
  340. return (!memcmp(addr1->ipv6, addr2->ipv6, sizeof(addr1->ipv6)));
  341. default:
  342. ASSERT(0)
  343. return 0;
  344. }
  345. }
  346. uint16_t BAddr_GetPort (BAddr *addr)
  347. {
  348. BAddr_Assert(addr);
  349. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  350. switch (addr->type) {
  351. case BADDR_TYPE_IPV4:
  352. return addr->ipv4.port;
  353. case BADDR_TYPE_IPV6:
  354. return addr->ipv6.port;
  355. default:
  356. ASSERT(0)
  357. return 0;
  358. }
  359. }
  360. void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr)
  361. {
  362. BAddr_Assert(addr);
  363. switch (addr->type) {
  364. case BADDR_TYPE_IPV4:
  365. BIPAddr_InitIPv4(ipaddr, addr->ipv4.ip);
  366. return;
  367. case BADDR_TYPE_IPV6:
  368. BIPAddr_InitIPv6(ipaddr, addr->ipv6.ip);
  369. return;
  370. default:
  371. BIPAddr_InitInvalid(ipaddr);
  372. }
  373. }
  374. void BAddr_SetPort (BAddr *addr, uint16_t port)
  375. {
  376. BAddr_Assert(addr);
  377. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  378. switch (addr->type) {
  379. case BADDR_TYPE_IPV4:
  380. addr->ipv4.port = port;
  381. break;
  382. case BADDR_TYPE_IPV6:
  383. addr->ipv6.port = port;
  384. break;
  385. default:
  386. ASSERT(0);
  387. }
  388. }
  389. void BIPAddr_Print (BIPAddr *addr, char *out)
  390. {
  391. switch (addr->type) {
  392. case BADDR_TYPE_NONE:
  393. sprintf(out, "(none)");
  394. break;
  395. case BADDR_TYPE_IPV4:
  396. sprintf(out, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8,
  397. *((uint8_t *)&addr->ipv4 + 0),
  398. *((uint8_t *)&addr->ipv4 + 1),
  399. *((uint8_t *)&addr->ipv4 + 2),
  400. *((uint8_t *)&addr->ipv4 + 3)
  401. );
  402. break;
  403. case BADDR_TYPE_IPV6: {
  404. const char *ptr = (const char *)addr->ipv6;
  405. sprintf(out,
  406. "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16":"
  407. "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16,
  408. badvpn_read_be16(ptr + 0),
  409. badvpn_read_be16(ptr + 2),
  410. badvpn_read_be16(ptr + 4),
  411. badvpn_read_be16(ptr + 6),
  412. badvpn_read_be16(ptr + 8),
  413. badvpn_read_be16(ptr + 10),
  414. badvpn_read_be16(ptr + 12),
  415. badvpn_read_be16(ptr + 14)
  416. );
  417. } break;
  418. default:
  419. ASSERT(0);
  420. }
  421. }
  422. BAddr BAddr_MakeNone (void)
  423. {
  424. BAddr addr;
  425. addr.type = BADDR_TYPE_NONE;
  426. return addr;
  427. }
  428. BAddr BAddr_MakeIPv4 (uint32_t ip, uint16_t port)
  429. {
  430. BAddr addr;
  431. addr.type = BADDR_TYPE_IPV4;
  432. addr.ipv4.ip = ip;
  433. addr.ipv4.port = port;
  434. return addr;
  435. }
  436. BAddr BAddr_MakeIPv6 (const uint8_t *ip, uint16_t port)
  437. {
  438. BAddr addr;
  439. addr.type = BADDR_TYPE_IPV6;
  440. memcpy(addr.ipv6.ip, ip, 16);
  441. addr.ipv6.port = port;
  442. return addr;
  443. }
  444. BAddr BAddr_MakeFromIpaddrAndPort (BIPAddr ipaddr, uint16_t port)
  445. {
  446. BIPAddr_Assert(&ipaddr);
  447. switch (ipaddr.type) {
  448. case BADDR_TYPE_NONE:
  449. return BAddr_MakeNone();
  450. case BADDR_TYPE_IPV4:
  451. return BAddr_MakeIPv4(ipaddr.ipv4, port);
  452. case BADDR_TYPE_IPV6:
  453. return BAddr_MakeIPv6(ipaddr.ipv6, port);
  454. default:
  455. ASSERT(0);
  456. return BAddr_MakeNone();
  457. }
  458. }
  459. void BAddr_InitNone (BAddr *addr)
  460. {
  461. *addr = BAddr_MakeNone();
  462. }
  463. void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port)
  464. {
  465. *addr = BAddr_MakeIPv4(ip, port);
  466. }
  467. void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port)
  468. {
  469. *addr = BAddr_MakeIPv6(ip, port);
  470. }
  471. void BAddr_InitFromIpaddrAndPort (BAddr *addr, BIPAddr ipaddr, uint16_t port)
  472. {
  473. BIPAddr_Assert(&ipaddr);
  474. *addr = BAddr_MakeFromIpaddrAndPort(ipaddr, port);
  475. }
  476. #ifdef BADVPN_LINUX
  477. void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr)
  478. {
  479. ASSERT(header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET)
  480. ASSERT(packet_type == BADDR_PACKET_PACKET_TYPE_HOST || packet_type == BADDR_PACKET_PACKET_TYPE_BROADCAST ||
  481. packet_type == BADDR_PACKET_PACKET_TYPE_MULTICAST || packet_type == BADDR_PACKET_PACKET_TYPE_OTHERHOST ||
  482. packet_type == BADDR_PACKET_PACKET_TYPE_OUTGOING)
  483. addr->type = BADDR_TYPE_PACKET;
  484. addr->packet.phys_proto = phys_proto;
  485. addr->packet.interface_index = interface_index;
  486. addr->packet.header_type = header_type;
  487. addr->packet.packet_type = packet_type;
  488. memcpy(addr->packet.phys_addr, phys_addr, 6);
  489. }
  490. #endif
  491. void BAddr_Assert (BAddr *addr)
  492. {
  493. switch (addr->type) {
  494. case BADDR_TYPE_NONE:
  495. case BADDR_TYPE_IPV4:
  496. case BADDR_TYPE_IPV6:
  497. #ifdef BADVPN_LINUX
  498. case BADDR_TYPE_PACKET:
  499. #endif
  500. return;
  501. default:
  502. ASSERT(0);
  503. }
  504. }
  505. int BAddr_IsInvalid (BAddr *addr)
  506. {
  507. BAddr_Assert(addr);
  508. return (addr->type == BADDR_TYPE_NONE);
  509. }
  510. void BAddr_Print (BAddr *addr, char *out)
  511. {
  512. BAddr_Assert(addr);
  513. BIPAddr ipaddr;
  514. switch (addr->type) {
  515. case BADDR_TYPE_NONE:
  516. sprintf(out, "(none)");
  517. break;
  518. case BADDR_TYPE_IPV4:
  519. BIPAddr_InitIPv4(&ipaddr, addr->ipv4.ip);
  520. BIPAddr_Print(&ipaddr, out);
  521. sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv4.port));
  522. break;
  523. case BADDR_TYPE_IPV6:
  524. BIPAddr_InitIPv6(&ipaddr, addr->ipv6.ip);
  525. BIPAddr_Print(&ipaddr, out);
  526. sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv6.port));
  527. break;
  528. #ifdef BADVPN_LINUX
  529. case BADDR_TYPE_PACKET:
  530. ASSERT(addr->packet.header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET)
  531. sprintf(out, "proto=%"PRIu16",ifindex=%d,htype=eth,ptype=%d,addr=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8,
  532. addr->packet.phys_proto, (int)addr->packet.interface_index, (int)addr->packet.packet_type,
  533. addr->packet.phys_addr[0], addr->packet.phys_addr[1], addr->packet.phys_addr[2],
  534. addr->packet.phys_addr[3], addr->packet.phys_addr[4], addr->packet.phys_addr[5]);
  535. break;
  536. #endif
  537. default:
  538. ASSERT(0);
  539. }
  540. }
  541. int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve)
  542. {
  543. int len = strlen(str);
  544. if (len < 1 || len > 1000) {
  545. return 0;
  546. }
  547. int addr_start;
  548. int addr_len;
  549. int port_start;
  550. int port_len;
  551. // leading '[' indicates an IPv6 address
  552. if (str[0] == '[') {
  553. addr->type = BADDR_TYPE_IPV6;
  554. // find ']'
  555. int i=1;
  556. while (i < len && str[i] != ']') i++;
  557. if (i >= len) {
  558. return 0;
  559. }
  560. addr_start = 1;
  561. addr_len = i - addr_start;
  562. // follows ':' and port number
  563. if (i + 1 >= len || str[i + 1] != ':') {
  564. return 0;
  565. }
  566. port_start = i + 2;
  567. port_len = len - port_start;
  568. }
  569. // otherwise it's an IPv4 address
  570. else {
  571. addr->type = BADDR_TYPE_IPV4;
  572. // find ':'
  573. int i=0;
  574. while (i < len && str[i] != ':') i++;
  575. if (i >= len) {
  576. return 0;
  577. }
  578. addr_start = 0;
  579. addr_len = i - addr_start;
  580. port_start = i + 1;
  581. port_len = len - port_start;
  582. }
  583. // copy address and port to zero-terminated buffers
  584. char addr_str[128];
  585. if (addr_len >= sizeof(addr_str)) {
  586. return 0;
  587. }
  588. memcpy(addr_str, str + addr_start, addr_len);
  589. addr_str[addr_len] = '\0';
  590. char port_str[6];
  591. if (port_len >= sizeof(port_str)) {
  592. return 0;
  593. }
  594. memcpy(port_str, str + port_start, port_len);
  595. port_str[port_len] = '\0';
  596. // parse port
  597. char *err;
  598. long int conv_res = strtol(port_str, &err, 10);
  599. if (port_str[0] == '\0' || *err != '\0') {
  600. return 0;
  601. }
  602. if (conv_res < 0 || conv_res > UINT16_MAX) {
  603. return 0;
  604. }
  605. uint16_t port = conv_res;
  606. port = hton16(port);
  607. // initialize hints
  608. struct addrinfo hints;
  609. memset(&hints, 0, sizeof(hints));
  610. switch (addr->type) {
  611. case BADDR_TYPE_IPV6:
  612. hints.ai_family = AF_INET6;
  613. break;
  614. case BADDR_TYPE_IPV4:
  615. hints.ai_family = AF_INET;
  616. break;
  617. }
  618. if (noresolve) {
  619. hints.ai_flags |= AI_NUMERICHOST;
  620. }
  621. // call getaddrinfo
  622. struct addrinfo *addrs;
  623. int res;
  624. if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) {
  625. return 0;
  626. }
  627. // set address
  628. switch (addr->type) {
  629. case BADDR_TYPE_IPV6:
  630. memcpy(addr->ipv6.ip, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6.ip));
  631. addr->ipv6.port = port;
  632. break;
  633. case BADDR_TYPE_IPV4:
  634. addr->ipv4.ip = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr;
  635. addr->ipv4.port = port;
  636. break;
  637. }
  638. freeaddrinfo(addrs);
  639. if (name) {
  640. if (strlen(addr_str) >= name_len) {
  641. return 0;
  642. }
  643. strcpy(name, addr_str);
  644. }
  645. return 1;
  646. }
  647. int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len)
  648. {
  649. return BAddr_Parse2(addr, str, name, name_len, 0);
  650. }
  651. int BAddr_Compare (BAddr *addr1, BAddr *addr2)
  652. {
  653. BAddr_Assert(addr1);
  654. BAddr_Assert(addr2);
  655. if (addr1->type != addr2->type) {
  656. return 0;
  657. }
  658. switch (addr1->type) {
  659. case BADDR_TYPE_IPV4:
  660. return (addr1->ipv4.ip == addr2->ipv4.ip && addr1->ipv4.port == addr2->ipv4.port);
  661. case BADDR_TYPE_IPV6:
  662. return (!memcmp(addr1->ipv6.ip, addr2->ipv6.ip, sizeof(addr1->ipv6.ip)) && addr1->ipv6.port == addr2->ipv6.port);
  663. default:
  664. return 0;
  665. }
  666. }
  667. int BAddr_CompareOrder (BAddr *addr1, BAddr *addr2)
  668. {
  669. BAddr_Assert(addr1);
  670. BAddr_Assert(addr2);
  671. int cmp = B_COMPARE(addr1->type, addr2->type);
  672. if (cmp) {
  673. return cmp;
  674. }
  675. switch (addr1->type) {
  676. case BADDR_TYPE_NONE: {
  677. return 0;
  678. } break;
  679. case BADDR_TYPE_IPV4: {
  680. uint32_t ip1 = ntoh32(addr1->ipv4.ip);
  681. uint32_t ip2 = ntoh32(addr2->ipv4.ip);
  682. cmp = B_COMPARE(ip1, ip2);
  683. if (cmp) {
  684. return cmp;
  685. }
  686. uint16_t port1 = ntoh16(addr1->ipv4.port);
  687. uint16_t port2 = ntoh16(addr2->ipv4.port);
  688. return B_COMPARE(port1, port2);
  689. } break;
  690. case BADDR_TYPE_IPV6: {
  691. cmp = memcmp(addr1->ipv6.ip, addr2->ipv6.ip, sizeof(addr1->ipv6.ip));
  692. if (cmp) {
  693. return B_COMPARE(cmp, 0);
  694. }
  695. uint16_t port1 = ntoh16(addr1->ipv6.port);
  696. uint16_t port2 = ntoh16(addr2->ipv6.port);
  697. return B_COMPARE(port1, port2);
  698. } break;
  699. default: {
  700. return 0;
  701. } break;
  702. }
  703. }
  704. #endif