📄 lat_usrreq.c
字号:
goto release; } (void)bcopy(p,commsg,len); m1->m_len = (short)len; objaddr.lat_family = AF_LAT; ifp = (struct ifnet *)rights; /* * Join the two mbufs and send to the interface * pointed to by rights. */ m_cat(m0,m1); ecbp->ecb_cmdmsg = m0; ecbp->ecb_inuse = 0; if (cm = m_copy(m0,0,M_COPYALL)) { (*ifp->if_output)(ifp,cm,&objaddr); }release: KM_FREE(ndp->ni_dirp, KM_NAMEI); break; case LIOCRES: if (nam) { rptr = (caddr_t)nam; /* * Skip over interface name. */ while ( *rptr++ ); res = (struct response_1 *)rptr; n = class1.scl_rmsg.q_head; /* * Find response information structure in response * queue matching solicit ID of user structure */ while (n) { res_que = mtod(n, struct response_1 *); if ( *(u_short *)res->rs1_solid == *(u_short *)res_que->rs1_solid ) { if (n == class1.scl_rmsg.q_head) { if ( (class1.scl_rmsg.q_head = n->m_act) == 0) class1.scl_rmsg.q_tail = 0; } else { if (n == class1.scl_rmsg.q_tail) { class1.scl_rmsg.q_tail = prev; prev->m_act = 0; } else prev->m_act = n->m_act; } rp = mtod(n,char *); (void)bcopy(rp,(caddr_t)nam,n->m_len); m_freem(n); goto found; } else { prev = n; n = n->m_act; } } /* while n */ /* * The address was not found. */ error = EADDRNOTAVAIL; } /* if nam */found: break; case LIOCINI: /* Designate the tty port in the first argument as * available only for host-initiated connections. * The first cmdbyte has the following significance. * 0 : Make available to server connections only. * 1 : Make available to host-initiated connections only. * 2 : Return in cmdbyte 0 or 1 to indicate current setting. */ if (nam) { p = (caddr_t)nam; /* * Skip over interface name. */ while ( *p++ ); cmdbyte = *p++; KM_ALLOC(ndp->ni_dirp,char *,MAXPATHLEN,KM_NAMEI,KM_NOARG); if(ndp->ni_dirp == NULL) { error = EIO; goto release2; } if(error = copyinstr(p, ndp->ni_dirp, MAXPATHLEN, (u_int *) 0)) { goto release2; } ndp->ni_nameiop = LOOKUP; if ( (gp = gfs_namei(ndp)) == 0 ) { error = EINVAL; goto release2; } else { unit = minor(gp->g_rdev); ecbp = &(statable[unit]); gput(gp); if (cmdbyte != '\002') ecbp->ecb_hostinit = cmdbyte; bcopy((caddr_t)&(ecbp->ecb_hostinit), (caddr_t)nam,1); } }release2: KM_FREE(ndp->ni_dirp,KM_NAMEI); break; default: break; }; break; /* * The get socket option call is used to retrieve information about * the current LAT state. */ case PRU_GETSOCKOPT: if (m) { class = ((int)nam >> 8) & 0377; switch ((int)nam & 0377) { /* * Read the LAT counters. */ case LAT_COUNTERS: bcopy((char *)&latctrs,(char *)mtod(m, caddr_t), sizeof(struct lat_counters)); m->m_len = sizeof(struct lat_counters); break; /* * Get LAT parameters. */ case LAT_PARAMS: pptr = mtod(m, struct lat_params *); pptr->lpm_version = LAT_VER; pptr->lpm_eco = LAT_ECO; pptr->lpm_mtimer = mtimer; m->m_len = sizeof(struct lat_params); break; /* * Get LAT directory message. */ case LAT_DIRMSG: if (class <= MAXCLASS && (scl = sclass[class])) { dptr = mtod(m,caddr_t); if (dm = scl->scl_dmsg) { while (dm && size) { len = size > dm->m_len ? dm->m_len : size; bcopy(mtod(dm, caddr_t), dptr, len); dptr += len; size -= len; dm = dm->m_next; } } m->m_len = CLBYTES - size; } else { error = ERANGE; } break; /* * Get LAT state. */ case LAT_STATE: if (class <= MAXCLASS && (scl = sclass[class])) { sptr = mtod(m, struct lat_state *); sptr->lst_state = scl->scl_state; m->m_len = sizeof(struct lat_state); } else { error = ERANGE; } break; default: error = EOPNOTSUPP; } } else { mprintf("lat err: getsockopt\n"); error = EMSGSIZE; } break; /* * The set socket option call is used to set up information about * the current LAT state. */ case PRU_SETSOCKOPT: if (suser()) { if (sockactive) { error = EBUSY; /* * if (m) * { * m_freem(m); * } */ break; } else sockactive++; class = ((int)nam >> 8) & 0377; switch ((int)nam & 0377) { /* * Zero the LAT counters. */ case LAT_COUNTERS: bzero(&latctrs, sizeof(struct lat_counters)); break; /* * Set LAT parameters. */ case LAT_PARAMS: if (m && m->m_len >= sizeof(struct lat_params)) { pptr = mtod(m, struct lat_params *); mtimer = pptr->lpm_mtimer; } else { mprintf("lat error: LAT_PARAMS\n"); error = EMSGSIZE; } break; /* * Set LAT directory message. */ case LAT_DIRMSG: if (class <= MAXCLASS && (scl = sclass[class])) { if ((m == 0) || (dm = m_copy(m, 0, M_COPYALL))) { if (scl->scl_dmsg) { m_freem(scl->scl_dmsg); } else { /* * Initialise the incarnation number of * the new service class to a 'random' * number - the low byte of the seconds * of the current time. */ dirptr = mtod(dm, struct direct_1 *); dirptr->dr1_inc = time.tv_sec; } scl->scl_dmsg = dm; } else { error = ENOBUFS; } } else { error = ERANGE; } break; /* * Set LAT state. */ case LAT_STATE: if (class <= MAXCLASS && (scl = sclass[class])) { if (m && m->m_len >= sizeof(struct lat_state)) { sptr = mtod(m, struct lat_state *); if ((scl->scl_state = sptr->lst_state) == LST_OFF) { for (slot = sl,i = 0; i < LAT_MAXSLOTS; slot++,i++) { if (slot->lsl_state != SST_FREE && slot->lsl_class == class) { (*scl->scl_hangup)(slot->lsl_vc, slot); terminateslot(slot); } } } } else { mprintf("lat error: LAT_STATE\n"); error = EMSGSIZE; } } else { error = ERANGE; } break; default: error = EOPNOTSUPP; } /* switch */ sockactive = 0; } else { error = EACCES; } break; default: panic("lat_usrreq"); } splx(s); return (error);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -