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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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 for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <sys/socket.h>
  26. #include <netinet/in.h>
  27. #include <arpa/inet.h>
  28. #include <errno.h>
  29. #include "udp.h"
  30. int udp_connect_input(struct io *io) {
  31. int sock = socket(AF_INET, SOCK_DGRAM, 0);
  32. if (sock < 0) {
  33. ts_LOGf("socket(SOCK_DGRAM): %s\n", strerror(errno));
  34. return -1;
  35. }
  36. ts_LOGf("Connecting input to udp://%s:%d/\n", inet_ntoa(io->addr), io->port);
  37. int on = 1;
  38. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  39. /* Set receive buffer size to ~2.0MB */
  40. int bufsize = (2000000 / 1316) * 1316;
  41. setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, sizeof(bufsize));
  42. // subscribe to multicast group
  43. if (IN_MULTICAST(ntohl(io->addr.s_addr))) {
  44. struct ip_mreq mreq;
  45. memcpy(&mreq.imr_multiaddr, &io->addr, sizeof(struct in_addr));
  46. mreq.imr_interface.s_addr = htonl(INADDR_ANY);
  47. if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
  48. ts_LOGf("setsockopt(IP_ADD_MEMBERSHIP %s): %s\n", inet_ntoa(io->addr), strerror(errno));
  49. return -1;
  50. }
  51. }
  52. // bind to the socket so data can be read
  53. struct sockaddr_in receiving_from;
  54. memset(&receiving_from, 0, sizeof(receiving_from));
  55. receiving_from.sin_family = AF_INET;
  56. receiving_from.sin_addr = io->addr;
  57. receiving_from.sin_port = htons(io->port);
  58. if (bind(sock, (struct sockaddr *) &receiving_from, sizeof(receiving_from)) < 0) {
  59. ts_LOGf("bind(): %s\n", strerror(errno));
  60. return -1;
  61. }
  62. io->fd = sock;
  63. ts_LOGf("Input connected to fd:%d\n", io->fd);
  64. return 1;
  65. }
  66. int udp_connect_output(struct io *io) {
  67. int sock = socket(AF_INET, SOCK_DGRAM, 0);
  68. if (sock < 0) {
  69. ts_LOGf("socket(SOCK_DGRAM): %s\n", strerror(errno));
  70. return -1;
  71. }
  72. ts_LOGf("Connecting output to udp://%s:%d ttl:%d\n",
  73. inet_ntoa(io->addr), io->port, io->ttl);
  74. int on = 1;
  75. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  76. set_sock_nonblock(sock);
  77. /* Set receive buffer size to ~2.0MB */
  78. int bufsize = (2000000 / 1316) * 1316;
  79. setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&bufsize, sizeof(bufsize));
  80. // subscribe to multicast group
  81. if (IN_MULTICAST(ntohl(io->addr.s_addr))) {
  82. int ttl = io->ttl;
  83. if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
  84. ts_LOGf("setsockopt(IP_MUTICAST_TTL): %s\n", strerror(errno));
  85. close(sock);
  86. return -1;
  87. }
  88. if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &io->intf, sizeof(io->intf)) < 0) {
  89. ts_LOGf("setsockopt(IP_MUTICAST_IF %s): %s\n", inet_ntoa(io->intf), strerror(errno));
  90. close(sock);
  91. return -1;
  92. }
  93. }
  94. struct sockaddr_in sockaddr;
  95. memset(&sockaddr, 0, sizeof(sockaddr));
  96. sockaddr.sin_family = AF_INET;
  97. sockaddr.sin_addr.s_addr = io->addr.s_addr;
  98. sockaddr.sin_port = htons(io->port);
  99. if (connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
  100. ts_LOGf("udp_connect() error: %s\n", strerror(errno));
  101. close(sock);
  102. return -1;
  103. }
  104. io->fd = sock;
  105. ts_LOGf("Output connected to fd:%d\n", io->fd);
  106. return 1;
  107. }