Potential DoS attack on PF due to infinite loop

Jingmin Zhou <[email protected]> Tue, 11 Jul 2017 12:29:33 -0700
Newsgroups gmane.os.openbsd.pf
Message-ID <CAAbDdZDd_06ZoS=BSmMNpVawtHsCTfKBkU09KdC7W_3oKCrvXg__45659.4413532459$1500203580$gmane$org@mail.gmail.com>
--94eb2c14e02828ac2905540fb815
Content-Type: text/plain; charset="UTF-8"

Recently we discovered a potential bug in pf_lb.c. It is in the latest code
that we retrieved from here:

https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c?annotate=1.60

The problem is at line 224. When a LB rule is configured to have 65535 as
the high port, and uint16 variable tmp reaches it, ++(tmp) will wrap around
and hence potentially enter into an infinite loop. Of course, it only
happens when high is configured to 65535.

Thanks,
Jingmin

                    146: int1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   147: pf_get_sport(struct pf_pdesc *pd, struct pf_rule
*r,1.1 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       148:     struct pf_addr *naddr, u_int16_t *nport,
u_int16_t low, u_int16_t high,1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   149:     struct pf_src_node **sn)1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       150: {
                    151:        struct pf_state_key_cmp key;
                    152:        struct pf_addr          init_addr;
                    153:        u_int16_t               cut;1.54
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     154:        int                     dir = (pd->dir ==
PF_IN) ? PF_OUT : PF_IN;
                    155:        int                     sidx = pd->sidx;
                    156:        int                     didx =
pd->didx;1.1 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       157:
                    158:        bzero(&init_addr,
sizeof(init_addr));1.19
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.19>
     claudio   159:        if (pf_map_addr(pd->naf, r, &pd->nsaddr,
naddr, &init_addr, sn, &r->nat,1.9
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.9>
      henning   160:            PF_SN_NAT))1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       161:                return (1);
                    162:1.35
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.35>
     bluhm     163:        if (pd->proto == IPPROTO_ICMP) {
                    164:                if (pd->ndport ==
htons(ICMP_ECHO)) {1.4
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.4>
      mcbride   165:                        low = 1;
                    166:                        high = 65535;
                    167:                } else
                    168:                        return (0);     /*
Don't try to modify non-echo ICMP */1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       169:        }1.35
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.35>
     bluhm     170: #ifdef INET6
                    171:        if (pd->proto == IPPROTO_ICMPV6) {
                    172:                if (pd->ndport ==
htons(ICMP6_ECHO_REQUEST)) {
                    173:                        low = 1;
                    174:                        high = 65535;
                    175:                } else
                    176:                        return (0);     /*
Don't try to modify non-echo ICMP */
                    177:        }
                    178: #endif /* INET6 */1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       179:
                    180:        do {1.19
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.19>
     claudio   181:                key.af = pd->naf;1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   182:                key.proto = pd->proto;
                    183:                key.rdomain = pd->rdomain;1.54
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     184:                PF_ACPY(&key.addr[didx],
&pd->ndaddr, key.af);
                    185:                PF_ACPY(&key.addr[sidx], naddr, key.af);
                    186:                key.port[didx] =
pd->ndport;1.1 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       187:
                    188:                /*
                    189:                 * port search; start random, step;
                    190:                 * similar 2 portloop in in_pcbbind
                    191:                 */1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   192:                if (!(pd->proto == IPPROTO_TCP ||
pd->proto == IPPROTO_UDP ||1.30
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.30>
     mikeb     193:                    pd->proto == IPPROTO_ICMP ||
pd->proto == IPPROTO_ICMPV6)) {1.12
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.12>
     sthen     194:                        /* XXX bug: icmp states
dont use the id on both
                    195:                         * XXX sides
(traceroute -I through nat) */1.54
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     196:                        key.port[sidx] =
pd->nsport;
                    197:                        if
(pf_find_state_all(&key, dir, NULL) == NULL) {1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   198:                                *nport =
pd->nsport;1.1 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       199:                                return (0);1.12
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.12>
     sthen     200:                        }1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       201:                } else if (low == 0 && high == 0)
{1.54 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     202:                        key.port[sidx] =
pd->nsport;
                    203:                        if
(pf_find_state_all(&key, dir, NULL) == NULL) {1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   204:                                *nport =
pd->nsport;1.1 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       205:                                return (0);1.12
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.12>
     sthen     206:                        }1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       207:                } else if (low == high) {1.54
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     208:                        key.port[sidx] =
htons(low);
                    209:                        if
(pf_find_state_all(&key, dir, NULL) == NULL) {1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       210:                                *nport =
htons(low);
                    211:                                return (0);
                    212:                        }
                    213:                } else {
                    214:                        u_int16_t tmp;
                    215:
                    216:                        if (low > high) {
                    217:                                tmp = low;
                    218:                                low = high;
                    219:                                high = tmp;
                    220:                        }
                    221:                        /* low < high */
                    222:                        cut =
arc4random_uniform(1 + high - low) + low;
                    223:                        /* low <= cut <= high */
                    224:                        for (tmp = cut; tmp <=
high; ++(tmp)) {1.54
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     225:                                key.port[sidx] =
htons(tmp);
                    226:                                if
(pf_find_state_all(&key, dir, NULL) ==1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   227:                                    NULL &&
!in_baddynamic(tmp, pd->proto)) {1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       228:                                        *nport =
htons(tmp);
                    229:                                        return (0);
                    230:                                }
                    231:                        }
                    232:                        for (tmp = cut - 1;
tmp >= low; --(tmp)) {1.54
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.54>
     bluhm     233:                                key.port[sidx] =
htons(tmp);
                    234:                                if
(pf_find_state_all(&key, dir, NULL) ==1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   235:                                    NULL &&
!in_baddynamic(tmp, pd->proto)) {1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       236:                                        *nport =
htons(tmp);
                    237:                                        return (0);
                    238:                                }
                    239:                        }
                    240:                }
                    241:1.6
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.6>
      henning   242:                switch (r->nat.opts &
PF_POOL_TYPEMASK) {1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       243:                case PF_POOL_RANDOM:
                    244:                case PF_POOL_ROUNDROBIN:1.15
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.15>
     zinke     245:                case PF_POOL_LEASTSTATES:1.29
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.29>
     mikeb     246:                        /*
                    247:                         * pick a different
source address since we're out
                    248:                         * of free port
choices for the current one.
                    249:                         */1.19
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.19>
     claudio   250:                        if (pf_map_addr(pd->naf, r,
&pd->nsaddr, naddr,1.13
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.13>
     henning   251:                            &init_addr, sn,
&r->nat, PF_SN_NAT))1.1
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       252:                                return (1);
                    253:                        break;
                    254:                case PF_POOL_NONE:
                    255:                case PF_POOL_SRCHASH:
                    256:                case PF_POOL_BITMASK:
                    257:                default:
                    258:                        return (1);
                    259:                }1.19
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.19>
     claudio   260:        } while (! PF_AEQ(&init_addr, naddr,
pd->naf) );1.1 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#rev1.1>
      pyr       261:        return (1);
     /* none available */
                    262: }

--94eb2c14e02828ac2905540fb815
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Recently we discovered a potential bug in pf_lb.c. It is i=
n the latest code that we retrieved from here:<div><br></div><div><a href=
=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c?annotate=
=3D1.60">https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c?anno=
tate=3D1.60</a><br></div><div><br></div><div>The problem is at line 224. Wh=
en a LB rule is configured to have 65535 as the high port, and uint16 varia=
ble tmp reaches it, ++(tmp) will wrap around and hence potentially enter in=
to an infinite loop. Of course, it only happens when high is configured to =
65535.</div><div><br></div><div>Thanks,</div><div>Jingmin</div><div><br><di=
v><pre style=3D"color:rgb(0,0,0)"><pre>                    146: int
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   147: pf_get_sport(struct pf_pdesc *pd, struc=
t pf_rule *r,
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       148: =C2=A0 =C2=A0 struct pf_addr *naddr, u_i=
nt16_t *nport, u_int16_t low, u_int16_t high,
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   149: =C2=A0 =C2=A0 struct pf_src_node **sn)
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       150: {
                    151: =C2=A0 =C2=A0 =C2=A0 =C2=A0struct pf_state_key_cmp=
 key;
                    152: =C2=A0 =C2=A0 =C2=A0 =C2=A0struct pf_addr =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0init_addr;
                    153: =C2=A0 =C2=A0 =C2=A0 =C2=A0u_int16_t =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cut;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     154: =C2=A0 =C2=A0 =C2=A0 =C2=A0int =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dir =3D (pd-=
&gt;dir =3D=3D PF_IN) ? PF_OUT : PF_IN;
                    155: =C2=A0 =C2=A0 =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sidx =3D pd-&gt;sidx;
                    156: =C2=A0 =C2=A0 =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 didx =3D pd-&gt;didx;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       157:
                    158: =C2=A0 =C2=A0 =C2=A0 =C2=A0bzero(&amp;init_addr, s=
izeof(init_addr));
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.19">1.19</a>      claudio   159: =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_map_a=
ddr(pd-&gt;naf, r, &amp;pd-&gt;nsaddr, naddr, &amp;init_addr, sn, &amp;r-&g=
t;nat,
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.9">1.9</a>       henning   160: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0PF_SN_NAT))
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       161: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0return (1);
                    162:
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.35">1.35</a>      bluhm     163: =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pd-&gt;p=
roto =3D=3D IPPROTO_ICMP) {
                    164: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0if (pd-&gt;ndport =3D=3D htons(ICMP_ECHO)) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.4">1.4</a>       mcbride   165: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0low =3D 1;
                    166: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0high =3D 65535;
                    167: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0} else
                    168: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (0); =C2=A0 =C2=A0 /* Don&#39;t tr=
y to modify non-echo ICMP */
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       169: =C2=A0 =C2=A0 =C2=A0 =C2=A0}
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.35">1.35</a>      bluhm     170: #ifdef INET6
                    171: =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pd-&gt;proto =3D=3D=
 IPPROTO_ICMPV6) {
                    172: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0if (pd-&gt;ndport =3D=3D htons(ICMP6_ECHO_REQUEST)) {
                    173: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0low =3D 1;
                    174: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0high =3D 65535;
                    175: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0} else
                    176: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (0); =C2=A0 =C2=A0 /* Don&#39;t tr=
y to modify non-echo ICMP */
                    177: =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    178: #endif /* INET6 */
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       179:
                    180: =C2=A0 =C2=A0 =C2=A0 =C2=A0do {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.19">1.19</a>      claudio   181: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0<a href=3D"http://key.af">key.af</a> =3D pd-&gt;naf;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   182: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0key.proto =3D pd-&gt;proto;
                    183: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0key.rdomain =3D pd-&gt;rdomain;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     184: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0PF_ACPY(&amp;key.addr[didx], &amp;pd-&gt;ndaddr, <a href=
=3D"http://key.af">key.af</a>);
                    185: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0PF_ACPY(&amp;key.addr[sidx], naddr, <a href=3D"http://key.af">key.af<=
/a>);
                    186: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0key.port[didx] =3D pd-&gt;ndport;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       187:
                    188: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0/*
                    189: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 * port search; start random, step;
                    190: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 * similar 2 portloop in in_pcbbind
                    191: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 */
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   192: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0if (!(pd-&gt;proto =3D=3D IPPROTO_TCP || pd-&gt;proto =3D=
=3D IPPROTO_UDP ||
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.30">1.30</a>      mikeb     193: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pd-&gt;proto =3D=3D IPPROTO_ICMP || pd-&gt;p=
roto =3D=3D IPPROTO_ICMPV6)) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.12">1.12</a>      sthen     194: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* XXX bug: icmp states dont u=
se the id on both
                    195: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * XXX sides (traceroute -I through nat) =
*/
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     196: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0key.port[sidx] =3D pd-&gt;nspo=
rt;
                    197: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_find_state_all(&amp;key, dir, NULL=
) =3D=3D NULL) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   198: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*n=
port =3D pd-&gt;nsport;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       199: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0re=
turn (0);
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.12">1.12</a>      sthen     200: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       201: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0} else if (low =3D=3D 0 &amp;&amp; high =3D=3D 0) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     202: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0key.port[sidx] =3D pd-&gt;nspo=
rt;
                    203: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_find_state_all(&amp;key, dir, NULL=
) =3D=3D NULL) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   204: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*n=
port =3D pd-&gt;nsport;
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       205: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0re=
turn (0);
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.12">1.12</a>      sthen     206: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       207: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0} else if (low =3D=3D high) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     208: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0key.port[sidx] =3D htons(low);
                    209: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_find_state_all(&amp;key, dir, NULL=
) =3D=3D NULL) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       210: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*n=
port =3D htons(low);
                    211: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (0);
                    212: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    213: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0} else {
                    214: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_int16_t tmp;
                    215:
                    216: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (low &gt; high) {
                    217: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tmp =3D low;
                    218: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0low =3D high;
                    219: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0high =3D tmp;
                    220: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    221: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* low &lt; high */
                    222: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cut =3D arc4random_uniform(1 + high - low=
) + low;
                    223: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* low &lt;=3D cut &lt;=3D high */
                    224: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for (tmp =3D cut; tmp &lt;=3D high; ++(tm=
p)) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     225: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ke=
y.port[sidx] =3D htons(tmp);
                    226: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_find_s=
tate_all(&amp;key, dir, NULL) =3D=3D
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   227: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0NULL &amp;&amp; !in_baddynamic(tmp, pd-&gt;proto)) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       228: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0*nport =3D htons(tmp);
                    229: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0return (0);
                    230: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    231: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    232: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for (tmp =3D cut - 1; tmp &gt;=3D low; --=
(tmp)) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.54">1.54</a>      bluhm     233: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ke=
y.port[sidx] =3D htons(tmp);
                    234: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_find_s=
tate_all(&amp;key, dir, NULL) =3D=3D
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   235: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0NULL &amp;&amp; !in_baddynamic(tmp, pd-&gt;proto)) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       236: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0*nport =3D htons(tmp);
                    237: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0return (0);
                    238: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    239: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
                    240: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0}
                    241:
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.6">1.6</a>       henning   242: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0switch (r-&gt;nat.opts &amp; PF_POOL_TYPEMASK) {
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       243: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0case PF_POOL_RANDOM:
                    244: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0case PF_POOL_ROUNDROBIN:
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.15">1.15</a>      zinke     245: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0case PF_POOL_LEASTSTATES:
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.29">1.29</a>      mikeb     246: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/*
                    247: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * pick a different source address since =
we&#39;re out
                    248: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * of free port choices for the current o=
ne.
                    249: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.19">1.19</a>      claudio   250: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (pf_map_addr(pd-&gt;naf, r,=
 &amp;pd-&gt;nsaddr, naddr,
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.13">1.13</a>      henning   251: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&amp;init_addr, =
sn, &amp;r-&gt;nat, PF_SN_NAT))
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       252: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0re=
turn (1);
                    253: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
                    254: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0case PF_POOL_NONE:
                    255: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0case PF_POOL_SRCHASH:
                    256: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0case PF_POOL_BITMASK:
                    257: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0default:
                    258: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (1);
                    259: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0}
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.19">1.19</a>      claudio   260: =C2=A0 =C2=A0 =C2=A0 =C2=A0} while (! P=
F_AEQ(&amp;init_addr, naddr, pd-&gt;naf) );
<a href=3D"https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf_lb.c#re=
v1.1">1.1</a>       pyr       261: =C2=A0 =C2=A0 =C2=A0 =C2=A0return (1); =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* none available */
                    262: }
</pre><div><br></div></pre></div></div></div>

--94eb2c14e02828ac2905540fb815--