1 /* routines that interface with pluto to get policy information
2 * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: policyquery.c,v 1.1 2004/03/15 20:35:25 as Exp $
26 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
32 #include <freeswan/ipsec_policy.h>
34 #include "libipsecpolicy.h"
36 static int policy_query_socket
= -1;
37 static u_int32_t policy_seq
= 1;
39 u_int32_t
ipsec_policy_seq(void)
44 err_t
ipsec_policy_init(void)
46 struct sockaddr_un sn
;
48 if(policy_query_socket
!= -1) {
52 policy_query_socket
= socket(PF_UNIX
, SOCK_STREAM
, 0);
53 if(policy_query_socket
== -1) {
54 return "failed to open policy socket";
58 sn
.sun_family
= AF_UNIX
;
59 strcpy(sn
.sun_path
, IPSEC_POLICY_SOCKET
);
61 if(connect(policy_query_socket
, (struct sockaddr
*)&sn
, sizeof(sn
)) != 0) {
62 int saveerrno
= errno
;
63 close(policy_query_socket
);
64 policy_query_socket
=-1;
66 return "failed to connect policy socket";
69 /* okay, I think we are done */
73 err_t
ipsec_policy_final(void)
75 if(policy_query_socket
!= -1) {
76 close(policy_query_socket
);
77 policy_query_socket
= -1;
83 err_t
ipsec_policy_readmsg(int policysock
,
87 struct ipsec_policy_msg_head ipmh
;
89 if(read(policysock
, &ipmh
, sizeof(ipmh
))
94 /* got the header, sanitize it, and find out how much more to read */
95 switch(ipmh
.ipm_version
) {
96 case IPSEC_POLICY_MSG_REVISION
:
100 /* XXX go deal with older versions, error for now */
101 fprintf(stderr
, "Bad magic header: %u\n", ipmh
.ipm_version
);
102 return "bad policy msg version magic";
105 if(ipmh
.ipm_msg_len
> buflen
) {
106 return "buffer too small for this message";
109 buflen
= ipmh
.ipm_msg_len
;
110 memcpy(buf
, &ipmh
, sizeof(ipmh
));
112 buflen
-= sizeof(ipmh
);
114 if(read(policysock
, buf
, buflen
) != buflen
) {
115 return "short read from socket";
121 err_t
ipsec_policy_sendrecv(unsigned char *buf
,
127 if(write(policy_query_socket
, buf
, buflen
)
129 return "write failed";
132 ret
= ipsec_policy_readmsg(policy_query_socket
,
135 ipsec_policy_final();
141 err_t
ipsec_policy_lookup(int fd
, struct ipsec_policy_cmd_query
*result
)
146 memset(result
, 0, sizeof(*result
));
149 result
->head
.ipm_version
= IPSEC_POLICY_MSG_REVISION
;
150 result
->head
.ipm_msg_len
= sizeof(*result
);
151 result
->head
.ipm_msg_type
= IPSEC_CMD_QUERY_HOSTPAIR
;
152 result
->head
.ipm_msg_seq
= ipsec_policy_seq();
154 /* suck out the data on the sockets */
155 len
= sizeof(result
->query_local
);
156 if(getsockname(fd
, (struct sockaddr
*)&result
->query_local
, &len
) != 0) {
157 return "getsockname failed";
160 len
= sizeof(result
->query_remote
);
161 if(getpeername(fd
, (struct sockaddr
*)&result
->query_remote
, &len
) != 0) {
162 return "getpeername failed";
165 return ipsec_policy_sendrecv((unsigned char *)result
, sizeof(*result
));