[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 |
Splash - DocumentationSNMP Plus a Lightweight API for SNAP Handlingsnap-1.1-wjdb/lib/inet.cGo 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 */ |