home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / net / linkaddr.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  165 lines

  1. /*    $NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $    */
  2.  
  3. /*-
  4.  * Copyright (c) 1990, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *    This product includes software developed by the University of
  18.  *    California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  */
  35.  
  36. #if defined(LIBC_SCCS) && !defined(lint)
  37. #if 0
  38. static char sccsid[] = "@(#)linkaddr.c    8.1 (Berkeley) 6/4/93";
  39. #else
  40. static char rcsid[] = "$NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $";
  41. #endif
  42. #endif /* LIBC_SCCS and not lint */
  43.  
  44. #include <sys/types.h>
  45. #include <sys/socket.h>
  46. #include <net/if_dl.h>
  47. #include <string.h>
  48.  
  49. /* States*/
  50. #define NAMING    0
  51. #define GOTONE    1
  52. #define GOTTWO    2
  53. #define RESET    3
  54. /* Inputs */
  55. #define    DIGIT    (4*0)
  56. #define    END    (4*1)
  57. #define DELIM    (4*2)
  58. #define LETTER    (4*3)
  59.  
  60. void
  61. link_addr(addr, sdl)
  62.     register const char *addr;
  63.     register struct sockaddr_dl *sdl;
  64. {
  65.     register char *cp = sdl->sdl_data;
  66.     char *cplim = sdl->sdl_len + (char *)sdl;
  67.     register int byte = 0, state = NAMING, new = 0;
  68.  
  69.     bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
  70.     sdl->sdl_family = AF_LINK;
  71.     do {
  72.         state &= ~LETTER;
  73.         if ((*addr >= '0') && (*addr <= '9')) {
  74.             new = *addr - '0';
  75.         } else if ((*addr >= 'a') && (*addr <= 'f')) {
  76.             new = *addr - 'a' + 10;
  77.         } else if ((*addr >= 'A') && (*addr <= 'F')) {
  78.             new = *addr - 'A' + 10;
  79.         } else if (*addr == 0) {
  80.             state |= END;
  81.         } else if (state == NAMING &&
  82.                (((*addr >= 'A') && (*addr <= 'Z')) ||
  83.                ((*addr >= 'a') && (*addr <= 'z'))))
  84.             state |= LETTER;
  85.         else
  86.             state |= DELIM;
  87.         addr++;
  88.         switch (state /* | INPUT */) {
  89.         case NAMING | DIGIT:
  90.         case NAMING | LETTER:
  91.             *cp++ = addr[-1];
  92.             continue;
  93.         case NAMING | DELIM:
  94.             state = RESET;
  95.             sdl->sdl_nlen = cp - sdl->sdl_data;
  96.             continue;
  97.         case GOTTWO | DIGIT:
  98.             *cp++ = byte;
  99.             /* FALLTHROUGH */
  100.         case RESET | DIGIT:
  101.             state = GOTONE;
  102.             byte = new;
  103.             continue;
  104.         case GOTONE | DIGIT:
  105.             state = GOTTWO;
  106.             byte = new + (byte << 4);
  107.             continue;
  108.         default: /* | DELIM */
  109.             state = RESET;
  110.             *cp++ = byte;
  111.             byte = 0;
  112.             continue;
  113.         case GOTONE | END:
  114.         case GOTTWO | END:
  115.             *cp++ = byte;
  116.             /* FALLTHROUGH */
  117.         case RESET | END:
  118.             break;
  119.         }
  120.         break;
  121.     } while (cp < cplim); 
  122.     sdl->sdl_alen = cp - LLADDR(sdl);
  123.     new = cp - (char *)sdl;
  124.     if (new > sizeof(*sdl))
  125.         sdl->sdl_len = new;
  126.     return;
  127. }
  128.  
  129. static char hexlist[] = "0123456789abcdef";
  130.  
  131. char *
  132. link_ntoa(sdl)
  133.     register const struct sockaddr_dl *sdl;
  134. {
  135.     static char obuf[64];
  136.     register char *out = obuf; 
  137.     register int i;
  138.     register u_char *in = (u_char *)LLADDR(sdl);
  139.     u_char *inlim = in + sdl->sdl_alen;
  140.     int firsttime = 1;
  141.  
  142.     if (sdl->sdl_nlen) {
  143.         bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
  144.         out += sdl->sdl_nlen;
  145.         if (sdl->sdl_alen)
  146.             *out++ = ':';
  147.     }
  148.     while (in < inlim) {
  149.         if (firsttime)
  150.             firsttime = 0;
  151.         else
  152.             *out++ = '.';
  153.         i = *in++;
  154.         if (i > 0xf) {
  155.             out[1] = hexlist[i & 0xf];
  156.             i >>= 4;
  157.             out[0] = hexlist[i];
  158.             out += 2;
  159.         } else
  160.             *out++ = hexlist[i];
  161.     }
  162.     *out = 0;
  163.     return (obuf);
  164. }
  165.