Annotation of tme/generic/ethernet.c, revision 1.1

1.1     ! root        1: /* $Id: ethernet.c,v 1.1 2003/05/02 17:10:50 fredette Exp $ */
        !             2: 
        !             3: /* generic/ethernet.c - generic ethernet implementation support: */
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 2003 Matt Fredette
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. All advertising materials mentioning features or use of this software
        !            18:  *    must display the following acknowledgement:
        !            19:  *      This product includes software developed by Matt Fredette.
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            33:  * POSSIBILITY OF SUCH DAMAGE.
        !            34:  */
        !            35: 
        !            36: #include <tme/common.h>
        !            37: _TME_RCSID("$Id: ethernet.c,v 1.1 2003/05/02 17:10:50 fredette Exp $");
        !            38: 
        !            39: /* includes: */
        !            40: #include <tme/generic/ethernet.h>
        !            41: #include <stdlib.h>
        !            42: 
        !            43: /* the Ethernet broadcast address: */
        !            44: const tme_uint8_t tme_ethernet_addr_broadcast[TME_ETHERNET_ADDR_SIZE] = {
        !            45:   0xff, 0xff, 0xff, 0xff, 0xff, 0xff
        !            46: };
        !            47: 
        !            48: /* this scores an Ethernet connection: */
        !            49: int
        !            50: tme_ethernet_connection_score(struct tme_connection *conn, unsigned int *_score)
        !            51: {
        !            52:   /* both sides must be Ethernet connections: */
        !            53:   assert(conn->tme_connection_type == TME_CONNECTION_ETHERNET);
        !            54:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_ETHERNET);
        !            55: 
        !            56:   /* XXX we don't do any real checking: */
        !            57:   *_score = 1;
        !            58:   return (TME_OK);
        !            59: }
        !            60: 
        !            61: /* this parses an ethernet address: */
        !            62: int
        !            63: tme_ethernet_addr_parse(const char *addr_string, tme_uint8_t *addr_bytes)
        !            64: {
        !            65:   const char *p1;
        !            66:   char *p2;
        !            67:   unsigned long byte;
        !            68:   int byte_i;
        !            69: 
        !            70:   /* if we were given a NULL string, the parse fails: */
        !            71:   if (addr_string == NULL) {
        !            72:     return (EINVAL);
        !            73:   }
        !            74: 
        !            75:   /* loop converting bytes: */
        !            76:   p1 = addr_string;
        !            77:   byte_i = 0;
        !            78:   for(;;) {
        !            79:     
        !            80:     /* convert the next byte: */
        !            81:     byte = strtoul(p1, &p2, 16);
        !            82: 
        !            83:     /* if some characters were converted: */
        !            84:     if (p2 != p1) {
        !            85:       
        !            86:       /* if this byte is out of range, the parse fails: */
        !            87:       if (byte > 0xff) {
        !            88:        return (EINVAL);
        !            89:       }
        !            90: 
        !            91:       /* if this is one too many bytes for an Ethernet address, the parse fails: */
        !            92:       else if (byte_i == TME_ETHERNET_ADDR_SIZE) {
        !            93:        return (EINVAL);
        !            94:       }
        !            95: 
        !            96:       /* store this byte: */
        !            97:       addr_bytes[byte_i++] = byte;
        !            98:     }
        !            99: 
        !           100:     /* if the conversion stopped on a NUL: */
        !           101:     if (*p2 == '\0') {
        !           102:       
        !           103:       /* if we haven't converted enough bytes, the parse fails,
        !           104:         otherwise the parse succeeds: */
        !           105:       return ((byte_i == TME_ETHERNET_ADDR_SIZE)
        !           106:              ? TME_OK
        !           107:              : EINVAL);
        !           108:     }
        !           109: 
        !           110:     /* if the conversion stopped on a colon, skip the colon and continue: */
        !           111:     else if (*p2 == ':') {
        !           112:       p1 = p2 + 1;
        !           113:     }
        !           114: 
        !           115:     /* otherwise, the parse fails: */
        !           116:     else {
        !           117:       return (EINVAL);
        !           118:     }
        !           119:   }
        !           120:   /* NOTREACHED */
        !           121: }
        !           122: 
        !           123: /* this copies frame chunks: */
        !           124: unsigned int
        !           125: tme_ethernet_chunks_copy(struct tme_ethernet_frame_chunk *chunks_dst,
        !           126:                         const struct tme_ethernet_frame_chunk *chunks_src)
        !           127: {
        !           128:   struct tme_ethernet_frame_chunk *chunk_dst;
        !           129:   const struct tme_ethernet_frame_chunk *chunk_src;
        !           130:   tme_uint8_t *chunk_bytes_dst;
        !           131:   const tme_uint8_t *chunk_bytes_src;
        !           132:   unsigned int chunk_size_dst;
        !           133:   unsigned int chunk_size_src;
        !           134:   unsigned int chunk_size;
        !           135:   unsigned int frame_size_total;
        !           136: 
        !           137:   chunk_src = chunks_src;
        !           138:   chunk_bytes_src = chunk_src->tme_ethernet_frame_chunk_bytes;
        !           139:   chunk_size_src = chunk_src->tme_ethernet_frame_chunk_bytes_count;
        !           140:   
        !           141:   frame_size_total = 0;
        !           142: 
        !           143:   /* if we have been given a destination: */
        !           144:   if (chunks_dst != NULL) {
        !           145: 
        !           146:     chunk_dst = chunks_dst;
        !           147:     chunk_bytes_dst = chunk_dst->tme_ethernet_frame_chunk_bytes;
        !           148:     chunk_size_dst = chunk_dst->tme_ethernet_frame_chunk_bytes_count;
        !           149: 
        !           150:     /* copy until we run out of source or destination chunks: */
        !           151:     for (; (chunk_dst != NULL
        !           152:            && chunk_src != NULL); ) {
        !           153:       
        !           154:       /* get the amount we can copy now: */
        !           155:       chunk_size = TME_MIN(chunk_size_dst, chunk_size_src);
        !           156:       assert(chunk_size > 0);
        !           157:       
        !           158:       /* copy: */
        !           159:       memcpy(chunk_bytes_dst, chunk_bytes_src, chunk_size);
        !           160:       
        !           161:       /* update: */
        !           162:       frame_size_total += chunk_size;
        !           163:       chunk_bytes_src += chunk_size;
        !           164:       chunk_size_src -= chunk_size;
        !           165:       if (chunk_size_src == 0
        !           166:          && (chunk_src = chunk_src->tme_ethernet_frame_chunk_next) != NULL) {
        !           167:        chunk_bytes_src = chunk_src->tme_ethernet_frame_chunk_bytes;
        !           168:        chunk_size_src = chunk_src->tme_ethernet_frame_chunk_bytes_count;
        !           169:       }
        !           170:       chunk_bytes_dst += chunk_size;
        !           171:       chunk_size_dst -= chunk_size;
        !           172:       if (chunk_size_dst == 0
        !           173:          && (chunk_dst = chunk_dst->tme_ethernet_frame_chunk_next) != NULL) {
        !           174:        chunk_bytes_dst = chunk_dst->tme_ethernet_frame_chunk_bytes;
        !           175:        chunk_size_dst = chunk_src->tme_ethernet_frame_chunk_bytes_count;
        !           176:       }
        !           177:     }
        !           178:   }
        !           179: 
        !           180:   /* count up the uncopied bytes: */
        !           181:   for (; chunk_src != NULL; ) {
        !           182:     frame_size_total += chunk_size_src;
        !           183:     if ((chunk_src = chunk_src->tme_ethernet_frame_chunk_next) != NULL) {
        !           184:       chunk_size_src = chunk_src->tme_ethernet_frame_chunk_bytes_count;
        !           185:     }
        !           186:   }
        !           187: 
        !           188:   /* done: */
        !           189:   return (frame_size_total);
        !           190: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.