home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / lib / libc / net / linkaddr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-20  |  4.3 KB  |  143 lines

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