📄 ethersim.c
字号:
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(ðeraddrTable, (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(ðeraddrTable, &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(ðeraddrTable, 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 + -