tsdecrypt reads and decrypts CSA encrypted incoming mpeg transport stream over UDP/RTP using code words obtained from OSCAM or similar CAM server. tsdecrypt communicates with CAM server using cs378x (camd35 over tcp) protocol or newcamd protocol. https://georgi.unixsol.org/programs/tsdecrypt/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

udp.c 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * UDP functions
  3. * Copyright (C) 2011 Unix Solutions Ltd.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License (COPYING file) for more details.
  13. *
  14. */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <unistd.h>
  21. #include <fcntl.h>
  22. #include <sys/socket.h>
  23. #include <netinet/in.h>
  24. #include <arpa/inet.h>
  25. #include <errno.h>
  26. #include "udp.h"
  27. int udp_connect_input(struct io *io) {
  28. int sock = socket(AF_INET, SOCK_DGRAM, 0);
  29. if (sock < 0) {
  30. ts_LOGf("socket(SOCK_DGRAM): %s\n", strerror(errno));
  31. return -1;
  32. }
  33. ts_LOGf("Connecting input to udp://%s:%d/\n", inet_ntoa(io->addr), io->port);
  34. int on = 1;
  35. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  36. /* Set receive buffer size to ~2.0MB */
  37. int bufsize = (2000000 / 1316) * 1316;
  38. setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, sizeof(bufsize));
  39. // subscribe to multicast group
  40. if (IN_MULTICAST(ntohl(io->addr.s_addr))) {
  41. struct ip_mreq mreq;
  42. memcpy(&mreq.imr_multiaddr, &io->addr, sizeof(struct in_addr));
  43. mreq.imr_interface.s_addr = htonl(INADDR_ANY);
  44. if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
  45. ts_LOGf("setsockopt(IP_ADD_MEMBERSHIP %s): %s\n", inet_ntoa(io->addr), strerror(errno));
  46. return -1;
  47. }
  48. }
  49. // bind to the socket so data can be read
  50. struct sockaddr_in receiving_from;
  51. memset(&receiving_from, 0, sizeof(receiving_from));
  52. receiving_from.sin_family = AF_INET;
  53. receiving_from.sin_addr = io->addr;
  54. receiving_from.sin_port = htons(io->port);
  55. if (bind(sock, (struct sockaddr *) &receiving_from, sizeof(receiving_from)) < 0) {
  56. ts_LOGf("bind(): %s\n", strerror(errno));
  57. return -1;
  58. }
  59. io->fd = sock;
  60. ts_LOGf("Input connected to fd:%d\n", io->fd);
  61. return 1;
  62. }
  63. int udp_connect_output(struct io *io) {
  64. int sock = socket(AF_INET, SOCK_DGRAM, 0);
  65. if (sock < 0) {
  66. ts_LOGf("socket(SOCK_DGRAM): %s\n", strerror(errno));
  67. return -1;
  68. }
  69. ts_LOGf("Connecting output to udp://%s:%d ttl:%d\n",
  70. inet_ntoa(io->addr), io->port, io->ttl);
  71. int on = 1;
  72. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  73. set_sock_nonblock(sock);
  74. /* Set receive buffer size to ~2.0MB */
  75. int bufsize = (2000000 / 1316) * 1316;
  76. setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&bufsize, sizeof(bufsize));
  77. // subscribe to multicast group
  78. if (IN_MULTICAST(ntohl(io->addr.s_addr))) {
  79. int ttl = io->ttl;
  80. if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
  81. ts_LOGf("setsockopt(IP_MUTICAST_TTL): %s\n", strerror(errno));
  82. close(sock);
  83. return -1;
  84. }
  85. if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &io->intf, sizeof(io->intf)) < 0) {
  86. ts_LOGf("setsockopt(IP_MUTICAST_IF %s): %s\n", inet_ntoa(io->intf), strerror(errno));
  87. close(sock);
  88. return -1;
  89. }
  90. }
  91. if (io->tos > -1) {
  92. if (setsockopt(sock, IPPROTO_IP, IP_TOS, &io->tos, sizeof(io->tos)) < 0) {
  93. ts_LOGf("setsockopt(IP_TOS 0x%02x): %s\n", io->tos, strerror(errno));
  94. }
  95. }
  96. struct sockaddr_in sockaddr;
  97. memset(&sockaddr, 0, sizeof(sockaddr));
  98. sockaddr.sin_family = AF_INET;
  99. sockaddr.sin_addr.s_addr = io->addr.s_addr;
  100. sockaddr.sin_port = htons(io->port);
  101. if (connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
  102. ts_LOGf("udp_connect() error: %s\n", strerror(errno));
  103. close(sock);
  104. return -1;
  105. }
  106. io->fd = sock;
  107. ts_LOGf("Output connected to fd:%d\n", io->fd);
  108. return 1;
  109. }