mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-25 23:10:32 +00:00
Negotiations
This commit is contained in:
parent
f4ed63ce70
commit
81edb50c8e
1 changed files with 84 additions and 15 deletions
|
@ -47,6 +47,36 @@ U0 GetColorString(I64 color_code, U8 *buf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U0 SendWindowSize(I64 sock, U16 rows, U16 cols) {
|
||||||
|
U8 buf[9];
|
||||||
|
|
||||||
|
buf[0] = 0xFF; // IAC
|
||||||
|
buf[1] = 0xFA; // SB
|
||||||
|
buf[2] = 0x1F; // NAWS (Negotiate About Window Size)
|
||||||
|
buf[3] = cols >> 8; // High byte of columns
|
||||||
|
buf[4] = cols & 0xFF; // Low byte of columns
|
||||||
|
buf[5] = rows >> 8; // High byte of rows
|
||||||
|
buf[6] = rows & 0xFF; // Low byte of rows
|
||||||
|
buf[7] = 0xFF; // IAC
|
||||||
|
buf[8] = 0xF0; // SE
|
||||||
|
|
||||||
|
TCPSocketSend(sock, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
U0 SendTerminalType(I64 sock, U8 *term_type) {
|
||||||
|
U8 buf[6 + StrLen(term_type)];
|
||||||
|
|
||||||
|
buf[0] = 0xFF; // IAC
|
||||||
|
buf[1] = 0xFA; // SB
|
||||||
|
buf[2] = 0x18; // Terminal Type
|
||||||
|
buf[3] = 0x00; // IS
|
||||||
|
StrCopy(buf + 4, term_type);
|
||||||
|
buf[4 + StrLen(term_type)] = 0xFF; // IAC
|
||||||
|
buf[5 + StrLen(term_type)] = 0xF0; // SE
|
||||||
|
|
||||||
|
TCPSocketSend(sock, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
U0 TelnetClient(U8 *host, U16 port) {
|
U0 TelnetClient(U8 *host, U16 port) {
|
||||||
I64 sock, bytes_received, input_len;
|
I64 sock, bytes_received, input_len;
|
||||||
U8 buffer[BUF_SIZE], input_buffer[BUF_SIZE], *ptr, ch;
|
U8 buffer[BUF_SIZE], input_buffer[BUF_SIZE], *ptr, ch;
|
||||||
|
@ -57,6 +87,8 @@ U0 TelnetClient(U8 *host, U16 port) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SendWindowSize(sock, 24, 80); // Send default window size of 24 rows and 80 columns
|
||||||
|
|
||||||
"Connected to %s:%d.\n", host, port;
|
"Connected to %s:%d.\n", host, port;
|
||||||
|
|
||||||
force_disconnect = FALSE;
|
force_disconnect = FALSE;
|
||||||
|
@ -68,8 +100,28 @@ U0 TelnetClient(U8 *host, U16 port) {
|
||||||
// Basic Telnet protocol parser: Ignore negotiation sequences
|
// Basic Telnet protocol parser: Ignore negotiation sequences
|
||||||
ptr = buffer;
|
ptr = buffer;
|
||||||
while (*ptr) {
|
while (*ptr) {
|
||||||
if (*ptr == 0xFF) {
|
if (*ptr == 0xFF) { // Telnet negotiation sequence
|
||||||
// Skip Telnet negotiation sequence (3 bytes)
|
U8 negotiation_code = *(ptr + 1);
|
||||||
|
U8 option_code = *(ptr + 2);
|
||||||
|
|
||||||
|
// Send a response to the server
|
||||||
|
U8 response[3];
|
||||||
|
response[0] = 0xFF; // IAC
|
||||||
|
|
||||||
|
// Check if the negotiation code is DO or DONT
|
||||||
|
if (negotiation_code == 0xFD && option_code == 0x18) {
|
||||||
|
response[1] = 0xFB; // WILL
|
||||||
|
TCPSocketSend(sock, response, 3);
|
||||||
|
SendTerminalType(sock, "ANSI");
|
||||||
|
} else if (negotiation_code == 0xFD || negotiation_code == 0xFE) {
|
||||||
|
response[1] = 0xFC; // WONT
|
||||||
|
} else { // Else, assume the negotiation code is WILL or WONT
|
||||||
|
response[1] = 0xFE; // DONT
|
||||||
|
}
|
||||||
|
|
||||||
|
response[2] = option_code;
|
||||||
|
|
||||||
|
TCPSocketSend(sock, response, 3);
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
} else if (*ptr == 0x1B) {
|
} else if (*ptr == 0x1B) {
|
||||||
// ANSI escape sequence
|
// ANSI escape sequence
|
||||||
|
@ -86,9 +138,14 @@ U0 TelnetClient(U8 *host, U16 port) {
|
||||||
// Process ansi_code
|
// Process ansi_code
|
||||||
if (*ptr == ';') {
|
if (*ptr == ';') {
|
||||||
ptr++; // Move to next part of the sequence
|
ptr++; // Move to next part of the sequence
|
||||||
} else if (*ptr == 'm') {
|
} else if (*ptr == 'm' || *ptr == 'H' || *ptr == 'J' || *ptr == 'K' || *ptr == 'C') {
|
||||||
ptr++; // Move past 'm'
|
ptr++; // Move past the current character
|
||||||
break; // End of the escape sequence
|
break; // End of the escape sequence
|
||||||
|
} else if (*ptr == '?') {
|
||||||
|
ptr++; // Skip the '?'
|
||||||
|
} else if (*ptr == 'h' || *ptr == 'l') {
|
||||||
|
ptr++; // Skip 'h' or 'l'
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
break; // Invalid character, exit loop
|
break; // Invalid character, exit loop
|
||||||
}
|
}
|
||||||
|
@ -102,31 +159,40 @@ U0 TelnetClient(U8 *host, U16 port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
"\n";
|
"\n";
|
||||||
Sleep(200); // Add a 200 ms delay
|
Sleep(500); // Add a 200 ms delay
|
||||||
// Prompt user for input and send it to the remote host
|
// Prompt user for input and send it to the remote host
|
||||||
"Enter your choice: ";
|
"Enter your choice: ";
|
||||||
|
|
||||||
input_len = 0;
|
U8 *line = input_buffer;
|
||||||
while (1) {
|
while (1) {
|
||||||
ch = CharGet;
|
ch = CharGet(, FALSE);
|
||||||
if (ch == '\r' || ch == '\n') {
|
if (ch == '\r' || ch == '\n') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ch == 27) { // ESC key
|
if (ch == CH_ESC || ch == CH_SHIFT_ESC) { // ESC key
|
||||||
force_disconnect = TRUE;
|
force_disconnect = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
input_buffer[input_len++] = ch;
|
if (ch == CH_BACKSPACE || ch == 127) { // Backspace or Delete key
|
||||||
|
if (line != input_buffer) {
|
||||||
|
line--; // Move the pointer back
|
||||||
|
"%c%c%c", 8, ' ', 8; // Move the cursor back, erase the character, and move the cursor back again
|
||||||
}
|
}
|
||||||
input_buffer[input_len] = '\0';
|
} else {
|
||||||
|
*line++ = ch;
|
||||||
|
"%c", ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*line++ = '\r';
|
||||||
|
*line++ = '\n';
|
||||||
|
*line = '\0';
|
||||||
|
|
||||||
if (!force_disconnect) {
|
if (!force_disconnect) {
|
||||||
SysLog("Sending: %s\n", input_buffer); // Debugging line
|
SysLog("Sending: %s\n", input_buffer); // Debugging line
|
||||||
input_buffer[input_len++] = '\r';
|
TCPSocketSendString(sock, input_buffer);
|
||||||
input_buffer[input_len++] = '\n';
|
|
||||||
TCPSocketSend(sock, input_buffer, input_len);
|
|
||||||
} else {
|
} else {
|
||||||
"Force disconnecting...\n";
|
"Force disconnecting...\n";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
"Error: Connection closed by the remote host.\n";
|
"Error: Connection closed by the remote host.\n";
|
||||||
|
@ -152,3 +218,6 @@ U0 TelnetPrompt() {
|
||||||
TelnetClient(form.host, form.port);
|
TelnetClient(form.host, form.port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dev auto-connect to test server
|
||||||
|
TelnetClient("mbrserver.com", 23);
|
Loading…
Reference in a new issue