1/*
2 * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#import	 <asl.h>
27#include <sys/types.h>
28#include "ike_session.h"
29#include "ipsecMessageTracer.h"
30#include "misc.h"
31#include "nattraversal.h"
32
33#define     TRUE	1
34#define		FALSE	0
35const char *ipsecSessionInvalidEventString = "Invalid Event";
36const char *ipsecSessionString			   = "IPSEC";
37
38/* tells us the event's description */
39const char * const ipsecSessionEventStrings[IPSECSESSIONEVENTCODE_MAX] = {	CONSTSTR("NONE") /* index place holder */,
40																			CONSTSTR("IKE Packet: transmit success"),
41																			CONSTSTR("IKE Packet: transmit failed"),
42																			CONSTSTR("IKE Packet: receive success"),
43																			CONSTSTR("IKE Packet: receive failed"),
44																			CONSTSTR("IKEv1 Phase 1 Initiator: success"),
45																			CONSTSTR("IKEv1 Phase 1 Initiator: failed"),
46																			CONSTSTR("IKEv1 Phase 1 Initiator: dropped"),
47																			CONSTSTR("IKEv1 Phase 1 Responder: success"),
48																			CONSTSTR("IKEv1 Phase 1 Responder: failed"),
49																			CONSTSTR("IKEv1 Phase 1 Responder: drop"),
50																			CONSTSTR("IKEv1 Phase 1: maximum retransmits"),
51																			CONSTSTR("IKEv1 Phase 1 AUTH: success"),
52																			CONSTSTR("IKEv1 Phase 1 AUTH: failed"),
53																			CONSTSTR("IKEv1 Dead-Peer-Detection: request transmitted"),
54																			CONSTSTR("IKEv1 Dead-Peer-Detection: response received"),
55																			CONSTSTR("IKEv1 Dead-Peer-Detection: request retransmitted"),
56																			CONSTSTR("IKEv1 Dead-Peer-Detection: request received"),
57																			CONSTSTR("IKEv1 Dead-Peer-Detection: response transmitted"),
58																			CONSTSTR("IKEv1 Dead-Peer-Detection: response retransmitted"),
59																			CONSTSTR("IKEv1 Dead-Peer-Detection: maximum retransmits"),
60																			CONSTSTR("IKEv1 Config: retransmited"),
61																			CONSTSTR("IKEv1 Mode-Config: success"),
62																			CONSTSTR("IKEv1 Mode-Config: failed"),
63																			CONSTSTR("IKEv1 Mode-Config: dropped"),
64																			CONSTSTR("IKEv1 XAUTH: success"),
65																			CONSTSTR("IKEv1 XAUTH: failed"),
66																			CONSTSTR("IKEv1 XAUTH: dropped"),
67																			CONSTSTR("IKEv1 Phase 2 Initiator: success"),
68																			CONSTSTR("IKEv1 Phase 2 Initiator: failed"),
69																			CONSTSTR("IKEv1 Phase 2 Initiator: dropped"),
70																			CONSTSTR("IKEv1 Phase 2 Responder: success"),
71																			CONSTSTR("IKEv1 Phase 2 Responder: fail"),
72																			CONSTSTR("IKEv1 Phase 2 Responder: drop"),
73																			CONSTSTR("IKEv1 Phase 2: maximum retransmits"),
74																			CONSTSTR("IKEv1 Phase 2 AUTH: success"),
75																			CONSTSTR("IKEv1 Phase 2 AUTH: failed"),
76																			CONSTSTR("IKEv1 Information-Notice: transmit success"),
77																			CONSTSTR("IKEv1 Information-Notice: transmit failed"),
78																			CONSTSTR("IKEv1 Information-Notice: receive success"),
79																			CONSTSTR("IKEv1 Information-Notice: receive failed"),
80																		};
81
82/* tells us if we can ignore the failure_reason passed into the event tracer */
83const int ipsecSessionEventIgnoreReason[IPSECSESSIONEVENTCODE_MAX] = {TRUE/* index place holder */,
84																			TRUE,
85																			TRUE,
86																			TRUE,
87																			TRUE,
88																			TRUE,
89																			FALSE,
90																			TRUE,
91																			TRUE,
92																			FALSE,
93																			TRUE,
94																			FALSE,
95																			TRUE,
96																			FALSE,
97																			TRUE,
98																			TRUE,
99																			TRUE,
100																			TRUE,
101																			TRUE,
102																			TRUE,
103																			FALSE,
104																			TRUE,
105																			TRUE,
106																			FALSE,
107																			FALSE,
108																			TRUE,
109																			FALSE,
110																			FALSE,
111																			TRUE,
112																			FALSE,
113																			TRUE,
114																			TRUE,
115																			FALSE,
116																			TRUE,
117																			FALSE,
118																			TRUE,
119																			FALSE,
120																			TRUE,
121																			TRUE,
122																			TRUE,
123																			TRUE,
124																			};
125
126
127const char *
128ipsecSessionEventCodeToString (ipsecSessionEventCode_t eventCode)
129{
130	if (eventCode <= IPSECSESSIONEVENTCODE_NONE || eventCode >= IPSECSESSIONEVENTCODE_MAX)
131		return ipsecSessionInvalidEventString;
132	return(ipsecSessionEventStrings[eventCode]);
133}
134
135const char *
136ipsecSessionGetConnectionDomain (ike_session_t *session)
137{
138	if (session) {
139		if (session->is_cisco_ipsec) {
140            if (session->established) {
141                return CISCOIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN;
142            } else {
143                return CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
144            }
145		} else if (session->is_l2tpvpn_ipsec) {
146            if (session->established) {
147                return L2TPIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN;
148            } else {
149                return L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
150            }
151		} else if (session->is_btmm_ipsec) {
152            if (session->established) {
153                return BTMMIPSEC_CONNECTION_ESTABLISHED_DOMAIN;
154            } else {
155                return BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
156            }
157		} else {
158            if (session->established) {
159                return PLAINIPSEC_CONNECTION_ESTABLISHED_DOMAIN;
160            } else {
161                return PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
162            }
163        }
164	}
165	return PLAINIPSECDOMAIN;
166}
167
168const char *
169ipsecSessionGetConnectionLessDomain (ike_session_t *session)
170{
171	if (session) {
172		if (session->is_cisco_ipsec) {
173            return CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
174		} else if (session->is_l2tpvpn_ipsec) {
175            return L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
176		} else if (session->is_btmm_ipsec) {
177            return BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
178		} else {
179            return PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
180        }
181	}
182	return PLAINIPSECDOMAIN;
183}
184
185const char *
186ipsecSessionGetPhaseDomain (ike_session_t *session)
187{
188	if (session) {
189		if (session->is_cisco_ipsec) {
190			return CISCOIPSECVPN_PHASE_DOMAIN;
191		} else if (session->is_l2tpvpn_ipsec) {
192			return L2TPIPSECVPN_PHASE_DOMAIN;
193		} else if (session->is_btmm_ipsec) {
194			return BTMMIPSEC_PHASE_DOMAIN;
195		}
196	}
197	return PLAINIPSEC_PHASE_DOMAIN;
198}
199
200static
201void
202ipsecSessionLogEvent (ike_session_t *session, const char *event_msg)
203{
204	aslmsg m;
205
206	if (!event_msg) {
207		return;
208	}
209
210	m = asl_new(ASL_TYPE_MSG);
211	asl_set(m, ASL_KEY_FACILITY, ipsecSessionGetPhaseDomain(session));
212	asl_set(m, ASL_KEY_MSG, ipsecSessionString);
213	asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg);
214	asl_free(m);
215}
216
217void
218ipsecSessionTracerStart (ike_session_t *session)
219{
220	if (session == NULL) {
221		return;
222	}
223	bzero(&session->stats, sizeof(session->stats));
224	bzero(&session->stop_timestamp, sizeof(session->stop_timestamp));
225	bzero(&session->estab_timestamp, sizeof(session->estab_timestamp));
226	gettimeofday(&session->start_timestamp, NULL);
227	ipsecSessionLogEvent(session, CONSTSTR("Connecting."));
228}
229
230void
231ipsecSessionTracerEvent (ike_session_t *session, ipsecSessionEventCode_t eventCode, const char *event, const char *failure_reason)
232{
233	char buf[1024];
234
235	if (session == NULL) {
236		//ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid session)."));
237		return;
238	}
239	if (eventCode <= IPSECSESSIONEVENTCODE_NONE || eventCode >= IPSECSESSIONEVENTCODE_MAX) {
240		ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid event code)."));
241		return;
242	}
243	if (event == NULL) {
244		ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid event)."));
245		return;
246	}
247
248	if (failure_reason) {
249		if (!session->term_reason &&
250            !ipsecSessionEventIgnoreReason[eventCode]) {
251			session->term_reason = (char*)failure_reason;
252		}
253	}
254
255	session->stats.counters[eventCode]++;
256	buf[0] = (char)0;
257	snprintf(buf, sizeof(buf), "%s. (%s).", ipsecSessionEventCodeToString(eventCode), event);
258	ipsecSessionLogEvent(session, CONSTSTR(buf));
259}
260
261static void
262ipsecSessionTracerLogFailureRate (ike_session_t *session, const char *signature, double failure_rate)
263{
264	aslmsg		m;
265	char		buf[128];
266	const char *domain = ipsecSessionGetPhaseDomain(session);
267
268	if (!signature || failure_rate <= 0.001) {
269		return;
270	}
271
272	m = asl_new(ASL_TYPE_MSG);
273	asl_set(m, "com.apple.message.domain", domain);
274	asl_set(m, ASL_KEY_FACILITY, domain);
275	asl_set(m, ASL_KEY_MSG, ipsecSessionString);
276    asl_set(m, "com.apple.message.result", "noop");
277	asl_set(m, "com.apple.message.signature", signature);
278	snprintf(buf, sizeof(buf), "%.3f", failure_rate);
279	asl_set(m, "com.apple.message.value", buf);	// stuff the up time into value
280	asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s. (Failure-Rate = %s).", signature, buf);
281	asl_free(m);
282}
283
284static void
285ipsecSessionTracerLogStop (ike_session_t *session, int caused_by_failure, const char *reason)
286{
287	aslmsg      m;
288	char        nat_buf[128];
289	char        buf[128];
290	const char *domain = (session->established)? ipsecSessionGetConnectionDomain(session) : ipsecSessionGetConnectionLessDomain(session);
291
292	m = asl_new(ASL_TYPE_MSG);
293	asl_set(m, "com.apple.message.domain", domain);
294	asl_set(m, ASL_KEY_FACILITY, domain);
295	asl_set(m, ASL_KEY_MSG, ipsecSessionString);
296    if (caused_by_failure ||
297        (reason && reason != ike_session_stopped_by_flush && reason != ike_session_stopped_by_vpn_disconnect)) {
298        asl_set(m, "com.apple.message.result", CONSTSTR("failure"));	// failure
299    } else {
300        asl_set(m, "com.apple.message.result", CONSTSTR("success"));	// success
301    }
302	if (reason) {
303        if (session->natt_flags & NAT_DETECTED_ME) {
304            snprintf(nat_buf, sizeof(nat_buf), "%s. NAT detected by Me", reason);
305            asl_set(m, "com.apple.message.signature", nat_buf);
306        } else if (session->natt_flags & NAT_DETECTED_PEER) {
307            snprintf(nat_buf, sizeof(nat_buf), "%s. NAT detected by Peer", reason);
308            asl_set(m, "com.apple.message.signature", nat_buf);
309        } else {
310            asl_set(m, "com.apple.message.signature", reason);
311        }
312	} else {
313		// reason was NULL; make sure success/failure have different signature
314		if (caused_by_failure) {
315			asl_set(m, "com.apple.message.signature", CONSTSTR("Internal/Server-side error"));
316		} else {
317			asl_set(m, "com.apple.message.signature", CONSTSTR("User/System initiated the disconnect"));
318		}
319	}
320	if (session->established) {
321		snprintf(buf, sizeof(buf), "%8.6f", timedelta(&session->estab_timestamp, &session->stop_timestamp));
322		asl_set(m, "com.apple.message.value", buf);	// stuff the up time into value
323		asl_log(NULL, m, ASL_LEVEL_NOTICE, "Disconnecting. (Connection was up for, %s seconds).", buf);
324	} else {
325		snprintf(buf, sizeof(buf), "%8.6f", timedelta(&session->start_timestamp, &session->stop_timestamp));
326		asl_set(m, "com.apple.message.value2", buf);	/// stuff the negoing time into value2
327		asl_log(NULL, m, ASL_LEVEL_NOTICE, "Disconnecting. (Connection tried to negotiate for, %s seconds).", buf);
328	}
329	asl_free(m);
330}
331
332void
333ipsecSessionTracerStop (ike_session_t *session, int caused_by_failure, const char *reason)
334{
335	if (session == NULL) {
336		return;
337	}
338
339	gettimeofday(&session->stop_timestamp, NULL);
340
341	ipsecSessionTracerLogStop(session, caused_by_failure, reason);
342
343	// go thru counters logging failure-rate events
344	if (session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL]) {
345		ipsecSessionTracerLogFailureRate(session,
346										 CONSTSTR("IKE Packets Transmit Failure-Rate Statistic"),
347										 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC]));
348	}
349	if (session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL]) {
350		ipsecSessionTracerLogFailureRate(session,
351										 CONSTSTR("IKE Packets Receive Failure-Rate Statistic"),
352										 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC]));
353	}
354	//if (session->version == IKE_VERSION_1) {
355		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT] ||
356			session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL] ||
357			session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]) {
358			ipsecSessionTracerLogFailureRate(session,
359											 CONSTSTR("IKE Phase 1 Failure-Rate Statistic"),
360											 get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT] +
361                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL] +
362                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]),
363                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC] +
364                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC])));
365		}
366		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL]) {
367			ipsecSessionTracerLogFailureRate(session,
368											 CONSTSTR("IKE Phase 1 Initiator Failure-Rate Statistic"),
369											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC]));
370		}
371		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]) {
372			ipsecSessionTracerLogFailureRate(session,
373											 CONSTSTR("IKE Phase 1 Responder Failure-Rate Statistic"),
374											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC]));
375		}
376		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL]) {
377			ipsecSessionTracerLogFailureRate(session,
378											 CONSTSTR("IKE Phase 1 Authentication Failure-Rate Statistic"),
379											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC]));
380		}
381		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT]) {
382			ipsecSessionTracerLogFailureRate(session,
383											 CONSTSTR("IKE Dead-Peer-Detection Failure-Rate Statistic"),
384											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT],
385                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT] +
386                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ])));
387		}
388		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT] ||
389			session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT]) {
390			ipsecSessionTracerLogFailureRate(session,
391											 CONSTSTR("IKE Dead-Peer-Detect Retransmit-Rate Statistic"),
392											 get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT] +
393                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT]),
394                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ] +
395                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ])));
396		}
397		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL]) {
398			ipsecSessionTracerLogFailureRate(session,
399											 CONSTSTR("IKE MODE-Config Failure-Rate Statistic"),
400											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_SUCC]));
401		}
402		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL]) {
403			ipsecSessionTracerLogFailureRate(session,
404											 CONSTSTR("IKE XAUTH Failure-Rate Statistic"),
405											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC]));
406		}
407		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT] ||
408			session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL] ||
409			session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]) {
410			ipsecSessionTracerLogFailureRate(session,
411											 CONSTSTR("IKE Phase 2 Failure-Rate Statistic"),
412											 get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT] +
413                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL] +
414                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]),
415                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC] +
416                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL])));
417		}
418		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL]) {
419			ipsecSessionTracerLogFailureRate(session,
420											 CONSTSTR("IKE Phase 2 Initiator Failure-Rate Statistic"),
421											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC]));
422		}
423		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]) {
424			ipsecSessionTracerLogFailureRate(session,
425											 CONSTSTR("IKE Phase 2 Responder Failure-Rate Statistic"),
426											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC]));
427		}
428		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL]) {
429			ipsecSessionTracerLogFailureRate(session,
430											 CONSTSTR("IKE Phase 2 Authentication Failure-Rate Statistics"),
431											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_SUCC]));
432		}
433		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL]) {
434			ipsecSessionTracerLogFailureRate(session,
435											 CONSTSTR("IKE Information-Notice Transmit Failure-Rate Statistic"),
436											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL]));
437		}
438		if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL]) {
439			ipsecSessionTracerLogFailureRate(session,
440											 CONSTSTR("IKE Information-Notice Receive Failure-Rate Statistic"),
441											 get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_SUCC]));
442		}
443	//}
444}
445
446void
447ipsecSessionTracerLogEstablished (ike_session_t *session)
448{
449	aslmsg      m;
450	const char *domain = ipsecSessionGetConnectionLessDomain(session);
451
452	m = asl_new(ASL_TYPE_MSG);
453	asl_set(m, "com.apple.message.domain", domain);
454	asl_set(m, ASL_KEY_FACILITY, domain);
455	asl_set(m, ASL_KEY_MSG, ipsecSessionString);
456    asl_set(m, "com.apple.message.result", "success");	// success
457    asl_set(m, "com.apple.message.signature", "success");
458    asl_log(NULL, m, ASL_LEVEL_NOTICE, "Connected.");
459	asl_free(m);
460}
461