2 * Copyright (C) 2014 Martin Willi
3 * Copyright (C) 2014 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "vici_control.h"
17 #include "vici_builder.h"
23 typedef struct private_vici_control_t private_vici_control_t
;
26 * Private data of an vici_control_t object.
28 struct private_vici_control_t
{
31 * Public vici_control_t interface.
33 vici_control_t
public;
38 vici_dispatcher_t
*dispatcher
;
42 * Log callback helper data
45 /** dispatcher to send log messages over */
46 vici_dispatcher_t
*dispatcher
;
47 /** connection ID to send messages to */
54 * Log using vici event messages
56 static bool log_vici(log_info_t
*info
, debug_t group
, level_t level
,
57 ike_sa_t
*ike_sa
, char *text
)
59 if (level
<= info
->level
)
61 vici_message_t
*message
;
62 vici_builder_t
*builder
;
64 builder
= vici_builder_create();
65 builder
->add_kv(builder
, "group", "%N", debug_names
, group
);
66 builder
->add_kv(builder
, "level", "%d", level
);
69 builder
->add_kv(builder
, "ikesa-name", "%s",
70 ike_sa
->get_name(ike_sa
));
71 builder
->add_kv(builder
, "ikesa-uniqueid", "%u",
72 ike_sa
->get_unique_id(ike_sa
));
74 builder
->add_kv(builder
, "msg", "%s", text
);
76 message
= builder
->finalize(builder
);
79 info
->dispatcher
->raise_event(info
->dispatcher
, "control-log",
87 * Send a (error) reply message
89 static vici_message_t
* send_reply(private_vici_control_t
*this, char *fmt
, ...)
91 vici_builder_t
*builder
;
94 builder
= vici_builder_create();
95 builder
->add_kv(builder
, "success", fmt ?
"no" : "yes");
99 builder
->vadd_kv(builder
, "errmsg", fmt
, args
);
102 return builder
->finalize(builder
);
106 * Get the child_cfg having name from peer_cfg
108 static child_cfg_t
* get_child_from_peer(peer_cfg_t
*peer_cfg
, char *name
)
110 child_cfg_t
*current
, *found
= NULL
;
111 enumerator_t
*enumerator
;
113 enumerator
= peer_cfg
->create_child_cfg_enumerator(peer_cfg
);
114 while (enumerator
->enumerate(enumerator
, ¤t
))
116 if (streq(current
->get_name(current
), name
))
119 found
->get_ref(found
);
123 enumerator
->destroy(enumerator
);
127 CALLBACK(initiate
, vici_message_t
*,
128 private_vici_control_t
*this, char *name
, u_int id
, vici_message_t
*request
)
130 child_cfg_t
*child_cfg
= NULL
;
131 peer_cfg_t
*peer_cfg
;
132 enumerator_t
*enumerator
;
136 .dispatcher
= this->dispatcher
,
140 child
= request
->get_str(request
, NULL
, "child");
141 timeout
= request
->get_int(request
, 0, "timeout");
142 log
.level
= request
->get_int(request
, 1, "loglevel");
146 return send_reply(this, "missing configuration name");
148 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
149 NULL
, NULL
, NULL
, NULL
, IKE_ANY
);
150 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
152 child_cfg
= get_child_from_peer(peer_cfg
, child
);
155 peer_cfg
->get_ref(peer_cfg
);
159 enumerator
->destroy(enumerator
);
163 return send_reply(this, "CHILD_SA config '%s' not found", child
);
165 switch (charon
->controller
->initiate(charon
->controller
,
166 peer_cfg
, child_cfg
, (controller_cb_t
)log_vici
, &log
, timeout
))
169 return send_reply(this, NULL
);
171 return send_reply(this, "CHILD_SA '%s' not established after %dms",
175 return send_reply(this, "establishing CHILD_SA '%s' failed", child
);
179 static void manage_command(private_vici_control_t
*this,
180 char *name
, vici_command_cb_t cb
, bool reg
)
182 this->dispatcher
->manage_command(this->dispatcher
, name
,
183 reg ? cb
: NULL
, this);
187 * (Un-)register dispatcher functions
189 static void manage_commands(private_vici_control_t
*this, bool reg
)
191 manage_command(this, "initiate", initiate
, reg
);
192 this->dispatcher
->manage_event(this->dispatcher
, "control-log", reg
);
195 METHOD(vici_control_t
, destroy
, void,
196 private_vici_control_t
*this)
198 manage_commands(this, FALSE
);
205 vici_control_t
*vici_control_create(vici_dispatcher_t
*dispatcher
)
207 private_vici_control_t
*this;
213 .dispatcher
= dispatcher
,
216 manage_commands(this, TRUE
);
218 return &this->public;