# 2.11BSD#431 - /usr/src/new/nntp/xmit/get_tcp_conn.c

##### Functions

    bcopy             X
    get_tcp_conn      X
    gservice          X
    inet_addr         X
    inet_ntoa         X
    name_to_address   X

##### struct's

    Services          X

       1: /*
       2: ** Routines to open a TCP connection
       3: **
       4: ** New version that supports the old (pre 4.2 BSD) socket calls,
       5: ** and systems with the old (pre 4.2 BSD) hostname lookup stuff.
       6: ** Compile-time options are:
       7: **
       8: **	USG		- you're on System III/V (you have my sympathies)
       9: **	NONETDB		- old hostname lookup with rhost()
      10: **	OLDSOCKET	- different args for socket() and connect()
      11: **
      12: ** Erik E. Fair <fair@ucbarpa.berkeley.edu>
      13: **
      14: */
      15:
      16: #include <sys/types.h>
      17: #include <sys/socket.h>
      18: #include <netinet/in.h>
      19: #include <ctype.h>
      20: #include <stdio.h>
      21: #include "get_tcp_conn.h"
      22: #ifndef NONETDB
      23: #include <netdb.h>
      24: #endif	NONETDB
      25:
      26: extern  int errno;
      27: extern  char    *Pname;
      28: extern  char    *errmsg();
      29: #ifndef htons
      30: extern  u_short htons();
      31: #endif	htons
      32: #ifndef NONETDB
      33: extern  char    *inet_ntoa();
      34: extern  u_long  inet_addr();
      35: #else
      36: /*
      37:  * inet_addr for EXCELAN (which does not have it!)
      38:  *
      39:  */
      40: u_long
      41: inet_addr(cp)
      42: register char   *cp;
      43: {
      44:     u_long val, base, n;
      45:     register char c;
      46:     u_long octet[4], *octetptr = octet;
      47: #ifndef htonl
      48:     extern  u_long  htonl();
      49: #endif	htonl
      50: again:
      51:     /*
      52: 	 * Collect number up to ``.''.
      53: 	 * Values are specified as for C:
      54: 	 * 0x=hex, 0=octal, other=decimal.
      55: 	 */
      56:     val = 0; base = 10;
      57:     if (*cp == '0')
      58:         base = 8, cp++;
      59:     if (*cp == 'x' || *cp == 'X')
      60:         base = 16, cp++;
      61:     while (c = *cp) {
      62:         if (isdigit(c)) {
      63:             val = (val * base) + (c - '0');
      64:             cp++;
      65:             continue;
      66:         }
      67:         if (base == 16 && isxdigit(c)) {
      68:             val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
      69:             cp++;
      70:             continue;
      71:         }
      72:         break;
      73:     }
      74:     if (*cp == '.') {
      75:         /*
      76: 		 * Internet format:
      77: 		 *	a.b.c.d
      78: 		 *	a.b.c	(with c treated as 16-bits)
      79: 		 *	a.b	(with b treated as 24 bits)
      80: 		 */
      81:         if (octetptr >= octet + 4)
      82:             return (-1);
      83:         *octetptr++ = val, cp++;
      84:         goto again;
      85:     }
      86:     /*
      87: 	 * Check for trailing characters.
      88: 	 */
      89:     if (*cp && !isspace(*cp))
      90:         return (-1);
      91:     *octetptr++ = val;
      92:     /*
      93: 	 * Concoct the address according to
      94: 	 * the number of octet specified.
      95: 	 */
      96:     n = octetptr - octet;
      97:     switch (n) {
      98:
      99:     case 1:             /* a -- 32 bits */
     100:         val = octet[0];
     101:         break;
     102:
     103:     case 2:             /* a.b -- 8.24 bits */
     104:         val = (octet[0] << 24) | (octet[1] & 0xffffff);
     105:         break;
     106:
     107:     case 3:             /* a.b.c -- 8.8.16 bits */
     108:         val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
     109:             (octet[2] & 0xffff);
     110:         break;
     111:
     112:     case 4:             /* a.b.c.d -- 8.8.8.8 bits */
     113:         val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
     114:               ((octet[2] & 0xff) << 8) | (octet[3] & 0xff);
     115:         break;
     116:
     117:     default:
     118:         return (-1);
     119:     }
     120:     val = htonl(val);
     121:     return (val);
     122: }
     123:
     124: char *
     125: inet_ntoa(in)
     126: struct in_addr in;
     127: {
     128:     static char address[20];
     129:
     130:     sprintf(address, "%u.%u.%u.%u",
     131:              (in.s_addr>>24)&0xff,
     132:              (in.s_addr>>16)&0xff,
     133:              (in.s_addr>>8 )&0xff,
     134:              (in.s_addr    )&0xff);
     135:     return(address);
     136: }
     137: #endif	NONETDB
     138:
     139: #ifdef  USG
     140: void
     141: bcopy(s, d, l)
     142: register caddr_t s, d;
     143: register int l;
     144: {
     145:     while (l-- > 0) *d++ = *s++;
     146: }
     147: #endif	USG
     148:
     149: /*
     150: ** Take the name of an internet host in ASCII (this may either be its
     151: ** official host name or internet number (with or without enclosing
     152: ** backets [])), and return a list of internet addresses.
     153: **
     154: ** returns NULL for failure to find the host name in the local database,
     155: ** or for a bad internet address spec.
     156: */
     157: u_long **
     158: name_to_address(host)
     159: char    *host;
     160: {
     161:     static  u_long  *host_addresses[2];
     162:     static  u_long  haddr;
     163:
     164:     if (host == (char *)NULL) {
     165:         return((u_long **)NULL);
     166:     }
     167:
     168:     host_addresses[0] = &haddr;
     169:     host_addresses[1] = (u_long *)NULL;
     170:
     171:     /*
     172: 	** Is this an ASCII internet address? (either of [10.0.0.78] or
     173: 	** 10.0.0.78). We get away with the second test because hostnames
     174: 	** and domain labels are not allowed to begin in numbers.
     175: 	** (cf. RFC952, RFC882).
     176: 	*/
     177:     if (*host == '[' || isdigit(*host)) {
     178:         char    namebuf[128];
     179:         register char   *cp = namebuf;
     180:
     181:         /*
     182: 		** strip brackets [] or anything else we don't want.
     183: 		*/
     184:         while(*host != '\0' && cp < &namebuf[sizeof(namebuf)]) {
     185:             if (isdigit(*host) || *host == '.')
     186:                 *cp++ = *host++;    /* copy */
     187:             else
     188:                 host++;         /* skip */
     189:         }
     190:         *cp = '\0';
     191:         haddr = inet_addr(namebuf);
     192:         return(&host_addresses[0]);
     193:     } else {
     194: #ifdef  NONETDB
     195:         extern  u_long  rhost();
     196:
     197:         /* lint is gonna bitch about this (comparing an unsigned?!) */
     198:         if ((haddr = rhost(&host)) == FAIL)
     199:             return((u_long **)NULL);    /* no such host */
     200:         return(&host_addresses[0]);
     201: #else
     202:         struct hostent  *hstp = gethostbyname(host);
     203:
     204:         if (hstp == NULL) {
     205:             return((u_long **)NULL);    /* no such host */
     206:         }
     207:
     208:         if (hstp->h_length != sizeof(u_long))
     209:             abort();    /* this is fundamental */
     210: #ifndef h_addr
     211:         /* alignment problems (isn't dbm wonderful?) */
     212:         bcopy((caddr_t)hstp->h_addr, (caddr_t)&haddr, sizeof(haddr));
     213:         return(&host_addresses[0]);
     214: #else
     215:         return((u_long **)hstp->h_addr_list);
     216: #endif	h_addr
     217: #endif	NONETDB
     218:     }
     219: }
     220:
     221: /*
     222: ** Get a service port number from a service name (or ASCII number)
     223: **
     224: ** Return zero if something is wrong (that's a reserved port)
     225: */
     226: #ifdef  NONETDB
     227: static struct Services {
     228:     char    *name;
     229:     u_short port;
     230: } Services[] = {
     231:     {"nntp",    IPPORT_NNTP},       /* RFC977 */
     232:     {"smtp",    IPPORT_SMTP},       /* RFC821 */
     233:     {"name",    IPPORT_NAMESERVER}, /* RFC881, RFC882, RFC883 */
     234:     {"time",    IPPORT_TIMESERVER}, /* RFC868 */
     235:     {"echo",    IPPORT_ECHO},       /* RFC862 */
     236:     {"discard", IPPORT_DISCARD},    /* RFC863 */
     237:     {"daytime", IPPORT_DAYTIME},    /* RFC867 */
     238:     {"login",   IPPORT_LOGINSERVER},    /* N/A - 4BSD specific */
     239: };
     240: #endif	NONETDB
     241:
     242: u_short
     243: gservice(serv, proto)
     244: char    *serv, *proto;
     245: {
     246:     if (serv == (char *)NULL || proto == (char *)NULL)
     247:         return((u_short)0);
     248:
     249:     if (isdigit(*serv)) {
     250:         return(htons((u_short)(atoi(serv))));
     251:     } else {
     252: #ifdef  NONETDB
     253:         register int    i;
     254:
     255:         for(i = 0; i < (sizeof(Services) / sizeof(struct Services)); i++) {
     256:             if (strcmp(serv, Services[i].name) == 0)
     257:                 return(htons(Services[i].port));
     258:         }
     259:         return((u_short)0);
     260: #else
     261:         struct servent  *srvp = getservbyname(serv, proto);
     262:
     263:         if (srvp == (struct servent *)NULL)
     264:             return((u_short)0);
     265:         return((u_short)srvp->s_port);
     266: #endif	NONETDB
     267:     }
     268: }
     269:
     270: /*
     271: ** given a host name (either name or internet address) and service name
     272: ** (or port number) (both in ASCII), give us a TCP connection to the
     273: ** requested service at the requested host (or give us FAIL).
     274: */
     275: get_tcp_conn(host, serv)
     276: char    *host, *serv;
     277: {
     278:     register int    sock;
     279:     u_long  **addrlist;
     280:     struct sockaddr_in  sadr;
     281: #ifdef  OLDSOCKET
     282:     struct sockproto    sp;
     283:
     284:     sp.sp_family    = (u_short)AF_INET;
     285:     sp.sp_protocol  = (u_short)IPPROTO_TCP;
     286: #endif	OLDSOCKET
     287:
     288:     if ((addrlist = name_to_address(host)) == (u_long **)NULL) {
     289:         return(NOHOST);
     290:     }
     291:
     292:     sadr.sin_family = (u_short)AF_INET; /* Only internet for now */
     293:     if ((sadr.sin_port = gservice(serv, "tcp")) == 0)
     294:         return(NOSERVICE);
     295:
     296:     for(; *addrlist != (u_long *)NULL; addrlist++) {
     297:         bcopy((caddr_t)*addrlist, (caddr_t)&sadr.sin_addr,
     298:             sizeof(sadr.sin_addr));
     299:
     300: #ifdef  OLDSOCKET
     301:         if ((sock = socket(SOCK_STREAM, &sp, (struct sockaddr *)NULL, 0)) < 0)
     302:             return(FAIL);
     303:
     304:         if (connect(sock, (struct sockaddr *)&sadr) < 0) {
     305: #else
     306:         if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
     307:             return(FAIL);
     308:
     309:         if (connect(sock, (struct sockaddr *)&sadr, sizeof(sadr)) < 0) {
     310: #endif	OLDSOCKET
     311:             int e_save = errno;
     312:
     313:             fprintf(stderr, "%s: %s [%s]: %s\n", Pname, host,
     314:                 inet_ntoa(sadr.sin_addr), errmsg(errno));
     315:             (void) close(sock); /* dump descriptor */
     316:             errno = e_save;
     317:         } else
     318:             return(sock);
     319:     }
     320:     return(FAIL);
     321: }

#### Defined functions

bcopy defined in line 140; used 3 times

- in line 212, 297
- in /usr/src/new/nntp/xmit/llist.c line 50

get_tcp_conn defined in line 275; used 1 times

- in /usr/src/new/nntp/xmit/remote.c line 168

gservice defined in line 242; used 1 times

- in line 293

inet_addr defined in line 40; used 2 times

- in line 34, 191

inet_ntoa defined in line 124; used 2 times

- in line 33, 314

name_to_address defined in line 157; used 1 times

- in line 288

#### Defined variables

Services defined in line 230; used 3 times

- in line 255-257(3)

#### Defined struct's

Services defined in line 227; used 2 times

- in line 255(2)

Last modified: 1987-11-30 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1747 |