📄 utility.c
字号:
/* direction: '<' or '>' *//* pointer: where suboption data sits *//* length: length of suboption data */voidprintsub(char direction, unsigned char *pointer, int length){ register int i = -1;#ifdef AUTHENTICATE char buf[512];#endif if (!(diagnostic & TD_OPTIONS)) return; if (direction) { netoprintf("td: %s suboption ", direction == '<' ? "recv" : "send"); if (length >= 3) { register int j; i = pointer[length-2]; j = pointer[length-1]; if (i != IAC || j != SE) { netoprintf("(terminated by "); if (TELOPT_OK(i)) netoprintf("%s ", TELOPT(i)); else if (TELCMD_OK(i)) netoprintf("%s ", TELCMD(i)); else netoprintf("%d ", i); if (TELOPT_OK(j)) netoprintf("%s", TELOPT(j)); else if (TELCMD_OK(j)) netoprintf("%s", TELCMD(j)); else netoprintf("%d", j); netoprintf(", not IAC SE!) "); } } length -= 2; } if (length < 1) { netoprintf("(Empty suboption???)"); return; } switch (pointer[0]) { case TELOPT_TTYPE: netoprintf("TERMINAL-TYPE "); switch (pointer[1]) { case TELQUAL_IS: netoprintf("IS \"%.*s\"", length-2, (char *)pointer+2); break; case TELQUAL_SEND: netoprintf("SEND"); break; default: netoprintf("- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_TSPEED: netoprintf("TERMINAL-SPEED"); if (length < 2) { netoprintf(" (empty suboption???)"); break; } switch (pointer[1]) { case TELQUAL_IS: netoprintf(" IS %.*s", length-2, (char *)pointer+2); break; default: if (pointer[1] == 1) netoprintf(" SEND"); else netoprintf(" %d (unknown)", pointer[1]); for (i = 2; i < length; i++) { netoprintf(" ?%d?", pointer[i]); } break; } break; case TELOPT_LFLOW: netoprintf("TOGGLE-FLOW-CONTROL"); if (length < 2) { netoprintf(" (empty suboption???)"); break; } switch (pointer[1]) { case 0: netoprintf(" OFF"); break; case 1: netoprintf(" ON"); break; default: netoprintf(" %d (unknown)", pointer[1]); } for (i = 2; i < length; i++) { netoprintf(" ?%d?", pointer[i]); } break; case TELOPT_NAWS: netoprintf("NAWS"); if (length < 2) { netoprintf(" (empty suboption???)"); break; } if (length == 2) { netoprintf(" ?%d?", pointer[1]); break; } netoprintf(" %d %d (%d)", pointer[1], pointer[2], (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); if (length == 4) { netoprintf(" ?%d?", pointer[3]); break; } netoprintf(" %d %d (%d)", pointer[3], pointer[4], (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); for (i = 5; i < length; i++) { netoprintf(" ?%d?", pointer[i]); } break; case TELOPT_LINEMODE: netoprintf("LINEMODE "); if (length < 2) { netoprintf(" (empty suboption???)"); break; } switch (pointer[1]) { case WILL: netoprintf("WILL "); goto common; case WONT: netoprintf("WONT "); goto common; case DO: netoprintf("DO "); goto common; case DONT: netoprintf("DONT "); common: if (length < 3) { netoprintf("(no option???)"); break; } switch (pointer[2]) { case LM_FORWARDMASK: netoprintf("Forward Mask"); for (i = 3; i < length; i++) { netoprintf(" %x", pointer[i]); } break; default: netoprintf("%d (unknown)", pointer[2]); for (i = 3; i < length; i++) { netoprintf(" %d", pointer[i]); } break; } break; case LM_SLC: netoprintf("SLC"); for (i = 2; i < length - 2; i += 3) { if (SLC_NAME_OK(pointer[i+SLC_FUNC])) netoprintf(" %s", SLC_NAME(pointer[i+SLC_FUNC])); else netoprintf(" %d", pointer[i+SLC_FUNC]); switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { case SLC_NOSUPPORT: netoprintf(" NOSUPPORT"); break; case SLC_CANTCHANGE: netoprintf(" CANTCHANGE"); break; case SLC_VARIABLE: netoprintf(" VARIABLE"); break; case SLC_DEFAULT: netoprintf(" DEFAULT"); break; } netoprintf("%s%s%s", pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| SLC_FLUSHOUT| SLC_LEVELBITS)) { netoprintf("(0x%x)", pointer[i+SLC_FLAGS]); } netoprintf(" %d;", pointer[i+SLC_VALUE]); if ((pointer[i+SLC_VALUE] == IAC) && (pointer[i+SLC_VALUE+1] == IAC)) i++; } for (; i < length; i++) { netoprintf(" ?%d?", pointer[i]); } break; case LM_MODE: netoprintf("MODE "); if (length < 3) { netoprintf("(no mode???)"); break; } { char tbuf[32]; snprintf(tbuf, sizeof(tbuf), "%s%s%s%s%s", pointer[2]&MODE_EDIT ? "|EDIT" : "", pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", pointer[2]&MODE_ACK ? "|ACK" : ""); netoprintf("%s", tbuf[1] ? &tbuf[1] : "0"); } if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) { netoprintf(" (0x%x)", pointer[2]); } for (i = 3; i < length; i++) { netoprintf(" ?0x%x?", pointer[i]); } break; default: netoprintf("%d (unknown)", pointer[1]); for (i = 2; i < length; i++) { netoprintf(" %d", pointer[i]); } } break; case TELOPT_STATUS: { const char *cp; register int j, k; netoprintf("STATUS"); switch (pointer[1]) { default: if (pointer[1] == TELQUAL_SEND) netoprintf(" SEND"); else netoprintf(" %d (unknown)", pointer[1]); for (i = 2; i < length; i++) { netoprintf(" ?%d?", pointer[i]); } break; case TELQUAL_IS: netoprintf(" IS\r\n"); for (i = 2; i < length; i++) { switch(pointer[i]) { case DO: cp = "DO"; goto common2; case DONT: cp = "DONT"; goto common2; case WILL: cp = "WILL"; goto common2; case WONT: cp = "WONT"; goto common2; common2: i++; if (TELOPT_OK((int)pointer[i])) netoprintf(" %s %s", cp, TELOPT(pointer[i])); else netoprintf(" %s %d", cp, pointer[i]); netoprintf("\r\n"); break; case SB: netoprintf(" SB "); i++; j = k = i; while (j < length) { if (pointer[j] == SE) { if (j+1 == length) break; if (pointer[j+1] == SE) j++; else break; } pointer[k++] = pointer[j++]; } printsub(0, &pointer[i], k - i); if (i < length) { netoprintf(" SE"); i = j; } else i = j - 1; netoprintf("\r\n"); break; default: netoprintf(" %d", pointer[i]); break; } } break; } break; } case TELOPT_XDISPLOC: netoprintf("X-DISPLAY-LOCATION "); switch (pointer[1]) { case TELQUAL_IS: netoprintf("IS \"%.*s\"", length-2, (char *)pointer+2); break; case TELQUAL_SEND: netoprintf("SEND"); break; default: netoprintf("- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_ENVIRON: netoprintf("ENVIRON "); switch (pointer[1]) { case TELQUAL_IS: netoprintf("IS "); goto env_common; case TELQUAL_SEND: netoprintf("SEND "); goto env_common; case TELQUAL_INFO: netoprintf("INFO "); env_common: { register int noquote = 2; for (i = 2; i < length; i++ ) { switch (pointer[i]) { case ENV_VAR: if (pointer[1] == TELQUAL_SEND) goto def_case; netoprintf("\" VAR " + noquote); noquote = 2; break; case ENV_VALUE: netoprintf("\" VALUE " + noquote); noquote = 2; break; case ENV_ESC: netoprintf("\" ESC " + noquote); noquote = 2; break; default: def_case: if (isprint(pointer[i]) && pointer[i] != '"') { if (noquote) { netoprintf("\""); noquote = 0; } netoprintf("%c", pointer[i]); } else { netoprintf("\" %03o " + noquote, pointer[i]); noquote = 2; } break; } } if (!noquote) netoprintf("\""); break; } } break;#if defined(AUTHENTICATE) case TELOPT_AUTHENTICATION: netoprintf("AUTHENTICATION"); if (length < 2) { netoprintf(" (empty suboption???)"); break; } switch (pointer[1]) { case TELQUAL_REPLY: case TELQUAL_IS: netoprintf(" %s ", (pointer[1] == TELQUAL_IS) ? "IS" : "REPLY"); if (AUTHTYPE_NAME_OK(pointer[2])) netoprintf("%s ", AUTHTYPE_NAME(pointer[2])); else netoprintf("%d ", pointer[2]); if (length < 3) { netoprintf("(partial suboption???)"); break; } netoprintf("%s|%s", ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER", ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY"); auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); netoprintf("%s", buf); break; case TELQUAL_SEND: i = 2; netoprintf(" SEND "); while (i < length) { if (AUTHTYPE_NAME_OK(pointer[i])) netoprintf("%s ", AUTHTYPE_NAME(pointer[i])); else netoprintf("%d ", pointer[i]); if (++i >= length) { netoprintf("(partial suboption???)"); break; } netoprintf("%s|%s ", ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER", ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY"); ++i; } break; case TELQUAL_NAME: i = 2; netoprintf(" NAME \""); /* * Was: * while (i < length) * *nfrontp += pointer[i++]; * *nfrontp += '"'; * * but I'm pretty sure that's wrong... */ while (i < length) netoprintf("%c", pointer[i++]); netoprintf("\""); break; default: for (i = 2; i < length; i++) { netoprintf(" ?%d?", pointer[i]); } break; } break;#endif#if defined(ENCRYPT) case TELOPT_ENCRYPT: netoprintf("ENCRYPT"); if (length < 2) { netoprintf(" (empty suboption???)"); break; } switch (pointer[1]) { case ENCRYPT_START: netoprintf(" START"); break; case ENCRYPT_END: netoprintf(" END"); break; case ENCRYPT_REQSTART: netoprintf(" REQUEST-START"); break; case ENCRYPT_REQEND: netoprintf(" REQUEST-END"); break; case ENCRYPT_IS: case ENCRYPT_REPLY: netoprintf(" %s ", (pointer[1] == ENCRYPT_IS) ? "IS" : "REPLY"); if (length < 3) { netoprintf(" (partial suboption???)"); break; } if (ENCTYPE_NAME_OK(pointer[2])) netoprintf("%s ", ENCTYPE_NAME(pointer[2])); else netoprintf(" %d (unknown)", pointer[2]); encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); netoprintf("%s", buf); break; case ENCRYPT_SUPPORT: i = 2; netoprintf(" SUPPORT "); while (i < length) { if (ENCTYPE_NAME_OK(pointer[i])) netoprintf("%s ", ENCTYPE_NAME(pointer[i])); else netoprintf("%d ", pointer[i]); i++; } break; case ENCRYPT_ENC_KEYID: netoprintf(" ENC_KEYID", pointer[1]); goto encommon; case ENCRYPT_DEC_KEYID: netoprintf(" DEC_KEYID", pointer[1]); goto encommon; default: netoprintf(" %d (unknown)", pointer[1]); encommon: for (i = 2; i < length; i++) { netoprintf(" %d", pointer[i]); } break; } break;#endif default: if (TELOPT_OK(pointer[0])) netoprintf("%s (unknown)", TELOPT(pointer[0])); else netoprintf("%d (unknown)", pointer[i]); for (i = 1; i < length; i++) { netoprintf(" %d", pointer[i]); } break; } netoprintf("\r\n");}/* * Dump a data buffer in hex and ascii to the output data stream. */voidprintdata(const char *tag, const char *ptr, int cnt){ register int i; char xbuf[30]; while (cnt) { /* flush net output buffer if no room for new data) */ if ((&netobuf[BUFSIZ] - nfrontp) < 80) { netflush(); } /* add a line of output */ netoprintf("%s: ", tag); for (i = 0; i < 20 && cnt; i++) { netoprintf("%02x", *ptr); if (isprint(*ptr)) { xbuf[i] = *ptr; } else { xbuf[i] = '.'; } if (i % 2) { netoprintf(" "); } cnt--; ptr++; } xbuf[i] = '\0'; netoprintf(" %s\r\n", xbuf ); } }#endif /* DIAGNOSTICS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -