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

📄 ethersim.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
    nfds = 0;    fds[nfds].fd = simfd;    fds[nfds].events = POLLIN;    serviceRoutine[nfds] = serviceSimPort;    nfds++;    if (netfd >= 0) {	fds[nfds].fd = netfd;	fds[nfds].events = POLLIN;    	serviceRoutine[nfds] = serviceNetPort;	nfds++;    }#ifdef MACH_NRP    if (nrpfd >= 0) {	fds[nfds].fd = nrpfd;	fds[nfds].events = POLLIN;    	serviceRoutine[nfds] = serviceNrpPort;	nfds++;    }#endif    while (1) {        int     n;	int	i;	fds[0].revents = fds[1].revents = fds[2].revents = 0;	n = poll(fds, nfds, 50);	if (n < 0) {	    if (errno == EINTR) continue;	    perror("poll");	    exit(1);	}	for (i = 0; i < nfds; i++) { 		if (fds[i].revents & POLLIN) {		    (void) serviceRoutine[i]();		}	}    }}/* *---------------------------------------------------------------------- * * serviceSimPort --  * *       Service a request that arrives at the simulated ethernet port. * * Results: *      -1 if problem occur with * * Side effects: * *---------------------------------------------------------------------- */intserviceSimPort(){    struct  ether_header  *hdrPtr;    struct sockaddr from;    int	    fromlen, n;    int	    etherAddrKey[2];    int xfersize;    Hash_Entry *entryPtr;    HostInfoRecord *srcHostInfo;    HostInfoRecord *dstHostInfo;    if (verbose) {      fprintf(stderr, "serviceSimPort()\n");    }    fromlen = sizeof (from);    n = recvfrom(simfd, curPacket, sizeof(curPacket), 0, &from, &fromlen);    if (n < 0) {	perror("recvfrom");	return -1;    }    if (!validPacket(curPacket, n, &from, fromlen)) {	return 0;    }    if ((n < ETHERMIN + sizeof(struct ether_header)) ||         (n > ETHERMTU + sizeof(struct ether_header))) {	fprintf(stderr, "Bad packet size %d\n", n);	return 0;    }    hdrPtr = (struct ether_header *) curPacket;    if (verbose) {#define	A(x) (hdrPtr->ether_dhost.ether_addr_octet[x])#define	B(x) (hdrPtr->ether_shost.ether_addr_octet[x])	fprintf(stderr, "ETHER: Src %x:%x:%x:%x:%x:%x  Dst %x:%x:%x:%x:%x:%x\n",                B(0),B(1),B(2),B(3),B(4),B(5), A(0),A(1),A(2),A(3),A(4),A(5));    }    /*     * Ensure that the mapping exists for this ethernet address.     */    etherAddrKey[1] = 0;    bcopy(hdrPtr->ether_shost.ether_addr_octet, (char *) etherAddrKey, 6);    entryPtr = Hash_CreateEntry(&etheraddrTable, (Address) etherAddrKey, NULL);    srcHostInfo = (HostInfoRecord *) Hash_GetValue(entryPtr);    if (srcHostInfo == NULL) {      srcHostInfo = (HostInfoRecord *) calloc(1, sizeof(HostInfoRecord));      if (verbose) {	fprintf(stderr, "setting srcHostInfo %#x\n", srcHostInfo);      }      bcopy(hdrPtr->ether_shost.ether_addr_octet, 	    &srcHostInfo->etheraddr, 6);      Hash_SetValue(entryPtr, srcHostInfo);    }    bcopy((caddr_t)&from, (caddr_t)&srcHostInfo->fromaddr, fromlen);    srcHostInfo->fromlen = fromlen;#ifdef MACH_NRP    {	int offset;    if ((offset = IsMachNRPPacket(hdrPtr))) {	xfersize = sendto(nrpfd, curPacket + offset, n-offset, 0x0, 				(caddr_t) &nrpaddr,				nrpaddrlen);	if (xfersize < 0) {	    perror("sendto nrp");	}        return 0;    }    }#endif    if (htons(hdrPtr->ether_type) == ETHERTYPE_IP) {      u_long	inetAddr;      if (verbose) {      struct in_addr	sAddr, dAddr;	fprintf(stderr, "ETHERTYPE_IP packet %#x\n", hdrPtr->ether_type);        bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_src),              (char *) &sAddr, sizeof(sAddr));        bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_dst),              (char *) &dAddr, sizeof(dAddr));	fprintf(stderr, "IP: Src %s ", inet_ntoa(sAddr)); 	fprintf(stderr, "Dst %s\n",  inet_ntoa(dAddr));      }      bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_src),	    (char *) &inetAddr, sizeof(inetAddr));      if (srcHostInfo->inetAddr != inetAddr) {	if (verbose) {	  fprintf(stderr, "srcHostInfo->inetAddr != inetAddr\n");	}	srcHostInfo->inetAddr = inetAddr;	entryPtr = Hash_CreateEntry(&ipaddrTable, (Address)inetAddr,NULL);	Hash_SetValue(entryPtr, srcHostInfo);      }    }#define	A(x) (hdrPtr->ether_dhost.ether_addr_octet[x])#define	B(x) (hdrPtr->ether_shost.ether_addr_octet[x])    if ((A(0) == 0xff) && (A(1) == 0xff) && (A(2) == 0xff) &&	(A(3) == 0xff) && (A(4) == 0xff) && (A(5) == 0xff)) {	Hash_Search search;	/*	 * Broadcast. 	 */	if (verbose) {	  fprintf(stderr, "broadcast packet\n");	}        if (ArpRequest(curPacket, n, curPacket, &n)) {    		if (n < ETHERMIN + sizeof(struct ether_header)) {			n =  ETHERMIN + sizeof(struct ether_header);		}		goto reply;        }	for (entryPtr = Hash_EnumFirst(&etheraddrTable, &search); 	     entryPtr != NULL; entryPtr = Hash_EnumNext(&search)) {	    dstHostInfo = (HostInfoRecord *) Hash_GetValue(entryPtr);	    if (dstHostInfo != srcHostInfo) { 		xfersize = sendto(simfd, curPacket, n, 0x0, 				    (struct sockaddr *) &dstHostInfo->fromaddr,				    dstHostInfo->fromlen);		if (xfersize < 0) {		    perror("sendto");		}	    }	}	return 0;    }   reply:    etherAddrKey[1] = 0;    bcopy(hdrPtr->ether_dhost.ether_addr_octet, 				(char *) etherAddrKey, 6);    entryPtr = Hash_FindEntry(&etheraddrTable, etherAddrKey);    if (entryPtr != NULL) {	dstHostInfo = (HostInfoRecord *) Hash_GetValue(entryPtr);	if (verbose) {	  fprintf(stderr, "sending packet\n");	}	xfersize = sendto(simfd, curPacket, n, 0x0, 				(struct sockaddr *) &dstHostInfo->fromaddr,				dstHostInfo->fromlen);	if (xfersize < 0) {	    perror("sendto");	}        return 0;    }     if ((htons(hdrPtr->ether_type) == ETHERTYPE_IP) && (netfd > 0)) {	u_long	destAddr;	if (verbose) {	  fprintf(stderr, "outputPacket\n");	}	bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_dst),		(char *) &destAddr, sizeof(destAddr));	destAddr = ntohl(destAddr);	if ((destAddr & mynetmask) != subnetaddr) {	    outputPacket(curPacket, n);	}        return 0;    }    fprintf(stderr, "Unknown dest address %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", A(0), A(1), A(2), A(3), A(4), A(5), 	    B(0), B(1), B(2), B(3), B(4), B(5));     return 0;}/* *---------------------------------------------------------------------- * * serviceNetPort --  * *       Service a request that arrives at the network interface tap port. * * Results: *      -1 if problem occur with * * Side effects: * *---------------------------------------------------------------------- */intserviceNetPort(){    struct  ether_header  *hdrPtr;    int	     n;    u_long	inetAddr;    Hash_Entry  *entryPtr;    HostInfoRecord *hostInfoRecord;    int xfersize;    if (verbose) {      fprintf(stderr, "serviceNetPort()\n");    }    n = read(netfd, curPacket, sizeof(curPacket));    if (n < 0) {	perror("read of serviceNetPort");	return -1;    }    if ((n < ETHERMIN + sizeof(struct ether_header)) || 	(n > ETHERMTU + sizeof(struct ether_header))) {	fprintf(stderr, "Bad packet size %d\n", n);	return -1;    }    hdrPtr = (struct ether_header *) curPacket;    if (htons(hdrPtr->ether_type) != ETHERTYPE_IP) {      if (verbose) {	fprintf(stderr, "htons(hdrPtr->ether_type) != ETHERTYPE_IP\n");      }      return 0;    }    bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_dst),		(char *) &inetAddr, sizeof(inetAddr));    entryPtr = Hash_FindEntry(&ipaddrTable, (Address)inetAddr);    if (entryPtr == NULL) {      if (verbose) {	fprintf(stderr, "entryPtr == NULL\n");      }      return 0;    }    hostInfoRecord = (HostInfoRecord *) Hash_GetValue(entryPtr);    if (verbose) {       struct in_addr	sAddr, dAddr;       bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_src),             (char *) &sAddr, sizeof(sAddr));       bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_dst),             (char *) &dAddr, sizeof(dAddr));       fprintf(stderr, "IP: Src %s ", inet_ntoa(sAddr));       fprintf(stderr, "Dst %s\n",  inet_ntoa(dAddr));       fprintf(stderr, "sending...\n");    }    xfersize = sendto(simfd, curPacket, n, 0x0, 				(struct sockaddr *) &hostInfoRecord->fromaddr,				hostInfoRecord->fromlen);    if (xfersize < 0) {	perror("sendto");    }    return 0;}/* *---------------------------------------------------------------------- * * validPacket --  * *       Check to see if we should accept this packet. * * Results: *      1 if packet ok. *      0 if we should request it. * * Side effects: * *---------------------------------------------------------------------- */intvalidPacket(packet, size, fromAddr, fromlen)    char *packet;	/* The contents of the packet. */    int	 size;		/* The size of the packet. */    struct sockaddr *fromAddr; /* Where the packet was from. */    int	  fromlen;	       /* The length of fromAddr. */{    struct  ether_header  *hdrPtr;    struct  sockaddr_in   *inaddrPtr;    u_long  srcAddr;    hdrPtr = (struct ether_header *) packet;    if ((size < ETHERMIN + sizeof(struct ether_header)) ||         (size > ETHERMTU + sizeof(struct ether_header))) {	fprintf(stderr, "Bad packet size %d\n", size);	return 0;    }    /*      * XXX - Do security checking here.  Currently we reject all packets      * from hosts outside our network.  We only if we are forwarding     * packets.     */    if (!noipforwarding) { 	if ((fromAddr->sa_family != AF_INET) || 	    (fromlen < offsetof(struct sockaddr_in, sin_zero))) {	    fprintf(stderr, "Packet from bad fromaddr\n");	    return 0;	}	inaddrPtr = (struct sockaddr_in *) fromAddr;	srcAddr = inet_netof(inaddrPtr->sin_addr);	if ((srcAddr != mynetaddr) && (srcAddr != IN_LOOPBACKNET)) {	    fprintf(stderr, "Security violation: Packet from host %s\n",			    inet_ntoa(inaddrPtr->sin_addr));	    return 0;	}    }    return 1;}/* *---------------------------------------------------------------------- * * initNITdevice --  * *       Initialize the network interface tap (NIT) file descriptor so *	 we can catch IP packets for this subnet. * * Results: *      None. * * Side effects: * *---------------------------------------------------------------------- */int initNITdevice(device, subNetAddr, netmask)    char	    *device;    /* Network interface name. */    u_long 	   subNetAddr;  /* IP address of the subnet. */    u_long	   netmask;	/* Network address mask of the interface. */{      struct strioctl     si;      struct ifreq   ifr;      struct packetfilt pf;      int   err, cmd;      int snaplen;      int fd;      fd = open(NIT_DEV, O_RDWR, 0);      if (fd < 0) {	  perror("open of NIT_DEV");	  return -1;      }      /* Arrange to get discrete messages from the stream. */      err = ioctl(fd, I_SRDOPT, (char *)RMSGD);      if (err < 0) {	  perror("I_SRDOPT RMSGD");	  goto bad;      }

⌨️ 快捷键说明

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