home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NET-TOOL.1 / NET-TOOL / net-tools / lib / inet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-03  |  4.2 KB  |  202 lines

  1. /*
  2.  * NET-2    This file contains an implementation of the "INET"
  3.  *        support functions for the NET-2 base distribution.
  4.  *
  5.  * Version:    @(#)inet.c    1.20    12/12/93
  6.  *
  7.  * Author:    Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  8.  *        Copyright 1993 MicroWalt Corporation
  9.  *
  10.  *        This program is free software; you can redistribute it
  11.  *        and/or  modify it under  the terms of  the GNU General
  12.  *        Public  License as  published  by  the  Free  Software
  13.  *        Foundation;  either  version 2 of the License, or  (at
  14.  *        your option) any later version.
  15.  */
  16. #include "config.h"
  17.  
  18. #if HAVE_AFINET
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <arpa/inet.h>
  22. #include <arpa/nameser.h>
  23. #include <netinet/in.h>
  24. #include <ctype.h>
  25. #include <errno.h>
  26. #include <netdb.h>
  27. #include <resolv.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <unistd.h>
  32. #include "support.h"
  33. #include "pathnames.h"
  34.  
  35.  
  36. struct addr {
  37.   struct sockaddr_in    addr;
  38.   char            *name;
  39.   struct addr        *next;
  40. };
  41.  
  42.  
  43. static struct addr *INET_nn = NULL;    /* addr-to-name cache        */
  44.  
  45.  
  46. static int
  47. INET_resolve(char *name, struct sockaddr_in *sin)
  48. {
  49.   struct hostent *hp;
  50.   struct netent *np;
  51.  
  52.   /* Grmpf. -FvK */
  53.   sin->sin_family = AF_INET;
  54.   sin->sin_port = 0;
  55.  
  56.   /* Default is special, meaning 0.0.0.0. */
  57.   if (!strcmp(name, "default")) {
  58.     sin->sin_addr.s_addr = INADDR_ANY;
  59.     return(1);
  60.   }
  61.  
  62.   /* Try the NETWORKS database to see if this is a known network. */
  63.   if ((np = getnetbyname(name)) != (struct netent *)NULL) {
  64.     sin->sin_addr.s_addr = htonl(np->n_net);
  65.     strcpy(name, np->n_name);
  66.     return(1);
  67.   }
  68.  
  69. #ifdef DEBUG
  70.   _res.options |= RES_DEBUG;
  71.   res_init();
  72. #endif
  73.  
  74.   if ((hp = gethostbyname(name)) == (struct hostent *)NULL) {
  75.     errno = h_errno;
  76.     return(-1);
  77.   }
  78.   memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], hp->h_length);
  79.   strcpy(name, hp->h_name);
  80.   return(0);
  81. }
  82.  
  83.  
  84. static int
  85. INET_rresolve(char *name, struct sockaddr_in *sin, int numeric)
  86. {
  87.   struct hostent *ent;
  88.   struct netent *np;
  89.   struct addr *pn;
  90.   unsigned long ad, host_ad;
  91.  
  92.   /* Grmpf. -FvK */
  93.   if (sin->sin_family != AF_INET) {
  94. #ifdef DEBUG
  95.     fprintf(stderr, "rresolve: unsupport address family %d !\n",
  96.                             sin->sin_family);
  97. #endif
  98.     errno = EAFNOSUPPORT;
  99.     return(-1);
  100.   }
  101.  
  102.   ad = (unsigned long) sin->sin_addr.s_addr;
  103.   if (ad == INADDR_ANY) {
  104.     if ((numeric & 0x7FFF) == 0) {
  105.         if (numeric & 0x8000) strcpy(name, "default");
  106.           else strcpy(name, "*");
  107.     } else {
  108.         sprintf(name, "%d.%d.%d.%d",
  109.             (int) (ad & 0xFF), (int) ((ad >> 8) & 0xFF),
  110.             (int) ((ad >> 16) & 0xFF),
  111.             (int) ((ad >> 24) & 0xFF));
  112.     }
  113.     return(0);
  114.   }
  115.  
  116. #if 0
  117.   INET_nn = NULL;
  118. #endif
  119.   pn = INET_nn;
  120.   while (pn != NULL) {
  121.     if (pn->addr.sin_addr.s_addr == ad) {
  122.         strcpy(name, pn->name);
  123.         return(0);
  124.     }
  125.     pn = pn->next;
  126.   }
  127.  
  128.   host_ad = ntohl(ad);
  129.   np = NULL;
  130.   ent = NULL;
  131.   if ((numeric & 0x7FFF) == 0) {
  132.       if ((host_ad & 0xFF) != 0)  {
  133.         ent = gethostbyaddr((char *) &ad, 4, AF_INET);
  134.         if (ent != NULL)
  135.             strcpy(name, ent->h_name);
  136.     } else {
  137.         np = getnetbyaddr(host_ad, AF_INET);
  138.         if (np != NULL) {
  139.             strcpy(name, np->n_name);
  140.         }
  141.     }
  142.   }
  143.   if ((ent == NULL) && (np == NULL)) {
  144.     sprintf(name, "%d.%d.%d.%d",
  145.         (int) (ad & 0xFF), (int) ((ad >> 8) & 0xFF),
  146.         (int) ((ad >> 16) & 0xFF),
  147.         (int) ((ad >> 24) & 0xFF));
  148.   }
  149.   pn = (struct addr *)malloc(sizeof(struct addr));
  150.   pn->addr = *sin;
  151.   pn->next = INET_nn;
  152.   pn->name = (char *) malloc(strlen(name) + 1);
  153.   strcpy(pn->name, name);
  154.   INET_nn = pn;
  155.  
  156.   return(0);
  157. }
  158.  
  159.  
  160. static void
  161. INET_reserror(char *text)
  162. {
  163.   herror(text);
  164. }
  165.  
  166.  
  167. /* Display an Internet socket address. */
  168. static char *
  169. INET_print(unsigned char *ptr)
  170. {
  171.   return(inet_ntoa((*(struct in_addr *) ptr)));
  172. }
  173.  
  174.  
  175. /* Display an Internet socket address. */
  176. static char *
  177. INET_sprint(struct sockaddr *sap, int numeric)
  178. {
  179.   static char buff[128];
  180.  
  181.   if (sap->sa_family == 0xFFFF || sap->sa_family == 0) return("[NONE SET]");
  182.   if (INET_rresolve(buff, (struct sockaddr_in *) sap, numeric) != 0)
  183.                             return(NULL);
  184.   return(buff);
  185. }
  186.  
  187.  
  188. static int
  189. INET_input(char *bufp, struct sockaddr *sap)
  190. {
  191.   return(INET_resolve(bufp, (struct sockaddr_in *) sap));
  192. }
  193.  
  194.  
  195. struct aftype inet_aftype = {
  196.   "inet",    "DARPA Internet",    AF_INET,    sizeof(unsigned long),
  197.   INET_print,    INET_sprint,        INET_input,    INET_reserror
  198. };
  199.  
  200.  
  201. #endif    /* HAVE_AFINET */
  202.