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

📄 if.c

📁 PPPoE在Linux上的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -