static void emit_lifetime(const char *extname, uint16_t exttype, struct sadb_ext *extensions[K_SADB_EXT_MAX + 1], char *lo[life_maxtype], u_int32_t l[life_maxtype]) { if (lo[life_alloc] != NULL || lo[life_bytes] != NULL || lo[life_addtime] != NULL || lo[life_usetime] != NULL || lo[life_packets] != NULL) { int error = pfkey_lifetime_build( &extensions[exttype], exttype, l[life_alloc], l[life_bytes], l[life_addtime], l[life_usetime], l[life_packets]); if (error != 0) { fprintf(stderr, "%s: Trouble building %s extension, error=%d.\n", progname, extname, error); pfkey_extensions_free(extensions); exit(1); } if (debug) { fprintf(stdout, "%s: %s extension assembled.\n", progname, extname); } } }
int lifetime_to_sadb_lifetime(struct sa_lifetime *lifetime, struct sadb_lifetime *ext_msg, int type) { int error = 0; if ( !(lifetime&&ext_msg) ) { PFKEY_DEBUG("param is null\n"); error = -EINVAL; goto err; } error = pfkey_lifetime_build((struct sadb_ext**)&ext_msg, type, lifetime->allocations, lifetime->bytes, lifetime->addtime, lifetime->usetime); err: return error; }
int sadb_msg_send_expire(struct ipsec_sa *sa) { int i=0, error = 0; struct sadb_msg *msg = NULL; struct sadb_ext *ext_msgs[SADB_EXT_MAX+1]; struct socket_list *pfkey_socketsp = NULL; if (!sa) { PFKEY_DEBUG("sa is null\n"); return -EINVAL; } memset(ext_msgs, 0, sizeof(ext_msgs)); error = pfkey_msg_hdr_build(&ext_msgs[0], SADB_EXPIRE, sa->ipsec_proto, 0, 0, 0); if (error) { PFKEY_DEBUG("pfkey_msg_hdr_build is failed\n"); goto free_ext_finish; } error = pfkey_sa_build(&ext_msgs[SADB_EXT_SA], SADB_EXT_SA, sa->spi, 64, sa->state, sa->auth_algo.algo, sa->esp_algo.algo, 0); /* TODO: add pfs flag to struct ipsec_sa */ if (error) { PFKEY_DEBUG("pfkey_sa_build is failed\n"); goto free_ext_finish; } error = pfkey_lifetime_build(&ext_msgs[SADB_EXT_LIFETIME_CURRENT], SADB_EXT_LIFETIME_CURRENT, sa->lifetime_c.allocations, sa->lifetime_c.bytes, sa->lifetime_c.addtime, sa->lifetime_c.usetime); if (error) { PFKEY_DEBUG("pfkey_lifetime_build is failed\n"); goto free_ext_finish; } switch(sa->state) { case SADB_SASTATE_DEAD: error = pfkey_lifetime_build(&ext_msgs[SADB_EXT_LIFETIME_HARD], SADB_EXT_LIFETIME_HARD, sa->lifetime_h.allocations, sa->lifetime_h.bytes, sa->lifetime_h.addtime, sa->lifetime_h.usetime); if (error) { PFKEY_DEBUG("pfkey_liftime_build(hard) is failed\n"); goto free_ext_finish; } break; case SADB_SASTATE_DYING: error = pfkey_lifetime_build(&ext_msgs[SADB_EXT_LIFETIME_SOFT], SADB_EXT_LIFETIME_SOFT, sa->lifetime_s.allocations, sa->lifetime_s.bytes, sa->lifetime_s.addtime, sa->lifetime_s.usetime); if (error) { PFKEY_DEBUG("pfkey_lifetime_build(soft) is failed\n"); goto free_ext_finish; } break; case SADB_SASTATE_LARVAL: case SADB_SASTATE_MATURE: default: error = -EINVAL; goto free_ext_finish; } error = pfkey_address_build(&ext_msgs[SADB_EXT_ADDRESS_SRC], SADB_EXT_ADDRESS_SRC, sa->proto, sa->prefixlen_s, (struct sockaddr*)&sa->src); if (error) goto free_ext_finish; error = pfkey_address_build(&ext_msgs[SADB_EXT_ADDRESS_DST], SADB_EXT_ADDRESS_DST, sa->proto, sa->prefixlen_d, (struct sockaddr*)&sa->dst); if (error) goto free_ext_finish; error = pfkey_msg_build(&msg, ext_msgs, EXT_BITS_OUT); write_lock(&pfkey_sk_lock); for (pfkey_socketsp = pfkey_open_sockets; pfkey_socketsp; pfkey_socketsp = pfkey_socketsp->next) { pfkey_upmsg(pfkey_socketsp->socketp, msg); } write_unlock(&pfkey_sk_lock); kfree(msg); free_ext_finish: for(i=0; i<SADB_MAX+1; i++) { if (ext_msgs[i]) { kfree(ext_msgs[i]); } } return 0; }