]> git.ipfire.org Git - people/stevee/aiccu.git/blame - common/tic.c
Add setup script functionality to Linux client
[people/stevee/aiccu.git] / common / tic.c
CommitLineData
d98f6a46
SS
1/**********************************************************
2 SixXS - Automatic IPv6 Connectivity Configuration Utility
3***********************************************************
4 Copyright 2003-2005 SixXS - http://www.sixxs.net
5***********************************************************
6 common/tic.c - Tunnel Information & Control Protocol
7***********************************************************
8 $Author: jeroen $
9 $Id: tic.c,v 1.17 2007-01-11 13:41:31 jeroen Exp $
10 $Date: 2007-01-11 13:41:31 $
11**********************************************************/
12
13#include "common.h"
14#include "aiccu.h"
15#include "tic.h"
16
17/* Specific includes only used here */
18#ifndef _WIN32
19#include <sys/utsname.h>
20#endif
21
22/* getline vars */
23char tic_buf[2048];
24unsigned int tic_filled;
25
26/*
27 * epochtime = epochtime as received in the packet
28 * Don't forget to convert byteorder using ntohl()
29 */
30int tic_checktime(time_t epochtime)
31{
32 /* Number of seconds we allow the clock to be off */
33 #define CLOCK_OFF 120
34 int i;
35
36 /* Get the current time */
37 time_t curr_time = time(NULL);
38
39 /* Is one of the times in the loop range? */
40 if ( (curr_time >= -CLOCK_OFF) ||
41 (epochtime >= -CLOCK_OFF))
42 {
43 /* Shift the times out of the loop range */
44 i =(int)(((int)curr_time) + (CLOCK_OFF*2)) -
45 (((int)epochtime) + (CLOCK_OFF*2));
46 }
47 else i = ((int)curr_time) - ((int)epochtime);
48
49 /* The clock may be faster, thus flip the sign */
50 if (i < 0) i = -i;
51
52 /* Compare the clock offset */
53 if (i > CLOCK_OFF)
54 {
55 /* Time is off */
56 return i;
57 }
58
59 /* Time is in the allowed range */
60 return 0;
61}
62
63bool tic_Login(struct TIC_conf *tic, const char *username, const char *password, const char *server)
64{
65 char buf[1024], sSignature[33], sChallenge[1024];
66 int i;
67#ifndef _WIN32
68 struct utsname uts_name;
69#else
70 OSVERSIONINFO osv;
71 OSVERSIONINFOEX osvEx;
72 char *platform = NULL;
73 char version[100];
74#endif
75
76 D(dolog(LOG_DEBUG, "Trying to connect to TIC server %s\n", server));
77
78 /* Connect to the TIC server */
79 tic->sock = connect_client(server, TIC_PORT, AF_INET, SOCK_STREAM);
80 if (!tic->sock)
81 {
82 dolog(LOG_ERR, "Couldn't connect to the TIC server %s\n", server);
83 return false;
84 }
85
86 /* Fetch the welcome */
87 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
88 {
89 return false;
90 }
91 if (buf[0] != '2')
92 {
93 dolog(LOG_ERR, "TIC Server is currently not available\n");
94 return false;
95 }
96
97 /* Send our client identification */
98#ifndef _WIN32
99 uname(&uts_name);
100 sock_printf(tic->sock, "client TIC/%s %s/%s %s/%s\n",
101 TIC_VERSION,
102 TIC_CLIENT_NAME, TIC_CLIENT_VERSION,
103 uts_name.sysname, uts_name.release);
104#else
105 osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
106 osvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
107
108 if (!GetVersionEx(&osv))
109 {
110 platform = "Windows";
111 snprintf(version, sizeof(version), "%s", "Unknown");
112 }
113 else
114 {
115
116 platform = (osv.dwPlatformId == VER_PLATFORM_WIN32s) ? "Win32s" :
117 ((osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ? "Win9x" :
118 ((osv.dwPlatformId == VER_PLATFORM_WIN32_NT) ? "WinNT" :
119 "Windows"));
120
121 if ( osv.dwMajorVersion < 5 ||
122 !GetVersionEx((OSVERSIONINFO *)&osvEx) ||
123 osvEx.wServicePackMajor <= 0)
124 {
125 snprintf(version, sizeof(version), "%d.%d.%d",
126 osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber);
127 }
128 else if (osvEx.wServicePackMinor <= 0)
129 {
130 snprintf(version, sizeof(version), "%d.%d.%d-SP%d",
131 osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber,
132 osvEx.wServicePackMajor);
133 }
134 else
135 {
136 snprintf(version, sizeof(version), "%d.%d.%d-SP%d.%d",
137 osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber,
138 osvEx.wServicePackMajor, osvEx.wServicePackMinor);
139 }
140 }
141 sock_printf(tic->sock, "client TIC/%s %s/%s %s/%s\n",
142 TIC_VERSION,
143 TIC_CLIENT_NAME, TIC_CLIENT_VERSION,
144 platform, version);
145#endif
146
147 /* Fetch the answer */
148 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
149 {
150 return false;
151 }
152 if (buf[0] != '2')
153 {
154 dolog(LOG_ERR, "Couldn't pass client information: %s.\n", &buf[4]);
155 return false;
156 }
157
158 /* Request current time */
159 sock_printf(tic->sock, "get unixtime\n");
160
161 /* Fetch the answer */
162 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
163 {
164 return false;
165 }
166 if (buf[0] != '2')
167 {
168 dolog(LOG_ERR, "Time not available? %s\n", &buf[4]);
169 return false;
170 }
171
172 /* Check if the time is correct */
173 i = tic_checktime(atoi(&buf[4]));
174 if (i != 0)
175 {
176 char quitmsg[100];
177 dolog(LOG_ERR, "The clock is off by %d seconds, use NTP to sync it!\n", i);
178 snprintf(quitmsg, sizeof(quitmsg), "Aborting: Clock is off by %d seconds\n", i);
179 tic_Logout(tic, quitmsg);
180 return false;
181 }
182
183#ifdef AICCU_GNUTLS
184 /* Upgrade to TLS */
185 sock_printf(tic->sock, "starttls\n");
186
187 /* Fetch the welcome */
188 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
189 {
190 return false;
191 }
192 if (buf[0] == '2')
193 {
194 /* Go to TLS mode */
195 if (!sock_gotls(tic->sock)) return false;
196 }
197 else
198 {
199 if (g_aiccu->requiretls)
200 {
201 dolog(LOG_ERR, "TIC Server does not support TLS and TLS is required\n");
202 return false;
203 }
204 if (g_aiccu->verbose) dolog(LOG_WARNING, "TIC Server does not support TLS but TLS is not required, continuing\n");
205 }
206
207#endif
208
209 /* Send our username */
210 sock_printf(tic->sock, "username %s\n", username);
211
212 /* Fetch the answer */
213 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
214 {
215 return false;
216 }
217 if (buf[0] != '2')
218 {
219 dolog(LOG_ERR, "Username not accepted: %s.\n", &buf[4]);
220 return false;
221 }
222
223 /* Pick a challenge */
224 sock_printf(tic->sock, "challenge md5\n");
225
226 /* Fetch the answer */
227 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
228 {
229 return false;
230 }
231 if (buf[0] != '2')
232 {
233 dolog(LOG_ERR, "Challenge not correct: %s.\n", &buf[4]);
234 return false;
235 }
236
237 /* Send the response */
238 /* sSignature = md5(challenge.md5(password)); */
239 MD5String(password, sSignature, sizeof(sSignature));
240 snprintf(sChallenge, sizeof(sChallenge), "%s%s", &buf[4], sSignature);
241 MD5String(sChallenge, sSignature, sizeof(sSignature));
242
243 sock_printf(tic->sock, "authenticate md5 %s\n", sSignature);
244
245 /* Fetch the answer */
246 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
247 {
248 tic_Logout(tic, NULL);
249 return false;
250 }
251 if (buf[0] != '2')
252 {
253 tic_Logout(tic, NULL);
254 dolog(LOG_ERR, "Response not accepted: %s.\n", &buf[4]);
255 return false;
256 }
257
258 /* Connect OK */
259 return true;
260}
261
262void tic_Logout(struct TIC_conf *tic, const char *quitmsg)
263{
264 /* A list of appropriate quit messages */
265 const char *byers[] = {
266 /* Swiss-German form of "Ciao" */
267 "Tschau!",
268
269 /* Dutch for "they who are going, greet you" */
270 "Zij die gaan, groeten u",
271 "See you later alligator",
272 "A bitter thought, but I have to go",
273
274 /* Dutch for "see you later" */
275 "Ajuuu paraplu",
276 "Thank you for the information",
277 "It was lovely talking to you again",
278 "Tschussss...",
279 "Aufwiedersehen",
280 "I'll be back. Ha, you didn't know I was going to say that!",
281 "We will be the only two people left in the world, Yes--Adam and Evil!",
282
283 /* Blutengel */
284 "Stranded",
285 "Die With You",
286 "The End Of Love",
287
288 /* Chamber */
289 "In My Garden",
290 "Set Me Free",
291
292 /* Faithless */
293 "Don't Leave",
294 "Insomnia",
295 "Why Go",
296
297 /* Garbage */
298 "The Trick Is To Keep Breathing",
299
300 /* The Gathering */
301 "We just stopped breating",
302 "Even the spirits are afraid",
303
304 /* Goldfrapp */
305 "Deer Stop",
306
307 /* Hooverphonic */
308 "The Last Thing I Need Is You",
309 "Every Time We Live Together",
310 "My Autumn's Done Come",
311
312 /* Infected Mushroom */
313 "Never Ever Land",
314 "None of this is real",
315 "Nothing Comes Easy",
316 "Illuminaughty",
317
318 /* Nine Inch Nails */
319 "Something I can never have",
320 "And All That Could Have Been...",
321 "That's what I get",
322
323 /* Opeth */
324 "Under the weeping moon",
325 "For Absent Friends",
326
327 /* Portishead */
328 "It Could Be Sweet",
329 "Half Day Closing",
330
331 /* Suicide Commando */
332 "Better Off Dead",
333
334 /* VNV Nation */
335 "Solitary",
336 "Forsaken",
337 "Holding On",
338
339 /* Within Temptation */
340 "This is not our farewell",
341 "Running Down That Hill",
342
343 /* Wumpscut */
344 "Schaltet den schmerz ab",
345 "Down where we belong",
346 };
347
348 /* Already disconnected? */
349 if (!tic->sock) return;
350
351 if (!quitmsg)
352 {
353 /* Stupid random quit messages, got to put some form of easteregg in it :) */
354 srand((unsigned)time(NULL));
355
356 quitmsg = (char *)byers[rand()%(sizeof(byers)/sizeof(char *))];
357 }
358
359 /* Send our bye bye */
360 sock_printf(tic->sock, "QUIT %s\n", quitmsg);
361
362 /* Disconnect */
363 sock_free(tic->sock);
364 tic->sock = NULL;
365}
366
367struct TIC_sTunnel *tic_ListTunnels(struct TIC_conf *tic)
368{
369 char buf[1024], buf2[1024];
370 struct TIC_sTunnel *start = NULL, *last = NULL, *tun = NULL;
371 int i;
372
373/* Request a list of Tunnels */
374 sock_printf(tic->sock, "tunnel list\n");
375
376 /* Fetch the answer */
377 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
378 {
379 return NULL;
380 }
381
382 /* 201 (start of list) ? */
383 if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1')
384 {
385 dolog(LOG_ERR, "Couldn't list tunnels: %s.\n", &buf[4]);
386 return NULL;
387 }
388
389 /* Process all the lines */
390 while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1)
391 {
392 /* 202 (end of list) ? */
393 if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break;
394
395 i = countfields(buf);
396 if (i != 4)
397 {
398 dolog(LOG_ERR, "Wrong field format when listing tunnels\n");
399 break;
400 }
401
402 /* Allocate a new struct */
403 tun = (struct TIC_sTunnel *)malloc(sizeof(*tun));
404 if (!tun)
405 {
406 dolog(LOG_ERR, "Memory problem while listing tunnels\n");
407 break;
408 }
409 memset(tun, 0, sizeof(*tun));
410
411 /* Copy the fields into the struct */
412 if (!copyfield(buf, 1, buf2, sizeof(buf2))) break;
413 tun->sId = strdup(buf2);
414 if (!copyfield(buf, 2, buf2, sizeof(buf2))) break;
415 tun->sIPv6 = strdup(buf2);
416 if (!copyfield(buf, 3, buf2, sizeof(buf2))) break;
417 tun->sIPv4 = strdup(buf2);
418 if (!copyfield(buf, 4, buf2, sizeof(buf2))) break;
419 tun->sPOPId = strdup(buf2);
420
421 /* Add it into the list */
422 if (last)
423 {
424 last->next = tun;
425 last = tun;
426 }
427 else
428 {
429 start = last = tun;
430 }
431 }
432
433 /* All went okay? */
434 if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2')
435 {
436 return start;
437 }
438
439 /* Free the structure, it was broken anyway */
440 tic_Free_sTunnel(start);
441
442 dolog(LOG_ERR, "Tunnel list went wrong: %s\n", &buf[4]);
443 return NULL;
444}
445
446struct TIC_sRoute *tic_ListRoutes(struct TIC_conf *tic)
447{
448 dolog(LOG_ERR, "Not implemented - tic_ListRoutes(%x)\n", tic);
449 return NULL;
450}
451
452struct TIC_sPOP *tic_ListPOPs(struct TIC_conf *tic)
453{
454 dolog(LOG_ERR, "Not implemented - tic_ListPOPs(%x)\n", tic);
455 return NULL;
456}
457
458struct pl_rule tunnel_rules[] =
459{
460 {"TunnelId", PLRT_STRING, offsetof(struct TIC_Tunnel, sId)},
461 {"Type", PLRT_STRING, offsetof(struct TIC_Tunnel, sType)},
462 {"IPv6 Endpoint", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv6_Local)},
463 {"IPv6 POP", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv6_POP)},
464 {"IPv6 PrefixLength", PLRT_INTEGER, offsetof(struct TIC_Tunnel, nIPv6_PrefixLength)},
465 {"POP Id", PLRT_STRING, offsetof(struct TIC_Tunnel, sPOP_Id)},
466 {"IPv4 Endpoint", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv4_Local)},
467 {"IPv4 POP", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv4_POP)},
468 {"UserState", PLRT_STRING, offsetof(struct TIC_Tunnel, sUserState)},
469 {"AdminState", PLRT_STRING, offsetof(struct TIC_Tunnel, sAdminState)},
470 {"Password", PLRT_STRING, offsetof(struct TIC_Tunnel, sPassword)},
471 {"Heartbeat_Interval", PLRT_INTEGER, offsetof(struct TIC_Tunnel, nHeartbeat_Interval)},
472 {"Tunnel MTU", PLRT_INTEGER, offsetof(struct TIC_Tunnel, nMTU)},
473 {NULL, PLRT_END, 0},
474};
475
476struct TIC_Tunnel *tic_GetTunnel(struct TIC_conf *tic, const char *sId)
477{
478 char buf[1024];
479 struct TIC_Tunnel *tun;
480
481 /* Get a Tunnel */
482 sock_printf(tic->sock, "tunnel show %s\n", sId);
483
484 /* Fetch the answer */
485 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
486 {
487 return NULL;
488 }
489
490 /* 201 (start of information) ? */
491 if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1')
492 {
493 dolog(LOG_ERR, "Couldn't show tunnel %s: %s.\n", sId, buf);
494 return NULL;
495 }
496
497 /* Allocate a new struct */
498 tun = (struct TIC_Tunnel *)malloc(sizeof(*tun));
499 if (!tun)
500 {
501 dolog(LOG_ERR, "Memory problem while getting tunnel %s\n", sId);
502 return NULL;
503 }
504 memset(tun, 0, sizeof(*tun));
505
506 /* Gather the information */
507 while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1)
508 {
509 /* 202 (end of list) ? */
510 if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break;
511
512 parseline(buf, ": ", tunnel_rules, tun);
513 }
514 /* All went okay? */
515 if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2')
516 {
517 struct in6_addr ipv6_ll, ipv6_local;
518 char ll[100];
519
ddeba48a
RH
520 /* Log that the fetch was successful */
521 dolog(LOG_INFO, "Successfully retrieved tunnel information for %s\n", sId);
d98f6a46
SS
522
523 /*
524 * Some TUN/TAP devices don't have any
525 * link local addresses and we want multicast and MLD to work
526 * thus we invent one based on the following:
527 *
528 * ipv6_us = 2001:0db8:1234:5678: : : :0001
529 * ipv6_ll = fe80: : : :0db8:1234:5678:0001
530 *
531 * Thus we ignore the first 16bits, take the following 48 bits
532 * and then add the last 16bits.
533 *
534 * As we are not 100% sure that this LL is unique we clear that bit.
535 */
536
537 inet_pton(AF_INET6, tun->sIPv6_Local, &ipv6_local);
538
539 /* Link Local (fe80::/64) */
540 ipv6_ll.s6_addr[ 0] = 0xfe;
541 ipv6_ll.s6_addr[ 1] = 0x80;
542 ipv6_ll.s6_addr[ 2] = 0x00;
543 ipv6_ll.s6_addr[ 3] = 0x00;
544 ipv6_ll.s6_addr[ 4] = 0x00;
545 ipv6_ll.s6_addr[ 5] = 0x00;
546 ipv6_ll.s6_addr[ 6] = 0x00;
547 ipv6_ll.s6_addr[ 7] = 0x00;
548 ipv6_ll.s6_addr[ 8] = ipv6_local.s6_addr[ 2] & 0xfc; /* Clear the LL Unique Bit */
549 ipv6_ll.s6_addr[ 9] = ipv6_local.s6_addr[ 3];
550 ipv6_ll.s6_addr[10] = ipv6_local.s6_addr[ 4];
551 ipv6_ll.s6_addr[11] = ipv6_local.s6_addr[ 5];
552 ipv6_ll.s6_addr[12] = ipv6_local.s6_addr[ 6];
553 ipv6_ll.s6_addr[13] = ipv6_local.s6_addr[ 7];
554 ipv6_ll.s6_addr[14] = ipv6_local.s6_addr[14];
555 ipv6_ll.s6_addr[15] = ipv6_local.s6_addr[15];
556
557 inet_ntop(AF_INET6, &ipv6_ll, ll, sizeof(ll));
558 if (tun->sIPv6_LinkLocal) free(tun->sIPv6_LinkLocal);
559 tun->sIPv6_LinkLocal = strdup(ll);
560
561 if ( strcmp(tun->sType, "ayiya") == 0 ||
562 strcmp(tun->sType, "l2tp") == 0)
563 {
564 tun->uses_tundev = 1;
565#ifdef NO_IFHEAD
566 dolog(LOG_ERR, "This build doesn't support the Tun/TAP device and thus can't instantiate tunnels of type %s, please fix your OS and recompile\n", tun->sType);
567 tic_Free_Tunnel(tun);
568 return NULL;
569#endif
570 }
571 else tun->uses_tundev = 0;
572
573 /* Need to override the local IPv4 address? */
574 if (g_aiccu->local_ipv4_override)
575 {
576 dolog(LOG_INFO, "Overriding Local IPv4 address from %s to %s\n", tun->sIPv4_Local, g_aiccu->local_ipv4_override);
577 free(tun->sIPv4_Local);
578 tun->sIPv4_Local = strdup(g_aiccu->local_ipv4_override);
579 }
580
581 return tun;
582 }
583
584 /* Free the structure, it is broken anyway */
585 tic_Free_Tunnel(tun);
586
587 dolog(LOG_ERR, "Tunnel Get for %s went wrong: %s\n", sId, buf);
588 return NULL;
589}
590
591struct TIC_Route *tic_GetRoute(struct TIC_conf *tic, const char *sId)
592{
593 dolog(LOG_ERR, "Not implemented - tic_GetRoute(%x, \"%s\")\n", tic, sId);
594 return NULL;
595}
596
597struct pl_rule pop_rules[] =
598{
599 {"POPId", PLRT_STRING, offsetof(struct TIC_POP, sId)},
600 {"City", PLRT_STRING, offsetof(struct TIC_POP, sCity)},
601 {"Country", PLRT_STRING, offsetof(struct TIC_POP, sCountry)},
602 {"IPv4", PLRT_STRING, offsetof(struct TIC_POP, sIPv4)},
603 {"IPv6", PLRT_STRING, offsetof(struct TIC_POP, sIPv6)},
604
605 {"ISP Short", PLRT_STRING, offsetof(struct TIC_POP, sISP_Short)},
606 {"ISP Name", PLRT_STRING, offsetof(struct TIC_POP, sISP_Name)},
607 {"ISP Website", PLRT_STRING, offsetof(struct TIC_POP, sISP_Website)},
608 {"ISP ASN", PLRT_STRING, offsetof(struct TIC_POP, sISP_ASN)},
609 {"ISP LIR", PLRT_STRING, offsetof(struct TIC_POP, sISP_LIR)},
610
611 {NULL, PLRT_END, 0},
612};
613
614struct TIC_POP *tic_GetPOP(struct TIC_conf *tic, const char *sId)
615{
616 char buf[1024];
617 struct TIC_POP *pop;
618
619 /* Get a Tunnel */
620 sock_printf(tic->sock, "pop show %s\n", sId);
621
622 /* Fetch the answer */
623 if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
624 {
625 return NULL;
626 }
627
628 /* 201 (start of info) ? */
629 if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1')
630 {
631 dolog(LOG_ERR, "Couldn't show POP %s: %s.\n", sId, buf);
632 return NULL;
633 }
634
635 /* Allocate a new struct */
636 pop = (struct TIC_POP *)malloc(sizeof(*pop));
637 if (!pop)
638 {
639 dolog(LOG_ERR, "Memory problem while getting POP\n");
640 return NULL;
641 }
642 memset(pop, 0, sizeof(*pop));
643
644 /* Gather the information */
645 while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1)
646 {
647 /* 202 (end of list) ? */
648 if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break;
649
650 parseline(buf, ": ", pop_rules, pop);
651 }
652 /* All went okay? */
653 if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2')
654 {
ddeba48a 655 dolog(LOG_INFO, "Successfully retrieved POP information for %s\n", sId);
d98f6a46
SS
656 return pop;
657 }
658
659 /* Free the structure, it is broken anyway */
660 tic_Free_POP(pop);
661
662 dolog(LOG_ERR, "POP Get for %s went wrong: %s\n", sId, buf);
663 return NULL;
664}
665
666void tic_Free_sTunnel(struct TIC_sTunnel *tun)
667{
668 struct TIC_sTunnel *next;
669
670 for (; tun; tun = next)
671 {
672 next = tun->next;
673 if (tun->sId) free(tun->sId);
674 if (tun->sIPv6) free(tun->sIPv6);
675 if (tun->sIPv4) free(tun->sIPv4);
676 if (tun->sPOPId) free(tun->sPOPId);
677 free(tun);
678 }
679}
680
681void tic_Free_sRoute(struct TIC_sRoute *rt)
682{
683 struct TIC_sRoute *next;
684
685 for (; rt; rt = next)
686 {
687 next = rt->next;
688 if (rt->sId) free(rt->sId);
689 if (rt->sTunnelId) free(rt->sTunnelId);
690 if (rt->sIPv6) free(rt->sIPv6);
691 free(rt);
692 }
693}
694
695void tic_Free_sPOP(struct TIC_sPOP *pop)
696{
697 struct TIC_sPOP *next;
698
699 for (; pop; pop = next)
700 {
701 next = pop->next;
702 if (pop->sId) free(pop->sId);
703 free(pop);
704 }
705}
706
707void tic_Free_Tunnel(struct TIC_Tunnel *tun)
708{
709 if (tun->sId) { free(tun->sId); tun->sId = NULL; }
710 if (tun->sType) { free(tun->sType); tun->sType = NULL; }
711 if (tun->sPOP_Id) { free(tun->sPOP_Id); tun->sPOP_Id = NULL; }
712 if (tun->sUserState) { free(tun->sUserState); tun->sUserState = NULL; }
713 if (tun->sAdminState) { free(tun->sAdminState); tun->sAdminState = NULL; }
714 if (tun->sPassword) { free(tun->sPassword); tun->sPassword = NULL; }
715 if (tun->sIPv4_Local) { free(tun->sIPv4_Local); tun->sIPv4_Local = NULL; }
716 if (tun->sIPv4_POP) { free(tun->sIPv4_POP); tun->sIPv4_POP = NULL; }
717 if (tun->sIPv6_Local) { free(tun->sIPv6_Local); tun->sIPv6_Local = NULL; }
718 if (tun->sIPv6_POP) { free(tun->sIPv6_POP); tun->sIPv6_POP = NULL; }
719 free(tun);
720 tun = NULL;
721}
722
723void tic_Free_Route(struct TIC_Route *rt)
724{
725 if (rt->sId) free(rt->sId);
726 if (rt->sTunnelId) free(rt->sTunnelId);
727 free(rt);
728}
729
730void tic_Free_POP(struct TIC_POP *pop)
731{
732 if (pop->sId) free(pop->sId);
733 if (pop->sCity) free(pop->sCity);
734 if (pop->sCountry) free(pop->sCountry);
735 if (pop->sIPv4) free(pop->sIPv4);
736 if (pop->sIPv6) free(pop->sIPv6);
737 if (pop->sISP_Short) free(pop->sISP_Short);
738 if (pop->sISP_Name) free(pop->sISP_Name);
739 if (pop->sISP_Website) free(pop->sISP_Website);
740 if (pop->sISP_ASN) free(pop->sISP_ASN);
741 if (pop->sISP_LIR) free(pop->sISP_LIR);
742
743 free(pop);
744}