void cardreader_process_ecm(struct s_reader *reader, struct s_client *cl, ECM_REQUEST *er) { cs_log_dump_dbg(D_ATR, er->ecm, er->ecmlen, "ecm:"); struct timeb tps, tpe; struct s_ecm_answer ea; memset(&ea, 0, sizeof(struct s_ecm_answer)); cs_ftime(&tps); int32_t rc = cardreader_do_ecm(reader, er, &ea); cs_ftime(&tpe); rdr_log_dbg(reader, D_READER, "%s: cardreader_do_ecm returned rc=%d (ERROR=%d)", __func__, rc, ERROR); ea.rc = E_FOUND; //default assume found ea.rcEx = 0; //no special flag if(rc == ERROR) { char buf[CS_SERVICENAME_SIZE]; rdr_log_dbg(reader, D_READER, "Error processing ecm for caid %04X, provid %06X, srvid %04X, servicename: %s", er->caid, er->prid, er->srvid, get_servicename(cl, er->srvid, er->prid, er->caid, buf, sizeof(buf))); ea.rc = E_NOTFOUND; ea.rcEx = 0; ICC_Async_DisplayMsg(reader, "Eer"); } if(rc == E_CORRUPT) { char buf[CS_SERVICENAME_SIZE]; rdr_log_dbg(reader, D_READER, "Error processing ecm for caid %04X, provid %06X, srvid %04X, servicename: %s", er->caid, er->prid, er->srvid, get_servicename(cl, er->srvid, er->prid, er->caid, buf, sizeof(buf))); ea.rc = E_NOTFOUND; ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum memcpy(ea.msglog, "Invalid ecm type for card", 25); } write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog, ea.tier, &ea.cw_ex); cl->lastecm = time((time_t *)0); char ecmd5[17 * 3]; cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5)); rdr_log_dbg(reader, D_READER, "ecm hash: %s real time: %"PRId64" ms", ecmd5, comp_timeb(&tpe, &tps)); reader_post_process(reader); }
void cardreader_process_ecm(struct s_reader *reader, struct s_client *cl, ECM_REQUEST *er) { if (ecm_ratelimit_check(reader, er, 1) != OK) { rdr_debug_mask(reader, D_READER, "%s: ratelimit check failed.", __func__); return; // reader_mode = 1: checkout ratelimiter in reader mode so srvid can be replaced } cs_ddump_mask(D_ATR, er->ecm, er->ecmlen, "ecm:"); struct timeb tps, tpe; cs_ftime(&tps); struct s_ecm_answer ea; memset(&ea, 0, sizeof(struct s_ecm_answer)); int32_t rc = cardreader_do_ecm(reader, er, &ea); rdr_debug_mask(reader, D_READER, "%s: cardreader_do_ecm returned rc=%d (ERROR=%d)", __func__, rc, ERROR); ea.rc = E_FOUND; //default assume found ea.rcEx = 0; //no special flag if (rc == ERROR) { char buf[32]; rdr_debug_mask(reader, D_READER, "Error processing ecm for caid %04X, srvid %04X, servicename: %s", er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf)); ea.rc = E_NOTFOUND; ea.rcEx = 0; ICC_Async_DisplayMsg(reader, "Eer"); } if (rc == E_CORRUPT) { char buf[32]; rdr_debug_mask(reader, D_READER, "Error processing ecm for caid %04X, srvid %04X, servicename: %s", er->caid, er->srvid, get_servicename(cl, er->srvid, er->caid, buf)); ea.rc = E_NOTFOUND; ea.rcEx = E2_WRONG_CHKSUM; //flag it as wrong checksum memcpy (ea.msglog,"Invalid ecm type for card",25); } cs_ftime(&tpe); cl->lastecm=time((time_t*)0); char ecmd5[17*3]; cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5)); rdr_debug_mask(reader, D_READER, "ecm hash: %s real time: %ld ms", ecmd5, 1000 * (tpe.time - tps.time) + tpe.millitm - tps.millitm); write_ecm_answer(reader, er, ea.rc, ea.rcEx, ea.cw, ea.msglog); reader_post_process(reader); }
/* * This function writes the current CW from ECM struct to a cwl file. * The filename is re-calculated and file re-opened every time. * This will consume a bit cpu time, but nothing has to be stored between * each call. If not file exists, a header is prepended */ void logCWtoFile(ECM_REQUEST *er, uchar *cw){ FILE *pfCWL; char srvname[128]; /* %s / %s _I %04X _ %s .cwl */ char buf[256 + sizeof(srvname)]; char date[9]; unsigned char i, parity, writeheader = 0; time_t t; struct tm timeinfo; /* * search service name for that id and change characters * causing problems in file name */ get_servicename(cur_client(), er->srvid, er->caid, srvname); for (i = 0; srvname[i]; i++) if (srvname[i] == ' ') srvname[i] = '_'; /* calc log file name */ time(&t); localtime_r(&t, &timeinfo); strftime(date, sizeof(date), "%Y%m%d", &timeinfo); snprintf(buf, sizeof(buf), "%s/%s_I%04X_%s.cwl", cfg.cwlogdir, date, er->srvid, srvname); /* open failed, assuming file does not exist, yet */ if((pfCWL = fopen(buf, "r")) == NULL) { writeheader = 1; } else { /* we need to close the file if it was opened correctly */ fclose(pfCWL); } if ((pfCWL = fopen(buf, "a+")) == NULL) { /* maybe this fails because the subdir does not exist. Is there a common function to create it? for the moment do not print32_t to log on every ecm cs_log(""error opening cw logfile for writing: %s (errno=%d %s)", buf, errno, strerror(errno)); */ return; } if (writeheader) { /* no global macro for cardserver name :( */ fprintf(pfCWL, "# OSCam cardserver v%s - http://streamboard.de.vu/oscam/\n", CS_VERSION); fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n"); strftime(buf, sizeof(buf),"DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n", &timeinfo); fprintf(pfCWL, "# %s", buf); fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname); } parity = er->ecm[0]&1; fprintf(pfCWL, "%d ", parity); for (i = parity * 8; i < 8 + parity * 8; i++) fprintf(pfCWL, "%02X ", cw[i]); /* better use incoming time er->tps rather than current time? */ strftime(buf,sizeof(buf),"%H:%M:%S\n", &timeinfo); fprintf(pfCWL, "# %s", buf); fflush(pfCWL); fclose(pfCWL); }
void cs_statistics(struct s_client * client) { if (!cfg.disableuserfile){ time_t t; struct tm lt; char buf[LOG_BUF_SIZE]; float cwps; time(&t); localtime_r(&t, <); if (client->cwfound+client->cwnot>0) { cwps=client->last-client->login; cwps/=client->cwfound+client->cwnot; } else cwps=0; char channame[32]; if(cfg.mon_appendchaninfo) get_servicename(client, client->last_srvid,client->last_caid, channame); else channame[0] = '\0'; int32_t lsec; if ((client->last_caid == 0xFFFF) && (client->last_srvid == 0xFFFF)) lsec = client->last - client->login; //client leave calc total duration else lsec = client->last - client->lastswitch; int32_t secs = 0, fullmins = 0, mins = 0, fullhours = 0; if((lsec > 0) && (lsec < 1000000)) { secs = lsec % 60; if (lsec > 60) { fullmins = lsec / 60; mins = fullmins % 60; if(fullmins > 60) { fullhours = fullmins / 60; } } } /* statistics entry start with 's' to filter it out on other end of pipe * so we can use the same Pipe as Log */ snprintf(buf, sizeof(buf), "s%02d.%02d.%02d %02d:%02d:%02d %3.1f %s %s %d %d %d %d %d %d %d %ld %ld %02d:%02d:%02d %s %04X:%04X %s\n", lt.tm_mday, lt.tm_mon+1, lt.tm_year%100, lt.tm_hour, lt.tm_min, lt.tm_sec, cwps, client->account->usr, cs_inet_ntoa(client->ip), client->port, client->cwfound, client->cwcache, client->cwnot, client->cwignored, client->cwtout, client->cwtun, client->login, client->last, fullhours, mins, secs, ph[client->ctyp].desc, client->last_caid, client->last_srvid, channame); cs_write_log_int(buf); } }
static void refresh_lcd_file(void) { char targetfile[256]; char tmpfile[256]; char channame[32]; if(cfg.lcd_output_path == NULL){ snprintf(targetfile, sizeof(targetfile),"%s%s", get_tmp_dir(), "/oscam.lcd"); snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", get_tmp_dir(), "/oscam.lcd"); } else { snprintf(targetfile, sizeof(targetfile),"%s%s", cfg.lcd_output_path, "/oscam.lcd"); snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", cfg.lcd_output_path, "/oscam.lcd"); } int8_t iscccam = 0; int32_t seconds = 0, secs = 0, fullmins = 0, mins = 0, fullhours = 0, hours = 0, days = 0; time_t now = time((time_t*)0); while(running) { now = time((time_t*)0); int16_t cnt = 0, idx = 0, count_r = 0, count_p = 0, count_u = 0; FILE *fpsave; if((fpsave = fopen(tmpfile, "w"))){ idx = 0; int16_t i; char *type; char *label; char *status; // Statuslines start secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0; seconds = now - first_client->login; secs = seconds % 60; if (seconds > 60) { fullmins = seconds / 60; mins = fullmins % 60; if(fullmins > 60) { fullhours = fullmins / 60; hours = fullhours % 24; days = fullhours / 24; } } fprintf(fpsave,"Version: %s\n", CS_VERSION); fprintf(fpsave,"Revision: %s\n", CS_SVN_VERSION); if(days == 0) fprintf(fpsave, "up: %02d:%02d:%02d\n", hours, mins, secs); else fprintf(fpsave, "up: %02dd %02d:%02d:%02d\n", days, hours, mins, secs); fprintf(fpsave,"totals: %d/%d/%d/%d/%d/%d\n", first_client->cwfound, first_client->cwnot, first_client->cwignored, first_client->cwtout, first_client->cwcache, first_client->cwtun); fprintf(fpsave,"uptime: %d\n", seconds); // Statuslines end // Readertable head fprintf(fpsave,"Typ| Label | Idle | w | s | b | e | St\n"); fprintf(fpsave,"---+------------+--------------+---+---+---+---+----\n"); struct s_client *cl; // Reader/Proxy table start for ( i=0, cl=first_client; cl ; cl=cl->next, i++) { if ((cl->typ=='r' || cl->typ=='p') && ((now - cl->last) < 20 || !cfg.lcd_hide_idle)){ type = ""; label = ""; status = "OFF"; secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0; seconds = now - cl->last; if (cl->typ == 'r'){ type = "R"; idx = count_r; label = cl->reader->label; if (cl->reader->card_status == CARD_INSERTED) status = "OK"; count_r++; } else if (cl->typ == 'p'){ type = "P"; iscccam = 0; idx = count_p; label = cl->reader->label; if ((strncmp(monitor_get_proto(cl), "cccam", 5) == 0)) iscccam = 1; if (cl->reader->card_status == CARD_INSERTED) status = "CON"; count_p++; } secs = seconds % 60; if (seconds > 60) { fullmins = seconds / 60; mins = fullmins % 60; if(fullmins > 60) { fullhours = fullmins / 60; hours = fullhours % 24; days = fullhours / 24; } } int16_t written = 0, skipped = 0, blocked = 0, error = 0; char *emmtext; if(cs_malloc(&emmtext, 16 * sizeof(char), -1)){ if(cl->typ == 'r' || !iscccam ){ for (i=0; i<4; i++) { error += cl->reader->emmerror[i]; blocked += cl->reader->emmblocked[i]; skipped += cl->reader->emmskipped[i]; written += cl->reader->emmwritten[i]; } snprintf(emmtext, 16, "%3d|%3d|%3d|%3d", written > 999? 999 : written, skipped > 999? 999 : skipped, blocked > 999? 999 : blocked, error > 999? 999 : error); } #ifdef MODULE_CCCAM else if(cl->typ == 'p' && iscccam ){ struct cc_data *rcc = cl->cc; if(rcc){ LLIST *cards = rcc->cards; if (cards) { int32_t cnt = ll_count(cards); int32_t locals = rcc->num_hop1; snprintf(emmtext, 16, " %3d/%3d card%s", locals, cnt, (cnt > 1)? "s ": " "); } } else { snprintf(emmtext, 16, " No cards "); } } #endif else { snprintf(emmtext, 16, " "); } } if(days == 0) { fprintf(fpsave,"%s%d | %-10.10s | %02d:%02d:%02d |%s| %s\n", type, idx, label, hours, mins, secs, emmtext, status); } else { fprintf(fpsave,"%s%d | %-10.10s |% 3dd %02d:%02d:%02d |%s| %s\n", type, idx, label, days, hours, mins, secs, emmtext, status); } free(emmtext); } } fprintf(fpsave,"---+------------+--------------+---+---+---+--++----\n"); // Reader/Proxy table end // Usertable start fprintf(fpsave,"Typ| Label | Channel | Time\n"); fprintf(fpsave,"---+------------+-----------------------------+-----\n"); /* //Testclient fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n", "U", 1, "test", "Sky De", "Discovery Channel", 568); */ for ( i=0, cl=first_client; cl ; cl=cl->next, i++) { seconds = now - cl->lastecm; if (cl->typ == 'c' && seconds < 15){ type = "U"; idx = count_u; label = cl->account->usr; count_u++; get_servicename(cl, cl->last_srvid, cl->last_caid, channame); fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n", type, idx, label, cl->last_srvidptr && cl->last_srvidptr->prov ? cl->last_srvidptr->prov : "", cl->last_srvidptr && cl->last_srvidptr->name ? cl->last_srvidptr->name : "", cl->cwlastresptime); } } fprintf(fpsave,"---+------------+-----------------------------+-----\n"); // Usertable end fclose(fpsave); } idx = 0; cs_sleepms(cfg.lcd_write_intervall * 1000); cnt++; if(rename(tmpfile, targetfile) < 0) cs_log("An error occured while writing oscam.lcd file %s.", targetfile); } }
static char *monitor_client_info(char id, struct s_client *cl, char *sbuf){ char channame[32]; sbuf[0] = '\0'; if (cl){ char ldate[16], ltime[16], *usr; int32_t lsec, isec, con, cau, lrt =- 1; time_t now; struct tm lt; now=time((time_t*)0); if ((cfg.hideclient_to <= 0) || (now-cl->lastecm < cfg.hideclient_to) || (now-cl->lastemm < cfg.hideclient_to) || (cl->typ != 'c')) { lsec = now - cl->login; isec = now - cl->last; usr = username(cl); if (cl->dup) con = 2; else if ((cl->tosleep) && (now-cl->lastswitch>cl->tosleep)) con = 1; else con = 0; // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r') { if ((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) || ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled)) cau = 0; else if ((now-cl->lastemm) / 60 > cfg.aulow) cau = (-1); else cau = 1; } else { cau = 0; } if( cl->typ == 'r') { int32_t i; struct s_reader *rdr; for (i=0,rdr=first_active_reader; rdr ; rdr=rdr->next, i++) if (cl->reader == rdr) lrt=i; if( lrt >= 0 ) lrt = 10 + cl->reader->card_status; } else lrt = cl->cwlastresptime; localtime_r(&cl->login, <); snprintf(ldate, sizeof(ldate), "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon+1, lt.tm_year % 100); int32_t cnr=get_threadnum(cl); snprintf(ltime, sizeof(ldate), "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec); snprintf(sbuf, 256, "[%c--CCC]%8X|%c|%d|%s|%d|%d|%s|%d|%s|%s|%s|%d|%04X:%04X|%s|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d\n", id, cl->tid, cl->typ, cnr, usr, cau, cl->crypted, cs_inet_ntoa(cl->ip), cl->port, client_get_proto(cl), ldate, ltime, lsec, cl->last_caid, cl->last_srvid, get_servicename(cl, cl->last_srvid, cl->last_caid, channame), isec, con, cl->cwfound, cl->cwnot, cl->cwcache, cl->cwignored, cl->cwtout, cl->emmok, cl->emmnok, lrt); } } return sbuf; }
void cs_statistics(struct s_client *client) { if(!cfg.disableuserfile) { struct tm lt; char buf[LOG_BUF_SIZE]; float cwps; time_t walltime = cs_time(); localtime_r(&walltime, <); if(client->cwfound + client->cwnot > 0) { cwps = client->last - client->login; cwps /= client->cwfound + client->cwnot; } else { cwps = 0; } char channame[CS_SERVICENAME_SIZE]; get_servicename(client, client->last_srvid, client->last_provid, client->last_caid, channame, sizeof(channame)); int32_t lsec; if((client->last_caid == NO_CAID_VALUE) && (client->last_srvid == NO_SRVID_VALUE)) { lsec = client->last - client->login; } //client leave calc total duration else { lsec = client->last - client->lastswitch; } int32_t secs = 0, fullmins = 0, mins = 0, fullhours = 0; if((lsec > 0) && (lsec < 1000000)) { secs = lsec % 60; if(lsec > 60) { fullmins = lsec / 60; mins = fullmins % 60; if(fullmins > 60) { fullhours = fullmins / 60; } } } /* statistics entry start with 's' to filter it out on other end of pipe * so we can use the same Pipe as Log */ snprintf(buf, sizeof(buf), "s%02d.%02d.%02d %02d:%02d:%02d %3.1f %s %s %d %d %d %d %d %d %d %ld %ld %02d:%02d:%02d %s %04X@%06X:%04X %s\n", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100, lt.tm_hour, lt.tm_min, lt.tm_sec, cwps, client->account->usr, cs_inet_ntoa(client->ip), client->port, client->cwfound, client->cwcache, client->cwnot, client->cwignored, client->cwtout, client->cwtun, client->login, client->last, fullhours, mins, secs, get_module(client)->desc, client->last_caid, client->last_provid, client->last_srvid, channame); cs_write_log_int(buf); } }