📄 if.c
字号:
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 + -