PageRenderTime 31ms CodeModel.GetById 40ms RepoModel.GetById 0ms app.codeStats 1ms

/source/libpfk/libpfk.cpp

https://gitlab.com/mvives/ike
C++ | 1848 lines | 1228 code | 454 blank | 166 comment | 212 complexity | bef65096ad30a8d28fd577a91cda0eaf MD5 | raw file
  1. /*
  2. * Copyright (c) 2007
  3. * Shrew Soft Inc. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Redistributions in any form must be accompanied by information on
  14. * how to obtain complete source code for the software and any
  15. * accompanying software that uses the software. The source code
  16. * must either be included in the distribution or be available for no
  17. * more than the cost of distribution plus a nominal fee, and must be
  18. * freely redistributable under reasonable conditions. For an
  19. * executable file, complete source code means the source code for all
  20. * modules it contains. It does not include source code for modules or
  21. * files that typically accompany the major components of the operating
  22. * system on which the executable file runs.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY SHREW SOFT INC ``AS IS'' AND ANY EXPRESS
  25. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
  27. * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SHREW SOFT INC
  28. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  34. * THE POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. * AUTHOR : Matthew Grooms
  37. * mgrooms@shrew.net
  38. *
  39. */
  40. #include "libpfk.h"
  41. //==============================================================================
  42. // message class
  43. //==============================================================================
  44. bool _PFKI_MSG::local()
  45. {
  46. return ( ( long ) header.sadb_msg_pid == getpid() );
  47. return false;
  48. }
  49. //==============================================================================
  50. // client interface class
  51. //==============================================================================
  52. #ifdef UNIX
  53. long _PFKI::send_message( PFKI_MSG & msg )
  54. {
  55. if( conn == -1 )
  56. return IPCERR_CLOSED;
  57. size_t msg_size = msg.size() + sizeof( sadb_msg );
  58. msg.header.sadb_msg_len = ( u_int16_t ) PFKEY_UNIT64( msg_size );
  59. msg.ins( &msg.header, sizeof( msg.header ) );
  60. msg.size( msg_size );
  61. return io_send( msg.buff(), msg_size );
  62. }
  63. long _PFKI::recv_message( PFKI_MSG & msg )
  64. {
  65. if( conn == -1 )
  66. return IPCERR_CLOSED;
  67. fd_set fds;
  68. FD_ZERO( &fds );
  69. FD_SET( conn, &fds );
  70. FD_SET( conn_wake[ 0 ], &fds );
  71. int max = conn_wake[ 0 ];
  72. if( max < conn )
  73. max = conn;
  74. if( select( max + 1, &fds, NULL, NULL, NULL ) <= 0 )
  75. return IPCERR_FAILED;
  76. if( FD_ISSET( conn, &fds ) )
  77. {
  78. msg.size( sizeof( sadb_msg ) );
  79. size_t msg_size = msg.size();
  80. long result = recv( conn, msg.buff(), msg_size, MSG_PEEK );
  81. if( result < 0 )
  82. return IPCERR_FAILED;
  83. if( result == 0 )
  84. return IPCERR_CLOSED;
  85. msg.size( result );
  86. msg.oset( 0 );
  87. if( !msg.get( &msg.header, sizeof( sadb_msg ) ) )
  88. return IPCERR_FAILED;
  89. msg_size = PFKEY_UNUNIT64( msg.header.sadb_msg_len );
  90. msg.size( msg_size );
  91. return io_recv( msg.buff(), msg_size );
  92. }
  93. if( FD_ISSET( conn_wake[ 0 ], &fds ) )
  94. {
  95. char c;
  96. recv( conn_wake[ 0 ], &c, 1, 0 );
  97. return IPCERR_WAKEUP;
  98. }
  99. return IPCERR_NODATA;
  100. }
  101. long _PFKI::attach( long timeout )
  102. {
  103. detach();
  104. //
  105. // open our pfkey socket
  106. //
  107. conn = socket( PF_KEY, SOCK_RAW, PF_KEY_V2 );
  108. if( conn < 0 )
  109. return IPCERR_FAILED;
  110. //
  111. // set socket buffer size
  112. //
  113. const int buffsize = PFKEY_BUFFSIZE;
  114. setsockopt( conn, SOL_SOCKET, SO_SNDBUF, &buffsize, sizeof( buffsize ) );
  115. setsockopt( conn, SOL_SOCKET, SO_RCVBUF, &buffsize, sizeof( buffsize ) );
  116. //
  117. // set socket to non-blocking
  118. //
  119. if( fcntl( conn, F_SETFL, O_NONBLOCK ) == -1 )
  120. return IPCERR_FAILED;
  121. return IPCERR_OK;
  122. }
  123. void _PFKI::wakeup()
  124. {
  125. ITH_IPCC::wakeup();
  126. }
  127. void _PFKI::detach()
  128. {
  129. if( conn != -1 )
  130. close( conn );
  131. }
  132. #endif
  133. //
  134. // PFKI WIN32 Specific
  135. //
  136. #ifdef WIN32
  137. long _PFKI::send_message( PFKI_MSG & msg )
  138. {
  139. size_t msg_size = msg.size() + sizeof( sadb_msg );
  140. msg.header.sadb_msg_len = ( u_int16_t ) PFKEY_UNIT64( msg_size );
  141. msg.ins( &msg.header, sizeof( msg.header ) );
  142. msg.size( msg_size );
  143. return io_send( msg.buff(), msg_size );
  144. }
  145. long _PFKI::recv_message( PFKI_MSG & msg )
  146. {
  147. msg.size( sizeof( sadb_msg ) );
  148. size_t msg_read = msg.size();
  149. size_t msg_size = 0;
  150. long result = io_recv( msg.buff(), msg_read );
  151. if( ( result == IPCERR_OK ) || ( result == IPCERR_BUFFER ) )
  152. {
  153. msg.oset( 0 );
  154. if( !msg.get( &msg.header, sizeof( sadb_msg ) ) )
  155. return IPCERR_FAILED;
  156. msg_size = PFKEY_UNUNIT64( msg.header.sadb_msg_len );
  157. msg.size( msg_size );
  158. result = io_recv( msg.buff() + msg_read, msg_size - msg_read );
  159. }
  160. return result;
  161. }
  162. long _PFKI::attach( long timeout )
  163. {
  164. return ITH_IPCC::attach( PFKI_PIPE_NAME, timeout );
  165. }
  166. void _PFKI::wakeup()
  167. {
  168. ITH_IPCC::wakeup();
  169. }
  170. void _PFKI::detach()
  171. {
  172. ITH_IPCC::detach();
  173. }
  174. #endif
  175. const char * _PFKI::name( long type, long value )
  176. {
  177. static const char * unknown = "unknown";
  178. switch( type )
  179. {
  180. case NAME_MSGTYPE:
  181. {
  182. static const char * msgtype_00 = "RESERVED";
  183. static const char * msgtype_01 = "GETSPI";
  184. static const char * msgtype_02 = "UPDATE";
  185. static const char * msgtype_03 = "ADD";
  186. static const char * msgtype_04 = "DELETE";
  187. static const char * msgtype_05 = "GET";
  188. static const char * msgtype_06 = "ACQUIRE";
  189. static const char * msgtype_07 = "REGISTER";
  190. static const char * msgtype_08 = "EXPIRE";
  191. static const char * msgtype_09 = "FLUSH";
  192. static const char * msgtype_10 = "DUMP";
  193. static const char * msgtype_11 = "X_PROMISC";
  194. static const char * msgtype_12 = "X_PCHANGE";
  195. static const char * msgtype_13 = "X_SPDUPDATE";
  196. static const char * msgtype_14 = "X_SPDADD";
  197. static const char * msgtype_15 = "X_SPDDELETE";
  198. static const char * msgtype_16 = "X_SPDGET";
  199. static const char * msgtype_17 = "X_SPDACQUIRE";
  200. static const char * msgtype_18 = "X_SPDDUMP";
  201. static const char * msgtype_19 = "X_SPDFLUSH";
  202. static const char * msgtype_20 = "X_SPDSETIDX";
  203. static const char * msgtype_21 = "X_SPDEXPIRE";
  204. static const char * msgtype_22 = "X_SPDDELETE2";
  205. // static const char * msgtype_23 = "X_NAT_T_NEW_MAPPING";
  206. switch( value )
  207. {
  208. case SADB_RESERVED:
  209. return msgtype_00;
  210. case SADB_GETSPI:
  211. return msgtype_01;
  212. case SADB_UPDATE:
  213. return msgtype_02;
  214. case SADB_ADD:
  215. return msgtype_03;
  216. case SADB_DELETE:
  217. return msgtype_04;
  218. case SADB_GET:
  219. return msgtype_05;
  220. case SADB_ACQUIRE:
  221. return msgtype_06;
  222. case SADB_REGISTER:
  223. return msgtype_07;
  224. case SADB_EXPIRE:
  225. return msgtype_08;
  226. case SADB_FLUSH:
  227. return msgtype_09;
  228. case SADB_DUMP:
  229. return msgtype_10;
  230. case SADB_X_PROMISC:
  231. return msgtype_11;
  232. case SADB_X_PCHANGE:
  233. return msgtype_12;
  234. case SADB_X_SPDUPDATE:
  235. return msgtype_13;
  236. case SADB_X_SPDADD:
  237. return msgtype_14;
  238. case SADB_X_SPDDELETE:
  239. return msgtype_15;
  240. case SADB_X_SPDGET:
  241. return msgtype_16;
  242. case SADB_X_SPDACQUIRE:
  243. return msgtype_17;
  244. case SADB_X_SPDDUMP:
  245. return msgtype_18;
  246. case SADB_X_SPDFLUSH:
  247. return msgtype_19;
  248. case SADB_X_SPDSETIDX:
  249. return msgtype_20;
  250. case SADB_X_SPDEXPIRE:
  251. return msgtype_21;
  252. case SADB_X_SPDDELETE2:
  253. return msgtype_22;
  254. // case SADB_X_NAT_T_NEW_MAPPING:
  255. // return msgtype_23;
  256. default:
  257. return unknown;
  258. }
  259. }
  260. case NAME_SAENCR:
  261. {
  262. static const char * encrtype_02 = "DES-CBC";
  263. static const char * encrtype_03 = "3DES-CBC";
  264. static const char * encrtype_06 = "CAST128-CBC";
  265. static const char * encrtype_07 = "BLOWFISH-CBC";
  266. static const char * encrtype_12 = "AES-CBC";
  267. switch( value )
  268. {
  269. case SADB_EALG_DESCBC:
  270. return encrtype_02;
  271. case SADB_EALG_3DESCBC:
  272. return encrtype_03;
  273. case SADB_X_EALG_CAST128CBC:
  274. return encrtype_06;
  275. case SADB_X_EALG_BLOWFISHCBC:
  276. return encrtype_07;
  277. case SADB_X_EALG_AESCBC:
  278. return encrtype_12;
  279. default:
  280. return unknown;
  281. }
  282. }
  283. case NAME_SACOMP:
  284. {
  285. static const char * comptype_01 = "OUI";
  286. static const char * comptype_02 = "DEFLATE";
  287. static const char * comptype_03 = "LZS";
  288. switch( value )
  289. {
  290. case SADB_X_CALG_OUI:
  291. return comptype_01;
  292. case SADB_X_CALG_DEFLATE:
  293. return comptype_02;
  294. case SADB_X_CALG_LZS:
  295. return comptype_03;
  296. default:
  297. return unknown;
  298. }
  299. }
  300. case NAME_SAAUTH:
  301. {
  302. static const char * authtype_02 = "HMAC-MD5";
  303. static const char * authtype_03 = "HMAC-SHA1";
  304. static const char * authtype_04 = "HMAC-SHA2-256";
  305. static const char * authtype_05 = "HMAC-SHA2-384";
  306. static const char * authtype_06 = "HMAC-SHA2-512";
  307. switch( value )
  308. {
  309. case SADB_AALG_MD5HMAC:
  310. return authtype_02;
  311. case SADB_AALG_SHA1HMAC:
  312. return authtype_03;
  313. case SADB_X_AALG_SHA2_256HMAC:
  314. return authtype_04;
  315. case SADB_X_AALG_SHA2_384HMAC:
  316. return authtype_05;
  317. case SADB_X_AALG_SHA2_512HMAC:
  318. return authtype_06;
  319. default:
  320. return unknown;
  321. }
  322. }
  323. case NAME_SATYPE:
  324. {
  325. static const char * satype_00 = "UNSPEC";
  326. static const char * satype_02 = "AH";
  327. static const char * satype_03 = "ESP";
  328. static const char * satype_05 = "RSVP";
  329. static const char * satype_06 = "OSPFV2";
  330. static const char * satype_07 = "RIPV2";
  331. static const char * satype_08 = "MIP";
  332. static const char * satype_09 = "IPCOMP";
  333. static const char * satype_11 = "TCPSIGNATURE";
  334. switch( value )
  335. {
  336. case SADB_SATYPE_UNSPEC:
  337. return satype_00;
  338. case SADB_SATYPE_AH:
  339. return satype_02;
  340. case SADB_SATYPE_ESP:
  341. return satype_03;
  342. case SADB_SATYPE_RSVP:
  343. return satype_05;
  344. case SADB_SATYPE_OSPFV2:
  345. return satype_06;
  346. case SADB_SATYPE_RIPV2:
  347. return satype_07;
  348. case SADB_SATYPE_MIP:
  349. return satype_08;
  350. case SADB_X_SATYPE_IPCOMP:
  351. return satype_09;
  352. // case SADB_X_SATYPE_TCPSIGNATURE:
  353. // return satype_11;
  354. default:
  355. return unknown;
  356. }
  357. }
  358. case NAME_SPMODE:
  359. {
  360. static const char * plcymode_00 = "ANY";
  361. static const char * plcymode_01 = "TANSPORT";
  362. static const char * plcymode_02 = "TUNNEL";
  363. switch( value )
  364. {
  365. case IPSEC_MODE_ANY:
  366. return plcymode_00;
  367. case IPSEC_MODE_TRANSPORT:
  368. return plcymode_01;
  369. case IPSEC_MODE_TUNNEL:
  370. return plcymode_02;
  371. default:
  372. return unknown;
  373. }
  374. }
  375. case NAME_SPTYPE:
  376. {
  377. static const char * plcytype_00 = "DISCARD";
  378. static const char * plcytype_01 = "NONE";
  379. static const char * plcytype_02 = "IPSEC";
  380. static const char * plcytype_03 = "ENTRUST";
  381. static const char * plcytype_04 = "BYPASS";
  382. switch( value )
  383. {
  384. case IPSEC_POLICY_DISCARD:
  385. return plcytype_00;
  386. case IPSEC_POLICY_NONE:
  387. return plcytype_01;
  388. case IPSEC_POLICY_IPSEC:
  389. return plcytype_02;
  390. case IPSEC_POLICY_ENTRUST:
  391. return plcytype_03;
  392. case IPSEC_POLICY_BYPASS:
  393. return plcytype_04;
  394. default:
  395. return unknown;
  396. }
  397. }
  398. case NAME_SPDIR:
  399. {
  400. static const char * plcydir_00 = "ANY";
  401. static const char * plcydir_01 = "INBOUND";
  402. static const char * plcydir_02 = "OUTBOUND";
  403. static const char * plcydir_03 = "MAX";
  404. static const char * plcydir_04 = "INVALID";
  405. switch( value )
  406. {
  407. case IPSEC_DIR_ANY:
  408. return plcydir_00;
  409. case IPSEC_DIR_INBOUND:
  410. return plcydir_01;
  411. case IPSEC_DIR_OUTBOUND:
  412. return plcydir_02;
  413. case IPSEC_DIR_MAX:
  414. return plcydir_03;
  415. case IPSEC_DIR_INVALID:
  416. return plcydir_04;
  417. default:
  418. return unknown;
  419. }
  420. }
  421. case NAME_SPLEVEL:
  422. {
  423. static const char * plcylevel_00 = "ANY";
  424. static const char * plcylevel_01 = "USE";
  425. static const char * plcylevel_02 = "REQUIRE";
  426. static const char * plcylevel_03 = "UNIQUE";
  427. switch( value )
  428. {
  429. case IPSEC_LEVEL_DEFAULT:
  430. return plcylevel_00;
  431. case IPSEC_LEVEL_USE:
  432. return plcylevel_01;
  433. case IPSEC_LEVEL_REQUIRE:
  434. return plcylevel_02;
  435. case IPSEC_LEVEL_UNIQUE:
  436. return plcylevel_03;
  437. default:
  438. return unknown;
  439. }
  440. }
  441. case NAME_NTTYPE:
  442. {
  443. static const char * nattype_00 = "NONE";
  444. static const char * nattype_01 = "ESPINUDP-NON-IKE";
  445. static const char * nattype_02 = "ESPINUDP";
  446. switch( value )
  447. {
  448. case 0:
  449. return nattype_00;
  450. #ifdef OPT_NATT
  451. case UDP_ENCAP_ESPINUDP_NON_IKE:
  452. return nattype_01;
  453. case UDP_ENCAP_ESPINUDP:
  454. return nattype_02;
  455. #endif
  456. default:
  457. return unknown;
  458. }
  459. }
  460. }
  461. return unknown;
  462. }
  463. //==============================================================================
  464. // buffer management functions
  465. //==============================================================================
  466. bool _PFKI::sockaddr_len( int safam, int & salen )
  467. {
  468. switch( safam )
  469. {
  470. case AF_INET:
  471. salen = sizeof( sockaddr_in );
  472. return true;
  473. }
  474. printf( "XX : address family %i unhandled\n", safam );
  475. return false;
  476. }
  477. long _PFKI::buff_get_ext( PFKI_MSG & msg, sadb_ext ** ext, long type )
  478. {
  479. unsigned char * buff = msg.buff();
  480. size_t size = msg.size();
  481. buff += sizeof( sadb_msg );
  482. size -= sizeof( sadb_msg );
  483. while( 1 )
  484. {
  485. //
  486. // make sure the buffer holds
  487. // enough data to contain an
  488. // extension header
  489. //
  490. if( long( sizeof( sadb_ext ) ) > size )
  491. {
  492. printf( "XX : extension not found\n" );
  493. return IPCERR_FAILED;
  494. }
  495. sadb_ext * ext_head = ( sadb_ext * ) buff;
  496. //
  497. // make sure the buffer holds
  498. // enough data to contain the
  499. // extension body
  500. //
  501. if( PFKEY_EXTLEN( ext_head ) > size )
  502. {
  503. printf( "XX : buffer too small for ext body ( %i bytes )\n",
  504. PFKEY_EXTLEN( ext_head ) );
  505. return IPCERR_FAILED;
  506. }
  507. //
  508. // stop evaluation if this is
  509. // the requested extension
  510. //
  511. if( ext_head->sadb_ext_type == type )
  512. {
  513. //
  514. // sainfo the pointers and size
  515. //
  516. *ext = ( sadb_ext * ) buff;
  517. break;
  518. }
  519. //
  520. // move to next extension
  521. //
  522. buff += PFKEY_EXTLEN( ext_head );
  523. size -= PFKEY_EXTLEN( ext_head );
  524. }
  525. return IPCERR_OK;
  526. }
  527. long _PFKI::buff_add_ext( PFKI_MSG & msg, sadb_ext ** ext, long xlen, bool unit64 )
  528. {
  529. size_t oset = msg.size();
  530. xlen = PFKEY_ALIGN8( xlen );
  531. msg.add( 0, xlen );
  532. *ext = ( sadb_ext * )( msg.buff() + oset );
  533. if( unit64 )
  534. ( *ext )->sadb_ext_len = ( u_int16_t ) PFKEY_UNIT64( xlen );
  535. else
  536. ( *ext )->sadb_ext_len = ( u_int16_t ) xlen;
  537. return IPCERR_OK;
  538. }
  539. long _PFKI::buff_get_address( sadb_address * ext, PFKI_ADDR & addr )
  540. {
  541. unsigned char * buff = ( unsigned char * ) ext;
  542. int size = PFKEY_UNUNIT64( ext->sadb_address_len );
  543. addr.proto = ext->sadb_address_proto;
  544. addr.prefix = ext->sadb_address_prefixlen;
  545. buff += sizeof( sadb_address );
  546. size -= sizeof( sadb_address );
  547. sockaddr * saddr = ( sockaddr * ) buff;
  548. int salen;
  549. if( !sockaddr_len( saddr->sa_family, salen ) )
  550. return IPCERR_FAILED;
  551. if( size < salen )
  552. {
  553. printf( "!! : pfkey address size mismatch\n" );
  554. return IPCERR_FAILED;
  555. }
  556. memcpy( &addr.saddr, saddr, salen );
  557. return IPCERR_OK;
  558. }
  559. long _PFKI::buff_set_address( sadb_address * ext, PFKI_ADDR & addr )
  560. {
  561. unsigned char * buff = ( unsigned char * ) ext;
  562. int size = PFKEY_UNUNIT64( ext->sadb_address_len );
  563. ext->sadb_address_proto = addr.proto;
  564. ext->sadb_address_prefixlen = addr.prefix;
  565. buff += sizeof( sadb_address );
  566. size -= sizeof( sadb_address );
  567. int salen;
  568. if( !sockaddr_len( addr.saddr.sa_family, salen ) )
  569. return IPCERR_FAILED;
  570. if( size < salen )
  571. {
  572. printf( "!! : pfkey address size mismatch\n" );
  573. return IPCERR_FAILED;
  574. }
  575. memcpy( buff, &addr.saddr, salen );
  576. return IPCERR_OK;
  577. }
  578. long _PFKI::buff_set_key( sadb_key * ext, PFKI_KEY & key )
  579. {
  580. unsigned char * buff = ( unsigned char * ) ext;
  581. int size = PFKEY_UNUNIT64( ext->sadb_key_len );
  582. ext->sadb_key_bits = key.length * 8;
  583. buff += sizeof( sadb_key );
  584. size -= sizeof( sadb_key );
  585. if( size < key.length )
  586. {
  587. printf( "!! : pfkey key size mismatch ( %i < %i )\n", size, key.length );
  588. return IPCERR_FAILED;
  589. }
  590. assert( PFKI_MAX_KEYLEN >= key.length );
  591. memcpy( buff, key.keydata, key.length );
  592. return IPCERR_OK;
  593. }
  594. long _PFKI::buff_get_key( sadb_key * ext, PFKI_KEY & key )
  595. {
  596. unsigned char * buff = ( unsigned char * ) ext;
  597. int size = PFKEY_UNUNIT64( ext->sadb_key_len );
  598. buff += sizeof( sadb_key );
  599. size -= sizeof( sadb_key );
  600. if( !ext->sadb_key_bits )
  601. return IPCERR_FAILED;
  602. key.length = ext->sadb_key_bits / 8;
  603. if( size < key.length )
  604. {
  605. printf( "!! : pfkey key size mismatch ( %i < %i )\n", size, key.length );
  606. return IPCERR_FAILED;
  607. }
  608. memcpy( key.keydata, buff, key.length );
  609. return IPCERR_OK;
  610. }
  611. long _PFKI::buff_get_ipsec( sadb_x_policy * ext, PFKI_SPINFO & spinfo )
  612. {
  613. unsigned char * buff = ( unsigned char * ) ext;
  614. int size = PFKEY_UNUNIT64( ext->sadb_x_policy_len );
  615. buff += sizeof( sadb_x_policy );
  616. size -= sizeof( sadb_x_policy );
  617. long xindex = 0;
  618. while( size >= long( sizeof( sadb_x_ipsecrequest ) ) )
  619. {
  620. sadb_x_ipsecrequest * ipsr = ( sadb_x_ipsecrequest * ) buff;
  621. if( xindex >= PFKI_MAX_XFORMS )
  622. break;
  623. spinfo.xforms[ xindex ].proto = ipsr->sadb_x_ipsecrequest_proto;
  624. spinfo.xforms[ xindex ].mode = ipsr->sadb_x_ipsecrequest_mode;
  625. spinfo.xforms[ xindex ].level = ipsr->sadb_x_ipsecrequest_level;
  626. spinfo.xforms[ xindex ].reqid = ipsr->sadb_x_ipsecrequest_reqid;
  627. unsigned char * addr_buff = buff;
  628. long addr_size = size;
  629. addr_buff += sizeof( sadb_x_ipsecrequest );
  630. addr_size -= sizeof( sadb_x_ipsecrequest );
  631. if( addr_size >= 0 )
  632. {
  633. sockaddr * saddr_src = ( sockaddr * )( addr_buff );
  634. switch( saddr_src->sa_family )
  635. {
  636. case AF_INET:
  637. {
  638. if( addr_size < long( sizeof( sockaddr_in ) ) )
  639. break;
  640. memcpy(
  641. &spinfo.xforms[ xindex ].saddr_src,
  642. saddr_src,
  643. sizeof( sockaddr_in ) );
  644. addr_buff += sizeof( sockaddr_in );
  645. addr_size -= sizeof( sockaddr_in );
  646. }
  647. }
  648. sockaddr * saddr_dst = ( sockaddr * )( addr_buff );
  649. switch( saddr_dst->sa_family )
  650. {
  651. case AF_INET:
  652. {
  653. if( addr_size < long( sizeof( sockaddr_in ) ) )
  654. break;
  655. memcpy(
  656. &spinfo.xforms[ xindex ].saddr_dst,
  657. saddr_dst,
  658. sizeof( sockaddr_in ) );
  659. addr_buff += sizeof( sockaddr_in );
  660. addr_size -= sizeof( sockaddr_in );
  661. }
  662. }
  663. }
  664. buff += ipsr->sadb_x_ipsecrequest_len;
  665. size -= ipsr->sadb_x_ipsecrequest_len;
  666. xindex++;
  667. }
  668. return IPCERR_OK;
  669. }
  670. long _PFKI::buff_add_ipsec( PFKI_MSG & msg, PFKI_SPINFO & spinfo )
  671. {
  672. size_t size = sizeof( sadb_x_policy );
  673. size_t oset = msg.size() - size;
  674. long result;
  675. long xindex = 0;
  676. while( spinfo.xforms[ xindex ].proto )
  677. {
  678. if( xindex >= PFKI_MAX_XFORMS )
  679. break;
  680. long ext_size = sizeof( sadb_x_ipsecrequest );
  681. int salen_src = 0;
  682. int salen_dst = 0;
  683. if( spinfo.xforms[ xindex ].mode == IPSEC_MODE_TUNNEL )
  684. {
  685. if( !sockaddr_len( spinfo.xforms[ xindex ].saddr_src.sa_family, salen_src ) )
  686. return IPCERR_FAILED;
  687. if( !sockaddr_len( spinfo.xforms[ xindex ].saddr_dst.sa_family, salen_dst ) )
  688. return IPCERR_FAILED;
  689. if( salen_src != salen_dst )
  690. return IPCERR_FAILED;
  691. ext_size += ( salen_src + salen_dst );
  692. }
  693. sadb_x_ipsecrequest * ipsr;
  694. result = buff_add_ext( msg, ( sadb_ext ** ) &ipsr, ext_size, false );
  695. if( result != IPCERR_OK )
  696. return result;
  697. ipsr->sadb_x_ipsecrequest_proto = spinfo.xforms[ xindex ].proto;
  698. ipsr->sadb_x_ipsecrequest_mode = spinfo.xforms[ xindex ].mode;
  699. ipsr->sadb_x_ipsecrequest_level = spinfo.xforms[ xindex ].level;
  700. ipsr->sadb_x_ipsecrequest_reqid = spinfo.xforms[ xindex ].reqid;
  701. unsigned char * ext_buff = ( unsigned char * ) ipsr;
  702. ext_buff += sizeof( sadb_x_ipsecrequest );
  703. if( salen_src )
  704. memcpy( ext_buff, &spinfo.xforms[ xindex ].saddr_src, salen_src );
  705. ext_buff += salen_src;
  706. if( salen_dst )
  707. memcpy( ext_buff, &spinfo.xforms[ xindex ].saddr_dst, salen_dst );
  708. size += ext_size;
  709. xindex++;
  710. }
  711. //
  712. // reset the policy size
  713. //
  714. unsigned char * buff = msg.buff() + oset;
  715. sadb_x_policy * xpl = ( sadb_x_policy * ) buff;
  716. xpl->sadb_x_policy_len = ( u_int16_t ) PFKEY_UNIT64( size );
  717. return IPCERR_OK;
  718. }
  719. //==============================================================================
  720. // message handler functions
  721. //==============================================================================
  722. long _PFKI::send_sainfo( u_int8_t sadb_msg_type, PFKI_SAINFO & sainfo, bool serv )
  723. {
  724. PFKI_MSG msg;
  725. #if defined( OPT_NATT ) && defined( __APPLE__ )
  726. sadb_sa_natt * xsa;
  727. #else
  728. sadb_sa * xsa;
  729. #endif
  730. sadb_x_sa2 * xsa2;
  731. sadb_address *xas, *xad;
  732. sadb_lifetime *xlh, *xls, *xlc;
  733. sadb_key *xke, *xka;
  734. sadb_spirange *xsr;
  735. long result;
  736. //
  737. // sa extension
  738. //
  739. switch( sadb_msg_type )
  740. {
  741. case SADB_DUMP:
  742. case SADB_ADD:
  743. case SADB_GET:
  744. case SADB_DELETE:
  745. case SADB_GETSPI:
  746. case SADB_UPDATE:
  747. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  748. break;
  749. if( ( sadb_msg_type == SADB_GETSPI ) && !serv )
  750. break;
  751. #if defined( OPT_NATT ) && defined( __APPLE__ )
  752. result = buff_add_ext( msg, ( sadb_ext ** ) &xsa, sizeof( sadb_sa_natt ) );
  753. if( result != IPCERR_OK )
  754. return result;
  755. xsa->sa.sadb_sa_exttype = SADB_EXT_SA;
  756. xsa->sa.sadb_sa_spi = sainfo.sa.spi;
  757. xsa->sa.sadb_sa_replay = sainfo.sa.replay;
  758. xsa->sa.sadb_sa_state = sainfo.sa.state;
  759. xsa->sa.sadb_sa_auth = sainfo.sa.auth;
  760. xsa->sa.sadb_sa_encrypt = sainfo.sa.encrypt;
  761. xsa->sa.sadb_sa_flags = sainfo.sa.flags;
  762. xsa->sadb_sa_natt_port = sainfo.sa.natt_port;
  763. #else
  764. result = buff_add_ext( msg, ( sadb_ext ** ) &xsa, sizeof( sadb_sa ) );
  765. if( result != IPCERR_OK )
  766. return result;
  767. xsa->sadb_sa_exttype = SADB_EXT_SA;
  768. xsa->sadb_sa_spi = sainfo.sa.spi;
  769. xsa->sadb_sa_replay = sainfo.sa.replay;
  770. xsa->sadb_sa_state = sainfo.sa.state;
  771. xsa->sadb_sa_auth = sainfo.sa.auth;
  772. xsa->sadb_sa_encrypt = sainfo.sa.encrypt;
  773. xsa->sadb_sa_flags = sainfo.sa.flags;
  774. #endif
  775. break;
  776. }
  777. if( sainfo.error )
  778. goto sainfo_error;
  779. //
  780. // sa2 extension
  781. //
  782. switch( sadb_msg_type )
  783. {
  784. case SADB_DUMP:
  785. case SADB_ADD:
  786. case SADB_GET:
  787. case SADB_GETSPI:
  788. case SADB_UPDATE:
  789. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  790. break;
  791. if( ( sadb_msg_type == SADB_GET ) && !serv )
  792. break;
  793. if( ( sadb_msg_type == SADB_GETSPI ) && serv )
  794. break;
  795. result = buff_add_ext( msg, ( sadb_ext ** ) &xsa2, sizeof( sadb_x_sa2 ) );
  796. if( result != IPCERR_OK )
  797. return result;
  798. xsa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
  799. xsa2->sadb_x_sa2_mode = sainfo.sa2.mode;
  800. xsa2->sadb_x_sa2_reqid = sainfo.sa2.reqid;
  801. xsa2->sadb_x_sa2_sequence = sainfo.sa2.sequence;
  802. break;
  803. }
  804. //
  805. // address extensions
  806. //
  807. switch( sadb_msg_type )
  808. {
  809. case SADB_DUMP:
  810. case SADB_ADD:
  811. case SADB_GET:
  812. case SADB_DELETE:
  813. case SADB_GETSPI:
  814. case SADB_UPDATE:
  815. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  816. break;
  817. if( ( sadb_msg_type == SADB_GET ) && !serv )
  818. break;
  819. int salen_src;
  820. if( !sockaddr_len( sainfo.paddr_src.saddr.sa_family, salen_src ) )
  821. return IPCERR_FAILED;
  822. result = buff_add_ext( msg, ( sadb_ext ** ) &xas, sizeof( sadb_address ) + salen_src );
  823. if( result != IPCERR_OK )
  824. return result;
  825. xas->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  826. result = buff_set_address( xas, sainfo.paddr_src );
  827. if( result != IPCERR_OK )
  828. return result;
  829. int salen_dst;
  830. if( !sockaddr_len( sainfo.paddr_dst.saddr.sa_family, salen_dst ) )
  831. return IPCERR_FAILED;
  832. result = buff_add_ext( msg, ( sadb_ext ** ) &xad, sizeof( sadb_address ) + salen_dst );
  833. if( result != IPCERR_OK )
  834. return result;
  835. xad->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  836. result = buff_set_address( xad, sainfo.paddr_dst );
  837. if( result != IPCERR_OK )
  838. return result;
  839. break;
  840. }
  841. //
  842. // soft and hard lifetime extensions
  843. //
  844. switch( sadb_msg_type )
  845. {
  846. case SADB_DUMP:
  847. case SADB_ADD:
  848. case SADB_GET:
  849. case SADB_UPDATE:
  850. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  851. break;
  852. if( ( sadb_msg_type == SADB_GET ) && !serv )
  853. break;
  854. result = buff_add_ext( msg, ( sadb_ext ** ) &xlh, sizeof( sadb_lifetime ) );
  855. if( result != IPCERR_OK )
  856. return result;
  857. xlh->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
  858. xlh->sadb_lifetime_allocations = sainfo.ltime_hard.allocations;
  859. xlh->sadb_lifetime_bytes = sainfo.ltime_hard.bytes;
  860. xlh->sadb_lifetime_addtime = sainfo.ltime_hard.addtime;
  861. xlh->sadb_lifetime_usetime = sainfo.ltime_hard.usetime;
  862. result = buff_add_ext( msg, ( sadb_ext ** ) &xls, sizeof( sadb_lifetime ) );
  863. if( result != IPCERR_OK )
  864. return result;
  865. xls->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
  866. xls->sadb_lifetime_allocations = sainfo.ltime_soft.allocations;
  867. xls->sadb_lifetime_bytes = sainfo.ltime_soft.bytes;
  868. xls->sadb_lifetime_addtime = sainfo.ltime_soft.addtime;
  869. xls->sadb_lifetime_usetime = sainfo.ltime_soft.usetime;
  870. break;
  871. }
  872. //
  873. // current lifetime extension
  874. //
  875. switch( sadb_msg_type )
  876. {
  877. case SADB_DUMP:
  878. case SADB_ADD:
  879. case SADB_GET:
  880. case SADB_UPDATE:
  881. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  882. break;
  883. if( ( sadb_msg_type == SADB_GET ) && !serv )
  884. break;
  885. result = buff_add_ext( msg, ( sadb_ext ** ) &xlc, sizeof( sadb_lifetime ) );
  886. if( result != IPCERR_OK )
  887. return result;
  888. xlc->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
  889. xlc->sadb_lifetime_allocations = sainfo.ltime_curr.allocations;
  890. xlc->sadb_lifetime_bytes = sainfo.ltime_curr.bytes;
  891. xlc->sadb_lifetime_addtime = sainfo.ltime_curr.addtime;
  892. xlc->sadb_lifetime_usetime = sainfo.ltime_curr.usetime;
  893. break;
  894. }
  895. //
  896. // key data extension
  897. //
  898. switch( sadb_msg_type )
  899. {
  900. case SADB_DUMP:
  901. case SADB_ADD:
  902. case SADB_GET:
  903. case SADB_UPDATE:
  904. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  905. break;
  906. if( ( sadb_msg_type == SADB_GET ) && !serv )
  907. break;
  908. if( sainfo.ekey.length )
  909. {
  910. result = buff_add_ext( msg, ( sadb_ext ** ) &xke, sizeof( sadb_key ) + sainfo.ekey.length );
  911. if( result != IPCERR_OK )
  912. return result;
  913. xke->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
  914. result = buff_set_key( xke, sainfo.ekey );
  915. if( result != IPCERR_OK )
  916. return result;
  917. }
  918. if( sainfo.akey.length )
  919. {
  920. result = buff_add_ext( msg, ( sadb_ext ** ) &xka, sizeof( sadb_key ) + sainfo.akey.length );
  921. if( result != IPCERR_OK )
  922. return result;
  923. xka->sadb_key_exttype = SADB_EXT_KEY_AUTH;
  924. result = buff_set_key( xka, sainfo.akey );
  925. if( result != IPCERR_OK )
  926. return result;
  927. }
  928. break;
  929. }
  930. #if defined( OPT_NATT ) && !defined( __APPLE__ )
  931. //
  932. // natt extension
  933. //
  934. switch( sadb_msg_type )
  935. {
  936. case SADB_DUMP:
  937. case SADB_ADD:
  938. case SADB_GET:
  939. case SADB_UPDATE:
  940. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  941. break;
  942. if( ( sadb_msg_type == SADB_GET ) && !serv )
  943. break;
  944. if( sainfo.natt.type )
  945. {
  946. sadb_x_nat_t_type *xnt;
  947. sadb_x_nat_t_port *xnps, *xnpd;
  948. result = buff_add_ext( msg, ( sadb_ext ** ) &xnt, sizeof( sadb_x_nat_t_type ) );
  949. if( result != IPCERR_OK )
  950. return result;
  951. xnt->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
  952. xnt->sadb_x_nat_t_type_type = sainfo.natt.type;
  953. result = buff_add_ext( msg, ( sadb_ext ** ) &xnps, sizeof( sadb_x_nat_t_port ) );
  954. if( result != IPCERR_OK )
  955. return result;
  956. xnps->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
  957. xnps->sadb_x_nat_t_port_port = sainfo.natt.port_src;
  958. result = buff_add_ext( msg, ( sadb_ext ** ) &xnpd, sizeof( sadb_x_nat_t_port ) );
  959. if( result != IPCERR_OK )
  960. return result;
  961. xnpd->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
  962. xnpd->sadb_x_nat_t_port_port = sainfo.natt.port_dst;
  963. }
  964. break;
  965. }
  966. #endif
  967. //
  968. // spi range extension
  969. //
  970. switch( sadb_msg_type )
  971. {
  972. case SADB_GETSPI:
  973. if( sainfo.range.min || sainfo.range.max )
  974. {
  975. result = buff_add_ext( msg, ( sadb_ext ** ) &xsr, sizeof( sadb_spirange ) );
  976. if( result != IPCERR_OK )
  977. return result;
  978. xsr->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
  979. xsr->sadb_spirange_min = sainfo.range.min;
  980. xsr->sadb_spirange_max = sainfo.range.max;
  981. }
  982. break;
  983. }
  984. sainfo_error:
  985. if( !serv )
  986. sainfo.pid = getpid();
  987. msg.header.sadb_msg_version = PF_KEY_V2;
  988. msg.header.sadb_msg_type = sadb_msg_type;
  989. msg.header.sadb_msg_errno = sainfo.error;
  990. msg.header.sadb_msg_satype = sainfo.satype;
  991. msg.header.sadb_msg_reserved = 0;
  992. msg.header.sadb_msg_seq = sainfo.seq;
  993. msg.header.sadb_msg_pid = sainfo.pid;
  994. return send_message( msg );
  995. }
  996. long _PFKI::send_spinfo( u_int8_t sadb_msg_type, PFKI_SPINFO & spinfo, bool serv )
  997. {
  998. PFKI_MSG msg;
  999. sadb_x_policy * xpl;
  1000. sadb_address *xas, *xad;
  1001. long result;
  1002. if( spinfo.error )
  1003. goto spinfo_error;
  1004. //
  1005. // sp extension
  1006. //
  1007. switch( sadb_msg_type )
  1008. {
  1009. case SADB_ACQUIRE:
  1010. case SADB_X_SPDDUMP:
  1011. case SADB_X_SPDADD:
  1012. case SADB_X_SPDDELETE2:
  1013. if( ( sadb_msg_type == SADB_X_SPDDUMP ) && !serv )
  1014. break;
  1015. result = buff_add_ext( msg, ( sadb_ext ** ) &xpl, sizeof( sadb_x_policy ) );
  1016. if( result != IPCERR_OK )
  1017. return result;
  1018. xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
  1019. xpl->sadb_x_policy_type = spinfo.sp.type;
  1020. xpl->sadb_x_policy_id = spinfo.sp.id;
  1021. xpl->sadb_x_policy_dir = spinfo.sp.dir;
  1022. if( spinfo.sp.type == IPSEC_POLICY_IPSEC )
  1023. {
  1024. result = buff_add_ipsec( msg, spinfo );
  1025. if( result != IPCERR_OK )
  1026. return result;
  1027. }
  1028. break;
  1029. }
  1030. //
  1031. // address extensions
  1032. //
  1033. switch( sadb_msg_type )
  1034. {
  1035. case SADB_ACQUIRE:
  1036. case SADB_X_SPDDUMP:
  1037. case SADB_X_SPDADD:
  1038. if( ( sadb_msg_type == SADB_X_SPDDUMP ) && !serv )
  1039. break;
  1040. int salen_src;
  1041. if( !sockaddr_len( spinfo.paddr_src.saddr.sa_family, salen_src ) )
  1042. return IPCERR_FAILED;
  1043. result = buff_add_ext( msg, ( sadb_ext ** ) &xas, sizeof( sadb_address ) + salen_src );
  1044. if( result != IPCERR_OK )
  1045. return result;
  1046. xas->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  1047. result = buff_set_address( xas, spinfo.paddr_src );
  1048. if( result != IPCERR_OK )
  1049. return result;
  1050. int salen_dst;
  1051. if( !sockaddr_len( spinfo.paddr_dst.saddr.sa_family, salen_dst ) )
  1052. return IPCERR_FAILED;
  1053. result = buff_add_ext( msg, ( sadb_ext ** ) &xad, sizeof( sadb_address ) + salen_dst );
  1054. if( result != IPCERR_OK )
  1055. return result;
  1056. xad->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  1057. result = buff_set_address( xad, spinfo.paddr_dst );
  1058. if( result != IPCERR_OK )
  1059. return result;
  1060. break;
  1061. }
  1062. spinfo_error:
  1063. if( !serv )
  1064. spinfo.pid = getpid();
  1065. msg.header.sadb_msg_version = PF_KEY_V2;
  1066. msg.header.sadb_msg_type = sadb_msg_type;
  1067. msg.header.sadb_msg_errno = spinfo.error;
  1068. msg.header.sadb_msg_satype = SADB_SATYPE_UNSPEC;
  1069. msg.header.sadb_msg_reserved = 0;
  1070. msg.header.sadb_msg_seq = spinfo.seq;
  1071. msg.header.sadb_msg_pid = spinfo.pid;
  1072. return send_message( msg );
  1073. }
  1074. //
  1075. // extension functions
  1076. //
  1077. long _PFKI::read_sa( PFKI_MSG & msg, PFKI_SA & sa )
  1078. {
  1079. //
  1080. // read policy extension
  1081. //
  1082. sadb_sa * xsa;
  1083. long result = buff_get_ext( msg, ( sadb_ext ** ) &xsa, SADB_EXT_SA );
  1084. if( result != IPCERR_OK )
  1085. return result;
  1086. sa.spi = xsa->sadb_sa_spi;
  1087. sa.replay = xsa->sadb_sa_replay;
  1088. sa.state = xsa->sadb_sa_state;
  1089. sa.auth = xsa->sadb_sa_auth;
  1090. sa.encrypt = xsa->sadb_sa_encrypt;
  1091. sa.flags = xsa->sadb_sa_flags;
  1092. return IPCERR_OK;
  1093. }
  1094. long _PFKI::read_sa2( PFKI_MSG & msg, PFKI_SA2 & sa2 )
  1095. {
  1096. //
  1097. // read policy extension
  1098. //
  1099. sadb_x_sa2 * xsa2;
  1100. long result = buff_get_ext( msg, ( sadb_ext ** ) &xsa2, SADB_X_EXT_SA2 );
  1101. if( result != IPCERR_OK )
  1102. return result;
  1103. sa2.mode = xsa2->sadb_x_sa2_mode;
  1104. sa2.sequence = xsa2->sadb_x_sa2_sequence;
  1105. sa2.reqid = xsa2->sadb_x_sa2_reqid;
  1106. return true;
  1107. }
  1108. long _PFKI::read_range( PFKI_MSG & msg, PFKI_RANGE & range )
  1109. {
  1110. //
  1111. // read address extension
  1112. //
  1113. sadb_spirange * xsr;
  1114. long result;
  1115. result = buff_get_ext( msg, ( sadb_ext ** ) &xsr, SADB_EXT_SPIRANGE );
  1116. if( result != IPCERR_OK )
  1117. return result;
  1118. range.min = xsr->sadb_spirange_min;
  1119. range.max = xsr->sadb_spirange_max;
  1120. return IPCERR_OK;
  1121. }
  1122. long _PFKI::read_ltime_curr( PFKI_MSG & msg, PFKI_LTIME & ltime )
  1123. {
  1124. //
  1125. // read lifetime extension
  1126. //
  1127. sadb_lifetime * xlt;
  1128. long result;
  1129. result = buff_get_ext( msg, ( sadb_ext ** ) &xlt, SADB_EXT_LIFETIME_CURRENT );
  1130. if( result != IPCERR_OK )
  1131. return result;
  1132. ltime.allocations = xlt->sadb_lifetime_allocations;
  1133. ltime.addtime = xlt->sadb_lifetime_addtime;
  1134. ltime.usetime = xlt->sadb_lifetime_usetime;
  1135. ltime.bytes = xlt->sadb_lifetime_bytes;
  1136. return IPCERR_OK;
  1137. }
  1138. long _PFKI::read_ltime_hard( PFKI_MSG & msg, PFKI_LTIME & ltime )
  1139. {
  1140. //
  1141. // read lifetime extension
  1142. //
  1143. sadb_lifetime * xlt;
  1144. long result;
  1145. result = buff_get_ext( msg, ( sadb_ext ** ) &xlt, SADB_EXT_LIFETIME_HARD );
  1146. if( result != IPCERR_OK )
  1147. return result;
  1148. ltime.allocations = xlt->sadb_lifetime_allocations;
  1149. ltime.addtime = xlt->sadb_lifetime_addtime;
  1150. ltime.usetime = xlt->sadb_lifetime_usetime;
  1151. ltime.bytes = xlt->sadb_lifetime_bytes;
  1152. return IPCERR_OK;
  1153. }
  1154. long _PFKI::read_ltime_soft( PFKI_MSG & msg, PFKI_LTIME & ltime )
  1155. {
  1156. //
  1157. // read lifetime extension
  1158. //
  1159. sadb_lifetime * xlt;
  1160. long result;
  1161. result = buff_get_ext( msg, ( sadb_ext ** ) &xlt, SADB_EXT_LIFETIME_SOFT );
  1162. if( result != IPCERR_OK )
  1163. return result;
  1164. ltime.allocations = xlt->sadb_lifetime_allocations;
  1165. ltime.addtime = xlt->sadb_lifetime_addtime;
  1166. ltime.usetime = xlt->sadb_lifetime_usetime;
  1167. ltime.bytes = xlt->sadb_lifetime_bytes;
  1168. return IPCERR_OK;
  1169. }
  1170. long _PFKI::read_key_a( PFKI_MSG & msg, PFKI_KEY & akey )
  1171. {
  1172. //
  1173. // read key extension
  1174. //
  1175. sadb_key * xka;
  1176. long result;
  1177. result = buff_get_ext( msg, ( sadb_ext ** ) &xka, SADB_EXT_KEY_AUTH );
  1178. if( result != IPCERR_OK )
  1179. return result;
  1180. result = buff_get_key( xka, akey );
  1181. if( result != IPCERR_OK )
  1182. return result;
  1183. return IPCERR_OK;
  1184. }
  1185. long _PFKI::read_key_e( PFKI_MSG & msg, PFKI_KEY & ekey )
  1186. {
  1187. //
  1188. // read key extension
  1189. //
  1190. sadb_key * xke;
  1191. long result;
  1192. result = buff_get_ext( msg, ( sadb_ext ** ) &xke, SADB_EXT_KEY_ENCRYPT );
  1193. if( result != IPCERR_OK )
  1194. return result;
  1195. result = buff_get_key( xke, ekey );
  1196. if( result != IPCERR_OK )
  1197. return result;
  1198. return IPCERR_OK;
  1199. }
  1200. long _PFKI::read_address_src( PFKI_MSG & msg, PFKI_ADDR & addr )
  1201. {
  1202. //
  1203. // read address extension
  1204. //
  1205. sadb_address * xad;
  1206. long result;
  1207. result = buff_get_ext( msg, ( sadb_ext ** ) &xad, SADB_EXT_ADDRESS_SRC );
  1208. if( result != IPCERR_OK )
  1209. return result;
  1210. result = buff_get_address( xad, addr );
  1211. if( result != IPCERR_OK )
  1212. return result;
  1213. return IPCERR_OK;
  1214. }
  1215. long _PFKI::read_address_dst( PFKI_MSG & msg, PFKI_ADDR & addr )
  1216. {
  1217. //
  1218. // read address extension
  1219. //
  1220. sadb_address * xad;
  1221. long result;
  1222. result = buff_get_ext( msg, ( sadb_ext ** ) &xad, SADB_EXT_ADDRESS_DST );
  1223. if( result != IPCERR_OK )
  1224. return result;
  1225. result = buff_get_address( xad, addr );
  1226. if( result != IPCERR_OK )
  1227. return result;
  1228. return IPCERR_OK;
  1229. }
  1230. #if defined( OPT_NATT ) && !defined( __APPLE__ )
  1231. long _PFKI::read_natt( PFKI_MSG & msg, PFKI_NATT & natt )
  1232. {
  1233. sadb_x_nat_t_type * xnt;
  1234. sadb_x_nat_t_port * xnps, * xnpd;
  1235. long result;
  1236. result = buff_get_ext( msg, ( sadb_ext ** ) &xnt, SADB_X_EXT_NAT_T_TYPE );
  1237. if( result != IPCERR_OK )
  1238. return result;
  1239. natt.type = xnt->sadb_x_nat_t_type_type;
  1240. result = buff_get_ext( msg, ( sadb_ext ** ) &xnps, SADB_X_EXT_NAT_T_SPORT );
  1241. if( result != IPCERR_OK )
  1242. return result;
  1243. natt.port_src = xnps->sadb_x_nat_t_port_port;
  1244. result = buff_get_ext( msg, ( sadb_ext ** ) &xnpd, SADB_X_EXT_NAT_T_DPORT );
  1245. if( result != IPCERR_OK )
  1246. return result;
  1247. natt.port_dst = xnpd->sadb_x_nat_t_port_port;
  1248. return IPCERR_OK;
  1249. }
  1250. # endif // OPT_NATT && !__APPLE__
  1251. long _PFKI::read_policy( PFKI_MSG & msg, PFKI_SPINFO & spinfo )
  1252. {
  1253. //
  1254. // read policy extension
  1255. //
  1256. sadb_x_policy * xpl;
  1257. long result;
  1258. result = buff_get_ext( msg, ( sadb_ext ** ) &xpl, SADB_X_EXT_POLICY );
  1259. if( result != IPCERR_OK )
  1260. return result;
  1261. spinfo.sp.type = xpl->sadb_x_policy_type;
  1262. spinfo.sp.id = xpl->sadb_x_policy_id;
  1263. spinfo.sp.dir = xpl->sadb_x_policy_dir;
  1264. if( spinfo.sp.type == IPSEC_POLICY_IPSEC )
  1265. {
  1266. result = buff_get_ipsec( xpl, spinfo );
  1267. if( result != IPCERR_OK )
  1268. return result;
  1269. }
  1270. return IPCERR_OK;
  1271. }
  1272. //
  1273. // client functions
  1274. //
  1275. long _PFKI::send_register( u_int8_t satype )
  1276. {
  1277. PFKI_SAINFO sainfo;
  1278. memset( &sainfo, 0, sizeof( sainfo ) );
  1279. sainfo.satype = satype;
  1280. return send_sainfo( SADB_REGISTER, sainfo, false );
  1281. }
  1282. long _PFKI::send_dump()
  1283. {
  1284. PFKI_SAINFO sainfo;
  1285. memset( &sainfo, 0, sizeof( sainfo ) );
  1286. return send_sainfo( SADB_DUMP, sainfo, false );
  1287. }
  1288. long _PFKI::send_add( PFKI_SAINFO & sainfo )
  1289. {
  1290. return send_sainfo( SADB_ADD, sainfo, false );
  1291. }
  1292. long _PFKI::send_get( PFKI_SAINFO & sainfo )
  1293. {
  1294. return send_sainfo( SADB_GET, sainfo, false );
  1295. }
  1296. long _PFKI::send_del( PFKI_SAINFO & sainfo )
  1297. {
  1298. return send_sainfo( SADB_DELETE, sainfo, false );
  1299. }
  1300. long _PFKI::send_getspi( PFKI_SAINFO & sainfo )
  1301. {
  1302. return send_sainfo( SADB_GETSPI, sainfo, false );
  1303. }
  1304. long _PFKI::send_update( PFKI_SAINFO & sainfo )
  1305. {
  1306. return send_sainfo( SADB_UPDATE, sainfo, false );
  1307. }
  1308. long _PFKI::send_spdump()
  1309. {
  1310. PFKI_SPINFO spinfo;
  1311. memset( &spinfo, 0, sizeof( spinfo ) );
  1312. return send_spinfo( SADB_X_SPDDUMP, spinfo, false );
  1313. }
  1314. long _PFKI::send_spadd( PFKI_SPINFO & spinfo )
  1315. {
  1316. return send_spinfo( SADB_X_SPDADD, spinfo, false );
  1317. }
  1318. long _PFKI::send_spdel( PFKI_SPINFO & spinfo )
  1319. {
  1320. return send_spinfo( SADB_X_SPDDELETE2, spinfo, false );
  1321. }
  1322. //
  1323. // server functions
  1324. //
  1325. long _PFKI::serv_dump( PFKI_SAINFO & sainfo )
  1326. {
  1327. return send_sainfo( SADB_DUMP, sainfo, true );
  1328. }
  1329. long _PFKI::serv_add( PFKI_SAINFO & sainfo )
  1330. {
  1331. return send_sainfo( SADB_ADD, sainfo, true );
  1332. }
  1333. long _PFKI::serv_get( PFKI_SAINFO & sainfo )
  1334. {
  1335. return send_sainfo( SADB_GET, sainfo, true );
  1336. }
  1337. long _PFKI::serv_del( PFKI_SAINFO & sainfo )
  1338. {
  1339. return send_sainfo( SADB_DELETE, sainfo, true );
  1340. }
  1341. long _PFKI::serv_acquire( PFKI_SPINFO & spinfo )
  1342. {
  1343. return send_spinfo( SADB_ACQUIRE, spinfo, true );
  1344. }
  1345. long _PFKI::serv_getspi( PFKI_SAINFO & sainfo )
  1346. {
  1347. return send_sainfo( SADB_GETSPI, sainfo, true );
  1348. }
  1349. long _PFKI::serv_update( PFKI_SAINFO & sainfo )
  1350. {
  1351. return send_sainfo( SADB_UPDATE, sainfo, true );
  1352. }
  1353. long _PFKI::serv_spdump( PFKI_SPINFO & spinfo )
  1354. {
  1355. return send_spinfo( SADB_X_SPDDUMP, spinfo, true );
  1356. }
  1357. long _PFKI::serv_spadd( PFKI_SPINFO & spinfo )
  1358. {
  1359. return send_spinfo( SADB_X_SPDADD, spinfo, true );
  1360. }
  1361. long _PFKI::serv_spdel( PFKI_SPINFO & spinfo )
  1362. {
  1363. return send_spinfo( SADB_X_SPDDELETE2, spinfo, true );
  1364. }
  1365. //==============================================================================
  1366. // server interface class
  1367. //==============================================================================
  1368. #ifdef WIN32
  1369. long _PFKS::init()
  1370. {
  1371. return ITH_IPCS::init( PFKI_PIPE_NAME, true );
  1372. }
  1373. void _PFKS::done()
  1374. {
  1375. ITH_IPCS::done();
  1376. }
  1377. long _PFKS::inbound( PFKI ** pfki )
  1378. {
  1379. IPCCONN ipcconn;
  1380. long result = ITH_IPCS::inbound( PFKI_PIPE_NAME, ipcconn );
  1381. if( result == IPCERR_OK )
  1382. {
  1383. *pfki = new PFKI;
  1384. if( *pfki == NULL )
  1385. return IPCERR_FAILED;
  1386. (*pfki)->io_conf( ipcconn );
  1387. }
  1388. return result;
  1389. }
  1390. void _PFKS::wakeup()
  1391. {
  1392. ITH_IPCS::wakeup();
  1393. }
  1394. #endif