forked from atheme/atheme
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathubase64.c
122 lines (111 loc) · 3.24 KB
/
ubase64.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* SPDX-License-Identifier: ISC
* SPDX-URL: https://spdx.org/licenses/ISC.html
*
* Copyright (C) 2005-2012 Atheme Project (http://atheme.org/)
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* atheme-services: A collection of minimalist IRC services
* ubase64.c: ircu base64 routines.
*/
#include <atheme.h>
#include "internal.h"
/*
* base64touint() written 01/20/06 by jilles, for getting IP addresses.
*/
static const char ub64_alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]";
#define __ '\377'
static const char ub64_lookuptab[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 0-15 */
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 16-31 */
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 32-47 */
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, __, __, __, __, __, __, /* 48-63 */
__, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 64-79 */
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 62, __, 63, __, __, /* 80-95 */
__, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96-111 */
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, __, __, __, __, __, /* 112-127 */
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ };
#undef __
const char *
uinttobase64(char *buf, uint64_t v, int64_t count)
{
buf[count] = '\0';
while (count > 0)
{
buf[--count] = ub64_alphabet[v & 63];
v >>= 6;
}
return buf;
}
unsigned int
base64touint(const char *buf)
{
int bits;
unsigned int v = 0;
int count = 6;
while (--count >= 0 && (bits = ub64_lookuptab[255 & *buf++]) != '\377')
v = v << 6 | bits;
return v;
}
void
decode_p10_ip(const char *b64, char ipstring[HOSTIPLEN + 1])
{
struct in_addr ip;
char buf[4];
int i, j;
size_t len;
ipstring[0] = '\0';
len = strlen(b64);
if (len == 6)
{
ip.s_addr = ntohl(base64touint(b64));
if (!inet_ntop(AF_INET, &ip, ipstring, HOSTIPLEN + 1))
ipstring[0] = '\0';
}
else if (len == 24 || (len < 24 && strchr(b64, '_')))
{
/* why is this encoded in such a complicated manner? */
i = 0;
j = 0;
while (b64[i] != '\0')
{
if (b64[i] == '_')
{
i++;
if (j > HOSTIPLEN - 2)
break;
if (j == 0)
ipstring[j++] = '0';
if (b64[i] == '\0')
ipstring[j++] = ':';
ipstring[j++] = ':';
}
else
{
if (j > HOSTIPLEN - 5)
break;
if (j != 0)
ipstring[j++] = ':';
mowgli_strlcpy(buf, b64 + i, 4);
i += strlen(buf);
j += sprintf(ipstring + j, "%x", (uint16_t)base64touint(buf));
}
}
ipstring[j] = '\0';
}
}
/* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
* vim:ts=8
* vim:sw=8
* vim:noexpandtab
*/