mirror of https://gerrit.osmocom.org/libtelnet
minor cleanup, added libtelnet_send_telopt()
This commit is contained in:
parent
5a458548ee
commit
2b4bfc4f79
22
README
22
README
|
@ -110,6 +110,11 @@ IIc. Sending Data
|
||||||
Sends a single "simple" TELNET command, such as the GO-AHEAD
|
Sends a single "simple" TELNET command, such as the GO-AHEAD
|
||||||
commands (255 249).
|
commands (255 249).
|
||||||
|
|
||||||
|
void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd,
|
||||||
|
unsigned char telopt);
|
||||||
|
Sends a TELNET command with an option code following. This is
|
||||||
|
only useful for the WILL, WONT, DO, DONT, and SB commands.
|
||||||
|
|
||||||
void libtelnet_send_negotiate(libtelnet_t *telnet,
|
void libtelnet_send_negotiate(libtelnet_t *telnet,
|
||||||
unsigned char cmd, unsigned char opt);
|
unsigned char cmd, unsigned char opt);
|
||||||
Sends a TELNET negotiation command. The cmd parameter must be
|
Sends a TELNET negotiation command. The cmd parameter must be
|
||||||
|
@ -123,10 +128,23 @@ IIc. Sending Data
|
||||||
a server or the user input from a client.
|
a server or the user input from a client.
|
||||||
|
|
||||||
void libtelnet_send_subnegotiation(libtelnet_t *telnet,
|
void libtelnet_send_subnegotiation(libtelnet_t *telnet,
|
||||||
unsigned char opt, unsigned char *buffer, unsigned int size);
|
unsigned char telopt, unsigned char *buffer, unsigned int size);
|
||||||
Sends a TELNET sub-negotiation command. The opt parameter
|
Sends a TELNET sub-negotiation command. The telopt parameter
|
||||||
is the sub-negotiation option.
|
is the sub-negotiation option.
|
||||||
|
|
||||||
|
Note that the above function is just a shorthand for:
|
||||||
|
libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt);
|
||||||
|
libtelnet_send_data(telnet, buffer, size);
|
||||||
|
libtelnet_send_command(telnet, LIBTELNET_SE);
|
||||||
|
|
||||||
|
For some subnegotiations that involve a lot of complex formatted
|
||||||
|
data to be sent, it may be easier to manually send the SB telopt
|
||||||
|
header and SE footer around mulitple calls to send_data.
|
||||||
|
|
||||||
|
NOTE: libtelnet_send_subrequest() does have special behavior in
|
||||||
|
PROXY mode, as in that mode this function will automatically
|
||||||
|
detect the COMPRESS2 marker and enable zlib compression.
|
||||||
|
|
||||||
IId. Event Handling
|
IId. Event Handling
|
||||||
|
|
||||||
libtelnet relies on an event-handling mechanism for processing
|
libtelnet relies on an event-handling mechanism for processing
|
||||||
|
|
41
libtelnet.c
41
libtelnet.c
|
@ -206,13 +206,6 @@ void _set_rfc1143(libtelnet_t *telnet, libtelnet_rfc1143_t q) {
|
||||||
telnet->q[telnet->q_size++] = q;
|
telnet->q[telnet->q_size++] = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send a negotiation without going through the RFC1143 checks */
|
|
||||||
static void _send_negotiate(libtelnet_t *telnet, unsigned char cmd,
|
|
||||||
unsigned char opt) {
|
|
||||||
unsigned char bytes[3] = { LIBTELNET_IAC, cmd, opt };
|
|
||||||
_send(telnet, bytes, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* negotiation handling magic for RFC1143 */
|
/* negotiation handling magic for RFC1143 */
|
||||||
static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
unsigned char telopt) {
|
unsigned char telopt) {
|
||||||
|
@ -249,9 +242,9 @@ static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
if (_event(telnet, LIBTELNET_EV_WILL, cmd, telopt, 0, 0) == 1) {
|
if (_event(telnet, LIBTELNET_EV_WILL, cmd, telopt, 0, 0) == 1) {
|
||||||
q.him = RFC1143_YES;
|
q.him = RFC1143_YES;
|
||||||
_set_rfc1143(telnet, q);
|
_set_rfc1143(telnet, q);
|
||||||
_send_negotiate(telnet, LIBTELNET_DO, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_DO, telopt);
|
||||||
} else
|
} else
|
||||||
_send_negotiate(telnet, LIBTELNET_DONT, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_DONT, telopt);
|
||||||
break;
|
break;
|
||||||
case RFC1143_YES:
|
case RFC1143_YES:
|
||||||
break;
|
break;
|
||||||
|
@ -274,7 +267,7 @@ static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
case RFC1143_WANTYES_OP:
|
case RFC1143_WANTYES_OP:
|
||||||
q.him = RFC1143_WANTNO;
|
q.him = RFC1143_WANTNO;
|
||||||
_set_rfc1143(telnet, q);
|
_set_rfc1143(telnet, q);
|
||||||
_send_negotiate(telnet, LIBTELNET_DONT, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_DONT, telopt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -287,7 +280,7 @@ static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
case RFC1143_YES:
|
case RFC1143_YES:
|
||||||
q.him = RFC1143_NO;
|
q.him = RFC1143_NO;
|
||||||
_set_rfc1143(telnet, q);
|
_set_rfc1143(telnet, q);
|
||||||
_send_negotiate(telnet, LIBTELNET_DONT, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_DONT, telopt);
|
||||||
_event(telnet, LIBTELNET_EV_WONT, 0, telopt,
|
_event(telnet, LIBTELNET_EV_WONT, 0, telopt,
|
||||||
0, 0);
|
0, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -318,9 +311,9 @@ static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
if (_event(telnet, LIBTELNET_EV_DO, cmd, telopt, 0, 0) == 1) {
|
if (_event(telnet, LIBTELNET_EV_DO, cmd, telopt, 0, 0) == 1) {
|
||||||
q.us = RFC1143_YES;
|
q.us = RFC1143_YES;
|
||||||
_set_rfc1143(telnet, q);
|
_set_rfc1143(telnet, q);
|
||||||
_send_negotiate(telnet, LIBTELNET_WILL, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_WILL, telopt);
|
||||||
} else
|
} else
|
||||||
_send_negotiate(telnet, LIBTELNET_WONT, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_WONT, telopt);
|
||||||
break;
|
break;
|
||||||
case RFC1143_YES:
|
case RFC1143_YES:
|
||||||
break;
|
break;
|
||||||
|
@ -343,7 +336,7 @@ static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
case RFC1143_WANTYES_OP:
|
case RFC1143_WANTYES_OP:
|
||||||
q.us = RFC1143_WANTNO;
|
q.us = RFC1143_WANTNO;
|
||||||
_set_rfc1143(telnet, q);
|
_set_rfc1143(telnet, q);
|
||||||
_send_negotiate(telnet, LIBTELNET_WONT, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_WONT, telopt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -356,7 +349,7 @@ static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
case RFC1143_YES:
|
case RFC1143_YES:
|
||||||
q.us = RFC1143_NO;
|
q.us = RFC1143_NO;
|
||||||
_set_rfc1143(telnet, q);
|
_set_rfc1143(telnet, q);
|
||||||
_send_negotiate(telnet, LIBTELNET_WONT, telopt);
|
libtelnet_send_telopt(telnet, LIBTELNET_WONT, telopt);
|
||||||
_event(telnet, LIBTELNET_EV_DONT, 0, telopt, 0, 0);
|
_event(telnet, LIBTELNET_EV_DONT, 0, telopt, 0, 0);
|
||||||
break;
|
break;
|
||||||
case RFC1143_WANTNO:
|
case RFC1143_WANTNO:
|
||||||
|
@ -673,6 +666,13 @@ void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd) {
|
||||||
_send(telnet, bytes, 2);
|
_send(telnet, bytes, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send an iac command with telopt */
|
||||||
|
void libtelnet_send_telopt(libtelnet_t *telnet, unsigned char cmd,
|
||||||
|
unsigned char telopt) {
|
||||||
|
unsigned char bytes[3] = { LIBTELNET_IAC, cmd, telopt };
|
||||||
|
_send(telnet, bytes, 3);
|
||||||
|
}
|
||||||
|
|
||||||
/* send negotiation */
|
/* send negotiation */
|
||||||
void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
|
void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
unsigned char telopt) {
|
unsigned char telopt) {
|
||||||
|
@ -814,10 +814,9 @@ void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send sub-request */
|
/* send sub-request */
|
||||||
void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char opt,
|
void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char telopt,
|
||||||
unsigned char *buffer, unsigned int size) {
|
unsigned char *buffer, unsigned int size) {
|
||||||
libtelnet_send_command(telnet, LIBTELNET_SB);
|
libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt);
|
||||||
libtelnet_send_data(telnet, &opt, 1);
|
|
||||||
libtelnet_send_data(telnet, buffer, size);
|
libtelnet_send_data(telnet, buffer, size);
|
||||||
libtelnet_send_command(telnet, LIBTELNET_SE);
|
libtelnet_send_command(telnet, LIBTELNET_SE);
|
||||||
|
|
||||||
|
@ -826,8 +825,7 @@ void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char opt,
|
||||||
* make sure all further data is compressed if not already.
|
* make sure all further data is compressed if not already.
|
||||||
*/
|
*/
|
||||||
if (telnet->flags & LIBTELNET_FLAG_PROXY &&
|
if (telnet->flags & LIBTELNET_FLAG_PROXY &&
|
||||||
telnet->z == 0 &&
|
telopt == LIBTELNET_TELOPT_COMPRESS2) {
|
||||||
opt == LIBTELNET_TELOPT_COMPRESS2) {
|
|
||||||
|
|
||||||
if (_init_zlib(telnet, 1, 1) != LIBTELNET_EOK)
|
if (_init_zlib(telnet, 1, 1) != LIBTELNET_EOK)
|
||||||
return;
|
return;
|
||||||
|
@ -852,5 +850,8 @@ void libtelnet_begin_compress2(libtelnet_t *telnet) {
|
||||||
* the compress marker itself being compressed.
|
* the compress marker itself being compressed.
|
||||||
*/
|
*/
|
||||||
_event(telnet, LIBTELNET_EV_SEND, 0, 0, compress2, sizeof(compress2));
|
_event(telnet, LIBTELNET_EV_SEND, 0, 0, compress2, sizeof(compress2));
|
||||||
|
|
||||||
|
/* notify app that compression was successfully enabled */
|
||||||
|
_event(telnet, LIBTELNET_EV_COMPRESS, 1, 0, 0, 0);
|
||||||
#endif /* HAVE_ZLIB */
|
#endif /* HAVE_ZLIB */
|
||||||
}
|
}
|
||||||
|
|
19
libtelnet.h
19
libtelnet.h
|
@ -200,7 +200,14 @@ extern void libtelnet_push(libtelnet_t *telnet, unsigned char *buffer,
|
||||||
/* send an iac command */
|
/* send an iac command */
|
||||||
extern void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd);
|
extern void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd);
|
||||||
|
|
||||||
/* send negotiation */
|
/* send an iac command with a telopt */
|
||||||
|
extern void libtelnet_send_telopt(libtelnet_t *telnet, unsigned char cmd,
|
||||||
|
unsigned char telopt);
|
||||||
|
|
||||||
|
/* send negotiation, with RFC1143 checking.
|
||||||
|
* will not actually send unless necessary, but will update internal
|
||||||
|
* negotiation queue.
|
||||||
|
*/
|
||||||
extern void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
|
extern void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
unsigned char opt);
|
unsigned char opt);
|
||||||
|
|
||||||
|
@ -208,9 +215,15 @@ extern void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
|
||||||
extern void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
|
extern void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
|
||||||
unsigned int size);
|
unsigned int size);
|
||||||
|
|
||||||
/* send sub-request */
|
/* send sub-request, equivalent to:
|
||||||
|
* libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt)
|
||||||
|
* libtelnet_send_data(telnet, buffer, size);
|
||||||
|
* libtelnet_send_command(telnet, LIBTELNET_SE);
|
||||||
|
* manually generating sequence may be easier for complex subnegotiations
|
||||||
|
* thare are most easily implemented with a series of send_data calls.
|
||||||
|
*/
|
||||||
extern void libtelnet_send_subnegotiation(libtelnet_t *telnet,
|
extern void libtelnet_send_subnegotiation(libtelnet_t *telnet,
|
||||||
unsigned char opt, unsigned char *buffer, unsigned int size);
|
unsigned char telopt, unsigned char *buffer, unsigned int size);
|
||||||
|
|
||||||
/* begin sending compressed data (server only) */
|
/* begin sending compressed data (server only) */
|
||||||
extern void libtelnet_begin_compress2(libtelnet_t *telnet);
|
extern void libtelnet_begin_compress2(libtelnet_t *telnet);
|
||||||
|
|
Loading…
Reference in New Issue