revert breaks some stupid old compilers
[oscam.git] / module-gbox.c
blob34cf94964c9b49e1884ba6916c47c1d4ae45d239
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"
24 #define RECEIVE_BUFFER_SIZE 1024
25 #define MIN_GBOX_MESSAGE_LENGTH 10 //CMD + pw + pw. TODO: Check if is really min
26 #define MIN_ECM_LENGTH 8
27 #define STATS_WRITE_TIME 300 //write stats file every 5 min
28 #define MAX_GBOX_CARDS 1024 //send max. 1024 to peer
30 #define LOCAL_GBOX_MAJOR_VERSION 0x02
32 static struct gbox_data local_gbox;
33 static int8_t local_gbox_initialized = 0;
34 static uint8_t local_cards_initialized = 0;
35 static uint8_t local_card_change_detected = 0;
36 static time_t last_stats_written;
37 uint8_t local_gbx_rev = 0x10;
39 static int32_t gbox_send_ecm(struct s_client *cli, ECM_REQUEST *er);
41 void gbx_local_card_changed(void)
43 cs_sleepms(100);
44 cs_log_dbg(D_READER, "Local card change detected");
45 local_card_change_detected = 1;
46 return;
49 char *get_gbox_tmp_fname(char *fext)
51 static char gbox_tmpfile_buf[64] = { 0 };
52 const char *slash = "/";
53 if(!cfg.gbox_tmp_dir)
55 snprintf(gbox_tmpfile_buf, sizeof(gbox_tmpfile_buf), "%s%s%s",get_tmp_dir(), slash, fext);
57 else
59 if(cfg.gbox_tmp_dir[strlen(cfg.gbox_tmp_dir) - 1] == '/') { slash = ""; }
60 snprintf(gbox_tmpfile_buf, sizeof(gbox_tmpfile_buf), "%s%s%s", cfg.gbox_tmp_dir, slash, fext);
62 return gbox_tmpfile_buf;
65 uint16_t gbox_get_local_gbox_id(void)
67 return local_gbox.id;
70 uint32_t gbox_get_local_gbox_password(void)
72 return local_gbox.password;
75 static uint8_t gbox_get_my_cpu_api (void)
77 /* For configurable later adapt according to these functions:
78 unsigned char *GboxAPI( unsigned char a ) {
79 a = a & 7 ;
80 switch ( a ) {
81 case 0 : strcpy ( s_24,"No API");
82 break;
83 case 1 : strcpy ( s_24,"API 1");
84 break;
85 case 2 : strcpy ( s_24,"API 2");
86 break;
87 case 3 : strcpy ( s_24,"API 3");
88 break;
89 case 4 : strcpy ( s_24,"IBM API");
90 break;
91 default : strcpy ( s_24," ");
93 return s_24 ;
96 unsigned char *GboxCPU( unsigned char a ) {
97 a = a & 112 ;
98 a = a >> 4 ;
99 switch ( a ) {
100 case 1 : strcpy ( s_23,"80X86 compatible CPU");
101 break;
102 case 2 : strcpy ( s_23,"Motorola PowerPC MPC823 CPU");
103 break;
104 case 3 : strcpy ( s_23,"IBM PowerPC STB CPU");
105 break;
106 default : strcpy ( s_23," ");
108 return s_23:
110 return cfg.gbox_my_cpu_api;
112 return(cfg.gbox_my_cpu_api);
115 static void write_attack_file (struct s_client *cli, uint8_t txt_id, uint16_t rcvd_id)
117 if (cfg.dis_attack_txt) {return;}
118 char tsbuf[28];
119 time_t walltime = cs_time();
120 cs_ctime_r(&walltime, tsbuf);
121 char *fext= FILE_ATTACK_INFO;
122 char *fname = get_gbox_tmp_fname(fext);
123 FILE *fhandle = fopen(fname, "a");
124 if(!fhandle)
126 cs_log("Couldn't open %s: %s", fname, strerror(errno));
127 return;
129 if(txt_id == GBOX_ATTACK_LOCAL_PW)
130 {fprintf(fhandle, "ATTACK ALERT FROM %04X %s - peer sends wrong local password - %s", rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);}
131 if(txt_id == GBOX_ATTACK_PEER_IGNORE)
132 {fprintf(fhandle, "ATTACK ALERT FROM %04X %s - peer is ignored - %s", rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);}
133 if(txt_id == GBOX_ATTACK_PEER_PW)
134 {fprintf(fhandle, "ATTACK ALERT FROM %04X %s - peer sends unknown peer password - %s", rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);}
135 if(txt_id == GBOX_ATTACK_AUTH_FAIL)
136 {fprintf(fhandle, "ATTACK ALERT FROM %04X %s - authentification failed - %s", rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);}
137 if(txt_id == GBOX_ATTACK_ECM_BLOCKED)
138 {fprintf(fhandle, "ATTACK ALERT FROM %04X %s - ECM is blocked - %s", rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);}
139 if(txt_id == GBOX_ATTACK_REMM_REQ_BLOCKED)
140 {fprintf(fhandle, "ATTACK ALERT FROM %04X %s - unaccepted peer sent REMM REQ - %s", rcvd_id, cs_inet_ntoa(cli->ip), tsbuf);}
141 fclose(fhandle);
142 return;
145 static void write_msg_info (struct s_client *cli, uint8_t msg_id, uint8_t txt_id, uint16_t misc)
147 if (msg_id == MSGID_GSMS && misc == 0x31) {return;}
148 char *fext= FILE_MSG_INFO;
149 char *fname = get_gbox_tmp_fname(fext);
150 if (file_exists(fname))
152 char buf[120];
153 memset(buf, 0, sizeof(buf));
154 if (msg_id == MSGID_ATTACK)
156 snprintf(buf, sizeof(buf), "%s %d %04X %d %s %d", fname, msg_id, misc, 0, cs_inet_ntoa(cli->ip), txt_id);
157 cs_log_dbg(D_READER, "found driver %s - write msg (msg_id = %d - txt-id = %d) Attack Alert from %s %04X", fname, msg_id, txt_id, cs_inet_ntoa(cli->ip), misc);
159 else
161 snprintf(buf, sizeof(buf), "%s %d %s %s %s %d", fname, msg_id, username(cli), cli->reader->device, cs_inet_ntoa(cli->ip), misc);
162 cs_log_dbg(D_READER, "found driver %s - write msg (id = %d) related to %s %s", fname, msg_id, username(cli),cli->reader->device);
164 char *cmd = buf;
165 FILE *p;
166 if ((p = popen(cmd, "w")) == NULL)
168 cs_log("Error %s",fname);
169 return;
171 pclose(p);
173 return;
176 void handle_attack(struct s_client *cli, uint8_t txt_id, uint16_t rcvd_id)
178 write_attack_file(cli, txt_id, rcvd_id);
179 write_msg_info(cli, MSGID_ATTACK, txt_id, rcvd_id);
180 return;
183 void gbox_write_peer_onl(void)
185 char *fext= FILE_GBOX_PEER_ONL;
186 char *fname = get_gbox_tmp_fname(fext);
187 FILE *fhandle = fopen(fname, "w");
188 if(!fhandle)
190 cs_log("Couldn't open %s: %s", fname, strerror(errno));
191 return;
193 cs_readlock(__func__, &clientlist_lock);
194 struct s_client *cl;
195 for(cl = first_client; cl; cl = cl->next)
197 if(cl->gbox && cl->typ == 'p')
199 struct gbox_peer *peer = cl->gbox;
201 if (peer->online)
203 fprintf(fhandle, "1 %s %s %04X 2.%02X\n",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id, peer->gbox.minor_version);
204 if (!peer->onlinestat)
206 peer->onlinestat = 1;
207 cs_log("comeONLINE: %s %s boxid: %04X v2.%02X cards:%d",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id, peer->gbox.minor_version, peer->filtered_cards);
208 write_msg_info(cl, MSGID_COMEONLINE, 0, peer->filtered_cards);
211 else
213 fprintf(fhandle, "0 %s %s %04X 0.00\n",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id);
214 if (peer->onlinestat)
216 peer->onlinestat = 0;
217 cs_log("goneOFFLINE: %s %s boxid: %04X",cl->reader->device, cs_inet_ntoa(cl->ip),peer->gbox.id);
218 write_msg_info(cl, MSGID_GONEOFFLINE, 0, 0);
223 cs_readunlock(__func__, &clientlist_lock);
224 fclose(fhandle);
225 return;
228 void gbox_write_version(void)
230 char *fext= FILE_GBOX_VERSION;
231 char *fname = get_gbox_tmp_fname(fext);
232 FILE *fhandle = fopen(fname, "w");
233 if(!fhandle)
235 cs_log("Couldn't open %s: %s", get_gbox_tmp_fname(FILE_GBOX_VERSION), strerror(errno));
236 return;
238 fprintf(fhandle, "%02X.%02X my-id: %04X\n", LOCAL_GBOX_MAJOR_VERSION, cfg.gbox_my_vers, local_gbox.id);
239 fclose(fhandle);
242 void hostname2ip(char *hostname, IN_ADDR_T *ip)
244 cs_resolve(hostname, ip, NULL, NULL);
247 static uint16_t gbox_convert_password_to_id(uint32_t password)
249 return (((password >> 24) & 0xff) ^ ((password >> 8) & 0xff)) << 8 | (((password >> 16) & 0xff) ^ (password & 0xff));
252 static int8_t gbox_remove_all_bad_sids(ECM_REQUEST *er, uint16_t sid)
254 if (!er) { return -1; }
256 struct gbox_card_pending *pending = NULL;
257 LL_LOCKITER *li = ll_li_create(er->gbox_cards_pending, 0);
258 while ((pending = ll_li_next(li)))
259 { gbox_remove_bad_sid(pending->id.peer, pending->id.slot, sid); }
260 ll_li_destroy(li);
261 return 0;
264 void gbox_free_cards_pending(ECM_REQUEST *er)
266 ll_destroy_free_data(&er->gbox_cards_pending);
269 void gbox_init_ecm_request_ext(struct gbox_ecm_request_ext *ere)
271 ere->gbox_hops = 0;
272 ere->gbox_peer = 0;
273 ere->gbox_mypeer = 0;
274 ere->gbox_slot = 0;
275 ere->gbox_version = 0;
276 ere->gbox_rev = 0;
277 ere->gbox_type = 0;
280 struct s_client *get_gbox_proxy(uint16_t gbox_id)
282 struct s_client *cl;
283 struct s_client *found = NULL;
284 cs_readlock(__func__, &clientlist_lock);
285 for(cl = first_client; cl; cl = cl->next)
287 if(cl->typ == 'p' && cl->gbox && cl->gbox_peer_id == gbox_id)
289 found = cl;
290 break;
293 cs_readunlock(__func__, &clientlist_lock);
294 return found;
297 static int8_t gbox_peer_online(struct gbox_peer *peer, uint8_t online)
299 if (!peer) { return -1; }
301 peer->online = online;
302 gbox_write_peer_onl();
303 return 0;
306 static int8_t gbox_clear_peer(struct gbox_peer *peer)
308 if (!peer) { return -1; }
310 peer->ecm_idx = 0;
311 peer->next_hello = 0;
312 peer->authstat = 0;
313 gbox_delete_cards(GBOX_DELETE_FROM_PEER, peer->gbox.id);
314 gbox_peer_online(peer, GBOX_PEER_OFFLINE);
316 return 0;
319 static int8_t gbox_reinit_proxy(struct s_client *proxy)
321 if (!proxy) { return -1; }
323 struct gbox_peer *peer = proxy->gbox;
324 gbox_clear_peer(peer);
325 if (!proxy->reader) { return -1; }
326 proxy->reader->tcp_connected = 0;
327 proxy->reader->card_status = NO_CARD;
328 proxy->reader->last_s = proxy->reader->last_g = 0;
330 return 0;
333 void gbox_send(struct s_client *cli, uchar *buf, int32_t l)
335 struct gbox_peer *peer = cli->gbox;
337 cs_log_dump_dbg(D_READER, buf, l, "<- data to %s (%d bytes):", cli->reader->label, l);
339 hostname2ip(cli->reader->device, &SIN_GET_ADDR(cli->udp_sa));
340 SIN_GET_FAMILY(cli->udp_sa) = AF_INET;
341 SIN_GET_PORT(cli->udp_sa) = htons((uint16_t)cli->reader->r_port);
343 gbox_encrypt(buf, l, peer->gbox.password);
344 sendto(cli->udp_fd, buf, l, 0, (struct sockaddr *)&cli->udp_sa, cli->udp_sa_len);
345 cs_log_dump_dbg(D_READER, buf, l, "<- encrypted data to %s (%d bytes):", cli->reader->label, l);
348 void gbox_send_hello_packet(struct s_client *cli, int8_t number, uchar *outbuf, uchar *ptr, int32_t nbcards, uint8_t hello_stat)
350 struct gbox_peer *peer = cli->gbox;
351 int32_t hostname_len = strlen(cfg.gbox_hostname);
352 int32_t len;
353 gbox_message_header(outbuf, MSG_HELLO, peer->gbox.password, local_gbox.password);
354 // initial HELLO = 0, subsequent = 1
355 if(hello_stat > GBOX_STAT_HELLOS)
356 { outbuf[10] = 1; }
357 else
358 { outbuf[10] = 0; }
359 outbuf[11] = number; // 0x80 (if last packet) else 0x00 | packet number
361 if((number & 0x0F) == 0)
363 if(hello_stat != GBOX_STAT_HELLOL)
364 { memcpy(++ptr, gbox_get_my_checkcode(), 7); }
365 else
366 { memset(++ptr, 0, 7); }
367 ptr += 7;
368 *ptr = local_gbox.minor_version;
369 *(++ptr) = local_gbox.cpu_api;
370 memcpy(++ptr, cfg.gbox_hostname, hostname_len);
371 ptr += hostname_len;
372 *ptr = hostname_len;
374 len = ptr - outbuf + 1;
375 switch(hello_stat)
377 case GBOX_STAT_HELLOL:
378 if (cfg.log_hello)
379 { cs_log("<- HelloL to %s", cli->reader->label);}
380 else
381 { cs_log_dbg(D_READER,"<- HelloL to %s", cli->reader->label);}
382 break;
383 case GBOX_STAT_HELLOS:
384 if (cfg.log_hello)
385 { cs_log("<- HelloS total cards %d to %s", nbcards, cli->reader->label);}
386 else
387 { cs_log_dbg(D_READER,"<- HelloS total cards %d to %s", nbcards, cli->reader->label);}
388 break;
389 case GBOX_STAT_HELLOR:
390 if (cfg.log_hello)
391 { cs_log("<- HelloR total cards %d to %s", nbcards, cli->reader->label);}
392 else
393 { cs_log_dbg(D_READER,"<- HelloR total cards %d to %s", nbcards, cli->reader->label);}
394 break;
395 default:
396 if (cfg.log_hello)
397 { cs_log("<- hello total cards %d to %s", nbcards, cli->reader->label);}
398 else
399 { cs_log_dbg(D_READER,"<- hello total cards %d to %s", nbcards, cli->reader->label);}
400 break;
402 cs_log_dump_dbg(D_READER, outbuf, len, "<- hello to %s, (len=%d):", cli->reader->label, len);
404 gbox_compress(outbuf, len, &len);
406 gbox_send(cli, outbuf, len);
409 void gbox_send_hello(struct s_client *proxy, uint8_t hello_stat)
411 if (!proxy)
413 cs_log("Invalid call to gbox_send_hello with proxy");
414 return;
416 uint16_t nbcards = 0;
417 uint16_t nbcards_cnt = 0;
418 uint8_t packet;
419 uchar buf[2048];
420 packet = 0;
421 uchar *ptr = buf + 11;
422 if(gbox_count_cards() != 0 && hello_stat > GBOX_STAT_HELLOL)
424 struct gbox_peer *peer = proxy->gbox;
425 if (!peer || !peer->my_user || !peer->my_user->account)
427 cs_log("Invalid call to gbox_send_hello with peer");
428 return;
430 memset(buf, 0, sizeof(buf));
431 struct gbox_card *card;
432 GBOX_CARDS_ITER *gci = gbox_cards_iter_create();
433 while((card = gbox_cards_iter_next(gci)))
435 //send to user only cards which matching CAID from account and lvl > 0
436 //and cccmaxhops from account
437 //do not send peer cards back
438 if(chk_ctab(gbox_get_caid(card->caprovid), &peer->my_user->account->ctab) && (card->lvl > 0) &&
439 #ifdef MODULE_CCCAM
440 (card->dist <= peer->my_user->account->cccmaxhops) &&
441 #endif
442 (!card->origin_peer || (card->origin_peer && card->origin_peer->gbox.id != peer->gbox.id)))
444 *(++ptr) = card->caprovid >> 24;
445 *(++ptr) = card->caprovid >> 16;
446 *(++ptr) = card->caprovid >> 8;
447 *(++ptr) = card->caprovid & 0xff;
448 *(++ptr) = 1; //note: original gbx is more efficient and sends all cards of one caid as package
449 *(++ptr) = card->id.slot;
450 *(++ptr) = ((card->lvl - 1) << 4) + card->dist + 1;
451 *(++ptr) = card->id.peer >> 8;
452 *(++ptr) = card->id.peer & 0xff;
453 nbcards++;
454 nbcards_cnt++;
455 if(nbcards_cnt == MAX_GBOX_CARDS )
457 cs_log("max cards gbox_send_hello with peer reached");
458 break;
460 if(nbcards == 100) //check if 100 is good or we need more sophisticated algorithm
462 gbox_send_hello_packet(proxy, packet, buf, ptr, nbcards, hello_stat);
463 packet++;
464 nbcards = 0;
465 ptr = buf + 11;
466 memset(buf, 0, sizeof(buf));
470 gbox_cards_iter_destroy(gci);
471 } // end if local card exists
472 //last packet has bit 0x80 set
473 gbox_send_hello_packet(proxy, 0x80 | packet, buf, ptr, nbcards, hello_stat);
474 return;
477 void gbox_reconnect_client(uint16_t gbox_id)
479 struct s_client *cl;
480 cs_readlock(__func__, &clientlist_lock);
481 for(cl = first_client; cl; cl = cl->next)
483 if(cl->gbox && cl->typ == 'p' && cl->gbox_peer_id == gbox_id)
485 hostname2ip(cl->reader->device, &SIN_GET_ADDR(cl->udp_sa));
486 SIN_GET_FAMILY(cl->udp_sa) = AF_INET;
487 SIN_GET_PORT(cl->udp_sa) = htons((uint16_t)cl->reader->r_port);
488 hostname2ip(cl->reader->device, &(cl->ip));
489 gbox_reinit_proxy(cl);
490 gbox_send_hello(cl, GBOX_STAT_HELLOL); //comment out line,if endless loops occur on LTE/DSL-Hybrid system @IP change
493 cs_readunlock(__func__, &clientlist_lock);
496 static void *gbox_server(struct s_client *cli, uchar *UNUSED(b), int32_t l)
498 if(l > 0)
500 cs_log("gbox_server %s/%d", cli->reader->label, cli->port);
501 // gbox_check_header_recvd(cli, NULL, b, l);
503 return 0;
506 char *gbox_username(struct s_client *client)
508 if(!client) { return "anonymous"; }
509 if(client->reader)
510 if(client->reader->r_usr[0])
511 { return client->reader->r_usr; }
512 return "anonymous";
515 static int8_t gbox_disconnect_double_peers(struct s_client *cli)
517 struct s_client *cl;
518 cs_writelock(__func__, &clientlist_lock);
519 for(cl = first_client; cl; cl = cl->next)
521 if (cl->typ == 'c' && cl->gbox_peer_id == cli->gbox_peer_id && cl != cli)
523 cl->reader = NULL;
524 cl->gbox = NULL;
525 cs_log_dbg(D_READER, "disconnected double client %s",username(cl));
526 // cs_log("disconnected double client %s - %s",username(cl), cs_inet_ntoa(cli->ip));
527 cs_disconnect_client(cl);
530 cs_writeunlock(__func__, &clientlist_lock);
531 return 0;
534 static int8_t gbox_auth_client(struct s_client *cli, uint32_t gbox_password)
536 if (!cli) { return -1; }
538 uint16_t gbox_id = gbox_convert_password_to_id(gbox_password);
539 struct s_client *cl = get_gbox_proxy(gbox_id);
541 if(cl->typ == 'p' && cl->gbox && cl->reader)
543 struct gbox_peer *peer = cl->gbox;
544 struct s_auth *account = get_account_by_name(gbox_username(cl));
546 if ((peer->gbox.password == gbox_password) && account)
548 cli->crypted = 1; //display as crypted
549 cli->gbox = cl->gbox; //point to the same gbox as proxy
550 cli->reader = cl->reader; //point to the same reader as proxy
551 cli->gbox_peer_id = cl->gbox_peer_id; //signal authenticated
552 gbox_disconnect_double_peers(cli);
553 cs_auth_client(cli, account, NULL);
554 cli->account = account;
555 cli->grp = account->grp;
556 cli->lastecm = time(NULL);
557 peer->my_user = cli;
558 return 0;
561 return -1;
564 static void gbox_server_init(struct s_client *cl)
566 cs_writelock(__func__, &clientlist_lock);
567 if(!cl->init_done)
569 if(IP_ISSET(cl->ip))
570 { cs_log("new connection from %s", cs_inet_ntoa(cl->ip)); }
571 //We cannot authenticate here, because we don't know gbox pw
572 cl->gbox_peer_id = NO_GBOX_ID;
573 cl->init_done = 1;
575 start_sms_sender();
577 cs_writeunlock(__func__, &clientlist_lock);
578 return;
581 static uint16_t gbox_decode_cmd(uchar *buf)
583 return buf[0] << 8 | buf[1];
586 int8_t gbox_message_header(uchar *buf, uint16_t cmd, uint32_t peer_password, uint32_t local_password)
588 if (!buf) { return -1; }
589 i2b_buf(2, cmd, buf);
590 i2b_buf(4, peer_password, buf + 2);
591 if (cmd == MSG_CW) { return 0; }
592 i2b_buf(4, local_password, buf + 6);
593 return 0;
596 //returns number of cards in a hello packet or -1 in case of error
597 int16_t read_cards_from_hello(uint8_t *ptr, uint8_t *len, CAIDTAB *ctab, uint8_t maxdist, struct gbox_peer *peer)
599 uint8_t *current_ptr = 0;
600 uint32_t caprovid;
601 int16_t ncards_in_msg = 0;
603 while(ptr < len)
605 caprovid = ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
607 ncards_in_msg += ptr[4];
608 //caid check
609 if(chk_ctab(gbox_get_caid(caprovid), ctab))
611 current_ptr = ptr;
612 ptr += 5;
614 // for all cards of current caid/provid,
615 while (ptr < current_ptr + 5 + current_ptr[4] * 4)
617 if ((ptr[1] & 0xf) <= maxdist)
618 { gbox_add_card(ptr[2] << 8 | ptr[3], caprovid, ptr[0], ptr[1] >> 4, ptr[1] & 0xf, GBOX_CARD_TYPE_GBOX, peer); }
619 ptr += 4; //next card
620 } // end while cards for provider
622 else
623 { ptr += 5 + ptr[4] * 4; } //skip cards because caid
624 } // end while < len
625 return ncards_in_msg;
628 //returns 1 if checkcode changed / 0 if not
629 static int32_t gbox_checkcode_recv(struct s_client *cli, uchar *checkcode)
631 struct gbox_peer *peer = cli->gbox;
632 if(memcmp(peer->checkcode, checkcode, 7))
634 memcpy(peer->checkcode, checkcode, 7);
635 cs_log_dump_dbg(D_READER, checkcode, 7, "-> new checkcode from %s:", cli->reader->label);
636 return 1;
638 return 0;
641 static void gbox_send_checkcode(struct s_client *cli)
643 struct gbox_peer *peer = cli->gbox;
644 uchar outbuf[20];
645 cs_log_dump_dbg(D_READER, gbox_get_my_checkcode(), 7, "<- my checkcode to %s:", cli->reader->label);
646 gbox_message_header(outbuf, MSG_CHECKCODE, peer->gbox.password, local_gbox.password);
647 memcpy(outbuf + 10, gbox_get_my_checkcode(), 7);
648 gbox_send(cli, outbuf, 17);
651 int32_t gbox_cmd_hello_rcvd(struct s_client *cli, uchar *data, int32_t n)
653 if (!cli || !cli->gbox || !cli->reader || !data) { return -1; }
655 struct gbox_peer *peer = cli->gbox;
656 int16_t cards_number = 0;
657 int32_t payload_len = n;
658 int32_t hostname_len = 0;
659 int32_t footer_len = 0;
660 uint8_t *ptr = 0;
662 if(!(gbox_decode_cmd(data) == MSG_HELLO1))
664 gbox_decompress(data, &payload_len);
665 cs_log_dump_dbg(D_READER, data, payload_len, "-> data decompressed (%d bytes):", payload_len);
666 ptr = data + 12;
668 else
670 ptr = data + 11;
671 cs_log_dump_dbg(D_READER, data, payload_len, "decrypted data (%d bytes):", payload_len);
673 if ((data[11] & 0xf) != peer->next_hello) //out of sync hellos
675 cs_log("-> out of sync hello from %s %s, expected: %02X, received: %02X"
676 ,username(cli), cli->reader->device, peer->next_hello, data[11] & 0xf);
677 peer->next_hello = 0;
678 gbox_send_hello(cli, GBOX_STAT_HELLOL);
679 return 0;
682 if (!(data[11] & 0xf)) //is first packet
684 gbox_delete_cards(GBOX_DELETE_FROM_PEER, peer->gbox.id);
685 hostname_len = data[payload_len - 1];
686 footer_len = hostname_len + 2 + 7;
687 if(!peer->hostname || memcmp(peer->hostname, data + payload_len - 1 - hostname_len, hostname_len))
689 NULLFREE(peer->hostname);
690 if(!cs_malloc(&peer->hostname, hostname_len + 1))
692 return -1;
694 memcpy(peer->hostname, data + payload_len - 1 - hostname_len, hostname_len);
695 peer->hostname[hostname_len] = '\0';
697 gbox_checkcode_recv(cli, data + payload_len - footer_len - 1);
698 peer->gbox.minor_version = data[payload_len - footer_len - 1 + 7];
699 peer->gbox.cpu_api = data[payload_len - footer_len + 7];
700 peer->total_cards = 0;
702 cs_log_dbg(D_READER, "-> Hello packet no. %d received from %s %s", (data[11] & 0xF) + 1, username(cli), cli->reader->device);
703 // read cards from hello
704 cards_number = read_cards_from_hello(ptr, data + payload_len - footer_len - 1, &cli->reader->ctab, cli->reader->gbox_maxdist, peer);
705 if (cards_number < 0)
706 { return -1; }
707 else
708 { peer->total_cards += cards_number; }
710 if(data[11] & 0x80) //last packet
712 uchar tmpbuf[8];
713 memset(&tmpbuf[0], 0xff, 7);
714 if(data[10] == 0x01 && !memcmp(data+12,tmpbuf,7)) //good night message
716 cs_log("-> Good Night from %s %s",username(cli), cli->reader->device);
717 write_msg_info(cli, MSGID_GOODNIGHT, 0, 0);
718 gbox_reinit_proxy(cli);
720 else //last packet of Hello
722 peer->filtered_cards = gbox_count_peer_cards(peer->gbox.id);
723 if(!data[10])
725 memset(&tmpbuf[0], 0, 7);
726 if (data[11] == 0x80 && !memcmp(data+12,tmpbuf,7))
728 gbox_peer_online(peer, GBOX_PEER_ONLINE);
729 if (cfg.log_hello)
730 {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);}
731 else
732 { 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);}
734 else
736 if (cfg.log_hello)
737 { 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); }
738 else
739 { 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); }
741 gbox_send_hello(cli, GBOX_STAT_HELLOR);
743 else
745 if (cfg.log_hello)
746 { 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); }
747 else
748 { 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);}
750 gbox_send_checkcode(cli);
752 if (cfg.log_hello)
753 { cs_log("<- HelloC my checkcode to %s (%s:%d)", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port);}
754 else
755 { cs_log_dbg(D_READER,"<- HelloC my checkcode to %s (%s:%d)", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port);}
757 if(!peer->online)
759 gbox_send_hello(cli, GBOX_STAT_HELLOS);
760 gbox_peer_online(peer, GBOX_PEER_ONLINE);
762 cli->reader->tcp_connected = CARD_INSERTED;
763 if(!peer->filtered_cards)
764 { cli->reader->card_status = NO_CARD; }
765 else
766 { cli->reader->card_status = CARD_INSERTED; }
768 peer->next_hello = 0;
769 gbox_write_share_cards_info();
770 cli->last = time((time_t *)0); //hello is activity on proxy
772 else { peer->next_hello++; }
773 return 0;
776 static int8_t is_blocked_peer(uint16_t peer_id)
778 int i;
779 if (cfg.gbox_block_ecm_num > 0)
781 for (i = 0; i < cfg.gbox_block_ecm_num; i++)
783 if (cfg.gbox_block_ecm[i] == peer_id)
784 { return 1; }
787 return 0;
790 static int8_t check_peer_ignored(uint16_t peer_id)
792 int i;
793 if (cfg.gbox_ignored_peer_num > 0)
795 for (i = 0; i < cfg.gbox_ignored_peer_num; i++)
797 if (cfg.gbox_ignored_peer[i] == peer_id)
798 { return 1; }
801 return 0;
804 static int8_t validate_peerpass(uint32_t rcvd_peer_pw)
806 struct s_client *cli;
807 cs_readlock(__func__, &clientlist_lock);
808 for(cli = first_client; cli; cli = cli->next)
810 if(cli->gbox && cli->typ == 'p')
812 struct s_reader *rdr = cli->reader;
813 if (rcvd_peer_pw == a2i(rdr->r_pwd, 4))
815 cs_readunlock(__func__, &clientlist_lock);
816 return 1;
817 } // valid peerpass
820 cs_readunlock(__func__, &clientlist_lock);
821 return 0;
824 static int8_t gbox_incoming_ecm(struct s_client *cli, uchar *data, int32_t n)
826 if (!cli || !cli->gbox || !data || !cli->reader) { return -1; }
828 struct gbox_peer *peer;
829 struct s_client *cl;
830 int32_t diffcheck = 0;
832 peer = cli->gbox;
833 if (!peer || !peer->my_user) { return -1; }
834 cl = peer->my_user;
836 if(n < 21)
837 { return -1; }
839 // No ECMs with length < MIN_LENGTH expected
840 if ((((data[19] & 0x0f) << 8) | data[20]) < MIN_ECM_LENGTH) { return -1; }
842 // GBOX_MAX_HOPS not violated
843 if (data[n - 15] + 1 > GBOX_MAXHOPS) { return -1; }
845 // ECM must not take more hops than allowed by gbox_reshare
846 if (data[n - 15] + 1 > cli->reader->gbox_reshare)
848 cs_log("-> ECM took more hops than allowed from gbox_reshare. Hops stealing detected!");
849 return -1;
852 //Check for blocked peers
853 uint16_t requesting_peer = data[(((data[19] & 0x0f) << 8) | data[20]) + 21] << 8 |
854 data[(((data[19] & 0x0f) << 8) | data[20]) + 22];
855 if (is_blocked_peer(requesting_peer))
857 handle_attack(cli, GBOX_ATTACK_ECM_BLOCKED, requesting_peer);
858 cs_log("ECM from peer %04X blocked by config", requesting_peer);
859 return -1;
862 ECM_REQUEST *er;
863 if(!(er = get_ecmtask())) { return -1; }
865 struct gbox_ecm_request_ext *ere;
866 if(!cs_malloc(&ere, sizeof(struct gbox_ecm_request_ext)))
868 NULLFREE(er);
869 return -1;
872 uchar *ecm = data + 18; //offset of ECM in gbx message
874 er->src_data = ere;
875 gbox_init_ecm_request_ext(ere);
877 er->gbox_ecm_id = peer->gbox.id;
879 if(peer->ecm_idx == 100) { peer->ecm_idx = 0; }
881 er->idx = peer->ecm_idx++;
882 er->ecmlen = SCT_LEN(ecm);
884 if(er->ecmlen < 3 || er->ecmlen > MAX_ECM_SIZE || er->ecmlen+18 > n)
885 { NULLFREE(ere); NULLFREE(er); return -1; }
887 er->pid = b2i(2, data + 10);
888 er->srvid = b2i(2, data + 12);
890 if(ecm[er->ecmlen + 5] == 0x05)
891 { er->caid = (ecm[er->ecmlen + 5] << 8); }
892 else
893 { er->caid = b2i(2, ecm + er->ecmlen + 5); }
895 memcpy(er->ecm, data + 18, er->ecmlen);
896 ere->gbox_peer = b2i(2, ecm + er->ecmlen);
897 ere->gbox_version = ecm[er->ecmlen + 2];
898 ere->gbox_rev = ecm[er->ecmlen + 3];
899 ere->gbox_type = ecm[er->ecmlen + 4];
900 uint32_t caprovid = b2i(4, ecm + er->ecmlen + 5);
901 ere->gbox_mypeer = b2i(2, ecm + er->ecmlen + 10);
902 ere->gbox_slot = ecm[er->ecmlen + 12];
903 diffcheck = gbox_checkcode_recv(cl, data + n - 14);
904 //TODO: What do we do with our own checkcode @-7?
905 er->gbox_crc = gbox_get_checksum(&er->ecm[0], er->ecmlen);
906 ere->gbox_hops = data[n - 15] + 1;
907 memcpy(&ere->gbox_routing_info[0], &data[n - 15 - ere->gbox_hops + 1], ere->gbox_hops - 1);
909 er->caid = gbox_get_caid(caprovid);
910 er->prid = gbox_get_provid(caprovid);
912 peer->gbox_rev = ecm[er->ecmlen + 3];
914 cs_log_dbg(D_READER, "-> ECM (-> %d) caid: %04X sid: %04X from peer: %04X rev: %01X.%01X (%s:%d)", ere->gbox_hops, er->caid, er->srvid, ere->gbox_peer, peer->gbox_rev >>4, peer->gbox_rev & 0x0f , peer->hostname, cli->port);
915 get_cw(cl, er);
917 //checkcode did not match gbox->peer checkcode
918 if(diffcheck)
920 // TODO: Send HelloS here?
921 // gbox->peer.hello_stat = GBOX_STAT_HELLOS;
922 // gbox_send_hello(cli);
924 return 0;
927 static uint32_t gbox_get_pending_time(ECM_REQUEST *er, uint16_t peer_id, uint8_t slot)
929 if (!er) { return 0; }
931 uint32_t ret_time = 0;
932 struct gbox_card_pending *pending = NULL;
933 LL_LOCKITER *li = ll_li_create(er->gbox_cards_pending, 0);
934 while ((pending = ll_li_next(li)))
936 if ((pending->id.peer == peer_id) && (pending->id.slot == slot))
938 ret_time = pending->pending_time;
939 break;
942 ll_li_destroy(li);
943 return ret_time;
946 static int32_t gbox_recv_chk(struct s_client *cli, uchar *dcw, int32_t *rc, uchar *data, int32_t n)
948 if(!cli || gbox_decode_cmd(data) != MSG_CW || n < 44)
949 { return -1; }
951 int i;
952 uint16_t id_card = 0;
953 struct s_client *proxy;
954 if(cli->typ != 'p')
955 { proxy = get_gbox_proxy(cli->gbox_peer_id); }
956 else
957 { proxy = cli; }
958 if (!proxy || !proxy->reader)
960 cs_log("error, gbox_recv_chk, proxy not found");
961 gbox_send_goodbye(cli);
962 return -1;
964 proxy->last = time((time_t *)0);
965 *rc = 1;
966 memcpy(dcw, data + 14, 16);
967 uint32_t crc = b2i(4, data + 30);
968 char tmp[32];
969 cs_log_dbg(D_READER, "-> dcw=%s, from peer=%04X, ecm_pid=%04X, sid=%04X, crc=%08X, type=%02X, dist=%01X, unkn=%01X, rev=%01X.%01X, chid=%04X",
970 cs_hexdump(0, dcw, 32, tmp, sizeof(tmp)),
971 data[10] << 8 | data[11], data[6] << 8 | data[7], data[8] << 8 | data[9], crc, data[41], data[42] & 0x0f, data[42] >> 4, data[43] >>4, data[43] & 0x0f, data[37] << 8 | data[38]);
972 struct timeb t_now;
973 cs_ftime(&t_now);
974 int64_t cw_time = GBOX_DEFAULT_CW_TIME;
975 for(i = 0; i < cfg.max_pending; i++)
977 if(proxy->ecmtask[i].gbox_crc == crc)
979 id_card = b2i(2, data + 10);
980 cw_time = comp_timeb(&t_now, &proxy->ecmtask[i].tps) - gbox_get_pending_time(&proxy->ecmtask[i], id_card, data[36]);
981 gbox_add_good_sid(id_card, proxy->ecmtask[i].caid, data[36], proxy->ecmtask[i].srvid, cw_time);
982 proxy->reader->currenthops = data[42] & 0x0f;
983 gbox_remove_all_bad_sids(&proxy->ecmtask[i], proxy->ecmtask[i].srvid);
984 if(proxy->ecmtask[i].gbox_ecm_status == GBOX_ECM_NOT_ASKED || proxy->ecmtask[i].gbox_ecm_status == GBOX_ECM_ANSWERED)
985 { return -1; }
986 proxy->ecmtask[i].gbox_ecm_status = GBOX_ECM_ANSWERED;
987 proxy->ecmtask[i].gbox_ecm_id = id_card;
988 *rc = 1;
989 return proxy->ecmtask[i].idx;
992 //late answers from other peers,timing not possible
993 gbox_add_good_sid(id_card, data[34] << 8 | data[35], data[36], data[8] << 8 | data[9], GBOX_DEFAULT_CW_TIME);
994 cs_log_dbg(D_READER, "no task found for crc=%08x", crc);
995 return -1;
998 static int8_t gbox_received_dcw(struct s_client *cli, uchar *data, int32_t n)
1000 struct gbox_peer *peer = cli->gbox;
1001 int32_t rc = 0, i = 0, idx = 0;
1002 uchar dcw[16];
1004 idx = gbox_recv_chk(cli, dcw, &rc, data, n);
1005 if(idx < 0) { return -1; } // no dcw received
1006 if(!idx) { idx = cli->last_idx; }
1007 peer->gbox_rev = data[43];
1008 cli->reader->last_g = time((time_t *)0); // for reconnect timeout
1009 for(i = 0; i < cfg.max_pending; i++)
1011 if(cli->ecmtask[i].idx == idx)
1013 cli->pending--;
1014 casc_check_dcw(cli->reader, i, rc, dcw);
1015 return 0;
1018 return -1;
1021 int32_t gbox_recv_cmd_switch(struct s_client *proxy, uchar *data, int32_t n)
1023 if (!data || !proxy) { return -1; }
1024 uint16_t cmd = gbox_decode_cmd(data);
1025 switch(cmd)
1027 case MSG_HERE:
1028 cs_log("-> HERE? from %s %s",username(proxy), proxy->reader->device);
1029 gbox_send_hello(proxy, GBOX_STAT_HELLOR);
1030 break;
1031 case MSG_GOODBYE:
1032 cs_log("-> goodbye message from %s %s",username(proxy), proxy->reader->device);
1033 //msg goodbye is an indication from peer that requested ECM failed (not found/rejected...)
1034 //TODO: implement on suitable place - rebroadcast ECM to other peers
1035 write_msg_info(proxy, MSGID_GOODBYE, 0, 0);
1036 break;
1037 case MSG_GSMS:
1038 if (!cfg.gsms_dis)
1040 cs_log("-> MSG_GSMS from %s %s", username(proxy), proxy->reader->device);
1041 gbox_send_gsms_ack(proxy);
1042 write_gsms_msg(proxy, data +16, data[14], data[15]);
1043 write_msg_info(proxy, MSGID_GSMS, 0, data[14]);
1045 else {gsms_unavail();}
1046 break;
1047 case MSG_GSMS_ACK:
1048 if (!cfg.gsms_dis)
1050 cs_log("-> MSG_GSMS_ACK from %s %s", username(proxy), proxy->reader->device);
1051 write_gsms_ack(proxy);
1053 else {gsms_unavail();}
1054 break;
1055 case MSG_HELLO1:
1056 case MSG_HELLO:
1057 if (gbox_cmd_hello_rcvd(proxy, data, n) < 0)
1058 { return -1; }
1059 break;
1060 case MSG_CW:
1061 gbox_received_dcw(proxy, data, n);
1062 break;
1063 case MSG_CHECKCODE:
1064 gbox_checkcode_recv(proxy, data + 10);
1065 if (cfg.log_hello)
1066 { cs_log("-> HelloC checkcode from %s - %s", username(proxy), proxy->reader->device);}
1067 else
1068 { cs_log_dbg(D_READER,"-> HelloC checkcode from %s - %s", username(proxy), proxy->reader->device);}
1069 break;
1070 case MSG_ECM:
1071 gbox_incoming_ecm(proxy, data, n);
1072 break;
1073 case MSG_REM_EMM:
1074 //cs_log_dbg(D_EMM,"-> Incoming REMM MSG (%d bytes) from %s - %s", n, username(proxy), proxy->reader->device);
1075 cs_log_dump_dbg(D_EMM, data, n, "-> gbox incoming REMM MSG - (len=%d bytes):", n);
1076 gbox_recvd_remm_cmd_switch(proxy, data, n);
1077 break;
1078 default:
1079 cs_log("-> unknown command %04X received from %s %s", cmd, username(proxy), proxy->reader->device);
1080 write_msg_info(proxy, MSGID_UNKNOWNMSG, 0, 0);
1081 cs_log_dump_dbg(D_READER, data, n, "unknown data (%d bytes) received from %s %s", n, username(proxy), proxy->reader->device);
1082 } // end switch
1084 if ((time(NULL) - last_stats_written) > STATS_WRITE_TIME)
1086 gbox_write_stats();
1087 last_stats_written = time(NULL);
1089 return 0;
1092 static uint8_t gbox_add_local_cards(struct s_reader *reader, TUNTAB *ttab)
1094 int32_t i;
1095 uint32_t prid = 0;
1096 uint8_t slot = 0;
1097 #ifdef MODULE_CCCAM
1098 LL_ITER it, it2;
1099 struct cc_card *card = NULL;
1100 struct cc_data *cc;
1101 uint32_t checksum = 0;
1102 uint16_t cc_peer_id = 0;
1103 struct cc_provider *provider;
1104 uint8_t *node1 = NULL;
1105 uint8_t min_reshare = 0;
1106 gbox_delete_cards(GBOX_DELETE_WITH_TYPE, GBOX_CARD_TYPE_CCCAM);
1107 #endif
1108 gbox_delete_cards(GBOX_DELETE_WITH_ID, local_gbox.id);
1109 struct s_client *cl;
1110 cs_readlock(__func__, &clientlist_lock);
1111 for(cl = first_client; cl; cl = cl->next)
1113 if(cl->typ == 'r' && cl->reader && cl->reader->card_status == CARD_INSERTED)
1115 slot = gbox_next_free_slot(local_gbox.id);
1116 //SECA, Viaccess and Cryptoworks have multiple providers
1117 if(caid_is_seca(cl->reader->caid) || caid_is_viaccess(cl->reader->caid) || caid_is_cryptoworks(cl->reader->caid))
1119 for(i = 0; i < cl->reader->nprov; i++)
1121 prid = cl->reader->prid[i][1] << 16 |
1122 cl->reader->prid[i][2] << 8 | cl->reader->prid[i][3];
1123 gbox_add_card(local_gbox.id, gbox_get_caprovid(cl->reader->caid, prid), slot, reader->gbox_reshare, 0, GBOX_CARD_TYPE_LOCAL, NULL);
1126 else
1128 gbox_add_card(local_gbox.id, gbox_get_caprovid(cl->reader->caid, 0), slot, reader->gbox_reshare, 0, GBOX_CARD_TYPE_LOCAL, NULL);
1130 //Check for Betatunnel on gbox account in oscam.user
1131 if (chk_is_betatunnel_caid(cl->reader->caid) == 1 && ttab->ttdata && cl->reader->caid == ttab->ttdata[0].bt_caidto)
1133 //For now only first entry in tunnel tab. No sense in iteration?
1134 //Add betatunnel card to transmitted list
1135 gbox_add_card(local_gbox.id, gbox_get_caprovid(ttab->ttdata[0].bt_caidfrom, 0), slot, reader->gbox_reshare, 0, GBOX_CARD_TYPE_BETUN, NULL);
1136 cs_log_dbg(D_READER, "gbox created betatunnel card for caid: %04X->%04X", ttab->ttdata[0].bt_caidfrom, cl->reader->caid);
1139 } //end local readers
1140 #ifdef MODULE_CCCAM
1141 if((cfg.ccc_reshare) && (cfg.cc_reshare > -1) && (reader->gbox_cccam_reshare) && cl->typ == 'p' && cl->reader && cl->reader->typ == R_CCCAM && cl->cc)
1143 cc = cl->cc;
1144 it = ll_iter_create(cc->cards);
1145 while((card = ll_iter_next(&it)))
1147 //calculate gbox id from cc node
1148 node1 = ll_has_elements(card->remote_nodes);
1149 checksum = ((node1[0] ^ node1[7]) << 8) |
1150 ((node1[1] ^ node1[6]) << 24) |
1151 (node1[2] ^ node1[5]) |
1152 ((node1[3] ^ node1[4]) << 16);
1153 cc_peer_id = ((((checksum >> 24) & 0xFF) ^((checksum >> 8) & 0xFF)) << 8 |
1154 (((checksum >> 16) & 0xFF) ^(checksum & 0xFF)));
1155 slot = gbox_next_free_slot(cc_peer_id);
1156 min_reshare = cfg.cc_reshare;
1157 if (card->reshare < min_reshare)
1158 { min_reshare = card->reshare; }
1159 min_reshare++; //strange CCCam logic. 0 means direct peers
1160 if (reader->gbox_cccam_reshare < min_reshare)
1161 { min_reshare = reader->gbox_cccam_reshare; }
1162 if(caid_is_seca(card->caid) || caid_is_viaccess(card->caid) || caid_is_cryptoworks(card->caid))
1164 it2 = ll_iter_create(card->providers);
1165 while((provider = ll_iter_next(&it2)))
1166 { gbox_add_card(cc_peer_id, gbox_get_caprovid(card->caid, provider->prov), slot, min_reshare, card->hop, GBOX_CARD_TYPE_CCCAM, NULL); }
1168 else
1169 { gbox_add_card(cc_peer_id, gbox_get_caprovid(card->caid, 0), slot, min_reshare, card->hop, GBOX_CARD_TYPE_CCCAM, NULL); }
1171 } //end cccam
1172 #endif
1173 } //end for clients
1174 cs_readunlock(__func__, &clientlist_lock);
1176 if (cfg.gbox_proxy_cards_num > 0)
1178 for (i = 0; i < cfg.gbox_proxy_cards_num; i++)
1180 slot = gbox_next_free_slot(local_gbox.id);
1181 gbox_add_card(local_gbox.id, cfg.gbox_proxy_card[i], slot, reader->gbox_reshare, 0, GBOX_CARD_TYPE_PROXY, NULL);
1182 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]));
1184 } //end add proxy reader cards
1185 gbox_write_local_cards_info();
1186 return slot;
1187 } //end add local gbox cards
1189 //returns -1 in case of error, 1 if authentication was performed, 0 else
1190 static int8_t gbox_check_header_recvd(struct s_client *cli, struct s_client *proxy, uchar *data, int32_t l)
1192 struct gbox_peer *peer = NULL;
1193 if (proxy) { peer = proxy->gbox; }
1195 char tmp[0x50];
1196 uint8_t crd =0;
1197 int32_t n = l;
1198 uint8_t authentication_done = 0;
1199 uint16_t peer_recvd_id = 0;
1200 uint32_t my_received_pw = 0;
1201 uint32_t peer_received_pw = 0;
1202 cs_log_dump_dbg(D_READER, data, n, "-> encrypted data (%d bytes) from %s:", n, cs_inet_ntoa(cli->ip));
1203 gbox_decrypt(data, n, local_gbox.password);
1204 cs_log_dump_dbg(D_READER, data, n, "-> decrypted data (%d bytes) from %s:", n, cs_inet_ntoa(cli->ip));
1205 //verify my pass received
1206 my_received_pw = b2i(4, data + 2);
1207 if (my_received_pw == local_gbox.password)
1209 if (gbox_decode_cmd(data) != MSG_CW)
1211 peer_received_pw = b2i(4, data + 6);
1212 peer_recvd_id = gbox_convert_password_to_id(peer_received_pw);
1213 //cs_log_dbg(D_READER, "-> data from IP: %s", cs_inet_ntoa(cli->ip));
1214 cs_log_dbg(D_READER, "-> data from peer: %04X data: %s", peer_recvd_id, cs_hexdump(0, data, l, tmp, sizeof(tmp)));
1215 //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);
1216 if (check_peer_ignored(peer_recvd_id))
1218 handle_attack(cli, GBOX_ATTACK_PEER_IGNORE, peer_recvd_id);
1219 cs_log("Peer blocked by conf - ignoring gbox peer_id: %04X", peer_recvd_id);
1220 return -1;
1222 if (!validate_peerpass(peer_received_pw))
1224 handle_attack(cli, GBOX_ATTACK_PEER_PW, peer_recvd_id);
1225 cs_log("peer: %04X - peerpass: %08X unknown -> check [reader] section", peer_recvd_id, peer_received_pw);
1226 return -1;
1228 if (cli->gbox_peer_id == NO_GBOX_ID)
1230 if (gbox_auth_client(cli, peer_received_pw) < 0)
1232 handle_attack(cli, GBOX_ATTACK_AUTH_FAIL, peer_recvd_id);
1233 cs_log ("Peer %04X:%s authentication failed. Check user in [account] or {reader] section", peer_recvd_id, cs_inet_ntoa(cli->ip));
1234 return -1;
1236 authentication_done = 1;
1237 proxy = get_gbox_proxy(cli->gbox_peer_id);
1238 if (!local_cards_initialized)
1240 local_cards_initialized = 1;
1241 local_card_change_detected = 0;
1242 crd = gbox_add_local_cards(proxy->reader, &cli->ttab);
1243 cs_log("Local cards initialized - cards: %d", crd);
1245 peer = proxy->gbox;
1247 if (!peer) { return -1; }
1249 if (peer_received_pw != peer->gbox.password)
1251 cs_log("gbox peer: %04X sends wrong own password", peer->gbox.id);
1252 return -1;
1255 else //is MSG_CW
1257 cs_log_dbg(D_READER, "-> CW data from peer: %04X data: %s", cli->gbox_peer_id, cs_hexdump(0, data, l, tmp, sizeof(tmp)));
1258 // if my pass ok verify CW | pass to peer
1259 if((data[39] != ((local_gbox.id >> 8) & 0xff)) || (data[40] != (local_gbox.id & 0xff)))
1261 cs_log("gbox peer: %04X sends CW for other than my id: %04X", cli->gbox_peer_id, local_gbox.id);
1262 return -1;
1266 else // error my passw
1268 cs_log("-> ATTACK ALERT from IP %s - peer sends wrong local password", cs_inet_ntoa(cli->ip));
1269 cs_log_dbg(D_READER,"-> received data: %s", cs_hexdump(0, data, n, tmp, sizeof(tmp)));
1270 handle_attack(cli, GBOX_ATTACK_LOCAL_PW, 0);
1271 return -1;
1273 if (!proxy) { return -1; }
1275 if (!IP_EQUAL(cli->ip, proxy->ip))
1277 cs_log("IP change received - peer %04X. Previous IP = %s. Reconnecting...", cli->gbox_peer_id, cs_inet_ntoa(proxy->ip));
1278 gbox_reconnect_client(cli->gbox_peer_id);
1279 write_msg_info(cli, MSGID_IPCHANGE, 0, 0);
1280 return -1;
1282 if(!peer) { return -1; }
1284 if (local_card_change_detected)
1286 local_card_change_detected = 0;
1287 crd = gbox_add_local_cards(proxy->reader, &cli->ttab);
1288 cs_log("Local cards update - cards: %d", crd);
1291 if(!peer->authstat)
1293 peer->authstat = 1;
1294 cs_log("peer %04X authenticated successfully", cli->gbox_peer_id);
1296 return authentication_done;
1299 static int32_t gbox_recv(struct s_client *cli, uchar *buf, int32_t l)
1301 uchar data[RECEIVE_BUFFER_SIZE];
1302 int32_t n = l, tmp;
1303 int8_t ret = 0;
1305 if(!cli->udp_fd || !cli->is_udp || cli->typ != 'c')
1306 { return -1; }
1308 n = recv_from_udpipe(buf);
1309 if (n < MIN_GBOX_MESSAGE_LENGTH || n >= RECEIVE_BUFFER_SIZE) //protect against too short or too long messages
1310 { return -1; }
1312 struct s_client *proxy = get_gbox_proxy(cli->gbox_peer_id);
1314 memcpy(&data[0], buf, n);
1316 ret = gbox_check_header_recvd(cli, proxy, &data[0], n);
1317 if (ret < 0) { return -1; }
1319 //in case of new authentication the proxy gbox can now be found
1320 if (ret) { proxy = get_gbox_proxy(cli->gbox_peer_id); }
1322 if (!proxy) { return -1; }
1324 cli->last = time((time_t *)0);
1325 //clients may timeout - attach to peer's gbox/reader
1326 cli->gbox = proxy->gbox; //point to the same gbox as proxy
1327 cli->reader = proxy->reader; //point to the same reader as proxy
1328 struct gbox_peer *peer = proxy->gbox;
1329 cs_writelock(__func__, &peer->lock);
1330 tmp = gbox_recv_cmd_switch(proxy, data, n);
1331 cs_writeunlock(__func__, &peer->lock);
1333 if(tmp < 0)
1334 { return -1; }
1336 return 0;
1339 static void gbox_send_dcw(struct s_client *cl, ECM_REQUEST *er)
1341 if (!cl || !er) { return; }
1343 struct s_client *cli = get_gbox_proxy(cl->gbox_peer_id);
1344 if (!cli || !cli->gbox) { return; }
1345 struct gbox_peer *peer = cli->gbox;
1347 if(er->rc >= E_NOTFOUND)
1349 cs_log_dbg(D_READER, "unable to decode!");
1350 gbox_send_goodbye(cli);
1351 return;
1354 uchar buf[60];
1355 memset(buf, 0, sizeof(buf));
1357 struct gbox_ecm_request_ext *ere = er->src_data;
1359 gbox_message_header(buf, MSG_CW , peer->gbox.password, 0);
1360 i2b_buf(2, er->pid, buf + 6); //PID
1361 i2b_buf(2, er->srvid, buf + 8); //SrvID
1362 i2b_buf(2, ere->gbox_mypeer, buf + 10); //From peer
1363 buf[12] = (ere->gbox_slot << 4) | (er->ecm[0] & 0x0f); //slot << 4 | even/odd
1364 buf[13] = er->caid >> 8; //CAID first byte
1365 memcpy(buf + 14, er->cw, 16); //CW
1366 i2b_buf(4, er->gbox_crc, buf + 30); //CRC
1367 i2b_buf(2, er->caid, buf + 34); //CAID
1368 buf[36] = ere->gbox_slot; //Slot
1369 if (buf[34] == 0x06) //if irdeto
1370 { i2b_buf(2, er->chid, buf + 37); } //CHID
1371 else
1373 if (local_gbox.minor_version == 0x2A)
1375 buf[37] = 0xff; //gbox.net sends 0xff
1376 buf[38] = 0xff; //gbox.net sends 0xff
1378 else
1380 buf[37] = 0; //gbox sends 0
1381 buf[38] = 0; //gbox sends 0
1384 i2b_buf(2, ere->gbox_peer, buf + 39); //Target peer
1385 if (er->rc == E_CACHE1 || er->rc == E_CACHE2 || er->rc == E_CACHEEX)
1386 { buf[41] = 0x03; } //source of cw -> cache
1387 else
1388 { buf[41] = 0x01; } //source of cw -> card, emu
1389 buf[42] = 0x30; //1st nibble unknown / 2nd nibble distance // to fix - dist always 0
1390 //buf[42] = 0x30 | (ere->gbox_hops & 0x0f);
1391 // buf[43] = ere->gbox_rev;
1392 buf[43] = local_gbx_rev;
1393 //This copies the routing info from ECM to answer.
1394 //Each hop adds one byte and number of hops is in er->gbox_hops.
1395 memcpy(&buf[44], &ere->gbox_routing_info, ere->gbox_hops - 1);
1396 buf[44 + ere->gbox_hops - 1] = ere->gbox_hops - 1; //Hops
1398 char tmp[0x50];
1399 cs_log("sending dcw to peer : %04x data: %s", er->gbox_peer, cs_hexdump(0, buf, er->gbox_hops + 44, tmp, sizeof(tmp)));
1401 gbox_send(cli, buf, ere->gbox_hops + 44); // to fix: ere->gbox_hops always 1
1403 if ( ere->gbox_rev >> 4 )
1405 gbox_send_remm_req(cli, er);
1407 cs_log_dbg(D_READER, "<- CW (<- %d) from %04X to %04X rev:%01X.%01X %s port:%d ", ere->gbox_hops, ere->gbox_mypeer, ere->gbox_peer, ere->gbox_rev >> 4, ere->gbox_rev & 0x0f, cli->reader->label, cli->port);
1410 /* // see r11270
1411 void *gbox_rebroadcast_thread(struct gbox_rbc_thread_args *args)
1413 if (!args) { return NULL; }
1415 struct s_client *cli = args->cli;
1416 ECM_REQUEST *er = args->er;
1417 uint32_t waittime = args->waittime;
1419 //NEEDFIX currently the next line avoids a second rebroadcast
1420 if (!is_valid_client(cli)) { return NULL; }
1422 SAFE_MUTEX_LOCK(&cli->thread_lock);
1423 cli->thread_active = 1;
1424 SAFE_SETSPECIFIC(getclient, cli);
1425 set_thread_name(__func__);
1426 cli->thread_active = 0;
1427 SAFE_MUTEX_UNLOCK(&cli->thread_lock);
1429 cs_sleepms(waittime);
1430 if (!cli || cli->kill || !cli->gbox || !er) { return NULL; }
1431 SAFE_MUTEX_LOCK(&cli->thread_lock);
1432 cli->thread_active = 1;
1434 struct gbox_peer *peer = cli->gbox;
1436 struct timeb t_now, tbc;
1437 cs_ftime(&t_now);
1439 tbc = er->tps;
1440 add_ms_to_timeb_diff(&tbc, cfg.ctimeout);
1441 int32_t time_to_timeout = (int32_t) comp_timeb(&tbc, &t_now);
1443 //ecm is not answered yet and still chance to get CW
1444 if (er->rc >= E_NOTFOUND && time_to_timeout > GBOX_DEFAULT_CW_TIME)
1446 cs_writelock(__func__, &peer->lock);
1447 gbox_send_ecm(cli, er);
1448 cs_writeunlock(__func__, &peer->lock);
1450 cli->thread_active = 0;
1451 SAFE_MUTEX_UNLOCK(&cli->thread_lock);
1453 return NULL;
1457 static int32_t gbox_send_ecm(struct s_client *cli, ECM_REQUEST *er)
1459 if(!cli || !er || !cli->reader)
1460 { return -1; }
1462 if(!cli->gbox || !cli->reader->tcp_connected)
1464 cs_log_dbg(D_READER, "%s server not init!", cli->reader->label);
1465 write_ecm_answer(cli->reader, er, E_NOTFOUND, 0x27, NULL, NULL, 0, NULL);
1466 return -1;
1469 struct gbox_peer *peer = cli->gbox;
1471 if(!peer->filtered_cards)
1473 cs_log_dbg(D_READER, "Send ECM failed, %s NO CARDS!", cli->reader->label);
1474 write_ecm_answer(cli->reader, er, E_NOTFOUND, E2_CCCAM_NOCARD, NULL, NULL, 0, NULL);
1475 return -1;
1478 if(!peer->online)
1480 cs_log_dbg(D_READER, "Send ECM failed, peer is OFFLINE!");
1481 write_ecm_answer(cli->reader, er, E_NOTFOUND, 0x27, NULL, NULL, 0, NULL);
1482 // gbox_send_hello(cli,0);
1483 return -1;
1486 if(er->gbox_ecm_status == GBOX_ECM_ANSWERED)
1487 { cs_log_dbg(D_READER, "%s replied to this ecm already", cli->reader->label); }
1489 if(er->gbox_ecm_status == GBOX_ECM_NOT_ASKED)
1490 { er->gbox_cards_pending = ll_create("pending_gbox_cards"); }
1492 if(er->gbox_ecm_id == peer->gbox.id)
1494 cs_log_dbg(D_READER, "%s provided ecm", cli->reader->label);
1495 write_ecm_answer(cli->reader, er, E_NOTFOUND, 0x27, NULL, NULL, 0, NULL);
1496 return 0;
1499 uchar send_buf[1024];
1500 int32_t buflen, len1;
1502 if(!er->ecmlen) { return 0; }
1504 len1 = er->ecmlen + 18; // length till end of ECM
1506 er->gbox_crc = gbox_get_checksum(&er->ecm[0], er->ecmlen);
1508 memset(send_buf, 0, sizeof(send_buf));
1510 uint8_t nb_matching_crds = 0;
1511 uint8_t max_ecm_reached = 0;
1512 uint32_t current_avg_card_time = 0;
1514 gbox_message_header(send_buf, MSG_ECM , peer->gbox.password, local_gbox.password);
1515 i2b_buf(2, er->pid, send_buf + 10);
1516 i2b_buf(2, er->srvid, send_buf + 12);
1517 send_buf[14] = 0x00;
1518 send_buf[15] = 0x00;
1519 //send_buf[16] = nb_matching_crds; //Number of cards the ECM should be forwarded to
1520 send_buf[17] = 0x00;
1521 memcpy(send_buf + 18, er->ecm, er->ecmlen);
1523 i2b_buf(2, local_gbox.id, send_buf + len1);
1524 send_buf[len1 + 2] = cfg.gbox_my_vers;
1525 send_buf[len1 + 3] = local_gbx_rev;
1526 send_buf[len1 + 4] = gbox_get_my_cpu_api();
1528 uint32_t caprovid = gbox_get_caprovid(er->caid, er->prid);
1529 i2b_buf(4, caprovid, send_buf + len1 + 5);
1531 send_buf[len1 + 9] = 0x00;
1532 buflen = len1 + 10;
1534 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);
1535 if (nb_matching_crds == cli->reader->gbox_maxecmsend)
1536 { max_ecm_reached = 1; }
1537 buflen += nb_matching_crds * 3;
1539 if(!nb_matching_crds && er->gbox_ecm_status == GBOX_ECM_NOT_ASKED)
1541 cs_log_dbg(D_READER, "no valid card found for CAID: %04X PROVID: %04X", er->caid, er->prid);
1542 write_ecm_answer(cli->reader, er, E_NOTFOUND, E2_CCCAM_NOCARD, NULL, NULL, 0, NULL);
1543 return -1;
1545 if(nb_matching_crds)
1547 send_buf[16] = nb_matching_crds; //Number of cards the ECM should be forwarded to
1549 //distance ECM
1550 send_buf[buflen] = 0; //fix me! if ecm to be forwarded -> must add +1
1551 buflen++;
1553 memcpy(&send_buf[buflen], gbox_get_my_checkcode(), 7);
1554 buflen = buflen + 7;
1555 memcpy(&send_buf[buflen], peer->checkcode, 7);
1556 buflen = buflen + 7;
1558 uint32_t i = 0;
1559 struct gbox_card_pending *pending = NULL;
1560 struct timeb t_now;
1561 cs_ftime(&t_now);
1562 for (i = 0; i < nb_matching_crds; i++)
1564 if(!cs_malloc(&pending, sizeof(struct gbox_card_pending)))
1566 cs_log("Can't allocate gbox card pending");
1567 return -1;
1569 pending->id.peer = (send_buf[len1+10+i*3] << 8) | send_buf[len1+11+i*3];
1570 pending->id.slot = send_buf[len1+12+i*3];
1571 pending->pending_time = comp_timeb(&t_now, &er->tps);
1573 ll_append(er->gbox_cards_pending, pending);
1574 cs_log_dbg(D_READER, "matching gbox card(s): %d, ID: %04X, Slot: %02X", i+1, (send_buf[len1+10+i*3] << 8) | send_buf[len1+11+i*3], send_buf[len1+12+i*3]);
1577 LL_LOCKITER *li = ll_li_create(er->gbox_cards_pending, 0);
1578 while ((pending = ll_li_next(li)))
1579 { cs_log_dbg(D_READER, "Pending Card ID: %04X Slot: %02X Time: %d", pending->id.peer, pending->id.slot, pending->pending_time); }
1580 ll_li_destroy(li);
1582 if(er->gbox_ecm_status > GBOX_ECM_NOT_ASKED)
1583 { er->gbox_ecm_status++; }
1584 else
1586 if(max_ecm_reached)
1587 { er->gbox_ecm_status = GBOX_ECM_SENT; }
1588 else
1589 { er->gbox_ecm_status = GBOX_ECM_SENT_ALL; }
1590 cli->pending++;
1592 cs_log_dbg(D_READER, "sending ecm for %04X@%06X sid: %04X to %d card(s) of %s", er->caid, er->prid , er->srvid, nb_matching_crds, cli->reader->label);
1593 gbox_send(cli, send_buf, buflen);
1594 cli->reader->last_s = time((time_t *) 0);
1596 /* // see r11270
1597 if(er->gbox_ecm_status < GBOX_ECM_ANSWERED)
1599 //Create thread to rebroacast ecm after time
1600 struct gbox_rbc_thread_args args;
1601 args.cli = cli;
1602 args.er = er;
1603 if ((current_avg_card_time > 0) && (cont_card_1 == 1))
1605 args.waittime = current_avg_card_time + (current_avg_card_time / 2);
1606 if (args.waittime < GBOX_MIN_REBROADCAST_TIME)
1607 { args.waittime = GBOX_MIN_REBROADCAST_TIME; }
1609 else
1610 { args.waittime = GBOX_REBROADCAST_TIMEOUT; }
1611 cs_log_dbg(D_READER, "Creating rebroadcast thread with waittime: %d", args.waittime);
1612 int32_t ret = start_thread("rebroadcast", (void *)gbox_rebroadcast_thread, &args, NULL, 1, 1);
1613 if(ret)
1615 return -1;
1618 else
1619 */ { er->gbox_ecm_status--; }
1621 return 0;
1624 //init my gbox with id, password and cards crc
1625 static int8_t init_local_gbox(void)
1627 int32_t i;
1628 local_gbox.id = 0;
1629 local_gbox.password = 0;
1630 local_gbox.minor_version = cfg.gbox_my_vers;
1631 local_gbox.cpu_api = gbox_get_my_cpu_api();
1632 init_gbox_cards();
1634 if(!cfg.gbox_port[0])
1636 cs_log("error, no/invalid port=%d configured in oscam.conf!", cfg.gbox_port[0] ? cfg.gbox_port[0] : 0);
1637 return -1;
1639 if(!cfg.gbox_hostname || strlen(cfg.gbox_hostname) > 128)
1641 cs_log("error, no/invalid hostname '%s' configured in oscam.conf!",
1642 cfg.gbox_hostname ? cfg.gbox_hostname : "");
1643 return -1;
1645 if(!cfg.gbox_password )
1647 cs_log("error, 'my_password' not configured in oscam.conf!");
1648 return -1;
1650 if(!cfg.gbox_reconnect || cfg.gbox_reconnect > GBOX_MAX_RECONNECT || cfg.gbox_reconnect < GBOX_MIN_RECONNECT)
1652 cs_log("Invalid 'gbox_reconnect = %d' Using default: %d sec",cfg.gbox_reconnect, DEFAULT_GBOX_RECONNECT);
1653 cfg.gbox_reconnect = DEFAULT_GBOX_RECONNECT;
1656 local_gbox.password = cfg.gbox_password;
1657 local_gbox.id = gbox_convert_password_to_id(local_gbox.password);
1659 if(!local_gbox.id)
1661 cs_log("invalid 'my_password' %08X -> local gbox id: %04X, choose another 'my_password'", cfg.gbox_password, local_gbox.id);
1662 return -1;
1665 local_gbox_initialized = 1;
1667 for(i = 0; i < CS_MAXPORTS; i++)
1669 if(!cfg.gbox_port[i])
1671 cs_log("we are online - %d port(s) to monitor", i);
1672 break;
1676 last_stats_written = time(NULL);
1677 gbox_write_version();
1678 start_sms_sender();
1679 return local_gbox_initialized;
1682 static int32_t gbox_peer_init(struct s_client *cli)
1684 if (!cli || cli->typ != 'p' || !cli->reader)
1686 cs_log("error, wrong call to gbox_peer_init!");
1687 return -1;
1690 if (local_gbox_initialized < 0) { return -1; }
1692 int8_t ret;
1693 if (!local_gbox_initialized)
1695 local_gbox_initialized = 1;
1696 ret = init_local_gbox();
1697 if (ret < 0)
1699 local_gbox_initialized = -1;
1700 cs_log("local gbox initialization failed");
1701 write_msg_info(cli, MSGID_GBOXONL, 0, 0);
1702 return -1;
1704 write_msg_info(cli, MSGID_GBOXONL, 0, 1);
1707 if(!cs_malloc(&cli->gbox, sizeof(struct gbox_peer)))
1708 { return -1; }
1710 struct s_reader *rdr = cli->reader;
1711 struct gbox_peer *peer = cli->gbox;
1713 memset(peer, 0, sizeof(struct gbox_peer));
1715 peer->gbox.password = a2i(rdr->r_pwd, 4);
1716 //cs_log_dbg(D_READER,"peer-reader-label: %s peer-reader-password: %s", cli->reader->label, rdr->r_pwd);
1717 peer->gbox.id = gbox_convert_password_to_id(peer->gbox.password);
1718 if (get_gbox_proxy(peer->gbox.id) || peer->gbox.id == NO_GBOX_ID || peer->gbox.id == local_gbox.id)
1720 cs_log("error, double/invalid gbox id: %04X", peer->gbox.id);
1721 return -1;
1723 cs_lock_create(__func__, &peer->lock, "gbox_lock", 5000);
1725 gbox_clear_peer(peer);
1727 cli->gbox_peer_id = peer->gbox.id;
1729 cli->pfd = 0;
1730 cli->crypted = 1;
1732 rdr->card_status = CARD_NEED_INIT;
1733 rdr->tcp_connected = 0;
1735 set_null_ip(&cli->ip);
1737 if((cli->udp_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
1739 cs_log("socket creation failed (errno=%d %s)", errno, strerror(errno));
1740 cs_disconnect_client(cli);
1743 int32_t opt = 1;
1744 setsockopt(cli->udp_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1746 set_so_reuseport(cli->udp_fd);
1748 set_socket_priority(cli->udp_fd, cfg.netprio);
1750 memset((char *)&cli->udp_sa, 0, sizeof(cli->udp_sa));
1752 if(!hostResolve(rdr))
1753 { return 0; }
1755 cli->port = rdr->r_port;
1756 SIN_GET_FAMILY(cli->udp_sa) = AF_INET;
1757 SIN_GET_PORT(cli->udp_sa) = htons((uint16_t)rdr->r_port);
1758 hostname2ip(cli->reader->device, &SIN_GET_ADDR(cli->udp_sa));
1760 cs_log("proxy %s (fd=%d, peer id=%04X, my id=%04X, my hostname=%s, peer's listen port=%d)",
1761 rdr->device, cli->udp_fd, peer->gbox.id, local_gbox.id, cfg.gbox_hostname, rdr->r_port);
1763 cli->pfd = cli->udp_fd;
1765 gbox_send_hello(cli, GBOX_STAT_HELLOL);
1767 if(!cli->reader->gbox_maxecmsend)
1768 { cli->reader->gbox_maxecmsend = DEFAULT_GBOX_MAX_ECM_SEND; }
1770 if(!cli->reader->gbox_maxdist)
1771 { cli->reader->gbox_maxdist = DEFAULT_GBOX_MAX_DIST; }
1773 //value > GBOX_MAXHOPS not allowed in gbox network
1774 if(!cli->reader->gbox_reshare || cli->reader->gbox_reshare > GBOX_MAXHOPS)
1775 { cli->reader->gbox_reshare = GBOX_MAXHOPS; }
1777 if(!cli->reader->gbox_cccam_reshare || cli->reader->gbox_cccam_reshare > GBOX_MAXHOPS)
1778 { cli->reader->gbox_cccam_reshare = GBOX_MAXHOPS; }
1780 return 0;
1783 static void gbox_send_HERE(struct s_client *cli)
1785 struct gbox_peer *peer = cli->gbox;
1786 uchar outbuf[32];
1787 int32_t hostname_len = strlen(cfg.gbox_hostname);
1788 gbox_message_header(outbuf, MSG_HERE, peer->gbox.password, local_gbox.password);
1789 outbuf[0xA] = cfg.gbox_my_vers;
1790 outbuf[0xB] = gbox_get_my_cpu_api();
1791 memcpy(&outbuf[0xC], cfg.gbox_hostname, hostname_len);
1792 cs_log("gbox send 'HERE?' to boxid: %04X", peer->gbox.id);
1793 //cs_log_dump_dbg(D_READER, outbuf, hostname_len + 0xC, "<- send HERE?, (len=%d):", hostname_len + 0xC);
1794 cs_log_dump(outbuf, hostname_len + 0xC, "<- send HERE?, (len=%d):", hostname_len + 0xC);
1795 gbox_send(cli, outbuf, hostname_len + 0xC);
1799 static void gbox_peer_idle (struct s_client *cl)
1801 uint32_t ptime_elapsed, etime_elapsed;
1802 struct s_client *proxy = get_gbox_proxy(cl->gbox_peer_id);
1803 struct gbox_peer *peer;
1805 if (proxy && proxy->gbox)
1807 etime_elapsed = llabs(cl->lastecm - time(NULL));
1808 if (llabs(proxy->last - time(NULL)) > etime_elapsed )
1809 { ptime_elapsed = etime_elapsed; }
1810 else
1811 { ptime_elapsed = llabs(proxy->last - time(NULL)); }
1813 if (ptime_elapsed > (cfg.gbox_reconnect *2) && cl->gbox_peer_id != NO_GBOX_ID)
1815 //gbox peer apparently died without saying goodnight
1816 peer = proxy->gbox;
1817 cs_writelock(__func__, &peer->lock);
1818 if (peer->online)
1820 cs_log("Lost connection to: %s %s - taking peer %04X %s offline",proxy->reader->device, cs_inet_ntoa(proxy->ip), cl->gbox_peer_id, username(cl));
1821 cs_log_dbg(D_READER, "time since last proxy activity: %d sec > %d => lost connection - taking peer %04X - %s offline", ptime_elapsed, cfg.gbox_reconnect *2, cl->gbox_peer_id, username(cl));
1822 write_msg_info(proxy, MSGID_LOSTCONNECT, 0, 0);
1823 gbox_reinit_proxy(proxy);
1825 cs_writeunlock(__func__, &peer->lock);
1828 if (etime_elapsed > cfg.gbox_reconnect && cl->gbox_peer_id != NO_GBOX_ID)
1830 peer = proxy->gbox;
1831 cs_writelock(__func__, &peer->lock);
1833 if (!(check_peer_ignored(cl->gbox_peer_id)))
1835 if (!peer->online && ptime_elapsed < cfg.gbox_reconnect *3)
1837 cs_log_dbg(D_READER, "%04X - %s -> offline - time since last ecm / proxy_act: %d sec / %d sec => trigger HELLOL", cl->gbox_peer_id, username(cl), etime_elapsed, ptime_elapsed);
1838 gbox_send_hello(proxy, GBOX_STAT_HELLOL);
1839 //gbox_send_HERE(proxy);
1841 if (peer->online)
1843 cs_log_dbg(D_READER, "%04X - %s -> online - time since last ecm /proxy activity: %d sec / %d sec => trigger keepalive HELLOS", cl->gbox_peer_id, username(cl), etime_elapsed, ptime_elapsed);
1844 gbox_send_hello(proxy, GBOX_STAT_HELLOS);
1847 cs_writeunlock(__func__, &peer->lock);
1850 cl->last = time((time_t *)0);
1853 static int8_t gbox_send_peer_good_night(struct s_client *proxy)
1855 uchar outbuf[64];
1856 int32_t hostname_len = 0;
1857 if (cfg.gbox_hostname)
1858 { hostname_len = strlen(cfg.gbox_hostname); }
1859 int32_t len = hostname_len + 22;
1860 if(proxy->gbox && proxy->typ == 'p')
1862 struct gbox_peer *peer = proxy->gbox;
1863 struct s_reader *rdr = proxy->reader;
1864 if (peer->online)
1866 gbox_message_header(outbuf, MSG_HELLO, peer->gbox.password, local_gbox.password);
1867 outbuf[10] = 0x01;
1868 outbuf[11] = 0x80;
1869 memset(&outbuf[12], 0xff, 7);
1870 outbuf[19] = cfg.gbox_my_vers;
1871 outbuf[20] = gbox_get_my_cpu_api();
1872 memcpy(&outbuf[21], cfg.gbox_hostname, hostname_len);
1873 outbuf[21 + hostname_len] = hostname_len;
1874 cs_log("<- good night to %s:%d id: %04X", rdr->device, rdr->r_port, peer->gbox.id);
1875 gbox_compress(outbuf, len, &len);
1876 gbox_send(proxy, outbuf, len);
1877 gbox_reinit_proxy(proxy);
1880 return 0;
1883 void gbox_send_good_night(void)
1885 gbox_free_cardlist();
1886 struct s_client *cli;
1887 cs_readlock(__func__, &clientlist_lock);
1888 for(cli = first_client; cli; cli = cli->next)
1890 if(cli->gbox && cli->typ == 'p')
1891 { gbox_send_peer_good_night(cli); }
1893 cs_readunlock(__func__, &clientlist_lock);
1896 void gbox_send_goodbye(struct s_client *cli) // indication that requested ECM failed
1898 if (local_gbox.minor_version != 0x2A)
1900 uchar outbuf[15];
1901 struct gbox_peer *peer = cli->gbox;
1902 gbox_message_header(outbuf, MSG_GOODBYE, peer->gbox.password, local_gbox.password);
1903 cs_log_dbg(D_READER,"<- goodbye - requested ecm failed. Send info to requesting boxid: %04X", peer->gbox.id);
1904 gbox_send(cli, outbuf, 10);
1906 else
1907 { return; }
1910 void module_gbox(struct s_module *ph)
1912 int32_t i;
1913 for(i = 0; i < CS_MAXPORTS; i++)
1915 if(!cfg.gbox_port[i]) { break; }
1916 ph->ptab.nports++;
1917 ph->ptab.ports[i].s_port = cfg.gbox_port[i];
1919 ph->desc = "gbox";
1920 ph->num = R_GBOX;
1921 ph->type = MOD_CONN_UDP;
1922 ph->large_ecm_support = 1;
1923 ph->listenertype = LIS_GBOX;
1924 ph->s_handler = gbox_server;
1925 ph->s_init = gbox_server_init;
1926 ph->send_dcw = gbox_send_dcw;
1927 ph->recv = gbox_recv;
1928 ph->c_init = gbox_peer_init;
1929 ph->c_recv_chk = gbox_recv_chk;
1930 ph->c_send_ecm = gbox_send_ecm;
1931 ph->c_send_emm = gbox_send_remm_data;
1932 ph->s_peer_idle = gbox_peer_idle;
1934 #endif