|
|
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.