⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inet.c

📁 Linux下网络相关工具源代码。
💻 C
字号:
/* * lib/inet.c This file contains an implementation of the "INET" *              support functions for the net-tools. *              (NET-3 base distribution). * * Version:    $Id: inet.c,v 1.11 1999/03/03 21:43:08 philip Exp $ * * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> *              Copyright 1993 MicroWalt Corporation * * Modified: *960113 {1.21} Bernd Eckenfels :       rresolve cache bug. *960128 {1.22} Bernd Eckenfels :       endian bug in print *960203 {1.23} Bernd Eckenfels :       net-features support *960217 {1.24} Bernd Eckenfels :       get_sname *960219 {1.25} Bernd Eckenfels :       extern int h_errno *960329 {1.26} Bernd Eckenfels :       resolve 255.255.255.255  *980101 {1.27} Bernd Eckenfels :	resolve raw sockets in /etc/protocols *990302 {1.28} Phil Blundell   :       add netmask to INET_rresolve * *              This program is free software; you can redistribute it *              and/or  modify it under  the terms of  the GNU General *              Public  License as  published  by  the  Free  Software *              Foundation;  either  version 2 of the License, or  (at *              your option) any later version. */#include "config.h"/* FIXME.  Split this file into inet4.c for the IPv4 specific parts   and inet.c for those shared between IPv4 and IPv6.  */#if HAVE_AFINET || HAVE_AFINET6#include <netinet/in.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <ctype.h>#include <errno.h>#include <netdb.h>#include <resolv.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include "version.h"#include "net-support.h"#include "pathnames.h"#include "intl.h"#include "util.h"extern int h_errno;		/* some netdb.h versions don't export this */struct addr {    struct sockaddr_in addr;    char *name;    struct addr *next;};struct service {    int number;    char *name;    struct service *next;};static struct service *tcp_name = NULL, *udp_name = NULL, *raw_name = NULL;#if HAVE_AFINETstatic struct addr *INET_nn = NULL;	/* addr-to-name cache           */static int INET_resolve(char *name, struct sockaddr_in *sin){    struct hostent *hp;    struct netent *np;    /* Grmpf. -FvK */    sin->sin_family = AF_INET;    sin->sin_port = 0;    /* Default is special, meaning 0.0.0.0. */    if (!strcmp(name, "default")) {	sin->sin_addr.s_addr = INADDR_ANY;	return (1);    }    /* Look to see if it's a dotted quad. */    if (inet_aton(name, &sin->sin_addr)) {	return 0;    }    /* Try the NETWORKS database to see if this is a known network. */    if ((np = getnetbyname(name)) != (struct netent *) NULL) {	sin->sin_addr.s_addr = htonl(np->n_net);	strcpy(name, np->n_name);	return 1;    }#ifdef DEBUG    res_init();    _res.options |= RES_DEBUG;#endif    if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {	errno = h_errno;	return -1;    }    memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], hp->h_length);    strcpy(name, hp->h_name);    return 0;}static int INET_rresolve(char *name, struct sockaddr_in *sin, int numeric,			 unsigned int netmask){    struct hostent *ent;    struct netent *np;    struct addr *pn;    unsigned long ad, host_ad;    /* Grmpf. -FvK */    if (sin->sin_family != AF_INET) {#ifdef DEBUG	fprintf(stderr, _("rresolve: unsupport address family %d !\n"), sin->sin_family);#endif	errno = EAFNOSUPPORT;	return (-1);    }    ad = (unsigned long) sin->sin_addr.s_addr;    if (ad == INADDR_ANY) {	if ((numeric & 0x7FFF) == 0) {	    if (numeric & 0x8000)		strcpy(name, "default");	    else		strcpy(name, "*");	    return (0);	}    }    if (numeric & 0x7FFF) {	strcpy(name, inet_ntoa(sin->sin_addr));	return (0);    }#if 0    INET_nn = NULL;#endif    pn = INET_nn;    while (pn != NULL) {	if (pn->addr.sin_addr.s_addr == ad) {	    strcpy(name, pn->name);	    return (0);	}	pn = pn->next;    }    host_ad = ntohl(ad);    np = NULL;    ent = NULL;    if ((ad & (~ netmask)) != 0) {	ent = gethostbyaddr((char *) &ad, 4, AF_INET);	if (ent != NULL)	    strcpy(name, ent->h_name);    } else {	np = getnetbyaddr(host_ad, AF_INET);	if (np != NULL) {	    strcpy(name, np->n_name);	}    }    if ((ent == NULL) && (np == NULL)) {	strcpy(name, inet_ntoa(sin->sin_addr));    }    pn = (struct addr *) malloc(sizeof(struct addr));    pn->addr = *sin;    pn->next = INET_nn;    pn->name = (char *) malloc(strlen(name) + 1);    strcpy(pn->name, name);    INET_nn = pn;    return (0);}static void INET_reserror(char *text){    herror(text);}/* Display an Internet socket address. */static char *INET_print(unsigned char *ptr){    return (inet_ntoa((*(struct in_addr *) ptr)));}/* Display an Internet socket address. */static char *INET_sprint(struct sockaddr *sap, int numeric){    static char buff[128];    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));    if (INET_rresolve(buff, (struct sockaddr_in *) sap, numeric, 		      0xffffff00) != 0)	return (NULL);    return (buff);}char *INET_sprintmask(struct sockaddr *sap, int numeric, 		      unsigned int netmask){    static char buff[128];    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));    if (INET_rresolve(buff, (struct sockaddr_in *) sap, numeric,		      netmask) != 0)	return (NULL);    return (buff);}static int INET_getsock(char *bufp, struct sockaddr *sap){    char *sp = bufp, *bp;    unsigned int i;    unsigned val;    struct sockaddr_in *sin;    sin = (struct sockaddr_in *) sap;    sin->sin_family = AF_INET;    sin->sin_port = 0;    val = 0;    bp = (char *) &val;    for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {	*sp = toupper(*sp);	if ((*sp >= 'A') && (*sp <= 'F'))	    bp[i] |= (int) (*sp - 'A') + 10;	else if ((*sp >= '0') && (*sp <= '9'))	    bp[i] |= (int) (*sp - '0');	else	    return (-1);	bp[i] <<= 4;	sp++;	*sp = toupper(*sp);	if ((*sp >= 'A') && (*sp <= 'F'))	    bp[i] |= (int) (*sp - 'A') + 10;	else if ((*sp >= '0') && (*sp <= '9'))	    bp[i] |= (int) (*sp - '0');	else	    return (-1);	sp++;    }    sin->sin_addr.s_addr = htonl(val);    return (sp - bufp);}static int INET_input(int type, char *bufp, struct sockaddr *sap){    switch (type) {    case 1:	return (INET_getsock(bufp, sap));    default:	return (INET_resolve(bufp, (struct sockaddr_in *) sap));    }}static int INET_getnetmask(char *adr, struct sockaddr *m, char *name){    struct sockaddr_in *mask = (struct sockaddr_in *) m;    char *slash, *end;    int prefix;    if ((slash = strchr(adr, '/')) == NULL)	return 0;    *slash++ = '\0';    prefix = strtoul(slash, &end, 0);    if (*end != '\0')	return -1;    if (name) {	sprintf(name, "/%d", prefix);    }    mask->sin_family = AF_INET;    mask->sin_addr.s_addr = htonl(~(0xffffffffU >> prefix));    return 1;}struct aftype inet_aftype ={    "inet", NULL, /*"DARPA Internet", */ AF_INET, sizeof(unsigned long),    INET_print, INET_sprint, INET_input, INET_reserror,    NULL /*INET_rprint */ , NULL /*INET_rinput */ ,    INET_getnetmask,    -1,    NULL};#endif				/* HAVE_AFINET */static void add2list(struct service **namebase, struct service *item){    if (*namebase == NULL) {	*namebase = item;	item->next = NULL;    } else {	item->next = *namebase;	*namebase = item;    }}static struct service *searchlist(struct service *servicebase, int number){    struct service *item;    for (item = servicebase; item != NULL; item = item->next) {	if (item->number == number)	    return (item);    }    return (NULL);}static int read_services(void){    struct servent *se;    struct protoent *pe;    struct service *item;    setservent(1);    while ((se = getservent())) {	/* Allocate a service entry. */	item = (struct service *) malloc(sizeof(struct service));	if (item == NULL)	    perror("netstat");	item->name = strdup(se->s_name);	item->number = se->s_port;	/* Fill it in. */	if (!strcmp(se->s_proto, "tcp")) {	    add2list(&tcp_name, item);	} else if (!strcmp(se->s_proto, "udp")) {	    add2list(&udp_name, item);	} else if (!strcmp(se->s_proto, "raw")) {	    add2list(&raw_name, item);	}    }    endservent();    setprotoent(1);    while ((pe = getprotoent())) {	/* Allocate a service entry. */	item = (struct service *) malloc(sizeof(struct service));	if (item == NULL)	    perror("netstat");	item->name = strdup(pe->p_name);	item->number = htons(pe->p_proto);	add2list(&raw_name, item);    }    endprotoent();    return (0);}char *get_sname(int socknumber, char *proto, int numeric){    static char buffer[64], init = 0;    struct service *item;    if (socknumber == 0)	return ("*");    if (numeric) {	sprintf(buffer, "%d", ntohs(socknumber));	return (buffer);    }    if (!init) {	(void) read_services();	init = 1;    }    buffer[0] = '\0';    if (!strcmp(proto, "tcp")) {	if ((item = searchlist(tcp_name, socknumber)) != NULL)	    sprintf(buffer, "%s", item->name);    } else if (!strcmp(proto, "udp")) {	if ((item = searchlist(udp_name, socknumber)) != NULL)	    sprintf(buffer, "%s", item->name);    } else if (!strcmp(proto, "raw")) {	if ((item = searchlist(raw_name, socknumber)) != NULL)	    sprintf(buffer, "%s", item->name);    }    if (!buffer[0])	sprintf(buffer, "%d", ntohs(socknumber));    return (buffer);}#endif				/* HAVE_AFINET || HAVE_AFINET6 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -