📄 ethersim_simport.c
字号:
/* * 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_simport.c -- * * serviceSimPort * * Service a request that arrives at the simulated ethernet port. * * Results: * -1 if problem occur with * * Side effects: * */#include "ethersim.h"intserviceSimPort(void){ struct ether_header *hdrPtr; struct sockaddr from; int fromlen, n; int etherAddrKey[2]; int xfersize; Hash_Entry *entryPtr; HostInfoRecord *srcHostInfo; HostInfoRecord *dstHostInfo; 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, "Sim: Bad packet size %d\n", n); return 0; } hdrPtr = (struct ether_header *) curPacket; if (verbose) { printf("Packet received from UDP host 0x%x\n", ((struct sockaddr_in *)&from)->sin_addr.s_addr); dispEtherPacket(n, hdrPtr, 0); } /* * Ensure that the mapping exists for this ethernet address. */ etherAddrKey[1] = 0;#ifdef sparc bcopy(hdrPtr->ether_shost.ether_addr_octet, (char *) etherAddrKey, 6);#endif#ifdef sgi bcopy(hdrPtr->ether_shost, (char *) etherAddrKey, 6);#endif entryPtr = Hash_CreateEntry(ðeraddrTable, (Address) etherAddrKey, NULL); srcHostInfo = (HostInfoRecord *) Hash_GetValue(entryPtr); if (srcHostInfo == NULL) { srcHostInfo = (HostInfoRecord *) calloc(1, sizeof(HostInfoRecord));#ifdef sparc bcopy(hdrPtr->ether_shost.ether_addr_octet, &srcHostInfo->etheraddr, 6);#endif#ifdef sgi bcopy(hdrPtr->ether_shost, &srcHostInfo->etheraddr, 6);#endif 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; bcopy(curPacket + sizeof(struct ether_header) + offsetof(struct ip, ip_src), (char *) &inetAddr, sizeof(inetAddr)); if (srcHostInfo->inetAddr != inetAddr) { srcHostInfo->inetAddr = inetAddr; entryPtr = Hash_CreateEntry(&ipaddrTable, (Address)inetAddr,NULL); Hash_SetValue(entryPtr, srcHostInfo); } }#ifdef SIM_PROXY if ((B(0) == 0xff) && (B(1) == 0xff) && (B(2) == 0xff) && (B(3) == 0xff) && (B(4) == 0xff) && (B(5) == 0xff)) {#else if ((A(0) == 0xff) && (A(1) == 0xff) && (A(2) == 0xff) && (A(3) == 0xff) && (A(4) == 0xff) && (A(5) == 0xff)) {#endif Hash_Search search; if(verbose) { printf("Broadcast packet received\n"); } /* * Broadcast. */ if (ArpRequest(curPacket, n, curPacket, &n)) { if (n < ETHERMIN + sizeof(struct ether_header)) { n = ETHERMIN + sizeof(struct ether_header); } goto reply; } if(verbose) { printf("Non ARP broadcast. sending to:\n"); } for (entryPtr = Hash_EnumFirst(ðeraddrTable, &search); entryPtr != NULL; entryPtr = Hash_EnumNext(&search)) { dstHostInfo = (HostInfoRecord *) Hash_GetValue(entryPtr); if (dstHostInfo != srcHostInfo) { if(verbose) { printf(" Dest: 0x%x\n"); } xfersize = sendto(simfd, curPacket, n, 0x0, (struct sockaddr *) &dstHostInfo->fromaddr, dstHostInfo->fromlen); if (xfersize < 0) { perror("sendto"); } } } return 0; } reply: etherAddrKey[1] = 0;#ifdef sparc bcopy(hdrPtr->ether_dhost.ether_addr_octet, (char *) etherAddrKey, 6);#endif#ifdef sgi bcopy(hdrPtr->ether_dhost, (char *) etherAddrKey, 6);#endif entryPtr = Hash_FindEntry(ðeraddrTable, (Address) etherAddrKey); if (entryPtr != NULL) { dstHostInfo = (HostInfoRecord *) Hash_GetValue(entryPtr); 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; 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); } else { if(verbose) { printf("Did not forward packet, dest 0x%x, SN 0x%x\n", destAddr, subnetaddr); } } 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -