[insert project logo here (125x200px max)]

Navigator

Mailinglists

Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums.

Copyright and Licensing Information

Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL).

All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License.

All sourcecode is made publicly available.

Acknowledgement

Splash and the Splash website are hosted by SourceForge.net

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap-1.1-wjdb/lib/inet.c

Go to the documentation of this file.
00001 /*
00002  * lib/inet.c   This file contains an implementation of the "INET"
00003  *      support functions for the net-tools.
00004  *      (NET-3 base distribution).
00005  *
00006  * Version: lib/inet.c 1.26 1996-03-29
00007  *
00008  * Author:  Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
00009  *      Copyright 1993 MicroWalt Corporation
00010  *
00011  * Modified:
00012  *960113 {1.21} Bernd Eckenfels :   rresolve cache bug.
00013  *960128 {1.22} Bernd Eckenfels :   endian bug in print
00014  *960203 {1.23} Bernd Eckenfels :       net-features support
00015  *960217 {1.24} Bernd Eckenfels :   get_sname
00016  *960219 {1.25} Bernd Eckenfels :   extern int h_errno
00017  *960329 {1.26} Bernd Eckenfels :   resolve 255.255.255.255 
00018  *
00019  *      This program is free software; you can redistribute it
00020  *      and/or  modify it under  the terms of  the GNU General
00021  *      Public  License as  published  by  the  Free  Software
00022  *      Foundation;  either  version 2 of the License, or  (at
00023  *      your option) any later version.
00024  */
00025 #include "config.h"
00026 
00027 #if HAVE_AFINET
00028 #include <sys/types.h>
00029 #include <sys/socket.h>
00030 #include <netinet/in.h>
00031 #include <arpa/inet.h>
00032 #include <arpa/nameser.h>
00033 #include <ctype.h>
00034 #include <errno.h>
00035 #include <netdb.h>
00036 #include <resolv.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <stdio.h>
00040 #include <unistd.h>
00041 #include "version.h"
00042 #include "net-support.h"
00043 #include "pathnames.h"
00044 #include "intl.h"
00045 
00046 extern int h_errno;  /* some netdb.h versions don't export this */
00047 
00048 struct addr {
00049   struct sockaddr_in    addr;
00050   char          *name;
00051   struct addr       *next;
00052 };
00053 
00054 struct service {
00055   int number;
00056   char *name;
00057   struct service *next;
00058 };
00059 
00060 static struct service *tcp_name = NULL,
00061               *udp_name = NULL,
00062               *raw_name = NULL;
00063 
00064 
00065 static struct addr *INET_nn = NULL; /* addr-to-name cache       */
00066 
00067 
00068 static int
00069 INET_resolve(char *name, struct sockaddr_in *sin)
00070 {
00071   struct hostent *hp;
00072   struct netent *np;
00073 
00074   /* Grmpf. -FvK */
00075   sin->sin_family = AF_INET;
00076   sin->sin_port = 0;
00077 
00078   /* Default is special, meaning 0.0.0.0. */
00079   if (!strcmp(name, "default")) {
00080     sin->sin_addr.s_addr = INADDR_ANY;
00081     return(1);
00082   }
00083 
00084   /* Look to see if it's a dotted quad. */
00085   if (inet_aton(name, &sin->sin_addr)) {
00086     return 0;
00087   }
00088 
00089   /* Try the NETWORKS database to see if this is a known network. */
00090   if ((np = getnetbyname(name)) != (struct netent *)NULL) {
00091     sin->sin_addr.s_addr = htonl(np->n_net);
00092     strcpy(name, np->n_name);
00093     return 1;
00094   }
00095 
00096 #ifdef DEBUG
00097   res_init();
00098   _res.options |= RES_DEBUG;
00099 #endif
00100 
00101   if ((hp = gethostbyname(name)) == (struct hostent *)NULL) {
00102     errno = h_errno;
00103     return -1;
00104   }
00105   memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], hp->h_length);
00106   strcpy(name, hp->h_name);
00107   return 0;
00108 }
00109 
00110 
00111 static int
00112 INET_rresolve(char *name, struct sockaddr_in *sin, int numeric)
00113 {
00114   struct hostent *ent;
00115   struct netent *np;
00116   struct addr *pn;
00117   unsigned long ad, host_ad;
00118 
00119   /* Grmpf. -FvK */
00120   if (sin->sin_family != AF_INET) {
00121 #ifdef DEBUG
00122     fprintf(stderr, _("rresolve: unsupport address family %d !\n"), sin->sin_family);
00123 #endif
00124     errno = EAFNOSUPPORT;
00125     return(-1);
00126   }
00127 
00128   ad = (unsigned long) sin->sin_addr.s_addr;
00129   if (ad == INADDR_ANY) {
00130     if ((numeric & 0x7FFF) == 0) {
00131         if (numeric & 0x8000) strcpy(name, "default");
00132           else strcpy(name, "*");
00133         return(0);
00134     }
00135   }
00136   if (numeric & 0x7FFF) {
00137     strcpy(name,inet_ntoa (sin->sin_addr));
00138     return(0);
00139   }
00140 
00141 #if 0
00142   INET_nn = NULL;
00143 #endif
00144   pn = INET_nn;
00145   while (pn != NULL) {
00146     if (pn->addr.sin_addr.s_addr == ad) {
00147         strcpy(name, pn->name);
00148         return(0);
00149     }
00150     pn = pn->next;
00151   }
00152 
00153   host_ad = ntohl(ad);
00154   np = NULL;
00155   ent = NULL;
00156   if ((host_ad & 0xFF) != 0)  {
00157     ent = gethostbyaddr((char *) &ad, 4, AF_INET);
00158     if (ent != NULL)
00159         strcpy(name, ent->h_name);
00160   } else {
00161     np = getnetbyaddr(host_ad, AF_INET);
00162     if (np != NULL) {
00163         strcpy(name, np->n_name);
00164     }
00165   }
00166   if ((ent == NULL) && (np == NULL)) {
00167     strcpy(name,inet_ntoa (sin->sin_addr));
00168   }
00169   pn = (struct addr *)malloc(sizeof(struct addr));
00170   pn->addr = *sin;
00171   pn->next = INET_nn;
00172   pn->name = (char *) malloc(strlen(name) + 1);
00173   strcpy(pn->name, name);
00174   INET_nn = pn;
00175 
00176   return(0);
00177 }
00178 
00179 
00180 static void
00181 INET_reserror(char *text)
00182 {
00183   herror(text);
00184 }
00185 
00186 
00187 /* Display an Internet socket address. */
00188 static char *
00189 INET_print(unsigned char *ptr)
00190 {
00191   return(inet_ntoa((*(struct in_addr *) ptr)));
00192 }
00193 
00194 
00195 /* Display an Internet socket address. */
00196 static char *
00197 INET_sprint(struct sockaddr *sap, int numeric)
00198 {
00199   static char buff[128];
00200 
00201   if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
00202     return strncpy (buff, _("[NONE SET]"), sizeof(buff));
00203   if (INET_rresolve(buff, (struct sockaddr_in *) sap, numeric) != 0)
00204                             return(NULL);
00205   return(buff);
00206 }
00207 
00208 
00209 static int
00210 INET_getsock(char *bufp, struct sockaddr *sap)
00211 {
00212   char *sp = bufp,*bp;
00213   unsigned int i;
00214   unsigned val;
00215   struct sockaddr_in *sin;
00216   
00217   sin             = (struct sockaddr_in *) sap;
00218   sin->sin_family = AF_INET;
00219   sin->sin_port   = 0;
00220 
00221   val = 0;
00222   bp=(char *)&val;
00223   for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {
00224     *sp = toupper(*sp);
00225     
00226     if ((*sp >= 'A') && (*sp <= 'F')) 
00227         bp[i] |= (int) (*sp - 'A') + 10;
00228     else if ((*sp >= '0') && (*sp <= '9'))
00229         bp[i] |= (int) (*sp - '0');
00230     else
00231         return(-1);
00232 
00233     bp[i] <<= 4;
00234     sp++;
00235     *sp = toupper(*sp);
00236     
00237     if ((*sp >= 'A') && (*sp <= 'F')) 
00238         bp[i] |= (int) (*sp - 'A') + 10;
00239     else if ((*sp >= '0') && (*sp <= '9'))
00240         bp[i] |= (int) (*sp - '0');
00241     else
00242         return(-1);
00243     
00244     sp++;
00245     }
00246     sin->sin_addr.s_addr = htonl (val);
00247 
00248     return(sp-bufp);
00249 }
00250 
00251 static int
00252 INET_input(int type, char *bufp, struct sockaddr *sap)
00253 {
00254   switch(type) {
00255     case 1:
00256         return(INET_getsock(bufp,sap));
00257     default:
00258         return(INET_resolve(bufp, (struct sockaddr_in *) sap));
00259   }
00260 }
00261 
00262 static int INET_getnetmask(char *adr, struct sockaddr *m, char *name)
00263 { 
00264     struct sockaddr_in *mask = (struct sockaddr_in *)m; 
00265     char *slash, *end; 
00266     int prefix; 
00267 
00268     if ((slash = strchr(adr, '/')) == NULL) 
00269         return 0; 
00270         
00271     *slash++ = '\0';
00272     prefix = strtoul(slash,&end,0);
00273     if (*end != '\0') 
00274         return -1; 
00275 
00276     if (name) {
00277         sprintf(name, "/%d", prefix); 
00278     }
00279         
00280     mask->sin_family = AF_INET; 
00281     mask->sin_addr.s_addr = htonl(~(0xffffffffU >> prefix)); 
00282     return 1;
00283 } 
00284 
00285 
00286 struct aftype inet_aftype = {
00287   "inet",   NULL, /*"DARPA Internet",*/ AF_INET,    sizeof(unsigned long),
00288   INET_print,   INET_sprint,        INET_input, INET_reserror,  
00289   NULL/*INET_rprint*/,  NULL/*INET_rinput*/,
00290   INET_getnetmask 
00291 };
00292 
00293 #endif  /* HAVE_AFINET || HAVE_AFINET6 */
00294 
00295 #if HAVE_AFINET || HAVE_AFINET6
00296 
00297 static void
00298 add2list(struct service **namebase, struct service *item) 
00299 {
00300   if (*namebase == NULL) {
00301     *namebase = item;
00302     item->next = NULL;
00303   } else {
00304     item->next = *namebase;
00305     *namebase = item;
00306   } 
00307 }
00308 
00309 
00310 static struct service *
00311 searchlist(struct service *servicebase, int number)
00312 {
00313   struct service *item;
00314 
00315   for(item = servicebase; item != NULL; item = item->next) {
00316     if (item->number == number) return(item);
00317   }
00318   return(NULL);
00319 }
00320 
00321 
00322 static int
00323 read_services(void)
00324 {
00325   struct servent *se;
00326   struct service *item;
00327 
00328   setservent(1);
00329   while((se=getservent())) {
00330     /* Allocate a service entry. */
00331     item = (struct service *) malloc(sizeof(struct service));
00332     if (item == NULL) perror("netstat"); 
00333     item->name = strdup(se->s_name);
00334     item->number = se->s_port;
00335 
00336     /* Fill it in. */
00337     if (! strcmp(se->s_proto, "tcp")) {
00338         add2list(&tcp_name,item);
00339     } else if (! strcmp(se->s_proto, "udp")) {
00340         add2list(&udp_name,item);
00341     } else if (! strcmp(se->s_proto, "raw")) {
00342         add2list(&raw_name,item);
00343     }
00344   }
00345   endservent();
00346   return(0);
00347 }
00348 
00349 
00350 char *
00351 get_sname(int socknumber, char *proto, int numeric)
00352 {
00353   static char buffer[64], init=0;
00354   struct service *item;
00355 
00356   if (socknumber == 0) return("*");
00357   if (numeric) {
00358     sprintf(buffer, "%d", ntohs(socknumber));
00359     return(buffer);
00360   }
00361   if (!init) {
00362     (void)read_services();
00363     init=1;
00364   }
00365   buffer[0]='\0';
00366   if (! strcmp(proto, "tcp")) {
00367     if ((item = searchlist(tcp_name, socknumber)) != NULL)
00368         sprintf(buffer, "%s", item->name);
00369   } else if (! strcmp(proto, "udp")) {
00370     if ((item = searchlist(udp_name, socknumber)) != NULL)
00371         sprintf(buffer, "%s", item->name);
00372   } else if (! strcmp(proto, "raw")) {
00373     if ((item = searchlist(raw_name, socknumber)) != NULL)
00374         sprintf(buffer, "%s", item->name);
00375 
00376   }
00377   if (!buffer[0])
00378     sprintf(buffer, "%d", ntohs(socknumber));
00379   return(buffer);
00380 }
00381 
00382 #endif  /* HAVE_AFINET || HAVE_AFINET6 */