diff -Nur racoon2-20070817cvs/iked/ikev2_payload.c racoon2-patched/iked/ikev2_payload.c --- racoon2-20070817cvs/iked/ikev2_payload.c 2007-08-17 10:57:42.000000000 +0900 +++ racoon2-patched/iked/ikev2_payload.c 2007-08-17 11:52:12.000000000 +0900 @@ -783,15 +783,20 @@ /* * encode special upper layer protocol selector into port */ +enum local_remote { + LOCAL, + REMOTE +}; enum start_end { START, END }; static u_int32_t -ulpsel2port(enum start_end which, struct rcf_selector *s) +ulpsel2port(enum local_remote which_side, enum start_end which_port, struct rcf_selector *s) { u_int32_t port; + struct rc_addrlist * al; switch (s->upper_layer_protocol) { case IPPROTO_ICMP: @@ -807,14 +812,14 @@ */ if (s->src->port != RC_PORT_ANY) port = s->src->port << 8; - else if (which == START) + else if (which_port == START) port = 0x0000; else port = 0xFF00; port &= 0xff00; if (s->dst->port != RC_PORT_ANY) port |= s->dst->port & 0xff; - else if (which == START) + else if (which_port == START) port |= 0x00; else port |= 0xFF; @@ -828,9 +833,14 @@ * the 16 bit local "port" selector during IKEv2 * exchange. */ - if (s->src->port != RC_PROTO_ANY) - port = s->src->port << 8; - else if (which == START) + if (which_side == LOCAL) + al = s->src; + else + al = s->dst; + + if (al->port != RC_PROTO_ANY) + port = al->port << 8; + else if (which_port == START) port = 0x0000; else port = 0xFF00; @@ -860,8 +870,8 @@ } return ikev2_construct_ts(s->upper_layer_protocol, - ulpsel2port(START, s), - ulpsel2port(END, s), + ulpsel2port(LOCAL, START, s), + ulpsel2port(LOCAL, END, s), s->src); } @@ -880,8 +890,8 @@ } return ikev2_construct_ts(s->upper_layer_protocol, - ulpsel2port(START, s), - ulpsel2port(END, s), + ulpsel2port(REMOTE, START, s), + ulpsel2port(REMOTE, END, s), s->dst); } @@ -1122,16 +1132,16 @@ case IPPROTO_ICMPV6: if (sel->src->port != 0 || sel->dst->port != 0) { - if (ulpsel2port(START, sel) != sport || - ulpsel2port(END, sel) != eport) + if (ulpsel2port(LOCAL, START, sel) != sport || + ulpsel2port(LOCAL, END, sel) != eport) continue; } else if (!IKEV2_TS_PORT_IS_ANY(sport, eport)) continue; break; case IPPROTO_MH: if (sel->src->port != 0) { - if (ulpsel2port(START, sel) != sport || - ulpsel2port(END, sel) != eport) + if (ulpsel2port(LOCAL, START, sel) != sport || + ulpsel2port(LOCAL, END, sel) != eport) continue; } else if (!IKEV2_TS_PORT_IS_ANY(sport, eport)) continue; @@ -1237,16 +1247,16 @@ case IPPROTO_ICMPV6: if (sel->src->port != 0 || sel->dst->port != 0) { - if (ulpsel2port(START, sel) != sport || - ulpsel2port(END, sel) != eport) + if (ulpsel2port(REMOTE, START, sel) != sport || + ulpsel2port(REMOTE, END, sel) != eport) continue; } else if (!IKEV2_TS_PORT_IS_ANY(sport, eport)) continue; break; case IPPROTO_MH: if (sel->src->port != 0) { - if (ulpsel2port(START, sel) != sport || - ulpsel2port(END, sel) != eport) + if (ulpsel2port(REMOTE, START, sel) != sport || + ulpsel2port(REMOTE, END, sel) != eport) continue; } else if (!IKEV2_TS_PORT_IS_ANY(sport, eport)) continue; diff -Nur racoon2-20070817cvs/lib/cfsetup.c racoon2-patched/lib/cfsetup.c --- racoon2-20070817cvs/lib/cfsetup.c 2007-08-17 10:57:42.000000000 +0900 +++ racoon2-patched/lib/cfsetup.c 2007-08-17 11:52:12.000000000 +0900 @@ -1888,7 +1888,7 @@ if (n->type != CFT_NUMBER) return -1; for (al = dst->src; al; al = al->next) - al->port = n->d.num; + al->port = n->d.num; /* type */ n = n->nexts; if (!n) @@ -1896,7 +1896,7 @@ if (n->type != CFT_NUMBER) return -1; for (al = dst->dst; al; al = al->next) - al->port = n->d.num; + al->port = n->d.num; /* code */ break; case IPPROTO_MH: n = head->nextp->nexts; @@ -1905,7 +1905,30 @@ if (n->type != CFT_NUMBER) return -1; for (al = dst->src; al; al = al->next) + { + al->port = n->d.num; + if (al->type == RCT_ADDR_INET) + rcs_setsaport(al->a.ipaddr, al->port << 8); + } + + /* We allow a second value for MH type. + * It is the type of reverse path messages. + * for example, valid configuration will be (for outbound selectors): + * On MN: upper_layer_protocol "mh" 5 6; (5 = BU and 6 = BA) + * On HA: upper_layer_protocol "mh" 6 5; + */ + n = n->nexts; + if (!n) + break; + if (n->type != CFT_NUMBER) + return -1; + for (al = dst->dst; al; al = al->next) + { al->port = n->d.num; + if (al->type == RCT_ADDR_INET) + rcs_setsaport(al->a.ipaddr, al->port << 8); + } + if (n->nexts) plog(PLOG_INTWARN, PLOGLOC, NULL, "spurious extra ulp parameter at %d in %s\n",