Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / core / net / arp.c
blobd0b43735349c43c4cdb7918960ecbb9f09037d46
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <system.h>
21 #include <string.h>
22 #include <dev.h>
23 #include <net/eth.h>
24 #include <net/net.h>
25 #include <net/if.h>
26 #include <net/ip.h>
27 #include <net/packet.h>
28 #include <net/socket.h>
29 #include <net/arp.h>
32 arp_cache_t arp_cache_list;
34 unsigned net_proto_arp_handler (packet_t *packet, char *buf, unsigned len)
36 proto_arp_t *arp = (proto_arp_t *) buf;
38 if (arp->hard_type != ARP_HARD_TYPE_ETHERNET)
39 return 0;
41 if (arp->prot_type != NET_PACKET_TYPE_IPV4)
42 return 0;
44 /* ARP request */
45 if (arp->op == ARP_OP_REQUEST) {
46 //printf ("ARP - REQUEST: %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char) arp->sender_ethernet[0], (unsigned char) arp->sender_ethernet[1], (unsigned char) arp->sender_ethernet[2], (unsigned char) arp->sender_ethernet[3], (unsigned char) arp->sender_ethernet[4], (unsigned char) arp->sender_ethernet[5]);
47 /* TODO: melo by to projit vsechny rozhrani */
48 netif_t *netif = netif_findbyname ("eth0");
50 /* send ARP reply */
51 if (arp->target_ipv4 == netif->ip)
52 arp_send_reply (netif, arp->sender_ethernet, arp->sender_ipv4);
54 return 1;
57 if (arp->op == ARP_OP_REPLY) {
58 //printf ("ARP - REPLY: %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char) arp->sender_ethernet[0], (unsigned char) arp->sender_ethernet[1], (unsigned char) arp->sender_ethernet[2], (unsigned char) arp->sender_ethernet[3], (unsigned char) arp->sender_ethernet[4], (unsigned char) arp->sender_ethernet[5]);
60 arp_cache_add (arp->sender_ethernet, arp->sender_ipv4);
62 return 1;
65 return 0;
68 int arp_send_request (netif_t *i, net_ipv4 target_ipaddr)
70 proto_arp_t *arp = (proto_arp_t *) kmalloc (sizeof (proto_arp_t));
72 if (!arp)
73 return 0;
75 arp->hard_type = ARP_HARD_TYPE_ETHERNET;
76 arp->prot_type = NET_PACKET_TYPE_IPV4;
77 arp->hard_size = 6;
78 arp->prot_size = 4;
79 arp->op = ARP_OP_REQUEST;
80 memcpy (&arp->sender_ethernet, i->dev->dev_addr, 6);
81 arp->sender_ipv4 = i->ip;
82 memset (&arp->target_ethernet, 0, 6);
84 /* internet connection */
85 if (net_proto_ip_network (target_ipaddr))
86 arp->target_ipv4 = i->gw;
87 else
88 /* intranet connection */
89 arp->target_ipv4 = target_ipaddr;
91 packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t));
93 if (!packet)
94 return 0;
96 memset (&packet->mac_dest, 0xff, 6);
97 memcpy (&packet->mac_source, i->dev->dev_addr, 6);
99 packet->type = NET_PACKET_TYPE_ARP;
101 int ret = net_packet_send (i, packet, (char *) arp, 28);
103 kfree (packet);
104 kfree (arp);
106 return 1;
109 int arp_send_reply (netif_t *i, mac_addr_t target_mac, net_ipv4 target_ipaddr)
111 proto_arp_t *arp = (proto_arp_t *) kmalloc (sizeof (proto_arp_t));
113 if (!arp)
114 return 0;
116 arp->hard_type = ARP_HARD_TYPE_ETHERNET;
117 arp->prot_type = NET_PACKET_TYPE_IPV4;
118 arp->hard_size = 6;
119 arp->prot_size = 4;
120 arp->op = ARP_OP_REPLY;
121 memcpy (&arp->sender_ethernet, i->dev->dev_addr, 6);
122 arp->sender_ipv4 = i->ip;
123 memcpy (&arp->target_ethernet, target_mac, 6);
124 arp->target_ipv4 = target_ipaddr;
126 packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t));
128 if (!packet)
129 return 0;
131 memcpy (&packet->mac_dest, target_mac, 6);
132 memcpy (&packet->mac_source, i->dev->dev_addr, 6);
134 packet->type = NET_PACKET_TYPE_ARP;
136 int ret = net_packet_send (i, packet, (char *) arp, 28);
138 kfree (packet);
139 kfree (arp);
141 return 1;
144 /* ARP Cache */
145 unsigned arp_cache_add (mac_addr_t mac, net_ipv4 ip)
147 arp_cache_t *cache;
148 for (cache = arp_cache_list.next; cache != &arp_cache_list; cache = cache->next) {
149 if (cache->ip == ip)
150 return 0;
153 /* alloc and init context */
154 cache = (arp_cache_t *) kmalloc (sizeof (arp_cache_t));
156 if (!cache)
157 return 0;
159 memcpy (&cache->mac, mac, 6);
161 cache->ip = ip;
163 /* add into list */
164 cache->next = &arp_cache_list;
165 cache->prev = arp_cache_list.prev;
166 cache->prev->next = cache;
167 cache->next->prev = cache;
169 return 1;
172 unsigned arp_cache_get (net_ipv4 ip, mac_addr_t *mac)
174 arp_cache_t *cache;
176 if (net_proto_ip_network (ip)) {
177 netif_t *eth = netif_findbyname ("eth0");
179 if (!eth)
180 return 0;
182 for (cache = arp_cache_list.next; cache != &arp_cache_list; cache = cache->next) {
183 if (cache->ip == eth->gw) {
184 memcpy (mac, cache->mac, 6);
185 return 1;
188 } else {
189 for (cache = arp_cache_list.next; cache != &arp_cache_list; cache = cache->next) {
190 if (cache->ip == ip) {
191 memcpy (mac, cache->mac, 6);
192 return 1;
197 return 0;
200 unsigned init_proto_arp ()
202 arp_cache_list.next = &arp_cache_list;
203 arp_cache_list.prev = &arp_cache_list;
205 mac_addr_t mac_addr;
206 memset (mac_addr, 0xff, 6);
207 arp_cache_add (mac_addr, INADDR_BROADCAST);
208 arp_cache_add (mac_addr, INADDR_ANY);
210 return 1;