PageRenderTime 42ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/ike/source/libpfk/libpfk.cpp

#
C++ | 1813 lines | 1202 code | 445 blank | 166 comment | 206 complexity | 6d24ff629381548795c2d7694e1e44ef 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. switch( value )
  305. {
  306. case SADB_AALG_MD5HMAC:
  307. return authtype_02;
  308. case SADB_AALG_SHA1HMAC:
  309. return authtype_03;
  310. default:
  311. return unknown;
  312. }
  313. }
  314. case NAME_SATYPE:
  315. {
  316. static const char * satype_00 = "UNSPEC";
  317. static const char * satype_02 = "AH";
  318. static const char * satype_03 = "ESP";
  319. static const char * satype_05 = "RSVP";
  320. static const char * satype_06 = "OSPFV2";
  321. static const char * satype_07 = "RIPV2";
  322. static const char * satype_08 = "MIP";
  323. static const char * satype_09 = "IPCOMP";
  324. static const char * satype_11 = "TCPSIGNATURE";
  325. switch( value )
  326. {
  327. case SADB_SATYPE_UNSPEC:
  328. return satype_00;
  329. case SADB_SATYPE_AH:
  330. return satype_02;
  331. case SADB_SATYPE_ESP:
  332. return satype_03;
  333. case SADB_SATYPE_RSVP:
  334. return satype_05;
  335. case SADB_SATYPE_OSPFV2:
  336. return satype_06;
  337. case SADB_SATYPE_RIPV2:
  338. return satype_07;
  339. case SADB_SATYPE_MIP:
  340. return satype_08;
  341. case SADB_X_SATYPE_IPCOMP:
  342. return satype_09;
  343. // case SADB_X_SATYPE_TCPSIGNATURE:
  344. // return satype_11;
  345. default:
  346. return unknown;
  347. }
  348. }
  349. case NAME_SPMODE:
  350. {
  351. static const char * plcymode_00 = "ANY";
  352. static const char * plcymode_01 = "TANSPORT";
  353. static const char * plcymode_02 = "TUNNEL";
  354. switch( value )
  355. {
  356. case IPSEC_MODE_ANY:
  357. return plcymode_00;
  358. case IPSEC_MODE_TRANSPORT:
  359. return plcymode_01;
  360. case IPSEC_MODE_TUNNEL:
  361. return plcymode_02;
  362. default:
  363. return unknown;
  364. }
  365. }
  366. case NAME_SPTYPE:
  367. {
  368. static const char * plcytype_00 = "DISCARD";
  369. static const char * plcytype_01 = "NONE";
  370. static const char * plcytype_02 = "IPSEC";
  371. static const char * plcytype_03 = "ENTRUST";
  372. static const char * plcytype_04 = "BYPASS";
  373. switch( value )
  374. {
  375. case IPSEC_POLICY_DISCARD:
  376. return plcytype_00;
  377. case IPSEC_POLICY_NONE:
  378. return plcytype_01;
  379. case IPSEC_POLICY_IPSEC:
  380. return plcytype_02;
  381. case IPSEC_POLICY_ENTRUST:
  382. return plcytype_03;
  383. case IPSEC_POLICY_BYPASS:
  384. return plcytype_04;
  385. default:
  386. return unknown;
  387. }
  388. }
  389. case NAME_SPDIR:
  390. {
  391. static const char * plcydir_00 = "ANY";
  392. static const char * plcydir_01 = "INBOUND";
  393. static const char * plcydir_02 = "OUTBOUND";
  394. static const char * plcydir_03 = "MAX";
  395. static const char * plcydir_04 = "INVALID";
  396. switch( value )
  397. {
  398. case IPSEC_DIR_ANY:
  399. return plcydir_00;
  400. case IPSEC_DIR_INBOUND:
  401. return plcydir_01;
  402. case IPSEC_DIR_OUTBOUND:
  403. return plcydir_02;
  404. case IPSEC_DIR_MAX:
  405. return plcydir_03;
  406. case IPSEC_DIR_INVALID:
  407. return plcydir_04;
  408. default:
  409. return unknown;
  410. }
  411. }
  412. case NAME_SPLEVEL:
  413. {
  414. static const char * plcylevel_00 = "ANY";
  415. static const char * plcylevel_01 = "USE";
  416. static const char * plcylevel_02 = "REQUIRE";
  417. static const char * plcylevel_03 = "UNIQUE";
  418. switch( value )
  419. {
  420. case IPSEC_LEVEL_DEFAULT:
  421. return plcylevel_00;
  422. case IPSEC_LEVEL_USE:
  423. return plcylevel_01;
  424. case IPSEC_LEVEL_REQUIRE:
  425. return plcylevel_02;
  426. case IPSEC_LEVEL_UNIQUE:
  427. return plcylevel_03;
  428. default:
  429. return unknown;
  430. }
  431. }
  432. case NAME_NTTYPE:
  433. {
  434. static const char * nattype_00 = "NONE";
  435. static const char * nattype_01 = "ESPINUDP-NON-IKE";
  436. static const char * nattype_02 = "ESPINUDP";
  437. switch( value )
  438. {
  439. case 0:
  440. return nattype_00;
  441. #ifdef OPT_NATT
  442. case UDP_ENCAP_ESPINUDP_NON_IKE:
  443. return nattype_01;
  444. case UDP_ENCAP_ESPINUDP:
  445. return nattype_02;
  446. #endif
  447. default:
  448. return unknown;
  449. }
  450. }
  451. }
  452. return unknown;
  453. }
  454. //==============================================================================
  455. // buffer management functions
  456. //==============================================================================
  457. bool _PFKI::sockaddr_len( int safam, int & salen )
  458. {
  459. switch( safam )
  460. {
  461. case AF_INET:
  462. salen = sizeof( sockaddr_in );
  463. return true;
  464. }
  465. printf( "XX : address family %i unhandled\n", safam );
  466. return false;
  467. }
  468. long _PFKI::buff_get_ext( PFKI_MSG & msg, sadb_ext ** ext, long type )
  469. {
  470. unsigned char * buff = msg.buff();
  471. size_t size = msg.size();
  472. buff += sizeof( sadb_msg );
  473. size -= sizeof( sadb_msg );
  474. while( 1 )
  475. {
  476. //
  477. // make sure the buffer holds
  478. // enough data to contain an
  479. // extension header
  480. //
  481. if( long( sizeof( sadb_ext ) ) > size )
  482. {
  483. printf( "XX : extension not found\n" );
  484. return IPCERR_FAILED;
  485. }
  486. sadb_ext * ext_head = ( sadb_ext * ) buff;
  487. //
  488. // make sure the buffer holds
  489. // enough data to contain the
  490. // extension body
  491. //
  492. if( PFKEY_EXTLEN( ext_head ) > size )
  493. {
  494. printf( "XX : buffer too small for ext body ( %i bytes )\n",
  495. PFKEY_EXTLEN( ext_head ) );
  496. return IPCERR_FAILED;
  497. }
  498. //
  499. // stop evaluation if this is
  500. // the requested extension
  501. //
  502. if( ext_head->sadb_ext_type == type )
  503. {
  504. //
  505. // sainfo the pointers and size
  506. //
  507. *ext = ( sadb_ext * ) buff;
  508. break;
  509. }
  510. //
  511. // move to next extension
  512. //
  513. buff += PFKEY_EXTLEN( ext_head );
  514. size -= PFKEY_EXTLEN( ext_head );
  515. }
  516. return IPCERR_OK;
  517. }
  518. long _PFKI::buff_add_ext( PFKI_MSG & msg, sadb_ext ** ext, long xlen, bool unit64 )
  519. {
  520. size_t oset = msg.size();
  521. xlen = PFKEY_ALIGN8( xlen );
  522. msg.add( 0, xlen );
  523. *ext = ( sadb_ext * )( msg.buff() + oset );
  524. if( unit64 )
  525. ( *ext )->sadb_ext_len = ( u_int16_t ) PFKEY_UNIT64( xlen );
  526. else
  527. ( *ext )->sadb_ext_len = ( u_int16_t ) xlen;
  528. return IPCERR_OK;
  529. }
  530. long _PFKI::buff_get_address( sadb_address * ext, PFKI_ADDR & addr )
  531. {
  532. unsigned char * buff = ( unsigned char * ) ext;
  533. int size = PFKEY_UNUNIT64( ext->sadb_address_len );
  534. addr.proto = ext->sadb_address_proto;
  535. addr.prefix = ext->sadb_address_prefixlen;
  536. buff += sizeof( sadb_address );
  537. size -= sizeof( sadb_address );
  538. sockaddr * saddr = ( sockaddr * ) buff;
  539. int salen;
  540. if( !sockaddr_len( saddr->sa_family, salen ) )
  541. return IPCERR_FAILED;
  542. if( size < salen )
  543. {
  544. printf( "!! : pfkey address size mismatch\n" );
  545. return IPCERR_FAILED;
  546. }
  547. memcpy( &addr.saddr, saddr, salen );
  548. return IPCERR_OK;
  549. }
  550. long _PFKI::buff_set_address( sadb_address * ext, PFKI_ADDR & addr )
  551. {
  552. unsigned char * buff = ( unsigned char * ) ext;
  553. int size = PFKEY_UNUNIT64( ext->sadb_address_len );
  554. ext->sadb_address_proto = addr.proto;
  555. ext->sadb_address_prefixlen = addr.prefix;
  556. buff += sizeof( sadb_address );
  557. size -= sizeof( sadb_address );
  558. int salen;
  559. if( !sockaddr_len( addr.saddr.sa_family, salen ) )
  560. return IPCERR_FAILED;
  561. if( size < salen )
  562. {
  563. printf( "!! : pfkey address size mismatch\n" );
  564. return IPCERR_FAILED;
  565. }
  566. memcpy( buff, &addr.saddr, salen );
  567. return IPCERR_OK;
  568. }
  569. long _PFKI::buff_set_key( sadb_key * ext, PFKI_KEY & key )
  570. {
  571. unsigned char * buff = ( unsigned char * ) ext;
  572. int size = PFKEY_UNUNIT64( ext->sadb_key_len );
  573. ext->sadb_key_bits = key.length * 8;
  574. buff += sizeof( sadb_key );
  575. size -= sizeof( sadb_key );
  576. if( size < key.length )
  577. {
  578. printf( "!! : pfkey key size mismatch ( %i < %i )\n", size, key.length );
  579. return IPCERR_FAILED;
  580. }
  581. memcpy( buff, key.keydata, key.length );
  582. return IPCERR_OK;
  583. }
  584. long _PFKI::buff_get_key( sadb_key * ext, PFKI_KEY & key )
  585. {
  586. unsigned char * buff = ( unsigned char * ) ext;
  587. int size = PFKEY_UNUNIT64( ext->sadb_key_len );
  588. buff += sizeof( sadb_key );
  589. size -= sizeof( sadb_key );
  590. if( !ext->sadb_key_bits )
  591. return IPCERR_FAILED;
  592. key.length = ext->sadb_key_bits / 8;
  593. if( size < key.length )
  594. {
  595. printf( "!! : pfkey key size mismatch ( %i < %i )\n", size, key.length );
  596. return IPCERR_FAILED;
  597. }
  598. memcpy( key.keydata, buff, key.length );
  599. return IPCERR_OK;
  600. }
  601. long _PFKI::buff_get_ipsec( sadb_x_policy * ext, PFKI_SPINFO & spinfo )
  602. {
  603. unsigned char * buff = ( unsigned char * ) ext;
  604. int size = PFKEY_UNUNIT64( ext->sadb_x_policy_len );
  605. buff += sizeof( sadb_x_policy );
  606. size -= sizeof( sadb_x_policy );
  607. long xindex = 0;
  608. while( size >= long( sizeof( sadb_x_ipsecrequest ) ) )
  609. {
  610. sadb_x_ipsecrequest * ipsr = ( sadb_x_ipsecrequest * ) buff;
  611. if( xindex >= PFKI_MAX_XFORMS )
  612. break;
  613. spinfo.xforms[ xindex ].proto = ipsr->sadb_x_ipsecrequest_proto;
  614. spinfo.xforms[ xindex ].mode = ipsr->sadb_x_ipsecrequest_mode;
  615. spinfo.xforms[ xindex ].level = ipsr->sadb_x_ipsecrequest_level;
  616. spinfo.xforms[ xindex ].reqid = ipsr->sadb_x_ipsecrequest_reqid;
  617. unsigned char * addr_buff = buff;
  618. long addr_size = size;
  619. addr_buff += sizeof( sadb_x_ipsecrequest );
  620. addr_size -= sizeof( sadb_x_ipsecrequest );
  621. if( addr_size >= 0 )
  622. {
  623. sockaddr * saddr_src = ( sockaddr * )( addr_buff );
  624. switch( saddr_src->sa_family )
  625. {
  626. case AF_INET:
  627. {
  628. if( addr_size < long( sizeof( sockaddr_in ) ) )
  629. break;
  630. memcpy(
  631. &spinfo.xforms[ xindex ].saddr_src,
  632. saddr_src,
  633. sizeof( sockaddr_in ) );
  634. addr_buff += sizeof( sockaddr_in );
  635. addr_size -= sizeof( sockaddr_in );
  636. }
  637. }
  638. sockaddr * saddr_dst = ( sockaddr * )( addr_buff );
  639. switch( saddr_dst->sa_family )
  640. {
  641. case AF_INET:
  642. {
  643. if( addr_size < long( sizeof( sockaddr_in ) ) )
  644. break;
  645. memcpy(
  646. &spinfo.xforms[ xindex ].saddr_dst,
  647. saddr_dst,
  648. sizeof( sockaddr_in ) );
  649. addr_buff += sizeof( sockaddr_in );
  650. addr_size -= sizeof( sockaddr_in );
  651. }
  652. }
  653. }
  654. buff += ipsr->sadb_x_ipsecrequest_len;
  655. size -= ipsr->sadb_x_ipsecrequest_len;
  656. xindex++;
  657. }
  658. return IPCERR_OK;
  659. }
  660. long _PFKI::buff_add_ipsec( PFKI_MSG & msg, PFKI_SPINFO & spinfo )
  661. {
  662. size_t size = sizeof( sadb_x_policy );
  663. size_t oset = msg.size() - size;
  664. long result;
  665. long xindex = 0;
  666. while( spinfo.xforms[ xindex ].proto )
  667. {
  668. if( xindex >= PFKI_MAX_XFORMS )
  669. break;
  670. long ext_size = sizeof( sadb_x_ipsecrequest );
  671. int salen_src = 0;
  672. int salen_dst = 0;
  673. if( spinfo.xforms[ xindex ].mode == IPSEC_MODE_TUNNEL )
  674. {
  675. if( !sockaddr_len( spinfo.xforms[ xindex ].saddr_src.sa_family, salen_src ) )
  676. return IPCERR_FAILED;
  677. if( !sockaddr_len( spinfo.xforms[ xindex ].saddr_dst.sa_family, salen_dst ) )
  678. return IPCERR_FAILED;
  679. if( salen_src != salen_dst )
  680. return IPCERR_FAILED;
  681. ext_size += ( salen_src + salen_dst );
  682. }
  683. sadb_x_ipsecrequest * ipsr;
  684. result = buff_add_ext( msg, ( sadb_ext ** ) &ipsr, ext_size, false );
  685. if( result != IPCERR_OK )
  686. return result;
  687. ipsr->sadb_x_ipsecrequest_proto = spinfo.xforms[ xindex ].proto;
  688. ipsr->sadb_x_ipsecrequest_mode = spinfo.xforms[ xindex ].mode;
  689. ipsr->sadb_x_ipsecrequest_level = spinfo.xforms[ xindex ].level;
  690. ipsr->sadb_x_ipsecrequest_reqid = spinfo.xforms[ xindex ].reqid;
  691. unsigned char * ext_buff = ( unsigned char * ) ipsr;
  692. ext_buff += sizeof( sadb_x_ipsecrequest );
  693. if( salen_src )
  694. memcpy( ext_buff, &spinfo.xforms[ xindex ].saddr_src, salen_src );
  695. ext_buff += salen_src;
  696. if( salen_dst )
  697. memcpy( ext_buff, &spinfo.xforms[ xindex ].saddr_dst, salen_dst );
  698. size += ext_size;
  699. xindex++;
  700. }
  701. //
  702. // reset the policy size
  703. //
  704. unsigned char * buff = msg.buff() + oset;
  705. sadb_x_policy * xpl = ( sadb_x_policy * ) buff;
  706. xpl->sadb_x_policy_len = ( u_int16_t ) PFKEY_UNIT64( size );
  707. return IPCERR_OK;
  708. }
  709. //==============================================================================
  710. // message handler functions
  711. //==============================================================================
  712. long _PFKI::send_sainfo( u_int8_t sadb_msg_type, PFKI_SAINFO & sainfo, bool serv )
  713. {
  714. PFKI_MSG msg;
  715. sadb_sa * xsa;
  716. sadb_x_sa2 * xsa2;
  717. sadb_address *xas, *xad;
  718. sadb_lifetime *xlh, *xls, *xlc;
  719. sadb_key *xke, *xka;
  720. sadb_spirange *xsr;
  721. long result;
  722. //
  723. // sa extension
  724. //
  725. switch( sadb_msg_type )
  726. {
  727. case SADB_DUMP:
  728. case SADB_ADD:
  729. case SADB_GET:
  730. case SADB_DELETE:
  731. case SADB_GETSPI:
  732. case SADB_UPDATE:
  733. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  734. break;
  735. if( ( sadb_msg_type == SADB_GETSPI ) && !serv )
  736. break;
  737. result = buff_add_ext( msg, ( sadb_ext ** ) &xsa, sizeof( sadb_sa ) );
  738. if( result != IPCERR_OK )
  739. return result;
  740. xsa->sadb_sa_exttype = SADB_EXT_SA;
  741. xsa->sadb_sa_spi = sainfo.sa.spi;
  742. xsa->sadb_sa_replay = sainfo.sa.replay;
  743. xsa->sadb_sa_state = sainfo.sa.state;
  744. xsa->sadb_sa_auth = sainfo.sa.auth;
  745. xsa->sadb_sa_encrypt = sainfo.sa.encrypt;
  746. xsa->sadb_sa_flags = sainfo.sa.flags;
  747. break;
  748. }
  749. if( sainfo.error )
  750. goto sainfo_error;
  751. //
  752. // sa2 extension
  753. //
  754. switch( sadb_msg_type )
  755. {
  756. case SADB_DUMP:
  757. case SADB_ADD:
  758. case SADB_GET:
  759. case SADB_GETSPI:
  760. case SADB_UPDATE:
  761. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  762. break;
  763. if( ( sadb_msg_type == SADB_GET ) && !serv )
  764. break;
  765. if( ( sadb_msg_type == SADB_GETSPI ) && serv )
  766. break;
  767. result = buff_add_ext( msg, ( sadb_ext ** ) &xsa2, sizeof( sadb_x_sa2 ) );
  768. if( result != IPCERR_OK )
  769. return result;
  770. xsa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
  771. xsa2->sadb_x_sa2_mode = sainfo.sa2.mode;
  772. xsa2->sadb_x_sa2_reqid = sainfo.sa2.reqid;
  773. xsa2->sadb_x_sa2_sequence = sainfo.sa2.sequence;
  774. break;
  775. }
  776. //
  777. // address extensions
  778. //
  779. switch( sadb_msg_type )
  780. {
  781. case SADB_DUMP:
  782. case SADB_ADD:
  783. case SADB_GET:
  784. case SADB_DELETE:
  785. case SADB_GETSPI:
  786. case SADB_UPDATE:
  787. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  788. break;
  789. if( ( sadb_msg_type == SADB_GET ) && !serv )
  790. break;
  791. int salen_src;
  792. if( !sockaddr_len( sainfo.paddr_src.saddr.sa_family, salen_src ) )
  793. return IPCERR_FAILED;
  794. result = buff_add_ext( msg, ( sadb_ext ** ) &xas, sizeof( sadb_address ) + salen_src );
  795. if( result != IPCERR_OK )
  796. return result;
  797. xas->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  798. result = buff_set_address( xas, sainfo.paddr_src );
  799. if( result != IPCERR_OK )
  800. return result;
  801. int salen_dst;
  802. if( !sockaddr_len( sainfo.paddr_dst.saddr.sa_family, salen_dst ) )
  803. return IPCERR_FAILED;
  804. result = buff_add_ext( msg, ( sadb_ext ** ) &xad, sizeof( sadb_address ) + salen_dst );
  805. if( result != IPCERR_OK )
  806. return result;
  807. xad->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  808. result = buff_set_address( xad, sainfo.paddr_dst );
  809. if( result != IPCERR_OK )
  810. return result;
  811. break;
  812. }
  813. //
  814. // soft and hard lifetime extensions
  815. //
  816. switch( sadb_msg_type )
  817. {
  818. case SADB_DUMP:
  819. case SADB_ADD:
  820. case SADB_GET:
  821. case SADB_UPDATE:
  822. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  823. break;
  824. if( ( sadb_msg_type == SADB_GET ) && !serv )
  825. break;
  826. result = buff_add_ext( msg, ( sadb_ext ** ) &xlh, sizeof( sadb_lifetime ) );
  827. if( result != IPCERR_OK )
  828. return result;
  829. xlh->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
  830. xlh->sadb_lifetime_allocations = sainfo.ltime_hard.allocations;
  831. xlh->sadb_lifetime_bytes = sainfo.ltime_hard.bytes;
  832. xlh->sadb_lifetime_addtime = sainfo.ltime_hard.addtime;
  833. xlh->sadb_lifetime_usetime = sainfo.ltime_hard.usetime;
  834. result = buff_add_ext( msg, ( sadb_ext ** ) &xls, sizeof( sadb_lifetime ) );
  835. if( result != IPCERR_OK )
  836. return result;
  837. xls->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
  838. xls->sadb_lifetime_allocations = sainfo.ltime_soft.allocations;
  839. xls->sadb_lifetime_bytes = sainfo.ltime_soft.bytes;
  840. xls->sadb_lifetime_addtime = sainfo.ltime_soft.addtime;
  841. xls->sadb_lifetime_usetime = sainfo.ltime_soft.usetime;
  842. break;
  843. }
  844. //
  845. // current lifetime extension
  846. //
  847. switch( sadb_msg_type )
  848. {
  849. case SADB_DUMP:
  850. case SADB_ADD:
  851. case SADB_GET:
  852. case SADB_UPDATE:
  853. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  854. break;
  855. if( ( sadb_msg_type == SADB_GET ) && !serv )
  856. break;
  857. result = buff_add_ext( msg, ( sadb_ext ** ) &xlc, sizeof( sadb_lifetime ) );
  858. if( result != IPCERR_OK )
  859. return result;
  860. xlc->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
  861. xlc->sadb_lifetime_allocations = sainfo.ltime_curr.allocations;
  862. xlc->sadb_lifetime_bytes = sainfo.ltime_curr.bytes;
  863. xlc->sadb_lifetime_addtime = sainfo.ltime_curr.addtime;
  864. xlc->sadb_lifetime_usetime = sainfo.ltime_curr.usetime;
  865. break;
  866. }
  867. //
  868. // key data extension
  869. //
  870. switch( sadb_msg_type )
  871. {
  872. case SADB_DUMP:
  873. case SADB_ADD:
  874. case SADB_GET:
  875. case SADB_UPDATE:
  876. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  877. break;
  878. if( ( sadb_msg_type == SADB_GET ) && !serv )
  879. break;
  880. if( sainfo.ekey.length )
  881. {
  882. result = buff_add_ext( msg, ( sadb_ext ** ) &xke, sizeof( sadb_key ) + sainfo.ekey.length );
  883. if( result != IPCERR_OK )
  884. return result;
  885. xke->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
  886. result = buff_set_key( xke, sainfo.ekey );
  887. if( result != IPCERR_OK )
  888. return result;
  889. }
  890. if( sainfo.akey.length )
  891. {
  892. result = buff_add_ext( msg, ( sadb_ext ** ) &xka, sizeof( sadb_key ) + sainfo.akey.length );
  893. if( result != IPCERR_OK )
  894. return result;
  895. xka->sadb_key_exttype = SADB_EXT_KEY_AUTH;
  896. result = buff_set_key( xka, sainfo.akey );
  897. if( result != IPCERR_OK )
  898. return result;
  899. }
  900. break;
  901. }
  902. #ifdef OPT_NATT
  903. //
  904. // natt extension
  905. //
  906. switch( sadb_msg_type )
  907. {
  908. case SADB_DUMP:
  909. case SADB_ADD:
  910. case SADB_GET:
  911. case SADB_UPDATE:
  912. if( ( sadb_msg_type == SADB_DUMP ) && !serv )
  913. break;
  914. if( ( sadb_msg_type == SADB_GET ) && !serv )
  915. break;
  916. if( sainfo.natt.type )
  917. {
  918. sadb_x_nat_t_type *xnt;
  919. sadb_x_nat_t_port *xnps, *xnpd;
  920. result = buff_add_ext( msg, ( sadb_ext ** ) &xnt, sizeof( sadb_x_nat_t_type ) );
  921. if( result != IPCERR_OK )
  922. return result;
  923. xnt->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
  924. xnt->sadb_x_nat_t_type_type = sainfo.natt.type;
  925. result = buff_add_ext( msg, ( sadb_ext ** ) &xnps, sizeof( sadb_x_nat_t_port ) );
  926. if( result != IPCERR_OK )
  927. return result;
  928. xnps->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
  929. xnps->sadb_x_nat_t_port_port = sainfo.natt.port_src;
  930. result = buff_add_ext( msg, ( sadb_ext ** ) &xnpd, sizeof( sadb_x_nat_t_port ) );
  931. if( result != IPCERR_OK )
  932. return result;
  933. xnpd->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
  934. xnpd->sadb_x_nat_t_port_port = sainfo.natt.port_dst;
  935. }
  936. break;
  937. }
  938. #endif
  939. //
  940. // spi range extension
  941. //
  942. switch( sadb_msg_type )
  943. {
  944. case SADB_GETSPI:
  945. if( sainfo.range.min || sainfo.range.max )
  946. {
  947. result = buff_add_ext( msg, ( sadb_ext ** ) &xsr, sizeof( sadb_spirange ) );
  948. if( result != IPCERR_OK )
  949. return result;
  950. xsr->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
  951. xsr->sadb_spirange_min = sainfo.range.min;
  952. xsr->sadb_spirange_max = sainfo.range.max;
  953. }
  954. break;
  955. }
  956. sainfo_error:
  957. if( !serv )
  958. sainfo.pid = getpid();
  959. msg.header.sadb_msg_version = PF_KEY_V2;
  960. msg.header.sadb_msg_type = sadb_msg_type;
  961. msg.header.sadb_msg_errno = sainfo.error;
  962. msg.header.sadb_msg_satype = sainfo.satype;
  963. msg.header.sadb_msg_reserved = 0;
  964. msg.header.sadb_msg_seq = sainfo.seq;
  965. msg.header.sadb_msg_pid = sainfo.pid;
  966. return send_message( msg );
  967. }
  968. long _PFKI::send_spinfo( u_int8_t sadb_msg_type, PFKI_SPINFO & spinfo, bool serv )
  969. {
  970. PFKI_MSG msg;
  971. sadb_x_policy * xpl;
  972. sadb_address *xas, *xad;
  973. long result;
  974. if( spinfo.error )
  975. goto spinfo_error;
  976. //
  977. // sp extension
  978. //
  979. switch( sadb_msg_type )
  980. {
  981. case SADB_ACQUIRE:
  982. case SADB_X_SPDDUMP:
  983. case SADB_X_SPDADD:
  984. case SADB_X_SPDDELETE2:
  985. if( ( sadb_msg_type == SADB_X_SPDDUMP ) && !serv )
  986. break;
  987. result = buff_add_ext( msg, ( sadb_ext ** ) &xpl, sizeof( sadb_x_policy ) );
  988. if( result != IPCERR_OK )
  989. return result;
  990. xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
  991. xpl->sadb_x_policy_type = spinfo.sp.type;
  992. xpl->sadb_x_policy_id = spinfo.sp.id;
  993. xpl->sadb_x_policy_dir = spinfo.sp.dir;
  994. if( spinfo.sp.type == IPSEC_POLICY_IPSEC )
  995. {
  996. result = buff_add_ipsec( msg, spinfo );
  997. if( result != IPCERR_OK )
  998. return result;
  999. }
  1000. break;
  1001. }
  1002. //
  1003. // address extensions
  1004. //
  1005. switch( sadb_msg_type )
  1006. {
  1007. case SADB_ACQUIRE:
  1008. case SADB_X_SPDDUMP:
  1009. case SADB_X_SPDADD:
  1010. if( ( sadb_msg_type == SADB_X_SPDDUMP ) && !serv )
  1011. break;
  1012. int salen_src;
  1013. if( !sockaddr_len( spinfo.paddr_src.saddr.sa_family, salen_src ) )
  1014. return IPCERR_FAILED;
  1015. result = buff_add_ext( msg, ( sadb_ext ** ) &xas, sizeof( sadb_address ) + salen_src );
  1016. if( result != IPCERR_OK )
  1017. return result;
  1018. xas->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  1019. result = buff_set_address( xas, spinfo.paddr_src );
  1020. if( result != IPCERR_OK )
  1021. return result;
  1022. int salen_dst;
  1023. if( !sockaddr_len( spinfo.paddr_dst.saddr.sa_family, salen_dst ) )
  1024. return IPCERR_FAILED;
  1025. result = buff_add_ext( msg, ( sadb_ext ** ) &xad, sizeof( sadb_address ) + salen_dst );
  1026. if( result != IPCERR_OK )
  1027. return result;
  1028. xad->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  1029. result = buff_set_address( xad, spinfo.paddr_dst );
  1030. if( result != IPCERR_OK )
  1031. return result;
  1032. break;
  1033. }
  1034. spinfo_error:
  1035. if( !serv )
  1036. spinfo.pid = getpid();
  1037. msg.header.sadb_msg_version = PF_KEY_V2;
  1038. msg.header.sadb_msg_type = sadb_msg_type;
  1039. msg.header.sadb_msg_errno = spinfo.error;
  1040. msg.header.sadb_msg_satype = SADB_SATYPE_UNSPEC;
  1041. msg.header.sadb_msg_reserved = 0;
  1042. msg.header.sadb_msg_seq = spinfo.seq;
  1043. msg.header.sadb_msg_pid = spinfo.pid;
  1044. return send_message( msg );
  1045. }
  1046. //
  1047. // extension functions
  1048. //
  1049. long _PFKI::read_sa( PFKI_MSG & msg, PFKI_SA & sa )
  1050. {
  1051. //
  1052. // read policy extension
  1053. //
  1054. sadb_sa * xsa;
  1055. long result = buff_get_ext( msg, ( sadb_ext ** ) &xsa, SADB_EXT_SA );
  1056. if( result != IPCERR_OK )
  1057. return result;
  1058. sa.spi = xsa->sadb_sa_spi;
  1059. sa.replay = xsa->sadb_sa_replay;
  1060. sa.state = xsa->sadb_sa_state;
  1061. sa.auth = xsa->sadb_sa_auth;
  1062. sa.encrypt = xsa->sadb_sa_encrypt;
  1063. sa.flags = xsa->sadb_sa_flags;
  1064. return IPCERR_OK;
  1065. }
  1066. long _PFKI::read_sa2( PFKI_MSG & msg, PFKI_SA2 & sa2 )
  1067. {
  1068. //
  1069. // read policy extension
  1070. //
  1071. sadb_x_sa2 * xsa2;
  1072. long result = buff_get_ext( msg, ( sadb_ext ** ) &xsa2, SADB_X_EXT_SA2 );
  1073. if( result != IPCERR_OK )
  1074. return result;
  1075. sa2.mode = xsa2->sadb_x_sa2_mode;
  1076. sa2.sequence = xsa2->sadb_x_sa2_sequence;
  1077. sa2.reqid = xsa2->sadb_x_sa2_reqid;
  1078. return true;
  1079. }
  1080. long _PFKI::read_range( PFKI_MSG & msg, PFKI_RANGE & range )
  1081. {
  1082. //
  1083. // read address extension
  1084. //
  1085. sadb_spirange * xsr;
  1086. long result;
  1087. result = buff_get_ext( msg, ( sadb_ext ** ) &xsr, SADB_EXT_SPIRANGE );
  1088. if( result != IPCERR_OK )
  1089. return result;
  1090. range.min = xsr->sadb_spirange_min;
  1091. range.max = xsr->sadb_spirange_max;
  1092. return IPCERR_OK;
  1093. }
  1094. long _PFKI::read_ltime_curr( PFKI_MSG & msg, PFKI_LTIME & ltime )
  1095. {
  1096. //
  1097. // read lifetime extension
  1098. //
  1099. sadb_lifetime * xlt;
  1100. long result;
  1101. result = buff_get_ext( msg, ( sadb_ext ** ) &xlt, SADB_EXT_LIFETIME_CURRENT );
  1102. if( result != IPCERR_OK )
  1103. return result;
  1104. ltime.allocations = xlt->sadb_lifetime_allocations;
  1105. ltime.addtime = xlt->sadb_lifetime_addtime;
  1106. ltime.usetime = xlt->sadb_lifetime_usetime;
  1107. ltime.bytes = xlt->sadb_lifetime_bytes;
  1108. return IPCERR_OK;
  1109. }
  1110. long _PFKI::read_ltime_hard( PFKI_MSG & msg, PFKI_LTIME & ltime )
  1111. {
  1112. //
  1113. // read lifetime extension
  1114. //
  1115. sadb_lifetime * xlt;
  1116. long result;
  1117. result = buff_get_ext( msg, ( sadb_ext ** ) &xlt, SADB_EXT_LIFETIME_HARD );
  1118. if( result != IPCERR_OK )
  1119. return result;
  1120. ltime.allocations = xlt->sadb_lifetime_allocations;
  1121. ltime.addtime = xlt->sadb_lifetime_addtime;
  1122. ltime.usetime = xlt->sadb_lifetime_usetime;
  1123. ltime.bytes = xlt->sadb_lifetime_bytes;
  1124. return IPCERR_OK;
  1125. }
  1126. long _PFKI::read_ltime_soft( PFKI_MSG & msg, PFKI_LTIME & ltime )
  1127. {
  1128. //
  1129. // read lifetime extension
  1130. //
  1131. sadb_lifetime * xlt;
  1132. long result;
  1133. result = buff_get_ext( msg, ( sadb_ext ** ) &xlt, SADB_EXT_LIFETIME_SOFT );
  1134. if( result != IPCERR_OK )
  1135. return result;
  1136. ltime.allocations = xlt->sadb_lifetime_allocations;
  1137. ltime.addtime = xlt->sadb_lifetime_addtime;
  1138. ltime.usetime = xlt->sadb_lifetime_usetime;
  1139. ltime.bytes = xlt->sadb_lifetime_bytes;
  1140. return IPCERR_OK;
  1141. }
  1142. long _PFKI::read_key_a( PFKI_MSG & msg, PFKI_KEY & akey )
  1143. {
  1144. //
  1145. // read key extension
  1146. //
  1147. sadb_key * xka;
  1148. long result;
  1149. result = buff_get_ext( msg, ( sadb_ext ** ) &xka, SADB_EXT_KEY_AUTH );
  1150. if( result != IPCERR_OK )
  1151. return result;
  1152. result = buff_get_key( xka, akey );
  1153. if( result != IPCERR_OK )
  1154. return result;
  1155. return IPCERR_OK;
  1156. }
  1157. long _PFKI::read_key_e( PFKI_MSG & msg, PFKI_KEY & ekey )
  1158. {
  1159. //
  1160. // read key extension
  1161. //
  1162. sadb_key * xke;
  1163. long result;
  1164. result = buff_get_ext( msg, ( sadb_ext ** ) &xke, SADB_EXT_KEY_ENCRYPT );
  1165. if( result != IPCERR_OK )
  1166. return result;
  1167. result = buff_get_key( xke, ekey );
  1168. if( result != IPCERR_OK )
  1169. return result;
  1170. return IPCERR_OK;
  1171. }
  1172. long _PFKI::read_address_src( PFKI_MSG & msg, PFKI_ADDR & addr )
  1173. {
  1174. //
  1175. // read address extension
  1176. //
  1177. sadb_address * xad;
  1178. long result;
  1179. result = buff_get_ext( msg, ( sadb_ext ** ) &xad, SADB_EXT_ADDRESS_SRC );
  1180. if( result != IPCERR_OK )
  1181. return result;
  1182. result = buff_get_address( xad, addr );
  1183. if( result != IPCERR_OK )
  1184. return result;
  1185. return IPCERR_OK;
  1186. }
  1187. long _PFKI::read_address_dst( PFKI_MSG & msg, PFKI_ADDR & addr )
  1188. {
  1189. //
  1190. // read address extension
  1191. //
  1192. sadb_address * xad;
  1193. long result;
  1194. result = buff_get_ext( msg, ( sadb_ext ** ) &xad, SADB_EXT_ADDRESS_DST );
  1195. if( result != IPCERR_OK )
  1196. return result;
  1197. result = buff_get_address( xad, addr );
  1198. if( result != IPCERR_OK )
  1199. return result;
  1200. return IPCERR_OK;
  1201. }
  1202. long _PFKI::read_natt( PFKI_MSG & msg, PFKI_NATT & natt )
  1203. {
  1204. #ifdef OPT_NATT
  1205. sadb_x_nat_t_type * xnt;
  1206. sadb_x_nat_t_port * xnps, * xnpd;
  1207. long result;
  1208. result = buff_get_ext( msg, ( sadb_ext ** ) &xnt, SADB_X_EXT_NAT_T_TYPE );
  1209. if( result != IPCERR_OK )
  1210. return result;
  1211. natt.type = xnt->sadb_x_nat_t_type_type;
  1212. result = buff_get_ext( msg, ( sadb_ext ** ) &xnps, SADB_X_EXT_NAT_T_SPORT );
  1213. if( result != IPCERR_OK )
  1214. return result;
  1215. natt.port_src = xnps->sadb_x_nat_t_port_port;
  1216. result = buff_get_ext( msg, ( sadb_ext ** ) &xnpd, SADB_X_EXT_NAT_T_DPORT );
  1217. if( result != IPCERR_OK )
  1218. return result;
  1219. natt.port_dst = xnpd->sadb_x_nat_t_port_port;
  1220. return IPCERR_OK;
  1221. #else
  1222. return IPCERR_FAILED;
  1223. #endif
  1224. }
  1225. long _PFKI::read_policy( PFKI_MSG & msg, PFKI_SPINFO & spinfo )
  1226. {
  1227. //
  1228. // read policy extension
  1229. //
  1230. sadb_x_policy * xpl;
  1231. long result;
  1232. result = buff_get_ext( msg, ( sadb_ext ** ) &xpl, SADB_X_EXT_POLICY );
  1233. if( result != IPCERR_OK )
  1234. return result;
  1235. spinfo.sp.type = xpl->sadb_x_policy_type;
  1236. spinfo.sp.id = xpl->sadb_x_policy_id;
  1237. spinfo.sp.dir = xpl->sadb_x_policy_dir;
  1238. if( spinfo.sp.type == IPSEC_POLICY_IPSEC )
  1239. {
  1240. result = buff_get_ipsec( xpl, spinfo );
  1241. if( result != IPCERR_OK )
  1242. return result;
  1243. }
  1244. return IPCERR_OK;
  1245. }
  1246. //
  1247. // client functions
  1248. //
  1249. long _PFKI::send_register( u_int8_t satype )
  1250. {
  1251. PFKI_SAINFO sainfo;
  1252. memset( &sainfo, 0, sizeof( sainfo ) );
  1253. sainfo.satype = satype;
  1254. return send_sainfo( SADB_REGISTER, sainfo, false );
  1255. }
  1256. long _PFKI::send_dump()
  1257. {
  1258. PFKI_SAINFO sainfo;
  1259. memset( &sainfo, 0, sizeof( sainfo ) );
  1260. return send_sainfo( SADB_DUMP, sainfo, false );
  1261. }
  1262. long _PFKI::send_add( PFKI_SAINFO & sainfo )
  1263. {
  1264. return send_sainfo( SADB_ADD, sainfo, false );
  1265. }
  1266. long _PFKI::send_get( PFKI_SAINFO & sainfo )
  1267. {
  1268. return send_sainfo( SADB_GET, sainfo, false );
  1269. }
  1270. long _PFKI::send_del( PFKI_SAINFO & sainfo )
  1271. {
  1272. return send_sainfo( SADB_DELETE, sainfo, false );
  1273. }
  1274. long _PFKI::send_getspi( PFKI_SAINFO & sainfo )
  1275. {
  1276. return send_sainfo( SADB_GETSPI, sainfo, false );
  1277. }
  1278. long _PFKI::send_update( PFKI_SAINFO & sainfo )
  1279. {
  1280. return send_sainfo( SADB_UPDATE, sainfo, false );
  1281. }
  1282. long _PFKI::send_spdump()
  1283. {
  1284. PFKI_SPINFO spinfo;
  1285. memset( &spinfo, 0, sizeof( spinfo ) );
  1286. return send_spinfo( SADB_X_SPDDUMP, spinfo, false );
  1287. }
  1288. long _PFKI::send_spadd( PFKI_SPINFO & spinfo )
  1289. {
  1290. return send_spinfo( SADB_X_SPDADD, spinfo, false );
  1291. }
  1292. long _PFKI::send_spdel( PFKI_SPINFO & spinfo )
  1293. {
  1294. return send_spinfo( SADB_X_SPDDELETE2, spinfo, false );
  1295. }
  1296. //
  1297. // server functions
  1298. //
  1299. long _PFKI::serv_dump( PFKI_SAINFO & sainfo )
  1300. {
  1301. return send_sainfo( SADB_DUMP, sainfo, true );
  1302. }
  1303. long _PFKI::serv_add( PFKI_SAINFO & sainfo )
  1304. {
  1305. return send_sainfo( SADB_ADD, sainfo, true );
  1306. }
  1307. long _PFKI::serv_get( PFKI_SAINFO & sainfo )
  1308. {
  1309. return send_sainfo( SADB_GET, sainfo, true );
  1310. }
  1311. long _PFKI::serv_del( PFKI_SAINFO & sainfo )
  1312. {
  1313. return send_sainfo( SADB_DELETE, sainfo, true );
  1314. }
  1315. long _PFKI::serv_acquire( PFKI_SPINFO & spinfo )
  1316. {
  1317. return send_spinfo( SADB_ACQUIRE, spinfo, true );
  1318. }
  1319. long _PFKI::serv_getspi( PFKI_SAINFO & sainfo )
  1320. {
  1321. return send_sainfo( SADB_GETSPI, sainfo, true );
  1322. }
  1323. long _PFKI::serv_update( PFKI_SAINFO & sainfo )
  1324. {
  1325. return send_sainfo( SADB_UPDATE, sainfo, true );
  1326. }
  1327. long _PFKI::serv_spdump( PFKI_SPINFO & spinfo )
  1328. {
  1329. return send_spinfo( SADB_X_SPDDUMP, spinfo, true );
  1330. }
  1331. long _PFKI::serv_spadd( PFKI_SPINFO & spinfo )
  1332. {
  1333. return send_spinfo( SADB_X_SPDADD, spinfo, true );
  1334. }
  1335. long _PFKI::serv_spdel( PFKI_SPINFO & spinfo )
  1336. {
  1337. return send_spinfo( SADB_X_SPDDELETE2, spinfo, true );
  1338. }
  1339. //==============================================================================
  1340. // server interface class
  1341. //==============================================================================
  1342. #ifdef WIN32
  1343. long _PFKS::init()
  1344. {
  1345. return ITH_IPCS::init( PFKI_PIPE_NAME, true );
  1346. }
  1347. void _PFKS::done()
  1348. {
  1349. ITH_IPCS::done();
  1350. }
  1351. long _PFKS::inbound( PFKI ** pfki )
  1352. {
  1353. IPCCONN ipcconn;
  1354. long result = ITH_IPCS::inbound( PFKI_PIPE_NAME, ipcconn );
  1355. if( result == IPCERR_OK )
  1356. {
  1357. *pfki = new PFKI;
  1358. if( *pfki == NULL )
  1359. return IPCERR_FAILED;
  1360. (*pfki)->io_conf( ipcconn );
  1361. }
  1362. return result;
  1363. }
  1364. void _PFKS::wakeup()
  1365. {
  1366. ITH_IPCS::wakeup();
  1367. }
  1368. #endif