1 /* reserved.c (adapted for trekhopd)
2  *
3  * Kevin P. Smith   7/3/89
4  *
5  */
6 #include "config.h"
7 #include "copyright2.h"
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/socket.h>
12 #include INC_NETINET_IN
13 
14 #include "Wlib.h"
15 #include "defs.h"
16 #include "struct.h"
17 #include "data.h"
18 #include "packets.h"
19 
20 #include "reserved.h"
21 
22 #ifdef GATEWAY
23 extern unsigned LONG netaddr;
24 
25 #endif
26 extern void terminate(int error);
27 
makeReservedPacket(struct reserved_spacket * packet)28 void makeReservedPacket(struct reserved_spacket *packet)
29 {
30   int     i;
31 
32   for (i = 0; i < 16; i++)
33     {
34       packet->data[i] = RANDOM() % 256;
35     }
36   packet->type = SP_RESERVED;
37 }
38 
39 /* A "random" table we use to hose our data. */
40 
41 static unsigned char swap[16][16] =
42 {
43   {4, 13, 9, 7, 5, 8, 14, 2, 10, 11, 6, 3, 12, 15, 0, 1},
44   {0, 4, 12, 5, 15, 2, 7, 3, 14, 6, 1, 10, 8, 13, 11, 9},
45   {9, 5, 4, 2, 3, 6, 10, 12, 1, 7, 15, 14, 11, 0, 13, 8},
46   {5, 8, 15, 4, 6, 9, 1, 12, 10, 3, 13, 11, 2, 7, 0, 14},
47   {15, 13, 1, 14, 4, 0, 8, 12, 11, 9, 2, 10, 3, 6, 7, 5},
48   {6, 7, 9, 11, 14, 1, 4, 13, 2, 12, 8, 15, 10, 0, 5, 3},
49   {11, 0, 10, 14, 7, 12, 2, 4, 15, 13, 3, 9, 1, 5, 8, 6},
50   {9, 8, 2, 10, 12, 14, 3, 7, 4, 0, 11, 1, 5, 15, 6, 13},
51   {15, 12, 3, 0, 10, 8, 13, 9, 14, 2, 4, 5, 7, 6, 1, 11},
52   {14, 3, 0, 11, 2, 10, 15, 12, 13, 1, 5, 4, 6, 8, 7, 9},
53   {1, 2, 7, 3, 8, 0, 10, 14, 6, 5, 13, 12, 4, 9, 11, 15},
54   {2, 1, 11, 9, 7, 3, 12, 6, 5, 8, 0, 10, 14, 4, 15, 13},
55   {0, 12, 15, 1, 13, 7, 6, 5, 3, 14, 11, 8, 9, 10, 2, 4},
56   {10, 9, 0, 6, 1, 14, 5, 12, 7, 4, 15, 13, 8, 2, 3, 11},
57   {3, 11, 6, 12, 10, 5, 14, 1, 9, 15, 7, 2, 13, 8, 4, 0},
58   {12, 6, 5, 8, 14, 4, 13, 15, 10, 0, 11, 9, 3, 1, 7, 2}
59 };
60 
encryptReservedPacket(struct reserved_spacket * spacket,struct reserved_cpacket * cpacket,char * server,int pno)61 void encryptReservedPacket(struct reserved_spacket *spacket, struct reserved_cpacket *cpacket, char *server, int pno)
62 {
63   struct sockaddr_in saddr;
64   unsigned char mixin1, mixin2, mixin3, mixin4, mixin5;
65   int     i, j, k;
66   char    buf[16];
67   unsigned char *s;
68   int     len;
69 
70 #ifndef GATEWAY
71   unsigned LONG netaddr = 0;
72 
73 #endif
74 
75   MCOPY(spacket->data, cpacket->data, 16);
76   MCOPY(spacket->data, cpacket->resp, 16);
77   cpacket->type = CP_RESERVED;
78 
79   /* if we didn't get it from -H, go ahead and query the socket */
80   if (netaddr == 0)
81     {
82       len = sizeof(saddr);
83       if (getpeername(sock, (struct sockaddr *) &saddr, (socklen_t *) &len) < 0)
84 	{
85 	  perror("getpeername(sock)");
86 	  terminate(1);
87 	}
88       netaddr = saddr.sin_addr.s_addr;
89     }
90 
91   /* printf("Verifying with netaddr %x\n", netaddr); */
92   mixin1 = (netaddr >> 24) & 0xff;
93   mixin2 = pno;
94   mixin3 = (netaddr >> 16) & 0xff;
95   mixin4 = (netaddr >> 8) & 0xff;
96   mixin5 = netaddr & 0xff;
97 
98   j = 0;
99   for (i = 0; i < 23; i++)
100     {
101       j = (j + cpacket->resp[j]) & 15;
102       s = swap[j];
103       cpacket->resp[s[i % 7]] ^= mixin1;
104       cpacket->resp[s[i % 5]] ^= mixin2;
105       cpacket->resp[s[i % 13]] ^= mixin3;
106       cpacket->resp[s[i % 3]] ^= mixin4;
107       cpacket->resp[s[i % 11]] ^= mixin5;
108       for (k = 0; k < 16; k++)
109 	{
110 	  buf[k] = cpacket->resp[s[k]];
111 	}
112       MCOPY(buf, cpacket->resp, 16);
113     }
114 }
115