/* * Connect to specified server via IP */ int ncp_sock_connect_in(struct ncp_conn *conn) { struct sockaddr_in sin; struct thread *td = conn->td; int addrlen=sizeof(sin), error; conn->flags = 0; bzero(&sin,addrlen); conn->ncp_so = conn->wdg_so = NULL; checkbad(socreate(AF_INET, &conn->ncp_so, SOCK_DGRAM, IPPROTO_UDP, td)); sin.sin_family = AF_INET; sin.sin_len = addrlen; checkbad(sobind(conn->ncp_so, (struct sockaddr *)&sin, td)); checkbad(ncp_soconnect(conn->ncp_so,(struct sockaddr*)&conn->li.addr, td)); if (!error) conn->flags |= NCPFL_SOCONN; return error; bad: ncp_sock_disconnect(conn); return (error); }
/* * Connect to specified server via IPX */ static int ncp_sock_connect_ipx(struct ncp_conn *conn) { struct sockaddr_ipx sipx; struct ipxpcb *npcb; struct thread *td = conn->td; int addrlen, error, count; sipx.sipx_port = htons(0); for (count = 0;;count++) { if (count > (IPXPORT_WELLKNOWN-IPXPORT_RESERVED)*2) { error = EADDRINUSE; goto bad; } conn->ncp_so = conn->wdg_so = NULL; checkbad(socreate(AF_IPX, &conn->ncp_so, SOCK_DGRAM, 0, td->td_ucred, td)); if (conn->li.opt & NCP_OPT_WDOG) checkbad(socreate(AF_IPX, &conn->wdg_so, SOCK_DGRAM, 0, td->td_ucred, td)); addrlen = sizeof(sipx); sipx.sipx_family = AF_IPX; ipx_setnullnet(sipx.sipx_addr); ipx_setnullhost(sipx.sipx_addr); sipx.sipx_len = addrlen; error = sobind(conn->ncp_so, (struct sockaddr *)&sipx, td); if (error == 0) { if ((conn->li.opt & NCP_OPT_WDOG) == 0) break; sipx.sipx_addr = sotoipxpcb(conn->ncp_so)->ipxp_laddr; sipx.sipx_port = htons(ntohs(sipx.sipx_port) + 1); ipx_setnullnet(sipx.sipx_addr); ipx_setnullhost(sipx.sipx_addr); error = sobind(conn->wdg_so, (struct sockaddr *)&sipx, td); } if (!error) break; if (error != EADDRINUSE) goto bad; sipx.sipx_port = htons((ntohs(sipx.sipx_port)+4) & 0xfff8); soclose(conn->ncp_so); if (conn->wdg_so) soclose(conn->wdg_so); } npcb = sotoipxpcb(conn->ncp_so); npcb->ipxp_dpt = IPXPROTO_NCP; /* IPXrouted must be running, i.e. route must be presented */ conn->li.ipxaddr.sipx_len = sizeof(struct sockaddr_ipx); checkbad(ncp_soconnect(conn->ncp_so, &conn->li.saddr, td)); if (conn->wdg_so) { sotoipxpcb(conn->wdg_so)->ipxp_laddr.x_net = npcb->ipxp_laddr.x_net; sotoipxpcb(conn->wdg_so)->ipxp_laddr.x_host= npcb->ipxp_laddr.x_host; } if (!error) { conn->flags |= NCPFL_SOCONN; } #ifdef NCPBURST if (ncp_burst_enabled) { checkbad(socreate(AF_IPX, &conn->bc_so, SOCK_DGRAM, 0, td)); bzero(&sipx, sizeof(sipx)); sipx.sipx_len = sizeof(sipx); checkbad(sobind(conn->bc_so, (struct sockaddr *)&sipx, td)); checkbad(ncp_soconnect(conn->bc_so, &conn->li.saddr, td)); } #endif if (!error) { conn->flags |= NCPFL_SOCONN; ncp_sock_checksum(conn, 0); } return error; bad: ncp_sock_disconnect(conn); return (error); }