📄 ethersim_init.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_init.c -- * * initSNPdevice -- * * Initialize the snoop file descriptor so that * we can catch IP packets for this subnet. * Result: Return the file descriptor is successful. * Otherwise, return -1. * */#include "ethersim.h"#ifdef sgi/* char *device; Network interface name. *//* u_long *subNetAddr; IP addresses (or address) for which proxy should be done *//* u_long count; number of IP addresses *//* u_long netmask; Network address mask of the interface.*/int#ifdef SIM_PROXYinitSNPdevice(char *device, u_long *subNetAddr, u_long count, u_long netmask)#elseinitSNPdevice(char *device, u_long subNetAddr, u_long netmask)#endif{ int s, i; struct sockaddr_raw sr; struct snoopfilter sf; struct ether_ip_header *ptr; int cc = 60000, on = 1; /* * Ethernet address of gateway machine(e.g. paia ). */ myetheraddr[0] = 8; myetheraddr[1] = 0; myetheraddr[2] = 0x69; myetheraddr[3] = 2; myetheraddr[4] = 0x14; myetheraddr[5] = 0xf1; /* * Create a raw socket for snoop device. */ s = socket(PF_RAW,SOCK_RAW,RAWPROTO_SNOOP); if ( s < 0) { perror("initSNPdevice:socket"); return -1; } /* * Bind the raw socket to the network interface. */ sr.sr_family = AF_RAW; sr.sr_port = 0; strncpy(sr.sr_ifname,device,sizeof(sr.sr_ifname)); if ( bind(s,&sr,sizeof(sr)) < 0) { perror("initSNPdevice:bind"); goto bad; }#ifdef SIM_PROXY if ( !((netmask == 0xff000000) || (netmask == 0xffff0000) || (netmask == 0xffffff00) || (netmask == 0xffffffff))) { fprintf(stderr,"Code can't handle netmask of 0x%x\n",netmask); goto bad; }#else if ( !((netmask == 0xff000000) || (netmask == 0xffff0000) || (netmask == 0xffffff00))) { fprintf(stderr,"Code can't handle netmask of 0x%x\n",netmask); goto bad; }#endif#ifdef SIM_PROXY for(i=0; i<count; i++) {#endif /* * Initialize a filter to only return IP packets to the * specified network. Add it to the interface's filter set. */ bzero((char*)&sf,sizeof(sf)); /* * Set the filter mask and matching value to only accept IP packets. */ ptr = (struct ether_ip_header *) RAW_HDR(sf.sf_mask,struct ether_header); ptr->etherHdr.ether_type = 0xffff; ptr = (struct ether_ip_header *) RAW_HDR(sf.sf_match,struct ether_header); ptr->etherHdr.ether_type = htons(ETHERTYPE_IP); /* * Set the filter to only accept packets sent to this network. */ { struct in_addr netval; struct in_addr srcNetVal; netval.s_addr = htonl(netmask); ptr = (struct ether_ip_header*) RAW_HDR(sf.sf_mask,struct ether_header); bcopy((u_char*) &netval,(u_char*) (u_char*) &sf + 32,4);#ifdef SIM_PROXY netval.s_addr = subNetAddr[i] & netmask ;#else netval.s_addr = htonl(((u_long)subNetAddr) & netmask );#endif ptr= (struct ether_ip_header *)RAW_HDR(sf.sf_match,struct ether_header); bcopy((u_char*) &netval,(u_char*) (u_char*) &sf + 36+ 32,4); } if ( ioctl(s,SIOCADDSNOOP,&sf) < 0) { perror("initSNPdevice:SIOCADDSNOOP"); goto bad; }#ifdef SIM_PROXY }#endif /* * Increase the socket's receive buffer size to a generous upper * bound, to cope with promiscuous reception of heavy traffic. * Turn snooping on and read captured packets. */ if ( setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&cc, sizeof(cc))< 0){ perror("initSNPdevice:setsockopt"); goto bad; } if ( ioctl(s,SIOCSNOOPING,&on) < 0) { perror("initSNPdevice:SIOSNOOPING"); goto bad; } return s; bad: (void)close(s); return -1;}#endif /* sgi */#ifdef sparc 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; } /* Configure the nit device, binding it to the proper underlying interface and setting the snapshot length to include entire ethernet packets. */ strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name); ifr.ifr_name[sizeof ifr.ifr_name - 1] = '\0'; si.ic_cmd = NIOCBIND; si.ic_timout = INFTIM; si.ic_len = sizeof ifr; si.ic_dp = (char *)𝔦 err = ioctl(fd, I_STR, (char *)&si); if (err < 0) { perror("I_STR NIOCBIND"); goto bad; } snaplen = 0; si.ic_cmd = NIOCSSNAP; si.ic_timout = INFTIM; si.ic_len = sizeof snaplen; si.ic_dp = (char *)&snaplen; err = ioctl(fd, I_STR, (char *)&si); if (err < 0) { perror("I_STR NIOCSSNAP"); goto bad; } /* * Read out the ethernet address so we can fill them into packets * being sent. */ si.ic_cmd = SIOCGIFADDR; si.ic_timout = INFTIM; si.ic_len = sizeof ifr; si.ic_dp = (char *)𝔦 err = ioctl(fd, I_STR, (char *)&si); if (err < 0) { perror("I_STR SIOCGIFADDR"); goto bad; } bcopy(ifr.ifr_addr.sa_data, (char *) &myetheraddr, sizeof(myetheraddr)); if (!((netmask == 0xff000000) || (netmask == 0xffff0000) || (netmask == 0xffffff00))) { fprintf(stderr, "Code can't handle netmask of 0x%x\n", netmask); goto bad; } /* * Add the packet filter to only return IP packets to the specified * network. */ err = ioctl(fd, I_PUSH, "pf"); if (err < 0) { perror("I_PUSH pf"); exit(1); } cmd = 0; pf.Pf_Filter[cmd++] = ENF_PUSHWORD + (u_short) offsetof(struct ether_header, ether_type)/sizeof(u_short); pf.Pf_Filter[cmd++] = ENF_PUSHLIT | ENF_CAND; pf.Pf_Filter[cmd++] = htons(ETHERTYPE_IP); if (netmask == 0xff000000) { u_short lowval, highval; lowval = (((u_long)subNetAddr) & netmask) >> 16; highval = lowval | 0xff; pf.Pf_Filter[cmd++] = ENF_PUSHWORD + (u_short) sizeof(struct ether_header)/sizeof(u_short) + offsetof(struct ip, ip_dst)/sizeof(u_short); pf.Pf_Filter[cmd++] = ENF_PUSHLIT | ENF_GE; pf.Pf_Filter[cmd++] = lowval; pf.Pf_Filter[cmd++] = ENF_PUSHWORD + (u_short) sizeof(struct ether_header)/sizeof(u_short) + offsetof(struct ip, ip_dst)/sizeof(u_short); pf.Pf_Filter[cmd++] = ENF_PUSHLIT | ENF_LE; pf.Pf_Filter[cmd++] = highval; pf.Pf_Filter[cmd++] = ENF_AND; } else { pf.Pf_Filter[cmd++] = ENF_PUSHWORD + (u_short) sizeof(struct ether_header)/sizeof(u_short) + offsetof(struct ip, ip_dst)/sizeof(u_short); pf.Pf_Filter[cmd++] = ENF_PUSHLIT | ENF_EQ; pf.Pf_Filter[cmd++] = (((u_long)subNetAddr) & netmask) >> 16; if (netmask == 0xffffff00) { u_short lowval, highval; lowval = (((u_long)subNetAddr) & netmask) & 0xffff; highval = lowval | 0xff; pf.Pf_Filter[cmd++] = ENF_PUSHWORD + (u_short) sizeof(struct ether_header)/sizeof(u_short) + offsetof(struct ip, ip_dst)/sizeof(u_short) + 1; pf.Pf_Filter[cmd++] = ENF_PUSHLIT | ENF_GE; pf.Pf_Filter[cmd++] = lowval; pf.Pf_Filter[cmd++] = ENF_PUSHWORD + (u_short) sizeof(struct ether_header)/sizeof(u_short) + offsetof(struct ip, ip_dst)/sizeof(u_short) + 1; pf.Pf_Filter[cmd++] = ENF_PUSHLIT | ENF_LE; pf.Pf_Filter[cmd++] = highval; pf.Pf_Filter[cmd++] = ENF_AND; } } pf.Pf_FilterLen = cmd; si.ic_cmd = NIOCSETF; si.ic_timout = INFTIM; si.ic_len = sizeof pf; si.ic_dp = (char *)&pf; err = ioctl(fd, I_STR, (char *)&si); if (err < 0) { perror("I_STR NIOCSETF"); goto bad; } /* Flush the read queue, to get rid of anything that accumulated before the device reached its final configuration. */ err = ioctl(fd, I_FLUSH, (char *)FLUSHR); if (err < 0) { perror("I_STR FLUSHR"); goto bad; } return fd; bad: (void) close(fd); return -1;}#endif /* sparc */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -