| 
              
              
                |  |  
                |  Author | Topic: 
                  Quantumlink protocol not that hard... (Read 82 
              times) |  
                | Keith 
                  Henrickson Guest
 
 | 
                    
                    
                      |  | Quantumlink protocol not that 
                        hard... « Thread Started on 
                        7/3/05 at 14:38 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  |  
                      | I've 
                        actually got a good deal of the protocol understood. My 
                        challenge is finding the time to do anything with 
                        it.
 
 One challenge to be overcome is understanding 
                        the disk file format. There are only 3 'real' programs 
                        on the disk. "*", "CHANGE ACCESS", and "DSK". The 
                        remaining programs are all loaded through the three 
                        letter filenames, as has been discussed on other 
                        threads. These files are simply track/sector pointers to 
                        the real files to be loaded. However, you ONLY have to 
                        learn about this if you want to write your own BASIC 
                        games to run inside people connection. Since each file 
                        has a header saying what to do with it, and can be 
                        lightly compressed/encrypted, this would need some 
                        exploration.
 
 However, most people are probably 
                        interested in bringing back the service. It's not THAT 
                        hard to get your head around the protocol.
 
 The 
                        Tymnet/Telenet login stuff is EASY to fake. Simply send 
                        the following string. C format for any programmers out 
                        there. "IDENTIFIER\xBA\xBA+" That's it. Just use a phone 
                        number like "/555-5555" to use the Tymnet (I beleive) 
                        login. Don't worry about what the commands mean. It's 
                        useless once you get connected.
 
 Next comes layer 
                        2. The client will send 
                        "\x5a\x4*\x*1\x4*\x*1\x7F\x7F\x23\x07\x09\x0D"
 The 5A 
                        and the 0D are framing characters. They were used by the 
                        system to pick each packet apart. The stuff with the '*' 
                        is the CRC. It is NOT a custom CRC, it is plain jane 
                        CRC-16, padded with the 4's and the 1's. Why they did 
                        THAT, I have no clue. The next two bytes are sequence 
                        numbers. The first byte is the packet # that is being 
                        transmitted. The second byte is the last packet number 
                        successfully received by the sender of the packet. It 
                        ALWAYS starts at 0x7F, and wraps around to 0x10. For 
                        instance, if I am sending packet 0x15, and I have most 
                        recently received your packet 0x11, then the bytes would 
                        be "\x15\x11". This way every time you receive a packet, 
                        you know which of YOUR packets the other guy has 
                        received so that you can throw away the copies you kept 
                        and free up memory. The "\x23\x07\x09" is saying, "I am 
                        a confused client, and my version number is 
                        9.7."
 
 To respond to this, the server sends back 
                        "\x5A\x4*\x*1\x4*\x*1\x7F\x7F\x24\x0D". The "\x24" tells 
                        the client, "You're OK. I understand you, and we'll 
                        start all over."
 
 For those of you who have worked 
                        at VERY low levels with ISDN, you will recognize some of 
                        this from Q.921. Interesting. Of course, all the numbers 
                        have changed and stuff, and the CRCs are added. But the 
                        concept is the same. LAPM on modems is actually quite 
                        similar too. Again, in ISDN terms, "\x23" is like a 
                        SABME, and "\x24" is like a UA.
 
 Once you exchange 
                        these two packets, layer 2 is up. YAY. The client will 
                        switch from "Waiting for access to Q-Link..." to 
                        "Verifying your account details".
 
 It will then 
                        send a packet like. 
                        "\x5A\x4*\x*1\x4*\x*1\x10\x7F\x20DD1234567890ABCD\x0d"
 
 Ok, 
                        now "\x20" says that this is a data packet. Data 
                        packets, and ONLY data packets increment our packet 
                        number. That's why the "\x7F" changed to a "\x10". Yay. 
                        Now, the next two bytes are always two alphanumerics. 
                        That is the command the client is sending. "DD" means, 
                        "logging in with account number and validation code". 
                        The first ten digits are your account number, NOT your 
                        screen name. The screen name is NEVER sent to the 
                        server. The last four letters are a validation code. 
                        Sort of a password.
 
 If your account is valid, the 
                        server will respond "D3EFGH". D3 says to write a new 
                        validation code, and the new code, which will be used on 
                        the NEXT login, is "EFGH".
 
 When the client has 
                        done so, it will send "D6", saying it wrote the code 
                        without errors.
 
 The server will then send either 
                        a "DO", to display the main menu, or it will send the 
                        welcome text using "SM/SE". All lines but the last are 
                        sent with SM, and the last line is sent with SE. That 
                        way the client knows you have the whole thing, and lets 
                        you press F5 to go to the main menu.
 
 I know a LOT 
                        more, and if there is real interest I will write it 
                        up.
 
 |  
                      | 
                          
                          
                            |  |  Logged |  |  |  
                | Keith 
                  Henrickson Guest
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #1 on 7/3/05 
                        at 14:44 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  |  
                      | Oh, and if 
                        you want to send me an email, my address is 
                        flipper@phin.com
 |  
                      | 
                          
                          
                            |  |  Logged |  |  |  
                | Jeff 
                  Ledger Administrator
 
      member is offline
 
 
 ![[avatar]](8bit TelBBS - Quantumlink protocol not that hard___files/bc.gif) 
 
 
 ![[homepage]](8bit TelBBS - Quantumlink protocol not that hard___files/www_sm.gif)  ![[send pm]](8bit TelBBS - Quantumlink protocol not that hard___files/message_sm.gif)  Joined: Feb 2004
 Posts: 
                182
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #2 on 7/3/05 
                        at 21:43 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  |  
                      | The only 
                        successful login I've been able to use is 
                        the
 TERMINAL=
 @
 @
 \0d
 CONNECTED
 
 using 
                        the number +5551212
 
 Once connected it sends about 
                        5 of these and then gives 
                        up.
 
 ZqE±N#
 ZqE±N#
 ZqE±N#
 ZqE±N#
 
 Am 
                        I looking at some type of compressed 
                        code?
 
 Jeff
 
 |  
                      | 
                          
                          
                            |  |  Logged |  
 "My computer boots in 2 seconds!"
 --Microsoft 
                        Beat That!
 |  |  
                | Keith 
                  Henrickson Guest
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #3 on 7/4/05 
                        at 0:39 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  |  
                      | Ok, so 
                        you're having better luck with Telenet. Or I have them 
                        backwards. Been MANY years, and I never used either 
                        service for anything but Q-Link.
 
 ANYWAY, you're 
                        seeing the clients hellos.
  
 Z is 0x5A in ASCII, of course, and will 
                        start EVERY packet.
 
 The next four characters are 
                        the encoded CRC. Looking them up in an ASCII table, I 
                        get:
 0x71, 0x45, 0xF1, 0x4E.
 The significant 
                        digits are 7, 5, F, E. The others are the static padding 
                        I referred to (if incorrectly), in my original post. The 
                        CRC is reassembled as FE75. This seems to be a perfectly 
                        normal CRC-16 of the remaining bytes in the 
                        packet.
 
 The '#' is 0x23 in ASCII, and therefore 
                        this is the 'confused client' packet that is always sent 
                        on startup.
 
 The remaining bytes 0x7F, 0x7F, 0x07, 
                        0x09 (the last two may differ, they're a version 
                        number), are unprintable and therefore won't show in a 
                        simple ASCII trace.
 
 You're 90% of the way to your 
                        first breakthrough. If you can figure out how to 
                        calculate CRCs (test it by confirming the CRC in the 
                        0x23. I SWEAR this is a normal CRC-16.), then you can 
                        reply by changing the 0x23 to a 0x24, getting rid of the 
                        0x07 and 0x09 bytes, fixing up the CRC, and sending it 
                        to the client.
 
 You will see your first text 
                        change when you get it right. The CRC function is based 
                        on a very poor understanding of what it was doing. It 
                        works, but all the variable names should be considered 
                        wrong. The algorithm is poor as well. I have a better 
                        function, but haven't had a chance to test it yet. I 
                        beleive this function generates CRC-16 with the byte 
                        order incorrect, which will of course, propogate through 
                        the entire CRC function
 
 
 /*Compute CRC for a 
                        packet. The packet data including sequence numbers 
                        and
 the packet type must be present. The framing 
                        characters and CRC bytes should
 not be present at 
                        all. */
 unsigned short compute_CRC(unsigned char 
                        *pszPacketDataBuf, int nPacketLen){
 
 int 
                        nByteCounter;
 int nBitCounter;
 unsigned short 
                        nTempCRC;
 unsigned char nCRCHigh;
 unsigned char 
                        nCRCLow;
 
 nCRCHigh = 0;
 nCRCLow = 0;
 
 for 
                        (nByteCounter = 0; nByteCounter < nPacketLen; 
                        nByteCounter++){
 /*Set a counter to 8 
                        times*/
 nTempCRC = (nCRCLow << 8);
 for 
                        (nBitCounter = 0; nBitCounter < 8; nBitCounter++) 
                        {
 /*Move low bit of new byte to C, high bit of new 
                        byte becomes 0
 Move C into low bit of A, Move high 
                        bit of A into C
 Mask off all of A except new bit 
                        */
 nTempCRC = ((nTempCRC & 0xFF00) | 
                        ((pszPacketDataBuf[nByteCounter] & (1 << 
                        nBitCounter)) >> nBitCounter));
 /*Xor CRChigh 
                        into A*/
 nTempCRC = nTempCRC ^ nCRCHigh;
 /*Move 
                        low bit of CRClow into C, high bit of CRC low becomes 
                        0
 Move C into high bit of A, move low bit of A into 
                        C
 If C is not set, not ready to xor in CRC polynomial 
                        */
 if (nTempCRC & 1) {
 nTempCRC = nTempCRC 
                        >> 1;
 /*Get CRClow
 Xor in polylow
 Store 
                        CRClow */
 nTempCRC = ((nTempCRC & 0x00FF) | 
                        (((nTempCRC >> 8) ^ 0xA0) << 8));
 /*Xor 
                        in polyhigh
 Store CRChigh */
 nTempCRC = nTempCRC ^ 
                        0x01;
 nCRCHigh = nTempCRC & 0x00FF;
 } else 
                        {
 nTempCRC = nTempCRC >> 1;
 nCRCHigh = 
                        nTempCRC & 0x00FF;
 }
 }
 nCRCLow = nTempCRC 
                        >> 8;
 }
 return ((nCRCHigh << 8) | 
                        nCRCLow);
 }
 
 /*Takes some data and sends it 
                        through the packet protocol. The
 packet type byte 
                        must be present, but the sequence numbers and
 framing 
                        bytes will be generated by this function. */
 void 
                        transmit_packet(unsigned char *pPacketBuf, int 
                        nPacketLen) {
 unsigned char 
                        szTempBuf[1024];
 unsigned short 
                        nCRC;
 
 szTempBuf[0] = 
                        0x5A;
 
 memcpy(&szTempBuf[7], pPacketBuf, 
                        nPacketLen);
 szTempBuf[5] = 0x7f;
 szTempBuf[6] = 
                        0x7f;
 nCRC = compute_CRC(&szTempBuf[5], 
                        nPacketLen+2);
 szTempBuf[1] = (nCRC & 0x00F0) | 
                        0x01;
 szTempBuf[2] = (nCRC & 0x000F) | 
                        0x40;
 szTempBuf[3] = ((nCRC >> 8)& 0x00F0) 
                        | 0x01;
 szTempBuf[4] = ((nCRC >> 8)& 
                        0x000F) | 0x40;
 szTempBuf[nPacketLen + 7] = 
                        0x0D;
 
 write(nWriteFD, szTempBuf, nPacketLen + 
                        8);
 }
 
 // Of course, this isn't in a function, 
                        but it shows the way to invoke the above code to get 
                        what you want
 transmit_packet("\x24",1);
 
 
 
 |  
                      | 
                          
                          
                            |  |  Logged |  |  |  
                | Jim 
                  Brain Full Member
 
    member is online
 
 
 
 
 
 ![[email]](8bit TelBBS - Quantumlink protocol not that hard___files/email_sm.gif)  ![[send pm]](8bit TelBBS - Quantumlink protocol not that hard___files/message_sm.gif)  Joined: Mar 2004
 Posts: 
                189
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #4 on 7/23/05 
                        at 2:28 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  ![[Modify]](8bit TelBBS - Quantumlink protocol not that hard___files/modify.gif)  ![[Delete]](8bit TelBBS - Quantumlink protocol not that hard___files/delete.gif) |  
                      | Yay!
 
 Success, 
                        thanks to Keith:
 
 2005-07-23 
                        01:15:42:168113080::RS->|0000|0d 0a |.. 
                        |
 2005-07-23 01:15:42:168113080::RS->|0000|43 4f 
                        4e 4e 45 43 54 |CONNECT |
 2005-07-23 
                        01:15:42:168113080::RS->|0000|0d 0a |.. 
                        |
 2005-07-23 01:15:43:168113080::RS<-|0000|0d |. 
                        |
 2005-07-23 01:15:43:168113080::RS<-|0000|0d |. 
                        |
 2005-07-23 01:15:43:168113464::RS->|0000|54 45 
                        52 4d 49 4e 41 4c 3d 0d |TERMINAL=. |
 2005-07-23 
                        01:15:47:168113080::RS<-|0000|44 31 0d |D1. 
                        |
 2005-07-23 01:15:47:168113464::RS->|0000|40 |@ 
                        |
 2005-07-23 01:15:47:168113080::RS<-|0000|53 45 
                        54 3f 20 31 30 3a |SET? 10: |
 2005-07-23 
                        01:15:48:168113080::RS<-|0000|30 2c 31 35 3a 30 2c 30 
                        |0,15:0,0 |
 2005-07-23 
                        01:15:48:168113080::RS<-|0000|3a 33 33 2c 35 37 3a 31 
                        |:33,57:1 |
 2005-07-23 
                        01:15:48:168113080::RS<-|0000|2c 36 33 3a 30 0d 
                        |,63:0. |
 2005-07-23 
                        01:15:48:168113464::RS->|0000|40 |@ |
 2005-07-23 
                        01:15:49:168113080::RS<-|0000|43 4f 4e 4e 45 43 54 20 
                        |CONNECT |
 2005-07-23 
                        01:15:49:168113080::RS<-|0000|37 30 33 33 39 2e 38 37 
                        |70339.87 |
 2005-07-23 
                        01:15:50:168113080::RS<-|0000|0d |. |
 2005-07-23 
                        01:15:51:168113464::RS->|0000|0d 0d 43 4f 4e 4e 45 43 
                        54 45 44 0d |..CONNECTED. |
 2005-07-23 
                        01:15:54:168113080::RS<-|0000|5a 81 42 31 4e 7f 7f 23 
                        |Z.B1N..# |
 2005-07-23 
                        01:15:54:168113080::RS<-|0000|05 09 0d |... 
                        |
 2005-07-23 01:15:54:168113464::RS->|0000|5a f1 
                        43 11 41 7f 7f 24 0d |Z.C.A..$. |
 2005-07-23 
                        01:15:55:168113080::RS<-|0000|5a 71 4b 41 4f 10 7f 20 
                        |ZqKAO.. |
 2005-07-23 
                        01:15:55:168113080::RS<-|0000|44 44 35 38 38 39 33 34 
                        |DD588934 |
 2005-07-23 
                        01:15:55:168113080::RS<-|0000|39 35 36 37 31 20 20 20 
                        |95671 |
 2005-07-23 
                        01:15:56:168113080::RS<-|0000|0d |. |
 2005-07-23 
                        01:15:56:168113464::RS->|0000|5a 61 40 f1 41 10 10 20 
                        44 33 31 20 20 20 0d |Za@.A.. D31 . |
 2005-07-23 
                        01:15:56:168113080::RS<-|0000|5a c1 44 81 45 11 10 20 
                        |Z.D.E.. |
 2005-07-23 
                        01:15:57:168113080::RS<-|0000|53 53 0d |SS. 
                        |
 2005-07-23 01:15:57:168113464::RS->|0000|5a 31 
                        48 81 44 11 11 20 53 53 0d |Z1H.D.. SS. |
 2005-07-23 
                        01:15:59:168113080::RS<-|0000|5a 31 47 c1 40 12 11 20 
                        |Z1G.@.. |
 2005-07-23 
                        01:15:59:168113080::RS<-|0000|53 47 0d 5a 21 43 31 42 
                        |SG.Z!C1B |
 2005-07-23 
                        01:16:00:168113080::RS<-|0000|13 11 20 44 36 0d |.. 
                        D6. |
 2005-07-23 01:16:00:168113464::RS->|0000|5a 
                        b1 49 c1 4f 12 13 20 44 4f 0d |Z.I.O.. DO. 
                        |
 
 I'm at the 9 colored blocks... I never 
                        used Q-Link, so I am driving in the blind.
 
 Notice 
                        in the above that I got a SS after the D3, to which I 
                        sent an SS back. I then got a SG and a D6 piggybacked on 
                        it, to which I sent the DO.
 
 In any event, many 
                        thanks. If I had not taken such a wrong turn trying to 
                        step through the code (spent days trying to get through 
                        it), I'd be much further. Oh well, time to make up for 
                        lost time.
 
 Keith, you sure I can;t interest you 
                        in a Java codebase? It has the FSM already installed 
                        (though it will no doubt need serious 
                        work).
 
 Jim
 
 |  
                      | 
                          
                          
                            |  |  Logged |  --
 Jim Brain
 
 |  |  
                | Jim 
                  Brain Full Member
 
    member is online
 
 
 
 
 
 ![[email]](8bit TelBBS - Quantumlink protocol not that hard___files/email_sm.gif)  ![[send pm]](8bit TelBBS - Quantumlink protocol not that hard___files/message_sm.gif)  Joined: Mar 2004
 Posts: 
                189
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #5 on 7/23/05 
                        at 2:31 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  ![[Modify]](8bit TelBBS - Quantumlink protocol not that hard___files/modify.gif)  ![[Delete]](8bit TelBBS - Quantumlink protocol not that hard___files/delete.gif) |  
                      | By the way, 
                        here's a much simpler CRC to use:
 
 Code:
                          
                            
                            
                              | 
                                
                                
                                | int poly=0xa001; int crc=0;
 int 
                                data;
 boolean carry;
 
 for(int 
                                i=0;i<stream.length;i++) 
                                {
 data=stream[i];
 for(int k=0;k<8;k++) 
                                {
 carry
 crc=crc^(data&1);
 data=data>>1;
 
 if((crc&1)!=0) 
                                {
 crc=crc>>1;
 crc=crc^poly;
 } 
                                else 
                                {
 crc=crc>>1;
 }
 }
 }
 
 |  |  
 |  
                      | 
                          
                          
                            | « Last Edit: 
                              7/23/05 at 2:36 by Jim 
                              Brain » |  Logged |  --
 Jim Brain
 
 |  |  
                | Jim 
                  Brain Full Member
 
    member is online
 
 
 
 
 
 ![[email]](8bit TelBBS - Quantumlink protocol not that hard___files/email_sm.gif)  ![[send pm]](8bit TelBBS - Quantumlink protocol not that hard___files/message_sm.gif)  Joined: Mar 2004
 Posts: 
                189
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #6 on 7/23/05 
                        at 2:55 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  ![[Modify]](8bit TelBBS - Quantumlink protocol not that hard___files/modify.gif)  ![[Delete]](8bit TelBBS - Quantumlink protocol not that hard___files/delete.gif) |  
                      | OK, two 
                        questions:
 
 When I select All but Commodore 
                        Showcase and PeopleConnection, I get ML, but what do I 
                        need to send back?
 
 Also, how does the server 
                        determine which of them the user selected, since they 
                        all send 
                      ML?
 
 
 |  
                      | 
                          
                          
                            |  |  Logged |  --
 Jim Brain
 
 |  |  
                | Keith 
                  Henrickson Guest
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #7 on 7/23/05 
                        at 12:21 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  |  
                      | People 
                        connection sends MR, and of course does it's own thing. 
                        To bring up the simplest of people connection screens, 
                        send back 'CMLobby' and 'CE\x01JBrain'. It's not much, 
                        but you will have access to the menu on F7 and 
                        everything.
 
 The other 8 areas should all function 
                        identically. You should receive 'ML', and send back 
                        'MC'. You will then see the first line of a menu pop up 
                        at the top of the screen. It is waiting for the menu in 
                        the form of 'KA' and 'KB' commands. To see how to draw a 
                        menu, look at qlinkold/qmenus.c
 
 The function 
                        qmens_rendermenu() outputs a standard menu.
 There are 
                        basically two fields to each line. One is the item 
                        number. It simply says which item will be requested from 
                        the server.
 The other field is a 24 bit value, of 
                        which two bytes have a significance that I understand. 
                        The first byte is the type of resource being requested. 
                        Some of them are simple like, "Change Area Menu", or 
                        "Post Office", or "Text Document". Some of them are 
                        complicated, like "Gateway service", and "Message 
                        Board", or "Mall Item". I have a list of what I know of 
                        each item in qlinkold/qlinkfuncs.txt
 The second byte 
                        is a bitfield, with the second bit indicating plus time 
                        or not. IIRC. There is a buffer overflow here that lets 
                        you create 'minus time'. Of course, that was just a 
                        cosmetic indicator on the client side. Setting it didn't 
                        do anything to the server.
 
 One correction to 
                        qlinkfuncs.txt is:
 Item 0x85 is the 'gateway 
                        service', and basically a simple line by line terminal 
                        program that communicates over the Y* series of commands 
                        in that 
                    file.
 
 |  
                      | 
                          
                          
                            |  |  Logged |  |  |  
                | Keith 
                  Henrickson Guest
 
 | 
                    
                    
                      |  | Re: Quantumlink protocol not that 
                        hard... « Reply #8 on 7/23/05 
                        at 14:02 »
 | ![[Quote]](8bit TelBBS - Quantumlink protocol not that hard___files/quote.gif)  |  
                      | 
 7/23/05 
                        at 12:21, Keith Henrickson wrote:
 
                          
                          
                            | 
                                
                                
                                | The other 8 
                                areas should all function identically. You 
                                should receive 'ML', and send back 'MC'. You 
                                will then see the first line of a menu pop up at 
                                the top of the screen. It is waiting for the 
                                menu in the form of 'KA' and 'KB' commands. To 
                                see how to draw a menu, look at 
                                qlinkold/qmenus.c
 
 |  |  Also, 
                        the client will send 'K1@@@a' or somesuch. There is a 
                        hard coded list of these in the client, one for each of 
                        the 8 root menus. After that, you're pretty much free to 
                        pick your own menu names. THere are some rules, but I 
                        haven't figured out what they are. The menu names are a 
                        4 ASCII char encoding of a 24 bit number. But message 
                        boards will pick their own 24 bit numbers in some cases. 
                        I never did figure them out.
 
 |  
                      | 
                          
                          
                            |  |  Logged |  |  |  
                |  |  |