Annotation of qemu/roms/SLOF/clients/net-snk/app/netlib/ethernet.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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