Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of webserverBlinky by
Diff: PPP-Blinky/ppp-blinky.cpp
- Revision:
- 160:bd701ad564cb
- Parent:
- 159:4d1bf96a59cd
- Child:
- 161:d59f778bc8ab
--- a/PPP-Blinky/ppp-blinky.cpp Sat Sep 02 07:48:53 2017 +0000 +++ b/PPP-Blinky/ppp-blinky.cpp Sat Sep 02 17:35:29 2017 +0000 @@ -166,7 +166,7 @@ union { tcpHeaderType * tcp; // pointer to tcp header struct char * tcpStart; // char pointer to tcp header struct (need a char pointer for byte offset calculations) - }; + }; int online; // we hunt for a PPP connection if this is zero int hostIP; // ip address of host int fcs; // PPP "frame check sequence" - a 16-bit HDLC-like checksum used in all PPP frames @@ -703,14 +703,13 @@ n=n+sprintf(pbuf+n, "%05d ",IPv4Id); // IPv4Id is a good way to correlate our dumps with net monitor or wireshark traces #define DUMP_FULL_IP_ADDRESS_YES #ifdef DUMP_FULL_IP_ADDRESS_YES - char * srcAdr = (char *)&ppp.ip->srcAdrR; // 4 bytes - char * dstAdr = (char *)&ppp.ip->dstAdrR; // 4 bytes = total of 20 bytes - //n=n+sprintf(pbuf+n, " %x %x ", ppp.pkt.ip.x, ppp.pkt.ip.y); + char * srcAdr = (char *)&ppp.ip->srcAdrR; + char * dstAdr = (char *)&ppp.ip->dstAdrR; n=n+sprintf(pbuf+n, " %d.%d.%d.%d %d.%d.%d.%d ",srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3], dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]); // full ip addresses #endif putsWhileCheckingInput( pbuf ); #ifndef TCP_HEADER_DUMP_YES - putsWhileCheckingInput('\x1b[30m\n'); // there is no TCP header dump, so terminate the line with \n and VT100 code for black + putsWhileCheckingInput('\x1b[30m\n'); // if there's no TCP header dump we terminate the line with \n and VT100 code for black #endif #endif } @@ -744,9 +743,11 @@ #define EVERY_PACKET_ON_A_NEW_LINE_YES #ifdef EVERY_PACKET_ON_A_NEW_LINE_YES putsWhileCheckingInput("\x1b[30m\n"); // write a black color and newline after every packet +#else + putsWhileCheckingInput("\x1b[30m"); // write a black color after every packet #endif if( outGoing && ppp.tcp->flag.fin ) { // ACK/FIN - if this is an outgoing FIN it's the end of a tcp conversation - putcWhileCheckingInput('\n'); // insert an extra new line to mark the end of an HTTP conversation + putcWhileCheckingInput('\n'); // insert an extra new line to mark the end (except for final ack) of an HTTP conversation } #endif } @@ -778,8 +779,8 @@ out[j]=0; } -/// handle a request for an http websocket -/// we end up here if we enter the following javascript in a web browser console: x = new WebSocket("ws://172.10.10.2"); +/// Handle a request for an http websocket. +/// We end up here if we enter the following javascript in a web browser console: x = new WebSocket("ws://172.10.10.2"); int webSocketHandler(char * dataStart) { int n=0; // byte counter @@ -821,7 +822,7 @@ { int n=0; // number of bytes we have printed so far n = webSocketHandler( dataStart ); // test for and handle WebSocket upgrade requests - if (n>0) return n; // if it's a WebSocket we already have the response, so return + if (n>0) return n; // if n>0 we already have a response, so return int nHeader; // byte size of HTTP header int contentLengthStart; // index where HTML starts @@ -880,33 +881,27 @@ return n; // total byte size of our response } -/// handle TCP data that is not an HTTP get -/// this is the response if we have TCP data but it's not an HTTP GET -/// this is handy when you for example want to use netcat (nc.exe) to talk to PPP-Blinky -/// this could also be a websocket receive event - especially if the first byte is 0x81 (websocket data push) +/// Handle TCP data that is not an HTTP GET. +/// This is handy when for example you want to use netcat (nc.exe) to talk to PPP-Blinky. +/// This could also be a websocket receive event - especially if the first byte is 0x81 (websocket data push) int tcpResponse(char * dataStart, int len, int * outFlags) { int n=0; // number of bytes we have printed so far if (dataStart[0] == 0x81) { // check if this is a websocket push message - // this is most likely a websocket push message. you get this when you enter this in your browser console: x.send("my message"); - if (0) putsWhileCheckingInput( "Got data from websocket send()\n" ); - - // for now we simply echo the websocket data back to the client - the client should therefore see an onmessage event - // to display the echoed data in your browser, enter the following into the browser console: x.onmessage = function(msg){ console.log( msg.data ); } - if (1) { - char mask [4]; - memcpy ( mask, dataStart+2, 4); // websocket messages are "masked", so first we obtain the 4-byte mask - int websocketMessageSize = len - 6; // 1 byte prefix (0x81), 1 byte, 4 bytes mask = 6 bytes - if((dataStart[1]&0x80)==0x80) // test if the mask bit is set, which means all data is xor'ed with the mask - for (int i=0; i<websocketMessageSize; i++) dataStart[i+6]^= mask[i%4]; // unmask each byte with one of the mask bytes - dataStart[1] = len-2; // add four extra bytes to the message length because we don't use mask bytes for the send - memcpy(dataStart+2, "Got:",4); // insert our own text into the four mask bytes - n = len; // our response size remains exactly the same length as what we received - } + char mask [4]; + memcpy ( mask, dataStart+2, 4); // websocket messages are "masked", so first we obtain the 4-byte mask + int websocketMessageSize = len - 6; // 1 byte prefix (0x81), 1 byte, 4 bytes mask = 6 bytes + if((dataStart[1]&0x80)==0x80) // test if the mask bit is set, which means all data is xor'ed with the mask + for (int i=0; i<websocketMessageSize; i++) dataStart[i+6]^= mask[i%4]; // unmask each byte with one of the mask bytes + dataStart[1] = len-2; // add four extra bytes to the message length because we don't use mask bytes for the send + memcpy(dataStart+2, "Got:",4); // insert our own text into the four mask bytes + n = len; // our response size remains exactly the same length as what we received } else if ( (dataStart[0]==0x88) && (dataStart[1]==0x80) && (len == 6) ) { // test for a websocket close request n=2; // our close command is only two bytes long because we don't use the four mask bytes dataStart[1]=0; // we don't have mask bytes on - } else if (v1) putsWhileCheckingInput("TCP data received\n"); + } else { + if (v1) putsWhileCheckingInput("TCP data received\n"); // all other tcp push packets + } return n; // total byte size of our response } @@ -915,17 +910,14 @@ void tcpHandler() { // IP header - char * ipPkt = ppp.pkt.buf+4; // ip packet start - char * protocol = ipPkt+9; // 1 byte - char protocolIP = protocol[0]; int packetLengthIp = __REV16(ppp.ip->lengthR ); // size of ip packet int headerSizeIp = 4 * ppp.ip->headerLength; // size of ip header // TCP header - + ppp.tcpStart = ppp.ipStart + headerSizeIp; // calculate where the TCP header starts int tcpSize = packetLengthIp - headerSizeIp; // tcp size = size of ip payload - char * tcp = ppp.ipStart+headerSizeIp; // start of tcp packet + char * tcp = ppp.ipStart+headerSizeIp; // calculate start of tcp packet int headerSizeTcp = 4 * (ppp.tcp->offset); // tcp "offset" for start of data is also the header size @@ -950,7 +942,7 @@ int dataLen = 0; // most of our responses will have zero TCP data, only a header int flagsOut = TCP_FLAG_ACK; // the default case is an ACK packet //int flagsTCP = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; // the tcp flags we received - + ppp.tcp->windowR = __REV16( 700 ); // set tcp window size to 700 bytes // A sparse TCP flag interpreter that implements stateless TCP connections @@ -988,7 +980,7 @@ ppp.tcp->ackTcpR = __REV( ack_out ); // byte reversed - tcp/ip messages are big-endian (high byte first) ppp.tcp->seqTcpR = __REV( seq_out ); // byte reversed - tcp/ip messages are big-endian (high byte first) - + ppp.tcp->flag.All = flagsOut; // update the TCP flags // recalculate all the header sizes @@ -1006,13 +998,13 @@ pseudoHeader.srcAdrR = ppp.ip->srcAdrR; // copy in ip source address pseudoHeader.dstAdrR = ppp.ip->dstAdrR; // copy in ip dest address pseudoHeader.zero = 0; // padding - pseudoHeader.protocol = protocolIP; // protocol number + pseudoHeader.protocol = ppp.ip->protocol; // protocol number pseudoHeader.lengthR = __REV16( tcpSize ); // size of tcp packet dataCheckSum(pseudoHeader.start, 12, 1); // start with the TCP checksum of the pseudoheader ppp.tcp->checksumR = 0; // before TCP checksum calculations the checksum bytes must be set cleared unsigned int pseudoHeaderSum=dataCheckSum((unsigned char *)ppp.tcpStart,tcpSize, 0); // continue the TCP checksum on the whole TCP packet ppp.tcp->checksumR = __REV16( pseudoHeaderSum); // tcp checksum done, store it in the TCP header - + dumpHeaderIP(1); // dump outgoing IP header dumpHeaderTCP(1); // dump outgoing TCP header for (int i=0; i<45*1000/10; i++) { // 45 ms delay before sending frame - a typical internet delay time