ip_addr.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /* $Id$
  2. *
  3. * ip address family realted 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. #ifndef ip_addr_h
  29. #define ip_addr_h
  30. #include <string.h>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <netinet/in.h>
  34. #include <netdb.h>
  35. #include "str.h"
  36. #include "dprint.h"
  37. enum sip_protos { PROTO_UDP, PROTO_TCP, PROTO_TLS };
  38. struct ip_addr{
  39. unsigned int af; /* address family: AF_INET6 or AF_INET */
  40. unsigned int len; /* address len, 16 or 4 */
  41. /* 64 bits alligned address */
  42. union {
  43. unsigned int addr32[4];
  44. unsigned short addr16[8];
  45. unsigned char addr[16];
  46. }u;
  47. };
  48. struct net{
  49. struct ip_addr ip;
  50. struct ip_addr mask;
  51. };
  52. union sockaddr_union{
  53. struct sockaddr s;
  54. struct sockaddr_in sin;
  55. #ifdef USE_IPV6
  56. struct sockaddr_in6 sin6;
  57. #endif
  58. };
  59. struct socket_info{
  60. int socket;
  61. str name; /* name - eg.: foo.bar or 10.0.0.1 */
  62. struct ip_addr address; /* ip address */
  63. str address_str; /* ip address converted to string -- optimization*/
  64. unsigned short port_no; /* port number */
  65. str port_no_str; /* port number converted to string -- optimization*/
  66. int is_ip; /* 1 if name is an ip address, 0 if not -- optimization*/
  67. int is_lo; /* 1 if is a loopback, 0 if not */
  68. union sockaddr_union su;
  69. int proto; /* tcp or udp*/
  70. };
  71. struct receive_info{
  72. struct ip_addr src_ip;
  73. struct ip_addr dst_ip;
  74. short src_port;
  75. short dst_port;
  76. int proto;
  77. int proto_reserved1;
  78. int proto_reserved2;
  79. union sockaddr_union src_su; /* usefull for replies*/
  80. struct socket_info* bind_address; /* sock_info structure on which
  81. the msg was received*/
  82. /* no need for dst_su yet */
  83. };
  84. /* len of the sockaddr */
  85. #ifdef HAVE_SOCKADDR_SA_LEN
  86. #define sockaddru_len(su) ((su).s.sa_len)
  87. #else
  88. #ifdef USE_IPV6
  89. #define sockaddru_len(su) \
  90. (((su).s.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):\
  91. sizeof(struct sockaddr_in))
  92. #else
  93. #define sockaddru_len(su) sizeof(struct sockaddr_in)
  94. #endif /*USE_IPV6*/
  95. #endif /* HAVE_SOCKADDR_SA_LEN*/
  96. /* inits an ip_addr with the addr. info from a hostent structure
  97. * ip = struct ip_addr*
  98. * he= struct hostent*
  99. */
  100. #define hostent2ip_addr(ip, he, addr_no) \
  101. do{ \
  102. (ip)->af=(he)->h_addrtype; \
  103. (ip)->len=(he)->h_length; \
  104. memcpy((ip)->u.addr, (he)->h_addr_list[(addr_no)], (ip)->len); \
  105. }while(0)
  106. /* gets the protocol family corresponding to a specific address family
  107. * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
  108. */
  109. #ifdef USE_IPV6
  110. #define AF2PF(af) (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
  111. #else
  112. #define AF2PF(af) (((af)==AF_INET)?PF_INET:(af))
  113. #endif
  114. struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
  115. struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
  116. void print_ip(struct ip_addr* ip);
  117. void stdout_print_ip(struct ip_addr* ip);
  118. void print_net(struct net* net);
  119. /* returns 1 if ip & net.mask == net.ip ; 0 otherwise & -1 on error
  120. [ diff. adress fams ]) */
  121. inline static int matchnet(struct ip_addr* ip, struct net* net)
  122. {
  123. unsigned int r;
  124. int ret;
  125. ret=-1;
  126. if (ip->af == net->ip.af){
  127. for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
  128. all multiple of 4*/
  129. if ((ip->u.addr32[r]&net->mask.u.addr32[r])!=
  130. net->ip.u.addr32[r]){
  131. return 0;
  132. }
  133. }
  134. return 1;
  135. };
  136. return -1;
  137. }
  138. /* inits an ip_addr pointer from a sockaddr structure*/
  139. static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
  140. {
  141. switch(sa->sa_family){
  142. case AF_INET:
  143. ip->af=AF_INET;
  144. ip->len=4;
  145. memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
  146. break;
  147. #ifdef USE_IPV6
  148. case AF_INET6:
  149. ip->af=AF_INET6;
  150. ip->len=16;
  151. memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
  152. break;
  153. #endif
  154. default:
  155. LOG(L_CRIT, "sockaddr2ip_addr: BUG: unknown address family %d\n",
  156. sa->sa_family);
  157. }
  158. }
  159. /* compare 2 ip_addrs (both args are pointers)*/
  160. #define ip_addr_cmp(ip1, ip2) \
  161. (((ip1)->af==(ip2)->af)&& \
  162. (memcmp((ip1)->u.addr, (ip2)->u.addr, (ip1)->len)==0))
  163. /* compare 2 sockaddr_unions */
  164. static inline int su_cmp(union sockaddr_union* s1, union sockaddr_union* s2)
  165. {
  166. if (s1->s.sa_family!=s2->s.sa_family) return 0;
  167. switch(s1->s.sa_family){
  168. case AF_INET:
  169. return (s1->sin.sin_port==s2->sin.sin_port)&&
  170. (memcmp(&s1->sin.sin_addr, &s2->sin.sin_addr, 4)==0);
  171. #ifdef USE_IPV6
  172. case AF_INET6:
  173. return (s1->sin6.sin6_port==s2->sin6.sin6_port)&&
  174. (memcmp(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr, 16)==0);
  175. #endif
  176. default:
  177. LOG(L_CRIT,"su_cmp: BUG: unknown address family %d\n",
  178. s1->s.sa_family);
  179. return 0;
  180. }
  181. }
  182. /* gets the port number */
  183. static inline short su_getport(union sockaddr_union* su)
  184. {
  185. switch(su->s.sa_family){
  186. case AF_INET:
  187. return su->sin.sin_port;
  188. #ifdef USE_IPV6
  189. case AF_INET6:
  190. return su->sin6.sin6_port;
  191. #endif
  192. default:
  193. LOG(L_CRIT,"su_get_port: BUG: unknown address family %d\n",
  194. su->s.sa_family);
  195. return 0;
  196. }
  197. }
  198. /* inits an ip_addr pointer from a sockaddr_union ip address */
  199. static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
  200. {
  201. switch(su->s.sa_family){
  202. case AF_INET:
  203. ip->af=AF_INET;
  204. ip->len=4;
  205. memcpy(ip->u.addr, &su->sin.sin_addr, 4);
  206. break;
  207. #ifdef USE_IPV6
  208. case AF_INET6:
  209. ip->af=AF_INET6;
  210. ip->len=16;
  211. memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
  212. break;
  213. #endif
  214. default:
  215. LOG(L_CRIT,"su2ip_addr: BUG: unknown address family %d\n",
  216. su->s.sa_family);
  217. }
  218. }
  219. /* ip_addr2su -> the same as init_su*/
  220. #define ip_addr2su init_su
  221. /* inits a struct sockaddr_union from a struct ip_addr and a port no
  222. * returns 0 if ok, -1 on error (unknown address family) */
  223. static inline int init_su( union sockaddr_union* su,
  224. struct ip_addr* ip,
  225. unsigned short port )
  226. {
  227. memset(su, 0, sizeof(union sockaddr_union));/*needed on freebsd*/
  228. su->s.sa_family=ip->af;
  229. switch(ip->af){
  230. #ifdef USE_IPV6
  231. case AF_INET6:
  232. memcpy(&su->sin6.sin6_addr, ip->u.addr, ip->len);
  233. #ifdef HAVE_SOCKADDR_SA_LEN
  234. su->sin6.sin6_len=sizeof(struct sockaddr_in6);
  235. #endif
  236. su->sin6.sin6_port=port;
  237. break;
  238. #endif
  239. case AF_INET:
  240. memcpy(&su->sin.sin_addr, ip->u.addr, ip->len);
  241. #ifdef HAVE_SOCKADDR_SA_LEN
  242. su->sin.sin_len=sizeof(struct sockaddr_in);
  243. #endif
  244. su->sin.sin_port=port;
  245. break;
  246. default:
  247. LOG(L_CRIT, "init_ss: BUG: unknown address family %d\n", ip->af);
  248. return -1;
  249. }
  250. return 0;
  251. }
  252. /* inits a struct sockaddr_union from a struct hostent, an address index in
  253. * the hostent structure and a port no.
  254. * WARNING: no index overflow checks!
  255. * returns 0 if ok, -1 on error (unknown address family) */
  256. static inline int hostent2su( union sockaddr_union* su,
  257. struct hostent* he,
  258. unsigned int idx,
  259. unsigned short port )
  260. {
  261. memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
  262. su->s.sa_family=he->h_addrtype;
  263. switch(he->h_addrtype){
  264. #ifdef USE_IPV6
  265. case AF_INET6:
  266. memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
  267. #ifdef HAVE_SOCKADDR_SA_LEN
  268. su->sin6.sin6_len=sizeof(struct sockaddr_in6);
  269. #endif
  270. su->sin6.sin6_port=port;
  271. break;
  272. #endif
  273. case AF_INET:
  274. memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
  275. #ifdef HAVE_SOCKADDR_SA_LEN
  276. su->sin.sin_len=sizeof(struct sockaddr_in);
  277. #endif
  278. su->sin.sin_port=port;
  279. break;
  280. default:
  281. LOG(L_CRIT, "hostent2su: BUG: unknown address family %d\n",
  282. he->h_addrtype);
  283. return -1;
  284. }
  285. return 0;
  286. }
  287. /* fast ip_addr -> string convertor;
  288. * it uses an internal buffer
  289. */
  290. static inline char* ip_addr2a(struct ip_addr* ip)
  291. {
  292. static char buff[40];/* 1234:5678:9012:3456:7890:1234:5678:9012\0 */
  293. int offset;
  294. register unsigned char a,b,c;
  295. #ifdef USE_IPV6
  296. register unsigned char d;
  297. register unsigned short hex4;
  298. #endif
  299. int r;
  300. #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
  301. offset=0;
  302. switch(ip->af){
  303. #ifdef USE_IPV6
  304. case AF_INET6:
  305. for(r=0;r<7;r++){
  306. hex4=ntohs(ip->u.addr16[r]);
  307. a=hex4>>12;
  308. b=(hex4>>8)&0xf;
  309. c=(hex4>>4)&0xf;
  310. d=hex4&0xf;
  311. if (a){
  312. buff[offset]=HEXDIG(a);
  313. buff[offset+1]=HEXDIG(b);
  314. buff[offset+2]=HEXDIG(c);
  315. buff[offset+3]=HEXDIG(d);
  316. buff[offset+4]=':';
  317. offset+=5;
  318. }else if(b){
  319. buff[offset]=HEXDIG(b);
  320. buff[offset+1]=HEXDIG(c);
  321. buff[offset+2]=HEXDIG(d);
  322. buff[offset+3]=':';
  323. offset+=4;
  324. }else if(c){
  325. buff[offset]=HEXDIG(c);
  326. buff[offset+1]=HEXDIG(d);
  327. buff[offset+2]=':';
  328. offset+=3;
  329. }else{
  330. buff[offset]=HEXDIG(d);
  331. buff[offset+1]=':';
  332. offset+=2;
  333. }
  334. }
  335. /* last int16*/
  336. hex4=ntohs(ip->u.addr16[r]);
  337. a=hex4>>12;
  338. b=(hex4>>8)&0xf;
  339. c=(hex4>>4)&0xf;
  340. d=hex4&0xf;
  341. if (a){
  342. buff[offset]=HEXDIG(a);
  343. buff[offset+1]=HEXDIG(b);
  344. buff[offset+2]=HEXDIG(c);
  345. buff[offset+3]=HEXDIG(d);
  346. buff[offset+4]=0;
  347. }else if(b){
  348. buff[offset]=HEXDIG(b);
  349. buff[offset+1]=HEXDIG(c);
  350. buff[offset+2]=HEXDIG(d);
  351. buff[offset+3]=0;
  352. }else if(c){
  353. buff[offset]=HEXDIG(c);
  354. buff[offset+1]=HEXDIG(d);
  355. buff[offset+2]=0;
  356. }else{
  357. buff[offset]=HEXDIG(d);
  358. buff[offset+1]=0;
  359. }
  360. break;
  361. #endif
  362. case AF_INET:
  363. for(r=0;r<3;r++){
  364. a=ip->u.addr[r]/100;
  365. c=ip->u.addr[r]%10;
  366. b=ip->u.addr[r]%100/10;
  367. if (a){
  368. buff[offset]=a+'0';
  369. buff[offset+1]=b+'0';
  370. buff[offset+2]=c+'0';
  371. buff[offset+3]='.';
  372. offset+=4;
  373. }else if (b){
  374. buff[offset]=b+'0';
  375. buff[offset+1]=c+'0';
  376. buff[offset+2]='.';
  377. offset+=3;
  378. }else{
  379. buff[offset]=c+'0';
  380. buff[offset+1]='.';
  381. offset+=2;
  382. }
  383. }
  384. /* last number */
  385. a=ip->u.addr[r]/100;
  386. c=ip->u.addr[r]%10;
  387. b=ip->u.addr[r]%100/10;
  388. if (a){
  389. buff[offset]=a+'0';
  390. buff[offset+1]=b+'0';
  391. buff[offset+2]=c+'0';
  392. buff[offset+3]=0;
  393. }else if (b){
  394. buff[offset]=b+'0';
  395. buff[offset+1]=c+'0';
  396. buff[offset+2]=0;
  397. }else{
  398. buff[offset]=c+'0';
  399. buff[offset+1]=0;
  400. }
  401. break;
  402. default:
  403. LOG(L_CRIT, "BUG: ip_addr2a: unknown address family %d\n",
  404. ip->af);
  405. return 0;
  406. }
  407. return buff;
  408. }
  409. /* converts an ip_addr structure to a hostent, returns pointer to internal
  410. * statical structure */
  411. static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
  412. {
  413. static struct hostent he;
  414. static char hostname[256];
  415. static char* p_aliases[1];
  416. static char* p_addr[2];
  417. static char address[16];
  418. p_aliases[0]=0; /* no aliases*/
  419. p_addr[1]=0; /* only one address*/
  420. p_addr[0]=address;
  421. strncpy(hostname, name->s, (name->len<256)?(name->len)+1:256);
  422. if (ip->len>16) return 0;
  423. memcpy(address, ip->u.addr, ip->len);
  424. he.h_addrtype=ip->af;
  425. he.h_length=ip->len;
  426. he.h_addr_list=p_addr;
  427. he.h_aliases=p_aliases;
  428. he.h_name=hostname;
  429. return &he;
  430. }
  431. #endif