+/*
+ * FUNCTION: isis_input
+ *
+ * PURPOSE: Process an incoming isis packet
+ *
+ * RETURNS: nothing
+ *
+ * SIDE EFFECTS:
+ *
+ * NOTES:
+ */
+isis_input(m0, shp)
+struct mbuf *m0; /* ptr to first mbuf of pkt */
+struct snpa_hdr *shp; /* subnetwork header */
+{
+ register int type;
+ register struct rawcb *rp, *first_rp = 0;
+ struct ifnet *ifp = shp->snh_ifp;
+ char workbuf[16];
+ struct mbuf *mm;
+
+ IFDEBUG(D_ISISINPUT)
+ int i;
+
+ printf("isis_input: pkt on ifp x%x (%s%d): from:", ifp,
+ ifp->if_name, ifp->if_unit);
+ for (i=0; i<6; i++)
+ printf("%x%c", shp->snh_shost[i]&0xff, (i<5) ? ':' : ' ');
+ printf(" to:");
+ for (i=0; i<6; i++)
+ printf("%x%c", shp->snh_dhost[i]&0xff, (i<5) ? ':' : ' ');
+ printf("\n");
+ ENDDEBUG
+ esis_dl.sdl_alen = ifp->if_addrlen;
+ esis_dl.sdl_index = ifp->if_index;
+ bcopy(shp->snh_shost, (caddr_t)esis_dl.sdl_data, esis_dl.sdl_alen);
+ for (rp = esis_pcb.rcb_next; rp != &esis_pcb; rp = rp->rcb_next) {
+ if (first_rp == 0) {
+ first_rp = rp;
+ continue;
+ }
+ if (mm = m_copy(m0, 0, M_COPYALL)) { /*can't block at interrupt level */
+ if (sbappendaddr(&rp->rcb_socket->so_rcv,
+ &esis_dl, mm, (struct mbuf *)0) != 0)
+ sorwakeup(rp->rcb_socket);
+ else {
+ IFDEBUG(D_ISISINPUT)
+ printf("Error in sbappenaddr, mm = 0x%x\n", mm);
+ ENDDEBUG
+ m_freem(mm);
+ }
+ }
+ }
+ if (first_rp && sbappendaddr(&first_rp->rcb_socket->so_rcv,
+ &esis_dl, m0, (struct mbuf *)0) != 0) {
+ sorwakeup(first_rp->rcb_socket);
+ return;
+ }
+ m_freem(m0);
+}
+
+isis_output(sdl, m)
+register struct sockaddr_dl *sdl;
+struct mbuf *m;
+{
+ register struct ifnet *ifp;
+ struct ifaddr *ifa, *ifa_ifwithnet();
+ struct sockaddr_iso siso;
+ int error = 0;
+ unsigned sn_len;
+
+ ifa = ifa_ifwithnet(sdl); /* extract ifp from sockaddr_dl */
+ if (ifa == 0) {
+ IFDEBUG(D_ISISOUTPUT)
+ printf("isis_output: interface not found\n");
+ ENDDEBUG
+ error = EINVAL;
+ goto release;
+ }
+ ifp = ifa->ifa_ifp;
+ sn_len = sdl->sdl_alen;
+ IFDEBUG(D_ISISOUTPUT)
+ u_char *cp = (u_char *)LLADDR(sdl), *cplim = cp + sn_len;
+ printf("isis_output: ifp 0x%x (%s%d), to: ",
+ ifp, ifp->if_name, ifp->if_unit);
+ while (cp < cplim) {
+ printf("%x", *cp++);
+ printf("%c", (cp < cplim) ? ':' : ' ');
+ }
+ printf("\n");
+ ENDDEBUG
+ bzero((caddr_t)&siso, sizeof(siso));
+ siso.siso_family = AF_ISO; /* This convention may be useful for X.25 */
+ siso.siso_data[0] = AFI_SNA;
+ siso.siso_nlen = sn_len + 1;
+ bcopy(LLADDR(sdl), siso.siso_data + 1, sn_len);
+ error = (ifp->if_output)(ifp, m, (struct sockaddr *)&siso, 0);
+ if (error) {
+ IFDEBUG(D_ISISOUTPUT)
+ printf("isis_output: error from ether_output is %d\n", error);
+ ENDDEBUG
+ }
+ return (error);
+
+release:
+ if (m != NULL)
+ m_freem(m);
+ return(error);
+}
+
+