00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "config.h"
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014
00015 #include "dnet.h"
00016
00017 static const char *octet2dec[] = {
00018 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
00019 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
00020 "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34",
00021 "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45",
00022 "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56",
00023 "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67",
00024 "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78",
00025 "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
00026 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100",
00027 "101", "102", "103", "104", "105", "106", "107", "108", "109",
00028 "110", "111", "112", "113", "114", "115", "116", "117", "118",
00029 "119", "120", "121", "122", "123", "124", "125", "126", "127",
00030 "128", "129", "130", "131", "132", "133", "134", "135", "136",
00031 "137", "138", "139", "140", "141", "142", "143", "144", "145",
00032 "146", "147", "148", "149", "150", "151", "152", "153", "154",
00033 "155", "156", "157", "158", "159", "160", "161", "162", "163",
00034 "164", "165", "166", "167", "168", "169", "170", "171", "172",
00035 "173", "174", "175", "176", "177", "178", "179", "180", "181",
00036 "182", "183", "184", "185", "186", "187", "188", "189", "190",
00037 "191", "192", "193", "194", "195", "196", "197", "198", "199",
00038 "200", "201", "202", "203", "204", "205", "206", "207", "208",
00039 "209", "210", "211", "212", "213", "214", "215", "216", "217",
00040 "218", "219", "220", "221", "222", "223", "224", "225", "226",
00041 "227", "228", "229", "230", "231", "232", "233", "234", "235",
00042 "236", "237", "238", "239", "240", "241", "242", "243", "244",
00043 "245", "246", "247", "248", "249", "250", "251", "252", "253",
00044 "254", "255"
00045 };
00046
00047 static const char *octet2hex[] = {
00048 "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a",
00049 "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15",
00050 "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20",
00051 "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b",
00052 "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36",
00053 "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41",
00054 "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c",
00055 "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57",
00056 "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62",
00057 "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d",
00058 "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78",
00059 "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83",
00060 "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e",
00061 "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
00062 "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4",
00063 "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
00064 "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba",
00065 "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5",
00066 "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0",
00067 "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db",
00068 "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6",
00069 "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1",
00070 "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc",
00071 "fd", "fe", "ff"
00072 };
00073
00074 char *
00075 eth_ntop(const eth_addr_t *eth, char *dst, size_t len)
00076 {
00077 const char *x;
00078 char *p = dst;
00079 int i;
00080
00081 if (len < 18)
00082 return (NULL);
00083
00084 for (i = 0; i < ETH_ADDR_LEN; i++) {
00085 for (x = octet2hex[eth->data[i]]; (*p = *x) != '\0'; x++, p++)
00086 ;
00087 *p++ = ':';
00088 }
00089 p[-1] = '\0';
00090
00091 return (dst);
00092 }
00093
00094 char *
00095 eth_ntoa(const eth_addr_t *eth)
00096 {
00097 struct addr a;
00098
00099 addr_pack(&a, ADDR_TYPE_ETH, ETH_ADDR_BITS, eth->data, ETH_ADDR_LEN);
00100 return (addr_ntoa(&a));
00101 }
00102
00103 int
00104 eth_pton(const char *p, eth_addr_t *eth)
00105 {
00106 char *ep;
00107 long l;
00108 int i;
00109
00110 for (i = 0; i < ETH_ADDR_LEN; i++) {
00111 l = strtol(p, &ep, 16);
00112 if (ep == p || l < 0 || l > 0xff ||
00113 (i < ETH_ADDR_LEN - 1 && *ep != ':'))
00114 break;
00115 eth->data[i] = (u_char)l;
00116 p = ep + 1;
00117 }
00118 return ((i == ETH_ADDR_LEN && *ep == '\0') ? 0 : -1);
00119 }
00120
00121 char *
00122 ip_ntop(const ip_addr_t *ip, char *dst, size_t len)
00123 {
00124 const char *d;
00125 char *p = dst;
00126 u_char *data = (u_char *)ip;
00127 int i;
00128
00129 if (len < 16)
00130 return (NULL);
00131
00132 for (i = 0; i < IP_ADDR_LEN; i++) {
00133 for (d = octet2dec[data[i]]; (*p = *d) != '\0'; d++, p++)
00134 ;
00135 *p++ = '.';
00136 }
00137 p[-1] = '\0';
00138
00139 return (dst);
00140 }
00141
00142 char *
00143 ip_ntoa(const ip_addr_t *ip)
00144 {
00145 struct addr a;
00146
00147 addr_pack(&a, ADDR_TYPE_IP, IP_ADDR_BITS, ip, IP_ADDR_LEN);
00148 return (addr_ntoa(&a));
00149 }
00150
00151 int
00152 ip_pton(const char *p, ip_addr_t *ip)
00153 {
00154 u_char *data = (u_char *)ip;
00155 char *ep;
00156 long l;
00157 int i;
00158
00159 for (i = 0; i < IP_ADDR_LEN; i++) {
00160 l = strtol(p, &ep, 10);
00161 if (ep == p || l < 0 || l > 0xff ||
00162 (i < IP_ADDR_LEN - 1 && *ep != '.'))
00163 break;
00164 data[i] = (u_char)l;
00165 p = ep + 1;
00166 }
00167 return ((i == IP_ADDR_LEN && *ep == '\0') ? 0 : -1);
00168 }
00169
00170 char *
00171 ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
00172 {
00173 struct { int base, len; } best, cur;
00174 char *p = dst;
00175 int i;
00176
00177 if (len < 46)
00178 return (NULL);
00179
00180 best.base = cur.base = -1;
00181
00182
00183
00184 for (i = 0; i < IP6_ADDR_LEN; i += 2) {
00185 if (*((uint16_t *)&ip6->data[i]) == 0) {
00186 if (cur.base == -1) {
00187 cur.base = i;
00188 cur.len = 0;
00189 } else
00190 cur.len += 2;
00191 } else {
00192 if (cur.base != -1) {
00193 if (best.base == -1 || cur.len > best.len)
00194 best = cur;
00195 cur.base = -1;
00196 }
00197 }
00198 }
00199 if (cur.base != -1 && (best.base == -1 || cur.len > best.len))
00200 best = cur;
00201 if (best.base != -1 && best.len < 2)
00202 best.base = -1;
00203 if (best.base == 0)
00204 *p++ = ':';
00205
00206 for (i = 0; i < IP6_ADDR_LEN; i += 2) {
00207 if (i == best.base) {
00208 *p++ = ':';
00209 i += best.len;
00210 } else if (i == 12 && best.base == 0 &&
00211 (best.len == 10 || (best.len == 8 &&
00212 *((uint16_t *)&ip6->data[10]) == 0xffff))) {
00213 if (ip_ntop((ip_addr_t *)&ip6->data[12], p,
00214 len - (p - dst)) == NULL)
00215 return (NULL);
00216 return (dst);
00217 } else p += sprintf(p, "%x:",
00218 ntohs(*((uint16_t *)&ip6->data[i])));
00219 }
00220 if (best.base + 2 + best.len == IP6_ADDR_LEN) {
00221 *p = '\0';
00222 } else
00223 p[-1] = '\0';
00224
00225 return (dst);
00226 }
00227
00228 char *
00229 ip6_ntoa(const ip6_addr_t *ip6)
00230 {
00231 struct addr a;
00232
00233 addr_pack(&a, ADDR_TYPE_IP6, IP6_ADDR_BITS, ip6->data, IP6_ADDR_LEN);
00234 return (addr_ntoa(&a));
00235 }
00236
00237 int
00238 ip6_pton(const char *p, ip6_addr_t *ip6)
00239 {
00240 uint16_t data[8], *u = (uint16_t *)ip6->data;
00241 int i, j, n, z = -1;
00242 char *ep;
00243 long l;
00244
00245 if (*p == ':')
00246 p++;
00247
00248 for (n = 0; n < 8; n++) {
00249 l = strtol(p, &ep, 16);
00250
00251 if (ep == p) {
00252 if (ep[0] == ':' && z == -1) {
00253 z = n;
00254 p++;
00255 } else if (ep[0] == '\0') {
00256 break;
00257 } else {
00258 return (-1);
00259 }
00260 } else if (ep[0] == '.' && n <= 6) {
00261 if (ip_pton(p, (ip_addr_t *)(data + n)) < 0)
00262 return (-1);
00263 n += 2;
00264 ep = "";
00265 break;
00266 } else if (l >= 0 && l <= 0xffff) {
00267 data[n] = htons((uint16_t)l);
00268
00269 if (ep[0] == '\0') {
00270 n++;
00271 break;
00272 } else if (ep[0] != ':' || ep[1] == '\0')
00273 return (-1);
00274
00275 p = ep + 1;
00276 } else
00277 return (-1);
00278 }
00279 if (n == 0 || *ep != '\0' || (z == -1 && n != 8))
00280 return (-1);
00281
00282 for (i = 0; i < z; i++) {
00283 u[i] = data[i];
00284 }
00285 while (i < 8 - (n - z - 1)) {
00286 u[i++] = 0;
00287 }
00288 for (j = z + 1; i < 8; i++, j++) {
00289 u[i] = data[j];
00290 }
00291 return (0);
00292 }