+/*
+ * return 1 if there's a pcb whose addresses 'confict' with the
+ * supplied addresses. Only exact matches (address with address
+ * or wildcard with wildcard) are considered to be in conflict
+ * since in_pcblookup will resolve anything else via 'best match'.
+ */
+int
+in_pcbconflict(head, faddr, laddr, fport, lport)
+ register struct inpcb *head;
+ register u_long faddr, laddr;
+ register u_short fport, lport;
+{
+ register struct inpcb *inp = head;
+
+ while ((inp = inp->inp_next) != head)
+ if (inp->inp_lport == lport &&
+ (fport == 0 || inp->inp_fport == fport) &&
+ (faddr == 0 || inp->inp_faddr.s_addr == faddr) &&
+ (laddr == 0 || inp->inp_laddr.s_addr == laddr))
+ return (1);
+ return (0);
+}
+
+/*
+ * Chose a unique (non-conflicting) local port for the inpcb list
+ * starting at 'head'. (A 'rover' is kept in the lport field of
+ * the list head to make N calls to this routine O(N^2) instead of
+ * O(N^3)). The port will always be
+ * IPPORT_RESERVED <= lport <= IPPORT_USERRESERVED
+ */
+u_short
+in_uniqueport(head, faddr, laddr, fport)
+ register struct inpcb *head;
+ register u_long faddr, laddr;
+ register u_short fport;
+{
+ register u_short lport = head->inp_lport;
+
+ do {
+ ++lport;
+ if (lport < IPPORT_RESERVED || lport > IPPORT_USERRESERVED)
+ lport = IPPORT_RESERVED;
+ } while (in_pcbconflict(head, faddr, laddr, fport, htons(lport)));
+ head->inp_lport = lport;
+ return (htons(lport));
+}
+