ip_addr.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. /* $Id$
  2. *
  3. * ip address family related structures
  4. *
  5. * Copyright (C) 2001-2003 FhG Fokus
  6. *
  7. * This file is part of ser, a free SIP server.
  8. *
  9. * ser is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version
  13. *
  14. * For a license to use the ser software under conditions
  15. * other than those described here, or to purchase support for this
  16. * software, please contact iptel.org by e-mail at the following addresses:
  17. * [email protected]
  18. *
  19. * ser is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27. */
  28. /*
  29. * History:
  30. * --------
  31. * 2003-02-13 added struct dest_info (andrei)
  32. * 2003-04-06 all ports are stored/passed in host byte order now (andrei)
  33. * 2006-04-20 comp support in recv_info and dest_info (andrei)
  34. * 2006-04-21 added init_dst_from_rcv (andrei)
  35. * 2007-06-26 added ip_addr_mk_any() (andrei)
  36. * 2008-05-21 added su2a(), ip_addr2sbuf(), ip4tosbuf(), ip62sbuf() (andrei)
  37. * 2009-09-14 added send flags support to dest_info (andrei)
  38. */
  39. #ifndef ip_addr_h
  40. #define ip_addr_h
  41. #include <string.h>
  42. #include <sys/types.h>
  43. #include <sys/socket.h>
  44. #include <netinet/in.h>
  45. #include <netdb.h>
  46. #include "str.h"
  47. #include "compiler_opt.h"
  48. #include "ut.h"
  49. #include "dprint.h"
  50. enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, PROTO_WS, PROTO_WSS, PROTO_OTHER };
  51. #define PROTO_LAST PROTO_OTHER
  52. #ifdef USE_COMP
  53. enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
  54. #endif
  55. struct ip_addr{
  56. unsigned int af; /* address family: AF_INET6 or AF_INET */
  57. unsigned int len; /* address len, 16 or 4 */
  58. /* 64 bits aligned address */
  59. union {
  60. unsigned long addrl[16/sizeof(long)]; /* long format*/
  61. unsigned int addr32[4];
  62. unsigned short addr16[8];
  63. unsigned char addr[16];
  64. }u;
  65. };
  66. typedef struct ip_addr ip_addr_t;
  67. struct net{
  68. struct ip_addr ip;
  69. struct ip_addr mask;
  70. };
  71. union sockaddr_union{
  72. struct sockaddr s;
  73. struct sockaddr_in sin;
  74. #ifdef USE_IPV6
  75. struct sockaddr_in6 sin6;
  76. #endif
  77. };
  78. enum si_flags { SI_NONE=0, SI_IS_IP=1, SI_IS_LO=2, SI_IS_MCAST=4,
  79. SI_IS_ANY=8, SI_IS_MHOMED=16 };
  80. struct addr_info{
  81. str name; /* name - eg.: foo.bar or 10.0.0.1 */
  82. struct ip_addr address; /*ip address */
  83. str address_str; /*ip address converted to string -- optimization*/
  84. enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
  85. union sockaddr_union su;
  86. struct addr_info* next;
  87. struct addr_info* prev;
  88. };
  89. struct advertise_info {
  90. str name; /* name - eg.: foo.bar or 10.0.0.1 */
  91. unsigned short port_no; /* port number */
  92. str port_no_str; /* port number converted to string -- optimization*/
  93. str address_str; /*ip address converted to string -- optimization*/
  94. struct ip_addr address; /* ip address */
  95. str sock_str; /* Socket proto, ip, and port as string */
  96. };
  97. struct socket_info{
  98. int socket;
  99. str name; /* name - eg.: foo.bar or 10.0.0.1 */
  100. struct ip_addr address; /* ip address */
  101. str address_str; /*ip address converted to string -- optimization*/
  102. str port_no_str; /* port number converted to string -- optimization*/
  103. enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
  104. union sockaddr_union su;
  105. struct socket_info* next;
  106. struct socket_info* prev;
  107. unsigned short port_no; /* port number */
  108. char proto; /* tcp or udp*/
  109. str sock_str; /* Socket proto, ip, and port as string */
  110. struct addr_info* addr_info_lst; /* extra addresses (e.g. SCTP mh) */
  111. int workers; /* number of worker processes for this socket */
  112. int workers_tcpidx; /* index of workers in tcp children array */
  113. struct advertise_info useinfo; /* details to be used in SIP msg */
  114. };
  115. struct receive_info{
  116. struct ip_addr src_ip;
  117. struct ip_addr dst_ip;
  118. unsigned short src_port; /* host byte order */
  119. unsigned short dst_port; /* host byte order */
  120. int proto_reserved1; /* tcp stores the connection id here */
  121. int proto_reserved2;
  122. union sockaddr_union src_su; /* useful for replies*/
  123. struct socket_info* bind_address; /* sock_info structure on which
  124. the msg was received*/
  125. char proto;
  126. #ifdef USE_COMP
  127. short comp; /* compression */
  128. #endif
  129. /* no need for dst_su yet */
  130. };
  131. /* send flags */
  132. #define SND_F_FORCE_CON_REUSE 1 /* reuse an existing connection or fail */
  133. #define SND_F_CON_CLOSE 2 /* close the connection after sending */
  134. #define SND_F_FORCE_SOCKET 4 /* send socket in dst is forced */
  135. struct snd_flags {
  136. unsigned char f; /* snd flags */
  137. unsigned char blst_imask; /* blacklist ignore mask */
  138. };
  139. typedef struct snd_flags snd_flags_t;
  140. #define SND_FLAGS_INIT(sflags) \
  141. do{ \
  142. (sflags)->f=0; \
  143. (sflags)->blst_imask=0; \
  144. }while(0)
  145. #define SND_FLAGS_OR(dst, src1, src2) \
  146. do{ \
  147. (dst)->f = (src1)->f | (src2)->f; \
  148. (dst)->blst_imask = (src1)->blst_imask | (src2)->blst_imask; \
  149. }while(0)
  150. #define SND_FLAGS_AND(dst, src1, src2) \
  151. do{ \
  152. (dst)->f = (src1)->f & (src2)->f; \
  153. (dst)->blst_imask = (src1)->blst_imask & (src2)->blst_imask; \
  154. }while(0)
  155. struct dest_info{
  156. struct socket_info* send_sock;
  157. union sockaddr_union to;
  158. int id; /* tcp stores the connection id here */
  159. char proto;
  160. snd_flags_t send_flags;
  161. #ifdef USE_COMP
  162. short comp;
  163. #endif
  164. };
  165. /* list of names for multi-homed sockets that need to bind on
  166. * multiple addresses in the same time (sctp ) */
  167. struct name_lst{
  168. char* name;
  169. struct name_lst* next;
  170. int flags;
  171. };
  172. struct socket_id{
  173. struct name_lst* addr_lst; /* address list, the first one must
  174. be present and is the main one
  175. (in case of multihoming sctp)*/
  176. int flags;
  177. int proto;
  178. int port;
  179. struct socket_id* next;
  180. };
  181. /* len of the sockaddr */
  182. #ifdef HAVE_SOCKADDR_SA_LEN
  183. #define sockaddru_len(su) ((su).s.sa_len)
  184. #else
  185. #ifdef USE_IPV6
  186. #define sockaddru_len(su) \
  187. (((su).s.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):\
  188. sizeof(struct sockaddr_in))
  189. #else
  190. #define sockaddru_len(su) sizeof(struct sockaddr_in)
  191. #endif /*USE_IPV6*/
  192. #endif /* HAVE_SOCKADDR_SA_LEN*/
  193. /* inits an ip_addr with the addr. info from a hostent structure
  194. * ip = struct ip_addr*
  195. * he= struct hostent*
  196. */
  197. #define hostent2ip_addr(ip, he, addr_no) \
  198. do{ \
  199. (ip)->af=(he)->h_addrtype; \
  200. (ip)->len=(he)->h_length; \
  201. memcpy((ip)->u.addr, (he)->h_addr_list[(addr_no)], (ip)->len); \
  202. }while(0)
  203. /* gets the protocol family corresponding to a specific address family
  204. * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
  205. */
  206. #ifdef USE_IPV6
  207. #define AF2PF(af) (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
  208. #else
  209. #define AF2PF(af) (((af)==AF_INET)?PF_INET:(af))
  210. #endif
  211. struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask);
  212. struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
  213. int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask);
  214. int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen);
  215. int mk_net_str(struct net* dst, str* s);
  216. void print_ip(char* prefix, struct ip_addr* ip, char* suffix);
  217. void stdout_print_ip(struct ip_addr* ip);
  218. void print_net(struct net* net);
  219. char* get_proto_name(unsigned int proto);
  220. #define proto2a get_proto_name
  221. #ifdef USE_MCAST
  222. /* Returns 1 if the given address is a multicast address */
  223. int is_mcast(struct ip_addr* ip);
  224. #endif /* USE_MCAST */
  225. /* returns 1 if the given ip address is INADDR_ANY or IN6ADDR_ANY,
  226. * 0 otherwise */
  227. inline static int ip_addr_any(struct ip_addr* ip)
  228. {
  229. int r;
  230. int l;
  231. l=ip->len/4;
  232. for (r=0; r<l; r++)
  233. if (ip->u.addr32[r]!=0)
  234. return 0;
  235. return 1;
  236. }
  237. /* returns 1 if the given ip address is a loopback address
  238. * 0 otherwise */
  239. inline static int ip_addr_loopback(struct ip_addr* ip)
  240. {
  241. if (ip->af==AF_INET)
  242. return ip->u.addr32[0]==htonl(INADDR_LOOPBACK);
  243. #ifdef USE_IPV6
  244. else if (ip->af==AF_INET6)
  245. return IN6_IS_ADDR_LOOPBACK((struct in6_addr*)ip->u.addr32);
  246. #endif /* USE_IPV6 */
  247. return 0;
  248. }
  249. /* creates an ANY ip_addr (filled with 0, af and len properly set) */
  250. inline static void ip_addr_mk_any(int af, struct ip_addr* ip)
  251. {
  252. ip->af=af;
  253. if (likely(af==AF_INET)){
  254. ip->len=4;
  255. ip->u.addr32[0]=0;
  256. }
  257. #ifdef USE_IPV6
  258. else{
  259. ip->len=16;
  260. #if (defined (ULONG_MAX) && ULONG_MAX > 4294967295) || defined LP64
  261. /* long is 64 bits */
  262. ip->u.addrl[0]=0;
  263. ip->u.addrl[1]=0;
  264. #else
  265. ip->u.addr32[0]=0;
  266. ip->u.addr32[1]=0;
  267. ip->u.addr32[2]=0;
  268. ip->u.addr32[3]=0;
  269. #endif /* ULONG_MAX */
  270. }
  271. #endif
  272. }
  273. /* returns 1 if ip & net.mask == net.ip ; 0 otherwise & -1 on error
  274. [ diff. address families ]) */
  275. inline static int matchnet(struct ip_addr* ip, struct net* net)
  276. {
  277. unsigned int r;
  278. if (ip->af == net->ip.af){
  279. for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
  280. all multiple of 4*/
  281. if ((ip->u.addr32[r]&net->mask.u.addr32[r])!=
  282. net->ip.u.addr32[r]){
  283. return 0;
  284. }
  285. }
  286. return 1;
  287. };
  288. return -1;
  289. }
  290. /* inits an ip_addr pointer from a sockaddr structure*/
  291. static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
  292. {
  293. switch(sa->sa_family){
  294. case AF_INET:
  295. ip->af=AF_INET;
  296. ip->len=4;
  297. memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
  298. break;
  299. #ifdef USE_IPV6
  300. case AF_INET6:
  301. ip->af=AF_INET6;
  302. ip->len=16;
  303. memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
  304. break;
  305. #endif
  306. default:
  307. LOG(L_CRIT, "sockaddr2ip_addr: BUG: unknown address family %d\n",
  308. sa->sa_family);
  309. }
  310. }
  311. /* compare 2 ip_addrs (both args are pointers)*/
  312. #define ip_addr_cmp(ip1, ip2) \
  313. (((ip1)->af==(ip2)->af)&& \
  314. (memcmp((ip1)->u.addr, (ip2)->u.addr, (ip1)->len)==0))
  315. /* compare 2 sockaddr_unions */
  316. static inline int su_cmp(const union sockaddr_union* s1,
  317. const union sockaddr_union* s2)
  318. {
  319. if (s1->s.sa_family!=s2->s.sa_family) return 0;
  320. switch(s1->s.sa_family){
  321. case AF_INET:
  322. return (s1->sin.sin_port==s2->sin.sin_port)&&
  323. (memcmp(&s1->sin.sin_addr, &s2->sin.sin_addr, 4)==0);
  324. #ifdef USE_IPV6
  325. case AF_INET6:
  326. return (s1->sin6.sin6_port==s2->sin6.sin6_port)&&
  327. (memcmp(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr, 16)==0);
  328. #endif
  329. default:
  330. LOG(L_CRIT,"su_cmp: BUG: unknown address family %d\n",
  331. s1->s.sa_family);
  332. return 0;
  333. }
  334. }
  335. /* gets the port number (host byte order) */
  336. static inline unsigned short su_getport(const union sockaddr_union* su)
  337. {
  338. switch(su->s.sa_family){
  339. case AF_INET:
  340. return ntohs(su->sin.sin_port);
  341. #ifdef USE_IPV6
  342. case AF_INET6:
  343. return ntohs(su->sin6.sin6_port);
  344. #endif
  345. default:
  346. LOG(L_CRIT,"su_get_port: BUG: unknown address family %d\n",
  347. su->s.sa_family);
  348. return 0;
  349. }
  350. }
  351. /* sets the port number (host byte order) */
  352. static inline void su_setport(union sockaddr_union* su, unsigned short port)
  353. {
  354. switch(su->s.sa_family){
  355. case AF_INET:
  356. su->sin.sin_port=htons(port);
  357. break;
  358. #ifdef USE_IPV6
  359. case AF_INET6:
  360. su->sin6.sin6_port=htons(port);
  361. break;
  362. #endif
  363. default:
  364. LOG(L_CRIT,"su_set_port: BUG: unknown address family %d\n",
  365. su->s.sa_family);
  366. }
  367. }
  368. /* inits an ip_addr pointer from a sockaddr_union ip address */
  369. static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
  370. {
  371. switch(su->s.sa_family){
  372. case AF_INET:
  373. ip->af=AF_INET;
  374. ip->len=4;
  375. memcpy(ip->u.addr, &su->sin.sin_addr, 4);
  376. break;
  377. #ifdef USE_IPV6
  378. case AF_INET6:
  379. ip->af=AF_INET6;
  380. ip->len=16;
  381. memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
  382. break;
  383. #endif
  384. default:
  385. LOG(L_CRIT,"su2ip_addr: BUG: unknown address family %d\n",
  386. su->s.sa_family);
  387. }
  388. }
  389. /* ip_addr2su -> the same as init_su*/
  390. #define ip_addr2su init_su
  391. /* inits a struct sockaddr_union from a struct ip_addr and a port no
  392. * returns 0 if ok, -1 on error (unknown address family)
  393. * the port number is in host byte order */
  394. static inline int init_su( union sockaddr_union* su,
  395. struct ip_addr* ip,
  396. unsigned short port )
  397. {
  398. memset(su, 0, sizeof(union sockaddr_union));/*needed on freebsd*/
  399. su->s.sa_family=ip->af;
  400. switch(ip->af){
  401. #ifdef USE_IPV6
  402. case AF_INET6:
  403. memcpy(&su->sin6.sin6_addr, ip->u.addr, ip->len);
  404. #ifdef HAVE_SOCKADDR_SA_LEN
  405. su->sin6.sin6_len=sizeof(struct sockaddr_in6);
  406. #endif
  407. su->sin6.sin6_port=htons(port);
  408. break;
  409. #endif
  410. case AF_INET:
  411. memcpy(&su->sin.sin_addr, ip->u.addr, ip->len);
  412. #ifdef HAVE_SOCKADDR_SA_LEN
  413. su->sin.sin_len=sizeof(struct sockaddr_in);
  414. #endif
  415. su->sin.sin_port=htons(port);
  416. break;
  417. default:
  418. LOG(L_CRIT, "init_ss: BUG: unknown address family %d\n", ip->af);
  419. return -1;
  420. }
  421. return 0;
  422. }
  423. /* inits a struct sockaddr_union from a struct hostent, an address index in
  424. * the hostent structure and a port no. (host byte order)
  425. * WARNING: no index overflow checks!
  426. * returns 0 if ok, -1 on error (unknown address family) */
  427. static inline int hostent2su( union sockaddr_union* su,
  428. struct hostent* he,
  429. unsigned int idx,
  430. unsigned short port )
  431. {
  432. memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
  433. su->s.sa_family=he->h_addrtype;
  434. switch(he->h_addrtype){
  435. #ifdef USE_IPV6
  436. case AF_INET6:
  437. memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
  438. #ifdef HAVE_SOCKADDR_SA_LEN
  439. su->sin6.sin6_len=sizeof(struct sockaddr_in6);
  440. #endif
  441. su->sin6.sin6_port=htons(port);
  442. break;
  443. #endif
  444. case AF_INET:
  445. memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
  446. #ifdef HAVE_SOCKADDR_SA_LEN
  447. su->sin.sin_len=sizeof(struct sockaddr_in);
  448. #endif
  449. su->sin.sin_port=htons(port);
  450. break;
  451. default:
  452. LOG(L_CRIT, "hostent2su: BUG: unknown address family %d\n",
  453. he->h_addrtype);
  454. return -1;
  455. }
  456. return 0;
  457. }
  458. /* maximum size of a str returned by ip_addr2str */
  459. #define IP6_MAX_STR_SIZE 39 /*1234:5678:9012:3456:7890:1234:5678:9012*/
  460. #define IP4_MAX_STR_SIZE 15 /*123.456.789.012*/
  461. #ifdef USE_IPV6
  462. /* converts a raw ipv6 addr (16 bytes) to ascii */
  463. static inline int ip6tosbuf(unsigned char* ip6, char* buff, int len)
  464. {
  465. int offset;
  466. register unsigned char a,b,c;
  467. register unsigned char d;
  468. register unsigned short hex4;
  469. int r;
  470. #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
  471. offset=0;
  472. if (unlikely(len<IP6_MAX_STR_SIZE))
  473. return 0;
  474. for(r=0;r<7;r++){
  475. hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
  476. a=hex4>>12;
  477. b=(hex4>>8)&0xf;
  478. c=(hex4>>4)&0xf;
  479. d=hex4&0xf;
  480. if (a){
  481. buff[offset]=HEXDIG(a);
  482. buff[offset+1]=HEXDIG(b);
  483. buff[offset+2]=HEXDIG(c);
  484. buff[offset+3]=HEXDIG(d);
  485. buff[offset+4]=':';
  486. offset+=5;
  487. }else if(b){
  488. buff[offset]=HEXDIG(b);
  489. buff[offset+1]=HEXDIG(c);
  490. buff[offset+2]=HEXDIG(d);
  491. buff[offset+3]=':';
  492. offset+=4;
  493. }else if(c){
  494. buff[offset]=HEXDIG(c);
  495. buff[offset+1]=HEXDIG(d);
  496. buff[offset+2]=':';
  497. offset+=3;
  498. }else{
  499. buff[offset]=HEXDIG(d);
  500. buff[offset+1]=':';
  501. offset+=2;
  502. }
  503. }
  504. /* last int16*/
  505. hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
  506. a=hex4>>12;
  507. b=(hex4>>8)&0xf;
  508. c=(hex4>>4)&0xf;
  509. d=hex4&0xf;
  510. if (a){
  511. buff[offset]=HEXDIG(a);
  512. buff[offset+1]=HEXDIG(b);
  513. buff[offset+2]=HEXDIG(c);
  514. buff[offset+3]=HEXDIG(d);
  515. offset+=4;
  516. }else if(b){
  517. buff[offset]=HEXDIG(b);
  518. buff[offset+1]=HEXDIG(c);
  519. buff[offset+2]=HEXDIG(d);
  520. offset+=3;
  521. }else if(c){
  522. buff[offset]=HEXDIG(c);
  523. buff[offset+1]=HEXDIG(d);
  524. offset+=2;
  525. }else{
  526. buff[offset]=HEXDIG(d);
  527. offset+=1;
  528. }
  529. return offset;
  530. }
  531. #endif /* USE_IPV6 */
  532. /* converts a raw ipv4 addr (4 bytes) to ascii */
  533. static inline int ip4tosbuf(unsigned char* ip4, char* buff, int len)
  534. {
  535. int offset;
  536. register unsigned char a,b,c;
  537. int r;
  538. offset=0;
  539. if (unlikely(len<IP4_MAX_STR_SIZE))
  540. return 0;
  541. for(r=0;r<3;r++){
  542. a=(unsigned char)ip4[r]/100;
  543. c=(unsigned char)ip4[r]%10;
  544. b=(unsigned char)ip4[r]%100/10;
  545. if (a){
  546. buff[offset]=a+'0';
  547. buff[offset+1]=b+'0';
  548. buff[offset+2]=c+'0';
  549. buff[offset+3]='.';
  550. offset+=4;
  551. }else if (b){
  552. buff[offset]=b+'0';
  553. buff[offset+1]=c+'0';
  554. buff[offset+2]='.';
  555. offset+=3;
  556. }else{
  557. buff[offset]=c+'0';
  558. buff[offset+1]='.';
  559. offset+=2;
  560. }
  561. }
  562. /* last number */
  563. a=(unsigned char)ip4[r]/100;
  564. c=(unsigned char)ip4[r]%10;
  565. b=(unsigned char)ip4[r]%100/10;
  566. if (a){
  567. buff[offset]=a+'0';
  568. buff[offset+1]=b+'0';
  569. buff[offset+2]=c+'0';
  570. offset+=3;
  571. }else if (b){
  572. buff[offset]=b+'0';
  573. buff[offset+1]=c+'0';
  574. offset+=2;
  575. }else{
  576. buff[offset]=c+'0';
  577. offset+=1;
  578. }
  579. return offset;
  580. }
  581. /* fast ip_addr -> string converter;
  582. * returns number of bytes written in buf on success, <=0 on error
  583. * The buffer must have enough space to hold the maximum size ip address
  584. * of the corresponding address (see IP[46] above) or else the function
  585. * will return error (no detailed might fit checks are made, for example
  586. * if len==7 the function will fail even for 1.2.3.4).
  587. */
  588. static inline int ip_addr2sbuf(struct ip_addr* ip, char* buff, int len)
  589. {
  590. switch(ip->af){
  591. #ifdef USE_IPV6
  592. case AF_INET6:
  593. return ip6tosbuf(ip->u.addr, buff, len);
  594. break;
  595. #endif /* USE_IPV6 */
  596. case AF_INET:
  597. return ip4tosbuf(ip->u.addr, buff, len);
  598. break;
  599. default:
  600. LOG(L_CRIT, "BUG: ip_addr2sbuf: unknown address family %d\n",
  601. ip->af);
  602. return 0;
  603. }
  604. return 0;
  605. }
  606. /* maximum size of a str returned by ip_addr2a (including \0) */
  607. #define IP_ADDR_MAX_STR_SIZE (IP6_MAX_STR_SIZE+1) /* ip62ascii + \0*/
  608. /* fast ip_addr -> string converter;
  609. * it uses an internal buffer
  610. */
  611. static inline char* ip_addr2a(struct ip_addr* ip)
  612. {
  613. static char buff[IP_ADDR_MAX_STR_SIZE];
  614. int len;
  615. len=ip_addr2sbuf(ip, buff, sizeof(buff)-1);
  616. buff[len]=0;
  617. return buff;
  618. }
  619. /* full address in text representation, including [] for ipv6 */
  620. static inline char* ip_addr2strz(struct ip_addr* ip)
  621. {
  622. static char buff[IP_ADDR_MAX_STR_SIZE+2];
  623. char *p;
  624. int len;
  625. p = buff;
  626. if(ip->af==AF_INET6) {
  627. *p++ = '[';
  628. }
  629. len=ip_addr2sbuf(ip, p, sizeof(buff)-3);
  630. p += len;
  631. if(ip->af==AF_INET6) {
  632. *p++ = ']';
  633. }
  634. *p=0;
  635. return buff;
  636. }
  637. #define SU2A_MAX_STR_SIZE (IP6_MAX_STR_SIZE + 2 /* [] */+\
  638. 1 /* : */ + USHORT2SBUF_MAX_LEN + 1 /* \0 */)
  639. /* returns an asciiz string containing the ip and the port
  640. * (<ip_addr>:port or [<ipv6_addr>]:port)
  641. */
  642. static inline char* su2a(union sockaddr_union* su, int su_len)
  643. {
  644. static char buf[SU2A_MAX_STR_SIZE];
  645. int offs;
  646. #ifdef USE_IPV6
  647. if (unlikely(su->s.sa_family==AF_INET6)){
  648. if (unlikely(su_len<sizeof(su->sin6)))
  649. return "<addr. error>";
  650. buf[0]='[';
  651. offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
  652. sizeof(buf)-4);
  653. buf[offs]=']';
  654. offs++;
  655. }else
  656. #endif /* USE_IPV6*/
  657. if (unlikely(su_len<sizeof(su->sin)))
  658. return "<addr. error>";
  659. else
  660. offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
  661. buf[offs]=':';
  662. offs+=1+ushort2sbuf(su_getport(su), &buf[offs+1], sizeof(buf)-(offs+1)-1);
  663. buf[offs]=0;
  664. return buf;
  665. }
  666. #define SUIP2A_MAX_STR_SIZE (IP6_MAX_STR_SIZE + 2 /* [] */ + 1 /* \0 */)
  667. /* returns an asciiz string containing the ip
  668. * (<ipv4_addr> or [<ipv6_addr>])
  669. */
  670. static inline char* suip2a(union sockaddr_union* su, int su_len)
  671. {
  672. static char buf[SUIP2A_MAX_STR_SIZE];
  673. int offs;
  674. #ifdef USE_IPV6
  675. if (unlikely(su->s.sa_family==AF_INET6)){
  676. if (unlikely(su_len<sizeof(su->sin6)))
  677. return "<addr. error>";
  678. buf[0]='[';
  679. offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
  680. sizeof(buf)-4);
  681. buf[offs]=']';
  682. offs++;
  683. }else
  684. #endif /* USE_IPV6*/
  685. if (unlikely(su_len<sizeof(su->sin)))
  686. return "<addr. error>";
  687. else
  688. offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
  689. buf[offs]=0;
  690. return buf;
  691. }
  692. /* converts an ip_addr structure to a hostent, returns pointer to internal
  693. * statical structure */
  694. static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
  695. {
  696. static struct hostent he;
  697. static char hostname[256];
  698. static char* p_aliases[1];
  699. static char* p_addr[2];
  700. static char address[16];
  701. p_aliases[0]=0; /* no aliases*/
  702. p_addr[1]=0; /* only one address*/
  703. p_addr[0]=address;
  704. strncpy(hostname, name->s, (name->len<256)?(name->len)+1:256);
  705. if (ip->len>16) return 0;
  706. memcpy(address, ip->u.addr, ip->len);
  707. he.h_addrtype=ip->af;
  708. he.h_length=ip->len;
  709. he.h_addr_list=p_addr;
  710. he.h_aliases=p_aliases;
  711. he.h_name=hostname;
  712. return &he;
  713. }
  714. /* init a dest_info structure */
  715. #define init_dest_info(dst) \
  716. do{ \
  717. memset((dst), 0, sizeof(struct dest_info)); \
  718. } while(0)
  719. /* init a dest_info structure from a recv_info structure */
  720. inline static void init_dst_from_rcv(struct dest_info* dst,
  721. struct receive_info* rcv)
  722. {
  723. dst->send_sock=rcv->bind_address;
  724. dst->to=rcv->src_su;
  725. dst->id=rcv->proto_reserved1;
  726. dst->proto=rcv->proto;
  727. dst->send_flags.f=0;
  728. dst->send_flags.blst_imask=0;
  729. #ifdef USE_COMP
  730. dst->comp=rcv->comp;
  731. #endif
  732. }
  733. /**
  734. * match ip address with net address and bitmask
  735. * - return 0 on match, -1 otherwise
  736. */
  737. int ip_addr_match_net(ip_addr_t *iaddr, ip_addr_t *naddr, int mask);
  738. int si_get_signaling_data(struct socket_info *si, str **addr, str **port);
  739. #endif