int ipsec_sa_print(struct ipsec_sa *ips) { char sa[SATOT_BUF]; size_t sa_len; printk(KERN_INFO "klips_debug: SA:"); if (ips == NULL) { printk("NULL\n"); return -ENOENT; } printk(" ref=%d", ips->ips_ref); printk(" refcount=%d", atomic_read(&ips->ips_refcount)); if (ips->ips_hnext != NULL) printk(" hnext=0p%p", ips->ips_hnext); if (ips->ips_next != NULL) printk(" next=0p%p", ips->ips_next); if (ips->ips_prev != NULL) printk(" prev=0p%p", ips->ips_prev); sa_len = KLIPS_SATOT(1, &ips->ips_said, 0, sa, sizeof(sa)); printk(" said=%s", sa_len ? sa : " (error)"); if (ips->ips_seq) printk(" seq=%u", ips->ips_seq); if (ips->ips_pid) printk(" pid=%u", ips->ips_pid); if (ips->ips_authalg) printk(" authalg=%u", ips->ips_authalg); if (ips->ips_encalg) printk(" encalg=%u", ips->ips_encalg); printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips)); if (ips->ips_replaywin) printk(" ooowin=%u", ips->ips_replaywin); if (ips->ips_flags) printk(" flags=%u", ips->ips_flags); if (ips->ips_addr_s) { char buf[SUBNETTOA_BUF]; sin_addrtot(ips->ips_addr_s, 0, buf, sizeof(buf)); printk(" src=%s", buf); } if (ips->ips_addr_d) { char buf[SUBNETTOA_BUF]; sin_addrtot(ips->ips_addr_s, 0, buf, sizeof(buf)); printk(" dst=%s", buf); } if (ips->ips_addr_p) { char buf[SUBNETTOA_BUF]; sin_addrtot(ips->ips_addr_p, 0, buf, sizeof(buf)); printk(" proxy=%s", buf); } if (ips->ips_key_bits_a) printk(" key_bits_a=%u", ips->ips_key_bits_a); if (ips->ips_key_bits_e) printk(" key_bits_e=%u", ips->ips_key_bits_e); printk("\n"); return 0; }
int ipsec_sa_init(struct ipsec_sa *ipsp) { int error = 0; char sa[SATOT_BUF]; size_t sa_len; #ifdef CONFIG_KLIPS_DEBUG char ipaddr_txt[ADDRTOA_BUF]; char ipaddr2_txt[ADDRTOA_BUF]; #endif #if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || \ defined (CONFIG_KLIPS_AUTH_HMAC_SHA1) unsigned char kb[AHMD596_BLKLEN]; int i; #endif if (ipsp == NULL) { KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "ipsp is NULL, fatal\n"); SENDERR(EINVAL); } sa_len = KLIPS_SATOT(debug_pfkey, &ipsp->ips_said, 0, sa, sizeof(sa)); KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "(pfkey defined) called for SA:%s\n", sa_len ? sa : " (error)"); KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "calling init routine of %s%s%s\n", IPS_XFORM_NAME(ipsp)); switch (ipsp->ips_said.proto) { #ifdef CONFIG_KLIPS_IPIP case IPPROTO_IPIP: { ipsp->ips_xformfuncs = ipip_xform_funcs; #ifdef CONFIG_KLIPS_DEBUG sin_addrtot(ipsp->ips_addr_s, 0, ipaddr_txt, sizeof(ipaddr_txt)); sin_addrtot(ipsp->ips_addr_d, 0, ipaddr2_txt, sizeof(ipaddr2_txt)); KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n", ipaddr_txt, ipaddr2_txt); #endif } break; #endif /* !CONFIG_KLIPS_IPIP */ #ifdef CONFIG_KLIPS_AH case IPPROTO_AH: ipsp->ips_xformfuncs = ah_xform_funcs; #ifdef CONFIG_KLIPS_OCF if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, 0)) break; #endif #ifdef CONFIG_KLIPS_ALG error = ipsec_alg_auth_key_create(ipsp); if ((error < 0) && (error != -EPROTO)) SENDERR(-error); if (error == -EPROTO) { /* perform manual key generation, ignore this particular error */ error = 0; #endif /* CONFIG_KLIPS_ALG */ switch (ipsp->ips_authalg) { # ifdef CONFIG_KLIPS_AUTH_HMAC_MD5 case AH_MD5: { unsigned char *akp; unsigned int aks; MD5_CTX *ictx; MD5_CTX *octx; if (ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "incorrect key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/, ipsp->ips_key_bits_a, AHMD596_KLEN * 8); SENDERR(EINVAL); } # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "hmac md5-96 key is 0x%08x %08x %08x %08x\n", ntohl(*(((__u32 *)ipsp->ips_key_a) + 0)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 1)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 2)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 3))); # endif /* KLIPS_DIVULGE_HMAC_KEY */ ipsp->ips_auth_bits = AHMD596_ALEN * 8; /* save the pointer to the key material */ akp = ipsp->ips_key_a; aks = ipsp->ips_key_a_size; KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "allocating %lu bytes for md5_ctx.\n", (unsigned long) sizeof(struct md5_ctx)); if ((ipsp->ips_key_a = (caddr_t) kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { ipsp->ips_key_a = akp; SENDERR(ENOMEM); } ipsp->ips_key_a_size = sizeof(struct md5_ctx); for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) kb[i] = akp[i] ^ HMAC_IPAD; for (; i < AHMD596_BLKLEN; i++) kb[i] = HMAC_IPAD; ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); osMD5Init(ictx); osMD5Update(ictx, kb, AHMD596_BLKLEN); for (i = 0; i < AHMD596_BLKLEN; i++) kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); osMD5Init(octx); osMD5Update(octx, kb, AHMD596_BLKLEN); # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ((__u32*)ictx)[0], ((__u32*)ictx)[1], ((__u32*)ictx)[2], ((__u32*)ictx)[3], ((__u32*)octx)[0], ((__u32*)octx)[1], ((__u32*)octx)[2], ((__u32*)octx)[3] ); # endif /* KLIPS_DIVULGE_HMAC_KEY */ /* zero key buffer -- paranoid */ memset(akp, 0, aks); kfree(akp); } break; # endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */ # ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1 case AH_SHA: { unsigned char *akp; unsigned int aks; SHA1_CTX *ictx; SHA1_CTX *octx; if (ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "incorrect key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/, ipsp->ips_key_bits_a, AHSHA196_KLEN * 8); SENDERR(EINVAL); } # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", ntohl(*(((__u32 *)ipsp->ips_key_a) + 0)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 1)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 2)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 3))); # endif /* KLIPS_DIVULGE_HMAC_KEY */ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; /* save the pointer to the key material */ akp = ipsp->ips_key_a; aks = ipsp->ips_key_a_size; KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "allocating %lu bytes for sha1_ctx.\n", (unsigned long) sizeof(struct sha1_ctx)); if ((ipsp->ips_key_a = (caddr_t) kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { ipsp->ips_key_a = akp; SENDERR(ENOMEM); } ipsp->ips_key_a_size = sizeof(struct sha1_ctx); for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) kb[i] = akp[i] ^ HMAC_IPAD; for (; i < AHMD596_BLKLEN; i++) kb[i] = HMAC_IPAD; ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); SHA1Init(ictx); SHA1Update(ictx, kb, AHSHA196_BLKLEN); for (i = 0; i < AHSHA196_BLKLEN; i++) kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx); SHA1Init(octx); SHA1Update(octx, kb, AHSHA196_BLKLEN); # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ((__u32*)ictx)[0], ((__u32*)ictx)[1], ((__u32*)ictx)[2], ((__u32*)ictx)[3], ((__u32*)octx)[0], ((__u32*)octx)[1], ((__u32*)octx)[2], ((__u32*)octx)[3] ); # endif /* KLIPS_DIVULGE_HMAC_KEY */ /* zero key buffer -- paranoid */ memset(akp, 0, aks); kfree(akp); } break; # endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */ default: KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "authalg=%d support not available in the kernel", ipsp->ips_authalg); SENDERR(EINVAL); } #ifdef CONFIG_KLIPS_ALG /* closure of the -EPROTO condition above */ } #endif break; #endif /* CONFIG_KLIPS_AH */ #ifdef CONFIG_KLIPS_ESP case IPPROTO_ESP: ipsp->ips_xformfuncs = esp_xform_funcs; { #ifdef CONFIG_KLIPS_OCF if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, ipsp->ips_encalg)) break; #endif #ifdef CONFIG_KLIPS_ALG error = ipsec_alg_enc_key_create(ipsp); if (error < 0) SENDERR(-error); error = ipsec_alg_auth_key_create(ipsp); if ((error < 0) && (error != -EPROTO)) SENDERR(-error); if (error == -EPROTO) { /* perform manual key generation, ignore this particular error */ error = 0; #endif /* CONFIG_KLIPS_ALG */ switch (ipsp->ips_authalg) { #if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || \ defined (CONFIG_KLIPS_AUTH_HMAC_SHA1) unsigned char *akp; unsigned int aks; #endif # ifdef CONFIG_KLIPS_AUTH_HMAC_MD5 case AH_MD5: { MD5_CTX *ictx; MD5_CTX *octx; if (ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "incorrect authorisation key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/, ipsp->ips_key_bits_a, AHMD596_KLEN * 8); SENDERR(EINVAL); } # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT( debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "hmac md5-96 key is 0x%08x %08x %08x %08x\n", ntohl(*(((__u32 *)(ipsp->ips_key_a)) + 0)), ntohl(*(((__u32 *)(ipsp->ips_key_a)) + 1)), ntohl(*(((__u32 *)(ipsp->ips_key_a)) + 2)), ntohl(*(((__u32 *)(ipsp->ips_key_a)) + 3))); # endif /* KLIPS_DIVULGE_HMAC_KEY */ ipsp->ips_auth_bits = AHMD596_ALEN * 8; /* save the pointer to the key material */ akp = ipsp->ips_key_a; aks = ipsp->ips_key_a_size; KLIPS_PRINT( debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "allocating %lu bytes for md5_ctx.\n", (unsigned long) sizeof(struct md5_ctx)); if ((ipsp->ips_key_a = (caddr_t) kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { ipsp->ips_key_a = akp; SENDERR(ENOMEM); } ipsp->ips_key_a_size = sizeof(struct md5_ctx); for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) kb[i] = akp[i] ^ HMAC_IPAD; for (; i < AHMD596_BLKLEN; i++) kb[i] = HMAC_IPAD; ictx = &(((struct md5_ctx*)(ipsp->ips_key_a)) ->ictx); osMD5Init(ictx); osMD5Update(ictx, kb, AHMD596_BLKLEN); for (i = 0; i < AHMD596_BLKLEN; i++) kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); octx = &(((struct md5_ctx*)(ipsp->ips_key_a)) ->octx); osMD5Init(octx); osMD5Update(octx, kb, AHMD596_BLKLEN); # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT( debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ((__u32*)ictx)[0], ((__u32*)ictx)[1], ((__u32*)ictx)[2], ((__u32*)ictx)[3], ((__u32*)octx)[0], ((__u32*)octx)[1], ((__u32*)octx)[2], ((__u32*)octx)[3] ); # endif /* KLIPS_DIVULGE_HMAC_KEY */ /* paranoid */ memset(akp, 0, aks); kfree(akp); break; } # endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */ # ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1 case AH_SHA: { SHA1_CTX *ictx; SHA1_CTX *octx; if (ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "incorrect authorisation key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/, ipsp->ips_key_bits_a, AHSHA196_KLEN * 8); SENDERR(EINVAL); } # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT( debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", ntohl(*(((__u32 *)ipsp->ips_key_a) + 0)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 1)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 2)), ntohl(*(((__u32 *)ipsp->ips_key_a) + 3))); # endif /* KLIPS_DIVULGE_HMAC_KEY */ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; /* save the pointer to the key material */ akp = ipsp->ips_key_a; aks = ipsp->ips_key_a_size; KLIPS_PRINT( debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "allocating %lu bytes for sha1_ctx.\n", (unsigned long) sizeof(struct sha1_ctx)); if ((ipsp->ips_key_a = (caddr_t) kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { ipsp->ips_key_a = akp; SENDERR(ENOMEM); } ipsp->ips_key_a_size = sizeof(struct sha1_ctx); for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) kb[i] = akp[i] ^ HMAC_IPAD; for (; i < AHMD596_BLKLEN; i++) kb[i] = HMAC_IPAD; ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a)) ->ictx); SHA1Init(ictx); SHA1Update(ictx, kb, AHSHA196_BLKLEN); for (i = 0; i < AHSHA196_BLKLEN; i++) kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); octx = &((struct sha1_ctx*)(ipsp->ips_key_a)) ->octx; SHA1Init(octx); SHA1Update(octx, kb, AHSHA196_BLKLEN); # if KLIPS_DIVULGE_HMAC_KEY KLIPS_PRINT( debug_pfkey && sysctl_ipsec_debug_verbose, "ipsec_sa_init: " "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ((__u32*)ictx)[0], ((__u32*)ictx)[1], ((__u32*)ictx)[2], ((__u32*)ictx)[3], ((__u32*)octx)[0], ((__u32*)octx)[1], ((__u32*)octx)[2], ((__u32*)octx)[3] ); # endif /* KLIPS_DIVULGE_HMAC_KEY */ memset(akp, 0, aks); kfree(akp); break; } # endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */ case AH_NONE: break; default: KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "authalg=%d support not available in the kernel.\n", ipsp->ips_authalg); SENDERR(EINVAL); } #ifdef CONFIG_KLIPS_ALG /* closure of the -EPROTO condition above */ } #endif ipsp->ips_iv_size = ipsp->ips_alg_enc->ixt_common.ixt_support. ias_ivlen / 8; /* Create IV */ if (ipsp->ips_iv_size) { if ((ipsp->ips_iv = (caddr_t) kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) SENDERR(ENOMEM); prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, ipsp->ips_iv_size); ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; } } break; #endif /* !CONFIG_KLIPS_ESP */ #ifdef CONFIG_KLIPS_IPCOMP case IPPROTO_COMP: ipsp->ips_xformfuncs = ipcomp_xform_funcs; ipsp->ips_comp_adapt_tries = 0; ipsp->ips_comp_adapt_skip = 0; ipsp->ips_comp_ratio_cbytes = 0; ipsp->ips_comp_ratio_dbytes = 0; #ifdef CONFIG_KLIPS_OCF if (ipsec_ocf_comp_sa_init(ipsp, ipsp->ips_encalg)) break; #endif ipsp->ips_comp_adapt_tries = 0; ipsp->ips_comp_adapt_skip = 0; ipsp->ips_comp_ratio_cbytes = 0; ipsp->ips_comp_ratio_dbytes = 0; break; #endif /* CONFIG_KLIPS_IPCOMP */ default: printk(KERN_ERR "KLIPS sa initialization: " "proto=%d unknown.\n", ipsp->ips_said.proto); SENDERR(EINVAL); } errlab: return error; }
IPSEC_PROCFS_DEBUG_NO_STATIC int ipsec_spi_format(struct ipsec_sa *sa_p, struct seq_file *seq) { char sa[SATOT_BUF]; char buf_s[SUBNETTOA_BUF]; char buf_d[SUBNETTOA_BUF]; size_t sa_len; ipsec_sa_get(sa_p, IPSEC_REFPROC); sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa)); seq_printf(seq, "%s ", sa_len ? sa : " (error)"); seq_printf(seq, "%s%s%s", IPS_XFORM_NAME(sa_p)); seq_printf(seq, ": dir=%s", (sa_p->ips_flags & EMT_INBOUND) ? "in " : "out"); if (sa_p->ips_addr_s) { sin_addrtot(sa_p->ips_addr_s, 0, buf_s, sizeof(buf_s)); seq_printf(seq, " src=%s", buf_s); } if ((sa_p->ips_said.proto == IPPROTO_IPIP) && (sa_p->ips_flags & (SADB_X_SAFLAGS_INFLOW |SADB_X_SAFLAGS_POLICYONLY))) { if (sa_p->ips_flow_s.u.v4.sin_family == AF_INET) { subnettoa(sa_p->ips_flow_s.u.v4.sin_addr, sa_p->ips_mask_s.u.v4.sin_addr, 0, buf_s, sizeof(buf_s)); subnettoa(sa_p->ips_flow_d.u.v4.sin_addr, sa_p->ips_mask_d.u.v4.sin_addr, 0, buf_d, sizeof(buf_d)); } else { subnet6toa(&sa_p->ips_flow_s.u.v6.sin6_addr, &sa_p->ips_mask_s.u.v6.sin6_addr, 0, buf_s, sizeof(buf_s)); subnet6toa(&sa_p->ips_flow_d.u.v6.sin6_addr, &sa_p->ips_mask_d.u.v6.sin6_addr, 0, buf_d, sizeof(buf_d)); } seq_printf(seq, " policy=%s->%s", buf_s, buf_d); } if (sa_p->ips_iv_bits) { int j; seq_printf(seq, " iv_bits=%dbits iv=0x", sa_p->ips_iv_bits); for (j = 0; j < sa_p->ips_iv_bits / 8; j++) { #ifdef CONFIG_KLIPS_OCF if (sa_p->ips_iv == NULL) { /* * ocf doesn't set the IV * so fake it for the test cases */ seq_printf(seq, "%02x", 0xA5 + j); } else #endif seq_printf(seq, "%02x", ((__u8*)sa_p->ips_iv)[j]); } } if (sa_p->ips_encalg || sa_p->ips_authalg) { if (sa_p->ips_replaywin) seq_printf(seq, " ooowin=%d", sa_p->ips_replaywin); if (sa_p->ips_errs.ips_replaywin_errs) seq_printf(seq, " ooo_errs=%d", sa_p->ips_errs.ips_replaywin_errs); if (sa_p->ips_replaywin_lastseq) seq_printf(seq, " seq=%d", sa_p->ips_replaywin_lastseq); if (sa_p->ips_replaywin_bitmap) seq_printf(seq, " bit=0x%Lx", sa_p->ips_replaywin_bitmap); if (sa_p->ips_replaywin_maxdiff) seq_printf(seq, " max_seq_diff=%d", sa_p->ips_replaywin_maxdiff); } if (sa_p->ips_flags & ~EMT_INBOUND) { seq_printf(seq, " flags=0x%x", sa_p->ips_flags & ~EMT_INBOUND); seq_printf(seq, "<"); /* flag printing goes here */ seq_printf(seq, ">"); } if (sa_p->ips_auth_bits) seq_printf(seq, " alen=%d", sa_p->ips_auth_bits); if (sa_p->ips_key_bits_a) seq_printf(seq, " aklen=%d", sa_p->ips_key_bits_a); if (sa_p->ips_errs.ips_auth_errs) seq_printf(seq, " auth_errs=%d", sa_p->ips_errs.ips_auth_errs); if (sa_p->ips_key_bits_e) seq_printf(seq, " eklen=%d", sa_p->ips_key_bits_e); if (sa_p->ips_errs.ips_encsize_errs) seq_printf(seq, " encr_size_errs=%d", sa_p->ips_errs.ips_encsize_errs); if (sa_p->ips_errs.ips_encpad_errs) seq_printf(seq, " encr_pad_errs=%d", sa_p->ips_errs.ips_encpad_errs); seq_printf(seq, " jiffies=%lu", jiffies); seq_printf(seq, " life(c,s,h)="); ipsec_lifetime_format(seq, "alloc", ipsec_life_countbased, &sa_p->ips_life.ipl_allocations); ipsec_lifetime_format(seq, "bytes", ipsec_life_countbased, &sa_p->ips_life.ipl_bytes); ipsec_lifetime_format(seq, "addtime", ipsec_life_timebased, &sa_p->ips_life.ipl_addtime); ipsec_lifetime_format(seq, "usetime", ipsec_life_timebased, &sa_p->ips_life.ipl_usetime); ipsec_lifetime_format(seq, "packets", ipsec_life_countbased, &sa_p->ips_life.ipl_packets); if (sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */ seq_printf(seq, " idle=%Ld", ipsec_jiffieshz_elapsed(jiffies/HZ, sa_p->ips_life.ipl_usetime.ipl_last)); } #ifdef CONFIG_KLIPS_IPCOMP if (sa_p->ips_said.proto == IPPROTO_COMP && (sa_p->ips_comp_ratio_dbytes || sa_p->ips_comp_ratio_cbytes)) { seq_printf(seq, " ratio=%Ld:%Ld", sa_p->ips_comp_ratio_dbytes, sa_p->ips_comp_ratio_cbytes); } #endif /* CONFIG_KLIPS_IPCOMP */ seq_printf(seq, " natencap="); switch (sa_p->ips_natt_type) { case 0: seq_printf(seq, "none"); break; case ESPINUDP_WITH_NON_IKE: seq_printf(seq, "nonike"); break; case ESPINUDP_WITH_NON_ESP: seq_printf(seq, "nonesp"); break; default: seq_printf(seq, "unknown"); break; } seq_printf(seq, " natsport=%d", sa_p->ips_natt_sport); seq_printf(seq, " natdport=%d", sa_p->ips_natt_dport); /* we decrement by one, because this SA has been referenced in order to dump this info */ seq_printf(seq, " refcount=%d", atomic_read(&sa_p->ips_refcount)-1); #ifdef IPSEC_SA_RECOUNT_DEBUG { int f; seq_printf(seq, "["); for (f = 0; f < sizeof(sa_p->ips_track); f++) seq_printf(seq, "%s%d", f == 0 ? "" : ",", sa_p->ips_track[f]); seq_printf(seq, "]"); } #endif seq_printf(seq, " ref=%d", sa_p->ips_ref); seq_printf(seq, " refhim=%d", sa_p->ips_refhim); if (sa_p->ips_out) { seq_printf(seq, " outif=%s:%d", sa_p->ips_out->name, sa_p->ips_transport_direct); } if (debug_xform) { seq_printf(seq, " reftable=%lu refentry=%lu", (unsigned long)IPsecSAref2table(sa_p->ips_ref), (unsigned long)IPsecSAref2entry(sa_p->ips_ref)); } seq_printf(seq, "\n"); ipsec_sa_put(sa_p, IPSEC_REFPROC); return 0; }