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

📄 if.c

📁 linux下的拨号程序rp-pppoe.3.7
💻 C
📖 第 1 页 / 共 2 页
字号:
	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: Interface name too long");    }    if (strlen(ifname) < 2) {	rp_fatal("socket: Interface name too short");    }    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.");	}	/* Common error is to omit /dev/ */	if (errno == ENOENT) {	    char ifname[512];	    snprintf(ifname, sizeof(ifname), "/dev/%s", base_dev);	    if ((fd = open(ifname, O_RDWR)) < 0) {		if (errno == EPERM) {		    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");		}	    }	}    }    if (fd < 0) {	fatalSys("socket");    }/* rearranged order of DLPI code - delphys 20010803 */    dlattachreq(fd, ppa);    dlokack(fd, (char *)buf);    dlbindreq(fd, type, 0, DL_CLDLS, 0, 0);    dlbindack(fd, (char *)buf);    dlinforeq(fd);    dlinfoack(fd, (char *)buf);    dl_abssaplen = ABS(dlp->info_ack.dl_sap_length);    dl_saplen = dlp->info_ack.dl_sap_length;    if (ETHERADDRL != (dlp->info_ack.dl_addr_length - dl_abssaplen))	fatalSys("invalid destination physical address length");    dl_addrlen = dl_abssaplen + ETHERADDRL;/* ethernet address retrieved as part of DL_INFO_ACK - delphys 20010803 */    memcpy(hwaddr, (u_char*)((char*)(dlp) + (int)(dlp->info_ack.dl_addr_offset)), ETHERADDRL);    if ( strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0 ) {	fatalSys("DLIOCRAW");    }    if (ioctl(fd, I_FLUSH, FLUSHR) < 0) fatalSys("I_FLUSH");    return fd;}/* cloned from dlcommon.c */void dlpromisconreq(int fd, u_long level){	dl_promiscon_req_t      promiscon_req;	struct  strbuf  ctl;	int     flags;	promiscon_req.dl_primitive = DL_PROMISCON_REQ;	promiscon_req.dl_level = level;	ctl.maxlen = 0;	ctl.len = sizeof (promiscon_req);	ctl.buf = (char *) &promiscon_req;	flags = 0;	if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)		fatalSys("dlpromiscon:  putmsg");}void dlinforeq(int fd){	dl_info_req_t   info_req;	struct  strbuf  ctl;	int     flags;	info_req.dl_primitive = DL_INFO_REQ;	ctl.maxlen = 0;	ctl.len = sizeof (info_req);	ctl.buf = (char *) &info_req;	flags = RS_HIPRI;	if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)		fatalSys("dlinforeq:  putmsg");}void dlunitdatareq(int fd, u_char *addrp, int addrlen, u_long minpri, u_long maxpri, u_char *datap, int datalen){	long    buf[MAXDLBUF];	union   DL_primitives   *dlp;	struct  strbuf  data, ctl;	dlp = (union DL_primitives*) buf;	dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ;	dlp->unitdata_req.dl_dest_addr_length = addrlen;	dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t);	dlp->unitdata_req.dl_priority.dl_min = minpri;	dlp->unitdata_req.dl_priority.dl_max = maxpri;	(void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)), addrp, addrlen);	ctl.maxlen = 0;	ctl.len = sizeof (dl_unitdata_req_t) + addrlen;	ctl.buf = (char *) buf;	data.maxlen = 0;	data.len = datalen;	data.buf = (char *) datap;	if (putmsg(fd, &ctl, &data, 0) < 0)		fatalSys("dlunitdatareq:  putmsg");}void dlinfoack(int fd, char *bufp){	union   DL_primitives   *dlp;	struct  strbuf  ctl;	int     flags;	ctl.maxlen = MAXDLBUF;	ctl.len = 0;	ctl.buf = bufp;	strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlinfoack");	dlp = (union DL_primitives *) ctl.buf;	expecting(DL_INFO_ACK, dlp);	if (ctl.len < sizeof (dl_info_ack_t)) {		char buffer[256];		sprintf(buffer, "dlinfoack:  response ctl.len too short:  %d", ctl.len);		rp_fatal(buffer);	}	if (flags != RS_HIPRI)		rp_fatal("dlinfoack:  DL_INFO_ACK was not M_PCPROTO");	if (ctl.len < sizeof (dl_info_ack_t)) {		char buffer[256];		sprintf(buffer, "dlinfoack:  short response ctl.len:  %d", ctl.len);		rp_fatal(buffer);	}}void dlbindreq(int fd, u_long sap, u_long max_conind, u_long service_mode, u_long conn_mgmt, u_long xidtest){	dl_bind_req_t   bind_req;	struct  strbuf  ctl;	int     flags;	bind_req.dl_primitive = DL_BIND_REQ;	bind_req.dl_sap = sap;	bind_req.dl_max_conind = max_conind;	bind_req.dl_service_mode = service_mode;	bind_req.dl_conn_mgmt = conn_mgmt;	bind_req.dl_xidtest_flg = xidtest;	ctl.maxlen = 0;	ctl.len = sizeof (bind_req);	ctl.buf = (char *) &bind_req;	flags = 0;	if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)		fatalSys("dlbindreq:  putmsg");}void dlattachreq(int fd, u_long ppa){	dl_attach_req_t attach_req;	struct  strbuf  ctl;	int     flags;	attach_req.dl_primitive = DL_ATTACH_REQ;	attach_req.dl_ppa = ppa;	ctl.maxlen = 0;	ctl.len = sizeof (attach_req);	ctl.buf = (char *) &attach_req;	flags = 0;	if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)		fatalSys("dlattachreq:  putmsg");}void dlokack(int fd, char *bufp){	union   DL_primitives   *dlp;	struct  strbuf  ctl;	int     flags;	ctl.maxlen = MAXDLBUF;	ctl.len = 0;	ctl.buf = bufp;	strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack");	dlp = (union DL_primitives *) ctl.buf;	expecting(DL_OK_ACK, dlp);	if (ctl.len < sizeof (dl_ok_ack_t)) {		char buffer[256];		sprintf(buffer, "dlokack:  response ctl.len too short:  %d", ctl.len);		rp_fatal(buffer);	}	if (flags != RS_HIPRI)		rp_fatal("dlokack:  DL_OK_ACK was not M_PCPROTO");	if (ctl.len < sizeof (dl_ok_ack_t)) {		char buffer[256];		sprintf(buffer, "dlokack:  short response ctl.len:  %d", ctl.len);		rp_fatal(buffer);	}}void dlbindack(int fd, char *bufp){	union   DL_primitives   *dlp;	struct  strbuf  ctl;	int     flags;	ctl.maxlen = MAXDLBUF;	ctl.len = 0;	ctl.buf = bufp;	strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack");	dlp = (union DL_primitives *) ctl.buf;	expecting(DL_BIND_ACK, dlp);	if (flags != RS_HIPRI)		rp_fatal("dlbindack:  DL_OK_ACK was not M_PCPROTO");	if (ctl.len < sizeof (dl_bind_ack_t)) {		char buffer[256];		sprintf(buffer, "dlbindack:  short response ctl.len:  %d", ctl.len);		rp_fatal(buffer);	}}int strioctl(int fd, int cmd, int timout, int len, char *dp){	struct  strioctl        sioc;	int     rc;	sioc.ic_cmd = cmd;	sioc.ic_timout = timout;	sioc.ic_len = len;	sioc.ic_dp = dp;	rc = ioctl(fd, I_STR, &sioc);	if (rc < 0)		return (rc);	else		return (sioc.ic_len);}void strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap, int *flagsp, char *caller){	int     rc;	static  char    errmsg[80];	/*	 * Start timer.	 */	(void) signal(SIGALRM, sigalrm);	if (alarm(MAXWAIT) < 0) {		(void) sprintf(errmsg, "%s:  alarm", caller);		fatalSys(errmsg);	}	/*	 * Set flags argument and issue getmsg().	 */	*flagsp = 0;	if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {		(void) sprintf(errmsg, "%s:  getmsg", caller);		fatalSys(errmsg);	}	/*	 * Stop timer.	 */	if (alarm(0) < 0) {		(void) sprintf(errmsg, "%s:  alarm", caller);		fatalSys(errmsg);	}	/*	 * Check for MOREDATA and/or MORECTL.	 */	if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) {		char buffer[256];		sprintf(buffer, "%s:  MORECTL|MOREDATA", caller);		rp_fatal(buffer);	}	if (rc & MORECTL) {		char buffer[256];		sprintf(buffer, "%s:  MORECTL", caller);		rp_fatal(buffer);	}	if (rc & MOREDATA) {		char buffer[256];		sprintf(buffer, "%s:  MOREDATA", caller);		rp_fatal(buffer);	}	/*	 * Check for at least sizeof (long) control data portion.	 */	if (ctlp->len < sizeof (long)) {		char buffer[256];		sprintf(buffer, "getmsg:  control portion length < sizeof (long):  %d", ctlp->len);		rp_fatal(buffer);	}}void sigalrm(int sig){	(void) rp_fatal("sigalrm:  TIMEOUT");}void expecting(int prim, union DL_primitives *dlp){	if (dlp->dl_primitive != (u_long)prim) {		char buffer[256];		sprintf(buffer, "expected %s got %s", dlprim(prim), dlprim(dlp->dl_primitive));		rp_fatal(buffer);		exit(1);	}}char *dlprim(u_long prim){	static  char    primbuf[80];	switch ((int)prim) {		CASERET(DL_INFO_REQ);		CASERET(DL_INFO_ACK);		CASERET(DL_ATTACH_REQ);		CASERET(DL_DETACH_REQ);		CASERET(DL_BIND_REQ);		CASERET(DL_BIND_ACK);		CASERET(DL_UNBIND_REQ);		CASERET(DL_OK_ACK);		CASERET(DL_ERROR_ACK);		CASERET(DL_SUBS_BIND_REQ);		CASERET(DL_SUBS_BIND_ACK);		CASERET(DL_UNITDATA_REQ);		CASERET(DL_UNITDATA_IND);		CASERET(DL_UDERROR_IND);		CASERET(DL_UDQOS_REQ);		CASERET(DL_CONNECT_REQ);		CASERET(DL_CONNECT_IND);		CASERET(DL_CONNECT_RES);		CASERET(DL_CONNECT_CON);		CASERET(DL_TOKEN_REQ);		CASERET(DL_TOKEN_ACK);		CASERET(DL_DISCONNECT_REQ);		CASERET(DL_DISCONNECT_IND);		CASERET(DL_RESET_REQ);		CASERET(DL_RESET_IND);		CASERET(DL_RESET_RES);		CASERET(DL_RESET_CON);		default:			(void) sprintf(primbuf, "unknown primitive 0x%lx", prim);			return (primbuf);	}}#endif /* USE_DLPI */

⌨️ 快捷键说明

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