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/>.
27 #include <net/packet.h>
28 #include <net/socket.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
)
41 if (arp
->prot_type
!= NET_PACKET_TYPE_IPV4
)
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");
51 if (arp
->target_ipv4
== netif
->ip
)
52 arp_send_reply (netif
, arp
->sender_ethernet
, arp
->sender_ipv4
);
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
);
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
));
75 arp
->hard_type
= ARP_HARD_TYPE_ETHERNET
;
76 arp
->prot_type
= NET_PACKET_TYPE_IPV4
;
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
;
88 /* intranet connection */
89 arp
->target_ipv4
= target_ipaddr
;
91 packet_t
*packet
= (packet_t
*) kmalloc (sizeof (packet_t
));
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);
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
));
116 arp
->hard_type
= ARP_HARD_TYPE_ETHERNET
;
117 arp
->prot_type
= NET_PACKET_TYPE_IPV4
;
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
));
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);
145 unsigned arp_cache_add (mac_addr_t mac
, net_ipv4 ip
)
148 for (cache
= arp_cache_list
.next
; cache
!= &arp_cache_list
; cache
= cache
->next
) {
153 /* alloc and init context */
154 cache
= (arp_cache_t
*) kmalloc (sizeof (arp_cache_t
));
159 memcpy (&cache
->mac
, mac
, 6);
164 cache
->next
= &arp_cache_list
;
165 cache
->prev
= arp_cache_list
.prev
;
166 cache
->prev
->next
= cache
;
167 cache
->next
->prev
= cache
;
172 unsigned arp_cache_get (net_ipv4 ip
, mac_addr_t
*mac
)
176 if (net_proto_ip_network (ip
)) {
177 netif_t
*eth
= netif_findbyname ("eth0");
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);
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);
200 unsigned init_proto_arp ()
202 arp_cache_list
.next
= &arp_cache_list
;
203 arp_cache_list
.prev
= &arp_cache_list
;
206 memset (mac_addr
, 0xff, 6);
207 arp_cache_add (mac_addr
, INADDR_BROADCAST
);
208 arp_cache_add (mac_addr
, INADDR_ANY
);