📄 kernel_pfkey.c
字号:
* record each time we call it. */ while (orphaned_holds != NULL && !pfkey_input_ready()) record_and_initiate_opportunistic(&orphaned_holds->ours , &orphaned_holds->his , orphaned_holds->transport_proto , "%hold found-pfkey");}/* asynchronous messages directly from PF_KEY socket */static voidpfkey_event(void){ pfkey_buf buf; if (pfkey_get(&buf)) pfkey_async(&buf);}static boolpfkey_build(int error, const char *description, const char *text_said, struct sadb_ext *extensions[SADB_EXT_MAX + 1]){ if (error == 0) { return TRUE; } else { loglog(RC_LOG_SERIOUS, "building of %s %s failed, code %d" , description, text_said, error); pfkey_extensions_free(extensions); return FALSE; }}/* pfkey_extensions_init + pfkey_build + pfkey_msg_hdr_build */static boolpfkey_msg_start(u_int8_t msg_type, u_int8_t satype, const char *description, const char *text_said, struct sadb_ext *extensions[SADB_EXT_MAX + 1]){ pfkey_extensions_init(extensions); return pfkey_build(pfkey_msg_hdr_build(&extensions[0], msg_type , satype, 0, ++pfkey_seq, pid) , description, text_said, extensions);}/* pfkey_build + pfkey_address_build */static boolpfkeyext_address(u_int16_t exttype, const ip_address *address, const char *description, const char *text_said, struct sadb_ext *extensions[SADB_EXT_MAX + 1]){ /* the following variable is only needed to silence * a warning caused by the fact that the argument * to sockaddrof is NOT pointer to const! */ ip_address t = *address; return pfkey_build(pfkey_address_build(extensions + exttype , exttype, 0, 0, sockaddrof(&t)) , description, text_said, extensions);}/* pfkey_build + pfkey_x_protocol_build */static boolpfkeyext_protocol(int transport_proto, const char *description, const char *text_said, struct sadb_ext *extensions[SADB_EXT_MAX + 1]){ return (transport_proto == 0) ? TRUE : pfkey_build(pfkey_x_protocol_build(extensions + SADB_X_EXT_PROTOCOL, transport_proto), description, text_said, extensions);}/* Finish (building, sending, accepting response for) PF_KEY message. * If response isn't NULL, the response from the kernel will be * placed there (and its errno field will not be examined). * Returns TRUE iff all appears well. */static boolfinish_pfkey_msg(struct sadb_ext *extensions[SADB_EXT_MAX + 1], const char *description, const char *text_said, pfkey_buf *response){ struct sadb_msg *pfkey_msg; bool success = TRUE; int error; error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN); if (error != 0) { loglog(RC_LOG_SERIOUS, "pfkey_msg_build of %s %s failed, code %d" , description, text_said, error); success = FALSE; } else { size_t len = pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN; DBG(DBG_KLIPS, DBG_log("finish_pfkey_msg: %s message %u for %s %s" , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type) , pfkey_msg->sadb_msg_seq , description, text_said); DBG_dump(NULL, (void *) pfkey_msg, len)); if (!no_klips) { ssize_t r = write(pfkeyfd, pfkey_msg, len); if (r != (ssize_t)len) { if (r < 0) { log_errno((e , "pfkey write() of %s message %u" " for %s %s failed" , sparse_val_show(pfkey_type_names , pfkey_msg->sadb_msg_type) , pfkey_msg->sadb_msg_seq , description, text_said)); } else { loglog(RC_LOG_SERIOUS , "ERROR: pfkey write() of %s message %u" " for %s %s truncated: %ld instead of %ld" , sparse_val_show(pfkey_type_names , pfkey_msg->sadb_msg_type) , pfkey_msg->sadb_msg_seq , description, text_said , (long)r, (long)len); } success = FALSE; /* if we were compiled with debugging, but we haven't already * dumped the KLIPS command, do so. */#ifdef DEBUG if ((cur_debugging & DBG_KLIPS) == 0) DBG_dump(NULL, (void *) pfkey_msg, len);#endif } else { /* Check response from KLIPS. * It ought to be an echo, perhaps with additional info. * If the caller wants it, response will point to space. */ pfkey_buf b; pfkey_buf *bp = response != NULL? response : &b; if (!pfkey_get_response(bp, ((struct sadb_msg *) extensions[0])->sadb_msg_seq)) { loglog(RC_LOG_SERIOUS , "ERROR: no response to our PF_KEY %s message for %s %s" , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type) , description, text_said); success = FALSE; } else if (pfkey_msg->sadb_msg_type != bp->msg.sadb_msg_type) { loglog(RC_LOG_SERIOUS , "FreeS/WAN ERROR: response to our PF_KEY %s message for %s %s was of wrong type (%s)" , sparse_name(pfkey_type_names, pfkey_msg->sadb_msg_type) , description, text_said , sparse_val_show(pfkey_type_names, bp->msg.sadb_msg_type)); success = FALSE; } else if (response == NULL && bp->msg.sadb_msg_errno != 0) { /* KLIPS is signalling a problem */ loglog(RC_LOG_SERIOUS , "ERROR: PF_KEY %s response for %s %s included errno %u: %s" , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type) , description, text_said , (unsigned) bp->msg.sadb_msg_errno , strerror(bp->msg.sadb_msg_errno)); success = FALSE; } } } } /* all paths must exit this way to free resources */ pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); return success;}/* register SA types that can be negotiated */voidpfkey_register_proto(unsigned satype, const char *satypename){ struct sadb_ext *extensions[SADB_EXT_MAX + 1]; pfkey_buf pfb; if (!(pfkey_msg_start(SADB_REGISTER , satype , satypename, NULL, extensions) && finish_pfkey_msg(extensions, satypename, "", &pfb))) { /* ??? should this be loglog */ plog("no KLIPS support for %s", satypename); } else { kernel_ops->pfkey_register_response(&pfb.msg); DBG(DBG_KLIPS, DBG_log("%s registered with kernel.", satypename)); }}static voidklips_pfkey_register(void){ pfkey_register_proto(SADB_SATYPE_AH, "AH"); pfkey_register_proto(SADB_SATYPE_ESP, "ESP"); can_do_IPcomp = FALSE; /* until we get a response from KLIPS */ pfkey_register_proto(SADB_X_SATYPE_COMP, "IPCOMP"); pfkey_register_proto(SADB_X_SATYPE_IPIP, "IPIP");}static boolpfkey_raw_eroute(const ip_address *this_host , const ip_subnet *this_client , const ip_address *that_host , const ip_subnet *that_client , ipsec_spi_t spi , unsigned int proto UNUSED , unsigned int transport_proto , unsigned int satype , const struct pfkey_proto_info *proto_info UNUSED , time_t use_lifetime UNUSED , unsigned int op , const char *text_said){ struct sadb_ext *extensions[SADB_EXT_MAX + 1]; ip_address sflow_ska, dflow_ska, smask_ska, dmask_ska; int sport = ntohs(portof(&this_client->addr)); int dport = ntohs(portof(&that_client->addr)); networkof(this_client, &sflow_ska); maskof(this_client, &smask_ska); setportof(sport ? ~0:0, &smask_ska); networkof(that_client, &dflow_ska); maskof(that_client, &dmask_ska); setportof(dport ? ~0:0, &dmask_ska); if (!pfkey_msg_start(op & ERO_MASK, satype , "pfkey_msg_hdr flow", text_said, extensions)) { return FALSE; } if (op != ERO_DELETE) { if (!(pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA] , SADB_EXT_SA , spi /* in network order */ , 0, 0, 0, 0, op >> ERO_FLAG_SHIFT) , "pfkey_sa add flow", text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_SRC, this_host , "pfkey_addr_s add flow", text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_DST, that_host , "pfkey_addr_d add flow", text_said , extensions))) { return FALSE; } } if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_FLOW, &sflow_ska , "pfkey_addr_sflow", text_said, extensions)) { return FALSE; } if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_FLOW, &dflow_ska , "pfkey_addr_dflow", text_said, extensions)) { return FALSE; } if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_MASK, &smask_ska , "pfkey_addr_smask", text_said, extensions)) { return FALSE; } if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_MASK, &dmask_ska , "pfkey_addr_dmask", text_said, extensions)) { return FALSE; } if (!pfkeyext_protocol(transport_proto , "pfkey_x_protocol", text_said, extensions)) { return FALSE; } return finish_pfkey_msg(extensions, "flow", text_said, NULL);}static boolpfkey_add_sa(const struct kernel_sa *sa, bool replace){ struct sadb_ext *extensions[SADB_EXT_MAX + 1]; return pfkey_msg_start(replace ? SADB_UPDATE : SADB_ADD, sa->satype , "pfkey_msg_hdr Add SA", sa->text_said, extensions) && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA] , SADB_EXT_SA , sa->spi /* in network order */ , sa->replay_window, SADB_SASTATE_MATURE , sa->authalg, sa->encalg, 0) , "pfkey_sa Add SA", sa->text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src , "pfkey_addr_s Add SA", sa->text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst , "pfkey_addr_d Add SA", sa->text_said, extensions) && (sa->authkeylen == 0 || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_AUTH] , SADB_EXT_KEY_AUTH, sa->authkeylen * BITS_PER_BYTE , sa->authkey) , "pfkey_key_a Add SA", sa->text_said, extensions)) && (sa->enckeylen == 0 || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_ENCRYPT] , SADB_EXT_KEY_ENCRYPT, sa->enckeylen * BITS_PER_BYTE , sa->enckey) , "pfkey_key_e Add SA", sa->text_said, extensions))#ifdef NAT_TRAVERSAL && (sa->natt_type == 0 || pfkey_build(pfkey_x_nat_t_type_build( &extensions[SADB_X_EXT_NAT_T_TYPE], sa->natt_type), "pfkey_nat_t_type Add ESP SA", sa->text_said, extensions)) && (sa->natt_sport == 0 || pfkey_build(pfkey_x_nat_t_port_build( &extensions[SADB_X_EXT_NAT_T_SPORT], SADB_X_EXT_NAT_T_SPORT, sa->natt_sport), "pfkey_nat_t_sport Add ESP SA", sa->text_said, extensions)) && (sa->natt_dport == 0 || pfkey_build(pfkey_x_nat_t_port_build( &extensions[SADB_X_EXT_NAT_T_DPORT], SADB_X_EXT_NAT_T_DPORT, sa->natt_dport), "pfkey_nat_t_dport Add ESP SA", sa->text_said, extensions)) && (sa->natt_type ==0 || isanyaddr(sa->natt_oa) || pfkeyext_address(SADB_X_EXT_NAT_T_OA, sa->natt_oa , "pfkey_nat_t_oa Add ESP SA", sa->text_said, extensions))#endif && finish_pfkey_msg(extensions, "Add SA", sa->text_said, NULL);}static boolpfkey_grp_sa(const struct kernel_sa *sa0, const struct kernel_sa *sa1){ struct sadb_ext *extensions[SADB_EXT_MAX + 1]; return pfkey_msg_start(SADB_X_GRPSA, sa1->satype , "pfkey_msg_hdr group", sa1->text_said, extensions) && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA] , SADB_EXT_SA , sa1->spi /* in network order */ , 0, 0, 0, 0, 0) , "pfkey_sa group", sa1->text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa1->dst , "pfkey_addr_d group", sa1->text_said, extensions) && pfkey_build(pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2] , sa0->satype) , "pfkey_satype group", sa0->text_said, extensions) && pfkey_build(pfkey_sa_build(&extensions[SADB_X_EXT_SA2] , SADB_X_EXT_SA2 , sa0->spi /* in network order */ , 0, 0, 0, 0, 0) , "pfkey_sa2 group", sa0->text_said, extensions) && pfkeyext_address(SADB_X_EXT_ADDRESS_DST2, sa0->dst , "pfkey_addr_d2 group", sa0->text_said, extensions) && finish_pfkey_msg(extensions, "group", sa1->text_said, NULL);}static boolpfkey_del_sa(const struct kernel_sa *sa){ struct sadb_ext *extensions[SADB_EXT_MAX + 1]; return pfkey_msg_start(SADB_DELETE, proto2satype(sa->proto) , "pfkey_msg_hdr delete SA", sa->text_said, extensions) && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA] , SADB_EXT_SA , sa->spi /* in host order */ , 0, SADB_SASTATE_MATURE, 0, 0, 0) , "pfkey_sa delete SA", sa->text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src , "pfkey_addr_s delete SA", sa->text_said, extensions) && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst , "pfkey_addr_d delete SA", sa->text_said, extensions) && finish_pfkey_msg(extensions, "Delete SA", sa->text_said, NULL);}voidpfkey_close(void){ while (pfkey_iq_head != NULL) { pfkey_item *it = pfkey_iq_head; pfkey_iq_head = it->next; pfree(it); } close(pfkeyfd); pfkeyfd = NULL_FD;}const struct kernel_ops klips_kernel_ops = { type: KERNEL_TYPE_KLIPS, async_fdp: &pfkeyfd, pfkey_register: klips_pfkey_register, pfkey_register_response: klips_pfkey_register_response, process_queue: pfkey_dequeue, process_msg: pfkey_event, raw_eroute: pfkey_raw_eroute, add_sa: pfkey_add_sa, grp_sa: pfkey_grp_sa, del_sa: pfkey_del_sa, get_spi: NULL, inbound_eroute: FALSE, policy_lifetime: FALSE, init: NULL};#endif /* KLIPS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -