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

📄 if.c

📁 ppp点对点协议
💻 C
📖 第 1 页 / 共 3 页
字号:
	sprintf(buffer, "Unsupported BPF version: %d.%d (kernel: %d.%d)", 			BPF_MAJOR_VERSION, BPF_MINOR_VERSION,			bpf_ver.bv_major, bpf_ver.bv_minor);	rp_fatal(buffer);    }    /* allocate a receive packet buffer */    if (ioctl(fd, BIOCGBLEN, &bpfLength) < 0) {	fatalSys("ioctl(BIOCGBLEN)");    }    if (!(bpfBuffer = (unsigned char *) malloc(bpfLength))) {	rp_fatal("malloc");    }    /* reads should return as soon as there is a packet available */    optval = 1;    if (ioctl(fd, BIOCIMMEDIATE, &optval) < 0) {	fatalSys("ioctl(BIOCIMMEDIATE)");    }    /* Bind the interface to the filter */    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    if (ioctl(fd, BIOCSETIF, &ifr) < 0) {	char buffer[256];	sprintf(buffer, "ioctl(BIOCSETIF) can't select interface %.16s",		ifname);	rp_fatal(buffer);    }    syslog(LOG_INFO, "Interface=%.16s HWaddr=%02X:%02X:%02X:%02X:%02X:%02X Device=%.32s Buffer size=%d",	   ifname, 	   hwaddr[0], hwaddr[1], hwaddr[2],	   hwaddr[3], hwaddr[4], hwaddr[5],	   bpfName, bpfLength);    return fd;}#endif /* USE_BPF */#ifdef USE_LINUX_PACKET/***********************************************************************%FUNCTION: openInterface*%ARGUMENTS:* ifname -- name of interface* type -- Ethernet frame type* hwaddr -- if non-NULL, set to the hardware address*%RETURNS:* A raw socket for talking to the Ethernet card.  Exits on error.*%DESCRIPTION:* Opens a raw Ethernet socket***********************************************************************/intopenInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr){    int optval=1;    int fd;    struct ifreq ifr;    int domain, stype;#ifdef HAVE_STRUCT_SOCKADDR_LL    struct sockaddr_ll sa;#else    struct sockaddr sa;#endif    memset(&sa, 0, sizeof(sa));#ifdef HAVE_STRUCT_SOCKADDR_LL    domain = PF_PACKET;    stype = SOCK_RAW;#else    domain = PF_INET;    stype = SOCK_PACKET;#endif    if ((fd = socket(domain, stype, htons(type))) < 0) {	/* Give a more helpful message for the common error case */	if (errno == EPERM) {	    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");	}	fatalSys("socket");    }    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) {	fatalSys("setsockopt");    }    /* Fill in hardware address */    if (hwaddr) {	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));	if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {	    fatalSys("ioctl(SIOCGIFHWADDR)");	}	memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);#ifdef ARPHRD_ETHER	if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {	    char buffer[256];	    sprintf(buffer, "Interface %.16s is not Ethernet", ifname);	    rp_fatal(buffer);	}#endif	if (NOT_UNICAST(hwaddr)) {	    char buffer[256];	    sprintf(buffer,		    "Interface %.16s has broadcast/multicast MAC address??",		    ifname);	    rp_fatal(buffer);	}    }    /* Sanity check on MTU */    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {	fatalSys("ioctl(SIOCGIFMTU)");    }    if (ifr.ifr_mtu < ETH_DATA_LEN) {	char buffer[256];	sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d.  You may have serious connection problems.",		ifname, ifr.ifr_mtu, ETH_DATA_LEN);	printErr(buffer);    }#ifdef HAVE_STRUCT_SOCKADDR_LL    /* Get interface index */    sa.sll_family = AF_PACKET;    sa.sll_protocol = htons(type);    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {	fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index");    }    sa.sll_ifindex = ifr.ifr_ifindex;#else    strcpy(sa.sa_data, ifname);#endif    /* We're only interested in packets on specified interface */    if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {	fatalSys("bind");    }    return fd;}#endif /* USE_LINUX *//************************************************************************%FUNCTION: sendPacket*%ARGUMENTS:* sock -- socket to send to* pkt -- the packet to transmit* size -- size of packet (in bytes)*%RETURNS:* 0 on success; -1 on failure*%DESCRIPTION:* Transmits a packet***********************************************************************/intsendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size){#if defined(USE_BPF)    if (write(sock, pkt, size) < 0) {	sysErr("write (sendPacket)");	return -1;    }#elif defined(HAVE_STRUCT_SOCKADDR_LL)    if (send(sock, pkt, size, 0) < 0) {	sysErr("send (sendPacket)");	return -1;    }#else#ifdef USE_DLPI#define ABS(x)          ((x) < 0 ? -(x) : (x))	u_char  addr[MAXDLADDR];	u_char  phys[MAXDLADDR];	u_char  sap[MAXDLADDR];	u_char    xmitbuf[MAXDLBUF];	int	data_size;	short	tmp_sap;	tmp_sap = htons(pkt->ethHdr.h_proto); 	data_size = size - sizeof(struct ethhdr); 	memcpy((char *)phys, (char *)pkt->ethHdr.h_dest, ETHERADDRL);	memcpy((char *)sap,  (char *)&tmp_sap, sizeof(ushort_t));	memcpy((char *)xmitbuf, (char *)pkt + sizeof(struct ethhdr), data_size); 	if (dl_saplen > 0) {  /* order is sap+phys */		(void) memcpy((char*)addr, (char*)&sap, dl_abssaplen);		(void) memcpy((char*)addr+dl_abssaplen, (char*)phys, ETHERADDRL);	} else {        /* order is phys+sap */		(void) memcpy((char*)addr, (char*)phys, ETHERADDRL);		(void) memcpy((char*)addr+ETHERADDRL, (char*)&sap, dl_abssaplen);	}#ifdef DL_DEBUG	printf("%02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n", 		addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],		addr[6],addr[7]);#endif	dlunitdatareq(sock, addr, dl_addrlen, 0, 0, xmitbuf, data_size);#else    struct sockaddr sa;    if (!conn) {	rp_fatal("relay and server not supported on Linux 2.0 kernels");    }    strcpy(sa.sa_data, conn->ifName);    if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) {	sysErr("sendto (sendPacket)");	return -1;    }#endif#endif    return 0;}#ifdef USE_BPF/************************************************************************%FUNCTION: clearPacketHeader*%ARGUMENTS:* pkt -- packet that needs its head clearing*%RETURNS:* nothing*%DESCRIPTION:* Clears a PPPoE packet header after a truncated packet has been* received.  Insures that the packet will fail any integrity tests* and will be discarded by upper level routines.  Also resets the* bpfSize and bpfOffset variables to force a new read on the next* call to receivePacket().***********************************************************************/voidclearPacketHeader(PPPoEPacket *pkt){    bpfSize = bpfOffset = 0;    memset(pkt, 0, HDR_SIZE);}#endif/************************************************************************%FUNCTION: receivePacket*%ARGUMENTS:* sock -- socket to read from* pkt -- place to store the received packet* size -- set to size of packet in bytes*%RETURNS:* >= 0 if all OK; < 0 if error*%DESCRIPTION:* Receives a packet***********************************************************************/intreceivePacket(int sock, PPPoEPacket *pkt, int *size){#ifdef USE_BPF    struct bpf_hdr hdr;    int seglen, copylen;    if (bpfSize <= 0) {	bpfOffset = 0;	if ((bpfSize = read(sock, bpfBuffer, bpfLength)) < 0) {	    sysErr("read (receivePacket)");	    return -1;	}    }    if (bpfSize < sizeof(hdr)) {	syslog(LOG_ERR, "Truncated bpf packet header: len=%d", bpfSize);	clearPacketHeader(pkt);		/* resets bpfSize and bpfOffset */	return 0;    }    memcpy(&hdr, bpfBuffer + bpfOffset, sizeof(hdr));    if (hdr.bh_caplen != hdr.bh_datalen) {	syslog(LOG_ERR, "Truncated bpf packet: caplen=%d, datalen=%d",	       hdr.bh_caplen, hdr.bh_datalen);	clearPacketHeader(pkt);		/* resets bpfSize and bpfOffset */	return 0;    }    seglen = hdr.bh_hdrlen + hdr.bh_caplen;    if (seglen > bpfSize) {	syslog(LOG_ERR, "Truncated bpf packet: seglen=%d, bpfSize=%d",	       seglen, bpfSize);	clearPacketHeader(pkt);		/* resets bpfSize and bpfOffset */	return 0;    }    seglen = BPF_WORDALIGN(seglen);    *size = copylen = ((hdr.bh_caplen < sizeof(PPPoEPacket)) ?			hdr.bh_caplen : sizeof(PPPoEPacket));    memcpy(pkt, bpfBuffer + bpfOffset + hdr.bh_hdrlen, copylen);    if (seglen >= bpfSize) {	bpfSize = bpfOffset = 0;    } else {	bpfSize -= seglen;	bpfOffset += seglen;    }#else#ifdef USE_DLPI	struct strbuf data; 	int flags = 0; 		int retval; 	data.buf = (char *) pkt; 	data.maxlen = MAXDLBUF; 	data.len = 0; 		if ((retval = getmsg(sock, NULL, &data, &flags)) < 0) {	    sysErr("read (receivePacket)");	    return -1;	}	*size = data.len; #else    if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) {	sysErr("recv (receivePacket)");	return -1;    }#endif#endif    return 0;}#ifdef USE_DLPI/***********************************************************************%FUNCTION: openInterface*%ARGUMENTS:* ifname -- name of interface* type -- Ethernet frame type* hwaddr -- if non-NULL, set to the hardware address*%RETURNS:* A raw socket for talking to the Ethernet card.  Exits on error.*%DESCRIPTION:* Opens a raw Ethernet socket***********************************************************************/intopenInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr){    int fd;    long buf[MAXDLBUF]; 	union   DL_primitives   *dlp;    char base_dev[PATH_MAX];     int ppa;     if(strlen(ifname) > PATH_MAX) {	rp_fatal("socket: string to long");     }    ppa = atoi(&ifname[strlen(ifname)-1]);    strncpy(base_dev, ifname, PATH_MAX);     base_dev[strlen(base_dev)-1] = '\0'; /* rearranged order of DLPI code - delphys 20010803 */    dlp = (union DL_primitives*) buf;    if (( fd = open(base_dev, O_RDWR)) < 0) {	/* Give a more helpful message for the common error case */	if (errno == EPERM) {	    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");

⌨️ 快捷键说明

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