1 /*
2 Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved
3
4 Permission to use, copy, modify, and distribute this software and its
5 documentation for any purpose and without fee is hereby granted, provided
6 that the above copyright notice appear in all copies and that both that
7 copyright notice and this permission notice appear in supporting
8 documentation, and that the name of the author not be used in advertising or
9 publicity pertaining to distribution of the software without specific,
10 written prior permission.
11
12 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
14 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
15 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
16 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
22 *
23 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
24 *
25 * This file contains Original Code and/or Modifications of Original Code
26 * as defined in and that are subject to the Apple Public Source License
27 * Version 2.0 (the 'License'). You may not use this file except in
28 * compliance with the License. The rights granted to you under the License
29 * may not be used to create, or enable the creation or redistribution of,
30 * unlawful or unlicensed copies of an Apple operating system, or to
31 * circumvent, violate, or enable the circumvention or violation of, any
32 * terms of an Apple operating system software license agreement.
33 *
34 * Please obtain a copy of the License at
35 * http://www.opensource.apple.com/apsl/ and read it before using this file.
36 *
37 * The Original Code and all software distributed under the License are
38 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
39 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
40 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
41 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
42 * Please see the License for the specific language governing rights and
43 * limitations under the License.
44 *
45 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
46 */
47
48 /*
49 * Copyright 1994, 1995 Massachusetts Institute of Technology
50 *
51 * Permission to use, copy, modify, and distribute this software and
52 * its documentation for any purpose and without fee is hereby
53 * granted, provided that both the above copyright notice and this
54 * permission notice appear in all copies, that both the above
55 * copyright notice and this permission notice appear in all
56 * supporting documentation, and that the name of M.I.T. not be used
57 * in advertising or publicity pertaining to distribution of the
58 * software without specific, written prior permission. M.I.T. makes
59 * no representations about the suitability of this software for any
60 * purpose. It is provided "as is" without express or implied
61 * warranty.
62 *
63 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
64 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
65 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
66 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
67 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
68 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
69 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
70 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
71 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
72 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
73 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 */
76
77 #include <sys/param.h>
78 #include <netinet/in.h>
79 #include <string.h>
80 #include <stdio.h>
81 #include <stdbool.h>
82 #include <assert.h>
83 #include <sys/types.h>
84 #include <sys/socket.h>
85 #include <arpa/inet.h>
86
87 #include "util.h"
88
89 const char OCTETS[][4] = {
90 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15",
91 "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31",
92 "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47",
93 "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63",
94 "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
95 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95",
96 "96", "97", "98", "99",
97 "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
98 "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122",
99 "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135",
100 "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148",
101 "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161",
102 "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174",
103 "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187",
104 "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200",
105 "201", "202", "203", "204", "205", "206", "207", "208", "209", "210", "211", "212", "213",
106 "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225", "226",
107 "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
108 "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252",
109 "253", "254", "255"
110 };
111
fmt_ipv4(BGPDUMP_IP_ADDRESS addr,char * buffer)112 char *fmt_ipv4(BGPDUMP_IP_ADDRESS addr, char *buffer)
113 {
114 assert(buffer);
115 uint8_t *ap = (uint8_t *)&addr.v4_addr.s_addr;
116
117 int pos = 0;
118 int i;
119 for(i = 0; i < 4; ++i) {
120 const char *octet = OCTETS[ap[i]];
121 buffer[pos++] = octet[0];
122 octet[1] ? buffer[pos++] = octet[1] : (void)0;
123 octet[2] ? buffer[pos++] = octet[2] : (void)0;
124 buffer[pos++] = '.';
125 }
126
127 buffer[pos - 1] = '\0';
128
129 return buffer;
130 }
131
fmt_ipv6(BGPDUMP_IP_ADDRESS addr,char * buffer)132 char *fmt_ipv6(BGPDUMP_IP_ADDRESS addr, char *buffer)
133 {
134 static const char hexchars[] = "0123456789abcdef";
135
136 assert(buffer);
137
138 /* check for mapped or compat addresses */
139 bool m = IN6_IS_ADDR_V4MAPPED(&addr.v6_addr);
140 bool c = IN6_IS_ADDR_V4COMPAT(&addr.v6_addr);
141 if (m || c) {
142 char buffer2[100];
143 BGPDUMP_IP_ADDRESS mapped = { .v4_addr.s_addr = ((uint32_t *)addr.v6_addr.s6_addr)[3] };
144
145 sprintf(buffer, "::%s%s", m ? "ffff:" : "", fmt_ipv4(mapped, buffer2));
146 return buffer;
147 }
148
149 char hexa[8][5];
150 int zr[8];
151 size_t len;
152 uint8_t x8, hx8;
153 uint16_t x16;
154
155 int i, k = 0;
156 for (i = 0; i < 16; i += 2) {
157 int j = 0;
158 bool skip = 1;
159
160 memset(hexa[k], 0, 5);
161
162 x8 = addr.v6_addr.s6_addr[i];
163
164 hx8 = x8 >> 4;
165 if (hx8 != 0)
166 {
167 skip = 0;
168 hexa[k][j++] = hexchars[hx8];
169 }
170
171 hx8 = x8 & 0x0f;
172 if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
173 {
174 skip = 0;
175 hexa[k][j++] = hexchars[hx8];
176 }
177
178 x8 = addr.v6_addr.s6_addr[i + 1];
179
180 hx8 = x8 >> 4;
181 if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
182 {
183 hexa[k][j++] = hexchars[hx8];
184 }
185
186 hx8 = x8 & 0x0f;
187 hexa[k][j] = hexchars[hx8];
188
189 k++;
190 }
191
192 /* find runs of zeros for :: convention */
193 int j = 0;
194 for (i = 7; i >= 0; i--)
195 {
196 zr[i] = j;
197 x16 = ((uint16_t *)addr.v6_addr.s6_addr)[i];
198 if (x16 == 0) j++;
199 else j = 0;
200 zr[i] = j;
201 }
202
203 /* find longest run of zeros */
204 k = -1;
205 j = 0;
206 for(i = 0; i < 8; i++)
207 {
208 if (zr[i] > j)
209 {
210 k = i;
211 j = zr[i];
212 }
213 }
214
215 for(i = 0; i < 8; i++)
216 {
217 if (i != k) zr[i] = 0;
218 }
219
220 len = 0;
221 for (i = 0; i < 8; i++)
222 {
223 if (zr[i] != 0)
224 {
225 /* check for leading zero */
226 if (i == 0)
227 buffer[len++] = ':';
228 buffer[len++] = ':';
229 i += (zr[i] - 1);
230 continue;
231 }
232 for (j = 0; hexa[i][j] != '\0'; j++)
233 buffer[len++] = hexa[i][j];
234 if (i != 7)
235 buffer[len++] = ':';
236 }
237
238 buffer[len] = '\0';
239
240 return buffer;
241 }
242
test_roundtrip(char * str)243 static void test_roundtrip(char *str)
244 {
245 BGPDUMP_IP_ADDRESS addr;
246 inet_pton(AF_INET6, str, &addr.v6_addr);
247 char tmp[1000];
248 fmt_ipv6(addr, tmp);
249 printf("%s -> %s [%s]\n", str, tmp, strcmp(str, tmp) ? "ERROR" : "ok");
250 }
251
test_fmt_ip()252 void test_fmt_ip()
253 {
254 test_roundtrip("fe80::");
255 test_roundtrip("2001:db8::1");
256 test_roundtrip("::ffff:192.168.2.1");
257 test_roundtrip("::192.168.1.2");
258 test_roundtrip("2001:7f8:30::2:1:0:8447");
259 }
260