Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

addr-util.c

Go to the documentation of this file.
00001 /*
00002  * addr-util.c
00003  *
00004  * Copyright (c) 2002 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: addr-util.c,v 1.4 2005/01/23 07:36:54 dugsong Exp $
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          * Algorithm borrowed from Vixie's inet_pton6()
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 = ""; /* XXX */
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 }

Generated on Sun May 14 14:51:11 2006 by  doxygen 1.4.2