1 /*
2 * atheme-services: A collection of minimalist IRC services
3 * ubase64.c: ircu base64 routines.
4 *
5 * Copyright (c) 2005-2007 Atheme Project (http://www.atheme.org)
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
12 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
15 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
19 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
20 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 * POSSIBILITY OF SUCH DAMAGE.
22 */
23
24 #include "atheme.h"
25
26 /*
27 * base64touint() written 01/20/06 by jilles, for getting IP addresses.
28 */
29
30 static const char ub64_alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]";
31 #define __ '\377'
32 static const char ub64_lookuptab[256] = {
33 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 0-15 */
34 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 16-31 */
35 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 32-47 */
36 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, __, __, __, __, __, __, /* 48-63 */
37 __, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 64-79 */
38 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 62, __, 63, __, __, /* 80-95 */
39 __, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96-111 */
40 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, __, __, __, __, __, /* 112-127 */
41 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
42 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
43 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
44 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
45 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
46 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
47 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
48 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ };
49 #undef __
50
uinttobase64(char * buf,uint64_t v,int64_t count)51 const char *uinttobase64(char *buf, uint64_t v, int64_t count)
52 {
53 buf[count] = '\0';
54
55 while (count > 0)
56 {
57 buf[--count] = ub64_alphabet[v & 63];
58 v >>= 6;
59 }
60
61 return buf;
62 }
63
base64touint(const char * buf)64 unsigned int base64touint(const char *buf)
65 {
66 int bits;
67 unsigned int v = 0;
68 int count = 6;
69
70 while (--count >= 0 && (bits = ub64_lookuptab[255 & *buf++]) != '\377')
71 v = v << 6 | bits;
72 return v;
73 }
74
decode_p10_ip(const char * b64,char ipstring[HOSTIPLEN])75 void decode_p10_ip(const char *b64, char ipstring[HOSTIPLEN])
76 {
77 struct in_addr ip;
78 char buf[4];
79 int i, j;
80 size_t len;
81
82 ipstring[0] = '\0';
83 len = strlen(b64);
84 if (len == 6)
85 {
86 ip.s_addr = ntohl(base64touint(b64));
87 if (!inet_ntop(AF_INET, &ip, ipstring, HOSTIPLEN))
88 ipstring[0] = '\0';
89 }
90 else if (len == 24 || (len < 24 && strchr(b64, '_')))
91 {
92 /* why is this encoded in such a complicated manner? */
93 i = 0;
94 j = 0;
95 while (b64[i] != '\0')
96 {
97 if (b64[i] == '_')
98 {
99 i++;
100 if (j >= HOSTIPLEN - 2)
101 break;
102 if (j == 0)
103 ipstring[j++] = '0';
104 if (b64[i] == '\0')
105 ipstring[j++] = ':';
106 ipstring[j++] = ':';
107 }
108 else
109 {
110 if (j >= HOSTIPLEN - 5)
111 break;
112 if (j != 0)
113 ipstring[j++] = ':';
114 mowgli_strlcpy(buf, b64 + i, 4);
115 i += strlen(buf);
116 j += sprintf(ipstring + j, "%x", (uint16_t)base64touint(buf));
117 }
118 }
119 ipstring[j] = '\0';
120 }
121 }
122
123 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
124 * vim:ts=8
125 * vim:sw=8
126 * vim:noexpandtab
127 */
128