📄 pk_usrreq.c
字号:
pk_start (lcp)register struct pklcd *lcp;{ pk_output (lcp); return (0); /* XXX pk_output should return a value */}#ifndef _offsetof#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))#endifstruct sockaddr_x25 pk_sockmask = { _offsetof(struct sockaddr_x25, x25_addr[0]), /* x25_len */ 0, /* x25_family */ -1, /* x25_net id */};/*ARGSUSED*/pk_control (so, cmd, data, ifp)struct socket *so;int cmd;caddr_t data;register struct ifnet *ifp;{ register struct ifreq_x25 *ifr = (struct ifreq_x25 *)data; register struct ifaddr *ifa = 0; register struct x25_ifaddr *ia = 0; struct pklcd *dev_lcp = 0; int error, s, old_maxlcn; unsigned n; /* * Find address for this interface, if it exists. */ if (ifp) for (ifa = ifp -> if_addrlist; ifa; ifa = ifa -> ifa_next) if (ifa -> ifa_addr -> sa_family == AF_CCITT) break; ia = (struct x25_ifaddr *)ifa; switch (cmd) { case SIOCGIFCONF_X25: if (ifa == 0) return (EADDRNOTAVAIL); ifr -> ifr_xc = ia -> ia_xc; return (0); case SIOCSIFCONF_X25: if ((so->so_state & SS_PRIV) == 0) return (EPERM); if (ifp == 0) panic ("pk_control"); if (ifa == (struct ifaddr *)0) { register struct mbuf *m; MALLOC(ia, struct x25_ifaddr *, sizeof (*ia), M_IFADDR, M_WAITOK); if (ia == 0) return (ENOBUFS); bzero ((caddr_t)ia, sizeof (*ia)); if (ifa = ifp -> if_addrlist) { for ( ; ifa -> ifa_next; ifa = ifa -> ifa_next) ; ifa -> ifa_next = &ia -> ia_ifa; } else ifp -> if_addrlist = &ia -> ia_ifa; ifa = &ia -> ia_ifa; ifa -> ifa_netmask = (struct sockaddr *)&pk_sockmask; ifa -> ifa_addr = (struct sockaddr *)&ia -> ia_xc.xc_addr; ifa -> ifa_dstaddr = (struct sockaddr *)&ia -> ia_dstaddr; /* XXX */ ia -> ia_ifp = ifp; ia -> ia_dstaddr.x25_family = AF_CCITT; ia -> ia_dstaddr.x25_len = pk_sockmask.x25_len; } else if (ISISO8802(ifp) == 0) { rtinit (ifa, (int)RTM_DELETE, 0); } old_maxlcn = ia -> ia_maxlcn; ia -> ia_xc = ifr -> ifr_xc; ia -> ia_dstaddr.x25_net = ia -> ia_xc.xc_addr.x25_net; if (ia -> ia_maxlcn != old_maxlcn && old_maxlcn != 0) { /* VERY messy XXX */ register struct pkcb *pkp; FOR_ALL_PKCBS(pkp) if (pkp -> pk_ia == ia) pk_resize (pkp); } /* * Give the interface a chance to initialize if thisp * is its first address, and to validate the address. */ ia -> ia_start = pk_start; s = splimp(); if (ifp -> if_ioctl) error = (*ifp -> if_ioctl)(ifp, SIOCSIFCONF_X25, (caddr_t) ifa); if (error) ifp -> if_flags &= ~IFF_UP; else if (ISISO8802(ifp) == 0) error = rtinit (ifa, (int)RTM_ADD, RTF_UP); splx (s); return (error); default: if (ifp == 0 || ifp -> if_ioctl == 0) return (EOPNOTSUPP); return ((*ifp -> if_ioctl)(ifp, cmd, data)); }}pk_ctloutput (cmd, so, level, optname, mp)struct socket *so;struct mbuf **mp;int cmd, level, optname;{ register struct mbuf *m = *mp; register struct pklcd *lcp = (struct pklcd *) so -> so_pcb; int error = EOPNOTSUPP; if (m == 0) return (EINVAL); if (cmd == PRCO_SETOPT) switch (optname) { case PK_FACILITIES: if (m == 0) return (EINVAL); lcp -> lcd_facilities = m; *mp = 0; return (0); case PK_ACCTFILE: if ((so->so_state & SS_PRIV) == 0) error = EPERM; else if (m -> m_len) error = pk_accton (mtod (m, char *)); else error = pk_accton ((char *)0); break; case PK_RTATTACH: error = pk_rtattach (so, m); break; case PK_PRLISTEN: error = pk_user_protolisten (mtod (m, u_char *)); } if (*mp) { (void) m_freem (*mp); *mp = 0; } return (error);}/* * Do an in-place conversion of an "old style" * socket address to the new style */staticold_to_new (m)register struct mbuf *m;{ register struct x25_sockaddr *oldp; register struct sockaddr_x25 *newp; register char *ocp, *ncp; struct sockaddr_x25 new; oldp = mtod (m, struct x25_sockaddr *); newp = &new; bzero ((caddr_t)newp, sizeof (*newp)); newp -> x25_family = AF_CCITT; newp -> x25_len = sizeof(*newp); newp -> x25_opts.op_flags = (oldp -> xaddr_facilities & X25_REVERSE_CHARGE) | X25_MQBIT | X25_OLDSOCKADDR; if (oldp -> xaddr_facilities & XS_HIPRIO) /* Datapac specific */ newp -> x25_opts.op_psize = X25_PS128; bcopy ((caddr_t)oldp -> xaddr_addr, newp -> x25_addr, (unsigned)min (oldp -> xaddr_len, sizeof (newp -> x25_addr) - 1)); if (bcmp ((caddr_t)oldp -> xaddr_proto, newp -> x25_udata, 4) != 0) { bcopy ((caddr_t)oldp -> xaddr_proto, newp -> x25_udata, 4); newp -> x25_udlen = 4; } ocp = (caddr_t)oldp -> xaddr_userdata; ncp = newp -> x25_udata + 4; while (*ocp && ocp < (caddr_t)oldp -> xaddr_userdata + 12) { if (newp -> x25_udlen == 0) newp -> x25_udlen = 4; *ncp++ = *ocp++; newp -> x25_udlen++; } bcopy ((caddr_t)newp, mtod (m, char *), sizeof (*newp)); m -> m_len = sizeof (*newp);}/* * Do an in-place conversion of a new style * socket address to the old style */staticnew_to_old (m)register struct mbuf *m;{ register struct x25_sockaddr *oldp; register struct sockaddr_x25 *newp; register char *ocp, *ncp; struct x25_sockaddr old; oldp = &old; newp = mtod (m, struct sockaddr_x25 *); bzero ((caddr_t)oldp, sizeof (*oldp)); oldp -> xaddr_facilities = newp -> x25_opts.op_flags & X25_REVERSE_CHARGE; if (newp -> x25_opts.op_psize == X25_PS128) oldp -> xaddr_facilities |= XS_HIPRIO; /* Datapac specific */ ocp = (char *)oldp -> xaddr_addr; ncp = newp -> x25_addr; while (*ncp) { *ocp++ = *ncp++; oldp -> xaddr_len++; } bcopy (newp -> x25_udata, (caddr_t)oldp -> xaddr_proto, 4); if (newp -> x25_udlen > 4) bcopy (newp -> x25_udata + 4, (caddr_t)oldp -> xaddr_userdata, (unsigned)(newp -> x25_udlen - 4)); bcopy ((caddr_t)oldp, mtod (m, char *), sizeof (*oldp)); m -> m_len = sizeof (*oldp);}pk_checksockaddr (m)struct mbuf *m;{ register struct sockaddr_x25 *sa = mtod (m, struct sockaddr_x25 *); register char *cp; if (m -> m_len != sizeof (struct sockaddr_x25)) return (1); if (sa -> x25_family != AF_CCITT || sa -> x25_udlen > sizeof (sa -> x25_udata)) return (1); for (cp = sa -> x25_addr; *cp; cp++) { if (*cp < '0' || *cp > '9' || cp >= &sa -> x25_addr[sizeof (sa -> x25_addr) - 1]) return (1); } return (0);}pk_send (lcp, m)struct pklcd *lcp;register struct mbuf *m;{ int mqbit = 0, error = 0; register struct x25_packet *xp; register struct socket *so; if (m -> m_type == MT_OOBDATA) { if (lcp -> lcd_intrconf_pending) error = ETOOMANYREFS; if (m -> m_pkthdr.len > 32) error = EMSGSIZE; M_PREPEND(m, PKHEADERLN, M_WAITOK); if (m == 0 || error) goto bad; *(mtod (m, octet *)) = 0; xp = mtod (m, struct x25_packet *); X25SBITS(xp -> bits, fmt_identifier, 1); xp -> packet_type = X25_INTERRUPT; SET_LCN(xp, lcp -> lcd_lcn); sbinsertoob ( (so = lcp -> lcd_so) ? &so -> so_snd : &lcp -> lcd_sb, m); goto send; } /* * Application has elected (at call setup time) to prepend * a control byte to each packet written indicating m-bit * and q-bit status. Examine and then discard this byte. */ if (lcp -> lcd_flags & X25_MQBIT) { if (m -> m_len < 1) { m_freem (m); return (EMSGSIZE); } mqbit = *(mtod (m, u_char *)); m -> m_len--; m -> m_data++; m -> m_pkthdr.len--; } error = pk_fragment (lcp, m, mqbit & 0x80, mqbit & 0x40, 1);send: if (error == 0 && lcp -> lcd_state == DATA_TRANSFER) lcp -> lcd_send (lcp); /* XXXXXXXXX fix pk_output!!! */ return (error);bad: if (m) m_freem (m); return (error);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -