rarpd.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,357 行 · 第 1/3 页

C
1,357
字号
			/* The host hardware info -ar$sha; need to get it */			if (ioctl(fid, EIOCDEVP, &devparams) < 0) {				syslog(LOG_ERR, "%m:device");				exit(1);			}			/* NOTE: The host is assumed to have an ethernet			 * address of 6 bytes.			 */			send_pack[22] = devparams.end_addr[0]; 			send_pack[23] = devparams.end_addr[1]; 			send_pack[24] = devparams.end_addr[2]; 			send_pack[25] = devparams.end_addr[3]; 			send_pack[26] = devparams.end_addr[4]; 			send_pack[27] = devparams.end_addr[5]; 						/* The host IP address - ar$spa; need to fetch it */			if ((gethostname(lhostname, sizeof(lhostname))) < 0) {				syslog(LOG_ERR, "%m: gethostname");					exit(1);			}			/* get the host info */			do {				lhost = gethostbyname(lhostname);			} while (lhost != NULL && lhost->h_addrtype != AF_INET);			if (lhost == NULL) {				syslog(LOG_ERR, "%m:gethostbyname");				exit(1);			}			/* NOTE: An assumption is made that the			 * length of the address returned is contained			 * in 4 bytes.			 * The address is returned in the network			 * byte order.			 */			send_pack[28] = lhost->h_addr[0];			send_pack[29] = lhost->h_addr[1];			send_pack[30] = lhost->h_addr[2];			send_pack[31] = lhost->h_addr[3];			/* The targets hardware address - ar$tha.			 * This can be different from the source 			 * of the RARP request.			 */			send_pack[32] = recv_pack[32];			send_pack[33] = recv_pack[33];			send_pack[34] = recv_pack[34];			send_pack[35] = recv_pack[35];			send_pack[36] = recv_pack[36];			send_pack[37] = recv_pack[37];			/* The reason for this whole thing ...!			 * the targets IP address - ar$tpa.			 */			send_pack[38] = list_ptr->ip[0];			send_pack[39] = list_ptr->ip[1];			send_pack[40] = list_ptr->ip[2];			send_pack[41] = list_ptr->ip[3];			if (debug) {	/* Print the entire packet to be sent */				syslog(LOG_DEBUG, "THE CONTENTS OF THE PACKET TO BE SENT ARE: ");				sprintf(log_msg,"Destination(6) : "); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, ':') + 1;				for (i = 0; i < 6; i++,msg_len += 3)					sprintf(log_msg + msg_len, "%.2x:", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg , "Source(6) : "); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, ':') + 1;				for (i = 6; i < 12; i++,msg_len += 3)					sprintf(log_msg + msg_len, "%.2x:", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg , "Packet type(2): 0x"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, 'x') + 1;				for (i = 12; i < 14; i++,msg_len += 2)					sprintf(log_msg + msg_len , "%.2x", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg , "Hardware addr. space type(2): 0x"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, 'x') + 1;				for (i = 14; i < 16; i++, msg_len++)					sprintf(log_msg + msg_len, "%.2x", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "Protocol addr. space type(2):0x"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, 'x') + 1;				for (i = 16; i < 18; i++,msg_len += 2)					sprintf(log_msg + msg_len, "%.2x", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "Hardware addr. length(1): 0x"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, 'x');				sprintf(log_msg + msg_len + 1, "%.2x", send_pack[18] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "IP addr. length(1): 0x"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, 'x');				sprintf(log_msg + msg_len + 1, "%.2x", send_pack[19] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "RARP type(2): 0x");				/* search for the delimiter */				msg_len = delimit(log_msg, 0, 'x') + 1;				for (i = 20; i < 22; i++,msg_len++)					sprintf(log_msg + msg_len, "%.2x", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "Source hardware addr.(6):"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, ':') + 1;				for (i = 22; i < 28; i++,msg_len += 3)					sprintf(log_msg + msg_len, "%.2x:", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "Source IP addr.(4): "); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, ':') + 1;				for (i = 28; i < 32; i++) {					sprintf(log_msg + msg_len, "%d.", send_pack[i] & 0xFF); 					msg_len = delimit (log_msg + msg_len, msg_len, '.') + 1;				}				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "Target hardware addr.(6):"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, ':') + 1;				for (i = 32; i < 38; i++, msg_len += 3)					sprintf(log_msg + msg_len, "%.2x:", send_pack[i] & 0xFF); 				syslog(LOG_DEBUG, "%s", log_msg);				sprintf(log_msg, "Target IP addr.(4):"); 				/* search for the delimiter */				msg_len = delimit(log_msg, 0, ':') + 1;				for (i = 38; i < 42; i++) {					sprintf(log_msg + msg_len, "%d.", send_pack[i] & 0xFF); 					msg_len = delimit (log_msg + msg_len, msg_len, '.') + 1;				}				/* Put this information into the syslog */				syslog(LOG_DEBUG, "%s", log_msg);			}			return(42); 	/* return # of bytes sent */		} else {			/* go to the next element in the list */			if ((list_ptr = list_ptr->next) == NULL)/* end of list*/				return(-1);			else				continue;		}	}} /*********************************************************************  * search for a delimiter  ********************************************************************/delimit(buffer, len, delimiter)char *buffer;int len;char delimiter;{	int i;	for (i = 0; buffer[i] != delimiter; i++, len++)		;	/* nop */	return(len);}int Fid;struct endevp DevParams;/* * Program to detect broadcast packets for * Reverse ARP using the packet filter. * The filter need not be run in the promiscuous * mode; the filter accepts all broadcast packets. */set_filter(devname)char *devname;{	struct eniocb IOCB;	short enmode;	int backlog = -1;	char *packet;	/* Open the device specified - should not fail */	if ((Fid = pfopen(devname, 2)) < 0) {		syslog(LOG_ERR, "%m: %s", devname);		exit(1);	}	if (ioctl(Fid, EIOCDEVP, &DevParams) < 0) {		syslog(LOG_ERR, "%m %s", devname);		exit(1);	}	if (verbose) 		PrintParams();			IOCB.en_rtout = 100;	/* in clock ticks */	if (ioctl(Fid, EIOCSETP, &IOCB) < 0) {		syslog(LOG_ERR, "%m %s", devname);		exit(1);	}	/* set the filter */	enmode = ENBATCH|ENTSTAMP|ENPROMISC|ENNONEXCL;	if (ioctl(Fid, EIOCMBIC, &enmode) < 0) {		syslog(LOG_ERR, "%m %s", devname);		exit(1);	}	if (ioctl(Fid, EIOCSETW, &backlog) < 0) {		syslog(LOG_ERR, "%m %s", devname);		exit(1);	}	BuildFilter();	return(Fid);		/* return the file descriptor */	}/* * Filter checks for a reverse ARP packet. * * Design: *	The filter checks the type of the packet. If it *	isn't a RARP packet, it gets junked.  *	After confirming it to be a RARP packet *	the type field of the RARP packet is checked. Only *	type 3 packets - request reverse - are accepted. *	Packet types 1,2 and 4 are ignored. If the *	packet passes the test, it is checked to see * 	if it was a broadcast RARP. *	This design provides the minimum amount of *	processing overhead. *  */BuildFilter(){	struct enfilter Filter;	Filter.enf_Priority =  36;/* The priority */	Filter.enf_FilterLen = 0; /* The length of the filter */	/* Check the type field in the EtherHeader */	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHWORD + 6;	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;		Filter.enf_Filter[Filter.enf_FilterLen++] = F_RARP;		/* Check the type field in the RARP packet */	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHWORD + 10;	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;		/* Check if it is a request packet of RARP */	Filter.enf_Filter[Filter.enf_FilterLen++] = F_REQREVR;	/* If the above test is true go and check the 	 * destination address. Is it a broadcast packet?	 */	/* Check the first word of destination address */	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHWORD + 0;	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;	Filter.enf_Filter[Filter.enf_FilterLen++] = 0xFFFF; 	/* Check the second word of destination address */    	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHWORD + 1;	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;	Filter.enf_Filter[Filter.enf_FilterLen++] = 0xFFFF;	/* Check the third word of destination address */	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHWORD + 2;	Filter.enf_Filter[Filter.enf_FilterLen++] = ENF_PUSHLIT | ENF_EQ;	Filter.enf_Filter[Filter.enf_FilterLen++] = 0xFFFF;	/* Set the filter */	if (ioctl(Fid, EIOCSETF, &Filter) < 0) {		syslog(LOG_ERR, "%m: could not set filter");		exit(1);	}	}PrintParams(){	char log_msg[MSG_SIZE]; /* for logging in messages */	int msg_len;            /* the current length */	int i;	syslog(LOG_INFO, "DEVICE PARAMETERS:");	sprintf(log_msg, "Device type: ");	msg_len = delimit (log_msg,0,':') + 1;	switch (DevParams.end_dev_type) {		case ENDT_3MB:			sprintf(log_msg + msg_len, "ENDT_3MB");			break;		case ENDT_BS3MB:			sprintf(log_msg + msg_len, "ENDT_BS3MB");			break;		case ENDT_10MB:			sprintf(log_msg + msg_len, "ENDT_10MB");			break;		default:			sprintf(log_msg + msg_len, "%d\n", DevParams.end_dev_type);			break;	}	syslog(LOG_INFO, "%s", log_msg);	syslog(LOG_INFO, "Address Length: %d", DevParams.end_addr_len);	syslog(LOG_INFO, "Header Length: %d", DevParams.end_hdr_len);	syslog(LOG_INFO, "MTU: %d", DevParams.end_MTU);	sprintf(log_msg, "Hardware address -> ");	msg_len = delimit (log_msg, 0, '>') + 1;	for (i = 0; i < 6; i++, msg_len++) {		sprintf( log_msg + msg_len, "%.2x", 0xFF & DevParams.end_addr[i]);		msg_len += 2;		sprintf(log_msg + msg_len, ":");	}	syslog(LOG_INFO, "%s", log_msg);	sprintf(log_msg, "Broadcast address -> ");	msg_len = delimit (log_msg, 0, '>') + 1;	for (i = 0; i < 6; i++, msg_len++) {		sprintf( log_msg + msg_len, "%.2x", 0xFF & DevParams.end_broadaddr[i]);		msg_len += 2;		sprintf(log_msg + msg_len, ":");	}	syslog(LOG_INFO, "%s", log_msg);}PrintBits(len, data)int len;u_char *data;{	char log_msg[MSG_SIZE]; /* for logging in messages */	int msg_len;            /* the current length */	int i;	unsigned int j;	unsigned int typ, type1, type2;	type1 = data[12];	type2 = data[13];	typ   = type1 << 8;	typ   = (typ | type2)&0xFFFF;/* just paranoid */	/* check the packet type received */	switch(typ) {		case RARP:			sprintf(log_msg, "RARP Broadcast from Host -> ");			break;		default: /* Should NEVER happen, unless the filter bombs */			syslog(LOG_ERR, "Unknown Broacast detected ....!!!");			syslog(LOG_ERR, "The type received was %x", typ & 0xFFFF);			sprintf(log_msg, "Unknown Broadcast from Host -> ");			break;	}	/* Print the source ethernet address */	msg_len = delimit (log_msg, 0, '>') + 1;	for (i = 6; i < 12; i++, msg_len++) {		sprintf( log_msg + msg_len, "%.2x", 0xFF & data[i]);		msg_len += 2;		sprintf(log_msg + msg_len, ":");	}	syslog(LOG_INFO, "%s", log_msg);}/* * This contains routines to read and write packets from and * to the network. *//***************************************************************** * 	listen_4_rarp reads the buffer of the device in  * question and retuns the contents of the packet when * a packet arrives. * ****************************************************************/listen_4_rarp (fid, buffer, buf_size)int fid;char *buffer;int buf_size;{	int buflen;	long clock;	/* to keep track of time in verbose */	while (1) {		buflen = read(fid, buffer, buf_size);		if (buflen < 0) {			perror("rarpd: read:");			return(-1);		} else {			if (buflen == 0) {	/* nothing as yet */				continue;			} else {				if (verbose) {					syslog(LOG_INFO, "Received %d bytes:", buflen);					PrintBits(buflen, buffer);				}				return(buflen);	/* Received a packet */			}		}	}}/***************************************************************** *	send_rarp_resp is a routine to write back the RARP reply back * on the device. It sends out a response to the RARP request * received. * ****************************************************************/send_rarp_resp (fid, buffer, buf_size)int fid;char *buffer;int buf_size;{	int nbytes;	if ((nbytes = write (fid, buffer, buf_size)) < 0) {		syslog(LOG_ERR, "%m write to device failed");		exit(1);	}	if (debug || verbose)		syslog(LOG_INFO, "Sent out response");}

⌨️ 快捷键说明

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