1 #define MODULE_LOG_PREFIX "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)
44 cs_log_dbg(D_READER
, "Local card change detected");
45 local_card_change_detected
= 1;
49 char *get_gbox_tmp_fname(char *fext
)
51 static char gbox_tmpfile_buf
[64] = { 0 };
52 const char *slash
= "/";
55 snprintf(gbox_tmpfile_buf
, sizeof(gbox_tmpfile_buf
), "%s%s%s",get_tmp_dir(), slash
, fext
);
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)
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 ) {
81 case 0 : strcpy ( s_24,"No API");
83 case 1 : strcpy ( s_24,"API 1");
85 case 2 : strcpy ( s_24,"API 2");
87 case 3 : strcpy ( s_24,"API 3");
89 case 4 : strcpy ( s_24,"IBM API");
91 default : strcpy ( s_24," ");
96 unsigned char *GboxCPU( unsigned char a ) {
100 case 1 : strcpy ( s_23,"80X86 compatible CPU");
102 case 2 : strcpy ( s_23,"Motorola PowerPC MPC823 CPU");
104 case 3 : strcpy ( s_23,"IBM PowerPC STB CPU");
106 default : strcpy ( 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;}
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");
126 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
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
);}
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
))
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
);
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
);
166 if ((p
= popen(cmd
, "w")) == NULL
)
168 cs_log("Error %s",fname
);
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
);
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");
190 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
193 cs_readlock(__func__
, &clientlist_lock
);
195 for(cl
= first_client
; cl
; cl
= cl
->next
)
197 if(cl
->gbox
&& cl
->typ
== 'p')
199 struct gbox_peer
*peer
= cl
->gbox
;
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
);
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
);
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");
235 cs_log("Couldn't open %s: %s", get_gbox_tmp_fname(FILE_GBOX_VERSION
), strerror(errno
));
238 fprintf(fhandle
, "%02X.%02X my-id: %04X\n", LOCAL_GBOX_MAJOR_VERSION
, cfg
.gbox_my_vers
, local_gbox
.id
);
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
); }
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
)
273 ere
->gbox_mypeer
= 0;
275 ere
->gbox_version
= 0;
280 struct s_client
*get_gbox_proxy(uint16_t gbox_id
)
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
)
293 cs_readunlock(__func__
, &clientlist_lock
);
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();
306 static int8_t gbox_clear_peer(struct gbox_peer
*peer
)
308 if (!peer
) { return -1; }
311 peer
->next_hello
= 0;
313 gbox_delete_cards(GBOX_DELETE_FROM_PEER
, peer
->gbox
.id
);
314 gbox_peer_online(peer
, GBOX_PEER_OFFLINE
);
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;
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
);
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
)
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); }
366 { memset(++ptr
, 0, 7); }
368 *ptr
= local_gbox
.minor_version
;
369 *(++ptr
) = local_gbox
.cpu_api
;
370 memcpy(++ptr
, cfg
.gbox_hostname
, hostname_len
);
374 len
= ptr
- outbuf
+ 1;
377 case GBOX_STAT_HELLOL
:
379 { cs_log("<- HelloL to %s", cli
->reader
->label
);}
381 { cs_log_dbg(D_READER
,"<- HelloL to %s", cli
->reader
->label
);}
383 case GBOX_STAT_HELLOS
:
385 { cs_log("<- HelloS total cards %d to %s", nbcards
, cli
->reader
->label
);}
387 { cs_log_dbg(D_READER
,"<- HelloS total cards %d to %s", nbcards
, cli
->reader
->label
);}
389 case GBOX_STAT_HELLOR
:
391 { cs_log("<- HelloR total cards %d to %s", nbcards
, cli
->reader
->label
);}
393 { cs_log_dbg(D_READER
,"<- HelloR total cards %d to %s", nbcards
, cli
->reader
->label
);}
397 { cs_log("<- hello total cards %d to %s", nbcards
, cli
->reader
->label
);}
399 { cs_log_dbg(D_READER
,"<- hello total cards %d to %s", nbcards
, cli
->reader
->label
);}
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
)
413 cs_log("Invalid call to gbox_send_hello with proxy");
416 uint16_t nbcards
= 0;
417 uint16_t nbcards_cnt
= 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");
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) &&
440 (card
->dist
<= peer
->my_user
->account
->cccmaxhops
) &&
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;
455 if(nbcards_cnt
== MAX_GBOX_CARDS
)
457 cs_log("max cards gbox_send_hello with peer reached");
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
);
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
);
477 void gbox_reconnect_client(uint16_t gbox_id
)
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
)
500 cs_log("gbox_server %s/%d", cli
->reader
->label
, cli
->port
);
501 // gbox_check_header_recvd(cli, NULL, b, l);
506 char *gbox_username(struct s_client
*client
)
508 if(!client
) { return "anonymous"; }
510 if(client
->reader
->r_usr
[0])
511 { return client
->reader
->r_usr
; }
515 static int8_t gbox_disconnect_double_peers(struct s_client
*cli
)
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
)
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
);
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
);
564 static void gbox_server_init(struct s_client
*cl
)
566 cs_writelock(__func__
, &clientlist_lock
);
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
;
577 cs_writeunlock(__func__
, &clientlist_lock
);
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);
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;
601 int16_t ncards_in_msg
= 0;
605 caprovid
= ptr
[0] << 24 | ptr
[1] << 16 | ptr
[2] << 8 | ptr
[3];
607 ncards_in_msg
+= ptr
[4];
609 if(chk_ctab(gbox_get_caid(caprovid
), ctab
))
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
623 { ptr
+= 5 + ptr
[4] * 4; } //skip cards because caid
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
);
641 static void gbox_send_checkcode(struct s_client
*cli
)
643 struct gbox_peer
*peer
= cli
->gbox
;
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;
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
);
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
);
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))
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)
708 { peer
->total_cards
+= cards_number
; }
710 if(data
[11] & 0x80) //last packet
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
);
725 memset(&tmpbuf
[0], 0, 7);
726 if (data
[11] == 0x80 && !memcmp(data
+12,tmpbuf
,7))
728 gbox_peer_online(peer
, GBOX_PEER_ONLINE
);
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
);}
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
);}
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
); }
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
);
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
); }
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
);
753 { cs_log("<- HelloC my checkcode to %s (%s:%d)", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
);}
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
);}
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
; }
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
++; }
776 static int8_t is_blocked_peer(uint16_t peer_id
)
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
)
790 static int8_t check_peer_ignored(uint16_t peer_id
)
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
)
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
);
820 cs_readunlock(__func__
, &clientlist_lock
);
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
;
830 int32_t diffcheck
= 0;
833 if (!peer
|| !peer
->my_user
) { 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!");
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
);
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
)))
872 uchar
*ecm
= data
+ 18; //offset of ECM in gbx message
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); }
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
);
917 //checkcode did not match gbox->peer checkcode
920 // TODO: Send HelloS here?
921 // gbox->peer.hello_stat = GBOX_STAT_HELLOS;
922 // gbox_send_hello(cli);
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
;
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)
952 uint16_t id_card
= 0;
953 struct s_client
*proxy
;
955 { proxy
= get_gbox_proxy(cli
->gbox_peer_id
); }
958 if (!proxy
|| !proxy
->reader
)
960 cs_log("error, gbox_recv_chk, proxy not found");
961 gbox_send_goodbye(cli
);
964 proxy
->last
= time((time_t *)0);
966 memcpy(dcw
, data
+ 14, 16);
967 uint32_t crc
= b2i(4, data
+ 30);
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]);
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
)
986 proxy
->ecmtask
[i
].gbox_ecm_status
= GBOX_ECM_ANSWERED
;
987 proxy
->ecmtask
[i
].gbox_ecm_id
= id_card
;
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
);
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;
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
)
1014 casc_check_dcw(cli
->reader
, i
, rc
, dcw
);
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
);
1028 cs_log("-> HERE? from %s %s",username(proxy
), proxy
->reader
->device
);
1029 gbox_send_hello(proxy
, GBOX_STAT_HELLOR
);
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);
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();}
1050 cs_log("-> MSG_GSMS_ACK from %s %s", username(proxy
), proxy
->reader
->device
);
1051 write_gsms_ack(proxy
);
1053 else {gsms_unavail();}
1057 if (gbox_cmd_hello_rcvd(proxy
, data
, n
) < 0)
1061 gbox_received_dcw(proxy
, data
, n
);
1064 gbox_checkcode_recv(proxy
, data
+ 10);
1066 { cs_log("-> HelloC checkcode from %s - %s", username(proxy
), proxy
->reader
->device
);}
1068 { cs_log_dbg(D_READER
,"-> HelloC checkcode from %s - %s", username(proxy
), proxy
->reader
->device
);}
1071 gbox_incoming_ecm(proxy
, data
, n
);
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
);
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
);
1084 if ((time(NULL
) - last_stats_written
) > STATS_WRITE_TIME
)
1087 last_stats_written
= time(NULL
);
1092 static uint8_t gbox_add_local_cards(struct s_reader
*reader
, TUNTAB
*ttab
)
1099 struct cc_card
*card
= NULL
;
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
);
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
);
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
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
)
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
); }
1169 { gbox_add_card(cc_peer_id
, gbox_get_caprovid(card
->caid
, 0), slot
, min_reshare
, card
->hop
, GBOX_CARD_TYPE_CCCAM
, NULL
); }
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();
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
; }
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
);
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
);
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
));
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
);
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
);
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
);
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);
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);
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
);
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
];
1305 if(!cli
->udp_fd
|| !cli
->is_udp
|| cli
->typ
!= 'c')
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
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
);
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
);
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
1373 if (local_gbox
.minor_version
== 0x2A)
1375 buf
[37] = 0xff; //gbox.net sends 0xff
1376 buf
[38] = 0xff; //gbox.net sends 0xff
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
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
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
);
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;
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);
1457 static int32_t gbox_send_ecm(struct s_client
*cli
, ECM_REQUEST
*er
)
1459 if(!cli
|| !er
|| !cli
->reader
)
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
);
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
);
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);
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
);
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;
1534 nb_matching_crds
= gbox_get_cards_for_ecm(&send_buf
[0], len1
+ 10, cli
->reader
->gbox_maxecmsend
, er
, ¤t_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
);
1545 if(nb_matching_crds
)
1547 send_buf
[16] = nb_matching_crds
; //Number of cards the ECM should be forwarded to
1550 send_buf
[buflen
] = 0; //fix me! if ecm to be forwarded -> must add +1
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;
1559 struct gbox_card_pending
*pending
= NULL
;
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");
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
); }
1582 if(er
->gbox_ecm_status
> GBOX_ECM_NOT_ASKED
)
1583 { er
->gbox_ecm_status
++; }
1587 { er
->gbox_ecm_status
= GBOX_ECM_SENT
; }
1589 { er
->gbox_ecm_status
= GBOX_ECM_SENT_ALL
; }
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);
1597 if(er->gbox_ecm_status < GBOX_ECM_ANSWERED)
1599 //Create thread to rebroacast ecm after time
1600 struct gbox_rbc_thread_args args;
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; }
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);
1619 */ { er
->gbox_ecm_status
--; }
1624 //init my gbox with id, password and cards crc
1625 static int8_t init_local_gbox(void)
1629 local_gbox
.password
= 0;
1630 local_gbox
.minor_version
= cfg
.gbox_my_vers
;
1631 local_gbox
.cpu_api
= gbox_get_my_cpu_api();
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);
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
: "");
1645 if(!cfg
.gbox_password
)
1647 cs_log("error, 'my_password' not configured in oscam.conf!");
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
);
1661 cs_log("invalid 'my_password' %08X -> local gbox id: %04X, choose another 'my_password'", cfg
.gbox_password
, local_gbox
.id
);
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
);
1676 last_stats_written
= time(NULL
);
1677 gbox_write_version();
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!");
1690 if (local_gbox_initialized
< 0) { return -1; }
1693 if (!local_gbox_initialized
)
1695 local_gbox_initialized
= 1;
1696 ret
= init_local_gbox();
1699 local_gbox_initialized
= -1;
1700 cs_log("local gbox initialization failed");
1701 write_msg_info(cli
, MSGID_GBOXONL
, 0, 0);
1704 write_msg_info(cli
, MSGID_GBOXONL
, 0, 1);
1707 if(!cs_malloc(&cli
->gbox
, sizeof(struct gbox_peer
)))
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
);
1723 cs_lock_create(__func__
, &peer
->lock
, "gbox_lock", 5000);
1725 gbox_clear_peer(peer
);
1727 cli
->gbox_peer_id
= peer
->gbox
.id
;
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
);
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
))
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
; }
1783 static void gbox_send_HERE(struct s_client *cli)
1785 struct gbox_peer *peer = cli->gbox;
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
; }
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
1817 cs_writelock(__func__
, &peer
->lock
);
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
)
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);
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
)
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
;
1866 gbox_message_header(outbuf
, MSG_HELLO
, peer
->gbox
.password
, local_gbox
.password
);
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
);
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)
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);
1910 void module_gbox(struct s_module
*ph
)
1913 for(i
= 0; i
< CS_MAXPORTS
; i
++)
1915 if(!cfg
.gbox_port
[i
]) { break; }
1917 ph
->ptab
.ports
[i
].s_port
= cfg
.gbox_port
[i
];
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
;