]> git.vomp.tv Git - vompserver.git/blob - udp6replier.c
15 years that line of code has been waiting to crash
[vompserver.git] / udp6replier.c
1 /*
2     Copyright 2019 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <arpa/inet.h>
23
24 #include "vompclientrrproc.h"
25
26 #include "udp6replier.h"
27
28 UDP6Replier::UDP6Replier()
29 {
30   message = NULL;
31   messageLen = 0;
32 }
33
34 UDP6Replier::~UDP6Replier()
35 {
36   shutdown();
37 }
38
39 int UDP6Replier::shutdown()
40 {
41   if (threadIsActive()) threadCancel();
42
43   if (message) delete[] message;
44   message = NULL;
45   return 1;
46 }
47
48 int UDP6Replier::run(USHORT port, char* serverName, USHORT serverPort)
49 {
50   if (threadIsActive()) return 1;
51
52   /*
53   VOMP Discovery Protocol V1
54
55   Client transmits: "VDP-0001\0<6-byte MAC>"...
56   ... for IPv4: broadcasts on ports 51051-51055
57   ... for IPv6: multicasts to ff15:766f:6d70:2064:6973:636f:7665:7279 port 51056
58
59   Server responds:
60
61   Field 1 p0: 9 bytes "VDP-0002\0"
62   
63   Field 2 p9, 1 byte:
64
65   0 = no IP specified
66   4 = first 4 bytes of field 3 are IPv4 address of server
67   6 = field 3 16 bytes are IPv6 address of server
68
69   Field 3, p10, 16 bytes:
70   As described above. If field 2 is 0, this should be all zeros. If this is an IPv4 address, remaining bytes should be zeros.
71
72   Field 4 p26, 2 bytes:
73   Port number of server
74
75   Field 5 p28, 4 bytes:
76   VOMP protocol version (defined in vdr.cc)
77   
78   Field 6 p32, variable length
79   String of server name, null terminated
80   */
81   
82   messageLen = strlen(serverName) + 33;
83   message = new char[messageLen];
84   memset(message, 0, messageLen);
85   // by zeroing the packet, this sets no ip address return information
86   
87   strcpy(message, "VDP-0002");
88   
89   USHORT temp = htons(serverPort);
90   memcpy(&message[26], &temp, 2);
91   
92   ULONG temp2 = htonl(VompClientRRProc::getProtocolVersionMin());
93   memcpy(&message[28], &temp2, 4);
94   
95   strcpy(&message[32], serverName);
96   // Fix Me add also the maximum version somewhere
97   if (!ds.init(port))
98   {
99     shutdown();
100     return 0;
101   }
102
103   if (!threadStart())
104   {
105     shutdown();
106     return 0;
107   }
108
109   Log::getInstance()->log("UDP6Replier", Log::DEBUG, "UDP replier started");
110   return 1;
111 }
112
113 void UDP6Replier::threadMethod()
114 {
115   int retval;
116   while(1)
117   {
118     retval = ds.waitforMessage(0);
119     if (retval == 1) continue;
120
121     if (!strncmp(ds.getData(), "VDP-0001", 8))
122     {
123       Log::getInstance()->log("UDP6Replier", Log::DEBUG, "UDP6 request from %s", ds.getFromIPA());
124       ds.send(ds.getFromIPA(), ds.getFromPort(), message, messageLen);
125     }
126   }
127 }