00001
00002
00003 extern "C" {
00004 #include <string.h>
00005 }
00006
00007 #include <iostream>
00008
00009 #include "telnet.h"
00010
00011 #define IAC 0xFF
00012 #define DONT 0xFE
00013 #define DO 0xFD
00014 #define WONT 0xFC
00015 #define WILL 0xFB
00016
00017
00018
00019
00020 static unsigned char *
00021 find_byte(unsigned char *buf, unsigned int len, unsigned char ch)
00022 {
00023 for (unsigned char *p = buf ; p < (buf + len) ; p++)
00024 if (*p == ch)
00025 return p;
00026
00027 return(NULL);
00028 }
00029
00030 using std::clog;
00031 using std::endl;
00032
00033 Blob *
00034 Telnet::decode(Blob *b)
00035 {
00036 b->inc_ref();
00037
00038 Blob *b2;
00039 size_t newlen = 0;
00040 size_t len = b->len();
00041 unsigned char *c, *dp = b->data();
00042 unsigned char *data = new unsigned char[len];
00043
00044 clog << "In Telnet::decode(" << b << ")" << endl;
00045
00046 while ((c = find_byte(dp, len, IAC))) {
00047
00048 if (c != dp) {
00049 memmove(data+newlen, dp, (c - dp));
00050 newlen += (c - dp);
00051 }
00052
00053 switch (c[1]) {
00054
00055 case DO:
00056 clog << "IAC DO " << short(c[2]) << endl;
00057 dp += 3; len -= 3;
00058 break;
00059 case DONT:
00060 clog << "IAC DONT " << short(c[2]) << endl;
00061 dp += 3; len -= 3;
00062 break;
00063 case WILL:
00064 clog << "IAC WILL " << short(c[2]) << endl;
00065 dp += 3; len -= 3;
00066 break;
00067 case WONT:
00068 clog << "IAC WONT " << short(c[2]) << endl;
00069 dp += 3; len -= 3;
00070 break;
00071 default:
00072 clog.setf(std::ios::hex, std::ios::dec|std::ios::hex|std::ios::oct);
00073 clog << "Found unknown IAC: code " << int(c[1]) << endl;
00074 dp += 2; len -= 2;
00075 break;
00076 }
00077 }
00078
00079
00080 if (len > 0) {
00081 memmove(data+newlen, dp, len);
00082 newlen += len;
00083 }
00084
00085
00086
00087 b->dec_ref();
00088 b2 = new Blob(data, newlen);
00089 delete [] data;
00090
00091 return(b2);
00092 }
00093
00094 Blob *
00095 Telnet::encode(Blob *b)
00096 {
00097
00098
00099 return (b);
00100 }