addrtoname.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 435 行

C
435
字号
/* * Copyright (c) 1988, 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * *  Internet, ethernet, port, and protocol string to address *  and address to string conversion routines *//* * SCCSID: @(#)addrtoname.c	4.1	ULTRIX	1/25/91 * Based on:static char rcsid[] =    "@(#) $Header: addrtoname.c,v 1.7 90/11/05 10:49:55 mccanne Exp $ (LBL)"; */#include <stdio.h>#include <strings.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <net/if.h>#include <netdb.h>#include <netinet/in.h>#include <netinet/if_ether.h>#include <arpa/inet.h>#include <signal.h>#include "interface.h"#include "addrtoname.h"#include "nametoaddr.h"#include "etherent.h"/* * hash tables for whatever-to-name translations */#define HASHNAMESIZE 4096struct hnamemem {	u_long addr;	char *name;	struct hnamemem *nxt;};struct hnamemem hnametable[HASHNAMESIZE];struct hnamemem tporttable[HASHNAMESIZE];struct hnamemem uporttable[HASHNAMESIZE];struct hnamemem eprototable[HASHNAMESIZE];struct enamemem {	u_short e_addr0;	u_short e_addr1;	u_short e_addr2;	char *e_name;	struct enamemem *e_nxt;};struct enamemem enametable[HASHNAMESIZE];/* * A faster replacement for inet_ntoa(). */char *intoa(addr)	u_long addr;{	register char *cp;	register u_int byte;	register int n;	static char buf[sizeof(".xxx.xxx.xxx.xxx")];	NTOHL(addr);	cp = &buf[sizeof buf];	*--cp = '\0';	n = 4;	do {		byte = addr & 0xff;		*--cp = byte % 10 + '0';		byte /= 10;		if (byte > 0) {			*--cp = byte % 10 + '0';			byte /= 10;			if (byte > 0)				*--cp = byte + '0';		}		*--cp = '.';		addr >>= 8;	} while (--n > 0);	return cp + 1;}static u_long f_netmask;static u_long f_localnet;static u_long netmask;/* * "getname" is written in this atrocious way to make sure we don't * wait forever while trying to get hostnames from yp. */#include <setjmp.h>jmp_buf getname_env;static voidnohostname(){	longjmp(getname_env, 1);}char *getname(addr)	u_long addr;{	register struct hnamemem *p;	register struct hostent *hp;	register u_long raddr = addr;	register char *cp;	p = &hnametable[ntohl(raddr) & (HASHNAMESIZE-1)]; 	for (; p->nxt; p = p->nxt) {		if (p->addr == raddr)			return (p->name);	}	p->addr = raddr;	p->nxt = (struct hnamemem *)calloc(1, sizeof (*p));	/*	 * Only print names when:	 * 	(1) -n was not given.	 *	(2) Address is foreign and -f was given.  If -f was not 	 *	    present, f_netmask and f_local are 0 and the second	 *	    test will succeed.	 *	(3) The host portion is not 0 (i.e., a network address).	 *	(4) The host portion is not broadcast.	 */	if (!nflag && (raddr & f_netmask) == f_localnet	    && (raddr &~ netmask) != 0 && (raddr | netmask) != 0xffffffff) {		if (!setjmp(getname_env)) {			(void)signal(SIGALRM, (int (*)())nohostname);			(void)alarm(20);			hp = gethostbyaddr((char *)&addr, sizeof(addr), 					   AF_INET);			(void)alarm(0);			if (hp) {				char *index();				char *dotp;					u_int len = strlen(hp->h_name) + 1;				p->name = (char *)malloc(len);				(void)strcpy(p->name, hp->h_name);				if (Nflag) {					/* Remove domain qualifications */					dotp = index(p->name, '.');					if (dotp)						*dotp = 0;				}				return (p->name);			}		}	}	cp = intoa(raddr);	p->name = (char *)malloc((unsigned)(strlen(cp) + 1));	(void)strcpy(p->name, cp);	return (p->name);}static char hex[] = "0123456789abcdef";/* Find the hash node that corresponds the ether address 'ep'. */static inline struct enamemem *lookup_emem(ep)	u_char *ep;{	register u_int i, j;	struct enamemem *tp;	i = *(u_short *)(ep + 4);	j = *(u_short *)(ep + 2);	tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];	while (tp->e_nxt)		if (tp->e_addr0 == i &&		    tp->e_addr1 == j &&		    tp->e_addr2 == *(u_short *)ep)			return tp;		else			tp = tp->e_nxt;	tp->e_addr0 = i;	tp->e_addr1 = j;	tp->e_addr2 = *(u_short *)ep;	tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));	return tp;}char *etheraddr_string(ep)	register u_char *ep;{	register u_int i, j;	register char *cp;	register struct enamemem *tp;	tp = lookup_emem(ep);	if (tp->e_name)		return tp->e_name;#ifdef ETHER_SERVICE	if (!nflag) {		cp = ETHER_ntohost(ep);		if (cp) {			tp->e_name = cp;			return cp;		}	}#endif			tp->e_name = cp = (char *)malloc(sizeof("00:00:00:00:00:00"));	if (j = *ep >> 4)		*cp++ = hex[j];	*cp++ = hex[*ep++ & 0xf];	for (i = 5; (int)--i >= 0;) {		*cp++ = ':';		if (j = *ep >> 4)			*cp++ = hex[j];		*cp++ = hex[*ep++ & 0xf];	}	*cp = '\0';	return (tp->e_name);}char *etherproto_string(port)	u_short port;{	register char *cp;	register struct hnamemem *tp;	register u_long i = port;	for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)		if (tp->addr == i)			return (tp->name);	tp->name = cp = (char *)malloc(sizeof("0000"));	tp->addr = i;	tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));	NTOHS(port);	*cp++ = hex[port >> 12 & 0xf];	*cp++ = hex[port >> 8 & 0xf];	*cp++ = hex[port >> 4 & 0xf];	*cp++ = hex[port & 0xf];	*cp++ = '\0';	return (tp->name);}char *tcpport_string(port)	u_short port;{	register struct hnamemem *tp;	register int i = port;	for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)		if (tp->addr == i)			return (tp->name);	tp->name = (char *)malloc(sizeof("00000"));	tp->addr = i;	tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));	(void)sprintf(tp->name, "%d", i);	return (tp->name);}char *udpport_string(port)	register u_short port;{	register struct hnamemem *tp;	register int i = port;	for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)		if (tp->addr == i)			return (tp->name);	tp->name = (char *)malloc(sizeof("00000"));	tp->addr = i;	tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));	(void)sprintf(tp->name, "%d", i);	return (tp->name);}static voidinit_servarray(){	struct servent *sv;	register struct hnamemem *table;	register int i;	while (sv = getservent()) {		NTOHS(sv->s_port);		i = sv->s_port & (HASHNAMESIZE-1);		if (strcmp(sv->s_proto, "tcp") == 0)			table = &tporttable[i];		else if (strcmp(sv->s_proto, "udp") == 0)			table = &uporttable[i];		else			continue;		while (table->name)			table = table->nxt;		if (nflag) {			char buf[32];			(void)sprintf(buf, "%d", sv->s_port);			table->name = (char *)malloc((unsigned)strlen(buf)+1);			(void)strcpy(table->name, buf);		} else {			table->name =				(char *)malloc((unsigned)strlen(sv->s_name)+1);			(void)strcpy(table->name, sv->s_name);		}		table->addr = sv->s_port;		table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));	}	endservent();}#include "etherproto.h"/* Static data base of ether protocol types. */struct eproto eproto_db[] = { 	{ "pup", ETHERTYPE_PUP },	{ "xns", ETHERTYPE_NS },	{ "ip", ETHERTYPE_IP },	{ "arp", ETHERTYPE_ARP },	{ "rarp", ETHERTYPE_REVARP },	{ "sprite", ETHERTYPE_SPRITE },	{ "mopdl", ETHERTYPE_MOPDL },	{ "moprc", ETHERTYPE_MOPRC },	{ "decnet", ETHERTYPE_DN },	{ "lat", ETHERTYPE_LAT },	{ "lanbridge", ETHERTYPE_LANBRIDGE },	{ "vexp", ETHERTYPE_VEXP },	{ "vprod", ETHERTYPE_VPROD },	{ "atalk", ETHERTYPE_ATALK },	{ "atalkarp", ETHERTYPE_AARP },	{ "loopback", ETHERTYPE_LOOPBACK },	{ (char *)0, 0 }};static voidinit_eprotoarray(){	register int i;	register struct hnamemem *table;	for (i = 0; eproto_db[i].s; i++) {		int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);		table = &eprototable[j];		while (table->name)			table = table->nxt;		table->name = eproto_db[i].s;		table->addr = ntohs(eproto_db[i].p);		table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));	}}static voidinit_etherarray(){#ifndef ETHER_SERVICE	FILE *fp;	struct etherent *ep;	struct enamemem *tp;	fp = fopen(ETHERS_FILE, "r");	if (fp == 0)		/* No data base; will have to settle for 		   numeric addresses. */		return;	while (ep = next_etherent(fp)) {		tp = lookup_emem(ep->addr);		tp->e_name = (char *)malloc((unsigned)strlen(ep->name)+1);		strcpy(tp->e_name, ep->name);	}#endif}voidinit_addrtoname(device, fflag)	char *device;	int fflag;{	u_long localnet;	lookup_net(device, &localnet, &netmask);	if (fflag) {		f_localnet = localnet;		f_netmask = netmask;	}	if (nflag)		/*		 * Simplest way to suppress names.		 */		return;	init_etherarray();	init_servarray();	init_eprotoarray();}

⌨️ 快捷键说明

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