4 # include "csgbox/gbox.h"
5 # define CS_VERSION_X CS_VERSION "-gbx-" GBXVERSION
7 # define CS_VERSION_X CS_VERSION
9 /*****************************************************************************
11 *****************************************************************************/
12 int pfd
=0; // Primary FD, must be closed on exit
13 int mfdr
=0; // Master FD (read)
14 int fd_m2c
=0; // FD Master -> Client (for clients / read )
15 int fd_c2m
=0; // FD Client -> Master (for clients / write )
16 int fd_c2l
=0; // FD Client -> Logger (for clients / write )
17 int cs_dblevel
=0; // Debug Level (TODO !!)
18 int cs_idx
=0; // client index (0=master, ...)
19 int cs_ptyp
=D_MASTER
; // process-type
20 struct s_module ph
[CS_MAX_MOD
]; // Protocols
21 int maxph
=0; // Protocols used
22 int cs_hw
=0; // hardware autodetect
23 int is_server
=0; // used in modules to specify function
24 int premhack
=0; // used to activate premiere hack 1801 -> 1702
25 pid_t master_pid
=0; // master pid OUTSIDE shm
26 ushort len4caid
[256]; // table for guessing caid (by len)
27 char cs_confdir
[128]=CS_CONFDIR
;
28 uchar mbuf
[1024]; // global buffer
32 struct s_acasc ac_stat
[CS_MAXPID
];
35 /*****************************************************************************
37 *****************************************************************************/
38 int *ecmidx
; // Shared Memory
39 int *logidx
; // Shared Memory
40 int *oscam_sem
; // sem (multicam.o)
41 int *c_start
; // idx of 1st client
42 int *log_fd
; // log-process is running
43 struct s_ecm
*ecmcache
; // Shared Memory
44 struct s_client
*client
; // Shared Memory
45 struct s_reader
*reader
; // Shared Memory
47 struct card_struct
*Cards
; // Shared Memory
48 struct idstore_struct
*idstore
; // Shared Memory
49 unsigned long *IgnoreList
; // Shared Memory
51 struct s_config
*cfg
; // Shared Memory
53 struct s_acasc_shm
*acasc
; // anti-cascading table indexed by account.ac_idx
56 int *loghistidx
; // ptr to current entry
57 char *loghist
; // ptr of log-history
59 int *mcl
=0; // Master close log?
61 static int shmsize
= CS_ECMCACHESIZE
*(sizeof(struct s_ecm
)) +
62 CS_MAXPID
*(sizeof(struct s_client
)) +
63 CS_MAXREADER
*(sizeof(struct s_reader
)) +
65 CS_MAXCARDS
*(sizeof(struct card_struct
))+
66 CS_MAXIGNORE
*(sizeof(long))+
67 CS_MAXPID
*(sizeof(struct idstore_struct
))+
70 CS_MAXPID
*(sizeof(struct s_acasc_shm
)) +
73 CS_MAXLOGHIST
*CS_LOGHISTSIZE
+ sizeof(int) +
75 sizeof(struct s_config
)+(6*sizeof(int));
78 char cs_memfile
[128]=CS_MMAPFILE
;
81 /*****************************************************************************
83 *****************************************************************************/
84 static char mloc
[128]={0};
85 static int shmid
=0; // Shared Memory ID
86 static int cs_last_idx
=0; // client index of last fork (master only)
87 static char* credit
[] = {
88 "dukat for the great MpCS piece of code",
89 "all members of streamboard.de.vu for testing",
90 "scotty and aroureos for the first softcam (no longer used)",
91 "John Moore for the hsic-client (humax 5400) and the arm-support",
92 "doz21 for the sio-routines and his support on camd3-protocol",
93 "kindzadza for his support on radegast-protocol",
94 "DS and ago for several modules in mpcs development",
95 "dingo35 for seca reader-support",
96 "dingo35 and okmikel for newcamd-support",
97 "hellmaster1024 for gb*x-support",
98 "the vdr-sc team for several good ideas :-)",
101 static void cs_set_mloc(int ato
, char *txt
)
109 char *cs_platform(char *buf
)
111 static char *hw
=NULL
;
116 cs_hw
=CS_HW_DBOX2
; // dbox2, default for now
117 if (!stat("/dev/sci0", &st
)) cs_hw
=CS_HW_DREAM
; // dreambox
121 case CS_HW_DBOX2
: hw
="dbox2" ; break;
123 case CS_HW_DREAM
: hw
="dreambox"; break;
126 if (!hw
) hw
=CS_OS_HW
;
128 sprintf(buf
, "%s-%s-%s", CS_OS_CPU
, hw
, CS_OS_SYS
);
135 fprintf(stderr
, "\nOSCam cardserver v%s (%s) - (w) 2009 by smurzch\n", CS_VERSION_X
, CS_OSTYPE
);
136 fprintf(stderr
, "\tbased on streamboard mp-cardserver v0.9d - (w) 2004-2007 by dukat\n\n");
137 fprintf(stderr
, "oscam [-b] [-c config-dir]");
139 fprintf(stderr
, " [-m memory-file]");
141 fprintf(stderr
, "\n\n\t-b : start in background\n");
142 fprintf(stderr
, "\t-c <dir> : read configuration from <dir>\n");
143 fprintf(stderr
, "\t default=%s\n", CS_CONFDIR
);
145 fprintf(stderr
, "\t-m <file>: use <file> as mmaped memory file\n");
146 fprintf(stderr
, "\t default=%s\n", CS_MMAPFILE
);
148 fprintf(stderr
, "\nthanks to ...\n");
149 for (i
=0; credit
[i
]; i
++)
150 fprintf(stderr
, "\t%s\n", credit
[i
]);
151 fprintf(stderr
, "\n");
156 static int daemon(int nochdir
, int noclose
)
162 case -1: return (-1);
173 if (!noclose
&& (fd
=open("/dev/null", O_RDWR
, 0)) != -1)
175 (void)dup2(fd
, STDIN_FILENO
);
176 (void)dup2(fd
, STDOUT_FILENO
);
177 (void)dup2(fd
, STDERR_FILENO
);
185 int recv_from_udpipe(uchar
*buf
, int l
)
188 if (!pfd
) return(-9);
192 cs_log("INTERNAL PIPE-ERROR");
195 memcpy(&n
, buf
+1, 2);
196 return(read(pfd
, buf
, n
));
199 char *username(int idx
)
201 if (client
[idx
].usr
[0])
202 return(client
[idx
].usr
);
207 static int idx_from_ip(in_addr_t ip
, in_port_t port
)
210 for (i
=idx
=0; (i
<CS_MAXPID
) && (!idx
); i
++)
211 if ((client
[i
].ip
==ip
) && (client
[i
].port
==port
) &&
212 ((client
[i
].typ
=='c') || (client
[i
].typ
=='m')))
217 int idx_from_pid(pid_t pid
)
220 for (i
=0, idx
=(-1); (i
<CS_MAXPID
) && (idx
<0); i
++)
221 if (client
[i
].pid
==pid
)
226 static long chk_caid(ushort caid
, CAIDTAB
*ctab
)
230 for (rc
=(-1), n
=0; (n
<CS_MAXCAIDTAB
) && (rc
<0); n
++)
231 if ((caid
& ctab
->mask
[n
]) == ctab
->caid
[n
])
232 rc
=ctab
->cmap
[n
] ? ctab
->cmap
[n
] : caid
;
236 int chk_bcaid(ECM_REQUEST
*er
, CAIDTAB
*ctab
)
239 if ((caid
=chk_caid(er
->caid
, ctab
))<0)
246 * void set_signal_handler(int sig, int flags, void (*sighandler)(int))
247 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
249 void set_signal_handler(int sig
, int flags
, void (*sighandler
)(int))
252 if ((signal(sig
, sighandler
)==SIG_IGN
) && (flags
& 2))
254 signal(sig
, SIG_IGN
);
255 siginterrupt(sig
, 0);
258 siginterrupt(sig
, (flags
& 1) ? 0 : 1);
261 sigaction(sig
, (struct sigaction
*) 0, &sa
);
262 if (!((flags
& 2) && (sa
.sa_handler
==SIG_IGN
)))
264 sigemptyset(&sa
.sa_mask
);
265 sa
.sa_flags
=(flags
& 1) ? SA_RESTART
: 0;
266 sa
.sa_handler
=sighandler
;
267 sigaction(sig
, &sa
, (struct sigaction
*) 0);
272 static void cs_alarm(int sig
)
274 cs_debug("Got alarm signal");
275 cs_log("disconnect from %s (deadlock!)", cs_inet_ntoa(client
[cs_idx
].ip
));
279 static void cs_master_alarm(int sig
)
281 cs_log("PANIC: master deadlock! last location: %s", mloc
);
282 fprintf(stderr
, "PANIC: master deadlock! last location: %s", mloc
);
287 static void cs_sigpipe(int sig
)
289 if ((cs_idx
) && (master_pid
!=getppid()))
291 cs_log("Got sigpipe signal -> captured");
294 void cs_exit(int sig
)
298 set_signal_handler(SIGCHLD
, 1, SIG_IGN
);
299 set_signal_handler(SIGHUP
, 1, SIG_IGN
);
300 if (sig
&& (sig
!=SIGQUIT
))
301 cs_log("exit with signal %d", sig
);
302 switch(client
[cs_idx
].typ
)
304 case 'c': cs_statistics(cs_idx
);
309 for (i
=1; i
<CS_MAXPID
; i
++)
311 kill(client
[i
].pid
, SIGQUIT
);
312 cs_log("cardserver down");
314 if (ecmcache
) shmdt((void *)ecmcache
);
320 munmap((void *)ecmcache
, (size_t)shmsize
);
321 if (shmid
) close(shmid
);
322 unlink(CS_MMAPFILE
); // ignore errors, last process must succeed
327 static void cs_reinit_clients()
330 struct s_auth
*account
;
332 for( i
=1; i
<CS_MAXPID
; i
++ )
333 if( client
[i
].pid
&& client
[i
].typ
=='c' && client
[i
].usr
[0] )
335 for (account
=cfg
->account
; (account
) ; account
=account
->next
)
336 if (!strcmp(client
[i
].usr
, account
->usr
))
340 client
[i
].pcrc
==crc32(0L, MD5(account
->pwd
, strlen(account
->pwd
), NULL
), 16))
342 client
[i
].grp
= account
->grp
;
343 client
[i
].au
= account
->au
;
344 client
[i
].tosleep
= (60*account
->tosleep
);
345 client
[i
].monlvl
= account
->monlvl
;
346 client
[i
].fchid
= account
->fchid
; // CHID filters
347 client
[i
].cltab
= account
->cltab
; // Class
348 client
[i
].ftab
= account
->ftab
; // Ident
349 client
[i
].sidtabok
= account
->sidtabok
; // services
350 client
[i
].sidtabno
= account
->sidtabno
; // services
351 memcpy(&client
[i
].ctab
, &account
->ctab
, sizeof(client
[i
].ctab
));
353 client
[i
].ac_idx
= account
->ac_idx
;
354 client
[i
].ac_penalty
= account
->ac_penalty
;
355 client
[i
].ac_limit
= (account
->ac_users
*100+80)*cfg
->ac_stime
;
360 if (ph
[client
[i
].ctyp
].type
& MOD_CONN_NET
)
362 cs_debug("client '%s', pid=%d not found in db (or password changed)",
363 client
[i
].usr
, client
[i
].pid
);
364 kill(client
[i
].pid
, SIGQUIT
);
370 static void cs_sighup()
372 uchar dummy
[1]={0x00};
373 write_to_pipe(fd_c2m
, PIP_ID_HUP
, dummy
, 1);
376 static void cs_accounts_chk()
383 for (i
=0; i
<CS_MAXPID
; i
++)
384 if (client
[i
].typ
=='a')
386 kill(client
[i
].pid
, SIGHUP
);
392 static void cs_debug_level()
396 cs_dblevel
^= D_ALL_DUMP
;
397 if (master_pid
==getpid())
398 for (i
=0; i
<CS_MAXPID
&& client
[i
].pid
; i
++)
399 client
[i
].dbglvl
=cs_dblevel
;
401 client
[cs_idx
].dbglvl
=cs_dblevel
;
402 cs_log("%sdebug_level=%d", (master_pid
==getpid())?"all ":"",cs_dblevel
);
405 static void cs_card_info(int i
)
407 uchar dummy
[1]={0x00};
408 for( i
=1; i
<CS_MAXPID
; i
++ )
409 if( client
[i
].pid
&& client
[i
].typ
=='r' && client
[i
].fd_m2c
)
410 write_to_pipe(client
[i
].fd_m2c
, PIP_ID_CIN
, dummy
, 1);
412 //kill(client[i].pid, SIGUSR2);
415 static void cs_child_chk(int i
)
417 while (waitpid(0, NULL
, WNOHANG
)>0);
418 for (i
=1; i
<CS_MAXPID
; i
++)
420 if (kill(client
[i
].pid
, 0)) {
421 if ((client
[i
].typ
!='c') && (client
[i
].typ
!='m'))
425 switch(client
[i
].typ
)
428 case 'a': txt
="anticascader"; break;
430 case 'l': txt
="logger"; break;
431 case 'p': txt
="proxy"; break;
432 case 'r': txt
="reader"; break;
433 case 'n': txt
="resolver"; break;
435 cs_log("PANIC: %s lost !! (pid=%d)", txt
, client
[i
].pid
);
445 if( cfg
->ac_enabled
)
447 strncpy(usr
, client
[i
].usr
, sizeof(usr
)-1);
448 ac_idx
= client
[i
].ac_idx
;
449 ac_limit
= client
[i
].ac_limit
;
450 ac_penalty
= client
[i
].ac_penalty
;
453 if (client
[i
].fd_m2c
) close(client
[i
].fd_m2c
);
454 if (client
[i
].ufd
) close(client
[i
].ufd
);
455 memset(&client
[i
], 0, sizeof(struct s_client
));
457 if( cfg
->ac_enabled
)
459 client
[i
].ac_idx
= ac_idx
;
460 client
[i
].ac_limit
= ac_limit
;
461 client
[i
].ac_penalty
= ac_penalty
;
462 strcpy(client
[i
].usr
, usr
);
471 int cs_fork(in_addr_t ip
, in_port_t port
)
475 for (i
=1; (i
<CS_MAXPID
) && (client
[i
].pid
); i
++);
479 memset(&client
[i
], 0, sizeof(struct s_client
));
483 cs_log("Cannot create pipe (errno=%d)", errno
);
489 cs_log("PANIC: Cannot fork() (errno=%d)", errno
);
491 case 0: // HERE is client
493 set_signal_handler(SIGALRM
, 0, cs_alarm
);
494 set_signal_handler(SIGCHLD
, 1, SIG_IGN
);
495 set_signal_handler(SIGHUP
, 1, SIG_IGN
);
496 set_signal_handler(SIGINT
, 1, SIG_IGN
);
497 set_signal_handler(SIGUSR1
, 1, cs_debug_level
);
498 is_server
=((ip
) || (port
<90)) ? 1 : 0;
502 if( port
!=97 ) cs_close_log();
510 default: // HERE is master
511 client
[i
].fd_m2c
=fdp
[1];
512 client
[i
].dbglvl
=cs_dblevel
;
516 client
[i
].typ
='c'; // dynamic client
519 cs_log("client(%d) connect from %s (pid=%d, pipfd=%d)",
520 i
-cdiff
, cs_inet_ntoa(ip
), pid
, client
[i
].fd_m2c
);
527 case 99: client
[i
].typ
='r'; // reader
528 client
[i
].sidtabok
=reader
[ridx
].sidtabok
;
529 client
[i
].sidtabno
=reader
[ridx
].sidtabno
;
530 reader
[ridx
].fd
=client
[i
].fd_m2c
;
531 reader
[ridx
].cs_idx
=i
;
532 if (reader
[ridx
].r_port
)
533 cs_log("proxy started (pid=%d, server=%s)",
534 pid
, reader
[ridx
].device
);
537 if (reader
[ridx
].typ
==R_MOUSE
)
538 cs_log("reader started (pid=%d, device=%s, detect=%s%s, mhz=%d)",
539 pid
, reader
[ridx
].device
,
540 reader
[ridx
].detect
&0x80 ? "!" : "",
541 RDR_CD_TXT
[reader
[ridx
].detect
&0x7f],
544 cs_log("reader started (pid=%d, device=%s)",
545 pid
, reader
[ridx
].device
);
546 client
[i
].ip
=client
[0].ip
;
547 strcpy(client
[i
].usr
, client
[0].usr
);
551 case 98: client
[i
].typ
='n'; // resolver
552 client
[i
].ip
=client
[0].ip
;
553 strcpy(client
[i
].usr
, client
[0].usr
);
554 cs_log("resolver started (pid=%d, delay=%d sec)",
555 pid
, cfg
->resolvedelay
);
558 case 97: client
[i
].typ
='l'; // logger
559 client
[i
].ip
=client
[0].ip
;
560 strcpy(client
[i
].usr
, client
[0].usr
);
561 cs_log("logger started (pid=%d)", pid
);
565 case 96: client
[i
].typ
='a';
566 client
[i
].ip
=client
[0].ip
;
567 strcpy(client
[i
].usr
, client
[0].usr
);
568 cs_log("anticascader started (pid=%d, delay=%d min)",
573 default: client
[i
].typ
='c'; // static client
574 client
[i
].ip
=client
[0].ip
;
576 cs_log("%s: initialized (pid=%d%s)", ph
[port
].desc
,
577 pid
, ph
[port
].logtxt
? ph
[port
].logtxt
: "");
581 client
[i
].login
=client
[i
].last
=time((time_t *)0);
582 client
[i
].pid
=pid
; // MUST be last -> wait4master()
589 cs_log("max connections reached -> reject client %s", cs_inet_ntoa(ip
));
595 static void init_signal()
598 for (i
=1; i
<NSIG
; i
++)
599 set_signal_handler(i
, 3, cs_exit
);
600 set_signal_handler(SIGWINCH
, 1, SIG_IGN
);
601 // set_signal_handler(SIGPIPE , 0, SIG_IGN);
602 set_signal_handler(SIGPIPE
, 0, cs_sigpipe
);
603 // set_signal_handler(SIGALRM , 0, cs_alarm);
604 set_signal_handler(SIGALRM
, 0, cs_master_alarm
);
605 set_signal_handler(SIGCHLD
, 1, cs_child_chk
);
606 // set_signal_handler(SIGHUP , 1, cs_accounts_chk);
607 set_signal_handler(SIGHUP
, 1, cs_sighup
);
608 set_signal_handler(SIGUSR1
, 1, cs_debug_level
);
609 set_signal_handler(SIGUSR2
, 1, cs_card_info
);
610 set_signal_handler(SIGCONT
, 1, SIG_IGN
);
611 cs_log("signal handling initialized (type=%s)",
621 static void init_shm()
626 if ((shmid
=open(cs_memfile
, O_RDWR
| O_CREAT
| O_TRUNC
, S_IRUSR
| S_IWUSR
))<0)
628 fprintf(stderr
, "Cannot create mmaped file (errno=%d)", errno
);
632 buf
=(char *)malloc(shmsize
);
633 memset(buf
, 0, shmsize
);
634 write(shmid
, buf
, shmsize
);
637 ecmcache
=(struct s_ecm
*)mmap((void *)0, (size_t) shmsize
,
638 PROT_READ
|PROT_WRITE
, MAP_SHARED
, shmid
, 0);
641 char *shmerr_txt
="Cannot %s shared memory (errno=%d)\n";
642 if ((shmid
=shmget(IPC_PRIVATE
, shmsize
, IPC_CREAT
| 0600))<0)
644 fprintf(stderr
, shmerr_txt
, "create", errno
);
648 if ((ecmcache
=(struct s_ecm
*)shmat(shmid
, 0, 0))==(void *)(-1))
650 fprintf(stderr
, shmerr_txt
, "attach", errno
);
653 memset(ecmcache
, 0, shmsize
);
654 shmctl(shmid
, IPC_RMID
, &sd
);
657 acasc
=(struct s_acasc_shm
*)&ecmcache
[CS_ECMCACHESIZE
];
658 ecmidx
=(int *)&acasc
[CS_MAXPID
];
660 ecmidx
=(int *)&ecmcache
[CS_ECMCACHESIZE
];
662 mcl
=(int *)((void *)ecmidx
+sizeof(int));
663 logidx
=(int *)((void *)mcl
+sizeof(int));
664 c_start
=(int *)((void *)logidx
+sizeof(int));
665 log_fd
=(int *)((void *)c_start
+sizeof(int));
666 oscam_sem
=(int *)((void *)log_fd
+sizeof(int));
667 client
=(struct s_client
*)((void *)oscam_sem
+sizeof(int));
668 reader
=(struct s_reader
*)&client
[CS_MAXPID
];
670 Cards
=(struct card_struct
*)&reader
[CS_MAXREADER
];
671 IgnoreList
=(unsigned long*)&Cards
[CS_MAXCARDS
];
672 idstore
=(struct idstore_struct
*)&IgnoreList
[CS_MAXIGNORE
];
673 cfg
=(struct s_config
*)&idstore
[CS_MAXPID
];
675 cfg
=(struct s_config
*)&reader
[CS_MAXREADER
];
678 loghistidx
=(int *)((void *)cfg
+sizeof(struct s_config
));
679 loghist
=(char *)((void *)loghistidx
+sizeof(int));
682 #ifdef DEBUG_SHM_POINTER
683 printf("SHM ALLOC: %x\n", shmsize
);
684 printf("SHM START: %p\n", (void *) ecmcache
);
685 printf("SHM ST1: %p %x (%x)\n", (void *) ecmidx
, ((void *) ecmidx
) - ((void *) ecmcache
), CS_ECMCACHESIZE
*(sizeof(struct s_ecm
)));
686 printf("SHM ST2: %p %x (%x)\n", (void *) oscam_sem
, ((void *) oscam_sem
) - ((void *) ecmidx
), sizeof(int));
687 printf("SHM ST3: %p %x (%x)\n", (void *) client
, ((void *) client
) - ((void *) oscam_sem
), sizeof(int));
688 printf("SHM ST4: %p %x (%x)\n", (void *) reader
, ((void *) reader
) - ((void *) client
), CS_MAXPID
*(sizeof(struct s_client
)));
689 printf("SHM ST5: %p %x (%x)\n", (void *) cfg
, ((void *) cfg
) - ((void *) reader
), CS_MAXREADER
*(sizeof(struct s_reader
)));
690 printf("SHM ST6: %p %x (%x)\n", ((void *) cfg
)+sizeof(struct s_config
), sizeof(struct s_config
), sizeof(struct s_config
));
691 printf("SHM ENDE: %p\n", ((void *) cfg
)+sizeof(struct s_config
));
692 printf("SHM SIZE: %x\n", ((void *) cfg
)-((void *) ecmcache
) + sizeof(struct s_config
));
699 client
[0].pid
=getpid();
700 client
[0].login
=time((time_t *)0);
701 client
[0].ip
=cs_inet_addr("127.0.0.1");
704 client
[0].dbglvl
=cs_dblevel
;
705 strcpy(client
[0].usr
, "root");
708 memset(loghist
, 0, CS_MAXLOGHIST
*CS_LOGHISTSIZE
);
712 static int start_listener(struct s_module
*ph
, int port_idx
)
714 int ov
=1, timeout
, is_udp
, i
;
716 //struct hostent *ptrh; /* pointer to a host table entry */
717 struct protoent
*ptrp
; /* pointer to a protocol table entry */
718 struct sockaddr_in sad
; /* structure to hold server's address */
720 ptxt
[0][0]=ptxt
[1][0]='\0';
721 if (!ph
->ptab
->ports
[port_idx
].s_port
)
723 cs_log("%s: disabled", ph
->desc
);
726 is_udp
=(ph
->type
==MOD_CONN_UDP
);
728 memset((char *)&sad
,0,sizeof(sad
)); /* clear sockaddr structure */
729 sad
.sin_family
= AF_INET
; /* set family to Internet */
734 sad
.sin_addr
.s_addr
=ph
->s_ip
;
735 sprintf(ptxt
[0], ", ip=%s", inet_ntoa(ph
->s_ip
));
738 sad
.sin_addr
.s_addr
=INADDR_ANY
;
739 timeout
=cfg
->bindwait
;
741 ph
->ptab
->ports
[port_idx
].fd
= 0;
743 if (ph
->ptab
->ports
[port_idx
].s_port
> 0) /* test for illegal value */
744 sad
.sin_port
= htons((u_short
)ph
->ptab
->ports
[port_idx
].s_port
);
747 cs_log("%s: Bad port %d", ph
->desc
, ph
->ptab
->ports
[port_idx
].s_port
);
751 /* Map transport protocol name to protocol number */
753 if( (ptrp
=getprotobyname(is_udp
? "udp" : "tcp")) )
756 ov
=(is_udp
) ? 17 : 6; // use defaults on error
758 if ((ph
->ptab
->ports
[port_idx
].fd
=socket(PF_INET
,is_udp
? SOCK_DGRAM
: SOCK_STREAM
, ov
))<0)
760 cs_log("%s: Cannot create socket (errno=%d)", ph
->desc
, errno
);
765 if (setsockopt(ph
->ptab
->ports
[port_idx
].fd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&ov
, sizeof(ov
))<0)
767 cs_log("%s: setsockopt failed (errno=%d)", ph
->desc
, errno
);
768 close(ph
->ptab
->ports
[port_idx
].fd
);
769 return(ph
->ptab
->ports
[port_idx
].fd
=0);
773 setsockopt(ph
->ptab
->ports
[port_idx
].fd
, SOL_SOCKET
, SO_REUSEPORT
, (void *)&ov
, sizeof(ov
));
778 if (!setsockopt(ph
->ptab
->ports
[port_idx
].fd
, SOL_SOCKET
, SO_PRIORITY
, (void *)&cfg
->netprio
, sizeof(ulong
)))
779 sprintf(ptxt
[1], ", prio=%d", cfg
->netprio
);
784 ulong keep_alive
= 1;
785 setsockopt(ph
->ptab
->ports
[port_idx
].fd
, SOL_SOCKET
, SO_KEEPALIVE
,
786 (void *)&keep_alive
, sizeof(ulong
));
791 if (bind(ph
->ptab
->ports
[port_idx
].fd
, (struct sockaddr
*)&sad
, sizeof (sad
))<0)
795 cs_log("%s: Bind request failed, waiting another %d seconds",
801 cs_log("%s: Bind request failed, giving up", ph
->desc
);
802 close(ph
->ptab
->ports
[port_idx
].fd
);
803 return(ph
->ptab
->ports
[port_idx
].fd
=0);
810 if (listen(ph
->ptab
->ports
[port_idx
].fd
, CS_QLEN
)<0)
812 cs_log("%s: Cannot start listen mode (errno=%d)", ph
->desc
, errno
);
813 close(ph
->ptab
->ports
[port_idx
].fd
);
814 return(ph
->ptab
->ports
[port_idx
].fd
=0);
817 cs_log("%s: initialized (fd=%d, port=%d%s%s%s)",
818 ph
->desc
, ph
->ptab
->ports
[port_idx
].fd
,
819 ph
->ptab
->ports
[port_idx
].s_port
,
820 ptxt
[0], ptxt
[1], ph
->logtxt
? ph
->logtxt
: "");
822 for( i
=0; i
<ph
->ptab
->ports
[port_idx
].ftab
.nfilts
; i
++ ) {
824 cs_log("CAID: %04X", ph
->ptab
->ports
[port_idx
].ftab
.filts
[i
].caid
);
825 for( j
=0; j
<ph
->ptab
->ports
[port_idx
].ftab
.filts
[i
].nprids
; j
++ )
826 cs_log("provid #%d: %06X", j
, ph
->ptab
->ports
[port_idx
].ftab
.filts
[i
].prids
[j
]);
828 return(ph
->ptab
->ports
[port_idx
].fd
);
831 static void *cs_client_resolve(void *dummy
)
836 struct s_auth
*account
;
837 struct sockaddr_in udp_sa
;
839 for (account
=cfg
->account
; account
; account
=account
->next
)
840 if (account
->dyndns
[0])
842 if (rht
=gethostbyname(account
->dyndns
))
844 memcpy(&udp_sa
.sin_addr
, rht
->h_addr
, sizeof(udp_sa
.sin_addr
));
845 account
->dynip
=cs_inet_order(udp_sa
.sin_addr
.s_addr
);
848 cs_log("can't resolve hostname %s (user: %s)", account
->dyndns
, account
->usr
);
849 client
[cs_idx
].last
=time((time_t)0);
851 sleep(cfg
->resolvedelay
);
855 static void start_client_resolver()
860 if (i
=pthread_create(&tid
, (pthread_attr_t
*)0, cs_client_resolve
, (void *) 0))
861 cs_log("ERROR: can't create resolver-thread (err=%d)", i
);
864 cs_log("resolver thread started");
873 struct s_auth
*account
;
874 for (i
=0; i
<CS_MAXREADER
; i
++)
875 if ((idx
=reader
[i
].cs_idx
) && (reader
[i
].typ
& R_IS_NETWORK
))
877 client
[cs_idx
].last
=time((time_t)0);
878 if (rht
=gethostbyname(reader
[i
].device
))
880 memcpy(&client
[idx
].udp_sa
.sin_addr
, rht
->h_addr
,
881 sizeof(client
[idx
].udp_sa
.sin_addr
));
882 client
[idx
].ip
=cs_inet_order(client
[idx
].udp_sa
.sin_addr
.s_addr
);
885 cs_log("can't resolve %s", reader
[i
].device
);
886 client
[cs_idx
].last
=time((time_t)0);
891 static void *cs_logger(void *dummy
)
893 static void cs_logger(void)
896 *log_fd
=client
[cs_idx
].fd_m2c
;
904 FD_SET(fd_m2c
, &fds
);
905 select(fd_m2c
+1, &fds
, 0, 0, 0);
907 if (master_pid
!=getppid())
910 if (FD_ISSET(fd_m2c
, &fds
))
913 // switch(n=read_from_pipe(fd_m2c, &ptr, 1))
914 n
=read_from_pipe(fd_m2c
, &ptr
, 1);
915 //if (n!=PIP_ID_NUL) printf("received %d bytes\n", n); fflush(stdout);
926 static void start_resolver()
931 if (i
=pthread_create(&tid
, (pthread_attr_t
*)0, cs_logger
, (void *) 0))
932 cs_log("ERROR: can't create logging-thread (err=%d)", i
);
935 cs_log("logging thread started");
939 sleep(1); // wait for reader
942 if (master_pid
!=getppid())
945 for (i
=0; i
<cfg
->resolvedelay
; i
++)
946 if (master_pid
!=getppid())
950 // sleep(cfg->resolvedelay);
955 static void start_anticascader()
960 set_signal_handler(SIGHUP
, 1, ac_init_stat
);
965 for( i
=0; i
<cfg
->ac_stime
*60; i
++ )
966 if( master_pid
!=getppid() )
971 if (master_pid
!=getppid())
979 static void init_cardreader()
981 for (ridx
=0; ridx
<CS_MAXREADER
; ridx
++)
982 if (reader
[ridx
].device
[0])
983 switch(cs_fork(0, 99))
995 static void init_service(int srv
)
997 switch(cs_fork(0, srv
))
1008 case 96: start_anticascader();
1010 case 97: cs_logger();
1011 case 98: start_resolver();
1019 for (i
=0; (i
<1000) && (client
[cs_idx
].pid
!=getpid()); i
++)
1021 if (client
[cs_idx
].pid
!=getpid())
1023 cs_log("PANIC: client not found in shared memory");
1026 cs_debug("starting client %d with ip %s",
1027 cs_idx
-cdiff
, cs_inet_ntoa(client
[cs_idx
].ip
));
1030 static void cs_fake_client(char *usr
)
1033 for (i
=cdiff
+1; i
<CS_MAXPID
; i
++)
1034 if ((client
[i
].pid
) && (client
[i
].typ
=='c') &&
1035 (!client
[i
].dup
) && (!strcmp(client
[i
].usr
, usr
)))
1039 cs_log("client %d duplicate user '%s', set to fake", i
-cdiff
, usr
);
1043 int cs_auth_client(struct s_auth
*account
, char *e_txt
)
1047 char *t_crypt
="encrypted";
1048 char *t_plain
="plain";
1049 char *t_grant
=" granted";
1050 char *t_reject
=" rejected";
1051 char *t_msg
[]= { buf
, "invalid access", "invalid ip", "unknown reason" };
1052 client
[cs_idx
].grp
=0xffffffff;
1053 client
[cs_idx
].au
=(-1);
1054 switch((long)account
)
1056 case -2: // gbx-dummy
1057 client
[cs_idx
].dup
=0;
1059 case 0: // reject access
1061 cs_log("%s %s-client %s%s (%s)",
1062 client
[cs_idx
].crypted
? t_crypt
: t_plain
,
1063 ph
[client
[cs_idx
].ctyp
].desc
,
1064 client
[cs_idx
].ip
? cs_inet_ntoa(client
[cs_idx
].ip
) : "",
1065 client
[cs_idx
].ip
? t_reject
: t_reject
+1,
1066 e_txt
? e_txt
: t_msg
[rc
]);
1068 default: // grant/check access
1069 if (client
[cs_idx
].ip
&& account
->dyndns
[0])
1070 if (client
[cs_idx
].ip
!= account
->dynip
)
1074 client
[cs_idx
].dup
=0;
1075 if (client
[cs_idx
].typ
=='c')
1077 client
[cs_idx
].grp
=account
->grp
;
1078 client
[cs_idx
].au
=account
->au
;
1079 client
[cs_idx
].tosleep
=(60*account
->tosleep
);
1080 memcpy(&client
[cs_idx
].ctab
, &account
->ctab
, sizeof(client
[cs_idx
].ctab
));
1082 cs_fake_client(account
->usr
);
1083 client
[cs_idx
].ftab
= account
->ftab
; // IDENT filter
1084 client
[cs_idx
].cltab
= account
->cltab
; // CLASS filter
1085 client
[cs_idx
].fchid
= account
->fchid
; // CHID filter
1086 client
[cs_idx
].sidtabok
= account
->sidtabok
; // services
1087 client
[cs_idx
].sidtabno
= account
->sidtabno
; // services
1088 client
[cs_idx
].pcrc
= crc32(0L, MD5(account
->pwd
, strlen(account
->pwd
), NULL
), 16);
1089 premhack
=account
->premhack
;
1091 ac_init_client(account
);
1095 client
[cs_idx
].monlvl
=account
->monlvl
;
1096 strcpy(client
[cs_idx
].usr
, account
->usr
);
1097 case -1: // anonymous grant access
1102 if (client
[cs_idx
].typ
=='m')
1103 sprintf(t_msg
[0], "lvl=%d", client
[cs_idx
].monlvl
);
1105 sprintf(t_msg
[0], "au=%d", client
[cs_idx
].au
+1);
1107 cs_log("%s %s-client %s%s (%s, %s)",
1108 client
[cs_idx
].crypted
? t_crypt
: t_plain
,
1109 e_txt
? e_txt
: ph
[client
[cs_idx
].ctyp
].desc
,
1110 client
[cs_idx
].ip
? cs_inet_ntoa(client
[cs_idx
].ip
) : "",
1111 client
[cs_idx
].ip
? t_grant
: t_grant
+1,
1112 username(cs_idx
), t_msg
[rc
]);
1118 void cs_disconnect_client(void)
1121 if (client
[cs_idx
].ip
)
1122 sprintf(buf
, " from %s", cs_inet_ntoa(client
[cs_idx
].ip
));
1123 cs_log("%s disconnected%s", username(cs_idx
), buf
);
1127 int check_ecmcache(ECM_REQUEST
*er
, ulong grp
)
1130 // cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1131 //cs_log("cache CHECK: grp=%lX", grp);
1132 for(i
=0; i
<CS_ECMCACHESIZE
; i
++)
1133 if ((grp
& ecmcache
[i
].grp
) &&
1134 (!memcmp(ecmcache
[i
].ecmd5
, er
->ecmd5
, CS_ECMSTORESIZE
)))
1136 //cs_log("cache found: grp=%lX cgrp=%lX", grp, ecmcache[i].grp);
1137 memcpy(er
->cw
, ecmcache
[i
].cw
, 16);
1143 static void store_ecm(ECM_REQUEST
*er
)
1145 //cs_log("store ecm from reader %d", er->reader[0]);
1146 memcpy(ecmcache
[*ecmidx
].ecmd5
, er
->ecmd5
, CS_ECMSTORESIZE
);
1147 memcpy(ecmcache
[*ecmidx
].cw
, er
->cw
, 16);
1148 ecmcache
[*ecmidx
].caid
=er
->caid
;
1149 ecmcache
[*ecmidx
].prid
=er
->prid
;
1150 ecmcache
[*ecmidx
].grp
=reader
[er
->reader
[0]].grp
;
1151 // cs_ddump(ecmcache[*ecmidx].ecmd5, CS_ECMSTORESIZE, "ECM stored (idx=%d)", *ecmidx);
1152 *ecmidx
=(*ecmidx
+1) % CS_ECMCACHESIZE
;
1155 void store_logentry(char *txt
)
1157 #ifdef CS_LOGHISTORY
1159 ptr
=(char *)(loghist
+(*loghistidx
*CS_LOGHISTSIZE
));
1160 ptr
[0]='\1'; // make username unusable
1162 if ((client
[cs_idx
].typ
=='c') || (client
[cs_idx
].typ
=='m'))
1163 strncpy(ptr
, client
[cs_idx
].usr
, 31);
1164 strncpy(ptr
+32, txt
, CS_LOGHISTSIZE
-33);
1165 *loghistidx
=(*loghistidx
+1) % CS_MAXLOGHIST
;
1171 * write all kind of data to pipe specified by fd
1173 int write_to_pipe(int fd
, int id
, uchar
*data
, int n
)
1175 uchar buf
[1024+3+sizeof(int)];
1177 //printf("WRITE_START pid=%d", getpid()); fflush(stdout);
1178 if ((id
<0) || (id
>PIP_ID_MAX
))
1180 memcpy(buf
, PIP_ID_TXT
[id
], 3);
1181 memcpy(buf
+3, &n
, sizeof(int));
1182 memcpy(buf
+3+sizeof(int), data
, n
);
1184 //n=write(fd, buf, n);
1185 //printf("WRITE_END pid=%d", getpid()); fflush(stdout);
1188 cs_log("write_to_pipe: fd==0");
1189 return(write(fd
, buf
, n
));
1194 * read all kind of data from pipe specified by fd
1195 * special-flag redir: if set AND data is ECM: this will redirected to appr. client
1197 int read_from_pipe(int fd
, uchar
**data
, int redir
)
1201 static uchar buf
[1024+1+3+sizeof(int)];
1208 if (bytes_available(fd
))
1210 if (read(fd
, buf
, 3+sizeof(int))==3+sizeof(int))
1211 memcpy(&hdr
, buf
+3, sizeof(int));
1213 cs_log("WARNING: pipe header to small !");
1219 for (l
=0; (rc
<0) && (PIP_ID_TXT
[l
]); l
++)
1220 if (!memcmp(buf
, PIP_ID_TXT
[l
], 3))
1225 fprintf(stderr
, "WARNING: pipe garbage");
1227 cs_log("WARNING: pipe garbage");
1233 if ((l
+3-1+sizeof(int))>sizeof(buf
))
1235 cs_log("WARNING: packet size (%d) to large", l
);
1236 l
=sizeof(buf
)+3-1+sizeof(int);
1238 if (!bytes_available(fd
))
1241 if (read(fd
, buf
+3+sizeof(int), l
)==l
)
1242 *data
=buf
+3+sizeof(int);
1245 cs_log("WARNING: pipe data to small !");
1248 buf
[l
+3+sizeof(int)]=0;
1249 if ((redir
) && (rc
==PIP_ID_ECM
))
1253 er
=(ECM_REQUEST
*)(buf
+3+sizeof(int));
1254 if( er
->cidx
&& client
[er
->cidx
].fd_m2c
)
1255 write(client
[er
->cidx
].fd_m2c
, buf
, l
+3+sizeof(int));
1264 * write_ecm_request():
1266 int write_ecm_request(int fd
, ECM_REQUEST
*er
)
1268 return(write_to_pipe(fd
, PIP_ID_ECM
, (uchar
*) er
, sizeof(ECM_REQUEST
)));
1271 int write_ecm_DCW(int fd
, ECM_REQUEST
*er
)
1273 return(write_to_pipe(fd
, PIP_ID_DCW
, (uchar
*) er
, sizeof(ECM_REQUEST
)));
1276 int write_ecm_answer(int fd
, ECM_REQUEST
*er
)
1280 for (i
=f
=0; i
<16; i
+=4)
1282 c
=((er
->cw
[i
]+er
->cw
[i
+1]+er
->cw
[i
+2]) & 0xff);
1290 cs_debug("notice: changed dcw checksum bytes");
1293 //cs_log("answer from reader %d (rc=%d)", er->reader[0], er->rc);
1295 if (er
->rc
==1||(er
->gbxRidx
&&er
->rc
==0)){
1299 return(write_ecm_request(fd
, er
));
1302 static int cs_read_timer(int fd
, uchar
*buf
, int l
, int msec
)
1308 if (!fd
) return(-1);
1309 tv
.tv_sec
= msec
/ 1000;
1310 tv
.tv_usec
= (msec
% 1000) * 1000;
1314 select(fd
+1, &fds
, 0, 0, &tv
);
1317 if (FD_ISSET(pfd
, &fds
))
1318 if (!(rc
=read(fd
, buf
, l
)))
1324 ECM_REQUEST
*get_ecmtask()
1331 n
=(ph
[client
[cs_idx
].ctyp
].multi
)?CS_MAXPENDING
:1;
1332 if( (ecmtask
=(ECM_REQUEST
*)malloc(n
*sizeof(ECM_REQUEST
))) )
1333 memset(ecmtask
, 0, n
*sizeof(ECM_REQUEST
));
1339 cs_log("Cannot allocate memory (errno=%d)", errno
);
1343 if (ph
[client
[cs_idx
].ctyp
].multi
)
1345 for (i
=0; (n
<0) && (i
<CS_MAXPENDING
); i
++)
1346 if (ecmtask
[i
].rc
<100)
1353 cs_log("WARNING: ecm pending table overflow !");
1356 memset(er
, 0, sizeof(ECM_REQUEST
));
1365 int send_dcw(ECM_REQUEST
*er
)
1367 static char *stxt
[]={"found", "cache1", "cache2", "emu",
1368 "not found", "timeout", "sleeping",
1369 "fake", "invalid", "corrupt"};
1370 static char *stxtEx
[]={"", "group", "caid", "ident", "class", "chid", "queue"};
1371 static char *stxtWh
[]={"", "user ", "reader ", "server ", "lserver "};
1377 for (lp
=(ushort
*)er
->ecm
+(er
->l
>>2), lc
=0; lp
>=(ushort
*)er
->ecm
; lp
--)
1381 snprintf(uname
,sizeof(uname
)-1, "%s(%04X)", username(cs_idx
), er
->gbxFrom
);
1383 snprintf(uname
,sizeof(uname
)-1, "%s", username(cs_idx
));
1386 if(reader
[er
->reader
[0]].typ
==R_GBOX
)
1387 snprintf(sby
, sizeof(sby
)-1, " by %s(%04X)", reader
[er
->reader
[0]].label
,er
->gbxCWFrom
);
1389 snprintf(sby
, sizeof(sby
)-1, " by %s", reader
[er
->reader
[0]].label
);
1391 if (er
->rc
<4) er
->rcEx
=0;
1393 snprintf(erEx
, sizeof(erEx
)-1, "rejected %s%s", stxtWh
[er
->rcEx
>>4],
1394 stxtEx
[er
->rcEx
&0xf]);
1395 cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s",
1396 uname
, er
->caid
, er
->prid
, er
->srvid
, er
->l
, lc
,
1397 er
->rcEx
?erEx
:stxt
[er
->rc
],
1398 1000*(tpe
.time
-er
->tps
.time
)+tpe
.millitm
-er
->tps
.millitm
, sby
);
1403 case 1: client
[cs_idx
].cwcache
++;
1405 case 0: client
[cs_idx
].cwfound
++; break;
1406 default: client
[cs_idx
].cwnot
++;
1408 client
[cs_idx
].cwcache
++;
1414 if( cfg
->show_ecm_dw
&& !client
[cs_idx
].dbglvl
)
1415 cs_dump(er
->cw
, 16, 0);
1416 if (er
->rc
==7) er
->rc
=0;
1417 ph
[client
[cs_idx
].ctyp
].send_dcw(er
);
1421 static void chk_dcw(int fd
)
1423 ECM_REQUEST
*er
, *ert
;
1424 if (read_from_pipe(fd
, (uchar
**)&er
, 0)!=PIP_ID_ECM
)
1426 //cs_log("dcw check from reader %d for idx %d (rc=%d)", er->reader[0], er->cpti, er->rc);
1427 ert
=&ecmtask
[er
->cpti
];
1429 return; // already done
1430 if( (er
->caid
!=ert
->caid
) || memcmp(er
->ecm
, ert
->ecm
, sizeof(er
->ecm
)) )
1433 if (er
->rc
>0) // found
1435 ert
->rc
=(er
->rc
==2)?2:0;
1437 ert
->reader
[0]=er
->reader
[0];
1438 memcpy(ert
->cw
, er
->cw
, sizeof(er
->cw
));
1439 ert
->gbxCWFrom
=er
->gbxCWFrom
;
1441 else // not found (from ONE of the readers !)
1444 ert
->reader
[er
->reader
[0]]=0;
1445 for (i
=0; (ert
) && (i
<CS_MAXREADER
); i
++)
1446 if (ert
->reader
[i
]) // we have still another chance
1447 ert
=(ECM_REQUEST
*)0;
1450 if (ert
) send_dcw(ert
);
1454 ulong
chk_provid(uchar
*ecm
, ushort caid
)
1461 provid
=b2i(2, ecm
+3);
1463 case 0x500: // viaccess
1464 i
=(ecm
[4]==0xD2) ? 3 : 0; // tpsflag -> offset+3
1465 if ((ecm
[5+i
]==3) && ((ecm
[4+i
]==0x90) || (ecm
[4+i
]==0x40)))
1466 provid
=(b2i(3, ecm
+6+i
) & 0xFFFFF0);
1469 if( caid
&0x0d00 && ecm
[8]==0x83 && ecm
[9]==1 )
1470 provid
=(ulong
)ecm
[10];
1476 void guess_irdeto(ECM_REQUEST *er)
1481 struct s_irdeto_quess *ptr;
1484 ptr = cfg->itab[b3];
1486 cs_debug("unknown irdeto byte 3: %02X", b3);
1489 b47 = b2i(4, er->ecm+4);
1490 //chid = b2i(2, er->ecm+6);
1491 //cs_debug("ecm: b47=%08X, ptr->b47=%08X, ptr->caid=%04X", b47, ptr->b47, ptr->caid);
1496 if( er->srvid && (er->srvid!=ptr->sid) )
1498 cs_debug("sid mismatched (ecm: %04X, guess: %04X), wrong oscam.ird file?",
1499 er->srvid, ptr->sid);
1504 er->chid=(ushort)ptr->b47;
1505 // cs_debug("quess_irdeto() found caid=%04X, sid=%04X, chid=%04X",
1506 // er->caid, er->srvid, er->chid);
1514 void guess_cardsystem(ECM_REQUEST
*er
)
1518 // viaccess - check by provid-search
1519 if( (er
->prid
=chk_provid(er
->ecm
, 0x500)) )
1523 // is ecm[1] always 0x30 ?
1524 // is ecm[3] always 0x07 ?
1525 if ((er
->ecm
[6]==1) && (er
->ecm
[4]==er
->ecm
[2]-2))
1528 // seca2 - very poor
1529 if ((er
->ecm
[8]==0x10) && ((er
->ecm
[9]&0xF1)==1))
1532 // is cryptoworks, but which caid ?
1533 if ((er
->ecm
[3]==0x81) && (er
->ecm
[4]==0xFF) &&
1534 (!er
->ecm
[5]) && (!er
->ecm
[6]) && (er
->ecm
[7]==er
->ecm
[2]-5))
1538 if (!er->caid && er->ecm[2]==0x31 && er->ecm[0x0b]==0x28)
1542 if (!er
->caid
) // guess by len ..
1543 er
->caid
=len4caid
[er
->ecm
[2]+3];
1549 void request_cw(ECM_REQUEST
*er
, int flag
)
1553 flag
=(flag
)?3:1; // flag specifies with/without fallback-readers
1554 for (i
=0; i
<CS_MAXREADER
; i
++)
1555 if (er
->reader
[i
]&flag
)
1556 write_ecm_request(reader
[i
].fd
, er
);
1559 void get_cw(ECM_REQUEST
*er
)
1561 int i
, j
, m
, rejected
;
1562 //uchar orig_caid[sizeof(er->caid)];
1564 //test the guessing ...
1565 //cs_log("caid should be %04X, provid %06X", er->caid, er->prid);
1568 client
[cs_idx
].lastecm
=time((time_t)0);
1571 guess_cardsystem(er
);
1573 if( (er
->caid
& 0xFF00)==0x600 && !er
->chid
)
1574 er
->chid
= (er
->ecm
[6]<<8)|er
->ecm
[7];
1577 er
->prid
=chk_provid(er
->ecm
, er
->caid
);
1579 // quickfix for 0100:000065
1580 if (er
->caid
== 0x100 && er
->prid
== 0x65 && er
->srvid
== 0)
1583 if( (!er
->prid
) && client
[cs_idx
].ncd_server
)
1585 int pi
= client
[cs_idx
].port_idx
;
1586 if( pi
>=0 && cfg
->ncd_ptab
.nports
&& cfg
->ncd_ptab
.nports
>= pi
)
1587 er
->prid
= cfg
->ncd_ptab
.ports
[pi
].ftab
.filts
[0].prids
[0];
1590 //cs_log("caid IS NOW .. %04X, provid %06X", er->caid, er->prid);
1593 if (er
->rc
>99) // rc<100 -> ecm error
1595 now
=time((time_t *) 0);
1600 if ((i
!=client
[cs_idx
].last_srvid
) || (!client
[cs_idx
].lastswitch
))
1601 client
[cs_idx
].lastswitch
=now
;
1602 if ((client
[cs_idx
].tosleep
) &&
1603 (now
-client
[cs_idx
].lastswitch
>client
[cs_idx
].tosleep
))
1604 er
->rc
=6; // sleeping
1605 client
[cs_idx
].last_srvid
=i
;
1606 client
[cs_idx
].last_caid
=m
;
1608 for (j
=0; (j
<6) && (er
->rc
>99); j
++)
1611 case 0: if (client
[cs_idx
].dup
)
1614 case 1: if (!chk_bcaid(er
, &client
[cs_idx
].ctab
))
1616 // cs_log("chk_bcaid failed");
1617 er
->rc
=8; // invalid
1621 case 2: if (!chk_srvid(er
, cs_idx
))
1624 case 3: if (!chk_ufilters(er
))
1627 case 4: if (!chk_sfilter(er
, ph
[client
[cs_idx
].ctyp
].ptab
))
1630 case 5: if( (i
=er
->l
-(er
->ecm
[2]+3)) )
1634 cs_debug("warning: ecm size adjusted from 0x%X to 0x%X",
1635 er
->l
, er
->ecm
[2]+3);
1636 er
->l
=(er
->ecm
[2]+3);
1639 er
->rc
=9; // corrupt
1644 if (premhack
) // quickhack for 1801:000501
1645 // moved behind the check routines, because newcamd-ECM will fail if ecm is converted before
1646 if (er
->caid
==0x1801 && er
->ecm
[3]==7 && er
->ecm
[5]==5 && er
->ecm
[6]==1)
1649 char hack
[13]={0x70, 0x51, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12, 0x07};
1652 er
->l
=(er
->ecm
[2]+3);
1653 memmove(er
->ecm
+14, er
->ecm
+4, er
->l
-1);
1654 memcpy(er
->ecm
+1, hack
, 13);
1657 cs_debug("ecm converted 1801:000501 -> 1702:000000");
1660 memcpy(er
->ecmd5
, MD5(er
->ecm
, er
->l
, NULL
), CS_ECMSTORESIZE
);
1662 if (check_ecmcache(er
, client
[cs_idx
].grp
))
1668 if( er
->rc
<100 && er
->rc
!=1 )
1672 if( !rejected
&& er
->rc
!=1 )
1674 for (i
=m
=0; i
<CS_MAXREADER
; i
++)
1675 if (matching_reader(er
, &reader
[i
])&&(i
!=ridx
))
1676 m
|=er
->reader
[i
]=(reader
[i
].fallback
)?2:1;
1680 case 0: er
->rc
=4; // no reader -> not found
1681 if (!er
->rcEx
) er
->rcEx
=E2_GROUP
;
1683 case 2: for (i
=0; i
<CS_MAXREADER
; i
++) // fallbacks only, switch them.
1689 if (cfg
->delay
) usleep(cfg
->delay
);
1698 void log_emm_request(int auidx
)
1700 // cs_log("%s send emm-request (reader=%s, caid=%04X)",
1701 // cs_inet_ntoa(client[cs_idx].ip), reader[auidx].label, reader[auidx].caid[0]);
1702 cs_log("%s emm-request sent (reader=%s, caid=%04X)",
1703 username(cs_idx
), reader
[auidx
].label
, reader
[auidx
].caid
[0]);
1706 void do_emm(EMM_PACKET
*ep
)
1709 au
=client
[cs_idx
].au
;
1711 if ((au
<0) || (au
>=CS_MAXREADER
))
1713 client
[cs_idx
].lastemm
=time((time_t)0);
1714 cs_ddump(reader
[au
].hexserial
, 8, "reader serial:");
1715 cs_ddump(ep
->hexserial
, 8, "emm SA:");
1716 // if ((!reader[au].fd) || (reader[au].b_nano[ep->emm[3]])) // blocknano is obsolete
1717 if ((!reader
[au
].fd
) || // reader has no fd
1718 (reader
[au
].caid
[0]!=b2i(2,ep
->caid
)) || // wrong caid
1719 (memcmp(reader
[au
].hexserial
, ep
->hexserial
, 8))) // wrong serial
1723 write_to_pipe(reader
[au
].fd
, PIP_ID_EMM
, (uchar
*) ep
, sizeof(EMM_PACKET
));
1726 static int comp_timeb(struct timeb
*tpa
, struct timeb
*tpb
)
1728 if (tpa
->time
>tpb
->time
) return(1);
1729 if (tpa
->time
<tpb
->time
) return(-1);
1730 if (tpa
->millitm
>tpb
->millitm
) return(1);
1731 if (tpa
->millitm
<tpb
->millitm
) return(-1);
1735 static void build_delay(struct timeb
*tpe
, struct timeb
*tpc
)
1737 if (comp_timeb(tpe
, tpc
)>0)
1739 tpe
->time
=tpc
->time
;
1740 tpe
->millitm
=tpc
->millitm
;
1744 struct timeval
*chk_pending(struct timeb tp_ctimeout
)
1748 struct timeb tpn
, tpe
, tpc
; // <n>ow, <e>nd, <c>heck
1749 static struct timeval tv
;
1753 tpe
=tp_ctimeout
; // latest delay -> disconnect
1756 i
=(ph
[client
[cs_idx
].ctyp
].multi
)?CS_MAXPENDING
:1;
1759 //cs_log("num pend=%d", i);
1760 for (--i
; i
>=0; i
--)
1761 if (ecmtask
[i
].rc
>=100) // check all pending ecm-requests
1766 tpc
.time
+=(er
->stage
) ? cfg
->ctimeout
: cfg
->ftimeout
;
1769 for (j
=0, act
=1; (act
) && (j
<CS_MAXREADER
); j
++)
1770 if (er
->reader
[j
]&1)
1772 //cs_log("stage 0, act=%d r0=%d, r1=%d, r2=%d, r3=%d, r4=%d r5=%d", act,
1773 // er->reader[0], er->reader[1], er->reader[2],
1774 // er->reader[3], er->reader[4], er->reader[5]);
1778 request_cw(er
, er
->stage
);
1779 tpc
.time
+=cfg
->ctimeout
-cfg
->ftimeout
;
1782 if (comp_timeb(&tpn
, &tpc
)>0) // action needed
1784 //cs_log("Action now %d.%03d", tpn.time, tpn.millitm);
1785 //cs_log(" %d.%03d", tpc.time, tpc.millitm);
1788 er
->rc
=5; // timeout
1795 request_cw(er
, er
->stage
);
1796 tpc
.time
+=cfg
->ctimeout
-cfg
->ftimeout
;
1799 build_delay(&tpe
, &tpc
);
1801 td
=(tpe
.time
-tpn
.time
)*1000+(tpe
.millitm
-tpn
.millitm
)+5;
1802 tv
.tv_sec
= td
/1000;
1803 tv
.tv_usec
= (td
%1000)*1000;
1804 //cs_log("delay %d.%06d", tv.tv_sec, tv.tv_usec);
1808 int process_input(uchar
*buf
, int l
, int timeout
)
1814 if (master_pid
!=getppid()) cs_exit(0);
1815 if (!pfd
) return(-1);
1818 if (ph
[client
[cs_idx
].ctyp
].watchdog
)
1819 alarm(cfg
->cmaxidle
+2);
1824 FD_SET(fd_m2c
, &fds
);
1826 rc
=select(((pfd
>fd_m2c
)?pfd
:fd_m2c
)+1, &fds
, 0, 0, chk_pending(tp
));
1827 if (master_pid
!=getppid()) cs_exit(0);
1830 if (errno
==EINTR
) continue;
1834 if (FD_ISSET(fd_m2c
, &fds
)) // read from pipe
1837 if (FD_ISSET(pfd
, &fds
)) // read from client
1839 rc
=ph
[client
[cs_idx
].ctyp
].recv(buf
, l
);
1842 if (tp
.time
<=time((time_t *)0)) // client maxidle reached
1848 if (ph
[client
[cs_idx
].ctyp
].watchdog
)
1849 alarm(cfg
->cmaxidle
+2);
1853 static void process_master_pipe()
1858 switch(n
=read_from_pipe(mfdr
, &ptr
, 1))
1869 void cs_log_config()
1874 sprintf(buf
, ", nice=%d", cfg
->nice
);
1877 cs_log("version=%s, system=%s%s", CS_VERSION_X
, cs_platform(buf
+64), buf
);
1878 cs_log("max. clients=%d, client max. idle=%d sec",
1880 CS_MAXPID
-3, cfg
->cmaxidle
);
1882 CS_MAXPID
-2, cfg
->cmaxidle
);
1884 if( cfg
->max_log_size
)
1885 sprintf(buf
, "%d Kb", cfg
->max_log_size
);
1887 strcpy(buf
, "unlimited");
1888 cs_log("max. logsize=%s", buf
);
1889 cs_log("client timeout=%d sec, cache delay=%d msec",
1890 cfg
->ctimeout
, cfg
->delay
);
1892 cs_log("shared memory initialized (size=%d, fd=%d)", shmsize
, shmid
);
1894 cs_log("shared memory initialized (size=%d, id=%d)", shmsize
, shmid
);
1898 int main (int argc
, char *argv
[])
1900 struct sockaddr_in cad
; /* structure to hold client's address */
1901 int scad
; /* length of address */
1902 //int fd; /* socket descriptors */
1908 void (*mod_def
[])(struct s_module
*)=
1923 while ((i
=getopt(argc
, argv
, "bc:d:hm:"))!=EOF
)
1929 case 'c': strncpy(cs_confdir
, optarg
, sizeof(cs_confdir
)-1);
1931 case 'd': cs_dblevel
=atoi(optarg
);
1935 strncpy(cs_memfile
, optarg
, sizeof(cs_memfile
)-1);
1942 if (cs_confdir
[strlen(cs_confdir
)]!='/') strcat(cs_confdir
, "/");
1945 for (i
=0; mod_def
[i
]; i
++) // must be later BEFORE init_config()
1947 memset(&ph
[i
], 0, sizeof(struct s_module
));
1951 cs_log("auth size=%d", sizeof(struct s_auth
));
1958 cs_set_mloc(30, "init");
1961 //init_irdeto_guess_tab();
1962 cs_init_statistics(cfg
->usrfile
);
1966 cs_log("Cannot create pipe (errno=%d)", errno
);
1973 if (bg
&& daemon(1,0))
1975 cs_log("Error starting in background (errno=%d)", errno
);
1978 master_pid
=client
[0].pid
=getpid();
1979 if (cfg
->pidfile
[0])
1982 if (!(fp
=fopen(cfg
->pidfile
, "w")))
1984 cs_log("Cannot open pid-file (errno=%d)", errno
);
1987 fprintf(fp
, "%d\n", getpid());
1991 for (i
=0; i
<CS_MAX_MOD
; i
++)
1992 if( (ph
[i
].type
& MOD_CONN_NET
) && ph
[i
].ptab
)
1993 for(j
=0; j
<ph
[i
].ptab
->nports
; j
++)
1995 start_listener(&ph
[i
], j
);
1996 if( ph
[i
].ptab
->ports
[j
].fd
+1>gfd
)
1997 gfd
=ph
[i
].ptab
->ports
[j
].fd
+1;
2000 start_client_resolver();
2001 init_service(97); // logger
2002 init_service(98); // resolver
2005 if( !cfg
->ac_enabled
)
2006 cs_log("anti cascading disabled");
2014 for (i
=0; i
<CS_MAX_MOD
; i
++)
2015 if (ph
[i
].type
& MOD_CONN_SERIAL
) // for now: oscam_ser only
2016 if (ph
[i
].s_handler
)
2029 for (i
=0; i
<CS_MAX_MOD
; i
++)
2030 if ( (ph
[i
].type
& MOD_CONN_NET
) && ph
[i
].ptab
)
2031 for (j
=0; j
<ph
[i
].ptab
->nports
; j
++)
2032 if (ph
[i
].ptab
->ports
[j
].fd
)
2033 FD_SET(ph
[i
].ptab
->ports
[j
].fd
, &fds
);
2035 cs_set_mloc(0, "before select");
2036 select(gfd
, &fds
, 0, 0, 0);
2037 cs_set_mloc(60, "after select");
2038 } while (errno
==EINTR
);
2039 cs_set_mloc(-1, "event (global)");
2041 client
[0].last
=time((time_t *)0);
2043 if (FD_ISSET(mfdr
, &fds
))
2045 cs_set_mloc(-1, "event: master-pipe");
2046 process_master_pipe();
2048 for (i
=0; i
<CS_MAX_MOD
; i
++)
2050 if( (ph
[i
].type
& MOD_CONN_NET
) && ph
[i
].ptab
)
2052 for( j
=0; j
<ph
[i
].ptab
->nports
; j
++ )
2054 if( ph
[i
].ptab
->ports
[j
].fd
&& FD_ISSET(ph
[i
].ptab
->ports
[j
].fd
, &fds
) )
2056 if (ph
[i
].type
==MOD_CONN_UDP
)
2058 cs_set_mloc(-1, "event: udp-socket");
2059 if ((n
=recvfrom(ph
[i
].ptab
->ports
[j
].fd
, buf
+3, sizeof(buf
)-3, 0, (struct sockaddr
*)&cad
, &scad
))>0)
2062 idx
=idx_from_ip(cs_inet_order(cad
.sin_addr
.s_addr
), ntohs(cad
.sin_port
));
2067 cs_log("Cannot create pipe (errno=%d)", errno
);
2070 switch(cs_fork(cs_inet_order(cad
.sin_addr
.s_addr
), ntohs(cad
.sin_port
)))
2077 client
[idx
=cs_last_idx
].ufd
=fdp
[1];
2081 // close(fdp[1]); // now used to simulate event
2084 client
[cs_idx
].ctyp
=i
;
2085 client
[cs_idx
].port_idx
=j
;
2086 client
[cs_idx
].udp_fd
=ph
[i
].ptab
->ports
[j
].fd
;
2087 client
[cs_idx
].udp_sa
=cad
;
2088 if (ph
[client
[cs_idx
].ctyp
].watchdog
)
2089 alarm(cfg
->cmaxidle
<<2);
2090 ph
[i
].s_handler(cad
); // never return
2098 memcpy(buf
+1, &rl
, 2);
2099 write(client
[idx
].ufd
, buf
, n
+3);
2105 cs_set_mloc(-1, "event: tcp-socket");
2106 if ((pfd
=accept(ph
[i
].ptab
->ports
[j
].fd
, (struct sockaddr
*)&cad
, &scad
))>0)
2108 switch(cs_fork(cs_inet_order(cad
.sin_addr
.s_addr
), ntohs(cad
.sin_port
)))
2116 client
[cs_idx
].ctyp
=i
;
2117 client
[cs_idx
].udp_fd
=pfd
;
2118 client
[cs_idx
].port_idx
=j
;
2119 if (ph
[client
[cs_idx
].ctyp
].watchdog
)
2120 alarm(cfg
->cmaxidle
<<2);
2127 } // if (ph[i].type & MOD_CONN_NET)