Switch to K&R style indentation.
[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.6 2002/09/09 21:25:02 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
49         if(!statusstring)
50                 statusstring = status_text[statusno];
51
52         return send_request(c, "%d %d %s", STATUS, statusno, statusstring);
53 }
54
55 int status_h(connection_t * c)
56 {
57         int statusno;
58         char statusstring[MAX_STRING_SIZE];
59
60         cp();
61
62         if(sscanf(c->buffer, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) {
63                 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS",
64                            c->name, c->hostname);
65                 return -1;
66         }
67
68         if(debug_lvl >= DEBUG_STATUS) {
69                 syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
70                            c->name, c->hostname, status_text[statusno], statusstring);
71         }
72
73         return 0;
74 }
75
76 int send_error(connection_t * c, int err, char *errstring)
77 {
78         cp();
79
80         if(!errstring)
81                 errstring = strerror(err);
82
83         return send_request(c, "%d %d %s", ERROR, err, errstring);
84 }
85
86 int error_h(connection_t * c)
87 {
88         int err;
89         char errorstring[MAX_STRING_SIZE];
90
91         cp();
92
93         if(sscanf(c->buffer, "%*d %d " MAX_STRING, &err, errorstring) != 2) {
94                 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR",
95                            c->name, c->hostname);
96                 return -1;
97         }
98
99         if(debug_lvl >= DEBUG_ERROR) {
100                 syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
101                            c->name, c->hostname, strerror(err), errorstring);
102         }
103
104         terminate_connection(c, c->status.active);
105
106         return 0;
107 }
108
109 int send_termreq(connection_t * c)
110 {
111         cp();
112
113         return send_request(c, "%d", TERMREQ);
114 }
115
116 int termreq_h(connection_t * c)
117 {
118         cp();
119
120         terminate_connection(c, c->status.active);
121
122         return 0;
123 }
124
125 int send_ping(connection_t * c)
126 {
127         cp();
128
129         c->status.pinged = 1;
130         c->last_ping_time = now;
131
132         return send_request(c, "%d", PING);
133 }
134
135 int ping_h(connection_t * c)
136 {
137         cp();
138
139         return send_pong(c);
140 }
141
142 int send_pong(connection_t * c)
143 {
144         cp();
145
146         return send_request(c, "%d", PONG);
147 }
148
149 int pong_h(connection_t * c)
150 {
151         cp();
152
153         c->status.pinged = 0;
154
155         /* Succesful connection, reset timeout if this is an outgoing connection. */
156
157         if(c->outgoing)
158                 c->outgoing->timeout = 0;
159
160         return 0;
161 }
162
163 /* Sending and receiving packets via TCP */
164
165 int send_tcppacket(connection_t * c, vpn_packet_t * packet)
166 {
167         int x;
168
169         cp();
170
171         /* Evil hack. */
172
173         x = send_request(c, "%d %hd", PACKET, packet->len);
174
175         if(x)
176                 return x;
177
178         return send_meta(c, packet->data, packet->len);
179 }
180
181 int tcppacket_h(connection_t * c)
182 {
183         short int len;
184
185         cp();
186
187         if(sscanf(c->buffer, "%*d %hd", &len) != 1) {
188                 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name,
189                            c->hostname);
190                 return -1;
191         }
192
193         /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
194
195         c->tcplen = len;
196
197         return 0;
198 }
199
200 /* Status strings */
201
202 char (*status_text[]) = {
203         "Warning",
204 };
205
206 /* Error strings */
207
208 char (*error_text[]) = {
209         "Error",
210 };