[gbx]
[oscam.git] / module-gbox.c
blob6507e6a5cc349a151b68e61681456e876f47738b
1 #define MODULE_LOG_PREFIX "gbox"
3 #include "globals.h"
4 #ifdef MODULE_GBOX
6 #include "module-gbox.h"
7 #include "module-gbox-helper.h"
8 #include "module-gbox-sms.h"
9 #include "module-gbox-cards.h"
10 #include "module-cccam.h"
11 #include "module-cccam-data.h"
12 #include "oscam-failban.h"
13 #include "oscam-client.h"
14 #include "oscam-ecm.h"
15 #include "oscam-lock.h"
16 #include "oscam-net.h"
17 #include "oscam-chk.h"
18 #include "oscam-string.h"
19 #include "oscam-time.h"
20 #include "oscam-reader.h"
21 #include "oscam-files.h"
22 #include "module-gbox-remm.h"
23 #include "module-dvbapi.h"
25 static struct gbox_data local_gbox;
26 static int8_t local_gbox_initialized = 0;
27 static uint8_t local_cards_initialized = 0;
28 static time_t last_stats_written;
29 uint8_t local_gbx_rev = 0x20;
31 static int32_t gbox_send_ecm(struct s_client *cli, ECM_REQUEST *er);
33 char *get_gbox_tmp_fname(char *fext)
35 static char gbox_tmpfile_buf[64] = { 0 };
36 const char *slash = "/";
37 if(!cfg.gbox_tmp_dir)
39 snprintf(gbox_tmpfile_buf, sizeof(gbox_tmpfile_buf), "%s%s%s",get_tmp_dir(), slash, fext);
41 else
43 if(cfg.gbox_tmp_dir[strlen(cfg.gbox_tmp_dir) - 1] == '/') { slash = ""; }
44 snprintf(gbox_tmpfile_buf, sizeof(gbox_tmpfile_buf), "%s%s%s", cfg.gbox_tmp_dir, slash, fext);
46 return gbox_tmpfile_buf;
49 uint16_t gbox_get_local_gbox_id(void)
51 return local_gbox.id;
54 uint32_t gbox_get_local_gbox_password(void)
56 return local_gbox.password;
59 static uint8_t gbox_get_my_cpu_api (void)
61 return(cfg.gbox_my_cpu_api);
64 static void write_attack_file (struct s_client *cli, uint8_t txt_id, uint16_t rcvd_id)
66 if (cfg.dis_attack_txt) {return;}
67 char tsbuf[28];
68 time_t walltime = cs_time();
69 cs_ctime_r(&walltime, tsbuf);
70 char *fext= FILE_ATTACK_INFO;
71 char *fname = get_gbox_tmp_fname(fext);
72 FILE *fhandle = fopen(fname, "a");
74 if(!fhandle)
76 cs_log("Couldn't open %s: %s", fname, strerror(errno));
77 return;
80 if(txt_id == GBOX_ATTACK_LOCAL_PW)
82 fprintf(fhandle, "ATTACK ALERT FROM %04X %s - peer sends wrong local password - %s",
83 rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);
86 if(txt_id == GBOX_ATTACK_PEER_IGNORE)
88 fprintf(fhandle, "ATTACK ALERT FROM %04X %s - peer is ignored - %s",
89 rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);
92 if(txt_id == GBOX_ATTACK_PEER_PW)
94 fprintf(fhandle, "ATTACK ALERT FROM %04X %s - peer sends unknown peer password - %s",
95 rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);
98 if(txt_id == GBOX_ATTACK_AUTH_FAIL)
100 fprintf(fhandle, "ATTACK ALERT FROM %04X %s - authentification failed - %s",
101 rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);
104 if(txt_id == GBOX_ATTACK_ECM_BLOCKED)
106 fprintf(fhandle, "ATTACK ALERT FROM %04X %s - ECM is blocked - %s",
107 rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);
110 if(txt_id == GBOX_ATTACK_REMM_REQ_BLOCKED)
112 fprintf(fhandle, "ATTACK ALERT FROM %04X %s - unaccepted peer sent REMM REQ - %s",
113 rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);
116 fclose(fhandle);
117 return;
120 void write_msg_info(struct s_client *cli, uint8_t msg_id, uint8_t txt_id, uint16_t misc)
122 if (msg_id == MSGID_GSMS && misc == 0x31) {return;}
123 char *fext= FILE_MSG_INFO;
124 char *fname = get_gbox_tmp_fname(fext);
126 if (file_exists(fname))
128 char buf[120];
129 memset(buf, 0, sizeof(buf));
131 if (msg_id == MSGID_ATTACK)
133 snprintf(buf, sizeof(buf), "%s %d %04X %d %s %d",
134 fname, msg_id, misc, 0, cs_inet_ntoa(cli->ip), txt_id);
136 cs_log_dbg(D_READER, "found driver %s - write msg (msg_id = %d - txt-id = %d) Attack Alert from %s %04X",
137 fname, msg_id, txt_id, cs_inet_ntoa(cli->ip), misc);
139 else
141 snprintf(buf, sizeof(buf), "%.24s %d %.24s %.24s %s %d",
142 fname, msg_id, username(cli), cli->reader->device, cs_inet_ntoa(cli->ip), misc);
144 cs_log_dbg(D_READER, "found driver %s - write msg (id = %d) related to %s %s",
145 fname, msg_id, username(cli),cli->reader->device);
148 char *cmd = buf;
149 FILE *p;
150 if ((p = popen(cmd, "w")) == NULL)
152 cs_log("Error %s",fname);
153 return;
155 pclose(p);
157 return;
160 void handle_attack(struct s_client *cli, uint8_t txt_id, uint16_t rcvd_id)
162 write_attack_file(cli, txt_id, rcvd_id);
163 write_msg_info(cli, MSGID_ATTACK, txt_id, rcvd_id);
164 return;
167 void gbox_write_peer_onl(void)
169 char *fext = FILE_GBOX_PEER_ONL;
170 char *fname = get_gbox_tmp_fname(fext);
171 FILE *fhandle = fopen(fname, "w");
172 if(!fhandle)
174 cs_log("Couldn't open %s: %s", fname, strerror(errno));
175 return;
178 cs_readlock(__func__, &clientlist_lock);
180 struct s_client *cl;
181 for(cl = first_client; cl; cl = cl->next)
183 if(cl->gbox && cl->typ == 'p')
185 struct gbox_peer *peer = cl->gbox;
186 if (peer->online)
188 fprintf(fhandle, "1 %s %s %04X 2.%02X\n", cl->reader->device,
189 cs_inet_ntoa(cl->ip), peer->gbox.id, peer->gbox.minor_version);
191 if (!peer->onlinestat)
193 peer->onlinestat = 1;
194 cs_log("comeONLINE: %s %s boxid: %04X v2.%02X cards:%d", cl->reader->device,
195 cs_inet_ntoa(cl->ip), peer->gbox.id, peer->gbox.minor_version, peer->filtered_cards);
196 write_msg_info(cl, MSGID_COMEONLINE, 0, peer->filtered_cards);
199 else
201 fprintf(fhandle, "0 %s %s %04X 0.00\n", cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id);
202 if (peer->onlinestat)
204 peer->onlinestat = 0;
205 cs_log("goneOFFLINE: %s %s boxid: %04X",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id);
206 write_msg_info(cl, MSGID_GONEOFFLINE, 0, 0);
211 cs_readunlock(__func__, &clientlist_lock);
212 fclose(fhandle);
213 return;
216 void gbox_write_version(void)
218 char *fext = FILE_GBOX_VERSION;
219 char *fname = get_gbox_tmp_fname(fext);
220 FILE *fhandle = fopen(fname, "w");
221 if(!fhandle)
223 cs_log("Couldn't open %s: %s", get_gbox_tmp_fname(FILE_GBOX_VERSION), strerror(errno));
224 return;
226 fprintf(fhandle, "%02X.%02X my-id: %04X rev: %01X.%01X\n", LOCAL_GBOX_MAJOR_VERSION, cfg.gbox_my_vers, local_gbox.id, local_gbx_rev >> 4, local_gbx_rev & 0xf);
227 fclose(fhandle);
230 void hostname2ip(char *hostname, IN_ADDR_T *ip)
232 cs_resolve(hostname, ip, NULL, NULL);
235 uint16_t gbox_convert_password_to_id(uint32_t password)
237 return (((password >> 24) & 0xff) ^ ((password >> 8) & 0xff)) << 8 | (((password >> 16) & 0xff) ^ (password & 0xff));
240 static int8_t gbox_remove_all_bad_sids(ECM_REQUEST *er, uint16_t sid)
242 if (!er)
244 return -1;
247 struct gbox_card_pending *pending = NULL;
248 LL_LOCKITER *li = ll_li_create(er->gbox_cards_pending, 0);
250 while ((pending = ll_li_next(li)))
252 gbox_remove_bad_sid(pending->id.peer, pending->id.slot, sid);
254 ll_li_destroy(li);
255 return 0;
258 void gbox_free_cards_pending(ECM_REQUEST *er)
260 ll_destroy_free_data(&er->gbox_cards_pending);
263 void gbox_init_ecm_request_ext(struct gbox_ecm_request_ext *ere)
265 ere->gbox_slot = 0;
266 ere->gbox_version = 0;
267 ere->gbox_rev = 0;
268 ere->gbox_type = 0;
271 struct s_client *get_gbox_proxy(uint16_t gbox_id)
273 struct s_client *cl;
274 struct s_client *found = NULL;
275 cs_readlock(__func__, &clientlist_lock);
277 for(cl = first_client; cl; cl = cl->next)
279 if(cl->typ == 'p' && cl->gbox && cl->gbox_peer_id == gbox_id)
281 found = cl;
282 break;
285 cs_readunlock(__func__, &clientlist_lock);
286 return found;
289 static int8_t gbox_peer_online(struct gbox_peer *peer, uint8_t online)
291 if (!peer) { return -1; }
293 peer->online = online;
294 gbox_write_peer_onl();
295 return 0;
298 static int8_t gbox_clear_peer(struct gbox_peer *peer)
300 if (!peer)
302 return -1;
305 peer->ecm_idx = 0;
306 peer->next_hello = 0;
307 peer->authstat = 0;
309 gbox_delete_cards(GBOX_DELETE_FROM_PEER, peer->gbox.id);
310 gbox_peer_online(peer, GBOX_PEER_OFFLINE);
312 return 0;
315 static int8_t gbox_reinit_proxy(struct s_client *proxy)
317 if (!proxy)
319 return -1;
322 struct gbox_peer *peer = proxy->gbox;
323 gbox_clear_peer(peer);
325 if (!proxy->reader)
327 return -1;
330 proxy->reader->tcp_connected = 0;
331 proxy->reader->card_status = CARD_NEED_INIT;
332 proxy->reader->last_s = proxy->reader->last_g = 0;
334 return 0;
337 void gbox_send(struct s_client *cli, uint8_t *buf, int32_t l)
339 struct gbox_peer *peer = cli->gbox;
341 cs_log_dump_dbg(D_READER, buf, l, "<- data to %s (%d bytes):", cli->reader->label, l);
343 hostname2ip(cli->reader->device, &SIN_GET_ADDR(cli->udp_sa));
344 SIN_GET_FAMILY(cli->udp_sa) = AF_INET;
345 SIN_GET_PORT(cli->udp_sa) = htons((uint16_t)cli->reader->r_port);
347 gbox_encrypt(buf, l, peer->gbox.password);
348 sendto(cli->udp_fd, buf, l, 0, (struct sockaddr *)&cli->udp_sa, cli->udp_sa_len);
349 cs_log_dump_dbg(D_READER, buf, l, "<- encrypted data to %s (%d bytes):", cli->reader->label, l);
352 void gbox_send_hello_packet(struct s_client *cli, int8_t number, uint8_t *outbuf, uint8_t *ptr, int32_t nbcards, uint8_t hello_stat)
354 struct gbox_peer *peer = cli->gbox;
355 int32_t hostname_len = strlen(cfg.gbox_hostname);
356 int32_t len;
358 gbox_message_header(outbuf, MSG_HELLO, peer->gbox.password, local_gbox.password);
360 // initial HELLO = 0, subsequent = 1
361 if(hello_stat > GBOX_STAT_HELLOS)
363 outbuf[10] = 1;
365 else
367 outbuf[10] = 0;
369 outbuf[11] = number; // 0x80 (if last packet) else 0x00 | packet number
371 if((number & 0x0F) == 0)
373 if(hello_stat != GBOX_STAT_HELLOL)
375 memcpy(++ptr, gbox_get_my_checkcode(), 7);
377 else
379 memset(++ptr, 0, 7);
382 ptr += 7;
383 *ptr = local_gbox.minor_version;
384 *(++ptr) = local_gbox.cpu_api;
385 memcpy(++ptr, cfg.gbox_hostname, hostname_len);
386 ptr += hostname_len;
387 *ptr = hostname_len;
389 len = ptr - outbuf + 1;
391 switch(hello_stat)
393 case GBOX_STAT_HELLOL:
394 if(cfg.log_hello)
395 { cs_log("<- HelloL to %s", cli->reader->label); }
396 else
397 { cs_log_dbg(D_READER,"<- HelloL to %s", cli->reader->label); }
398 break;
400 case GBOX_STAT_HELLOS:
401 if(cfg.log_hello)
402 { cs_log("<- HelloS total cards %d to %s", nbcards, cli->reader->label); }
403 else
404 { cs_log_dbg(D_READER,"<- HelloS total cards %d to %s", nbcards, cli->reader->label); }
405 break;
407 case GBOX_STAT_HELLOR:
408 if(cfg.log_hello)
409 { cs_log("<- HelloR total cards %d to %s", nbcards, cli->reader->label); }
410 else
411 { cs_log_dbg(D_READER,"<- HelloR total cards %d to %s", nbcards, cli->reader->label); }
412 break;
414 default:
415 if(cfg.log_hello)
416 { cs_log("<- hello total cards %d to %s", nbcards, cli->reader->label); }
417 else
418 { cs_log_dbg(D_READER,"<- hello total cards %d to %s", nbcards, cli->reader->label); }
419 break;
421 cs_log_dump_dbg(D_READER, outbuf, len, "<- hello to %s, (len=%d):", cli->reader->label, len);
423 gbox_compress(outbuf, len, &len);
424 gbox_send(cli, outbuf, len);
427 void gbox_send_hello(struct s_client *proxy, uint8_t hello_stat)
429 if(!proxy)
431 cs_log("Invalid proxy try to call 'gbox_send_hello'");
432 return;
435 uint16_t nbcards = 0;
436 uint16_t nbcards_cnt = 0;
437 uint8_t packet;
438 uint8_t buf[2048];
439 packet = 0;
440 uint8_t *ptr = buf + 11;
442 if(gbox_count_cards() != 0 && hello_stat > GBOX_STAT_HELLOL)
444 struct gbox_peer *peer = proxy->gbox;
445 if(!peer || !peer->my_user || !peer->my_user->account)
447 cs_log("Invalid peer try to call 'gbox_send_hello'");
448 return;
451 memset(buf, 0, sizeof(buf));
452 struct gbox_card *card;
453 GBOX_CARDS_ITER *gci = gbox_cards_iter_create();
455 while((card = gbox_cards_iter_next(gci)))
457 //send to user only cards which matching CAID from account and lvl > 0
458 //and cccmaxhops from account
459 //do not send peer cards back
460 if(chk_ctab(gbox_get_caid(card->caprovid), &peer->my_user->account->ctab) && (card->lvl > 0) &&
461 #ifdef MODULE_CCCAM
462 (card->dist <= peer->my_user->account->cccmaxhops) &&
463 #endif
464 (!card->origin_peer || (card->origin_peer && card->origin_peer->gbox.id != peer->gbox.id)))
466 if(card->type == GBOX_CARD_TYPE_GBOX)
468 // cs_log_dbg(D_READER,"send to peer gbox-card %04X - level=%d crd-owner=%04X", card->caprovid >> 16, card->lvl, card->id.peer);
469 *(++ptr) = card->caprovid >> 24;
470 *(++ptr) = card->caprovid >> 16;
471 *(++ptr) = card->caprovid >> 8;
472 *(++ptr) = card->caprovid & 0xff;
473 *(++ptr) = 1; // note: original gbx is more efficient and sends all cards of one caid as package
474 *(++ptr) = card->id.slot;
475 *(++ptr) = ((card->lvl - 1) << 4) + card->dist + 1;
477 else if(card->type == GBOX_CARD_TYPE_CCCAM)
479 if(proxy->reader->gbox_cccam_reshare < 0)
480 { continue; }
481 else
483 if(proxy->reader->gbox_cccam_reshare > proxy->reader->gbox_reshare)
485 proxy->reader->gbox_cccam_reshare = proxy->reader->gbox_reshare;
487 // cs_log_dbg(D_READER,"send to peer %04X - ccc-card %04X - level=%d crd-owner=%04X", peer->gbox.id, card->caprovid >> 16, proxy->reader->gbox_cccam_reshare, card->id.peer);
488 *(++ptr) = card->caprovid >> 24;
489 *(++ptr) = card->caprovid >> 16;
490 *(++ptr) = card->caprovid >> 8;
491 *(++ptr) = card->caprovid & 0xff;
492 *(++ptr) = 1;
493 *(++ptr) = card->id.slot;
494 *(++ptr) = ((proxy->reader->gbox_cccam_reshare) << 4) + card->dist + 1;
497 else if(proxy->reader->gbox_reshare > 0)
499 //cs_log_dbg(D_READER,"send local crd %04X reshare=%d crd-owner=%04X", card->caprovid >> 16, proxy->reader->gbox_reshare, card->id.peer);
500 *(++ptr) = card->caprovid >> 24;
501 *(++ptr) = card->caprovid >> 16;
502 *(++ptr) = card->caprovid >> 8;
503 *(++ptr) = card->caprovid & 0xff;
504 *(++ptr) = 1;
505 *(++ptr) = card->id.slot;
506 *(++ptr) = ((proxy->reader->gbox_reshare - 1) << 4) + card->dist + 1;
508 else
510 cs_log_dbg(D_READER,"WARNING: local card %04X will NOT be shared - !reshare=%d! crd-owner=%04X", card->caprovid >> 16, proxy->reader->gbox_reshare, card->id.peer);
511 continue;
514 *(++ptr) = card->id.peer >> 8;
515 *(++ptr) = card->id.peer & 0xff;
516 nbcards++;
517 nbcards_cnt++;
519 if(nbcards_cnt == MAX_GBOX_CARDS )
521 cs_log("gbox_send_hello - max cards send to peer reached");
522 break;
525 if(nbcards == 100) // check if 100 is good or we need more sophisticated algorithm
527 gbox_send_hello_packet(proxy, packet, buf, ptr, nbcards, hello_stat);
528 packet++;
529 nbcards = 0;
530 ptr = buf + 11;
531 memset(buf, 0, sizeof(buf));
534 } // while cards exist
536 gbox_cards_iter_destroy(gci);
538 } // end if cards exists
540 gbox_send_hello_packet(proxy, 0x80 | packet, buf, ptr, nbcards, hello_stat); //last packet has bit 0x80 set
541 return;
544 void gbox_reconnect_peer(struct s_client *cl)
546 struct gbox_peer *peer = cl->gbox;
547 hostname2ip(cl->reader->device, &SIN_GET_ADDR(cl->udp_sa));
548 SIN_GET_FAMILY(cl->udp_sa) = AF_INET;
549 SIN_GET_PORT(cl->udp_sa) = htons((uint16_t)cl->reader->r_port);
550 hostname2ip(cl->reader->device, &(cl->ip));
551 gbox_reinit_proxy(cl);
552 cs_log("reconnect %s peer: %04X", username(cl), peer->gbox.id);
553 gbox_send_hello(cl, GBOX_STAT_HELLOL);
554 return;
557 void restart_gbox_peer(char *rdrlabel, uint8_t allrdr, uint16_t gbox_id)
559 struct s_client *cl;
560 cs_readlock(__func__, &clientlist_lock);
562 for(cl = first_client; cl; cl = cl->next)
564 if(cl->gbox && cl->typ == 'p' &&
565 ((rdrlabel && !strcmp(rdrlabel, cl->reader->label)) ||
566 allrdr || (gbox_id && cl->gbox_peer_id == gbox_id)))
567 { gbox_reconnect_peer(cl); }
569 cs_readunlock(__func__, &clientlist_lock);
572 static void *gbox_server(struct s_client *cli, uint8_t *UNUSED(b), int32_t l)
574 if(l > 0)
576 cs_log("gbox_server %s/%d", cli->reader->label, cli->port);
577 //gbox_check_header_recvd(cli, NULL, b, l);
579 return NULL;
582 char *gbox_username(struct s_client *client)
584 if(!client)
586 return "anonymous";
589 if(client->reader)
591 if(client->reader->r_usr[0])
593 return client->reader->r_usr;
596 return "anonymous";
599 static int8_t gbox_disconnect_double_peers(struct s_client *cli)
601 struct s_client *cl;
602 cs_writelock(__func__, &clientlist_lock);
604 for(cl = first_client; cl; cl = cl->next)
606 if(cl->typ == 'c' && cl->gbox_peer_id == cli->gbox_peer_id && cl != cli)
608 cl->reader = NULL;
609 cl->gbox = NULL;
610 cs_log_dbg(D_READER, "disconnected double client %s", username(cl));
611 //cs_log("disconnected double client %s - %s",username(cl), cs_inet_ntoa(cli->ip));
612 cs_disconnect_client(cl);
615 cs_writeunlock(__func__, &clientlist_lock);
616 return 0;
619 static int8_t gbox_auth_client(struct s_client *cli, uint32_t gbox_password)
621 if(!cli) { return -1; }
623 uint16_t gbox_id = gbox_convert_password_to_id(gbox_password);
624 struct s_client *cl = get_gbox_proxy(gbox_id);
626 if(cl->typ == 'p' && cl->gbox && cl->reader)
628 struct gbox_peer *peer = cl->gbox;
629 struct s_auth *account = get_account_by_name(gbox_username(cl));
631 if ((peer->gbox.password == gbox_password) && account)
633 cli->crypted = 1; // display as crypted
634 cli->gbox = cl->gbox; // point to the same gbox as proxy
635 cli->reader = cl->reader; // point to the same reader as proxy
636 cli->gbox_peer_id = cl->gbox_peer_id; // signal authenticated
637 gbox_disconnect_double_peers(cli);
638 cs_auth_client(cli, account, NULL);
639 cli->account = account;
640 cli->grp = account->grp;
641 cli->lastecm = time(NULL);
642 peer->my_user = cli;
643 return 0;
646 return -1;
649 static void gbox_server_init(struct s_client *cl)
651 cs_writelock(__func__, &clientlist_lock);
652 if(!cl->init_done)
654 if(IP_ISSET(cl->ip))
656 cs_log("new connection from %s", cs_inet_ntoa(cl->ip));
659 // We cannot authenticate here, because we don't know gbox pw
660 cl->gbox_peer_id = NO_GBOX_ID;
661 cl->init_done = 1;
663 start_sms_sender();
665 cs_writeunlock(__func__, &clientlist_lock);
666 return;
669 static uint16_t gbox_decode_cmd(uint8_t *buf)
671 return buf[0] << 8 | buf[1];
674 int8_t gbox_message_header(uint8_t *buf, uint16_t cmd, uint32_t peer_password, uint32_t local_password)
676 if (!buf) { return -1; }
677 i2b_buf(2, cmd, buf);
678 i2b_buf(4, peer_password, buf + 2);
679 if (cmd == MSG_CW) { return 0; }
680 i2b_buf(4, local_password, buf + 6);
681 return 0;
684 // returns number of cards in a hello packet or -1 in case of error
685 int16_t read_cards_from_hello(uint8_t *ptr, uint8_t *len, CAIDTAB *ctab, uint8_t maxdist, struct gbox_peer *peer)
687 uint8_t *current_ptr = 0;
688 uint32_t caprovid;
689 int16_t ncards_in_msg = 0;
691 while(ptr < len)
693 caprovid = ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
695 ncards_in_msg += ptr[4];
696 //caid check
697 if(chk_ctab(gbox_get_caid(caprovid), ctab))
699 current_ptr = ptr;
700 ptr += 5;
702 // for all cards of current caid/provid,
703 while (ptr < current_ptr + 5 + current_ptr[4] * 4)
705 if ((ptr[1] & 0xf) <= maxdist)
707 gbox_add_card(ptr[2] << 8 | ptr[3], caprovid, ptr[0], ptr[1] >> 4, ptr[1] & 0xf, GBOX_CARD_TYPE_GBOX, peer);
709 ptr += 4; // next card
710 } // end while cards for provider
712 else
714 ptr += 5 + ptr[4] * 4; // skip cards because caid
716 } // end while < len
717 return ncards_in_msg;
720 // returns 1 if checkcode changed / 0 if not
721 static int32_t gbox_checkcode_recv(struct s_client *cli, uint8_t *checkcode)
723 struct gbox_peer *peer = cli->gbox;
724 if(memcmp(peer->checkcode, checkcode, 7))
726 memcpy(peer->checkcode, checkcode, 7);
727 cs_log_dump_dbg(D_READER, checkcode, 7, "-> new checkcode from %s:", cli->reader->label);
728 return 1;
730 return 0;
733 static void disable_remm(struct s_client *cli)
735 if (cli->reader->blockemm & 0x80) // if remm marker bit set
737 struct gbox_peer *peer = cli->gbox;
738 cs_log("-> Disable REMM Req for %04X %s %s", peer->gbox.id, cli->reader->label, cli->reader->device);
739 cli->reader->gbox_remm_peer = 0;
740 cli->reader->blockemm = 15;
741 write_msg_info(cli, MSGID_REMM, 0, 0);
743 return;
746 static void gbox_revd_goodnight(struct s_client *cli)
748 cs_log("-> Good Night received from %s %s", cli->reader->label, cli->reader->device);
749 disable_remm(cli);
750 write_msg_info(cli, MSGID_GOODNIGHT, 0, 0);
751 gbox_reinit_proxy(cli);
752 return;
755 static void gbox_send_checkcode(struct s_client *cli)
757 struct gbox_peer *peer = cli->gbox;
758 uint8_t outbuf[20];
759 cs_log_dump_dbg(D_READER, gbox_get_my_checkcode(), 7, "<- my checkcode to %s:", cli->reader->label);
760 gbox_message_header(outbuf, MSG_CHECKCODE, peer->gbox.password, local_gbox.password);
761 memcpy(outbuf + 10, gbox_get_my_checkcode(), 7);
762 gbox_send(cli, outbuf, 17);
765 int32_t gbox_cmd_hello_rcvd(struct s_client *cli, uint8_t *data, int32_t n)
767 if (!cli || !cli->gbox || !cli->reader || !data) { return -1; }
769 struct gbox_peer *peer = cli->gbox;
770 int16_t cards_number = 0;
771 int32_t payload_len = n;
772 int32_t hostname_len = 0;
773 int32_t footer_len = 0;
774 uint8_t *ptr = 0;
776 if(!(gbox_decode_cmd(data) == MSG_HELLO1))
778 gbox_decompress(data, &payload_len);
779 cs_log_dump_dbg(D_READER, data, payload_len, "-> data decompressed (%d bytes):", payload_len);
780 ptr = data + 12;
782 else
784 ptr = data + 11;
785 cs_log_dump_dbg(D_READER, data, payload_len, "decrypted data (%d bytes):", payload_len);
788 if ((data[11] & 0xf) != peer->next_hello) // out of sync hellos
790 cs_log("-> out of sync hello from %s %s, expected: %02X, received: %02X",
791 username(cli), cli->reader->device, peer->next_hello, data[11] & 0xf);
793 peer->next_hello = 0;
794 gbox_send_hello(cli, GBOX_STAT_HELLOL);
795 return 0;
798 if (!(data[11] & 0xf)) // is first packet
800 gbox_delete_cards(GBOX_DELETE_FROM_PEER, peer->gbox.id);
801 hostname_len = data[payload_len - 1];
802 footer_len = hostname_len + 2 + 7;
804 if(!peer->hostname || memcmp(peer->hostname, data + payload_len - 1 - hostname_len, hostname_len))
806 NULLFREE(peer->hostname);
807 if(!cs_malloc(&peer->hostname, hostname_len + 1))
809 return -1;
811 memcpy(peer->hostname, data + payload_len - 1 - hostname_len, hostname_len);
812 peer->hostname[hostname_len] = '\0';
815 gbox_checkcode_recv(cli, data + payload_len - footer_len - 1);
816 peer->gbox.minor_version = data[payload_len - footer_len - 1 + 7];
817 peer->gbox.cpu_api = data[payload_len - footer_len + 7];
818 peer->total_cards = 0;
821 cs_log_dbg(D_READER, "-> Hello packet no. %d received from %s %s",
822 (data[11] & 0xF) + 1, username(cli), cli->reader->device);
824 // read cards from hello
825 cards_number = read_cards_from_hello(ptr, data + payload_len - footer_len - 1, &cli->reader->ctab, cli->reader->gbox_maxdist, peer);
827 if (cards_number < 0)
828 { return -1; }
829 else
830 { peer->total_cards += cards_number; }
832 if(data[11] & 0x80) // last packet
834 uint8_t tmpbuf[8];
835 memset(&tmpbuf[0], 0xff, 7);
837 if(data[10] == 0x01 && !memcmp(data + 12, tmpbuf, 7)) // good night message
839 gbox_revd_goodnight(cli);
841 else // last packet of Hello
843 peer->filtered_cards = gbox_count_peer_cards(peer->gbox.id);
845 if(!data[10])
847 memset(&tmpbuf[0], 0, 7);
848 if(data[11] == 0x80 && !memcmp(data + 12, tmpbuf, 7))
850 gbox_peer_online(peer, GBOX_PEER_ONLINE);
851 if(cfg.log_hello)
852 { cs_log("-> HelloL from %s (%s:%d) v2.%02X", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port, peer->gbox.minor_version);}
853 else
854 { cs_log_dbg(D_READER,"-> HelloL from %s (%s:%d) v2.%02X", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port, peer->gbox.minor_version);}
856 else
858 if(cfg.log_hello)
859 { cs_log("-> HelloS from %s (%s:%d) v2.%02X with %d cards", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port, peer->gbox.minor_version, peer->filtered_cards); }
860 else
861 { cs_log_dbg(D_READER,"-> HelloS in %d packets from %s (%s:%d) v2.%02X with %d cards filtered to %d cards", (data[0x0B] & 0x0f)+1, cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port, peer->gbox.minor_version, peer->total_cards, peer->filtered_cards); }
863 gbox_send_hello(cli, GBOX_STAT_HELLOR);
865 else
867 if (cfg.log_hello)
868 { cs_log("-> HelloR from %s (%s:%d) v2.%02X with %d cards", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port, peer->gbox.minor_version, peer->filtered_cards); }
869 else
870 { cs_log_dbg(D_READER,"-> HelloR in %d packets from %s (%s:%d) v2.%02X with %d cards filtered to %d cards", (data[0x0B] & 0x0f)+1, cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port, peer->gbox.minor_version, peer->total_cards, peer->filtered_cards);}
872 gbox_send_checkcode(cli);
874 if (cfg.log_hello)
875 { cs_log("<- HelloC my checkcode to %s (%s:%d)", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port);}
876 else
877 { cs_log_dbg(D_READER,"<- HelloC my checkcode to %s (%s:%d)", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port);}
880 if(!peer->online)
882 gbox_send_hello(cli, GBOX_STAT_HELLOS);
883 gbox_peer_online(peer, GBOX_PEER_ONLINE);
886 cli->reader->tcp_connected = CARD_INSERTED;
888 if(!peer->filtered_cards)
890 cli->reader->card_status = NO_CARD;
892 else
894 cli->reader->card_status = CARD_INSERTED;
898 peer->next_hello = 0;
899 gbox_write_peer_onl();
900 gbox_write_share_cards_info();
901 cli->last = time((time_t *)0); // hello is activity on proxy
903 else
905 peer->next_hello++;
908 return 0;
911 uint8_t get_peer_onl_status(uint16_t peer_id)
913 cs_readlock(__func__, &clientlist_lock);
914 struct s_client *cl;
915 for(cl = first_client; cl; cl = cl->next)
917 if(cl->gbox && cl->typ == 'p')
919 struct gbox_peer *peer = cl->gbox;
920 if((peer->gbox.id == peer_id) && peer->online)
922 cs_readunlock(__func__, &clientlist_lock);
923 return 1;
927 cs_readunlock(__func__, &clientlist_lock);
928 return 0;
931 static int8_t is_blocked_peer(uint16_t peer_id)
933 int i;
934 if (cfg.gbox_block_ecm_num > 0)
936 for (i = 0; i < cfg.gbox_block_ecm_num; i++)
938 if (cfg.gbox_block_ecm[i] == peer_id)
940 return 1;
944 return 0;
947 static int8_t check_peer_ignored(uint16_t peer_id)
949 int i;
950 if (cfg.gbox_ignored_peer_num > 0)
952 for (i = 0; i < cfg.gbox_ignored_peer_num; i++)
954 if (cfg.gbox_ignored_peer[i] == peer_id)
956 return 1;
960 return 0;
963 static int8_t validate_peerpass(uint32_t rcvd_peer_pw)
965 struct s_client *cli;
966 cs_readlock(__func__, &clientlist_lock);
968 for(cli = first_client; cli; cli = cli->next)
970 if(cli->gbox && cli->typ == 'p')
972 struct s_reader *rdr = cli->reader;
974 if (rcvd_peer_pw == a2i(rdr->r_pwd, 4))
976 cs_readunlock(__func__, &clientlist_lock);
977 return 1;
978 } // valid peerpass
981 cs_readunlock(__func__, &clientlist_lock);
982 return 0;
985 static int8_t gbox_incoming_ecm(struct s_client *cli, uint8_t *data, int32_t n)
987 if(!cli || !cli->gbox || !data || !cli->reader) { return -1; }
989 struct gbox_peer *peer;
990 struct s_client *cl;
991 int32_t diffcheck = 0;
993 peer = cli->gbox;
994 if (!peer || !peer->my_user)
996 return -1;
998 cl = peer->my_user;
1000 if(n < 21)
1002 return -1;
1005 // No ECMs with length < MIN_LENGTH expected
1006 if ((((data[19] & 0x0f) << 8) | data[20]) < MIN_ECM_LENGTH)
1008 return -1;
1011 // GBOX_MAX_HOPS not violated
1012 if (data[n - 15] + 1 > GBOX_MAXHOPS)
1014 cs_log("-> incoming ECM distance: %d > max ECM distance: %d", data[n - 15] + 1, GBOX_MAXHOPS);
1015 return -1;
1018 // ECM must not take more hops than allowed by gbox_reshare
1019 if (data[n - 15] + 1 > cli->reader->gbox_reshare)
1021 cs_log("-> incoming ECM dist: %d more than allowed from specified gbox_reshare: %d", data[n - 15] + 1, cli->reader->gbox_reshare);
1022 return -1;
1025 // Check for blocked peers
1026 uint16_t requesting_peer = data[(((data[19] & 0x0f) << 8) | data[20]) + 21] << 8 |
1027 data[(((data[19] & 0x0f) << 8) | data[20]) + 22];
1029 if (is_blocked_peer(requesting_peer))
1031 handle_attack(cli, GBOX_ATTACK_ECM_BLOCKED, requesting_peer);
1032 cs_log("ECM from peer %04X blocked by config", requesting_peer);
1033 return -1;
1036 ECM_REQUEST *er;
1037 if(!(er = get_ecmtask()))
1039 return -1;
1042 struct gbox_ecm_request_ext *ere;
1043 if(!cs_malloc(&ere, sizeof(struct gbox_ecm_request_ext)))
1045 NULLFREE(er);
1046 return -1;
1049 uint8_t *ecm = data + 18; // offset of ECM in gbx message
1051 er->src_data = ere;
1052 gbox_init_ecm_request_ext(ere);
1054 if(peer->ecm_idx == 100)
1056 peer->ecm_idx = 0;
1059 er->idx = peer->ecm_idx++;
1060 er->ecmlen = SCT_LEN(ecm);
1062 if(er->ecmlen < 3 || er->ecmlen > MAX_ECM_SIZE || er->ecmlen + 18 > n)
1064 NULLFREE(ere);
1065 NULLFREE(er);
1066 return -1;
1069 er->pid = b2i(2, data + 10);
1070 er->srvid = b2i(2, data + 12);
1072 if(ecm[er->ecmlen + 5] == 0x05)
1074 er->caid = (ecm[er->ecmlen + 5] << 8);
1076 else
1078 er->caid = b2i(2, ecm + er->ecmlen + 5);
1081 memcpy(er->ecm, data + 18, er->ecmlen);
1083 er->gbox_ecm_src_peer = b2i(2, ecm + er->ecmlen); //boxid which ORIGINALLY broadcasted the ECM
1084 ere->gbox_version = ecm[er->ecmlen + 2];
1085 ere->gbox_rev = ecm[er->ecmlen + 3];
1086 ere->gbox_type = ecm[er->ecmlen + 4];
1087 uint32_t caprovid = b2i(4, ecm + er->ecmlen + 5);
1088 er->gbox_cw_src_peer = b2i(2, ecm + er->ecmlen + 10); //boxid to send ECM to (cw source peer)
1089 ere->gbox_slot = ecm[er->ecmlen + 12];
1090 diffcheck = gbox_checkcode_recv(cl, data + n - 14);
1091 //TODO: What do we do with our own checkcode @-7?
1092 er->gbox_crc = gbox_get_checksum(&er->ecm[0], er->ecmlen);
1093 er->gbox_ecm_dist = data[n - 15] + 1;
1095 memcpy(&ere->gbox_routing_info[0], &data[n - 15 - er->gbox_ecm_dist + 1], er->gbox_ecm_dist - 1);
1097 er->caid = gbox_get_caid(caprovid);
1098 er->prid = gbox_get_provid(caprovid);
1100 peer->gbox_rev = ecm[er->ecmlen + 3];
1102 cs_log_dbg(D_READER,"-> ECM (->%d) - ecm-requesting-peer: %04X - cw_src_peer: %04X caid: %04X sid: %04X from_peer: %04X rev: %01X.%01X (%s:%d)",
1103 er->gbox_ecm_dist, er->gbox_ecm_src_peer, er->gbox_cw_src_peer, er->caid, er->srvid, peer->gbox.id, peer->gbox_rev >> 4,
1104 peer->gbox_rev & 0xf, peer->hostname, cli->port);
1106 get_cw(cl, er);
1108 // checkcode did not match gbox->peer checkcode
1109 if(diffcheck)
1111 // TODO: Send HelloS here?
1112 //gbox->peer.hello_stat = GBOX_STAT_HELLOS;
1113 //gbox_send_hello(cli);
1115 return 0;
1118 static uint32_t gbox_get_pending_time(ECM_REQUEST *er, uint16_t peer_id, uint8_t slot)
1120 if(!er)
1122 return 0;
1125 uint32_t ret_time = 0;
1126 struct gbox_card_pending *pending = NULL;
1127 LL_LOCKITER *li = ll_li_create(er->gbox_cards_pending, 0);
1129 while((pending = ll_li_next(li)))
1131 if ((pending->id.peer == peer_id) && (pending->id.slot == slot))
1133 ret_time = pending->pending_time;
1134 er->gbox_cw_src_peer = peer_id;
1135 break;
1138 ll_li_destroy(li);
1139 return ret_time;
1142 static int32_t gbox_chk_recvd_dcw(struct s_client *cli, uint8_t *dcw, int32_t *rc, uint8_t *data, int32_t n)
1144 if(!cli || gbox_decode_cmd(data) != MSG_CW || n < 44)
1146 return -1;
1149 int i;
1150 uint16_t id_card = 0;
1151 struct s_client *proxy;
1153 if(cli->typ != 'p')
1155 proxy = get_gbox_proxy(cli->gbox_peer_id);
1157 else
1159 proxy = cli;
1162 if (!proxy || !proxy->reader)
1164 cs_log("error, gbox_chk_recvd_dcw, proxy not found");
1165 gbox_send_goodbye(cli);
1166 return -1;
1169 proxy->last = time((time_t *)0);
1170 *rc = 1;
1171 memcpy(dcw, data + 14, 16);
1172 uint32_t crc = b2i(4, data + 30);
1173 char tmp[33];
1174 cs_log_dbg(D_READER,"-> CW (->%d) received cw: %s from CW-source-peer=%04X, caid=%04X, slot= %d, ecm_pid=%04X, sid=%04X, crc=%08X, cw-src-type=%d, cw-dist=%d, hw-type=%d, rev=%01X.%01X, chid=%04X", data[42] & 0x0f,
1175 cs_hexdump(0, dcw, 16, tmp, sizeof(tmp)), data[10] << 8 | data[11], data[34] << 8 | data[35], data[36], data[6] << 8 | data[7],
1176 data[8] << 8 | data[9], crc, data[41], data[42] & 0x0f, data[42] >> 4, data[43] >> 4,
1177 data[43] & 0x0f, data[37] << 8 | data[38]);
1179 struct timeb t_now;
1180 cs_ftime(&t_now);
1181 int64_t cw_time = GBOX_DEFAULT_CW_TIME;
1183 for(i = 0; i < cfg.max_pending; i++)
1185 if(proxy->ecmtask[i].gbox_crc == crc)
1187 id_card = b2i(2, data + 10);
1188 cw_time = comp_timeb(&t_now, &proxy->ecmtask[i].tps) - gbox_get_pending_time(&proxy->ecmtask[i], id_card, data[36]);
1189 gbox_add_good_sid(id_card, proxy->ecmtask[i].caid, data[36], proxy->ecmtask[i].srvid, cw_time);
1190 gbox_remove_all_bad_sids(&proxy->ecmtask[i], proxy->ecmtask[i].srvid);
1192 if(proxy->ecmtask[i].gbox_ecm_status == GBOX_ECM_NEW_REQ || proxy->ecmtask[i].gbox_ecm_status == GBOX_ECM_ANSWERED)
1194 return -1;
1197 proxy->ecmtask[i].gbox_ecm_status = GBOX_ECM_ANSWERED;
1198 proxy->ecmtask[i].gbox_cw_src_peer = id_card;
1199 proxy->reader->currenthops = gbox_get_crd_dist_lev(id_card) & 0xf;
1200 proxy->reader->gbox_cw_src_peer = id_card;
1201 proxy->reader->gbox_crd_slot_lev = (data[36] << 4) | ((gbox_get_crd_dist_lev(id_card) >> 4) & 0xf);
1202 *rc = 1;
1203 return proxy->ecmtask[i].idx;
1207 // late answers from other peers,timing not possible
1208 gbox_add_good_sid(id_card, data[34] << 8 | data[35], data[36], data[8] << 8 | data[9], GBOX_DEFAULT_CW_TIME);
1209 cs_log_dbg(D_READER, "no task found for crc=%08x", crc);
1211 return -1;
1214 static int8_t gbox_received_dcw(struct s_client *cli, uint8_t *data, int32_t n)
1216 int32_t rc = 0, i = 0, idx = 0;
1217 uint8_t dcw[16];
1219 idx = gbox_chk_recvd_dcw(cli, dcw, &rc, data, n);
1221 if(idx < 0) // no dcw received
1223 return -1;
1226 if(!idx)
1228 idx = cli->last_idx;
1231 cli->reader->last_g = time((time_t *)0); // for reconnect timeout
1233 for(i = 0; i < cfg.max_pending; i++)
1235 if(cli->ecmtask[i].idx == idx)
1237 cli->pending--;
1238 casc_check_dcw(cli->reader, i, rc, dcw);
1239 return 0;
1242 return -1;
1245 int32_t gbox_recv_cmd_switch(struct s_client *proxy, uint8_t *data, int32_t n)
1247 if (!data || !proxy)
1249 return -1;
1252 uint16_t cmd = gbox_decode_cmd(data);
1253 switch(cmd)
1255 case MSG_HERE:
1256 cs_log("-> HERE? from %s %s",username(proxy), proxy->reader->device);
1257 gbox_send_hello(proxy, GBOX_STAT_HELLOR);
1258 break;
1260 case MSG_GOODBYE:
1261 cs_log("-> goodbye message from %s %s",username(proxy), proxy->reader->device);
1262 //msg goodbye is an indication from peer that requested ECM failed (not found/rejected...)
1263 //TODO: implement on suitable place - rebroadcast ECM to other peers
1264 write_msg_info(proxy, MSGID_GOODBYE, 0, 0);
1265 break;
1267 case MSG_GSMS:
1268 if(!cfg.gsms_dis)
1270 cs_log("-> MSG_GSMS from %s %s", username(proxy), proxy->reader->device);
1271 gbox_send_gsms_ack(proxy);
1272 write_gsms_msg(proxy, data +16, data[14], data[15]);
1273 write_msg_info(proxy, MSGID_GSMS, 0, data[14]);
1275 else
1277 gsms_unavail();
1279 break;
1281 case MSG_GSMS_ACK:
1282 if(!cfg.gsms_dis)
1284 cs_log("-> MSG_GSMS_ACK from %s %s", username(proxy), proxy->reader->device);
1285 write_gsms_ack(proxy);
1287 else
1289 gsms_unavail();
1291 break;
1293 case MSG_HELLO1:
1294 case MSG_HELLO:
1295 if(gbox_cmd_hello_rcvd(proxy, data, n) < 0)
1297 return -1;
1299 break;
1301 case MSG_CW:
1302 gbox_received_dcw(proxy, data, n);
1303 break;
1305 case MSG_CHECKCODE:
1306 gbox_checkcode_recv(proxy, data + 10);
1307 if (cfg.log_hello)
1309 cs_log("-> HelloC checkcode from %s - %s", username(proxy), proxy->reader->device);
1311 else
1313 cs_log_dbg(D_READER,"-> HelloC checkcode from %s - %s", username(proxy), proxy->reader->device);
1315 break;
1317 case MSG_ECM:
1318 gbox_incoming_ecm(proxy, data, n);
1319 break;
1321 case MSG_REM_EMM:
1322 //cs_log_dbg(D_EMM,"-> Incoming REMM MSG (%d bytes) from %s - %s", n, username(proxy), proxy->reader->device);
1323 cs_log_dump_dbg(D_EMM, data, n, "-> gbox incoming REMM MSG - (len=%d bytes):", n);
1324 gbox_recvd_remm_cmd_switch(proxy, data, n);
1325 break;
1327 default:
1328 cs_log("-> unknown command %04X received from %s %s",
1329 cmd, username(proxy), proxy->reader->device);
1331 write_msg_info(proxy, MSGID_UNKNOWNMSG, 0, 0);
1333 cs_log_dump_dbg(D_READER, data, n, "unknown data (%d bytes) received from %s %s",
1334 n, username(proxy), proxy->reader->device);
1335 } // end switch
1337 if((time(NULL) - last_stats_written) > STATS_WRITE_TIME)
1339 gbox_write_stats();
1340 last_stats_written = time(NULL);
1342 return 0;
1345 static void add_betatunnel_card(uint16_t caid, uint8_t slot)
1347 int32_t i;
1348 struct s_client *cli;
1349 cs_readlock(__func__, &clientlist_lock);
1351 for(cli = first_client; cli; cli = cli->next)
1353 TUNTAB *ttab;
1354 ttab = &cli->ttab;
1356 for(i = 0; i < ttab->ttnum; i++)
1358 // Check for Betatunnel on gbox account in oscam.user
1359 if(cli->gbox && ttab->ttdata && caid == ttab->ttdata[i].bt_caidto)
1361 gbox_add_card(local_gbox.id, gbox_get_caprovid(ttab->ttdata[i].bt_caidfrom, i), slot, DEFAULT_GBOX_RESHARE, 0, GBOX_CARD_TYPE_BETUN, NULL);
1362 cs_log_dbg(D_READER, "gbox created betatunnel card for caid: %04X->%04X",
1363 ttab->ttdata[i].bt_caidfrom, caid);
1368 cs_readunlock(__func__, &clientlist_lock);
1369 return;
1372 static uint8_t gbox_add_local_cards(void)
1374 int32_t i;
1375 uint32_t prid = 0;
1376 uint8_t slot = 0;
1377 #ifdef MODULE_CCCAM
1378 LL_ITER it, it2;
1379 struct cc_card *card = NULL;
1380 struct cc_data *cc;
1381 uint32_t checksum = 0;
1382 uint16_t cc_peer_id = 0;
1383 struct cc_provider *provider;
1384 uint8_t *node1 = NULL;
1386 gbox_delete_cards(GBOX_DELETE_WITH_TYPE, GBOX_CARD_TYPE_CCCAM);
1387 #endif
1388 gbox_delete_cards(GBOX_DELETE_WITH_ID, local_gbox.id);
1389 struct s_client *cl;
1391 cs_readlock(__func__, &clientlist_lock);
1392 for(cl = first_client; cl; cl = cl->next)
1394 if(cl->typ == 'r' && cl->reader && cl->reader->card_status == CARD_INSERTED)
1396 slot = gbox_next_free_slot(local_gbox.id);
1398 // SECA, Viaccess and Cryptoworks have multiple providers
1399 if(caid_is_seca(cl->reader->caid) || caid_is_cryptoworks(cl->reader->caid))
1401 for(i = 0; i < cl->reader->nprov; i++)
1403 prid = cl->reader->prid[i][1] << 16 | cl->reader->prid[i][2] << 8 | cl->reader->prid[i][3];
1404 gbox_add_card(local_gbox.id, gbox_get_caprovid(cl->reader->caid, prid), slot, DEFAULT_GBOX_RESHARE, 0, GBOX_CARD_TYPE_LOCAL, NULL);
1407 else if(caid_is_viaccess(cl->reader->caid)) //skip via issuer
1409 for(i = 1; i < cl->reader->nprov; i++)
1411 prid = cl->reader->prid[i][1] << 16 | cl->reader->prid[i][2] << 8 | cl->reader->prid[i][3];
1412 gbox_add_card(local_gbox.id, gbox_get_caprovid(cl->reader->caid, prid), slot, DEFAULT_GBOX_RESHARE, 0, GBOX_CARD_TYPE_LOCAL, NULL);
1415 else
1417 gbox_add_card(local_gbox.id, gbox_get_caprovid(cl->reader->caid, 0), slot, DEFAULT_GBOX_RESHARE, 0, GBOX_CARD_TYPE_LOCAL, NULL);
1419 if (chk_is_betatunnel_caid(cl->reader->caid) == 1 ) // 1702 1722
1420 { add_betatunnel_card(cl->reader->caid, gbox_next_free_slot(local_gbox.id)); }
1422 } // end local readers
1424 #ifdef MODULE_CCCAM
1425 if((cfg.cc_gbx_reshare_en) && (cfg.cc_reshare > -1) && cl->typ == 'p' && cl->reader && cl->reader->typ == R_CCCAM && cl->cc)
1427 cc = cl->cc;
1428 it = ll_iter_create(cc->cards);
1430 while((card = ll_iter_next(&it)))
1432 if((chk_ctab_ex(card->caid, &cfg.ccc_gbx_check_caidtab)))
1434 // calculate gbox id from cc node
1435 node1 = ll_has_elements(card->remote_nodes);
1436 checksum = ((node1[0] ^ node1[7]) << 8) | ((node1[1] ^ node1[6]) << 24) | (node1[2] ^ node1[5]) | ((node1[3] ^ node1[4]) << 16);
1437 cc_peer_id = ((((checksum >> 24) & 0xFF) ^ ((checksum >> 8) & 0xFF)) << 8 | (((checksum >> 16) & 0xFF) ^ (checksum & 0xFF)));
1439 slot = gbox_next_free_slot(cc_peer_id);
1441 if(caid_is_seca(card->caid) || caid_is_viaccess(card->caid) || caid_is_cryptoworks(card->caid))
1443 it2 = ll_iter_create(card->providers);
1444 while((provider = ll_iter_next(&it2)))
1446 gbox_add_card(cc_peer_id, gbox_get_caprovid(card->caid, provider->prov), slot, DEFAULT_CCC_GBOX_RESHARE, card->hop, GBOX_CARD_TYPE_CCCAM, NULL);
1449 else
1451 gbox_add_card(cc_peer_id, gbox_get_caprovid(card->caid, 0), slot, DEFAULT_CCC_GBOX_RESHARE, card->hop, GBOX_CARD_TYPE_CCCAM, NULL);
1455 } // end cccam
1456 #endif
1457 } // end for clients
1459 cs_readunlock(__func__, &clientlist_lock);
1461 if (cfg.gbox_proxy_cards_num > 0)
1463 for (i = 0; i < cfg.gbox_proxy_cards_num; i++)
1465 slot = gbox_next_free_slot(local_gbox.id);
1466 gbox_add_card(local_gbox.id, cfg.gbox_proxy_card[i], slot, DEFAULT_GBOX_RESHARE, 0, GBOX_CARD_TYPE_PROXY, NULL);
1467 cs_log_dbg(D_READER,"add proxy card: slot %d %04X:%06X", slot, gbox_get_caid(cfg.gbox_proxy_card[i]), gbox_get_provid(cfg.gbox_proxy_card[i]));
1471 gbox_write_local_cards_info();
1472 return slot;
1475 static void gbox_send_peer_crd_update(void)
1477 struct s_client *cl;
1478 cs_readlock(__func__, &clientlist_lock);
1480 for (cl = first_client; cl; cl = cl->next)
1482 if(cl->gbox && cl->typ == 'p' && !check_peer_ignored(cl->gbox_peer_id))
1484 struct gbox_peer *peer = cl->gbox;
1485 if (peer->online)
1487 gbox_send_hello(cl, GBOX_STAT_HELLOS);
1491 cs_readunlock(__func__, &clientlist_lock);
1492 return;
1495 void gbx_local_card_stat(uint8_t crdstat, uint16_t caid)
1497 if(crdstat && local_cards_initialized)
1499 if(crdstat == LOCALCARDEJECTED)
1501 cs_sleepms(100);
1504 if(crdstat == LOCALCARDUP)
1506 cs_sleepms(2000);
1507 cs_log("New local card ready - caid = %04X", caid);
1510 cs_log("Local cards update send to peer(s) online -> crd(s):%d", gbox_add_local_cards());
1511 gbox_write_local_cards_info();
1512 gbox_send_peer_crd_update();
1514 return;
1517 // returns -1 in case of error, 1 if authentication was performed, 0 else
1518 static int8_t gbox_check_header_recvd(struct s_client *cli, struct s_client *proxy, uint8_t *data, int32_t l)
1520 struct gbox_peer *peer = NULL;
1521 if (proxy) { peer = proxy->gbox; }
1523 char tmp[0x50];
1524 int32_t n = l;
1525 uint8_t authentication_done = 0;
1526 uint16_t peer_recvd_id = 0;
1527 uint32_t my_received_pw = 0;
1528 uint32_t peer_received_pw = 0;
1530 cs_log_dump_dbg(D_READER, data, n, "-> encrypted data (%d bytes) from %s:", n, cs_inet_ntoa(cli->ip));
1531 gbox_decrypt(data, n, local_gbox.password);
1532 cs_log_dump_dbg(D_READER, data, n, "-> decrypted data (%d bytes) from %s:", n, cs_inet_ntoa(cli->ip));
1534 // verify my pass received
1535 my_received_pw = b2i(4, data + 2);
1536 if (my_received_pw == local_gbox.password)
1538 if (gbox_decode_cmd(data) != MSG_CW)
1540 peer_received_pw = b2i(4, data + 6);
1541 peer_recvd_id = gbox_convert_password_to_id(peer_received_pw);
1543 //cs_log_dbg(D_READER, "-> data from IP: %s", cs_inet_ntoa(cli->ip));
1544 cs_log_dbg(D_READER, "-> data from peer: %04X data: %s", peer_recvd_id, cs_hexdump(0, data, l, tmp, sizeof(tmp)));
1545 //cs_log_dbg(D_READER,"my_received pw: %08X - peer_recvd pw: %08X - peer_recvd_id: %04X ", my_received_pw, peer_received_pw, peer_recvd_id);
1547 if (check_peer_ignored(peer_recvd_id))
1549 handle_attack(cli, GBOX_ATTACK_PEER_IGNORE, peer_recvd_id);
1550 cs_log("Peer blocked by conf - ignoring gbox peer_id: %04X", peer_recvd_id);
1551 return -1;
1554 if (!validate_peerpass(peer_received_pw))
1556 handle_attack(cli, GBOX_ATTACK_PEER_PW, peer_recvd_id);
1557 cs_log("peer: %04X - peerpass: %08X unknown -> check oscam.server->[reader]->password",
1558 peer_recvd_id, peer_received_pw);
1560 return -1;
1563 if (cli->gbox_peer_id == NO_GBOX_ID)
1565 if (gbox_auth_client(cli, peer_received_pw) < 0)
1567 handle_attack(cli, GBOX_ATTACK_AUTH_FAIL, peer_recvd_id);
1568 cs_log ("Peer %04X:%s authentication failed. Check user in [account] or {reader] section",
1569 peer_recvd_id, cs_inet_ntoa(cli->ip));
1571 return -1;
1574 authentication_done = 1;
1575 proxy = get_gbox_proxy(cli->gbox_peer_id);
1577 if (!local_cards_initialized)
1579 local_cards_initialized = 1;
1580 //gbox_add_local_cards();
1581 cs_log("Local cards initialized - cards: %d", gbox_add_local_cards());
1583 peer = proxy->gbox;
1586 if (!peer)
1588 return -1;
1591 if (peer_received_pw != peer->gbox.password)
1593 cs_log("gbox peer: %04X sends wrong own password", peer->gbox.id);
1594 return -1;
1597 else // is MSG_CW
1599 cs_log_dbg(D_READER, "-> CW data from peer: %04X data: %s",
1600 cli->gbox_peer_id, cs_hexdump(0, data, l, tmp, sizeof(tmp)));
1602 if((data[39] != ((local_gbox.id >> 8) & 0xff)) || (data[40] != (local_gbox.id & 0xff)))
1604 cs_log_dbg(D_READER,"peer: %04X sends CW not to my id: %04X -> forwarding CW to requesting peer %02X%02X ", cli->gbox_peer_id, local_gbox.id, data[39], data[40]);
1608 else // error my passw
1610 cs_log("-> ATTACK ALERT from IP %s - peer sends wrong local password: %08X", cs_inet_ntoa(cli->ip), my_received_pw);
1611 cs_log_dbg(D_READER,"-> received data: %s", cs_hexdump(0, data, n, tmp, sizeof(tmp)));
1612 handle_attack(cli, GBOX_ATTACK_LOCAL_PW, 0);
1613 return -1;
1616 if(!proxy)
1618 return -1;
1621 if(!IP_EQUAL(cli->ip, proxy->ip))
1623 cs_log("IP change received - peer %04X. Previous IP = %s. Reconnecting...", cli->gbox_peer_id, cs_inet_ntoa(proxy->ip));
1624 restart_gbox_peer(NULL, 0, cli->gbox_peer_id);
1625 write_msg_info(cli, MSGID_IPCHANGE, 0, 0);
1626 return -1;
1629 if(!peer)
1631 return -1;
1634 if(!peer->authstat)
1636 peer->authstat = 1;
1637 cs_log("peer %04X authenticated successfully", cli->gbox_peer_id);
1639 return authentication_done;
1642 static int32_t gbox_recv(struct s_client *cli, uint8_t *buf, int32_t l)
1644 uint8_t data[RECEIVE_BUFFER_SIZE];
1645 int32_t n = l, tmp;
1646 int8_t ret = 0;
1648 if(!cli->udp_fd || !cli->is_udp || cli->typ != 'c')
1650 return -1;
1653 n = recv_from_udpipe(buf);
1654 if (n < MIN_GBOX_MESSAGE_LENGTH || n >= RECEIVE_BUFFER_SIZE) // protect against too short or too long messages
1656 return -1;
1659 struct s_client *proxy = get_gbox_proxy(cli->gbox_peer_id);
1661 memcpy(&data[0], buf, n);
1663 ret = gbox_check_header_recvd(cli, proxy, &data[0], n);
1664 if (ret < 0)
1666 return -1;
1669 // in case of new authentication the proxy gbox can now be found
1670 if (ret)
1672 proxy = get_gbox_proxy(cli->gbox_peer_id);
1675 if (!proxy)
1677 return -1;
1680 cli->last = time((time_t *)0);
1681 // clients may timeout - attach to peer's gbox/reader
1682 cli->gbox = proxy->gbox; // point to the same gbox as proxy
1683 cli->reader = proxy->reader; // point to the same reader as proxy
1684 struct gbox_peer *peer = proxy->gbox;
1685 cs_writelock(__func__, &peer->lock);
1686 tmp = gbox_recv_cmd_switch(proxy, data, n);
1687 cs_writeunlock(__func__, &peer->lock);
1689 if(tmp < 0)
1691 return -1;
1694 return 0;
1697 static uint8_t check_setup( void)
1699 #ifdef HAVE_DVBAPI
1700 if (module_dvbapi_enabled())
1701 { return 0x30; } //stb
1702 else
1703 { return 0x50; }
1704 #else
1705 return 0x50; //server
1706 #endif
1709 static void gbox_send_dcw(struct s_client *cl, ECM_REQUEST *er)
1711 if (!cl || !er)
1713 return;
1716 struct s_client *cli = get_gbox_proxy(cl->gbox_peer_id);
1717 if (!cli || !cli->gbox)
1719 return;
1721 struct gbox_peer *peer = cli->gbox;
1723 struct gbox_ecm_request_ext *ere = er->src_data;
1725 if(er->rc == E_NOTFOUND && cli->reader->gbox_force_remm && ere->gbox_rev >> 4)
1727 gbox_send_remm_req(cli, er);
1728 return;
1731 if(er->rc >= E_NOTFOUND)
1733 cs_log_dbg(D_READER, "unable to decode!");
1734 gbox_send_goodbye(cli);
1735 return;
1738 uint8_t buf[60];
1739 memset(buf, 0, sizeof(buf));
1741 gbox_message_header(buf, MSG_CW , peer->gbox.password, 0);
1742 i2b_buf(2, er->pid, buf + 6); // PID
1743 i2b_buf(2, er->srvid, buf + 8); // SrvID
1744 i2b_buf(2, er->gbox_cw_src_peer, buf + 10); // From peer - source of cw
1745 buf[12] = (ere->gbox_slot << 4) | (er->ecm[0] & 0x0f); // slot << 4 | even/odd
1746 buf[13] = er->caid >> 8; // CAID first byte
1747 memcpy(buf + 14, er->cw, 16); // CW
1748 i2b_buf(4, er->gbox_crc, buf + 30); // CRC
1749 i2b_buf(2, er->caid, buf + 34); // CAID
1750 buf[36] = ere->gbox_slot; // Slot
1752 if (buf[34] == 0x06) // if irdeto
1754 i2b_buf(2, er->chid, buf + 37); // CHID
1756 else
1758 if (local_gbox.minor_version == 0x2A)
1760 buf[37] = 0xff; // gbox.net sends 0xff
1761 buf[38] = 0xff; // gbox.net sends 0xff
1763 else
1765 buf[37] = 0; // gbox sends 0
1766 buf[38] = 0; // gbox sends 0
1770 i2b_buf(2, er->gbox_ecm_src_peer, buf + 39); // Target peer to recv cw
1772 if(er->rc == E_CACHE1 || er->rc == E_CACHE2 || er->rc == E_CACHEEX)
1773 { buf[41] = 0x03; } // source of cw -> cache
1774 else
1775 { buf[41] = 0x01; } // source of cw -> card, emu
1777 uint8_t cw_dist = gbox_get_crd_dist_lev(er->gbox_cw_src_peer) & 0xf;
1779 buf[42] = ((check_setup()) | (cw_dist + 1));
1780 buf[43] = ere->gbox_rev & 0xf0;
1782 // This copies the routing info from ECM to cw answer.
1783 memcpy(&buf[44], &ere->gbox_routing_info, er->gbox_ecm_dist - 1);
1784 buf[44 + er->gbox_ecm_dist - 1] = er->gbox_ecm_dist - 1; //act. dist
1786 uint8_t i;
1787 for(i = 0; i < er->gbox_ecm_dist; i++)
1789 buf[44 +i] = i;
1792 gbox_send(cli, buf, 44 + er->gbox_ecm_dist);
1795 char tmp[0x50];
1796 cs_log("sending dcw to peer : %04x data: %s", er->gbox_ecm_src_peer, cs_hexdump(0, buf, er->gbox_ecm_dist + 44, tmp, sizeof(tmp)));
1799 if(ere->gbox_rev >> 4)
1800 { gbox_send_remm_req(cli, er); }
1802 cs_log_dbg(D_READER,"<- CW (<-%d) caid; %04X from cw-source-peer: %04X forward to ecm-requesting-peer: %04X - forwarding peer: %04X %s rev:%01X.%01X port:%d",
1803 er->gbox_ecm_dist, er->caid, er->gbox_cw_src_peer, er->gbox_ecm_src_peer, peer->gbox.id, cli->reader->label,
1804 ere->gbox_rev >> 4, ere->gbox_rev & 0xf, cli->port);
1807 static int32_t gbox_send_ecm(struct s_client *cli, ECM_REQUEST *er)
1809 if(!cli || !cli->reader || !er || !er->ecmlen)
1811 return -1;
1814 if(!cli->gbox || !cli->reader->tcp_connected)
1816 cs_log_dbg(D_READER, "%s server not init!", cli->reader->label);
1817 write_ecm_answer(cli->reader, er, E_NOTFOUND, 0x27, NULL, NULL, 0, NULL);
1818 return -1;
1821 struct gbox_peer *peer = cli->gbox;
1823 if(!peer->filtered_cards)
1825 cs_log_dbg(D_READER, "Send ECM failed, %s NO CARDS!", cli->reader->label);
1826 write_ecm_answer(cli->reader, er, E_NOTFOUND, E2_CCCAM_NOCARD, NULL, NULL, 0, NULL);
1827 return -1;
1830 if(!peer->online)
1832 cs_log_dbg(D_READER, "Send ECM failed, peer is OFFLINE!");
1833 write_ecm_answer(cli->reader, er, E_NOTFOUND, 0x27, NULL, NULL, 0, NULL);
1834 //gbox_send_hello(cli,0);
1835 return -1;
1838 if(er->gbox_ecm_status == GBOX_ECM_ANSWERED)
1840 cs_log_dbg(D_READER, "%s replied to this ecm already", cli->reader->label);
1843 if(er->gbox_ecm_status == GBOX_ECM_NEW_REQ)
1845 er->gbox_cards_pending = ll_create("pending_gbox_cards");
1848 uint8_t send_buf[1024];
1849 int32_t buflen, len1;
1851 len1 = er->ecmlen + 18; // length till end of ECM
1853 er->gbox_crc = gbox_get_checksum(&er->ecm[0], er->ecmlen);
1855 memset(send_buf, 0, sizeof(send_buf));
1857 uint8_t nb_matching_crds = 0;
1858 uint32_t current_avg_card_time = 0;
1860 gbox_message_header(send_buf, MSG_ECM , peer->gbox.password, local_gbox.password);
1861 i2b_buf(2, er->pid, send_buf + 10);
1862 i2b_buf(2, er->srvid, send_buf + 12);
1863 send_buf[14] = 0x00;
1864 send_buf[15] = 0x00;
1865 send_buf[17] = 0x00;
1866 memcpy(send_buf + 18, er->ecm, er->ecmlen);
1868 if(!er->gbox_ecm_dist)
1870 er->gbox_ecm_src_peer = local_gbox.id;
1871 i2b_buf(2, local_gbox.id, send_buf + len1); //local boxid first broadcasted the ECM
1872 send_buf[len1 + 3] = 0x4;
1874 else
1876 i2b_buf(2, er->gbox_ecm_src_peer, send_buf + len1); //forward boxid that originally broadcasted the ECM
1877 send_buf[len1 + 3] = 0;
1880 send_buf[len1 + 2] = cfg.gbox_my_vers;
1882 if(check_valid_remm_peer( peer->gbox.id))
1884 send_buf[len1 + 3] = local_gbx_rev;
1887 send_buf[len1 + 4] = gbox_get_my_cpu_api();
1889 uint32_t caprovid = gbox_get_caprovid(er->caid, er->prid);
1890 i2b_buf(4, caprovid, send_buf + len1 + 5);
1892 send_buf[len1 + 9] = 0x00;
1893 buflen = len1 + 10;
1895 //TODO: set requested number of cards according to er->stage, max for fallback=4
1896 nb_matching_crds = gbox_get_cards_for_ecm(&send_buf[0], len1 + 10, cli->reader->gbox_maxecmsend, er, &current_avg_card_time, peer->gbox.id, cli->reader->gbox_force_remm);
1898 buflen += nb_matching_crds * 3;
1900 if(!nb_matching_crds && er->gbox_ecm_status == GBOX_ECM_NEW_REQ)
1902 cs_log_dbg(D_READER, "no valid card found for CAID: %04X PROV: %06X", er->caid, er->prid);
1903 write_ecm_answer(cli->reader, er, E_NOTFOUND, E2_CCCAM_NOCARD, NULL, NULL, 0, NULL);
1904 return -1;
1907 if(nb_matching_crds)
1909 send_buf[16] = nb_matching_crds; // Number of cards the ECM should be forwarded to
1911 // distance ECM
1912 uint8_t i;
1913 for(i = 0; i < er->gbox_ecm_dist + 1; i++)
1915 send_buf[buflen] = i;
1916 buflen++;
1919 memcpy(&send_buf[buflen], gbox_get_my_checkcode(), 7);
1920 buflen = buflen + 7;
1921 memcpy(&send_buf[buflen], peer->checkcode, 7);
1922 buflen = buflen + 7;
1924 struct gbox_card_pending *pending = NULL;
1925 struct timeb t_now;
1926 cs_ftime(&t_now);
1928 for (i = 0; i < nb_matching_crds; i++)
1930 if(!cs_malloc(&pending, sizeof(struct gbox_card_pending)))
1932 cs_log("Can't allocate gbox card pending");
1933 return -1;
1935 pending->id.peer = (send_buf[len1+10+i*3] << 8) | send_buf[len1+11+i*3];
1936 pending->id.slot = send_buf[len1+12+i*3];
1937 pending->pending_time = comp_timeb(&t_now, &er->tps);
1939 ll_append(er->gbox_cards_pending, pending);
1940 cs_log_dbg(D_READER, "matching gbox card(s): %d, ID: %04X, Slot: %02X",
1941 i + 1, (send_buf[len1 + 10 + i * 3] << 8) | send_buf[len1 + 11 + i * 3], send_buf[len1 + 12 + i * 3]);
1944 LL_LOCKITER *li = ll_li_create(er->gbox_cards_pending, 0);
1945 while ((pending = ll_li_next(li)))
1947 cs_log_dbg(D_READER, "Pending Card ID: %04X Slot: %02X time: %d", pending->id.peer, pending->id.slot, pending->pending_time);
1948 er->gbox_cw_src_peer = pending->id.peer;
1949 cs_log_dbg(D_READER,"<- ECM (<-%d) - caid: %04X prov: %06X sid: %04X to cw-src-peer: %04X - ecm_src_peer: %04X",
1950 gbox_get_crd_dist_lev(er->gbox_cw_src_peer) & 0xf, er->caid, er->prid, er->srvid, er->gbox_cw_src_peer, er->gbox_ecm_src_peer);
1952 ll_li_destroy(li);
1954 if(er->gbox_ecm_status == GBOX_ECM_NEW_REQ)
1956 er->gbox_ecm_status++;
1957 cli->pending++;
1960 gbox_send(cli, send_buf, buflen);
1961 cli->reader->last_s = time((time_t *) 0);
1963 return 0;
1966 // init my gbox with id, password and cards crc
1967 static int8_t init_local_gbox(void)
1969 int32_t i;
1970 local_gbox.id = 0;
1971 local_gbox.password = 0;
1972 local_gbox.minor_version = cfg.gbox_my_vers;
1973 local_gbox.cpu_api = gbox_get_my_cpu_api();
1974 init_gbox_cards();
1976 if(!cfg.gbox_port[0])
1978 cs_log("error, no/invalid port=%d configured in oscam.conf!", cfg.gbox_port[0] ? cfg.gbox_port[0] : 0);
1979 return -1;
1982 if(!cfg.gbox_hostname || strlen(cfg.gbox_hostname) > 128)
1984 cs_log("error, no/invalid hostname '%s' configured in oscam.conf!",
1985 cfg.gbox_hostname ? cfg.gbox_hostname : "");
1986 return -1;
1989 if(!cfg.gbox_password)
1991 cs_log("error, 'my_password' not configured in oscam.conf!");
1992 return -1;
1995 if(!cfg.gbox_reconnect || cfg.gbox_reconnect > GBOX_MAX_RECONNECT || cfg.gbox_reconnect < GBOX_MIN_RECONNECT)
1997 cs_log("Invalid 'gbox_reconnect = %d' Using default: %d sec", cfg.gbox_reconnect, DEFAULT_GBOX_RECONNECT);
1998 cfg.gbox_reconnect = DEFAULT_GBOX_RECONNECT;
2001 local_gbox.password = cfg.gbox_password;
2002 local_gbox.id = gbox_convert_password_to_id(local_gbox.password);
2004 if(!local_gbox.id)
2006 cs_log("invalid 'my_password' %08X -> local gbox id: %04X, choose another 'my_password'",
2007 cfg.gbox_password, local_gbox.id);
2008 return -1;
2011 local_gbox_initialized = 1;
2013 for(i = 0; i < CS_MAXPORTS; i++)
2015 if(!cfg.gbox_port[i])
2017 cs_log("we are online - %d port(s) to monitor", i);
2018 break;
2022 last_stats_written = time(NULL);
2023 gbox_write_version();
2024 start_sms_sender();
2025 return local_gbox_initialized;
2028 static int32_t gbox_peer_init(struct s_client *cli)
2030 if(!cli || cli->typ != 'p' || !cli->reader)
2032 cs_log("error, wrong call to gbox_peer_init!");
2033 return -1;
2036 if (local_gbox_initialized < 0)
2038 return -1;
2041 int8_t ret;
2042 if(!local_gbox_initialized)
2044 local_gbox_initialized = 1;
2045 ret = init_local_gbox();
2046 if (ret < 0)
2048 local_gbox_initialized = -1;
2049 cs_log("local gbox initialization failed");
2050 write_msg_info(cli, MSGID_GBOXONL, 0, 0);
2051 return -1;
2053 write_msg_info(cli, MSGID_GBOXONL, 0, 1);
2056 if(!cs_malloc(&cli->gbox, sizeof(struct gbox_peer)))
2058 return -1;
2061 struct s_reader *rdr = cli->reader;
2062 struct gbox_peer *peer = cli->gbox;
2064 memset(peer, 0, sizeof(struct gbox_peer));
2066 peer->gbox.password = a2i(rdr->r_pwd, 4);
2067 //cs_log_dbg(D_READER,"peer-reader-label: %s peer-reader-password: %s", cli->reader->label, rdr->r_pwd);
2068 peer->gbox.id = gbox_convert_password_to_id(peer->gbox.password);
2070 if (get_gbox_proxy(peer->gbox.id) || peer->gbox.id == NO_GBOX_ID || peer->gbox.id == local_gbox.id)
2072 cs_log("error, double/invalid gbox id: %04X", peer->gbox.id);
2073 return -1;
2075 cs_lock_create(__func__, &peer->lock, "gbox_lock", 5000);
2077 gbox_clear_peer(peer);
2079 cli->gbox_peer_id = peer->gbox.id;
2081 cli->pfd = 0;
2082 cli->crypted = 1;
2084 rdr->card_status = CARD_NEED_INIT;
2085 rdr->tcp_connected = 0;
2087 set_null_ip(&cli->ip);
2089 if((cli->udp_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
2091 cs_log("socket creation failed (errno=%d %s)", errno, strerror(errno));
2092 cs_disconnect_client(cli);
2095 int32_t opt = 1;
2096 setsockopt(cli->udp_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
2098 set_so_reuseport(cli->udp_fd);
2100 set_socket_priority(cli->udp_fd, cfg.netprio);
2102 memset((char *)&cli->udp_sa, 0, sizeof(cli->udp_sa));
2104 if(!hostResolve(rdr))
2106 return 0;
2109 cli->port = rdr->r_port;
2110 SIN_GET_FAMILY(cli->udp_sa) = AF_INET;
2111 SIN_GET_PORT(cli->udp_sa) = htons((uint16_t)rdr->r_port);
2112 hostname2ip(cli->reader->device, &SIN_GET_ADDR(cli->udp_sa));
2114 cs_log("proxy %s (fd=%d, peer id=%04X, my id=%04X, my hostname=%s, peer's listen port=%d)",
2115 rdr->device, cli->udp_fd, peer->gbox.id, local_gbox.id, cfg.gbox_hostname, rdr->r_port);
2117 cli->pfd = cli->udp_fd;
2119 gbox_send_hello(cli, GBOX_STAT_HELLOL);
2121 if(!cli->reader->gbox_maxecmsend)
2123 cli->reader->gbox_maxecmsend = DEFAULT_GBOX_MAX_ECM_SEND;
2126 if(!cli->reader->gbox_maxdist)
2128 cli->reader->gbox_maxdist = DEFAULT_GBOX_MAX_DIST;
2131 // value > GBOX_MAXHOPS not allowed in gbox network
2132 if(cli->reader->gbox_reshare > GBOX_MAXHOPS)
2134 cli->reader->gbox_reshare = GBOX_MAXHOPS;
2137 if(cli->reader->gbox_cccam_reshare > GBOX_MAXHOPS)
2139 cli->reader->gbox_cccam_reshare = GBOX_MAXHOPS;
2142 return 0;
2145 static void gbox_send_HERE(struct s_client *cli)
2147 struct gbox_peer *peer = cli->gbox;
2148 uint8_t outbuf[32];
2149 int32_t hostname_len = strlen(cfg.gbox_hostname);
2150 gbox_message_header(outbuf, MSG_HERE, peer->gbox.password, local_gbox.password);
2151 outbuf[0xA] = cfg.gbox_my_vers;
2152 outbuf[0xB] = gbox_get_my_cpu_api();
2153 memcpy(&outbuf[0xC], cfg.gbox_hostname, hostname_len);
2154 cs_log("gbox send 'HERE?' to boxid: %04X", peer->gbox.id);
2155 //cs_log_dump_dbg(D_READER, outbuf, hostname_len + 0xC, "<- send HERE?, (len=%d):", hostname_len + 0xC);
2156 cs_log_dump(outbuf, hostname_len + 0xC, "<- send HERE?, (len=%d):", hostname_len + 0xC);
2157 gbox_send(cli, outbuf, hostname_len + 0xC);
2161 static void gbox_peer_idle (struct s_client *cl)
2163 uint32_t ptime_elapsed, etime_elapsed;
2164 struct s_client *proxy = get_gbox_proxy(cl->gbox_peer_id);
2165 struct gbox_peer *peer;
2167 if (proxy && proxy->gbox)
2169 etime_elapsed = llabs(cl->lastecm - time(NULL));
2171 if (llabs(proxy->last - time(NULL)) > etime_elapsed)
2173 ptime_elapsed = etime_elapsed;
2175 else
2177 ptime_elapsed = llabs(proxy->last - time(NULL));
2180 if (ptime_elapsed > (cfg.gbox_reconnect *2) && cl->gbox_peer_id != NO_GBOX_ID)
2182 // gbox peer apparently died without saying goodnight
2183 peer = proxy->gbox;
2184 cs_writelock(__func__, &peer->lock);
2186 if (peer->online)
2188 disable_remm(cl);
2189 cs_log("Lost connection to: %s %s - taking peer %04X %s offline",
2190 proxy->reader->device, cs_inet_ntoa(proxy->ip), cl->gbox_peer_id, username(cl));
2192 cs_log_dbg(D_READER, "time since last proxy activity: %d sec > %d => lost connection - taking peer %04X - %s offline",
2193 ptime_elapsed, cfg.gbox_reconnect *2, cl->gbox_peer_id, username(cl));
2195 write_msg_info(proxy, MSGID_LOSTCONNECT, 0, 0);
2196 gbox_reinit_proxy(proxy);
2198 cs_writeunlock(__func__, &peer->lock);
2201 if (etime_elapsed > cfg.gbox_reconnect && cl->gbox_peer_id != NO_GBOX_ID)
2203 peer = proxy->gbox;
2204 cs_writelock(__func__, &peer->lock);
2206 if (!(check_peer_ignored(cl->gbox_peer_id)))
2208 if (!peer->online && ptime_elapsed < cfg.gbox_reconnect *3)
2210 cs_log_dbg(D_READER, "%04X - %s -> offline - time since last ecm / proxy_act: %d sec / %d sec => trigger HELLOL",
2211 cl->gbox_peer_id, username(cl), etime_elapsed, ptime_elapsed);
2213 gbox_send_hello(proxy, GBOX_STAT_HELLOL);
2214 //gbox_send_HERE(proxy);
2217 if (peer->online)
2219 cs_log_dbg(D_READER, "%04X - %s -> online - time since last ecm /proxy activity: %d sec / %d sec => trigger keepalive HELLOS",
2220 cl->gbox_peer_id, username(cl), etime_elapsed, ptime_elapsed);
2222 gbox_send_hello(proxy, GBOX_STAT_HELLOS);
2225 cs_writeunlock(__func__, &peer->lock);
2228 cl->last = time((time_t *)0);
2231 static int8_t gbox_send_peer_good_night(struct s_client *proxy)
2233 uint8_t outbuf[64];
2234 int32_t hostname_len = 0;
2236 if (cfg.gbox_hostname)
2238 hostname_len = strlen(cfg.gbox_hostname);
2241 int32_t len = hostname_len + 22;
2243 if(proxy->gbox && proxy->typ == 'p')
2245 struct gbox_peer *peer = proxy->gbox;
2246 struct s_reader *rdr = proxy->reader;
2248 if (peer->online)
2250 gbox_message_header(outbuf, MSG_HELLO, peer->gbox.password, local_gbox.password);
2251 outbuf[10] = 0x01;
2252 outbuf[11] = 0x80;
2253 memset(&outbuf[12], 0xff, 7);
2254 outbuf[19] = cfg.gbox_my_vers;
2255 outbuf[20] = gbox_get_my_cpu_api();
2256 memcpy(&outbuf[21], cfg.gbox_hostname, hostname_len);
2257 outbuf[21 + hostname_len] = hostname_len;
2258 cs_log("<- good night to %s:%d id: %04X", rdr->device, rdr->r_port, peer->gbox.id);
2259 gbox_compress(outbuf, len, &len);
2260 gbox_send(proxy, outbuf, len);
2261 gbox_reinit_proxy(proxy);
2264 return 0;
2267 void gbox_send_good_night(void)
2269 gbox_free_cardlist();
2270 struct s_client *cli;
2271 cs_readlock(__func__, &clientlist_lock);
2273 for(cli = first_client; cli; cli = cli->next)
2275 if(cli->gbox && cli->typ == 'p')
2277 gbox_send_peer_good_night(cli);
2280 cs_readunlock(__func__, &clientlist_lock);
2283 void gbox_send_goodbye(struct s_client *cli) // indication that requested ECM failed
2285 if (local_gbox.minor_version != 0x2A)
2287 uint8_t outbuf[15];
2288 struct gbox_peer *peer = cli->gbox;
2289 gbox_message_header(outbuf, MSG_GOODBYE, peer->gbox.password, local_gbox.password);
2290 cs_log_dbg(D_READER,"<- goodbye - requested ecm failed. Send info to requesting boxid: %04X", peer->gbox.id);
2291 gbox_send(cli, outbuf, 10);
2293 else
2295 return;
2299 void module_gbox(struct s_module *ph)
2301 int32_t i;
2303 for(i = 0; i < CS_MAXPORTS; i++)
2305 if(!cfg.gbox_port[i])
2307 break;
2310 ph->ptab.nports++;
2311 ph->ptab.ports[i].s_port = cfg.gbox_port[i];
2314 ph->desc = "gbox";
2315 ph->num = R_GBOX;
2316 ph->type = MOD_CONN_UDP;
2317 ph->large_ecm_support = 1;
2318 ph->listenertype = LIS_GBOX;
2319 ph->s_handler = gbox_server;
2320 ph->s_init = gbox_server_init;
2321 ph->send_dcw = gbox_send_dcw;
2322 ph->recv = gbox_recv;
2323 ph->c_init = gbox_peer_init;
2324 ph->c_send_ecm = gbox_send_ecm;
2325 ph->c_send_emm = gbox_send_remm_data;
2326 ph->s_peer_idle = gbox_peer_idle;
2328 #endif