BAddr.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  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. static void BIPAddr_InitLocalhost (BIPAddr *addr, int addr_type);
  83. /**
  84. * Converts an IP address to human readable form.
  85. *
  86. * @param addr IP address to convert
  87. * @param out destination buffer. Must be at least BIPADDR_MAX_PRINT_LEN characters long.
  88. */
  89. static void BIPAddr_Print (BIPAddr *addr, char *out);
  90. /**
  91. * Socket address - IP address and transport protocol port number
  92. */
  93. typedef struct {
  94. int type;
  95. union {
  96. struct {
  97. uint32_t ip;
  98. uint16_t port;
  99. } ipv4;
  100. struct {
  101. uint8_t ip[16];
  102. uint16_t port;
  103. } ipv6;
  104. struct {
  105. uint16_t phys_proto;
  106. int interface_index;
  107. int header_type;
  108. int packet_type;
  109. uint8_t phys_addr[8];
  110. } packet;
  111. };
  112. } BAddr;
  113. /**
  114. * Makes an invalid address.
  115. */
  116. static BAddr BAddr_MakeNone (void);
  117. /**
  118. * Makes an IPv4 address.
  119. *
  120. * @param ip IP address in network byte order
  121. * @param port port number in network byte order
  122. */
  123. static BAddr BAddr_MakeIPv4 (uint32_t ip, uint16_t port);
  124. /**
  125. * Makes an IPv6 address.
  126. *
  127. * @param ip IP address (16 bytes)
  128. * @param port port number in network byte order
  129. */
  130. static BAddr BAddr_MakeIPv6 (const uint8_t *ip, uint16_t port);
  131. /**
  132. * Makes an address from a BIPAddr and port number.
  133. *
  134. * @param ipaddr the BIPAddr
  135. * @param port port number in network byte order
  136. */
  137. static BAddr BAddr_MakeFromIpaddrAndPort (BIPAddr ipaddr, uint16_t port);
  138. /**
  139. * Deprecated, use BAddr_MakeNone.
  140. */
  141. static void BAddr_InitNone (BAddr *addr);
  142. /**
  143. * Deprecated, use BAddr_MakeIPv4.
  144. */
  145. static void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port);
  146. /**
  147. * Deprecated, use BAddr_MakeIPv6.
  148. */
  149. static void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port);
  150. /**
  151. * Deprecated, use BAddr_MakeFromIpaddrAndPort.
  152. */
  153. static void BAddr_InitFromIpaddrAndPort (BAddr *addr, BIPAddr ipaddr, uint16_t port);
  154. /**
  155. * Initializes a packet socket (data link layer) address.
  156. * Only Ethernet addresses are supported.
  157. *
  158. * @param addr the object
  159. * @param phys_proto identifier for the upper protocol, network byte order (EtherType)
  160. * @param interface_index network interface index
  161. * @param header_type data link layer header type. Must be BADDR_PACKET_HEADER_TYPE_ETHERNET.
  162. * @param packet_type the manner in which packets are sent/received. Must be one of
  163. * BADDR_PACKET_PACKET_TYPE_HOST, BADDR_PACKET_PACKET_TYPE_BROADCAST,
  164. * BADDR_PACKET_PACKET_TYPE_MULTICAST, BADDR_PACKET_PACKET_TYPE_OTHERHOST,
  165. * BADDR_PACKET_PACKET_TYPE_OUTGOING.
  166. * @param phys_addr data link layer address (MAC address)
  167. */
  168. static void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr);
  169. /**
  170. * Does nothing.
  171. *
  172. * @param addr the object
  173. */
  174. static void BAddr_Assert (BAddr *addr);
  175. /**
  176. * Determines whether the address is an invalid address.
  177. *
  178. * @param addr the object
  179. * @return 1 if invalid, 0 if invalid
  180. **/
  181. static int BAddr_IsInvalid (BAddr *addr);
  182. /**
  183. * Returns the port number in the address.
  184. *
  185. * @param addr the object
  186. * Must be an IPv4 or IPv6 address.
  187. * @return port number, in network byte order
  188. */
  189. static uint16_t BAddr_GetPort (BAddr *addr);
  190. /**
  191. * Returns the IP address in the address.
  192. *
  193. * @param addr the object
  194. * @param ipaddr IP address will be returned here. If \a addr is not
  195. * an IPv4 or IPv6 address, an invalid address will be
  196. * returned.
  197. */
  198. static void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr);
  199. /**
  200. * Sets the port number in the address.
  201. *
  202. * @param addr the object
  203. * Must be an IPv4 or IPv6 address.
  204. * @param port port number, in network byte order
  205. */
  206. static void BAddr_SetPort (BAddr *addr, uint16_t port);
  207. /**
  208. * Converts an IP address to human readable form.
  209. *
  210. * @param addr address to convert
  211. * @param out destination buffer. Must be at least BADDR_MAX_PRINT_LEN characters long.
  212. */
  213. static void BAddr_Print (BAddr *addr, char *out);
  214. /**
  215. * Resolves an address string.
  216. * Format is "addr:port" for IPv4, "[addr]:port" for IPv6.
  217. * addr is be a numeric address or a name.
  218. * port is a numeric port number.
  219. *
  220. * @param addr output address
  221. * @param name if not NULL, the name portion of the address will be
  222. * stored here
  223. * @param name_len if name is not NULL, the size of the name buffer
  224. * @param noresolve only accept numeric addresses. Avoids blocking the caller.
  225. * @return 1 on success, 0 on parse error
  226. */
  227. static int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve) WARN_UNUSED;
  228. /**
  229. * Resolves an address string.
  230. * IPv4 input format is "a.b.c.d:p", where a.b.c.d is the IP address
  231. * and d is the port number.
  232. * IPv6 input format is "[addr]:p", where addr is an IPv6 addres in
  233. * standard notation and p is the port number.
  234. *
  235. * @param addr output address
  236. * @param name if not NULL, the name portion of the address will be
  237. * stored here
  238. * @param name_len if name is not NULL, the size of the name buffer
  239. * @return 1 on success, 0 on parse error
  240. */
  241. static int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len) WARN_UNUSED;
  242. static int BAddr_Compare (BAddr *addr1, BAddr *addr2);
  243. static int BAddr_CompareOrder (BAddr *addr1, BAddr *addr2);
  244. void BIPAddr_InitInvalid (BIPAddr *addr)
  245. {
  246. addr->type = BADDR_TYPE_NONE;
  247. }
  248. void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip)
  249. {
  250. addr->type = BADDR_TYPE_IPV4;
  251. addr->ipv4 = ip;
  252. }
  253. void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip)
  254. {
  255. addr->type = BADDR_TYPE_IPV6;
  256. memcpy(addr->ipv6, ip, 16);
  257. }
  258. void BIPAddr_Assert (BIPAddr *addr)
  259. {
  260. switch (addr->type) {
  261. case BADDR_TYPE_NONE:
  262. case BADDR_TYPE_IPV4:
  263. case BADDR_TYPE_IPV6:
  264. return;
  265. default:
  266. ASSERT(0);
  267. }
  268. }
  269. int BIPAddr_IsInvalid (BIPAddr *addr)
  270. {
  271. BIPAddr_Assert(addr);
  272. return (addr->type == BADDR_TYPE_NONE);
  273. }
  274. int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve)
  275. {
  276. int len = strlen(str);
  277. char *addr_start;
  278. int addr_len;
  279. // determine address type
  280. if (len >= 1 && str[0] == '[' && str[len - 1] == ']') {
  281. addr->type = BADDR_TYPE_IPV6;
  282. addr_start = str + 1;
  283. addr_len = len - 2;
  284. } else {
  285. addr->type = BADDR_TYPE_IPV4;
  286. addr_start = str;
  287. addr_len = len;
  288. }
  289. // copy
  290. char addr_str[BADDR_MAX_ADDR_LEN + 1];
  291. if (addr_len > BADDR_MAX_ADDR_LEN) {
  292. return 0;
  293. }
  294. memcpy(addr_str, addr_start, addr_len);
  295. addr_str[addr_len] = '\0';
  296. // initialize hints
  297. struct addrinfo hints;
  298. memset(&hints, 0, sizeof(hints));
  299. switch (addr->type) {
  300. case BADDR_TYPE_IPV6:
  301. hints.ai_family = AF_INET6;
  302. break;
  303. case BADDR_TYPE_IPV4:
  304. hints.ai_family = AF_INET;
  305. break;
  306. }
  307. if (noresolve) {
  308. hints.ai_flags |= AI_NUMERICHOST;
  309. }
  310. // call getaddrinfo
  311. struct addrinfo *addrs;
  312. int res;
  313. if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) {
  314. return 0;
  315. }
  316. // set address
  317. switch (addr->type) {
  318. case BADDR_TYPE_IPV6:
  319. memcpy(addr->ipv6, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6));
  320. break;
  321. case BADDR_TYPE_IPV4:
  322. addr->ipv4 = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr;
  323. break;
  324. }
  325. freeaddrinfo(addrs);
  326. return 1;
  327. }
  328. int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2)
  329. {
  330. BIPAddr_Assert(addr1);
  331. BIPAddr_Assert(addr2);
  332. if (addr1->type != addr2->type) {
  333. return 0;
  334. }
  335. switch (addr1->type) {
  336. case BADDR_TYPE_NONE:
  337. return 0;
  338. case BADDR_TYPE_IPV4:
  339. return (addr1->ipv4 == addr2->ipv4);
  340. case BADDR_TYPE_IPV6:
  341. return (!memcmp(addr1->ipv6, addr2->ipv6, sizeof(addr1->ipv6)));
  342. default:
  343. ASSERT(0)
  344. return 0;
  345. }
  346. }
  347. uint16_t BAddr_GetPort (BAddr *addr)
  348. {
  349. BAddr_Assert(addr);
  350. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  351. switch (addr->type) {
  352. case BADDR_TYPE_IPV4:
  353. return addr->ipv4.port;
  354. case BADDR_TYPE_IPV6:
  355. return addr->ipv6.port;
  356. default:
  357. ASSERT(0)
  358. return 0;
  359. }
  360. }
  361. void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr)
  362. {
  363. BAddr_Assert(addr);
  364. switch (addr->type) {
  365. case BADDR_TYPE_IPV4:
  366. BIPAddr_InitIPv4(ipaddr, addr->ipv4.ip);
  367. return;
  368. case BADDR_TYPE_IPV6:
  369. BIPAddr_InitIPv6(ipaddr, addr->ipv6.ip);
  370. return;
  371. default:
  372. BIPAddr_InitInvalid(ipaddr);
  373. }
  374. }
  375. void BAddr_SetPort (BAddr *addr, uint16_t port)
  376. {
  377. BAddr_Assert(addr);
  378. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  379. switch (addr->type) {
  380. case BADDR_TYPE_IPV4:
  381. addr->ipv4.port = port;
  382. break;
  383. case BADDR_TYPE_IPV6:
  384. addr->ipv6.port = port;
  385. break;
  386. default:
  387. ASSERT(0);
  388. }
  389. }
  390. void BIPAddr_Print (BIPAddr *addr, char *out)
  391. {
  392. switch (addr->type) {
  393. case BADDR_TYPE_NONE:
  394. sprintf(out, "(none)");
  395. break;
  396. case BADDR_TYPE_IPV4:
  397. sprintf(out, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8,
  398. *((uint8_t *)&addr->ipv4 + 0),
  399. *((uint8_t *)&addr->ipv4 + 1),
  400. *((uint8_t *)&addr->ipv4 + 2),
  401. *((uint8_t *)&addr->ipv4 + 3)
  402. );
  403. break;
  404. case BADDR_TYPE_IPV6: {
  405. const char *ptr = (const char *)addr->ipv6;
  406. sprintf(out,
  407. "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16":"
  408. "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16,
  409. badvpn_read_be16(ptr + 0),
  410. badvpn_read_be16(ptr + 2),
  411. badvpn_read_be16(ptr + 4),
  412. badvpn_read_be16(ptr + 6),
  413. badvpn_read_be16(ptr + 8),
  414. badvpn_read_be16(ptr + 10),
  415. badvpn_read_be16(ptr + 12),
  416. badvpn_read_be16(ptr + 14)
  417. );
  418. } break;
  419. default:
  420. ASSERT(0);
  421. }
  422. }
  423. BAddr BAddr_MakeNone (void)
  424. {
  425. BAddr addr;
  426. addr.type = BADDR_TYPE_NONE;
  427. return addr;
  428. }
  429. BAddr BAddr_MakeIPv4 (uint32_t ip, uint16_t port)
  430. {
  431. BAddr addr;
  432. addr.type = BADDR_TYPE_IPV4;
  433. addr.ipv4.ip = ip;
  434. addr.ipv4.port = port;
  435. return addr;
  436. }
  437. BAddr BAddr_MakeIPv6 (const uint8_t *ip, uint16_t port)
  438. {
  439. BAddr addr;
  440. addr.type = BADDR_TYPE_IPV6;
  441. memcpy(addr.ipv6.ip, ip, 16);
  442. addr.ipv6.port = port;
  443. return addr;
  444. }
  445. BAddr BAddr_MakeFromIpaddrAndPort (BIPAddr ipaddr, uint16_t port)
  446. {
  447. BIPAddr_Assert(&ipaddr);
  448. switch (ipaddr.type) {
  449. case BADDR_TYPE_NONE:
  450. return BAddr_MakeNone();
  451. case BADDR_TYPE_IPV4:
  452. return BAddr_MakeIPv4(ipaddr.ipv4, port);
  453. case BADDR_TYPE_IPV6:
  454. return BAddr_MakeIPv6(ipaddr.ipv6, port);
  455. default:
  456. ASSERT(0);
  457. return BAddr_MakeNone();
  458. }
  459. }
  460. void BAddr_InitNone (BAddr *addr)
  461. {
  462. *addr = BAddr_MakeNone();
  463. }
  464. void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port)
  465. {
  466. *addr = BAddr_MakeIPv4(ip, port);
  467. }
  468. void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port)
  469. {
  470. *addr = BAddr_MakeIPv6(ip, port);
  471. }
  472. void BAddr_InitFromIpaddrAndPort (BAddr *addr, BIPAddr ipaddr, uint16_t port)
  473. {
  474. BIPAddr_Assert(&ipaddr);
  475. *addr = BAddr_MakeFromIpaddrAndPort(ipaddr, port);
  476. }
  477. #ifdef BADVPN_LINUX
  478. void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr)
  479. {
  480. ASSERT(header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET)
  481. ASSERT(packet_type == BADDR_PACKET_PACKET_TYPE_HOST || packet_type == BADDR_PACKET_PACKET_TYPE_BROADCAST ||
  482. packet_type == BADDR_PACKET_PACKET_TYPE_MULTICAST || packet_type == BADDR_PACKET_PACKET_TYPE_OTHERHOST ||
  483. packet_type == BADDR_PACKET_PACKET_TYPE_OUTGOING)
  484. addr->type = BADDR_TYPE_PACKET;
  485. addr->packet.phys_proto = phys_proto;
  486. addr->packet.interface_index = interface_index;
  487. addr->packet.header_type = header_type;
  488. addr->packet.packet_type = packet_type;
  489. memcpy(addr->packet.phys_addr, phys_addr, 6);
  490. }
  491. #endif
  492. void BAddr_Assert (BAddr *addr)
  493. {
  494. switch (addr->type) {
  495. case BADDR_TYPE_NONE:
  496. case BADDR_TYPE_IPV4:
  497. case BADDR_TYPE_IPV6:
  498. #ifdef BADVPN_LINUX
  499. case BADDR_TYPE_PACKET:
  500. #endif
  501. return;
  502. default:
  503. ASSERT(0);
  504. }
  505. }
  506. int BAddr_IsInvalid (BAddr *addr)
  507. {
  508. BAddr_Assert(addr);
  509. return (addr->type == BADDR_TYPE_NONE);
  510. }
  511. void BAddr_Print (BAddr *addr, char *out)
  512. {
  513. BAddr_Assert(addr);
  514. BIPAddr ipaddr;
  515. switch (addr->type) {
  516. case BADDR_TYPE_NONE:
  517. sprintf(out, "(none)");
  518. break;
  519. case BADDR_TYPE_IPV4:
  520. BIPAddr_InitIPv4(&ipaddr, addr->ipv4.ip);
  521. BIPAddr_Print(&ipaddr, out);
  522. sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv4.port));
  523. break;
  524. case BADDR_TYPE_IPV6:
  525. BIPAddr_InitIPv6(&ipaddr, addr->ipv6.ip);
  526. BIPAddr_Print(&ipaddr, out);
  527. sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv6.port));
  528. break;
  529. #ifdef BADVPN_LINUX
  530. case BADDR_TYPE_PACKET:
  531. ASSERT(addr->packet.header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET)
  532. sprintf(out, "proto=%"PRIu16",ifindex=%d,htype=eth,ptype=%d,addr=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8,
  533. addr->packet.phys_proto, (int)addr->packet.interface_index, (int)addr->packet.packet_type,
  534. addr->packet.phys_addr[0], addr->packet.phys_addr[1], addr->packet.phys_addr[2],
  535. addr->packet.phys_addr[3], addr->packet.phys_addr[4], addr->packet.phys_addr[5]);
  536. break;
  537. #endif
  538. default:
  539. ASSERT(0);
  540. }
  541. }
  542. int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve)
  543. {
  544. int len = strlen(str);
  545. if (len < 1 || len > 1000) {
  546. return 0;
  547. }
  548. int addr_start;
  549. int addr_len;
  550. int port_start;
  551. int port_len;
  552. // leading '[' indicates an IPv6 address
  553. if (str[0] == '[') {
  554. addr->type = BADDR_TYPE_IPV6;
  555. // find ']'
  556. int i=1;
  557. while (i < len && str[i] != ']') i++;
  558. if (i >= len) {
  559. return 0;
  560. }
  561. addr_start = 1;
  562. addr_len = i - addr_start;
  563. // follows ':' and port number
  564. if (i + 1 >= len || str[i + 1] != ':') {
  565. return 0;
  566. }
  567. port_start = i + 2;
  568. port_len = len - port_start;
  569. }
  570. // otherwise it's an IPv4 address
  571. else {
  572. addr->type = BADDR_TYPE_IPV4;
  573. // find ':'
  574. int i=0;
  575. while (i < len && str[i] != ':') i++;
  576. if (i >= len) {
  577. return 0;
  578. }
  579. addr_start = 0;
  580. addr_len = i - addr_start;
  581. port_start = i + 1;
  582. port_len = len - port_start;
  583. }
  584. // copy address and port to zero-terminated buffers
  585. char addr_str[128];
  586. if (addr_len >= sizeof(addr_str)) {
  587. return 0;
  588. }
  589. memcpy(addr_str, str + addr_start, addr_len);
  590. addr_str[addr_len] = '\0';
  591. char port_str[6];
  592. if (port_len >= sizeof(port_str)) {
  593. return 0;
  594. }
  595. memcpy(port_str, str + port_start, port_len);
  596. port_str[port_len] = '\0';
  597. // parse port
  598. char *err;
  599. long int conv_res = strtol(port_str, &err, 10);
  600. if (port_str[0] == '\0' || *err != '\0') {
  601. return 0;
  602. }
  603. if (conv_res < 0 || conv_res > UINT16_MAX) {
  604. return 0;
  605. }
  606. uint16_t port = conv_res;
  607. port = hton16(port);
  608. // initialize hints
  609. struct addrinfo hints;
  610. memset(&hints, 0, sizeof(hints));
  611. switch (addr->type) {
  612. case BADDR_TYPE_IPV6:
  613. hints.ai_family = AF_INET6;
  614. break;
  615. case BADDR_TYPE_IPV4:
  616. hints.ai_family = AF_INET;
  617. break;
  618. }
  619. if (noresolve) {
  620. hints.ai_flags |= AI_NUMERICHOST;
  621. }
  622. // call getaddrinfo
  623. struct addrinfo *addrs;
  624. int res;
  625. if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) {
  626. return 0;
  627. }
  628. // set address
  629. switch (addr->type) {
  630. case BADDR_TYPE_IPV6:
  631. memcpy(addr->ipv6.ip, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6.ip));
  632. addr->ipv6.port = port;
  633. break;
  634. case BADDR_TYPE_IPV4:
  635. addr->ipv4.ip = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr;
  636. addr->ipv4.port = port;
  637. break;
  638. }
  639. freeaddrinfo(addrs);
  640. if (name) {
  641. if (strlen(addr_str) >= name_len) {
  642. return 0;
  643. }
  644. strcpy(name, addr_str);
  645. }
  646. return 1;
  647. }
  648. int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len)
  649. {
  650. return BAddr_Parse2(addr, str, name, name_len, 0);
  651. }
  652. int BAddr_Compare (BAddr *addr1, BAddr *addr2)
  653. {
  654. BAddr_Assert(addr1);
  655. BAddr_Assert(addr2);
  656. if (addr1->type != addr2->type) {
  657. return 0;
  658. }
  659. switch (addr1->type) {
  660. case BADDR_TYPE_IPV4:
  661. return (addr1->ipv4.ip == addr2->ipv4.ip && addr1->ipv4.port == addr2->ipv4.port);
  662. case BADDR_TYPE_IPV6:
  663. return (!memcmp(addr1->ipv6.ip, addr2->ipv6.ip, sizeof(addr1->ipv6.ip)) && addr1->ipv6.port == addr2->ipv6.port);
  664. default:
  665. return 0;
  666. }
  667. }
  668. int BAddr_CompareOrder (BAddr *addr1, BAddr *addr2)
  669. {
  670. BAddr_Assert(addr1);
  671. BAddr_Assert(addr2);
  672. int cmp = B_COMPARE(addr1->type, addr2->type);
  673. if (cmp) {
  674. return cmp;
  675. }
  676. switch (addr1->type) {
  677. case BADDR_TYPE_NONE: {
  678. return 0;
  679. } break;
  680. case BADDR_TYPE_IPV4: {
  681. uint32_t ip1 = ntoh32(addr1->ipv4.ip);
  682. uint32_t ip2 = ntoh32(addr2->ipv4.ip);
  683. cmp = B_COMPARE(ip1, ip2);
  684. if (cmp) {
  685. return cmp;
  686. }
  687. uint16_t port1 = ntoh16(addr1->ipv4.port);
  688. uint16_t port2 = ntoh16(addr2->ipv4.port);
  689. return B_COMPARE(port1, port2);
  690. } break;
  691. case BADDR_TYPE_IPV6: {
  692. cmp = memcmp(addr1->ipv6.ip, addr2->ipv6.ip, sizeof(addr1->ipv6.ip));
  693. if (cmp) {
  694. return B_COMPARE(cmp, 0);
  695. }
  696. uint16_t port1 = ntoh16(addr1->ipv6.port);
  697. uint16_t port2 = ntoh16(addr2->ipv6.port);
  698. return B_COMPARE(port1, port2);
  699. } break;
  700. default: {
  701. return 0;
  702. } break;
  703. }
  704. }
  705. void BIPAddr_InitLocalhost (BIPAddr *addr, int addr_type)
  706. {
  707. if (addr_type == BADDR_TYPE_IPV4) {
  708. addr->type = addr_type;
  709. addr->ipv4 = hton32(0x7f000001);
  710. }
  711. else if (addr_type == BADDR_TYPE_IPV6) {
  712. addr->type = addr_type;
  713. memset(addr->ipv6, 0, 16);
  714. addr->ipv6[15] = 1;
  715. }
  716. else {
  717. addr->type = BADDR_TYPE_NONE;
  718. }
  719. }
  720. #endif