📄 if_cons.c
字号:
case 0x05: /* network congestion */ case 0x85: case 0x8d: /* not obtainable */ case 0x0d: case 0x95: /* RPOA out of order */ case 0x15: /* take out bit 8 * so we don't have to have so many perror entries */ error = (CONL_ERROR_MASK | 0x100 | (cause & ~0x80)); goto done; case 0xc1: /* gateway-detected proc error */ case 0xc3: /* gateway congestion */ error = (CONL_ERROR_MASK | 0x100 | cause); goto done; } } /* otherwise, a *hopefully* valid perror exists in the e_reason field */ error = xp->packet_data; if (error = 0) { printf("Incoming PKT TYPE 0x%x with reason 0x%x\n", pk_decode(xp), cause); error = E_CO_HLI_DISCA; } done: return error;}#endif /* KERNEL *//* * NAME: make_partial_x25_packet() * * FUNCTION and ARGUMENTS: * Makes part of an X.25 call packet, for use by x25. * (src) and (dst) are the NSAP-addresses of source and destination. * (buf) is a ptr to a buffer into which to write this partial header. * * 0 Facility length (in octets) * 1 Facility field, which is a set of: * m facil code * m+1 facil param len (for >2-byte facilities) in octets * m+2..p facil param field * q user data (protocol identification octet) * * * RETURNS: * 0 if OK * E* if failed. * * SIDE EFFECTS: * Stores facilites mbuf in X.25 control block, where the connect * routine knows where to look for it. */#ifdef X25_1984 int cons_use_facils = 1;#else /* X25_1984 */int cons_use_facils = 0;#endif /* X25_1984 */int cons_use_udata = 1; /* KLUDGE FOR DEBUGGING */Static intmake_partial_x25_packet(isop, lcp) struct isopcb *isop; struct pklcd *lcp;{ u_int proto; int flag; caddr_t buf; register caddr_t ptr; register int len = 0; int buflen =0; caddr_t facil_len; int oddness = 0; struct mbuf *m; IFDEBUG(D_CCONN) printf("make_partial_x25_packet(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", isop->isop_laddr, isop->isop_faddr, proto, m, flag); ENDDEBUG if (cons_use_udata) { if (isop->isop_x25crud_len > 0) { /* * The user specified something. Stick it in */ bcopy(isop->isop_x25crud, lcp->lcd_faddr.x25_udata, isop->isop_x25crud_len); lcp->lcd_faddr.x25_udlen = isop->isop_x25crud_len; } } if (cons_use_facils == 0) { lcp->lcd_facilities = 0; return 0; } MGETHDR(m, MT_DATA, M_WAITOK); if (m == 0) return ENOBUFS; buf = mtod(m, caddr_t); ptr = buf; /* ptr now points to facil length (len of whole facil field in OCTETS */ facil_len = ptr ++; m->m_len = 0; pk_build_facilities(m, &lcp->lcd_faddr, 0); IFDEBUG(D_CADDR) printf("make_partial calling: ptr 0x%x, len 0x%x\n", ptr, isop->isop_laddr->siso_addr.isoa_len); ENDDEBUG if (cons_use_facils) { *ptr++ = 0; /* Marker to separate X.25 facitilies from CCITT ones */ *ptr++ = 0x0f; *ptr = 0xcb; /* calling facility code */ ptr ++; ptr ++; /* leave room for facil param len (in OCTETS + 1) */ ptr ++; /* leave room for the facil param len (in nibbles), * high two bits of which indicate full/partial NSAP */ len = isop->isop_laddr->siso_addr.isoa_len; bcopy( isop->isop_laddr->siso_data, ptr, len); *(ptr-2) = len+1; /* facil param len in octets */ *(ptr-1) = len<<1; /* facil param len in nibbles */ ptr += len; IFDEBUG(D_CADDR) printf("make_partial called: ptr 0x%x, len 0x%x\n", ptr, isop->isop_faddr->siso_addr.isoa_len); ENDDEBUG *ptr = 0xc9; /* called facility code */ ptr ++; ptr ++; /* leave room for facil param len (in OCTETS + 1) */ ptr ++; /* leave room for the facil param len (in nibbles), * high two bits of which indicate full/partial NSAP */ len = isop->isop_faddr->siso_nlen; bcopy(isop->isop_faddr->siso_data, ptr, len); *(ptr-2) = len+1; /* facil param len = addr len + 1 for each of these * two length fields, in octets */ *(ptr-1) = len<<1; /* facil param len in nibbles */ ptr += len; } *facil_len = ptr - facil_len - 1; if (*facil_len > MAX_FACILITIES) return E_CO_PNA_LONG; buflen = (int)(ptr - buf); IFDEBUG(D_CDUMP_REQ) register int i; printf("ECN_CONNECT DATA buf 0x%x len %d (0x%x)\n", buf, buflen, buflen); for( i=0; i < buflen; ) { printf("+%d: %x %x %x %x %x %x %x %x\n", i, *(buf+i), *(buf+i+1), *(buf+i+2), *(buf+i+3), *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7)); i+=8; } ENDDEBUG IFDEBUG(D_CADDR) printf("make_partial returns buf 0x%x size 0x%x bytes\n", mtod(m, caddr_t), buflen); ENDDEBUG if (buflen > MHLEN) return E_CO_PNA_LONG; m->m_pkthdr.len = m->m_len = buflen; lcp->lcd_facilities = m; return 0;}/* * NAME: NSAPtoDTE() * CALLED FROM: * make_partial_x25_packet() * FUNCTION and ARGUMENTS: * get a DTE address from an NSAP-address (struct sockaddr_iso) * (dst_octet) is the octet into which to begin stashing the DTE addr * (dst_nibble) takes 0 or 1. 1 means begin filling in the DTE addr * in the high-order nibble of dst_octet. 0 means low-order nibble. * (addr) is the NSAP-address * (flag) is true if the transport suffix is to become the * last two digits of the DTE address * A DTE address is a series of ASCII digits * * A DTE address may have leading zeros. The are significant. * 1 digit per nibble, may be an odd number of nibbles. * * An NSAP-address has the DTE address in the IDI. Leading zeros are * significant. Trailing hex f indicates the end of the DTE address. * The IDI is a series of BCD digits, one per nibble. * * RETURNS * # significant digits in the DTE address, -1 if error. */Static intNSAPtoDTE(siso, sx25) register struct sockaddr_iso *siso; register struct sockaddr_x25 *sx25;{ int dtelen = -1; IFDEBUG(D_CADDR) printf("NSAPtoDTE: nsap: %s\n", clnp_iso_addrp(&siso->siso_addr)); ENDDEBUG if (siso->siso_data[0] == AFI_37) { register char *out = sx25->x25_addr; register char *in = siso->siso_data + 1; register int nibble; char *lim = siso->siso_data + siso->siso_nlen; char *olim = out+15; int lowNibble = 0; while (in < lim) { nibble = ((lowNibble ? *in++ : (*in >> 4)) & 0xf) | 0x30; lowNibble ^= 1; if (nibble != 0x3f && out < olim) *out++ = nibble; } dtelen = out - sx25->x25_addr; *out++ = 0; } else { /* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/ register struct rtentry *rt; extern struct sockaddr_iso blank_siso; struct sockaddr_iso nsiso; nsiso = blank_siso; bcopy(nsiso.siso_data, siso->siso_data, nsiso.siso_nlen = siso->siso_nlen); if (rt = rtalloc1(&nsiso, 1)) { register struct sockaddr_x25 *sxx = (struct sockaddr_x25 *)rt->rt_gateway; register char *in = sxx->x25_addr; rt->rt_use--; if (sxx && sxx->x25_family == AF_CCITT) { bcopy(sx25->x25_addr, sxx->x25_addr, sizeof(sx25->x25_addr)); while (*in++) {} dtelen = in - sxx->x25_addr; } } } return dtelen;}/* * NAME: FACILtoNSAP() * CALLED FROM: * parse_facil() * FUNCTION and ARGUMENTS: * Creates and NSAP in the sockaddr_iso (addr) from the * x.25 facility found at buf - 1. * RETURNS: * 0 if ok, -1 if error. */Static intFACILtoNSAP(addr, buf) register u_char *buf; register struct sockaddr_iso *addr;{ int len_in_nibbles = *++buf & 0x3f; u_char buf_len = (len_in_nibbles + 1) >> 1;; /* in bytes */ IFDEBUG(D_CADDR) printf("FACILtoNSAP( 0x%x, 0x%x, 0x%x )\n", buf, buf_len, addr ); ENDDEBUG len_in_nibbles = *buf & 0x3f; /* despite the fact that X.25 makes us put a length in nibbles * here, the NSAP-addrs are always in full octets */ switch (*buf++ & 0xc0) { case 0: /* Entire OSI NSAP address */ bcopy((caddr_t)buf, addr->siso_data, addr->siso_nlen = buf_len); break; case 40: /* Partial OSI NSAP address, assume trailing */ if (buf_len + addr->siso_nlen > sizeof(addr->siso_addr)) return -1; bcopy((caddr_t)buf, TSEL(addr), buf_len); addr->siso_nlen += buf_len; break; default: /* Rather than blow away the connection, just ignore and use NSAP from DTE */; } return 0;}Staticinit_siso(siso)register struct sockaddr_iso *siso;{ siso->siso_len = sizeof (*siso); siso->siso_family = AF_ISO; siso->siso_data[0] = AFI_37; siso->siso_nlen = 8;}/* * NAME: DTEtoNSAP() * CALLED FROM: * parse_facil() * FUNCTION and ARGUMENTS: * Creates a type 37 NSAP in the sockaddr_iso (addr) * from a DTE address found in a sockaddr_x25. * * RETURNS: * 0 if ok; E* otherwise. */Static intDTEtoNSAP(addr, sx) struct sockaddr_iso *addr; struct sockaddr_x25 *sx;{ register char *in, *out; register int first; int pad_tail = 0; int src_len; init_siso(addr); in = sx->x25_addr; src_len = strlen(in); addr->siso_nlen = (src_len + 3) / 2; out = addr->siso_data; *out++ = 0x37; if (src_len & 1) { pad_tail = 0xf; src_len++; } for (first = 0; src_len > 0; src_len--) { first |= 0xf & *in++; if (src_len & 1) { *out++ = first; first = 0; } else first <<= 4; } if (pad_tail) out[-1] |= 0xf; return 0; /* ok */}/* * FUNCTION and ARGUMENTS: * parses (buf_len) bytes beginning at (buf) and finds * a called nsap, a calling nsap, and protocol identifier. * RETURNS: * 0 if ok, E* otherwise. */Static intparse_facil(lcp, isop, buf, buf_len) caddr_t buf; u_char buf_len; /* in bytes */ struct isopcb *isop; struct pklcd *lcp;{ register int i; register u_char *ptr = (u_char *)buf; u_char *ptr_lim, *facil_lim; int facil_param_len, facil_len; IFDEBUG(D_CADDR) printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n", lcp, isop, buf, buf_len); dump_buf(buf, buf_len); ENDDEBUG /* find the beginnings of the facility fields in buf * by skipping over the called & calling DTE addresses * i <- # nibbles in called + # nibbles in calling * i += 1 so that an odd nibble gets rounded up to even * before dividing by 2, then divide by two to get # octets */ i = (int)(*ptr >> 4) + (int)(*ptr&0xf); i++; ptr += i >> 1; ptr ++; /* plus one for the DTE lengths byte */ /* ptr now is at facil_length field */ facil_len = *ptr++; facil_lim = ptr + facil_len; IFDEBUG(D_CADDR) printf("parse_facils: facil length is 0x%x\n", (int) facil_len); ENDDEBUG while (ptr < facil_lim) { /* get NSAP addresses from facilities */ switch (*ptr++) { case 0xcb: /* calling NSAP */ facil_param_len = FACILtoNSAP(isop->isop_faddr, ptr); break; case 0xc9: /* called NSAP */ facil_param_len = FACILtoNSAP(isop->isop_laddr, ptr); break; /* from here to default are legit cases that I ignore */ /* variable length */ case 0xca: /* end-to-end transit delay negot */ case 0xc6: /* network user id */ case 0xc5: /* charging info : indicating monetary unit */ case 0xc2: /* charging info : indicating segment count */ case 0xc1: /* charging info : indicating call duration */ case 0xc4: /* RPOA extended format */ case 0xc3: /* call redirection notification */ facil_param_len = 0; break; /* 1 octet */ case 0x0a: /* min. throughput class negot */ case 0x02: /* throughput class */ case 0x03: case 0x47: /* CUG shit */ case 0x0b: /* expedited data negot */ case 0x01: /* Fast select or reverse charging (example of intelligent protocol design) */ case 0x04: /* charging info : requesting service */ case 0x08: /* called line addr modified notification */ case 0x00: /* marker to indicate beginning of CCITT facils */ facil_param_len = 1; break; /* any 2 octets */ case 0x42: /* pkt size */ case 0x43: /* win size */ case 0x44: /* RPOA basic format */ case 0x41: /* bilateral CUG shit */ case 0x49: /* transit delay selection and indication */ facil_param_len = 2; break; default: printf("BOGUS FACILITY CODE facil_lim 0x%x facil_len %d, ptr 0x%x *ptr 0x%x\n", facil_lim, facil_len, ptr - 1, ptr[-1]); /* facil that we don't handle return E_CO_HLI_REJI; */ switch (ptr[-1] & 0xc0) { case 0x00: facil_param_len = 1; break; case 0x40: facil_param_len = 2; break; case 0x80: facil_param_len = 3; break; case 0xc0: facil_param_len = 0; break; } } if (facil_param_len == -1) return E_CO_REG_ICDA; if (facil_param_len == 0) /* variable length */ facil_param_len = (int)*ptr++; /* 1 + the real facil param */ ptr += facil_param_len; } return 0;}#endif /* TPCONS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -