*** sshconnect.c 1999/09/17 03:21:39 1.1 --- sshconnect.c 1999/09/17 04:16:56 *************** *** 15,21 **** */ /* ! * $Id: sshconnect.c,v 1.1 1999/09/17 03:21:39 kolya Exp kolya $ * $Log: sshconnect.c,v $ * Revision 1.1 1999/09/17 03:21:39 kolya * Initial revision --- 15,21 ---- */ /* ! * $Id: sshconnect.c,v 1.1 1999/09/17 03:21:39 kolya Exp $ * $Log: sshconnect.c,v $ * Revision 1.1 1999/09/17 03:21:39 kolya * Initial revision *************** *** 389,394 **** --- 389,534 ---- return sock; } + #if defined(IP_OPTIONS) && defined(IPPROTO_IP) + /* Set source routing options on a socket */ + + + unsigned long + sourceroute(arg, cpp, lenp) + char *arg; + char **cpp; + int *lenp; + { + static char lsr[44]; + #ifdef sysV88 + static IOPTN ipopt; + #endif + char *cp, *cp2, *lsrp, *lsrep; + register int tmp; + struct in_addr sin_addr; + register struct hostent *host = 0; + register char c; + + /* + * Verify the arguments, and make sure we have + * at least 7 bytes for the option. + */ + if (cpp == NULL || lenp == NULL) + return((unsigned long)-1); + if (*cpp != NULL && *lenp < 7) + return((unsigned long)-1); + /* + * Decide whether we have a buffer passed to us, + * or if we need to use our own static buffer. + */ + if (*cpp) { + lsrp = *cpp; + lsrep = lsrp + *lenp; + } else { + *cpp = lsrp = lsr; + lsrep = lsrp + 44; + } + + cp = arg; + + /* + * Next, decide whether we have a loose source + * route or a strict source route, and fill in + * the begining of the option. + */ + #ifndef sysV88 + if (*cp == '!') { + cp++; + *lsrp++ = IPOPT_SSRR; + } else + *lsrp++ = IPOPT_LSRR; + #else + if (*cp == '!') { + cp++; + ipopt.io_type = IPOPT_SSRR; + } else + ipopt.io_type = IPOPT_LSRR; + #endif + + if (*cp != '%') + return((unsigned long)-1); + + #ifndef sysV88 + lsrp++; /* skip over length, we'll fill it in later */ + *lsrp++ = 4; + #endif + + cp++; + + sin_addr.s_addr = 0; + + for (c = 0;;) { + if (c == ':') + cp2 = 0; + else for (cp2 = cp; c = *cp2; cp2++) { + if (c == ',') { + *cp2++ = '\0'; + if (*cp2 == '%') + cp2++; + } else if (c == '%') { + *cp2++ = '\0'; + } else if (c == ':') { + *cp2++ = '\0'; + } else + continue; + break; + } + if (!c) + cp2 = 0; + + if ((tmp = inet_addr(cp)) != -1) { + sin_addr.s_addr = tmp; + } else if (host = gethostbyname(cp)) { + #if defined(h_addr) + memcpy((caddr_t)&sin_addr, + host->h_addr_list[0], sizeof(sin_addr)); + #else + memcpy((caddr_t)&sin_addr, host->h_addr, + sizeof(sin_addr)); + #endif + } else { + *cpp = cp; + return(0); + } + memcpy(lsrp, (char *)&sin_addr, 4); + lsrp += 4; + if (cp2) + cp = cp2; + else + break; + /* + * Check to make sure there is space for next address + */ + if (lsrp + 4 > lsrep) + return((unsigned long)-1); + } + #ifndef sysV88 + if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { + *cpp = 0; + *lenp = 0; + return((unsigned long)-1); + } + *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ + *lenp = lsrp - *cpp; + #else + ipopt.io_len = lsrp - *cpp; + if (ipopt.io_len <= 5) { /* Is 3 better ? */ + *cpp = 0; + *lenp = 0; + return((unsigned long)-1); + } + *lenp = sizeof(ipopt); + *cpp = (char *) &ipopt; + #endif + return(sin_addr.s_addr); + } + #endif + /* Opens a TCP/IP connection to the remote server on the given host. If port is 0, the default port will be used. If anonymous is zero, a privileged port will be allocated to make the connection. *************** *** 410,415 **** --- 550,560 ---- #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) struct linger linger; #endif /* SO_LINGER */ + #if defined(IP_OPTIONS) && defined(IPPROTO_IP) + char *srp = 0; + unsigned long sourceroute(), srlen, temp; + char *hostp; + #endif debug("ssh_connect: getuid %d geteuid %d anon %d", (int)getuid(), (int)geteuid(), anonymous); *************** *** 445,465 **** --- 590,639 ---- { if (attempt > 0) debug("Trying again..."); + hostaddr.sin_addr.s_addr = 0; + + #if defined(IP_OPTIONS) && defined(IPPROTO_IP) + hostp=(char *)strdup(host); + if (hostp[0] == '%' || hostp[0] == '!') { + if ((host = strrchr(hostp, ':')) == NULL) + host = strrchr(hostp, '%'); + host++; + srp = 0; + temp = sourceroute(hostp, &srp, &srlen); + if (temp == 0) { + herror(srp); + return 0; + } else if (temp == -1) { + printf("Bad source route option: %s\r\n", hostp); + return 0; + } else { + hostaddr.sin_addr.s_addr = temp; + } + } + #endif /* Try to parse the host name as a numeric inet address. */ memset(&hostaddr, 0, sizeof(hostaddr)); hostaddr.sin_family = AF_INET; hostaddr.sin_port = htons(port); + if(!hostaddr.sin_addr.s_addr) { #ifdef BROKEN_INET_ADDR hostaddr.sin_addr.s_addr = inet_network(host); #else /* BROKEN_INET_ADDR */ hostaddr.sin_addr.s_addr = inet_addr(host); #endif /* BROKEN_INET_ADDR */ + } if ((hostaddr.sin_addr.s_addr & 0xffffffff) != 0xffffffff) { /* Create a socket. */ sock = ssh_create_socket(original_real_uid, !anonymous && geteuid() == UID_ROOT); + + #if defined(IP_OPTIONS) && defined(IPPROTO_IP) + if (srp && setsockopt(sock, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) + < 0) + perror("setsockopt (IP_OPTIONS)"); + #endif /* Valid numeric IP address */ debug("Connecting to %.100s port %d.", *************** *** 535,540 **** --- 709,720 ---- /* Create a socket for connecting. */ sock = ssh_create_socket(original_real_uid, !anonymous && geteuid() == UID_ROOT); + + #if defined(IP_OPTIONS) && defined(IPPROTO_IP) + if (srp && setsockopt(sock, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) + < 0) + perror("setsockopt (IP_OPTIONS)"); + #endif /* Connect to the host. */ #if defined(SOCKS) *** canohost.c 1999/09/17 04:30:23 1.1 --- canohost.c 1999/09/17 04:30:48 *************** *** 14,20 **** */ /* ! * $Id: canohost.c,v 1.1 1999/09/17 04:30:23 kolya Exp kolya $ * $Log: canohost.c,v $ * Revision 1.1 1999/09/17 04:30:23 kolya * Initial revision --- 14,20 ---- */ /* ! * $Id: canohost.c,v 1.1 1999/09/17 04:30:23 kolya Exp $ * $Log: canohost.c,v $ * Revision 1.1 1999/09/17 04:30:23 kolya * Initial revision *************** *** 161,168 **** sprintf(cp, " %2.2x", *ucp); log_msg("Connection from %.100s with IP options:%.800s", inet_ntoa(from.sin_addr), text); ! packet_disconnect("Connection from %.100s with IP options:%.800s", ! inet_ntoa(from.sin_addr), text); } } #endif --- 161,168 ---- sprintf(cp, " %2.2x", *ucp); log_msg("Connection from %.100s with IP options:%.800s", inet_ntoa(from.sin_addr), text); ! /* packet_disconnect("Connection from %.100s with IP options:%.800s", ! inet_ntoa(from.sin_addr), text); */ } } #endif