|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.