int rtloginl () { LINK *link; CIRCUIT *circuit; SADDR sp; char *buf, call[ln_axaddr+1]; if (MemLow) return cmd_exit; getpeername(CurProc->input, &sp); if (sp.type isnt TYPE_NETROM) return cmd_exit; ax2str(call, sp.a.nr.node); if (node_find(call)) return cmd_exit; // Already linked. for (link = link_hd; link; link = link->next) if (matchi(call, link->call)) break; if (!link) return cmd_exit; // We don't link with this system. if (link->flags & (p_linked | p_linkini)) return cmd_exit; // Already linked. // Accept the link request. puser(link->alias); buf = mallocw(LINE128); strcpy(buf, call); strlop(buf, '-'); puser(buf); free(buf); // Create a circuit for this link. circuit = circuit_new(p_linked, CurProc->output); if (!circuit) return cmd_exit; tputs("OK\n"); circuit->u.link = link; link->flags = p_linked; state_tell(circuit); makelinks(); // Run in circles, scream and shout. for (;;) if (getinp(circuit)) chkctl(circuit); else { link_drop(circuit); link->flags = p_nil; return cmd_exit; } }
static void dissect_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *isdn_tree; proto_item *ti; static const guint8 v120_sabme[3] = { 0x08, 0x01, 0x7F }; static const guint8 ppp[2] = { 0xFF, 0x03 }; circuit_t *circuit; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISDN"); if (pinfo->pseudo_header->isdn.uton) { col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Network"); col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "User"); } else { col_set_str(pinfo->cinfo, COL_RES_DL_DST, "User"); col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "Network"); } pinfo->ctype = CT_ISDN; pinfo->circuit_id = pinfo->pseudo_header->isdn.channel; if (tree) { ti = proto_tree_add_item(tree, proto_isdn, tvb, 0, 0, ENC_NA); isdn_tree = proto_item_add_subtree(ti, ett_isdn); proto_tree_add_uint(isdn_tree, hf_isdn_channel, tvb, 0, 0, pinfo->pseudo_header->isdn.channel); } /* * Set up a circuit for this channel, and assign it a dissector. */ circuit = find_circuit(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num); if (circuit == NULL) circuit = circuit_new(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num); if (circuit_get_dissector(circuit) == NULL) { /* * We don't yet know the type of traffic on the circuit. */ switch (pinfo->pseudo_header->isdn.channel) { case 0: /* * D-channel. Dissect it with whatever protocol * the user specified, or the default of LAPD if * they didn't specify one. */ switch (dchannel_protocol) { case DCHANNEL_LAPD: circuit_set_dissector(circuit, lapd_handle); break; case DCHANNEL_DPNSS: circuit_set_dissector(circuit, dpnss_link_handle); break; } break; default: /* * B-channel. * * We don't know yet whether the datastream is * V.120 or not; this heuristic tries to figure * that out. * * We cannot glean this from the Q.931 SETUP message, * because no commercial V.120 implementation I've * seen actually sets the V.120 protocol discriminator * (that, or I'm misreading the spec badly). * * TODO: close the circuit after a close on the B * channel is detected. * * -Bert Driehuis (from the i4btrace reader; * this heuristic was moved from there to * here) * * XXX - I don't know that one can guarantee that * the SABME will appear in the first frame on * the channels, so we probably can't just say * "it must be PPP" if we don't immediately see * the V.120 SABME frame, so we do so only if * we see the 0xFF 0x03. Unfortunately, that * won't do the right thing if the PPP-over-HDLC * headers aren't being used.... */ if (tvb_memeql(tvb, 0, v120_sabme, 3) == 0) { /* * We assume this is V.120. */ circuit_set_dissector(circuit, v120_handle); } else if (tvb_memeql(tvb, 0, ppp, 2) == 0) { /* * We assume this is PPP. */ circuit_set_dissector(circuit, ppp_hdlc_handle); } break; } } if (!try_circuit_dissector(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num, tvb, pinfo, tree, NULL)) call_dissector(data_handle, tvb, pinfo, tree); }
static void link_out () { LINK *link; NR_NODE *np; CIRCUIT *circuit; SADDR addr; word s; link = (LINK *)p; if (MemLow) { link->flags = p_nil; return; } puser(link->alias); // See if the requested destination is a known alias or call, // use it if it is. Otherwise give up. np = nr_findca(link->call); if (!np) { link->flags = p_nil; return; } s = socket(TYPE_NETROM); mysock(s); flushoff(s); // The RT control process will do the flush. // Set up the local and remote addresses. addr.type = TYPE_NETROM; memcpy(addr.a.nr.user, Node->call, ln_call+1); memcpy(addr.a.nr.node, Node->call, ln_call+1); bind(s, &addr); memcpy(addr.a.nr.user, np->call, ln_call+1); memcpy(addr.a.nr.node, np->call, ln_call+1); if (!connect(s, &addr)) { link->flags = p_nil; return; } // Create a circuit for this link. circuit = circuit_new(p_linkini, s); if (!circuit) { link->flags = p_nil; return; } circuit->u.link = link; tputs("*RTL\n"); // Log in to the remote RT system. // Run in circles, scream and shout. for (;;) if (getinp(circuit)) { if (circuit->flags & p_linked) chkctl(circuit); else { if (!matchi(circuit->buf, "OK")) { link_drop(circuit); link->flags = p_nil; return; } link->flags = p_linked; circuit->flags = p_linked; state_tell(circuit); } } else { link_drop(circuit); link->flags = p_nil; return; } }
int rtloginu () { CIRCUIT *c, *circuit; USER *user; // Is this user already logged in to RT somewhere else? if (user_find(CurProc->user)) { tputs("*** Already connected at another node.\n"); return cmd_exit; } if (log_rt) tlogp("RT Login"); // Create a circuit for this user. circuit = circuit_new(p_user, CurProc->output); if (!circuit) return cmd_exit; // Create the user entry. user = user_join(circuit, CurProc->user, Node->calls, Node->aliass); circuit->u.user = user; tputs("RoundTable Server.\nType /h for command summary.\nBringing up links to other nodes.\n"); tputs("This may take a minute or two.\nThe /p command shows what nodes are linked.\n"); text_tellu(user, rtjoin, NULL, o_all); user_tell(user, id_join); show_users(); makelinks(); // Run in circles, scream and shout. for (;;) if (getinp(circuit)) { if (circuit->buf[0] is '/') { if (!rt_cmd(circuit)) { tputs("Returned to node.\n"); logout(circuit); return cmd_ok; } } else { text_tellu(user, circuit->buf, NULL, o_topic); // To local users. // To remote users. for (c = circuit_hd; c; c = c->next) if ((c->flags & p_linked) && c->refcnt && ct_find(c, user->topic)) nprintf(c->s, "%c%c%s %s %s\n", FORMAT, id_data, Node->calls, user->call, circuit->buf); } } else { logout(circuit); return cmd_exit; } }