New revision of the Tunnel6 client with improvements and routed prefix support
[tunnel6.git] / client / src / proto.c
blob739bded0a1e7e4c9511a23b5fb49b2afa0c4840d
1 /*
2 * tunnel6
3 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifndef __WIN32__
21 #include <stdlib.h>
22 #include <string.h>
23 # include <netinet/in.h>
24 #else
25 # include <windows.h>
26 #endif
27 #include <stdio.h>
28 #include "ipv6.h"
29 #include "proto.h"
30 #include "tundev.h"
31 #include "tunnel.h"
32 #include "packet.h"
33 #include "defaults.h"
35 extern int cont; /* Continue in tunnel processing ? 1 - yes / 0 - no */
36 ipv6_addr_t tunip; /* IPv6 address obtained from tunnel server */
37 ipv6_addr_t tungw; /* IPv6 gateway obtained from tunnel server */
38 ipv6_prefix_t tunpr; /* IPv6 prefix obtained from tunnel server */
40 /* PROTOCOL Command - LOGIN */
41 int proto_login (char *data, char *name, char *pwd)
43 unsigned name_len = strlen (name);
44 unsigned pwd_len = strlen (pwd);
46 char *req = (char *) malloc (5 + name_len + pwd_len);
48 if (!req)
49 return -1;
51 /* fill the protocol command */
52 req[0] = PROTO_MAGIC; /* magic signature */
53 req[1] = PROTO_CMD_LOGIN; /* login cmd */
54 req[2] = name_len;
55 req[3] = pwd_len;
57 memcpy (req+4, name, name_len);
58 memcpy (req+4+name_len, pwd, pwd_len);
60 /* send LOGIN request to tunnel server */
61 if (tunnel_send (req, 4 + name_len + pwd_len) == -1) {
62 printf ("ERROR -> tunnel_send ()\n");
63 free (req);
64 return -1;
67 free (req);
69 /* Receive protocol data */
70 if (tunnel_recv () == 0) {
71 printf ("ERROR -> tunnel_recv ()\n");
72 return -1;
75 /* Was a login succesfull ? */
76 switch (data[0]) {
77 case PROTO_CMD_LOGIN_OK:
78 break;
79 case PROTO_CMD_LOGIN_FAIL:
80 printf ("ERROR -> Login failed - incorrect name or password !\n");
81 return -1;
82 case PROTO_CMD_LOGIN_MULTI:
83 printf ("ERROR -> Login failed - you are logged multiply times !\n");
84 return -1;
87 /* save obtained IPv6 address */
88 memcpy (tunip, data+1, sizeof (ipv6_addr_t));
89 /* save obtained IPv6 gateway */
90 memcpy (tungw, data+1+sizeof (ipv6_addr_t), sizeof (ipv6_addr_t));
91 /* save obtained IPv6 prefix for routing */
92 memcpy (tunpr, data+1+2*sizeof (ipv6_prefix_t), sizeof (ipv6_prefix_t));
94 printf ("> Login succesfull !\n> Obtained IPv6: %s\n", ipv6_print (tunip));
96 /* Display routed prefix when available */
97 if (tunpr[15]) {
98 ipv6_addr_t tmp;
99 memcpy (tmp, (void *) tunpr, sizeof (ipv6_addr_t)-1);
100 memset ((char *) tmp + 15, 0, 1);
102 printf ("> Routed IPv6 prefix: %s/%u\n", ipv6_print (tmp), (unsigned char) tunpr[15]);
105 return 0;
108 /* PROTOCOL Command - DISCONNECT by server*/
109 int proto_cmd_disconnect ()
111 printf ("> disconnected by server\n");
113 cont = 0;
115 return 0;
118 /* PROTOCOL Command - DISCONNECT */
119 int proto_cmd_disconnect2 ()
121 printf ("> disconnected\n");
123 /* build command */
124 char req[2];
125 req[0] = PROTO_MAGIC;
126 req[1] = PROTO_CMD_DISCONNECT;
128 return tunnel_send (req, 2);
131 /* TUNNEL PROTOCOL HANDLER */
132 int proto_cmd (char *data, unsigned len)
134 char *proto = (char *) data;
136 switch (*proto) {
137 case PROTO_CMD_DISCONNECT:
138 return proto_cmd_disconnect ();
141 return 0;
144 /* TUNNEL COMMUNICATION HANDLER */
145 int proto_comm (char *data, unsigned len)
147 #ifndef __WIN32__
148 struct proto_ipv6_t *ip = (struct proto_ipv6_t *) data;
150 /* we need check incoming destination address
151 because it could be one of our routed client packet */
152 if (ipv6_cmp_prefix (tunpr, (unsigned char *) ip->dest))
153 return ipv6_send (data, len);
154 #endif
155 /* send received data to virtual TUN device */
156 return tundev_send (data, len);
159 /* PROTOCOL PARSER - parse incoming server data */
160 int proto_parse (char *data, unsigned len)
162 struct proto_ipv6_t *ip = (struct proto_ipv6_t *) data;
164 /* check type of packet */
165 switch (ip->ver) {
166 case PROTO_MAGIC:
167 return proto_cmd (data+1, len-1);
168 case PROTO_IPV6:
169 return proto_comm (data, len);
172 return 0;
175 int proto_init ()
178 return 0;