BAddr.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /**
  2. * @file BAddr.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. *
  22. * @section DESCRIPTION
  23. *
  24. * Network address abstractions used by {@link BSocket}.
  25. */
  26. #ifndef BADVPN_SYSTEM_BADDR_H
  27. #define BADVPN_SYSTEM_BADDR_H
  28. #include <stdint.h>
  29. #include <limits.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include <inttypes.h>
  34. #ifdef BADVPN_USE_WINAPI
  35. #include <ws2tcpip.h>
  36. #else
  37. #include <sys/types.h>
  38. #include <sys/socket.h>
  39. #include <netdb.h>
  40. #include <netinet/in.h>
  41. #endif
  42. #include <misc/byteorder.h>
  43. #include <misc/debug.h>
  44. #define BADDR_TYPE_NONE 0
  45. #define BADDR_TYPE_IPV4 1
  46. #define BADDR_TYPE_IPV6 2
  47. #ifndef BADVPN_USE_WINAPI
  48. #define BADDR_TYPE_UNIX 3 // only a domain number for BSocket
  49. #endif
  50. #ifdef BADVPN_LINUX
  51. #define BADDR_TYPE_PACKET 4
  52. #endif
  53. #define BADDR_MAX_ADDR_LEN 128
  54. #define BIPADDR_MAX_PRINT_LEN 40
  55. #define BADDR_MAX_PRINT_LEN 120
  56. #define BADDR_PACKET_HEADER_TYPE_ETHERNET 1
  57. #define BADDR_PACKET_PACKET_TYPE_HOST 1
  58. #define BADDR_PACKET_PACKET_TYPE_BROADCAST 2
  59. #define BADDR_PACKET_PACKET_TYPE_MULTICAST 3
  60. #define BADDR_PACKET_PACKET_TYPE_OTHERHOST 4
  61. #define BADDR_PACKET_PACKET_TYPE_OUTGOING 5
  62. typedef struct {
  63. int type;
  64. union {
  65. uint32_t ipv4;
  66. uint8_t ipv6[16];
  67. };
  68. } BIPAddr;
  69. static void BIPAddr_InitInvalid (BIPAddr *addr);
  70. static void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip);
  71. static void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip);
  72. static void BIPAddr_Assert (BIPAddr *addr);
  73. static int BIPAddr_IsInvalid (BIPAddr *addr);
  74. static int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve) WARN_UNUSED;
  75. static int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2);
  76. /**
  77. * Converts an IP address to human readable form.
  78. *
  79. * @param addr IP address to convert
  80. * @param out destination buffer. Must be at least BIPADDR_MAX_PRINT_LEN characters long.
  81. */
  82. static void BIPAddr_Print (BIPAddr *addr, char *out);
  83. /**
  84. * Socket address - IP address and transport protocol port number
  85. */
  86. typedef struct {
  87. int type;
  88. union {
  89. struct {
  90. uint32_t ip;
  91. uint16_t port;
  92. } ipv4;
  93. struct {
  94. uint8_t ip[16];
  95. uint16_t port;
  96. } ipv6;
  97. struct {
  98. uint16_t phys_proto;
  99. int interface_index;
  100. int header_type;
  101. int packet_type;
  102. uint8_t phys_addr[8];
  103. } packet;
  104. };
  105. } BAddr;
  106. /**
  107. * Initializes an invalid address.
  108. */
  109. static void BAddr_InitNone (BAddr *addr);
  110. /**
  111. * Initializes an IPv4 address.
  112. *
  113. * @param addr the object
  114. * @param ip IP address in network byte order
  115. * @param port port number in network byte order
  116. */
  117. static void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port);
  118. /**
  119. * Initializes an IPv6 address.
  120. *
  121. * @param addr the object
  122. * @param ip 16-byte IP address in network byte order
  123. * @param port port number in network byte order
  124. */
  125. static void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port);
  126. /**
  127. * Initializes a packet socket (data link layer) address.
  128. * Only Ethernet addresses are supported.
  129. *
  130. * @param addr the object
  131. * @param phys_proto identifier for the upper protocol, network byte order (EtherType)
  132. * @param interface_index network interface index
  133. * @param header_type data link layer header type. Must be BADDR_PACKET_HEADER_TYPE_ETHERNET.
  134. * @param packet_type the manner in which packets are sent/received. Must be one of
  135. * BADDR_PACKET_PACKET_TYPE_HOST, BADDR_PACKET_PACKET_TYPE_BROADCAST,
  136. * BADDR_PACKET_PACKET_TYPE_MULTICAST, BADDR_PACKET_PACKET_TYPE_OTHERHOST,
  137. * BADDR_PACKET_PACKET_TYPE_OUTGOING.
  138. * @param phys_addr data link layer address (MAC address)
  139. */
  140. static void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr);
  141. /**
  142. * Does nothing.
  143. *
  144. * @param addr the object
  145. */
  146. static void BAddr_Assert (BAddr *addr);
  147. /**
  148. * Determines whether the address is an invalid address.
  149. *
  150. * @param addr the object
  151. * @return 1 if invalid, 0 if invalid
  152. **/
  153. static int BAddr_IsInvalid (BAddr *addr);
  154. /**
  155. * Returns the port number in the address.
  156. *
  157. * @param addr the object
  158. * Must be an IPv4 or IPv6 address.
  159. * @return port number, in network byte order
  160. */
  161. static uint16_t BAddr_GetPort (BAddr *addr);
  162. /**
  163. * Returns the IP address in the address.
  164. *
  165. * @param addr the object
  166. * Must be an IPv4 or IPv6 address.
  167. * @param ipaddr IP address will be returned here
  168. */
  169. static void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr);
  170. /**
  171. * Sets the port number in the address.
  172. *
  173. * @param addr the object
  174. * Must be an IPv4 or IPv6 address.
  175. * @param port port number, in network byte order
  176. */
  177. static void BAddr_SetPort (BAddr *addr, uint16_t port);
  178. /**
  179. * Converts an IP address to human readable form.
  180. *
  181. * @param addr address to convert
  182. * @param out destination buffer. Must be at least BADDR_MAX_PRINT_LEN characters long.
  183. */
  184. static void BAddr_Print (BAddr *addr, char *out);
  185. /**
  186. * Resolves an address string.
  187. * Format is "addr:port" for IPv4, "[addr]:port" for IPv6.
  188. * addr is be a numeric address or a name.
  189. * port is a numeric port number.
  190. *
  191. * @param addr output address
  192. * @param name if not NULL, the name portion of the address will be
  193. * stored here
  194. * @param name_len if name is not NULL, the size of the name buffer
  195. * @param noresolve only accept numeric addresses. Avoids blocking the caller.
  196. * @return 1 on success, 0 on parse error
  197. */
  198. static int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve) WARN_UNUSED;
  199. /**
  200. * Resolves an address string.
  201. * IPv4 input format is "a.b.c.d:p", where a.b.c.d is the IP address
  202. * and d is the port number.
  203. * IPv6 input format is "[addr]:p", where addr is an IPv6 addres in
  204. * standard notation and p is the port number.
  205. *
  206. * @param addr output address
  207. * @param name if not NULL, the name portion of the address will be
  208. * stored here
  209. * @param name_len if name is not NULL, the size of the name buffer
  210. * @return 1 on success, 0 on parse error
  211. */
  212. static int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len) WARN_UNUSED;
  213. void BIPAddr_InitInvalid (BIPAddr *addr)
  214. {
  215. addr->type = BADDR_TYPE_NONE;
  216. }
  217. void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip)
  218. {
  219. addr->type = BADDR_TYPE_IPV4;
  220. addr->ipv4 = ip;
  221. }
  222. void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip)
  223. {
  224. addr->type = BADDR_TYPE_IPV6;
  225. memcpy(addr->ipv6, ip, 16);
  226. }
  227. void BIPAddr_Assert (BIPAddr *addr)
  228. {
  229. switch (addr->type) {
  230. case BADDR_TYPE_NONE:
  231. case BADDR_TYPE_IPV4:
  232. case BADDR_TYPE_IPV6:
  233. return;
  234. default:
  235. ASSERT(0);
  236. }
  237. }
  238. int BIPAddr_IsInvalid (BIPAddr *addr)
  239. {
  240. BIPAddr_Assert(addr);
  241. return (addr->type == BADDR_TYPE_NONE);
  242. }
  243. int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve)
  244. {
  245. int len = strlen(str);
  246. char *addr_start;
  247. int addr_len;
  248. // determine address type
  249. if (len >= 1 && str[0] == '[' && str[len - 1] == ']') {
  250. addr->type = BADDR_TYPE_IPV6;
  251. addr_start = str + 1;
  252. addr_len = len - 2;
  253. } else {
  254. addr->type = BADDR_TYPE_IPV4;
  255. addr_start = str;
  256. addr_len = len;
  257. }
  258. // copy
  259. char addr_str[BADDR_MAX_ADDR_LEN + 1];
  260. if (addr_len > BADDR_MAX_ADDR_LEN) {
  261. return 0;
  262. }
  263. memcpy(addr_str, addr_start, addr_len);
  264. addr_str[addr_len] = '\0';
  265. // initialize hints
  266. struct addrinfo hints;
  267. memset(&hints, 0, sizeof(hints));
  268. switch (addr->type) {
  269. case BADDR_TYPE_IPV6:
  270. hints.ai_family = AF_INET6;
  271. break;
  272. case BADDR_TYPE_IPV4:
  273. hints.ai_family = AF_INET;
  274. break;
  275. }
  276. if (noresolve) {
  277. hints.ai_flags |= AI_NUMERICHOST;
  278. }
  279. // call getaddrinfo
  280. struct addrinfo *addrs;
  281. int res;
  282. if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) {
  283. return 0;
  284. }
  285. // set address
  286. switch (addr->type) {
  287. case BADDR_TYPE_IPV6:
  288. memcpy(addr->ipv6, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6));
  289. break;
  290. case BADDR_TYPE_IPV4:
  291. addr->ipv4 = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr;
  292. break;
  293. }
  294. freeaddrinfo(addrs);
  295. return 1;
  296. }
  297. int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2)
  298. {
  299. BIPAddr_Assert(addr1);
  300. BIPAddr_Assert(addr2);
  301. if (addr1->type != addr2->type) {
  302. return 0;
  303. }
  304. switch (addr1->type) {
  305. case BADDR_TYPE_NONE:
  306. return 0;
  307. case BADDR_TYPE_IPV4:
  308. return (addr1->ipv4 == addr2->ipv4);
  309. case BADDR_TYPE_IPV6:
  310. return (!memcmp(addr1->ipv6, addr2->ipv6, sizeof(addr1->ipv6)));
  311. default:
  312. ASSERT(0)
  313. return 0;
  314. }
  315. }
  316. uint16_t BAddr_GetPort (BAddr *addr)
  317. {
  318. BAddr_Assert(addr);
  319. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  320. switch (addr->type) {
  321. case BADDR_TYPE_IPV4:
  322. return addr->ipv4.port;
  323. case BADDR_TYPE_IPV6:
  324. return addr->ipv6.port;
  325. default:
  326. ASSERT(0)
  327. return 0;
  328. }
  329. }
  330. void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr)
  331. {
  332. BAddr_Assert(addr);
  333. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  334. switch (addr->type) {
  335. case BADDR_TYPE_IPV4:
  336. BIPAddr_InitIPv4(ipaddr, addr->ipv4.ip);
  337. return;
  338. case BADDR_TYPE_IPV6:
  339. BIPAddr_InitIPv6(ipaddr, addr->ipv6.ip);
  340. return;
  341. default:
  342. ASSERT(0);
  343. }
  344. }
  345. void BAddr_SetPort (BAddr *addr, uint16_t port)
  346. {
  347. BAddr_Assert(addr);
  348. ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6)
  349. switch (addr->type) {
  350. case BADDR_TYPE_IPV4:
  351. addr->ipv4.port = port;
  352. break;
  353. case BADDR_TYPE_IPV6:
  354. addr->ipv6.port = port;
  355. break;
  356. default:
  357. ASSERT(0);
  358. }
  359. }
  360. struct _BAddr_ipv6_addr
  361. {
  362. uint16_t addr[8];
  363. } __attribute__((packed));
  364. void BIPAddr_Print (BIPAddr *addr, char *out)
  365. {
  366. switch (addr->type) {
  367. case BADDR_TYPE_NONE:
  368. sprintf(out, "(none)");
  369. break;
  370. case BADDR_TYPE_IPV4:
  371. sprintf(out, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8,
  372. *((uint8_t *)&addr->ipv4 + 0),
  373. *((uint8_t *)&addr->ipv4 + 1),
  374. *((uint8_t *)&addr->ipv4 + 2),
  375. *((uint8_t *)&addr->ipv4 + 3)
  376. );
  377. break;
  378. case BADDR_TYPE_IPV6: {
  379. struct _BAddr_ipv6_addr *s = (struct _BAddr_ipv6_addr *)addr->ipv6;
  380. sprintf(out,
  381. "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16":"
  382. "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16,
  383. ntoh16(s->addr[0]),
  384. ntoh16(s->addr[1]),
  385. ntoh16(s->addr[2]),
  386. ntoh16(s->addr[3]),
  387. ntoh16(s->addr[4]),
  388. ntoh16(s->addr[5]),
  389. ntoh16(s->addr[6]),
  390. ntoh16(s->addr[7])
  391. );
  392. } break;
  393. default:
  394. ASSERT(0);
  395. }
  396. }
  397. void BAddr_InitNone (BAddr *addr)
  398. {
  399. addr->type = BADDR_TYPE_NONE;
  400. }
  401. void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port)
  402. {
  403. addr->type = BADDR_TYPE_IPV4;
  404. addr->ipv4.ip = ip;
  405. addr->ipv4.port = port;
  406. }
  407. void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port)
  408. {
  409. addr->type = BADDR_TYPE_IPV6;
  410. memcpy(addr->ipv6.ip, ip, 16);
  411. addr->ipv6.port = port;
  412. }
  413. #ifdef BADVPN_LINUX
  414. void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr)
  415. {
  416. ASSERT(header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET)
  417. ASSERT(packet_type == BADDR_PACKET_PACKET_TYPE_HOST || packet_type == BADDR_PACKET_PACKET_TYPE_BROADCAST ||
  418. packet_type == BADDR_PACKET_PACKET_TYPE_MULTICAST || packet_type == BADDR_PACKET_PACKET_TYPE_OTHERHOST ||
  419. packet_type == BADDR_PACKET_PACKET_TYPE_OUTGOING)
  420. addr->type = BADDR_TYPE_PACKET;
  421. addr->packet.phys_proto = phys_proto;
  422. addr->packet.interface_index = interface_index;
  423. addr->packet.header_type = header_type;
  424. addr->packet.packet_type = packet_type;
  425. memcpy(addr->packet.phys_addr, phys_addr, 6);
  426. }
  427. #endif
  428. void BAddr_Assert (BAddr *addr)
  429. {
  430. switch (addr->type) {
  431. case BADDR_TYPE_NONE:
  432. case BADDR_TYPE_IPV4:
  433. case BADDR_TYPE_IPV6:
  434. #ifdef BADVPN_LINUX
  435. case BADDR_TYPE_PACKET:
  436. #endif
  437. return;
  438. default:
  439. ASSERT(0);
  440. }
  441. }
  442. int BAddr_IsInvalid (BAddr *addr)
  443. {
  444. BAddr_Assert(addr);
  445. return (addr->type == BADDR_TYPE_NONE);
  446. }
  447. void BAddr_Print (BAddr *addr, char *out)
  448. {
  449. BAddr_Assert(addr);
  450. BIPAddr ipaddr;
  451. switch (addr->type) {
  452. case BADDR_TYPE_NONE:
  453. sprintf(out, "(none)");
  454. break;
  455. case BADDR_TYPE_IPV4:
  456. BIPAddr_InitIPv4(&ipaddr, addr->ipv4.ip);
  457. BIPAddr_Print(&ipaddr, out);
  458. sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv4.port));
  459. break;
  460. case BADDR_TYPE_IPV6:
  461. BIPAddr_InitIPv6(&ipaddr, addr->ipv6.ip);
  462. BIPAddr_Print(&ipaddr, out);
  463. sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv6.port));
  464. break;
  465. #ifdef BADVPN_LINUX
  466. case BADDR_TYPE_PACKET:
  467. ASSERT(addr->packet.header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET)
  468. sprintf(out, "proto=%"PRIu16",ifindex=%d,htype=eth,ptype=%d,addr=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8,
  469. addr->packet.phys_proto, (int)addr->packet.interface_index, (int)addr->packet.packet_type,
  470. addr->packet.phys_addr[0], addr->packet.phys_addr[1], addr->packet.phys_addr[2],
  471. addr->packet.phys_addr[3], addr->packet.phys_addr[4], addr->packet.phys_addr[5]);
  472. break;
  473. #endif
  474. default:
  475. ASSERT(0);
  476. }
  477. }
  478. int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve)
  479. {
  480. BAddr result;
  481. int len = strlen(str);
  482. if (len < 1 || len > 1000) {
  483. return 0;
  484. }
  485. int addr_start;
  486. int addr_len;
  487. int port_start;
  488. int port_len;
  489. // leading '[' indicates an IPv6 address
  490. if (str[0] == '[') {
  491. addr->type = BADDR_TYPE_IPV6;
  492. // find ']'
  493. int i=1;
  494. while (i < len && str[i] != ']') i++;
  495. if (i >= len) {
  496. return 0;
  497. }
  498. addr_start = 1;
  499. addr_len = i - addr_start;
  500. // follows ':' and port number
  501. if (i + 1 >= len || str[i + 1] != ':') {
  502. return 0;
  503. }
  504. port_start = i + 2;
  505. port_len = len - port_start;
  506. }
  507. // otherwise it's an IPv4 address
  508. else {
  509. addr->type = BADDR_TYPE_IPV4;
  510. // find ':'
  511. int i=0;
  512. while (i < len && str[i] != ':') i++;
  513. if (i >= len) {
  514. return 0;
  515. }
  516. addr_start = 0;
  517. addr_len = i - addr_start;
  518. port_start = i + 1;
  519. port_len = len - port_start;
  520. }
  521. // copy address and port to zero-terminated buffers
  522. char addr_str[128];
  523. if (addr_len >= sizeof(addr_str)) {
  524. return 0;
  525. }
  526. memcpy(addr_str, str + addr_start, addr_len);
  527. addr_str[addr_len] = '\0';
  528. char port_str[6];
  529. if (port_len >= sizeof(port_str)) {
  530. return 0;
  531. }
  532. memcpy(port_str, str + port_start, port_len);
  533. port_str[port_len] = '\0';
  534. // parse port
  535. char *err;
  536. long int conv_res = strtol(port_str, &err, 10);
  537. if (port_str[0] == '\0' || *err != '\0') {
  538. return 0;
  539. }
  540. if (conv_res < 0 || conv_res > UINT16_MAX) {
  541. return 0;
  542. }
  543. uint16_t port = conv_res;
  544. port = hton16(port);
  545. // initialize hints
  546. struct addrinfo hints;
  547. memset(&hints, 0, sizeof(hints));
  548. switch (addr->type) {
  549. case BADDR_TYPE_IPV6:
  550. hints.ai_family = AF_INET6;
  551. break;
  552. case BADDR_TYPE_IPV4:
  553. hints.ai_family = AF_INET;
  554. break;
  555. }
  556. if (noresolve) {
  557. hints.ai_flags |= AI_NUMERICHOST;
  558. }
  559. // call getaddrinfo
  560. struct addrinfo *addrs;
  561. int res;
  562. if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) {
  563. return 0;
  564. }
  565. // set address
  566. switch (addr->type) {
  567. case BADDR_TYPE_IPV6:
  568. memcpy(addr->ipv6.ip, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6.ip));
  569. addr->ipv6.port = port;
  570. break;
  571. case BADDR_TYPE_IPV4:
  572. addr->ipv4.ip = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr;
  573. addr->ipv4.port = port;
  574. break;
  575. }
  576. freeaddrinfo(addrs);
  577. if (name) {
  578. snprintf(name, name_len, "%s", addr_str);
  579. }
  580. return 1;
  581. }
  582. int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len)
  583. {
  584. return BAddr_Parse2(addr, str, name, name_len, 0);
  585. }
  586. #endif