Browse Source

Create functions that process each stream element

Georgi Chorbadzhiyski 13 years ago
parent
commit
7a57615158
1 changed files with 207 additions and 199 deletions
  1. 207
    199
      tsdecrypt.c

+ 207
- 199
tsdecrypt.c View File

@@ -18,6 +18,45 @@
18 18
 
19 19
 #include "util.h"
20 20
 
21
+struct ts {
22
+	struct ts_pat		*pat, *curpat;
23
+	struct ts_cat		*cat, *curcat;
24
+	struct ts_pmt		*pmt, *curpmt;
25
+	struct ts_privsec	*emm, *last_emm;
26
+	struct ts_privsec	*ecm, *last_ecm;
27
+	uint16_t			pmt_pid;
28
+	uint16_t			service_id;
29
+	uint16_t			emm_caid, emm_pid;
30
+	uint16_t			ecm_caid, ecm_pid;
31
+	uint16_t			ecm_counter;
32
+};
33
+
34
+struct ts *ts_alloc() {
35
+	struct ts *ts = calloc(1, sizeof(struct ts));
36
+	return ts;
37
+}
38
+
39
+void ts_free(struct ts **pts) {
40
+	struct ts *ts = *pts;
41
+	if (ts) {
42
+		ts_pat_free(&ts->pat);
43
+		ts_pat_free(&ts->curpat);
44
+		ts_cat_free(&ts->cat);
45
+		ts_cat_free(&ts->curcat);
46
+		ts_pmt_free(&ts->pmt);
47
+		ts_pmt_free(&ts->curpmt);
48
+		ts_privsec_free(&ts->emm);
49
+		ts_privsec_free(&ts->last_emm);
50
+		ts_privsec_free(&ts->ecm);
51
+		ts_privsec_free(&ts->last_ecm);
52
+		FREE(*pts);
53
+	}
54
+}
55
+
56
+void LOG_func(const char *msg) {
57
+	fprintf(stderr, "%s", msg);
58
+}
59
+
21 60
 enum CA_system req_CA_sys = CA_CONNAX;
22 61
 char *camd35_user = "user";
23 62
 char *camd35_pass = "pass";
@@ -25,26 +64,6 @@ uint32_t camd35_auth = 0;
25 64
 AES_KEY camd35_aes_encrypt_key;
26 65
 AES_KEY camd35_aes_decrypt_key;
27 66
 
28
-void show_help() {
29
-	printf("TSCRYPT v1.0\n");
30
-	puts("Copyright (c) 2011 Unix Solutions Ltd.");
31
-	puts("");
32
-	puts("	Usage: tsdecrypt [opts] < data > data.decrypted");
33
-	puts("");
34
-	exit(0);
35
-}
36
-
37
-void parse_options(int argc, char **argv) {
38
-	int j;
39
-	while ((j = getopt(argc, argv, "f:h")) != -1) {
40
-		switch (j) {
41
-			case 'h':
42
-				show_help();
43
-				exit(0);
44
-		}
45
-	}
46
-}
47
-
48 67
 enum e_flag {
49 68
 	TYPE_EMM,
50 69
 	TYPE_ECM
@@ -99,6 +118,9 @@ static int camd35_send(uint8_t *data, uint8_t data_len, enum e_flag tp) {
99 118
 	uint8_t buf[BUF_SIZE];
100 119
 	uint8_t *bdata = buf + 4;
101 120
 
121
+	if (!camd35_auth)
122
+		camd35_init_auth(camd35_user, camd35_pass);
123
+
102 124
 	init_4b(camd35_auth, buf); // Put authentication token
103 125
 	memcpy(bdata, data, data_len); // Put data
104 126
 
@@ -150,6 +172,144 @@ static int camd35_send_emm(uint16_t ca_id, uint8_t *data, uint8_t data_len) {
150 172
 	return camd35_send(buf, to_send, TYPE_EMM);
151 173
 }
152 174
 
175
+#define handle_table_changes(TABLE) \
176
+	do { \
177
+		if (!ts->cur##TABLE) \
178
+			ts->cur##TABLE = ts_##TABLE##_alloc(); \
179
+		ts->cur##TABLE = ts_##TABLE##_push_packet(ts->cur##TABLE, ts_packet); \
180
+		if (!ts->cur##TABLE->initialized) \
181
+			return;  \
182
+		if (ts_##TABLE##_is_same(ts->TABLE, ts->cur##TABLE)) { \
183
+			ts_##TABLE##_free(&ts->cur##TABLE); \
184
+			return; \
185
+		} \
186
+		ts_##TABLE##_free(&ts->TABLE); \
187
+		ts->TABLE = ts->cur##TABLE; \
188
+		ts->cur##TABLE = NULL; \
189
+		ts_##TABLE##_dump(ts->TABLE); \
190
+	} while(0)
191
+
192
+void process_pat(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
193
+	int i;
194
+	if (pid != 0x00)
195
+		return;
196
+
197
+	handle_table_changes(pat);
198
+
199
+	for (i=0;i<ts->pat->programs_num;i++) {
200
+		struct ts_pat_program *prg = ts->pat->programs[i];
201
+		if (prg->pid) {
202
+			if (prg->program != 0) {
203
+				ts->pmt_pid    = prg->pid;
204
+				ts->service_id = prg->program;
205
+			}
206
+		}
207
+	}
208
+}
209
+
210
+void process_cat(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
211
+	if (pid != 0x01)
212
+		return;
213
+
214
+	handle_table_changes(cat);
215
+
216
+	ts_get_emm_info(ts->cat, req_CA_sys, &ts->emm_caid, &ts->emm_pid);
217
+}
218
+
219
+void process_pmt(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
220
+	if (!pid || pid != ts->pmt_pid)
221
+		return;
222
+
223
+	handle_table_changes(pmt);
224
+
225
+	if (!ts->ecm_caid) {
226
+		ts_get_ecm_info(ts->pmt, req_CA_sys, &ts->ecm_caid, &ts->ecm_pid);
227
+		char *CA_sys = ts_get_CA_sys_txt(ts_get_CA_sys(ts->ecm_caid));
228
+		ts_LOGf("%s Service : 0x%04x\n", CA_sys, ts->service_id);
229
+		ts_LOGf("%s CA_id   : 0x%04x\n", CA_sys, ts->emm_caid);
230
+		ts_LOGf("%s EMM pid : 0x%04x\n", CA_sys, ts->emm_pid);
231
+		ts_LOGf("%s ECM pid : 0x%04x\n", CA_sys, ts->ecm_pid);
232
+	}
233
+}
234
+
235
+void process_emm(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
236
+	if (!ts->emm_pid || ts->emm_pid != pid)
237
+		return;
238
+
239
+	if (!ts->emm)
240
+		ts->emm = ts_privsec_alloc();
241
+
242
+	ts->emm = ts_privsec_push_packet(ts->emm, ts_packet);
243
+	if (!ts->emm->initialized)
244
+		return;
245
+
246
+	struct ts_header *th = &ts->emm->ts_header;
247
+	struct ts_section_header *sec = ts->emm->section_header;
248
+	camd35_send_emm(ts->emm_caid, sec->section_data, sec->section_length + 3);
249
+	char *data = ts_hex_dump(sec->section_data, 16, 0);
250
+	ts_LOGf("EMM | CAID: 0x%04x PID 0x%04x Table: 0x%02x Length: %3d Data: %s..\n",
251
+		ts->emm_caid,
252
+		th->pid,
253
+		sec->table_id,
254
+		sec->section_length + 3,
255
+		data);
256
+	FREE(data);
257
+	ts_privsec_free(&ts->last_emm);
258
+	ts->last_emm = ts->emm;
259
+	ts->emm = ts_privsec_alloc();
260
+}
261
+
262
+void process_ecm(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
263
+	if (!ts->ecm_pid || ts->ecm_pid != pid)
264
+		return;
265
+
266
+	if (!ts->ecm)
267
+		ts->ecm = ts_privsec_alloc();
268
+
269
+	ts->ecm = ts_privsec_push_packet(ts->ecm, ts_packet);
270
+	if (!ts->ecm->initialized)
271
+		return;
272
+
273
+	struct ts_header *th = &ts->ecm->ts_header;
274
+	struct ts_section_header *sec = ts->ecm->section_header;
275
+	if (!ts_privsec_is_same(ts->ecm, ts->last_ecm)) {
276
+		camd35_send_ecm(ts->service_id, ts->ecm_caid, ts->ecm_counter++, sec->section_data, sec->section_length + 3);
277
+		char *data = ts_hex_dump(sec->section_data, 16, 0);
278
+		ts_LOGf("ECM | CAID: 0x%04x PID 0x%04x Table: 0x%02x Length: %3d Data: %s..\n",
279
+			ts->ecm_caid,
280
+			th->pid,
281
+			sec->table_id,
282
+			sec->section_length + 3,
283
+			data);
284
+		FREE(data);
285
+	} else {
286
+		ts_LOGf("ECM | CAID: 0x%04x PID 0x%04x Table: 0x%02x Length: %3d Data: --duplicate--\n",
287
+			ts->ecm_caid,
288
+			th->pid,
289
+			sec->table_id,
290
+			sec->section_length + 3);
291
+	}
292
+	ts_privsec_free(&ts->last_ecm);
293
+	ts->last_ecm = ts->ecm;
294
+	ts->ecm = ts_privsec_alloc();
295
+}
296
+
297
+void ts_process_packets(struct ts *ts, uint8_t *data, uint8_t data_len) {
298
+	int i;
299
+	for (i=0; i<data_len; i += 188) {
300
+		uint8_t *ts_packet = data + i;
301
+		uint16_t pid = ts_packet_get_pid(ts_packet);
302
+
303
+		process_pat(ts, pid, ts_packet);
304
+		process_cat(ts, pid, ts_packet);
305
+		process_pmt(ts, pid, ts_packet);
306
+		process_emm(ts, pid, ts_packet);
307
+		process_ecm(ts, pid, ts_packet);
308
+	}
309
+}
310
+
311
+
312
+
153 313
 #define ERR(x) do { fprintf(stderr, "%s", x); return NULL; } while (0)
154 314
 
155 315
 static uint8_t *camd35_recv_cw(uint8_t *data, int data_len) {
@@ -184,194 +344,42 @@ static uint8_t *camd35_recv_cw(uint8_t *data, int data_len) {
184 344
 
185 345
 #undef ERR
186 346
 
187
-void camd35_test() {
188
-	#define test_ecm_len 103
189
-	uint8_t test_ecm[test_ecm_len] = {
190
-		 0x80, 0x70, 0x64, 0x70, 0x62, 0x64, 0x20, 0x76, 0xFF, 0xA8, 0xC1, 0x80, 0x9C, 0xE3, 0xDC, 0xB4, 
191
-		 0xD9, 0xC3, 0xD1, 0xEA, 0x26, 0xFE, 0xF7, 0xE4, 0xA8, 0x26, 0x34, 0x45, 0x51, 0x82, 0x6A, 0xE0, 
192
-		 0x00, 0x37, 0x09, 0x1A, 0xAE, 0xC3, 0x5A, 0xD6, 0xE1, 0xC1, 0x5F, 0x8E, 0x55, 0xC3, 0xA4, 0x88, 
193
-		 0x38, 0x93, 0xDC, 0xD5, 0x9F, 0x10, 0x58, 0xC0, 0xED, 0xB8, 0x4C, 0xED, 0x19, 0x6A, 0x2A, 0xEF, 
194
-		 0x6D, 0xCB, 0x9F, 0x7B, 0x71, 0xC4, 0x29, 0x44, 0x7F, 0xA0, 0x76, 0x80, 0x9E, 0x29, 0x52, 0x4E, 
195
-		 0x19, 0x11, 0xC4, 0xCD, 0xFD, 0x8F, 0x4F, 0xEC, 0x7F, 0x6A, 0xE3, 0x1F, 0x1F, 0x24, 0x0D, 0xEE, 
196
-		 0x7F, 0xF2, 0x35, 0xA4, 0x1C, 0x86, 0x84 };
197
-
198
-	#define test_recv_len 128
199
-	uint8_t test_recv[test_recv_len] = {
200
-		 0x00, 0x67, 0x00, 0x00, 0x99, 0x14, 0x7A, 0xA0, 0x15, 0x22, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00,
201
-		 0x00, 0x12, 0xFF, 0xFF, 0x80, 0x70, 0x64, 0x70, 0x62, 0x64, 0x20, 0x76, 0xFF, 0xA8, 0xC1, 0x80,
202
-		 0x9C, 0xE3, 0xDC, 0xB4, 0xD9, 0xC3, 0xD1, 0xEA, 0x26, 0xFE, 0xF7, 0xE4, 0xA8, 0x26, 0x34, 0x45,
203
-		 0x51, 0x82, 0x6A, 0xE0, 0x00, 0x37, 0x09, 0x1A, 0xAE, 0xC3, 0x5A, 0xD6, 0xE1, 0xC1, 0x5F, 0x8E,
204
-		 0x55, 0xC3, 0xA4, 0x88, 0x38, 0x93, 0xDC, 0xD5, 0x9F, 0x10, 0x58, 0xC0, 0xED, 0xB8, 0x4C, 0xED,
205
-		 0x19, 0x6A, 0x2A, 0xEF, 0x6D, 0xCB, 0x9F, 0x7B, 0x71, 0xC4, 0x29, 0x44, 0x7F, 0xA0, 0x76, 0x80,
206
-		 0x9E, 0x29, 0x52, 0x4E, 0x19, 0x11, 0xC4, 0xCD, 0xFD, 0x8F, 0x4F, 0xEC, 0x7F, 0x6A, 0xE3, 0x1F,
207
-		 0x1F, 0x24, 0x0D, 0xEE, 0x7F, 0xF2, 0x35, 0xA4, 0x1C, 0x86, 0x84, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
208
-	};
209
-
210
-	#define test_recv_cw_len 52
211
-	uint8_t test_recv_cw[test_recv_cw_len] = {
212
-		 0x11, 0x22, 0x33, 0x44,
213
-		 0x01, 0x10, 0x00, 0x00, 0xB2, 0x05, 0xDF, 0xA0, 0x15, 0x22, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00,
214
-		 0x00, 0x12, 0xFF, 0xFF, 0xE1, 0x96, 0xE6, 0x5D, 0x09, 0x83, 0x91, 0x1D, 0x85, 0xA4, 0xD1, 0xFA,
215
-		 0xB7, 0x43, 0xAA, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
216
-	};
217
-
218
-	camd35_init_auth(camd35_user, camd35_pass);
219
-
220
-	char *d = ts_hex_dump(test_recv, test_recv_len, 16);
221
-	fprintf(stderr, "%s\n\n", d);
222
-	free(d);
223
-
224
-	camd35_send_ecm(0x1522, 0x0b01, 0x0012, test_ecm, test_ecm_len);
347
+void show_help() {
348
+	printf("TSDECRYPT v1.0\n");
349
+	puts("Copyright (c) 2011 Unix Solutions Ltd.");
350
+	puts("");
351
+	puts("	Usage: tsdecrypt [opts] < data > data.decrypted");
352
+	puts("");
353
+	exit(0);
354
+}
225 355
 
226
-//	camd35_send_emm(0x0b01, test_ecm, test_ecm_len);
227
-//
228
-//	camd35_recv_cw(test_recv_cw, test_recv_cw_len);
356
+void parse_options(int argc, char **argv) {
357
+	int j;
358
+	while ((j = getopt(argc, argv, "f:h")) != -1) {
359
+		switch (j) {
360
+			case 'h':
361
+				show_help();
362
+				exit(0);
363
+		}
364
+	}
229 365
 }
230 366
 
367
+#define FRAME_SIZE (188 * 7)
231 368
 
232 369
 int main(int argc, char **argv) {
233
-	int fd = 0; // stdin
370
+	ssize_t readen;
371
+	uint8_t ts_packet[FRAME_SIZE];
372
+
373
+	ts_set_log_func(LOG_func);
234 374
 
235 375
 	parse_options(argc, argv);
236 376
 
237
-	camd35_init_auth(camd35_user, camd35_pass);
238
-
239
-	struct ts_pat *pat = ts_pat_alloc();
240
-	struct ts_cat *cat = ts_cat_alloc();
241
-	struct ts_pmt *pmt = ts_pmt_alloc();
242
-	struct ts_privsec *emm = ts_privsec_alloc();
243
-	struct ts_privsec *ecm = ts_privsec_alloc();
244
-	struct ts_privsec *last_emm = NULL;
245
-	struct ts_privsec *last_ecm = NULL;
246
-	uint16_t pmt_pid = 0;
247
-
248
-	uint16_t ca_id = 0;
249
-	uint16_t emm_caid = 0, emm_pid = 0;
250
-	uint16_t ecm_caid = 0, ecm_pid = 0;
251
-	uint16_t service_id = 0;
252
-	uint16_t ecm_counter = 0;
253
-
377
+	struct ts *ts = ts_alloc();
254 378
 	do {
255
-		uint8_t ts_packet[188];
256
-		ssize_t readen = read(fd, ts_packet, 188);
257
-		if (readen < 188)
258
-			break;
259
-
260
-		uint16_t pid = ts_packet_get_pid(ts_packet);
261
-
262
-		if (pid == 0x00) {
263
-			pat = ts_pat_push_packet(pat, ts_packet);
264
-			if (pat->initialized) {
265
-				int i;
266
-				for (i=0;i<pat->programs_num;i++) {
267
-					struct ts_pat_program *prg = pat->programs[i];
268
-					if (prg->pid) {
269
-						if (prg->program != 0) {
270
-							service_id = prg->program;
271
-							pmt_pid = prg->pid;
272
-						}
273
-					}
274
-				}
275
-				ts_pat_free(&pat);
276
-				pat = ts_pat_alloc();
277
-			}
278
-		}
279
-
280
-		if (pid == 1) {
281
-			cat = ts_cat_push_packet(cat, ts_packet);
282
-			if (cat->initialized) {
283
-				if (req_CA_sys != CA_UNKNOWN) {
284
-					ts_get_emm_info(cat, req_CA_sys, &emm_caid, &emm_pid);
285
-					ca_id = emm_caid;
286
-				}
287
-				ts_cat_free(&cat);
288
-				cat = ts_cat_alloc();
289
-			}
290
-		}
291
-
292
-		if (pid && pid == pmt_pid) {
293
-			pmt = ts_pmt_push_packet(pmt, ts_packet, pmt_pid);
294
-			if (pmt->initialized) {
295
-				if (req_CA_sys != CA_UNKNOWN && !ecm_caid) {
296
-					ts_get_ecm_info(pmt, req_CA_sys, &ecm_caid, &ecm_pid);
297
-					char *CA_sys = ts_get_CA_sys_txt(ts_get_CA_sys(emm_caid));
298
-					printf("%s Service : 0x%04x\n", CA_sys, service_id);
299
-					printf("%s CA_id   : 0x%04x\n", CA_sys, emm_caid);
300
-					printf("%s EMM pid : 0x%04x\n", CA_sys, emm_pid);
301
-					printf("%s ECM pid : 0x%04x\n", CA_sys, ecm_pid);
302
-				}
303
-				ts_pmt_free(&pmt);
304
-				pmt = ts_pmt_alloc();
305
-			}
306
-		}
307
-
308
-		if (emm_pid && pid == emm_pid) {
309
-			emm = ts_privsec_push_packet(emm, ts_packet);
310
-			if (emm->initialized) {
311
-				struct ts_header *th = &emm->ts_header;
312
-				struct ts_section_header *sec = emm->section_header;
313
-				camd35_send_emm(ca_id, sec->section_data, sec->section_length + 3);
314
-				char *data = ts_hex_dump(sec->section_data, sec->section_length, 0);
315
-				ts_LOGf("EMM dump | CAID: 0x%04x PID 0x%04x (%5d) Table: 0x%02x (%3d) Length: %4d Data: %s\n",
316
-					emm_caid,
317
-					th->pid, th->pid,
318
-					sec->table_id, sec->table_id,
319
-					sec->section_length + 3,
320
-					data);
321
-				FREE(data);
322
-				ts_privsec_free(&last_emm);
323
-				last_emm = emm;
324
-				emm = ts_privsec_alloc();
325
-			}
326
-		}
327
-
328
-#ifndef min
329
-#define min(a,b) ((a < b) ? a : b)
330
-#endif
331
-
332
-		if (ecm_pid && pid == ecm_pid) {
333
-			ecm = ts_privsec_push_packet(ecm, ts_packet);
334
-			if (ecm->initialized) {
335
-				int is_same = 0;
336
-				struct ts_header *th = &ecm->ts_header;
337
-				struct ts_section_header *sec = ecm->section_header;
338
-				if (last_ecm) {
339
-					is_same = memcmp(
340
-						last_ecm->section_header->section_data,
341
-						ecm->section_header->section_data,
342
-						min(last_ecm->section_header->section_length, ecm->section_header->section_length)) == 0;
343
-				}
344
-				if (!is_same) {
345
-					camd35_send_ecm(service_id, ca_id, ecm_counter++, sec->section_data, sec->section_length + 3);
346
-					char *data = ts_hex_dump(sec->section_data, sec->section_length, 0);
347
-					ts_LOGf("ECM dump | CAID: 0x%04x PID 0x%04x (%5d) Table: 0x%02x (%3d) Length: %4d Data: %s\n",
348
-						ecm_caid,
349
-						th->pid, th->pid,
350
-						sec->table_id, sec->table_id,
351
-						sec->section_length + 3,
352
-						data);
353
-					FREE(data);
354
-				} else if (0) {
355
-					ts_LOGf("ECM dump | CAID: 0x%04x PID 0x%04x (%5d) Table: 0x%02x (%3d) Length: %4d Data: --duplicate--\n",
356
-						ecm_caid,
357
-						th->pid, th->pid,
358
-						sec->table_id, sec->table_id,
359
-						sec->section_length + 3);
360
-				}
361
-				ts_privsec_free(&last_ecm);
362
-				last_ecm = ecm;
363
-				ecm = ts_privsec_alloc();
364
-			}
365
-		}
366
-	} while (1);
367
-	ts_pat_free(&pat);
368
-	ts_cat_free(&cat);
369
-	ts_pmt_free(&pmt);
370
-	ts_privsec_free(&emm);
371
-	ts_privsec_free(&ecm);
372
-	ts_privsec_free(&last_emm);
373
-	ts_privsec_free(&last_ecm);
374
-
379
+		readen = read(0, ts_packet, FRAME_SIZE);
380
+		ts_process_packets(ts, ts_packet, readen);
381
+	} while (readen == FRAME_SIZE);
382
+	ts_free(&ts);
375 383
 
376 384
 	exit(0);
377 385
 }

Loading…
Cancel
Save