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

📄 arpd.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/*  * arpd.c -- * *	A program to reply to ARP and RARP requests.  This program *	only translates between Internet and Ethernet addresses.  See *	RFC826 for details of the ARP protocol, and RFC903 for details *	of the RARP protocol. * * Copyright 1989 Regents of the University of California * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies.  The University of California * makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without * express or implied warranty. */#ifndef lintstatic char rcsid[] = "$Header: /hive/cvsroot/simulation/apps/unix/ethersim/sun/arpd.c,v 1.3 1997/02/03 20:24:17 verghese Exp $ SPRITE (Berkeley)";#endif not lint#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <net/if_arp.h>#include <netinet/in.h>#include <sys/file.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/time.h>#include <net/if.h>#include <netinet/if_ether.h>int arpverbose = 0;/* * The ARP/RARP packet size is defined below.  Because of structure * alignment differences between machines, it isn't safe to use * sizeof with the structure. */#define ARP_PACKET_SIZE 42static int FindArpReply(unsigned long dstipaddr, struct ether_addr *etherdst);extern unsigned long FindGateway(unsigned long);/* *---------------------------------------------------------------------- * * ArpRequest -- * *	Handle an ARP request. * * Results: *	None. * * Side effects: *	A response is transmitted for the ARP request. * *---------------------------------------------------------------------- */intArpRequest(pin, pinlen, pout, poutlen)	void *pin;	int pinlen;	void *pout;	int *poutlen;{    struct {	struct ether_header hdr;	struct ether_arp arp;    } packet;    int bytesRead, etherType, protocolType, hardwareType, arpOp;    unsigned long senderAddr, targetAddr;    struct ether_addr eaddr;    /*     * Read and validate the ARP packet.     */    bytesRead = (sizeof(packet) > pinlen) ? pinlen : sizeof(packet);    bcopy(pin, &packet, bytesRead);     if (bytesRead < 0) {	printf("arpd couldn't read ARP packet: %d\n", errno);	return 0;    }    if (bytesRead < ARP_PACKET_SIZE) {	if (arpverbose)		printf("arpd got short ARP packet: only %d bytes\n", bytesRead);	return 0;    }    etherType = ntohs(packet.hdr.ether_type);    if (etherType != ETHERTYPE_ARP) {	if (arpverbose)		printf("arpd got ARP packet with ether_type 0x%x\n", etherType);	return 0;    }    arpOp = ntohs(packet.arp.ea_hdr.ar_op);    if (arpOp != ARPOP_REQUEST) {	if (arpverbose) {	    printf("arpd got ARP packet with unknown op %d\n", arpOp);	}	return 0;    }    hardwareType = ntohs(packet.arp.ea_hdr.ar_hrd);    if (hardwareType != ARPHRD_ETHER) {	if (arpverbose) {	    printf("arpd got ARP packet with unknown hardware type 0x%x\n",		    hardwareType);	}	return 0;    }    protocolType = ntohs(packet.arp.ea_hdr.ar_pro);    if (protocolType != ETHERTYPE_IP) {	if (arpverbose) {	    printf("arpd got ARP packet with unknown protocol type 0x%x\n",		    protocolType);	}	return 0;    }    bcopy((char *) packet.arp.arp_spa, (char *) &senderAddr,	    sizeof(senderAddr));    bcopy((char *) packet.arp.arp_tpa, (char *) &targetAddr,	    sizeof(targetAddr));          if(!FindArpReply(targetAddr, &eaddr)) {       /*         * If we do not find the address in the arp cache,        * do a ping of the address using a "system" call        * This way we will find it the next time, maybe        */       char buf[128];       struct in_addr *in =  (struct in_addr *)&targetAddr;       strcpy(buf, "/usr/etc/ping ");       strcat(buf, inet_ntoa(*in));       strcat(buf, " &");       if (arpverbose)          printf("%#x not in arp cache, doing %s\n", targetAddr, buf);       system(buf);	return 0;    }    /*     * Reverse sender and target fields, and respond with the appropriate     * Ethernet address.  No need to fill in the source in the packet     * header:  the kernel automatically overwrites it.     */    bcopy((char *) &targetAddr, (char *) packet.arp.arp_spa,	    sizeof(targetAddr));    bcopy((char *) &senderAddr, (char *) packet.arp.arp_tpa,	    sizeof(senderAddr));    bcopy((char *) &packet.arp.arp_sha, (char *) &packet.arp.arp_tha,	    sizeof(struct ether_addr));    bcopy((char *) &eaddr, (char *) &packet.arp.arp_sha,	    sizeof(struct ether_addr));    packet.arp.ea_hdr.ar_op = htons(ARPOP_REPLY);    bcopy((char *) &packet.hdr.ether_shost, (char *) &packet.hdr.ether_dhost,	    sizeof(struct ether_addr));    bcopy((char *) &packet, pout, ARP_PACKET_SIZE);    (*poutlen) = ARP_PACKET_SIZE;    return 1;}static intFindArpReply(dstipaddr, etherdst)	unsigned long dstipaddr;	struct ether_addr *etherdst;{    FILE *pfd;    unsigned int gateway;    int found;    gateway = FindGateway(dstipaddr);    if (gateway == (unsigned int ) -1) {	return 0;    }    pfd = popen("/usr/etc/arp -a", "r");    if (pfd == (FILE *) NULL) {	return 0;    }    found = 0;    while(1) {	unsigned int ip1,ip2,ip3,ip4,e1,e2,e3,e4,e5,e6;	struct in_addr *ia = (struct in_addr *) &gateway;	int n;    	char name[256], eaddrstring[32];	char line[1024];	extern int verbose;	if (fgets(line, sizeof(line), pfd) == 0)	  break;	if (verbose) {	  fprintf(stderr, "arp request result: %s", line);	}	n = sscanf(line, "%s (%d.%d.%d.%d) at %s\n", 		name, &ip1,&ip2,&ip3,&ip4, eaddrstring);	if (verbose) {	  fprintf(stderr, "n=%d name=%s\n", n, name);	}	if (n < 0) 		break;	if (n != 6) 		continue;	if (    (ip1 == ia->S_un.S_un_b.s_b1) &&		(ip2 == ia->S_un.S_un_b.s_b2) &&		(ip3 == ia->S_un.S_un_b.s_b3) &&		(ip4 == ia->S_un.S_un_b.s_b4))  {	        struct ether_addr *e = ether_aton(eaddrstring);                if (verbose) {#define	A(x) (e->ether_addr_octet[x])                   fprintf(stderr, "ARP entry found %s %d.%d.%d.%d %s %x:%x:%x:%x:%x:%x\n",                            name, ip1, ip2, ip3, ip4, eaddrstring, A(1), A(2), A(3), A(4), A(5), A(6));                }		if (e != NULL) {			*etherdst = *e;			found = 1;		}		break;	}    }     pclose(pfd);    return found;}     

⌨️ 快捷键说明

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