|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: ! 13: ! 14: /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ALGORITHMS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ ! 15: ! 16: /** \file netbase.c <pre> ! 17: * *********************** Receive-handle diagram ************************* ! 18: * ! 19: * Note: Every layer calls out required upper layer ! 20: * ! 21: * lower ! 22: * | MAC/LLC Receive packet (receive_ether) ! 23: * | | ! 24: * | NETWORK +-----------+---------+ ! 25: * | | | ! 26: * | IPv4 (handle_ipv4) IPv6 (handle_ipv4) ! 27: * | ARP (handle_arp) ICMP & NDP ! 28: * | ICMP | ! 29: * | | | ! 30: * | +---------+---------+ ! 31: * | | ! 32: * | TRANSPORT +---------+---------+ ! 33: * | | | ! 34: * | TCP (handle_tcp) UDP (handle_udp) ! 35: * | | ! 36: * | APPLICATION +----------------+-----------+ ! 37: * V | | ! 38: * upper DNS (handle_dns) BootP / DHCP (handle_bootp_client) ! 39: * ! 40: * ************************************************************************ ! 41: * </pre> */ ! 42: ! 43: ! 44: /*>>>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<*/ ! 45: ! 46: #include <ethernet.h> ! 47: #include <string.h> ! 48: #include <sys/socket.h> ! 49: #include <ipv4.h> ! 50: //#include <ipv6.h> ! 51: ! 52: ! 53: /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/ ! 54: ! 55: static uint8_t ether_packet[ETH_MTU_SIZE]; ! 56: static uint8_t own_mac[6] = {0, 0, 0, 0, 0, 0}; ! 57: static uint8_t multicast_mac[] = {0x01, 0x00, 0x5E}; ! 58: static const uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; ! 59: ! 60: /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<*/ ! 61: ! 62: /** ! 63: * Ethernet: Set the own MAC address to initializes ethernet layer. ! 64: * ! 65: * @param own_mac own hardware-address (MAC) ! 66: */ ! 67: void ! 68: set_mac_address(const uint8_t * _own_mac) { ! 69: if (_own_mac) ! 70: memcpy(own_mac, _own_mac, 6); ! 71: else ! 72: memset(own_mac, 0, 6); ! 73: } ! 74: ! 75: /** ! 76: * Ethernet: Set the own MAC address to initializes ethernet layer. ! 77: * ! 78: * @return own hardware-address (MAC) ! 79: */ ! 80: const uint8_t * ! 81: get_mac_address(void) { ! 82: return own_mac; ! 83: } ! 84: ! 85: /** ! 86: * Ethernet: Check if given multicast address is a multicast MAC address ! 87: * starting with 0x3333 ! 88: * ! 89: * @return true or false ! 90: */ ! 91: static uint8_t ! 92: is_multicast_mac(uint8_t * mac) { ! 93: ! 94: uint16_t mc = 0x3333; ! 95: if (memcmp(mac, &mc, 2) == 0) ! 96: return 1; ! 97: ! 98: return 0; ! 99: } ! 100: ! 101: ! 102: /** ! 103: * Ethernet: Receives an ethernet-packet and handles it according to ! 104: * Receive-handle diagram. ! 105: * ! 106: * @return ZERO - packet was handled or no packets received; ! 107: * NON ZERO - error condition occurs. ! 108: */ ! 109: int32_t ! 110: receive_ether(void) { ! 111: int32_t bytes_received; ! 112: struct ethhdr * ethh; ! 113: ! 114: memset(ether_packet, 0, ETH_MTU_SIZE); ! 115: bytes_received = recv(0, ether_packet, ETH_MTU_SIZE, 0); ! 116: ! 117: if (!bytes_received) // No messages ! 118: return 0; ! 119: ! 120: if (bytes_received < sizeof(struct ethhdr)) ! 121: return -1; // packet is too small ! 122: ! 123: ethh = (struct ethhdr *) ether_packet; ! 124: ! 125: if(memcmp(ethh->dest_mac, broadcast_mac, 6) != 0 ! 126: && memcmp(ethh->dest_mac, multicast_mac, 3) != 0 ! 127: && memcmp(ethh->dest_mac, own_mac, 6 ) != 0 ! 128: && !is_multicast_mac(ethh->dest_mac)) ! 129: return -1; // packet is too small ! 130: ! 131: switch (htons(ethh -> type)) { ! 132: case ETHERTYPE_IP: ! 133: return handle_ipv4((uint8_t*) (ethh + 1), ! 134: bytes_received - sizeof(struct ethhdr)); ! 135: /* ! 136: case ETHERTYPE_IPv6: ! 137: return handle_ipv6(ether_packet + sizeof(struct ethhdr), ! 138: bytes_received - sizeof(struct ethhdr)); ! 139: */ ! 140: case ETHERTYPE_ARP: ! 141: return handle_arp((uint8_t*) (ethh + 1), ! 142: bytes_received - sizeof(struct ethhdr)); ! 143: default: ! 144: break; ! 145: } ! 146: return -1; // unknown protocol ! 147: } ! 148: ! 149: /** ! 150: * Ethernet: Sends an ethernet frame via the initialized file descriptor. ! 151: * ! 152: * @return number of transmitted bytes ! 153: */ ! 154: int ! 155: send_ether(void* buffer, int len) ! 156: { ! 157: return send(0, buffer, len, 0); ! 158: } ! 159: ! 160: /** ! 161: * Ethernet: Creates Ethernet-packet. Places Ethernet-header in a packet and ! 162: * fills it with corresponding information. ! 163: * <p> ! 164: * Use this function with similar functions for other network layers ! 165: * (fill_arphdr, fill_iphdr, fill_udphdr, fill_dnshdr, fill_btphdr). ! 166: * ! 167: * @param packet Points to the place where eth-header must be placed. ! 168: * @param eth_type Type of the next level protocol (e.g. IP or ARP). ! 169: * @param src_mac Sender MAC address ! 170: * @param dest_mac Receiver MAC address ! 171: * @see ethhdr ! 172: * @see fill_arphdr ! 173: * @see fill_iphdr ! 174: * @see fill_udphdr ! 175: * @see fill_dnshdr ! 176: * @see fill_btphdr ! 177: */ ! 178: void ! 179: fill_ethhdr(uint8_t * packet, uint16_t eth_type, ! 180: const uint8_t * src_mac, const uint8_t * dest_mac) { ! 181: struct ethhdr * ethh = (struct ethhdr *) packet; ! 182: ! 183: ethh -> type = htons(eth_type); ! 184: memcpy(ethh -> src_mac, src_mac, 6); ! 185: memcpy(ethh -> dest_mac, dest_mac, 6); ! 186: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.