1 /* 2 * TLVs (Type, Length, Value) 3 * 4 * Copyright (C) 2001 Barnaby Gray <barnaby@beedesign.co.uk> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22 #ifndef TLV_H 23 #define TLV_H 24 25 #include <string> 26 #include <map> 27 28 #include <string.h> 29 #include <stdlib.h> 30 31 #include "Xml.h" 32 #include "exceptions.h" 33 #include "buffer.h" 34 #include "constants.h" 35 #include "ICQ.h" 36 #include "Capabilities.h" 37 38 namespace ICQ2000 { 39 40 // ------------- TLV numerical constants ------------ 41 42 /* 43 * TLV types 44 * Originally I thought TLV types were distinct within 45 * each channel, but in Messages it turns out they are only 46 * distinct within each block. To complicate matters you 47 * then get TLVs inside TLVs.. 48 * Solution: the TLV parser must be told what it is expecting 49 * to parse so that the correct TLV types are associated 50 */ 51 52 enum TLV_ParseMode { TLV_ParseMode_Channel01, 53 TLV_ParseMode_Channel02, 54 TLV_ParseMode_Channel04, 55 TLV_ParseMode_MessageBlock, 56 TLV_ParseMode_AdvMsgBlock, 57 TLV_ParseMode_InMessageData, 58 TLV_ParseMode_InAdvMsgData, 59 TLV_ParseMode_SBL, 60 TLV_ParseMode_SBL_Rights 61 }; 62 63 // Channel 0x0001 64 const unsigned short TLV_Screenname = 0x0001; 65 const unsigned short TLV_Password = 0x0002; 66 const unsigned short TLV_ClientProfile = 0x0003; 67 const unsigned short TLV_UserInfo = 0x0005; 68 const unsigned short TLV_Cookie = 0x0006; 69 const unsigned short TLV_CountryCode = 0x000e; 70 const unsigned short TLV_Language = 0x000f; 71 const unsigned short TLV_ClientBuildMinor = 0x0014; 72 const unsigned short TLV_ClientType = 0x0016; 73 const unsigned short TLV_ClientVersionMajor = 0x0017; 74 const unsigned short TLV_ClientVersionMinor = 0x0018; 75 const unsigned short TLV_ClientICQNumber = 0x0019; 76 const unsigned short TLV_ClientBuildMajor = 0x001a; 77 const unsigned short TLV_Type94 = 0x0094; 78 79 // Channel 0x0002 80 const unsigned short TLV_UserClass = 0x0001; 81 const unsigned short TLV_SignupDate = 0x0002; 82 const unsigned short TLV_SignonDate = 0x0003; 83 const unsigned short TLV_Port = 0x0004; // ?? 84 const unsigned short TLV_UserInfoCapabilities = 0x0005; 85 const unsigned short TLV_Status = 0x0006; 86 const unsigned short TLV_Unknown = 0x0008; // ?? 87 const unsigned short TLV_IPAddress = 0x000a; 88 const unsigned short TLV_WebAddress = 0x000b; 89 const unsigned short TLV_LANDetails = 0x000c; 90 const unsigned short TLV_Capabilities = 0x000d; 91 const unsigned short TLV_TimeOnline = 0x000f; 92 const unsigned short TLV_ContactNickname = 0x0131; 93 const unsigned short TLV_AuthAwaited = 0x0066; 94 95 // Channel 0x0004 96 // const unsigned short TLV_Screenname = 0x0001; 97 const unsigned short TLV_ErrorURL = 0x0004; 98 const unsigned short TLV_Redirect = 0x0005; 99 // const unsigned short TLV_Cookie = 0x0006; 100 const unsigned short TLV_ErrorCode = 0x0008; 101 const unsigned short TLV_DisconnectReason = 0x0009; 102 const unsigned short TLV_DisconnectMessage = 0x000b; 103 const unsigned short TLV_Unknown3 = 0x000c; 104 const unsigned short TLV_EmailAddress = 0x0011; 105 const unsigned short TLV_RegStatus = 0x0013; 106 107 // Message Block 108 const unsigned short TLV_MessageData = 0x0002; 109 const unsigned short TLV_ServerAckRequested = 0x0003; 110 const unsigned short TLV_MessageIsAutoResponse = 0x0004; 111 const unsigned short TLV_ICQData = 0x0005; 112 113 // Advanced Message Block 114 const unsigned short TLV_AdvMsgData = 0x0005; 115 116 // In Message Data 117 const unsigned short TLV_Unknown0501 = 0x0501; 118 const unsigned short TLV_MessageText = 0x0101; 119 120 // In Advanced Message Data 121 const unsigned short TLV_AdvMsgBody = 0x2711; 122 // loads more - but we don't parse them yet 123 124 // In Server-based list data 125 const unsigned short TLV_SBL_Await_Auth = 0x0066; 126 const unsigned short TLV_SBL_Ids = 0x00c8; 127 const unsigned short TLV_SBL_Visibility = 0x00ca; 128 const unsigned short TLV_SBL_ICQTIC = 0x00cd; 129 const unsigned short TLV_SBL_ImportTime = 0x00d4; 130 const unsigned short TLV_SBL_Nick = 0x0131; 131 const unsigned short TLV_SBL_SMS_No = 0x013a; 132 133 // ------------- abstract TLV classes --------------- 134 135 class TLV { 136 public: ~TLV()137 virtual ~TLV() { } 138 139 virtual unsigned short Type() const = 0; 140 virtual unsigned short Length() const = 0; 141 }; 142 143 // -- Inbound TLV -- 144 class InTLV : public TLV { 145 public: 146 virtual void ParseValue(Buffer& b) = 0; 147 148 static InTLV* ParseTLV(Buffer& b, TLV_ParseMode pm); 149 }; 150 151 // -- Outbound TLV -- 152 class OutTLV : public TLV { 153 protected: 154 virtual void OutputHeader(Buffer& b) const; 155 virtual void OutputValue(Buffer& b) const = 0; 156 157 public: 158 virtual void Output(Buffer& b) const; 159 }; 160 161 // -------------- base classes ---------------------- 162 163 class CharTLV : public OutTLV, public InTLV { 164 protected: 165 unsigned char m_value; 166 167 virtual void OutputValue(Buffer& b) const; 168 169 public: 170 CharTLV(); 171 CharTLV(unsigned char n); 172 Length()173 unsigned short Length() const { return 1; } 174 175 virtual void ParseValue(Buffer& b); Value()176 virtual unsigned char Value() const { return m_value; } 177 }; 178 179 class ShortTLV : public OutTLV, public InTLV { 180 protected: 181 unsigned short m_value; 182 183 virtual void OutputValue(Buffer& b) const; 184 185 public: 186 ShortTLV(); 187 ShortTLV(unsigned short n); 188 Length()189 unsigned short Length() const { return 2; } 190 191 virtual void ParseValue(Buffer& b); Value()192 virtual unsigned short Value() const { return m_value; } 193 }; 194 195 196 class LongTLV : public OutTLV, public InTLV { 197 protected: 198 unsigned int m_value; 199 200 virtual void OutputValue(Buffer& b) const; 201 202 public: 203 LongTLV(); 204 LongTLV(unsigned int n); 205 Length()206 unsigned short Length() const { return 4; } 207 208 virtual void ParseValue(Buffer& b); Value()209 virtual unsigned int Value() const { return m_value; } 210 }; 211 212 213 class StringTLV : public OutTLV, public InTLV { 214 protected: 215 std::string m_value; 216 217 virtual void OutputValue(Buffer& b) const; 218 219 public: 220 StringTLV(); 221 StringTLV(const std::string& val); 222 Length()223 unsigned short Length() const { return m_value.size(); } 224 225 virtual void ParseValue(Buffer& b); Value()226 virtual std::string Value() const { return m_value; } 227 }; 228 229 230 // --------------- actual classes ------------------- 231 232 class ErrorURLTLV : public StringTLV { 233 public: ErrorURLTLV()234 ErrorURLTLV() { } Type()235 unsigned short Type() const { return TLV_ErrorURL; } 236 }; 237 238 class ErrorCodeTLV : public ShortTLV { 239 public: ErrorCodeTLV()240 ErrorCodeTLV() { } Type()241 unsigned short Type() const { return TLV_ErrorCode; } 242 }; 243 244 class DisconnectReasonTLV : public ShortTLV { 245 public: DisconnectReasonTLV()246 DisconnectReasonTLV() { } Type()247 unsigned short Type() const { return TLV_DisconnectReason; } 248 }; 249 250 class DisconnectMessageTLV : public StringTLV { 251 public: DisconnectMessageTLV()252 DisconnectMessageTLV() { } Type()253 unsigned short Type() const { return TLV_DisconnectMessage; } 254 }; 255 256 class ScreenNameTLV : public StringTLV { 257 public: 258 ScreenNameTLV(); 259 ScreenNameTLV(const std::string& val); 260 Type()261 unsigned short Type() const { return TLV_Screenname; } 262 }; 263 264 class PasswordTLV : public OutTLV { 265 protected: 266 std::string m_password; 267 268 void OutputValue(Buffer& b) const; 269 270 public: 271 PasswordTLV(const std::string& pw); 272 Type()273 unsigned short Type() const { return TLV_Password; } Length()274 unsigned short Length() const { return m_password.size(); } 275 }; 276 277 const unsigned char ALLOWDIRECT_EVERYONE = 0x00; 278 const unsigned char ALLOWDIRECT_AUTHORIZATION = 0x10; 279 const unsigned char ALLOWDIRECT_CONTACTLIST = 0x20; 280 281 const unsigned char WEBAWARE_NORMAL = 0x02; 282 const unsigned char WEBAWARE_WEBAWARE = 0x03; 283 284 class StatusTLV : public OutTLV, public InTLV { 285 private: 286 unsigned char m_allowDirect; 287 unsigned char m_webAware; 288 unsigned short m_status; 289 290 protected: 291 void OutputValue(Buffer& b) const; 292 void ParseValue(Buffer& b); 293 294 public: StatusTLV(unsigned char ad,unsigned char wa,unsigned short st)295 StatusTLV(unsigned char ad, unsigned char wa, unsigned short st) 296 : m_allowDirect(ad), m_webAware(wa), m_status(st) 297 { } StatusTLV()298 StatusTLV() { } 299 Type()300 unsigned short Type() const { return TLV_Status; } Length()301 unsigned short Length() const { return 4; } 302 getAllowDirect()303 unsigned char getAllowDirect() { return m_allowDirect; } getWebAware()304 unsigned char getWebAware() { return m_webAware; } getStatus()305 unsigned short getStatus() { return m_status; } getBirthday()306 bool getBirthday() { return ((m_webAware & 0x08) == 0x08); } 307 setAllowDirect(unsigned char m)308 void setAllowDirect(unsigned char m) { m_allowDirect = m; } setWebAware(unsigned char m)309 void setWebAware(unsigned char m) { m_webAware = m; } setStatus(unsigned short m)310 void setStatus(unsigned short m) { m_status = m; } 311 }; 312 313 // -- Client*TLVs -- 314 315 class ClientProfileTLV : public StringTLV { 316 public: ClientProfileTLV(const std::string & val)317 ClientProfileTLV(const std::string& val) : StringTLV(val) { } Type()318 unsigned short Type() const { return TLV_ClientProfile; } 319 }; 320 321 class ClientTypeTLV : public ShortTLV { 322 public: ClientTypeTLV(unsigned short n)323 ClientTypeTLV(unsigned short n) : ShortTLV(n) { } Type()324 unsigned short Type() const { return TLV_ClientType; } 325 }; 326 327 class ClientVersionMajorTLV : public ShortTLV { 328 public: ClientVersionMajorTLV(unsigned short n)329 ClientVersionMajorTLV(unsigned short n) : ShortTLV(n) { } Type()330 unsigned short Type() const { return TLV_ClientVersionMajor; } 331 }; 332 333 class ClientVersionMinorTLV : public ShortTLV { 334 public: ClientVersionMinorTLV(unsigned short n)335 ClientVersionMinorTLV(unsigned short n) : ShortTLV(n) { } Type()336 unsigned short Type() const { return TLV_ClientVersionMinor; } 337 }; 338 339 class ClientICQNumberTLV : public ShortTLV { 340 public: ClientICQNumberTLV(unsigned short n)341 ClientICQNumberTLV(unsigned short n) : ShortTLV(n) { } Type()342 unsigned short Type() const { return TLV_ClientICQNumber; } 343 }; 344 345 class ClientBuildMajorTLV : public ShortTLV { 346 public: ClientBuildMajorTLV(unsigned short n)347 ClientBuildMajorTLV(unsigned short n) : ShortTLV(n) { } Type()348 unsigned short Type() const { return TLV_ClientBuildMajor; } 349 }; 350 351 class ClientBuildMinorTLV : public LongTLV { 352 public: ClientBuildMinorTLV(unsigned int n)353 ClientBuildMinorTLV(unsigned int n) : LongTLV(n) { } Type()354 unsigned short Type() const { return TLV_ClientBuildMinor; } 355 }; 356 357 class CountryCodeTLV : public StringTLV { 358 public: CountryCodeTLV(std::string val)359 CountryCodeTLV(std::string val) : StringTLV(val) { } Type()360 unsigned short Type() const { return TLV_CountryCode; } 361 }; 362 363 class LanguageTLV : public StringTLV { 364 public: LanguageTLV(const std::string & val)365 LanguageTLV(const std::string& val) : StringTLV(val) { } Type()366 unsigned short Type() const { return TLV_Language; } 367 }; 368 369 class Type94TLV : public CharTLV 370 { 371 public: Type94TLV(unsigned char n)372 Type94TLV(unsigned char n) : CharTLV(n) { } Type()373 unsigned short Type() const { return TLV_Type94; } 374 }; 375 376 // -- 377 378 class WebAddressTLV : public StringTLV { 379 public: WebAddressTLV()380 WebAddressTLV() { } Type()381 unsigned short Type() const { return TLV_WebAddress; } 382 }; 383 384 class UserClassTLV : public ShortTLV { 385 public: UserClassTLV()386 UserClassTLV() { } Type()387 unsigned short Type() const { return TLV_UserClass; } 388 }; 389 390 class TimeOnlineTLV : public LongTLV { 391 public: TimeOnlineTLV()392 TimeOnlineTLV() { } Type()393 unsigned short Type() const { return TLV_TimeOnline; } 394 }; 395 396 class SignupDateTLV : public LongTLV { 397 public: SignupDateTLV()398 SignupDateTLV() { } Type()399 unsigned short Type() const { return TLV_SignupDate; } 400 }; 401 402 class SignonDateTLV : public LongTLV { 403 public: SignonDateTLV()404 SignonDateTLV() { } Type()405 unsigned short Type() const { return TLV_SignonDate; } 406 }; 407 408 class UnknownTLV : public ShortTLV { 409 public: UnknownTLV()410 UnknownTLV() : ShortTLV(0) { } Type()411 unsigned short Type() const { return TLV_Unknown; } 412 }; 413 414 class IPAddressTLV : public LongTLV { 415 public: IPAddressTLV()416 IPAddressTLV() { } Type()417 unsigned short Type() const { return TLV_IPAddress; } 418 }; 419 420 class PortTLV : public ShortTLV { 421 public: PortTLV()422 PortTLV() { } Type()423 unsigned short Type() const { return TLV_Port; } 424 }; 425 426 class UserInfoCapabilitiesTLV : public OutTLV { 427 private: 428 Capabilities m_capabilities; 429 430 public: 431 UserInfoCapabilitiesTLV(); Type()432 unsigned short Type() const { return TLV_UserInfoCapabilities; } 433 unsigned short Length() const; 434 435 void OutputValue(Buffer& b) const; 436 }; 437 438 class CapabilitiesTLV : public InTLV { 439 private: 440 Capabilities m_capabilities; 441 442 public: CapabilitiesTLV()443 CapabilitiesTLV() { } Type()444 unsigned short Type() const { return TLV_Capabilities; } Length()445 unsigned short Length() const { return m_capabilities.get_length(); } 446 447 Capabilities get_capabilities() const; 448 449 void ParseValue(Buffer& b); 450 }; 451 452 class RedirectTLV : public InTLV { 453 private: 454 std::string m_server; 455 unsigned short m_port; 456 457 public: RedirectTLV()458 RedirectTLV() { } 459 Length()460 unsigned short Length() const { return m_server.size(); } Type()461 unsigned short Type() const { return TLV_Redirect; } 462 463 void ParseValue(Buffer& b); 464 getHost()465 std::string getHost() { return m_server; } getPort()466 unsigned short getPort() { return m_port; } 467 }; 468 469 class CookieTLV : public InTLV, public OutTLV { 470 private: 471 unsigned char *m_value; 472 unsigned short m_length; 473 474 public: CookieTLV()475 CookieTLV() : m_value(NULL), m_length(0) { } 476 CookieTLV(const unsigned char *ck, unsigned short len); 477 ~CookieTLV(); 478 Length()479 unsigned short Length() const { return m_length; } Type()480 unsigned short Type() const { return TLV_Cookie; } 481 482 void ParseValue(Buffer& b); 483 void OutputValue(Buffer& b) const; 484 Value()485 const unsigned char* Value() { return m_value; } 486 }; 487 488 // can go out as well 489 class LANDetailsTLV : public InTLV, public OutTLV { 490 private: 491 unsigned int m_lan_ip; 492 unsigned short m_lan_port, m_firewall; 493 unsigned char m_tcp_version; 494 unsigned int m_dc_cookie; 495 496 public: 497 LANDetailsTLV(); 498 LANDetailsTLV(unsigned int ip, unsigned short port); 499 Length()500 unsigned short Length() const { return 0; } // varies Type()501 unsigned short Type() const { return TLV_LANDetails; } 502 getLanIP()503 unsigned int getLanIP() const { return m_lan_ip; } getLanPort()504 unsigned short getLanPort() const { return m_lan_port; } getFirewall()505 unsigned short getFirewall() const { return m_firewall; } getTCPVersion()506 unsigned char getTCPVersion() const { return m_tcp_version; } getDCCookie()507 unsigned int getDCCookie() const { return m_dc_cookie; } 508 509 void ParseValue(Buffer& b); 510 void OutputValue(Buffer& b) const; 511 }; 512 513 class RawTLV : public InTLV { 514 protected: 515 unsigned short m_type; 516 unsigned short m_length; 517 518 public: 519 RawTLV(unsigned short type); 520 Type()521 unsigned short Type() const { return m_type; } Length()522 unsigned short Length() const { return m_length; } 523 void ParseValue(Buffer& b); 524 }; 525 526 const unsigned short MESSAGETEXT_FLAG1_UCS2 = 0x02; 527 const unsigned short MESSAGETEXT_FLAG1_ISO8859_1 = 0x03; 528 529 class MessageTextTLV : public InTLV { 530 protected: 531 std::string m_message; 532 unsigned short m_flag1, m_flag2; 533 534 public: MessageTextTLV()535 MessageTextTLV() 536 : m_message(), m_flag1(0), m_flag2(0) { } 537 getMessage()538 std::string getMessage() { return m_message; } getFlag1()539 unsigned short getFlag1() { return m_flag1; } getFlag2()540 unsigned short getFlag2() { return m_flag1; } 541 542 void ParseValue(Buffer& b); Type()543 unsigned short Type() const { return TLV_MessageText; } Length()544 unsigned short Length() const { return 0; } 545 }; 546 547 class MessageDataTLV : public InTLV { 548 MessageTextTLV mttlv; 549 550 public: 551 MessageDataTLV(); 552 getMessage()553 std::string getMessage() { return mttlv.getMessage(); } getFlag1()554 unsigned short getFlag1() { return mttlv.getFlag1(); } getFlag2()555 unsigned short getFlag2() { return mttlv.getFlag2(); } 556 557 void ParseValue(Buffer& b); Type()558 unsigned short Type() const { return TLV_MessageData; } Length()559 unsigned short Length() const { return 0; } 560 }; 561 562 class AdvMsgBodyTLV : public InTLV { 563 protected: 564 ICQSubType *m_icqsubtype; 565 566 public: 567 AdvMsgBodyTLV(); 568 ~AdvMsgBodyTLV(); 569 570 ICQSubType* grabICQSubType(); 571 572 void ParseValue(Buffer& b); Type()573 unsigned short Type() const { return TLV_AdvMsgBody; } Length()574 unsigned short Length() const { return 0; } 575 }; 576 577 class AdvMsgDataTLV : public InTLV { 578 ICQSubType *m_icqsubtype; 579 580 public: 581 AdvMsgDataTLV(); 582 ~AdvMsgDataTLV(); 583 584 ICQSubType* grabICQSubType(); 585 586 void ParseValue(Buffer& b); Type()587 unsigned short Type() const { return TLV_AdvMsgData; } Length()588 unsigned short Length() const { return 0; } 589 }; 590 591 // ============================================================================ 592 // SBL TLVs 593 // ============================================================================ 594 595 class SBLAwaitAuthTLV : public InTLV 596 { 597 public: SBLAwaitAuthTLV()598 SBLAwaitAuthTLV() { } 599 Type()600 unsigned short Type() const { return TLV_SBL_Await_Auth; } Length()601 unsigned short Length() const { return 0; } 602 void ParseValue(Buffer& b); 603 }; 604 605 class SBLIdsTLV : public InTLV 606 { 607 public: SBLIdsTLV()608 SBLIdsTLV() { } 609 Type()610 unsigned short Type() const { return TLV_SBL_Ids; } Length()611 unsigned short Length() const { return 0; } 612 void ParseValue(Buffer& b); 613 }; 614 615 class SBLVisibilityTLV : public CharTLV 616 { 617 public: SBLVisibilityTLV()618 SBLVisibilityTLV() { } Type()619 unsigned short Type() const { return TLV_SBL_Visibility; } 620 }; 621 622 class SBLICQTICTLV : public StringTLV 623 { 624 public: SBLICQTICTLV()625 SBLICQTICTLV() { } Type()626 unsigned short Type() const { return TLV_SBL_ICQTIC; } 627 }; 628 629 class SBLImportTimeTLV : public LongTLV 630 { 631 public: SBLImportTimeTLV()632 SBLImportTimeTLV() { } Type()633 unsigned short Type() const { return TLV_SBL_ImportTime; } 634 }; 635 636 class SBLNickTLV : public StringTLV 637 { 638 public: SBLNickTLV()639 SBLNickTLV() { } Type()640 unsigned short Type() const { return TLV_SBL_Nick; } 641 }; 642 643 class SBLSMSNoTLV : public StringTLV 644 { 645 public: SBLSMSNoTLV()646 SBLSMSNoTLV() { } Type()647 unsigned short Type() const { return TLV_SBL_SMS_No; } 648 }; 649 650 // --------------- ICQDataTLV ------------------ 651 652 class ICQDataTLV : public InTLV { 653 private: 654 ICQSubType *m_icqsubtype; 655 656 public: 657 ICQDataTLV(); 658 ~ICQDataTLV(); 659 660 ICQSubType* getICQSubType() const; 661 ICQSubType* grabICQSubType(); 662 663 void ParseValue(Buffer& b); Type()664 unsigned short Type() const { return TLV_ICQData; } Length()665 unsigned short Length() const { return 0; } 666 667 }; 668 669 // ---------------- TLV List ------------------- 670 671 class TLVList { 672 private: 673 std::map<unsigned short,InTLV*> tlvmap; 674 public: 675 TLVList(); 676 ~TLVList(); 677 678 void Parse(Buffer& b, TLV_ParseMode pm, unsigned short no_tlvs); 679 void ParseByLength(Buffer& b, TLV_ParseMode pm, unsigned int len); 680 681 bool exists(unsigned short type); 682 InTLV* & operator[](unsigned short type); 683 684 }; 685 686 Buffer& operator<<(Buffer& b, const ICQ2000::OutTLV& t); 687 688 } 689 690 #endif 691