af1cb527eb1426f9a31cce802861af40bb45a6da
[tinc] / src / protocol_misc.c
1 /*
2     protocol_misc.c -- handle the meta-protocol, miscellaneous functions
3     Copyright (C) 1999-2002 Ivo Timmermans <ivo@o2w.nl>,
4                   2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5
6     This program 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     This program 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 this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20     $Id: protocol_misc.c,v 1.1.4.4 2002/06/21 10:11:19 guus Exp $
21 */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <syslog.h>
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <errno.h>
31
32 #include <utils.h>
33
34 #include "conf.h"
35 #include "net.h"
36 #include "netutl.h"
37 #include "protocol.h"
38 #include "meta.h"
39 #include "connection.h"
40
41 #include "system.h"
42
43 /* Status and error notification routines */
44
45 int send_status(connection_t *c, int statusno, char *statusstring)
46 {
47 cp
48   if(!statusstring)
49     statusstring = status_text[statusno];
50 cp
51   return send_request(c, "%d %d %s", STATUS, statusno, statusstring);
52 }
53
54 int status_h(connection_t *c)
55 {
56   int statusno;
57   char statusstring[MAX_STRING_SIZE];
58 cp
59   if(sscanf(c->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
60     {
61        syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS",
62               c->name, c->hostname);
63        return -1;
64     }
65
66   if(debug_lvl >= DEBUG_STATUS)
67     {
68       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
69              c->name, c->hostname, status_text[statusno], statusstring);
70     }
71
72 cp
73   return 0;
74 }
75
76 int send_error(connection_t *c, int err, char *errstring)
77 {
78 cp
79   if(!errstring)
80     errstring = strerror(err);
81   return send_request(c, "%d %d %s", ERROR, err, errstring);
82 }
83
84 int error_h(connection_t *c)
85 {
86   int err;
87   char errorstring[MAX_STRING_SIZE];
88 cp
89   if(sscanf(c->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
90     {
91        syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR",
92               c->name, c->hostname);
93        return -1;
94     }
95
96   if(debug_lvl >= DEBUG_ERROR)
97     {
98       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
99              c->name, c->hostname, strerror(err), errorstring);
100     }
101
102   terminate_connection(c, c->status.active);
103 cp
104   return 0;
105 }
106
107 int send_termreq(connection_t *c)
108 {
109 cp
110   return send_request(c, "%d", TERMREQ);
111 }
112
113 int termreq_h(connection_t *c)
114 {
115 cp
116   terminate_connection(c, c->status.active);
117 cp
118   return 0;
119 }
120
121 int send_ping(connection_t *c)
122 {
123 cp
124   c->status.pinged = 1;
125   c->last_ping_time = now;
126 cp
127   return send_request(c, "%d", PING);
128 }
129
130 int ping_h(connection_t *c)
131 {
132 cp
133   return send_pong(c);
134 }
135
136 int send_pong(connection_t *c)
137 {
138 cp
139   return send_request(c, "%d", PONG);
140 }
141
142 int pong_h(connection_t *c)
143 {
144 cp
145   c->status.pinged = 0;
146
147   /* Succesful connection, reset timeout if this is an outgoing connection. */
148   
149   if(c->outgoing)
150     c->outgoing->timeout = 0;
151 cp
152   return 0;
153 }
154
155 /* Sending and receiving packets via TCP */
156
157 int send_tcppacket(connection_t *c, vpn_packet_t *packet)
158 {
159   int x;
160 cp  
161   /* Evil hack. */
162
163   x = send_request(c, "%d %hd", PACKET, packet->len);
164
165   if(x)
166     return x;
167 cp
168   return send_meta(c, packet->data, packet->len);
169 }
170
171 int tcppacket_h(connection_t *c)
172 {
173   short int len;
174 cp  
175   if(sscanf(c->buffer, "%*d %hd", &len) != 1)
176     {
177       syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name, c->hostname);
178       return -1;
179     }
180
181   /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
182
183   c->tcplen = len;
184 cp
185   return 0;
186 }
187
188 /* Status strings */
189
190 char (*status_text[]) = {
191   "Warning",
192 };
193
194 /* Error strings */
195
196 char (*error_text[]) = {
197   "Error",
198 };