//! Handle a command. void handle(uint8_t const app, uint8_t const verb, uint32_t const len){ int i; //debugstr("GoodFET"); //led_off(); // find the app and call the handle fn for(i = 0; i < num_apps; i++){ if(apps[i]->app == app){ // call the app's handle fn (*(apps[i]->handle))(app, verb, len); // exit early return; } } // if we get here, then the desired app is not compiled into // this firmware debugstr("App missing."); debughex(app); txdata(app, NOK, 0); }
void sendtopeer( struct cs_cachepeer_data *peer, unsigned char *buf, int len) { if (peer->host->ip && peer->port) { struct sockaddr_in si_other; int slen=sizeof(si_other); memset((char *) &si_other, 0, sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons( peer->port ); si_other.sin_addr.s_addr = peer->host->ip; if (flag_debugnet) { debugf(" cache: send data (%d) to peer (%s:%d)\n", len, peer->host->name,peer->port); debughex(buf,len); } while (1) { struct pollfd pfd; pfd.fd = peer->outsock; pfd.events = POLLOUT; int retval = poll(&pfd, 1, 10); if (retval>0) { if ( pfd.revents & (POLLOUT) ) { sendto(peer->outsock, buf, len, 0, (struct sockaddr *)&si_other, slen); } else debugf(" cache: error sending data\n"); break; } else if (retval<0) { if ( (errno!=EINTR)&&(errno!=EAGAIN) ) { debugf(" cache: error sending data\n"); break; } } else debugf(" cache: error sending data\n"); } } }
//! Handles MSP430X2 JTAG commands. Forwards others to JTAG. void jtag430x2_handle_fn( uint8_t const app, uint8_t const verb, uint32_t const len) { unsigned int i,val; unsigned long at, l; //jtag430_resettap(); if(verb!=START && jtag430mode==MSP430MODE){ (*(jtag430_app.handle))(app,verb,len); return; } switch(verb){ case START: //Enter JTAG mode. //do cmddata[0]=jtag430x2_start(); //while(cmddata[0]==00 || cmddata[0]==0xFF); //MSP430 or MSP430X if(jtagid==MSP430JTAGID){ //debugstr("ERROR, using JTAG430X2 instead of JTAG430!"); jtag430mode=MSP430MODE; /* So the way this works is that a width of 20 does some backward-compatibility finagling, causing the correct value to be exchanged for addresses on 16-bit chips as well as the new MSP430X chips. (This has only been verified on the MSP430F2xx family. TODO verify for others.) */ drwidth=20; //Perform a reset and disable watchdog. jtag430_por(); jtag430_writemem(0x120,0x5a80);//disable watchdog jtag430_haltcpu(); jtag430_resettap(); txdata(app,verb,1); return; }else if(jtagid==MSP430X2JTAGID){ jtag430mode=MSP430X2MODE; drwidth=20; }else{ debugstr("JTAG version unknown."); txdata(app,NOK,1); return; } jtag430x2_fusecheck(); jtag430x2_syncpor(); jtag430_resettap(); txdata(app,verb,1); break; case JTAG430_READMEM: case PEEK: at=cmddatalong[0]; //Fetch large blocks for bulk fetches, //small blocks for individual peeks. if(len>5) l=(cmddataword[2]);//always even. else l=2; l&=~1;//clear lsbit if(l<2) l=2; txhead(app,verb,l); for(i=0;i<l;i+=2){ //jtag430_resettap(); //delay(10); val=jtag430x2_readmem(at); at+=2; serial_tx(val&0xFF); serial_tx((val&0xFF00)>>8); } break; case JTAG430_COREIP_ID: cmddataword[0]=jtag430_coreid(); txdata(app,verb,2); break; case JTAG430_DEVICE_ID: cmddatalong[0]=jtag430_deviceid(); txdata(app,verb,4); break; case JTAG430_WRITEFLASH: case JTAG430_WRITEMEM: case POKE: jtag430x2_writemem(cmddatalong[0], cmddataword[2]); cmddataword[0]=jtag430x2_readmem(cmddatalong[0]); txdata(app,verb,2); break; //unimplemented functions case JTAG430_HALTCPU: //jtag430x2_haltcpu(); debugstr("Warning, not trying to halt for lack of code."); txdata(app,verb,0); break; case JTAG430_RELEASECPU: case JTAG430_SETINSTRFETCH: case JTAG430_ERASEFLASH: case JTAG430_SETPC: debugstr("This function is not yet implemented for MSP430X2."); debughex(verb); txdata(app,NOK,0); break; default: (*(jtag_app.handle))(app,verb,len); } jtag430_resettap(); }
/////////////////////////////////////////////////////////////////////////////// // Connect to a server. // Return // 0: no error int cc_connect_srv(struct cs_server_data *srv, int fd) { int n; uint8 data[20]; uint8 hash[SHA_DIGEST_LENGTH]; uint8 buf[CC_MAXMSGSIZE]; char pwd[64]; // if (fd < 0) return -1; // INIT srv->progname = NULL; memset( srv->version, 0, sizeof(srv->version) ); // get init seed(random) from server if((n = recv_nonb(fd, data, 16,3000)) != 16) { static char msg[]= "Server does not return init sequence"; srv->statmsg = msg; //debugf("Client: Server (%s:%d) does not return 16 bytes\n", srv->host->name,srv->port); close(fd); return -2; } if (flag_debugnet) { debugf(" CCcam: receive server init seed (%d)\n",n); debughex(data,n); } // Check newbox int isnewbox = 0; uchar a = (data[0]^'M') + data[1] + data[2]; uchar b = data[4] + (data[5]^'C') + data[6]; uchar c = data[8] + data[9] + (data[10]^'S'); if ( (a==data[3])&&(b==data[7])&&(c==data[11]) ) isnewbox = 1; cc_crypt_xor(data); // XOR init bytes with 'CCcam' SHA_CTX ctx; SHA1_Init(&ctx); SHA1_Update(&ctx, data, 16); SHA1_Final(hash, &ctx); //debugdump(hash, sizeof(hash), "CCcam: sha1 hash:"); //initialisate crypto states cc_crypt_init(&srv->recvblock, hash, 20); cc_decrypt(&srv->recvblock, data, 16); cc_crypt_init(&srv->sendblock, data, 16); cc_decrypt(&srv->sendblock, hash, 20); cc_msg_send( fd, &srv->sendblock, CC_MSG_NO_HEADER, 20,hash); // send crypted hash to server memset(buf, 0, sizeof(buf)); memcpy(buf, srv->user, 20); //debugf(" CCcam: username '%s'\n",srv->username); cc_msg_send( fd, &srv->sendblock, CC_MSG_NO_HEADER, 20, buf); // send usr '0' padded -> 20 bytes memset(buf, 0, sizeof(buf)); memset(pwd, 0, sizeof(pwd)); //debugf("CCcam: 'CCcam' xor\n"); memcpy(buf, "CCcam", 5); strncpy(pwd, srv->pass, 63); cc_encrypt(&srv->sendblock, (uint8 *)pwd, strlen(pwd)); cc_msg_send( fd, &srv->sendblock, CC_MSG_NO_HEADER, 6, buf); // send 'CCcam' xor w/ pwd if ((n = recv_nonb(fd, data, 20,3000)) != 20) { static char msg[]= "Password ACK not received"; srv->statmsg = msg; debugf(" CCcam: login failed to Server (%s:%d), pwd ack not received (n = %d)\n",srv->host->name,srv->port, n); return -2; } cc_decrypt(&srv->recvblock, data, 20); //hexdump(data, 20, "CCcam: pwd ack received:"); if (memcmp(data, buf, 5)) { // check server response static char msg[]= "Invalid user/pass"; srv->statmsg = msg; debugf(" CCcam: login failed to Server (%s:%d), usr/pwd invalid\n",srv->host->name,srv->port); return -2; }// else debugf(" CCcam: login succeeded to Server (%s:%d)\n",srv->host->name,srv->port); srv->handle = fd; if (!cc_sendinfo_srv(srv,isnewbox)) { srv->handle = -1; static char msg[]= "Error sending client data"; srv->statmsg = msg; debugf(" CCcam: login failed to Server (%s:%d), could not send client data\n",srv->host->name,srv->port); return -3; } static char msg[]= "Connected"; srv->statmsg = msg; srv->keepalivesent = 0; srv->keepalivetime = GetTickCount(); srv->connected = GetTickCount(); srv->busy = 0; srv->lastecmoktime = 0; srv->lastecmtime = 0; srv->lastdcwtime = 0; srv->chkrecvtime = 0; memset(srv->version,0,32); pipe_wakeup( srvsocks[1] ); return 0; }
void cache_recvmsg() { unsigned int recv_ip; unsigned short recv_port; unsigned char buf[1024]; struct sockaddr_in si_other; socklen_t slen=sizeof(si_other); uint ticks = GetTickCount(); struct cs_cachepeer_data *peer; int received = recvfrom( cfg.cachesock, buf, sizeof(buf), 0, (struct sockaddr*)&si_other, &slen); memcpy( &recv_ip, &si_other.sin_addr, 4); recv_port = ntohs(si_other.sin_port); if (received>0) { if (flag_debugnet) { debugf(" cache: recv data (%d) from address (%s:%d)\n", received, ip2string(recv_ip), recv_port ); debughex(buf,received); } // Store Data struct cache_data req; switch(buf[0]) { case TYPE_REQUEST: // Check Peer peer = getpeerbyaddr(recv_ip,recv_port); if (!peer) { peer = getpeerbyip(recv_ip); if (!peer) break; } peer->lastactivity = ticks; //peer->totreq++; // Check Multics diferent version if ( !strcmp("MultiCS",peer->program) && (!strcmp("r63",peer->version)||!strcmp("r64",peer->version)||!strcmp("r65",peer->version)||!strcmp("r66",peer->version)||!strcmp("r67",peer->version)||!strcmp("r68",peer->version)||!strcmp("r69",peer->version)||!strcmp("r70",peer->version)||!strcmp("r71",peer->version)||!strcmp("r72",peer->version)||!strcmp("r73",peer->version)||!strcmp("r74",peer->version)||!strcmp("r75",peer->version)||!strcmp("r76",peer->version)||!strcmp("r77",peer->version)||!strcmp("r78",peer->version)||!strcmp("r79",peer->version)||!strcmp("r80",peer->version)||!strcmp("r81",peer->version)||!strcmp("r82",peer->version)||!strcmp("r83",peer->version)||!strcmp("r84",peer->version)||!strcmp("r85",peer->version)) ) break; // Check CSP if (received==20) { // arbiter number strcpy(peer->program,"CSP"); break; } // Check Status if (peer->disabled) break; // Get DATA req.tag = buf[1]; req.sid = (buf[2]<<8) | buf[3]; req.onid = (buf[4]<<8) | buf[5]; req.caid = (buf[6]<<8) | buf[7]; req.hash = (buf[8]<<24) | (buf[9]<<16) | (buf[10]<<8) |buf[11]; // Check Cache Request if (!cache_check(&req)) break; // peer->reqnb++; // ADD CACHE struct cache_data *pcache = cache_fetch( &req ); if (pcache==NULL) { //*debugf(" [CACHE] << Cache Request from %s %04x:%04x:%08x\n", peer->host->name, req.caid, req.sid, req.hash); pcache = cache_new( &req ); if (cfg.cache.trackermode) { // Send REQUEST to all Peers struct cs_cachepeer_data *p = cfg.cachepeer; while (p) { if (!p->disabled) if (p->host->ip && p->port) if ( (p->lastactivity+75000)>ticks ) if ( !p->fblock0onid || pcache->onid ) cache_send_request(pcache,p); p = p->next; } pcache->sendcache = 1; cfg.cachereq++; } } else if (!cfg.cache.trackermode) { if ( (pcache->status==CACHE_STAT_DCW)&&(pcache->sendcache!=2) ) { //debugf(" [CACHE] << Request Reply >> to peer %s %04x:%04x:%08x\n", peer->host->name, req.caid, req.sid, req.hash); peer->ihitfwd++; peer->hitfwd++; cache_send_reply(pcache,peer); } } break; case TYPE_REPLY: // Check Peer peer = getpeerbyaddr(recv_ip,recv_port); if (!peer) { peer = getpeerbyip(recv_ip); if (!peer) break; } peer->lastactivity = ticks; //peer->totrep++; // Check Multics diferent version if ( !strcmp("MultiCS",peer->program) && (!strcmp("r63",peer->version)||!strcmp("r64",peer->version)||!strcmp("r65",peer->version)||!strcmp("r66",peer->version)||!strcmp("r67",peer->version)||!strcmp("r68",peer->version)||!strcmp("r69",peer->version)||!strcmp("r70",peer->version)||!strcmp("r71",peer->version)||!strcmp("r72",peer->version)||!strcmp("r73",peer->version)||!strcmp("r74",peer->version)||!strcmp("r75",peer->version)||!strcmp("r76",peer->version)||!strcmp("r77",peer->version)||!strcmp("r78",peer->version)||!strcmp("r79",peer->version)||!strcmp("r80",peer->version)||!strcmp("r81",peer->version)||!strcmp("r82",peer->version)||!strcmp("r83",peer->version)||!strcmp("r84",peer->version)||!strcmp("r85",peer->version)) ) break; // Check Status if (peer->disabled) break; // 02 80 00CD 0001 0500 8D1DB359 80 // failed // 02 80 00CD 0001 0500 8D1DB359 80 00CD 0000 0500 63339F359A663232B73158405A255DDC // OLD // 02 80 001F 0001 0100 9A3BA1C1 80 BC02DB99DE3D526D5702D42D4C249505 0005 6361726431 // NEW if (buf[12]!=buf[1]) { //peer->rep_badheader++; break; } req.tag = buf[1]; req.sid = (buf[2]<<8) | buf[3]; req.onid = (buf[4]<<8) | buf[5]; req.caid = (buf[6]<<8) | buf[7]; req.hash = (buf[8]<<24) | (buf[9]<<16) | (buf[10]<<8) |buf[11]; // Check Cache Request if (!cache_check(&req)) { //peer->rep_badfields++; break; } // if (received==13) { // FAILED //peer->rep_failed++; //*debugf(" [CACHE] <| Failed Cache Reply from %s (CAID:%04x SID:%04x ONID:%04x)\n", peer->host->name, req.caid, req.sid, req.onid); // NOTHING TO DO break; } else if (received>=29) { // 02 80 001F 0001 0100 9A3BA1C1 80 BC02DB99DE3D526D5702D42D4C249505 0005 6361726431 // NEW if ( !acceptDCW(buf+13) ) { //peer->rep_baddcw++; break; } //*debugf(" [CACHE] << Good Cache Reply from %s %04x:%04x:%08x (ONID:%04x)\n", peer->host->name, req.caid, req.sid, req.hash, req.onid); peer->repok++; // Request+Reply // Search for Cache data struct cache_data *pcache = cache_fetch( &req ); if (pcache==NULL) pcache = cache_new( &req ); if (pcache->status!=CACHE_STAT_DCW) { //*debugf(" [CACHE] Update Cache DCW %04x:%04x:%08x\n", pcache->caid, pcache->sid, pcache->hash); pcache->peerid = peer->id; memcpy(pcache->cw, buf+13, 16); pcache->status = CACHE_STAT_DCW; if (pcache->sendpipe) { uchar buf[128]; // 32 por defecto buf[0] = PIPE_CACHE_FIND_SUCCESS; buf[1] = 11+2+16; // Data length buf[2] = pcache->tag; buf[3] = pcache->sid>>8; buf[4] = pcache->sid&0xff; buf[5] = pcache->onid>>8; buf[6] = pcache->onid&0xff; buf[7] = pcache->caid>>8; buf[8] = pcache->caid&0xff; buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff; buf[13] = peer->id>>8; buf[14] = peer->id&0xff; memcpy( buf+15, pcache->cw, 16); //*debugf(" pipe Cache->Ecm: PIPE_CACHE_FIND_SUCCESS %04x:%04x:%08x\n",pcache->caid, pcache->sid, pcache->hash); // debughex(buf, 13+16); pipe_send( srvsocks[1], buf, 13+2+16); //pcache->sendpipe = 0; } if (cfg.cache.trackermode) { // Send REQUEST to all Peers struct cs_cachepeer_data *p = cfg.cachepeer; while (p) { if (!p->disabled) if (p->host->ip && p->port) if ( (p->lastactivity+75000)>ticks ) if ( !p->fblock0onid || pcache->onid ) cache_send_reply(pcache,p); p = p->next; } pcache->sendcache = 2; cfg.cacherep++; } } else if ( pcache->sendpipe && memcmp(pcache->cw, buf+13, 16) ) { // resend to server pcache->peerid = peer->id; memcpy(pcache->cw, buf+13, 16); pcache->status = CACHE_STAT_DCW; uchar buf[128]; // 32 por defecto buf[0] = PIPE_CACHE_FIND_SUCCESS; buf[1] = 11+2+16; // Data length buf[2] = pcache->tag; buf[3] = pcache->sid>>8; buf[4] = pcache->sid&0xff; buf[5] = pcache->onid>>8; buf[6] = pcache->onid&0xff; buf[7] = pcache->caid>>8; buf[8] = pcache->caid&0xff; buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff; buf[13] = peer->id>>8; buf[14] = peer->id&0xff; memcpy( buf+15, pcache->cw, 16); pipe_send( srvsocks[1], buf, 13+2+16); }