RealtimeCompLab2
Dependencies: mbed
Fork of PPP-Blinky by
Diff: main.cpp
- Revision:
- 28:1aa629be05e7
- Parent:
- 27:78d194dd8799
- Child:
- 29:30de79d658f6
--- a/main.cpp Tue Jan 03 03:19:47 2017 +0000 +++ b/main.cpp Wed Jan 04 02:20:06 2017 +0000 @@ -16,8 +16,8 @@ // https://en.wikibooks.org/wiki/Serial_Programming/IP_Over_Serial_Connections // http://pingtester.net/ - nice tool for high rate ping testing -Serial pc(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem on your pc -Serial xx(PC_10, PC_11); // debug((((( port - use an additional USB serial port to monitor this +Serial xx(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem on your pc +Serial pc(PC_10, PC_11); // debug((((( port - use an additional USB serial port to monitor this // the second #define below gets rid of all the debug printfs #define debug(x) xx.printf x @@ -33,6 +33,8 @@ struct { int online; int ident; + int sync; + int seq; struct { char * buf; volatile int head; @@ -56,7 +58,7 @@ tcpType tcp; -void pppInitStruct(){ ppp.online=0; ppp.rx.buf=rxbuf; ppp.rx.tail=0; ppp.rx.head=0; ppp.rx.total=0; ppp.pkt.buf=frbuf; ppp.pkt.len=0; ppp.ident=0;} +void pppInitStruct(){ ppp.online=0; ppp.rx.buf=rxbuf; ppp.rx.tail=0; ppp.rx.head=0; ppp.rx.total=0; ppp.pkt.buf=frbuf; ppp.pkt.len=0; ppp.ident=0; ppp.sync=0; ppp.seq=77;} int crcG; // frame check sequence (CRC) holder void crcDo(int x){for (int i=0;i<8;i++){crcG=((crcG&1)^(x&1))?(crcG>>1)^0x8408:crcG>>1;x>>=1;}} // crc calculator @@ -140,7 +142,6 @@ } void sendFrame(){ - ppp.ident++; int crc = crcBuf(ppp.pkt.buf, ppp.pkt.len-2); // update crc ppp.pkt.buf[ ppp.pkt.len-2 ] = (~crc>>0); // fcs lo (crc) ppp.pkt.buf[ ppp.pkt.len-1 ] = (~crc>>8); // fcs hi (crc) @@ -295,7 +296,6 @@ char * pktLen = ipPkt+2; // 2 bytes char * ident = ipPkt+4; // 2 bytes char * flags = ipPkt+6; // 2 bits - //char * fragment = ipPkt+6; // 14 bits char * ttl = ipPkt+8; // 1 byte char * protocol = ipPkt+9; // 1 byte char * headercheck= ipPkt+10; // 2 bytes @@ -309,39 +309,25 @@ int packetLength = (pktLen[0]<<8)|pktLen[1]; // ip total packet length int identIP = (ident[0]<<8)|ident[1]; int flagsIP = flags[0]>>14&3; - //int fragmentIP = ((fragment[0]&0x3f)<<8)|fragment[1]; int ttlIP = ttl[0]; int protocolIP = protocol[0]; int checksumIP = (headercheck[0]<<8)|headercheck[1]; char srcIP [16]; snprintf(srcIP,16, "%d.%d.%d.%d", srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3]); char dstIP [16]; snprintf(dstIP,16, "%d.%d.%d.%d", dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]); debug(("IP %s %s v%d h%d d%d e%d L%d ",srcIP,dstIP,versionIP,headerSizeIP,dscpIP,ecnIP,packetLength)); - debug(("i%04x f%d t%d p%d C%04x\n",identIP,flagsIP,ttlIP,protocolIP,checksumIP)); + if(0) { debug(("i%04x f%d t%d p%d C%04x\n",identIP,flagsIP,ttlIP,protocolIP,checksumIP)); } } void dumpHeaderTCP() { int ipHdrLen = (ppp.pkt.buf[4]&0xf)*4; // overall length of ip packet char * s = ppp.pkt.buf+4+ipHdrLen; // start of tcp packet - //char * srctcp = s + 0; // 2 bytes - //char * dsttcp = s + 2; // 2 bytes char * seqtcp = s + 4; // 4 bytes char * acktcp = s + 8; // 4 bytes - //char * offset = s + 12; // 4 bits char * flagbitstcp = s + 12; // 9 bits - //char * winsizetcp = s + 14; // 2 bytes - //char * checksumtcp = s + 16; // 2 bytes - //char * urgentpointer = s + 18; // 2 bytes - - //int srcPort = (srctcp[0]<<8)|srctcp[1]; - //int dstPort = (dsttcp[0]<<8)|dsttcp[1]; int seq = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]); int ack = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]); - //int tcpHdrSize = ((offset[0]>>4)&0x0f)*4; // size of tcp header only int flags = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; - //int winsize = (winsizetcp[0]<<8)|winsizetcp[1]; - //int checkTCP = (checksumtcp[0]<<8)|checksumtcp[1]; - //int urgentTCP = (urgentpointer[0]<<8)|urgentpointer[1]; int idx = 0; char flagInfo [40]; if (flags & (1<<0)) idx=snprintf(flagInfo+idx,40, "FIN "); if (flags & (1<<1)) idx=snprintf(flagInfo+idx,40, "SYN "); @@ -350,8 +336,7 @@ if (flags & (1<<6)) idx=snprintf(flagInfo+idx,40, "ECE "); if (flags & (1<<7)) idx=snprintf(flagInfo+idx,40, "CWR "); if (flags & (1<<8)) idx=snprintf(flagInfo+idx,40, "NS "); - debug(("Flag %s Seq %08x Ack %08x ", flagInfo, seq, ack)); - + if(0) { debug(("Flag %s Seq %08x Ack %08x ", flagInfo, seq, ack)); } } void tcpHandler() { @@ -362,7 +347,7 @@ char * ihl = ipPkt; // bottom 4 bits char * ident = ipPkt+4; // 2 bytes char * pktLen = ipPkt+2; // 2 bytes - char * protocol = ipPkt+9; // 1 byte + char * protocol = ipPkt+9; // 1 byte char * srcAdr = ipPkt+12; // 4 bytes char * dstAdr = ipPkt+16; // 4 bytes = total of 20 bytes @@ -371,61 +356,102 @@ ident[0] = ppp.ident>>8; ident[1] = ppp.ident>>0; // stuff in our ident - char src[4]; char dst[4]; memcpy(src, srcAdr,4); memcpy(dst, dstAdr,4); - memcpy(srcAdr, dst,4); memcpy(dstAdr, src,4); // swap ip address source/dest - headercheck[0]=0; headercheck[1]=0; headerCheckSum(); // redo the tcp header checksum - - headercheck[0]=0; headercheck[1]=0; headerCheckSum(); // redo the tcp header checksum - - int ipHdrLen = (ppp.pkt.buf[4]&0xf)*4; // length of ip header + int ipHdrLen = (ppp.pkt.buf[4]&0xf)*4; // length of ip header char * s = ppp.pkt.buf+4+ipHdrLen; // start of tcp packet char * srctcp = s + 0; // 2 bytes char * dsttcp = s + 2; // 2 bytes + char * seqtcp = s + 4; // 4 bytes + char * acktcp = s + 8; // 4 bytes + char * offset = s + 12; // 4 bits char * flagbitstcp = s + 12; // 9 bits char * checksumtcp = s + 16; // 2 bytes int tcpSize = packetLength - headerSizeIP; + int tcpHeaderLen = ((offset[0]>>4)&0x0f)*4; // size of tcp header only + int dataLen = tcpSize - tcpHeaderLen; // data is what's left after the header + + int seq = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]); + int ack = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]); + + char * dataStart = s + tcpHeaderLen; // start of data + int flagsTCP = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; + + #define TCP_FLAG_ACK (1<<4) + #define TCP_FLAG_SYN (1<<1) + #define TCP_FLAG_PSH (1<<3) + #define TCP_FLAG_RST (1<<2) + #define TCP_FLAG_FIN (1<<0) - int syncFound = 0; - #define TCP_FLAG_SYN 2 - if ((flagsTCP & TCP_FLAG_SYN)!=0) syncFound=1; + // a simple state machine to emulate basie TCP states (e.g. webserver) + + int dataLenOld = dataLen; // we are updating data len but still need to use it + dataLen = 0; // reset the data length to prep for a short response + + if ( ((flagsTCP & ~TCP_FLAG_ACK) == 0) && ((flagsTCP & TCP_FLAG_ACK) != 0) ) { + if (dataLenOld > 0) { // they sent data in the ack + ack = seq + dataLenOld; // we update to show we know + seq = ppp.seq; + } + else { + if (ack <= ppp.seq) return; // just an empty ack + ppp.seq = ack; // update our count + ack = seq; + seq = ppp.seq; + } + } + else if ( (flagsTCP & TCP_FLAG_FIN) != 0 ) { // got FIN + flagbitstcp[1] |= TCP_FLAG_ACK; // do a syn-ack + ack = seq; + seq = ppp.seq; + } + else if ( (flagsTCP & TCP_FLAG_SYN) != 0 ) { // got SYN + flagbitstcp[1] |= TCP_FLAG_ACK; // do a syn-ack + ack = seq + 1; + seq = ppp.seq-1; + } + else if ( (flagsTCP & TCP_FLAG_PSH) != 0 ) { // respond to push with ack + flagbitstcp[1] = TCP_FLAG_ACK; + int temp = ack; + ack = seq + dataLenOld; + ppp.seq = temp; + seq = temp; + if ( strncmp(dataStart, "GET / HTTP/1.1", 14) == 0) { // check for web client + dataLen = 3*32; // extend the data + memset(dataStart,0, dataLen ); + sprintf(dataStart,"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked; charset=utf-8\r\nF\r\nmbed-PPP-Blinky\r\n\r\n0\r\n\r\n"); + } + } + + // now we have to redo all the header sizes + + int newPacketSize = headerSizeIP + tcpHeaderLen + dataLen; + pktLen[0] = (newPacketSize>>8); pktLen[1]=newPacketSize; // ip total packet size + ppp.pkt.len = newPacketSize+6; // ppp packet length + tcpSize = tcpHeaderLen + dataLen; // tcp packet size - #define TCP_FLAG_ACK (1<<4) - flagbitstcp[1] = TCP_FLAG_ACK; // change any flag to an ACK + // redo all the header stuff + + acktcp[0]=ack>>24; acktcp[1]=ack>>16; acktcp[2]=ack>>8; acktcp[3]=ack>>0; // save ack + seqtcp[0]=seq>>24; seqtcp[1]=seq>>16; seqtcp[2]=seq>>8; seqtcp[3]=seq>>0; // save seq + char src[4]; char dst[4]; memcpy(src, srcAdr,4); memcpy(dst, dstAdr,4); + memcpy(srcAdr, dst,4); memcpy(dstAdr, src,4); // swap ip address source/dest char psrc[2]; char pdst[2]; memcpy(psrc, srctcp,2); memcpy(pdst, dsttcp,2); memcpy(srctcp, pdst,2); memcpy(dsttcp, psrc,2); // swap ip port source/dest - + + headercheck[0]=0; headercheck[1]=0; headerCheckSum(); // redo the ip header checksum char pseudoHeader[12]; int sum; char temp[12]; // for the terrible pseudoheader checksum - memcpy( pseudoHeader+0, srcAdr, 8); // source and destination addresses. pseudoHeader[8]=0; pseudoHeader[9]=protocol[0]; pseudoHeader[10]=tcpSize>>8; pseudoHeader[11]=tcpSize; memcpy(temp, s-12, 12); // keep a copy memcpy( s-12, pseudoHeader, 12); // put the header on the tcp packet checksumtcp[0]=0; checksumtcp[1]=0; - sum=dataCheckSum(s-12,tcpSize+12); // update TCP checksum + sum=dataCheckSum(s-12,tcpSize+12); // update TCP checksum checksumtcp[0]=sum>>8; checksumtcp[1]=sum; memcpy( s-12, temp, 12); // overwrite the pseudoheader - sendFrame(); // return the TCP packet - - if (syncFound==0) return; - - flagbitstcp[1] = TCP_FLAG_SYN; // change the ACK to our SYN - - memcpy( pseudoHeader+0, srcAdr, 8); // source and destination addresses. - pseudoHeader[8]=0; pseudoHeader[9]=protocol[0]; - pseudoHeader[10]=tcpSize>>8; pseudoHeader[11]=tcpSize; - memcpy(temp, s-12, 12); // keep a copy - memcpy( s-12, pseudoHeader, 12); // put the header on the tcp packet - checksumtcp[0]=0; checksumtcp[1]=0; - sum=dataCheckSum(s-12,tcpSize+12); // update TCP checksum - checksumtcp[0]=sum>>8; checksumtcp[1]=sum; - memcpy( s-12, temp, 12); // overwrite the pseudoheader - - sendFrame(); // send our request as a response to a SYN } void dumpDataTCP() { @@ -433,11 +459,8 @@ int ipHeaderLen = (ppp.pkt.buf[4]&0xf)*4; // length of ip header int tcpHeaderLen = ((ppp.pkt.buf[4+ipHeaderLen+12]>>4)&0xf)*4;; // length of tcp header int dataLen = ipPktLen - ipHeaderLen - tcpHeaderLen; // data is what's left after the two headers - //debug(("TCP %d ipHeader %d tcpHeader %d Data %d\n", ipPktLen, ipHeaderLen, tcpHeaderLen, dataLen)); - if (dataLen > 0) { - debug(("%s\n",ppp.pkt.buf+4+ipHeaderLen+tcpHeaderLen)); - } - + if(0) { debug(("TCP %d ipHeader %d tcpHeader %d Data %d\n", ipPktLen, ipHeaderLen, tcpHeaderLen, dataLen)); } // 1 for more verbose + if (dataLen > 0) { debug(("%s\n",ppp.pkt.buf+4+ipHeaderLen+tcpHeaderLen)); } // show the data } void TCPpacket(){ @@ -469,7 +492,7 @@ char dstIP [16]; snprintf(dstIP,16, "%d.%d.%d.%d", dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]); debug(("IP %s %s v%d h%d d%d e%d L%d ",srcIP,dstIP,versionIP,headerSizeIP,dscpIP,ecnIP,packetLength)); debug(("i%04x f%d t%d p%d C%04x\n",identIP,flagsIP,ttlIP,protocolIP,checksumIP)); - //dumpHeaderTCP(); + dumpHeaderTCP(); dumpDataTCP(); tcpHandler(); } @@ -485,7 +508,6 @@ case 6: TCPpacket(); break; default: otherProtocol(); } - //debug((("IP frame proto %3d len %4d %d.%d.%d.%d %d.%d.%d.%d\n", ppp.pkt.buf[13],(ppp.pkt.buf[6]<<8)+ppp.pkt.buf[7],ppp.pkt.buf[16],ppp.pkt.buf[17],ppp.pkt.buf[18],ppp.pkt.buf[19],ppp.pkt.buf[20],ppp.pkt.buf[21],ppp.pkt.buf[22],ppp.pkt.buf[23] ); } void LCPconfReq() {