/* Processs a SADB_ACQUIRE message from KLIPS. * Try to build an opportunistic connection! * See RFC 2367 "PF_KEY Key Management API, Version 2" 3.1.6 * <base, address(SD), (address(P)), (identity(SD),) (sensitivity,) proposal> * - extensions for source and data IP addresses * - optional extensions for identity [not useful for us?] * - optional extension for sensitivity [not useful for us?] * - expension for proposal [not useful for us?] * * ??? We must use the sequence number in creating an SA. * We actually need to create up to 4 SAs each way. Which one? * I guess it depends on the protocol present in the sadb_msg_satype. * For now, we'll ignore this requirement. * * ??? We need some mechanism to make sure that multiple ACQUIRE messages * don't cause a whole bunch of redundant negotiations. */ static void process_pfkey_acquire(pfkey_buf *buf, struct sadb_ext *extensions[SADB_EXT_MAX + 1]) { struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC]; struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST]; int src_proto = srcx->sadb_address_proto; int dst_proto = dstx->sadb_address_proto; ip_address *src = (ip_address*)&srcx[1]; ip_address *dst = (ip_address*)&dstx[1]; ip_subnet ours, his; err_t ugh = NULL; /* assumption: we're only catching our own outgoing packets * so source is our end and destination is the other end. * Verifying this is not actually convenient. * * This stylized control structure yields a complaint or * desired results. For compactness, a pointer value is * treated as a boolean. Logically, the structure is: * keep going as long as things are OK. */ if (buf->msg.sadb_msg_pid == 0 /* we only wish to hear from kernel */ && !(ugh = src_proto == dst_proto? NULL : "src and dst protocols differ") && !(ugh = addrtypeof(src) == addrtypeof(dst)? NULL : "conflicting address types") && !(ugh = addrtosubnet(src, &ours)) && !(ugh = addrtosubnet(dst, &his))) record_and_initiate_opportunistic(&ours, &his, 0, "%acquire-pfkey"); if (ugh != NULL) plog("SADB_ACQUIRE message from KLIPS malformed: %s", ugh); }
/* asynchronous messages from our queue */ static void pfkey_dequeue(void) { while (pfkey_iq_head != NULL) { pfkey_item *it = pfkey_iq_head; pfkey_async(&it->buf); pfkey_iq_head = it->next; pfree(it); } /* Handle any orphaned holds, but only if no pfkey input is pending. * For each, we initiate Opportunistic. * note: we don't need to advance the pointer because * record_and_initiate_opportunistic will remove the current * 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"); }
static void netlink_acquire(struct nlmsghdr *n) { struct xfrm_user_acquire *acquire; const xfrm_address_t *srcx, *dstx; int src_proto, dst_proto; ip_address src, dst; ip_subnet ours, his; unsigned family; unsigned transport_proto; err_t ugh = NULL; if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire))) { openswan_log("netlink_acquire got message with length %lu < %lu bytes; ignore message" , (unsigned long) n->nlmsg_len , (unsigned long) sizeof(*acquire)); return; } acquire = NLMSG_DATA(n); srcx = &acquire->sel.saddr; dstx = &acquire->sel.daddr; family = acquire->policy.sel.family; transport_proto = acquire->sel.proto; src_proto = 0; /* XXX-MCR where to get protocol from? */ dst_proto = 0; /* ditto */ /* XXX also the type of src/dst should be checked to make sure * that they aren't v4 to v6 or something goofy */ if (!(ugh = xfrm_to_ip_address(family, srcx, &src)) && !(ugh = xfrm_to_ip_address(family, dstx, &dst)) && !(ugh = src_proto == dst_proto? NULL : "src and dst protocols differ") && !(ugh = addrtosubnet(&src, &ours)) && !(ugh = addrtosubnet(&dst, &his))) record_and_initiate_opportunistic(&ours, &his, transport_proto , "%acquire-netlink"); if (ugh != NULL) openswan_log("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh); }