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

📄 ethersim.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//*  * ethersim.c -- * *	 Simuation of a local ethernet with a gateway interface. *	 This program simulates a local ethernet with a gateway machine *	 attached to it.  The simulated ethernet accepts ethernet packets *	 that arrive on the special UDP port.  It is assumed that these *	 packets are send by the network module of simos services running *	 on top of Unix.  This program decodes the ethernet header and  *	 uses it to determine which UDP port to output the packet on. *	 This is done by keeping track of the ethernet address of the machine *	 sending packets to the ethernet port. * *	 When this program receives an ethernet packet of type IP to an IP *	 destination address outside the subnet of the local ethernet, it *	 outputs the packet to the local (phsyical) ethernet attached to  *	 the machine.  By doing this the program acts like a gateway machine. * *	 The program also opens the network interface of the machines and  *	 grabs any packets with an IP destination of the simulated subnet.   *	 This is done using Sun's NIT protocol and packet filter.  Packets *	 addressed to a known simulated host will be forward on to that  *	 host's UDP port.   * *	 NOTES: *	    1) Because this program uses NIT to get packets from the outside *	       packets arriving at network interfaces other than the one *	       specified are not seen.  In particular, packets sent thru *	       the loopback (lo0) interface are not seen by this program.  *	       This means that processes on the local machine can't talk IP *	       to the simulated machines.   *	    2) This program is a big security hole because it accepts packets *	       from an non-privledged UDP port and forwards them on to the *	       local ethernet.  I think that outputPacket() does enough  *	       checking to stop this from being a problem. * */#include <sys/types.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/file.h>#include <sys/wait.h>#include <sys/time.h>#include <net/if.h>#include <net/nit_if.h>#include <net/nit_pf.h>#include <net/nit_buf.h>#include <net/packetfilt.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#include <arpa/inet.h>#include <stdio.h>#include <signal.h>#include <pwd.h>#include <setjmp.h>#include <netdb.h>#include <errno.h>#include <strings.h>#include <varargs.h>#include <stropts.h>#include <poll.h>#include <search.h>#include <memory.h>#include <stdlib.h>#include <unistd.h>#include "hash.h"#include "ethersim.h"#ifdef MACH_NRP#include <netinet/udp.h>#include "nd.h"#endif/* * Program options setable from the command line. */u_long subnetaddr = 0xab404fe0; 	/* Subnet address (i.e. 171.64.79.224). */int    simportnumber = ETHER_SIM_PORT;  /* UDP port of simulated ethernet. */int    noipforwarding = 0;		/* Boolean - Don't forward ip packet. */char   interfacename[32] = "le0";	/* Name of interface to forward IP 					 * packets on. */int    verbose = 0;                     /* verbose: tell user about pkts */u_long   routeraddr = (u_long)-1;/* * Buffer to hold the current packet being transmitted on the ethernet.  * This must be big enought to hold an ethernet MTU and its header.  We * add 128 bytes for good measure. */char curPacket[ETHERMTU + sizeof(struct ether_header) + 128];int	simfd;		/* Open file descriptor of simulated ethernet port. */int	netfd;          /* Open file descriptor of network interface tap. */#ifdef MACH_NRPint nrpfd = -1;		/* Open file descriptor of socket or NRP server.  */char *nrphost = "localhost";  /* Host with NRP server. */struct sockaddr_in nrpaddr;int nrpaddrlen;struct ether_addr my_simetheraddr; /* My simulated ether addr. */struct in_addr my_simipaddr; /* My simulated ip addr. */#endif /* * The ethernet address and IP network address of the interface being used. */struct ether_addr myetheraddr;u_long mynetaddr;/* * The internet address and netmask of the interface being used. */u_long myinetAddr;u_long mynetmask;/* * HostInfoRecord - Info kept per simulated host. */typedef struct HostInfoRecord {    struct ether_addr etheraddr;/* Ethernet address of host. */    u_long inetAddr;		/* Internet address of host. */    struct sockaddr fromaddr;	/* Socket the of the simulated machines 				 * ethernet interface. */    int	 fromlen;		/* Length in bytes of fromaddr. */} HostInfoRecord;/* * Hash tables that map  *	etheraddrTable - Ethernet addresses to HostInfoRecord. *	ipaddrTable    - IP addresses to HostInfoRecord.  */Hash_Table etheraddrTable;Hash_Table ipaddrTable;/* * Stupid SunOS header missing stuff. */    /* Options stuff. */extern char *optarg;extern int optind;extern int getopt _ARGS_((int argc, char **argv, char *optstring));extern int fprintf ();  /* fprintf and fscanf are varags so no prototype. */extern int fscanf ();extern int fgetc _ARGS_((FILE *stream));extern void perror _ARGS_((char *msg));extern int pclose _ARGS_((FILE *stream));extern int ioctl _ARGS_((int fd, int request, caddr_t arg));extern int socket _ARGS_((int domain, int type, int protocol));extern int bind _ARGS_((int s, struct sockaddr *name, int namelen));extern int recvfrom _ARGS_((int s, char *buf, int len, int flags, 				struct sockaddr *from, int *fromlen));extern int sendto _ARGS_((int s, char *msg, int len, int flags, 				struct sockaddr *to, int tolen));extern u_long inet_netof _ARGS_((struct in_addr in));extern void bzero _ARGS_((void *b, int length));extern void bcopy _ARGS_((void *a, void *b, int length));extern int poll _ARGS_((struct pollfd *fds, unsigned long nfds, int timeout));extern int putmsg _ARGS_((int fd, struct strbuf *ctlptr, 				struct strbuf *dataptr, int flags));extern long strtol _ARGS_((char *str, char **ptr, int base));/* * offsetof() return the offset of a field into the structure. */#ifndef offsetof#define	offsetof(_t, _f)  ((int) &(((_t *) 0)->_f))#endif#define	NIT_DEV "/dev/nit"/* * Forward routine declartions. */int serviceSimPort _ARGS_((void));int serviceNetPort _ARGS_((void));#ifdef MACH_NRPint serviceNrpPort _ARGS_((void));int IsMachNRPPacket _ARGS_((struct ether_header *hdrPtr,int  size));#endifint initNITdevice  _ARGS_((char *device, u_long subNetAddr, u_long netmask));int outputPacket   _ARGS_((char *packet, int size));int lookupInterface _ARGS_((char *interfacename, u_long *inetAddrPtr, 				u_long *netmaskPtr));int validPacket _ARGS_((char *packet, int size, struct sockaddr *fromAddr, 				int fromlen));#ifdef MACH_NRP/* Forwards */#endif/* *---------------------------------------------------------------------- * * main --  * *       Main routine and loop for ethersim. * * Results: *      Only returns if an error occurs. * * Side effects: * *---------------------------------------------------------------------- */intmain(argc, argv)int argc;char *argv[];{    int	c, errflg;    struct sockaddr_in addr;    int	   nfds;    struct pollfd  fds[3];    int	   (*serviceRoutine[3])();    simfd = netfd = -1;    errflg = 0;#ifdef MACH_NRP#define OPTS "vfg:p:n:s:r:"#else#define OPTS "vfg:p:n:r:"#endif    while ((c = getopt(argc, argv,  OPTS)) != -1) {       switch (c) {        case 'v':	     verbose = 1;	     break;	case 'f':	     noipforwarding = 1;	     break;	case 'i':	     strncpy(interfacename, optarg, sizeof(optarg)-1);	     break;	case 'g':	     subnetaddr = inet_network(optarg);	     if (subnetaddr == (u_long) -1) {		 fprintf(stderr, "%s: Malformed gateway address %s\n", argv[0],					optarg);		 errflg++;	     }	     break;	case 'r':	     routeraddr = inet_network(optarg);	     if (routeraddr == (u_long) -1) {		 fprintf(stderr, "%s: Malformed router address %s\n", argv[0],					optarg);		 errflg++;	     }	     break;	case 'p':	     simportnumber = atoi(optarg);	     if (simportnumber < 0) {		 fprintf(stderr, "%s: Illegal port number %s\n", argv[0], 						optarg);		 errflg++;	     }	     break;#ifdef MACH_NRP	case 's':	    nrphost = optarg;	    break;#endif	case '?':	     errflg++;	}    }    if (errflg) {#ifdef MACH_NRP	(void)fprintf(stderr, 		"usage: %s [-v] [-g netaddr] [-p portnumber] [-n netmask] [-s nrphost]\n", 				argv[0]);#else	(void)fprintf(stderr, 		"usage: %s [-v] [-g netaddr] [-p portnumber] [-n netmask]\n", 				argv[0]);#endif	exit (2);    }    /*     * Create the socket that transmits on the simulated ethernet will be     * sent.  It is a UDP port number ETHER_SIM_PORT.  The mostly likely     * cause of failure is another ethersim running causing the bind     * to fail with address in use.     */    simfd = socket(AF_INET, SOCK_DGRAM, 0);    if (simfd < 0) {        perror("main: socket");        exit(1);    }    bzero((char *)&addr, sizeof(addr));    addr.sin_port = htons(simportnumber);    addr.sin_family = AF_INET;    if (bind(simfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        perror("main: bind");        exit(2);    }#ifdef MACH_NRP    /*     * Create the socket the commonicates with the nrp server.     */    nrpfd = socket(AF_INET, SOCK_DGRAM, 0);    if (nrpfd < 0) {        perror("main: nrp socket");        exit(1);    }    bzero((char *)&addr, sizeof(addr));    addr.sin_family = AF_INET;    if (bind(nrpfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        perror("main: nrp bind");        exit(2);    }    { 	struct hostent *host;        host = gethostbyname(nrphost);	if (!host) {		perror(nrphost);		exit(2);	}	nrpaddr.sin_family =  host->h_addrtype;	bcopy(host->h_addr, &nrpaddr.sin_addr, host->h_length);	nrpaddr.sin_port = htons(IPPORT_NDREQUEST);	nrpaddrlen = sizeof(nrpaddr);    }    bcopy("ETHERS", &my_simetheraddr, 6);      my_simipaddr.s_addr =  htonl(subnetaddr | 0xFEFE);#endif /* MACH_NRP */    if (!noipforwarding && (geteuid() != 0)) {	fprintf(stderr, "%s: not running as root - IP forwarding disabled\n",			argv[0]);	noipforwarding = 1;    }    if (!noipforwarding) {	if (lookupInterface(interfacename, &myinetAddr, &mynetmask) < 0) {	    fprintf(stderr, "Couldn't find interface %s\n", interfacename);	    exit(3);	}	{		struct in_addr tmp;		tmp.s_addr = myinetAddr;		mynetaddr = inet_netof(tmp);	}	netfd = initNITdevice(interfacename, subnetaddr, mynetmask);	if (netfd < 0) {	    fprintf(stderr, "Couldn't initialize network tap\n");	    exit(3);	}    }     /*     * Initialize mapping hash tables.     */    Hash_InitTable(&etheraddrTable, 0, 2);    Hash_InitTable(&ipaddrTable, 0, HASH_ONE_WORD_KEYS);    /*     * Loop waiting for packets to arrive.     */

⌨️ 快捷键说明

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