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 + -
显示快捷键?