📄 pfkey_v2_parser.c
字号:
struct ipsec_sa *ips1p, *ips2p, *ipsp; struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; struct sadb_msg *pfkey_reply = NULL; struct socket_list *pfkey_socketsp; uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; char sa1[SATOT_BUF], sa2[SATOT_BUF]; size_t sa_len1, sa_len2 = 0; int error = 0; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: .\n"); pfkey_extensions_init(extensions_reply); if(extr == NULL || extr->ips == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "extr or extr->ips is NULL, fatal.\n"); SENDERR(EINVAL); } sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1)); if(extr->ips2 != NULL) { sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2)); } spin_lock_bh(&tdb_lock); ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said)); if(ips1p == NULL) { spin_unlock_bh(&tdb_lock); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n", sa_len1 ? sa1 : " (error)"); SENDERR(ENOENT); } if(extr->ips2) { /* GRPSA */ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said)); if(ips2p == NULL) { ipsec_sa_put(ips1p); spin_unlock_bh(&tdb_lock); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n", sa_len2 ? sa2 : " (error)"); SENDERR(ENOENT); } /* Is either one already linked? */ if(ips1p->ips_onext) { ipsec_sa_put(ips1p); ipsec_sa_put(ips2p); spin_unlock_bh(&tdb_lock); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "ipsec_sa for SA: %s is already linked.\n", sa_len1 ? sa1 : " (error)"); SENDERR(EEXIST); } if(ips2p->ips_inext) { ipsec_sa_put(ips1p); ipsec_sa_put(ips2p); spin_unlock_bh(&tdb_lock); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "ipsec_sa for SA: %s is already linked.\n", sa_len2 ? sa2 : " (error)"); SENDERR(EEXIST); } /* Is extr->ips already linked to extr->ips2? */ ipsp = ips2p; while(ipsp) { if(ipsp == ips1p) { ipsec_sa_put(ips1p); ipsec_sa_put(ips2p); spin_unlock_bh(&tdb_lock); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "ipsec_sa for SA: %s is already linked to %s.\n", sa_len1 ? sa1 : " (error)", sa_len2 ? sa2 : " (error)"); SENDERR(EEXIST); } ipsp = ipsp->ips_onext; } /* link 'em */ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "linking ipsec_sa SA: %s with %s.\n", sa_len1 ? sa1 : " (error)", sa_len2 ? sa2 : " (error)"); ips1p->ips_onext = ips2p; ips2p->ips_inext = ips1p; } else { /* UNGRPSA */ ipsec_sa_put(ips1p); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "unlinking ipsec_sa SA: %s.\n", sa_len1 ? sa1 : " (error)"); while(ips1p->ips_onext) { ips1p = ips1p->ips_onext; } while(ips1p->ips_inext) { ipsp = ips1p; ips1p = ips1p->ips_inext; ipsec_sa_put(ips1p); ipsp->ips_inext = NULL; ipsec_sa_put(ipsp); ips1p->ips_onext = NULL; } } spin_unlock_bh(&tdb_lock); if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], SADB_X_GRPSA, satype, 0, ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), extensions_reply) && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], SADB_EXT_SA, extr->ips->ips_said.spi, extr->ips->ips_replaywin, extr->ips->ips_state, extr->ips->ips_authalg, extr->ips->ips_encalg, extr->ips->ips_flags, extr->ips->ips_ref), extensions_reply) && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], SADB_EXT_ADDRESS_DST, 0, /*extr->ips->ips_said.proto,*/ 0, extr->ips->ips_addr_d), extensions_reply) && (extr->ips2 ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2], ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype /* proto2satype(extr->ips2->ips_said.proto) */), extensions_reply) && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2], SADB_X_EXT_SA2, extr->ips2->ips_said.spi, extr->ips2->ips_replaywin, extr->ips2->ips_state, extr->ips2->ips_authalg, extr->ips2->ips_encalg, extr->ips2->ips_flags, extr->ips2->ips_ref), extensions_reply) && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2], SADB_X_EXT_ADDRESS_DST2, 0, /*extr->ips->ips_said.proto,*/ 0, extr->ips2->ips_addr_d), extensions_reply) ) : 1 ) )) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "failed to build the x_grpsa reply message extensions\n"); SENDERR(-error); } if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "failed to build the x_grpsa reply message\n"); SENDERR(-error); } for(pfkey_socketsp = pfkey_open_sockets; pfkey_socketsp; pfkey_socketsp = pfkey_socketsp->next) { if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", satype, satype2name(satype), pfkey_socketsp->socketp, error); SENDERR(-error); } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n", satype, satype2name(satype), pfkey_socketsp->socketp); } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " "succeeded in sending x_grpsa reply message.\n"); errlab: if (pfkey_reply) { pfkey_msg_free(&pfkey_reply); } pfkey_extensions_free(extensions_reply); return error;}DEBUG_NO_STATIC intpfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr){ int error = 0;#ifdef CONFIG_KLIPS_DEBUG char buf1[64], buf2[64];#endif /* CONFIG_KLIPS_DEBUG */ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; struct sadb_msg *pfkey_reply = NULL; struct socket_list *pfkey_socketsp; uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ip_address srcflow, dstflow, srcmask, dstmask; KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: .\n"); pfkey_extensions_init(extensions_reply); memset((caddr_t)&srcflow, 0, sizeof(srcflow)); memset((caddr_t)&dstflow, 0, sizeof(dstflow)); memset((caddr_t)&srcmask, 0, sizeof(srcmask)); memset((caddr_t)&dstmask, 0, sizeof(dstmask)); if(!extr || !(extr->ips) || !(extr->eroute)) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "missing extr, ipsec_sa or eroute data.\n"); SENDERR(EINVAL); } srcflow.u.v4.sin_family = AF_INET; dstflow.u.v4.sin_family = AF_INET; srcmask.u.v4.sin_family = AF_INET; dstmask.u.v4.sin_family = AF_INET; srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;#ifdef CONFIG_KLIPS_DEBUG if (debug_pfkey) { subnettoa(extr->eroute->er_eaddr.sen_ip_src, extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); subnettoa(extr->eroute->er_eaddr.sen_ip_dst, extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "calling breakeroute and/or makeroute for %s->%s\n", buf1, buf2); }#endif /* CONFIG_KLIPS_DEBUG */ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */ struct ipsec_sa *ipsp, *ipsq; char sa[SATOT_BUF]; size_t sa_len; ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); if(ipsq == NULL) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "ipsec_sa not found, cannot set incoming policy.\n"); SENDERR(ENOENT); } ipsp = ipsq; while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) { ipsp = ipsp->ips_inext; } if(ipsp == NULL) { ipsec_sa_put(ipsq); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "SA chain does not have an IPIP SA, cannot set incoming policy.\n"); SENDERR(ENOENT); } sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW; ipsp->ips_flow_s = srcflow; ipsp->ips_flow_d = dstflow; ipsp->ips_mask_s = srcmask; ipsp->ips_mask_d = dstmask; ipsec_sa_put(ipsq); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n", sa_len ? sa : " (error)"); } else { struct sk_buff *first = NULL, *last = NULL; if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "REPLACEFLOW flag set, calling breakeroute.\n"); if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr), &(extr->eroute->er_emask), &first, &last))) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "breakeroute returned %d. first=0p%p, last=0p%p\n", error, first, last); if(first != NULL) { ipsec_kfree_skb(first); } if(last != NULL) { ipsec_kfree_skb(last); } SENDERR(-error); } } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "calling makeroute.\n"); if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr), &(extr->eroute->er_emask), extr->ips->ips_said, ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid, NULL, &(extr->ips->ips_ident_s), &(extr->ips->ips_ident_d)))) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "makeroute returned %d.\n", error); SENDERR(-error); } if(first != NULL) { KLIPS_PRINT(debug_eroute, "klips_debug:pfkey_x_addflow_parse: " "first=0p%p HOLD packet re-injected.\n", first); DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL); } if(last != NULL) { KLIPS_PRINT(debug_eroute, "klips_debug:pfkey_x_addflow_parse: " "last=0p%p HOLD packet re-injected.\n", last); DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL); } } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " "makeroute call successful.\n"); if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], SADB_X_ADDFLOW, satype, 0, ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), extensions_reply) && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], SADB_EXT_SA, extr->ips->ips_said.spi, extr->ips->ips_replaywin, extr->ips->ips_state, extr->ips->ips_authalg, extr->ips->ips_encalg, extr->ips->ips_flags, extr->ips->ips_ref), extensions_reply) && (extensions[SADB_EXT_ADDRESS_SRC] ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], SADB_EXT_ADDRESS_SRC, 0, /*extr->ips->ips_said.proto,*/ 0, extr->ips->ips_addr_s), extensions_reply) : 1) && (extensions[SADB_EXT_ADDRESS_DST] ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], SADB_EXT_ADDRESS_DST, 0, /*extr->ips->ips_said.proto,*/ 0, extr->ips->ips_addr_d), extensions_reply) : 1) && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], SADB_X_EXT_ADDRESS_SRC_FLOW, 0, /*extr->ips->ips_said.proto,*/ 0, (struct sockaddr*)&srcflow), extensio
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -