/* * Process initial NCP handshake (attach) * NOTE: Since all functions below may change conn attributes, they * should be called with LOCKED connection, also they use procp & ucred */ int ncp_ncp_connect(struct ncp_conn *conn) { struct ncp_rq *rqp; struct ncp_rphdr *rp; int error; error = ncp_rq_alloc_any(NCP_ALLOC_SLOT, 0, conn, conn->td, conn->ucred, &rqp); if (error) return error; conn->flags &= ~(NCPFL_SIGNACTIVE | NCPFL_SIGNWANTED | NCPFL_ATTACHED | NCPFL_LOGGED | NCPFL_INVALID); conn->seq = 0; error = ncp_request_int(rqp); if (!error) { rp = mtod(rqp->rp.md_top, struct ncp_rphdr*); conn->connid = rp->conn_low + (rp->conn_high << 8); }
int ncp_request(struct ncp_rq *rqp) { struct ncp_conn *ncp = rqp->nr_conn; int error, rcnt; error = ncp_conn_lock(ncp, rqp->nr_td, rqp->nr_cred, NCPM_EXECUTE); if (error) goto out; rcnt = NCP_RESTORE_COUNT; for(;;) { if (ncp->flags & NCPFL_ATTACHED) { error = ncp_request_int(rqp); if (ncp->flags & NCPFL_ATTACHED) break; } if (rcnt-- == 0) { error = ECONNRESET; break; } /* * Do not attempt to restore connection recursively */ if (ncp->flags & NCPFL_RESTORING) { error = ENOTCONN; break; } error = ncp_restore_login(ncp); if (error) continue; } ncp_conn_unlock(ncp, rqp->nr_td); out: if (error && (rqp->nr_flags & NCPR_DONTFREEONERR) == 0) ncp_rq_done(rqp); return error; }