1+ #include "arp.h"
2+ #include "libc/heap.h"
3+ #include "libc/mem.h"
4+ #include "network.h"
5+ #include "rtl8139.h"
6+ #include "serial.h"
7+
8+ arp_table_entry_t arp_table [512 ];
9+ int arp_table_size ;
10+ int arp_table_curr ;
11+
12+ uint8_t broadcast_mac_address [] = {0xff , 0xff , 0xff , 0xff , 0xff , 0xff };
13+
14+ void arp_handle_packet (arp_packet_t * arp_packet ) {
15+ uint8_t dst_hardware_addr [6 ];
16+ uint8_t dst_protocol_addr [4 ];
17+ // save some packet field
18+ memcpy (dst_hardware_addr , arp_packet -> src_hardware_addr , 6 );
19+ memcpy (dst_protocol_addr , arp_packet -> src_protocol_addr , 4 );
20+ // reply arp request, if the ip address matches(have to hard code the IP
21+ // eveywhere, because I don't have dhcp yet)
22+ if (ntohs (arp_packet -> opcode ) == ARP_REQUEST ) {
23+ // qemu_printf("Got ARP REQUEST......................");
24+ uint32_t my_ip = 0x0e02000a ;
25+ if (memcmp (arp_packet -> dst_protocol_addr , (uint8_t * )& my_ip , 4 )) {
26+
27+ // set source MAC address, IP address (hardcode the IP address as 10.2.2.3
28+ // until we really get one..)
29+ get_mac_addr (arp_packet -> src_hardware_addr );
30+ arp_packet -> src_protocol_addr [0 ] = 10 ;
31+ arp_packet -> src_protocol_addr [1 ] = 0 ;
32+ arp_packet -> src_protocol_addr [2 ] = 2 ;
33+ arp_packet -> src_protocol_addr [3 ] = 14 ;
34+
35+ // set destination MAC address, IP address
36+ memcpy (arp_packet -> dst_hardware_addr , dst_hardware_addr , 6 );
37+ memcpy (arp_packet -> dst_protocol_addr , dst_protocol_addr , 4 );
38+
39+ // set opcode
40+ arp_packet -> opcode = htons (ARP_REPLY );
41+
42+ // set lengths
43+ arp_packet -> hardware_addr_len = 6 ;
44+ arp_packet -> protocol_addr_len = 4 ;
45+
46+ // set hardware type
47+ arp_packet -> hardware_type = htons (HARDWARE_TYPE_ETHERNET );
48+
49+ // set protocol = IPv4
50+ arp_packet -> protocol = htons (ETHERNET_TYPE_IP );
51+
52+ // now send it with ethernet
53+ ethernet_send_packet (dst_hardware_addr , (uint8_t * )arp_packet ,
54+ sizeof (arp_packet_t ), ETHERNET_TYPE_ARP );
55+
56+ // qemu_printf("Replied Arp, the reply looks like this\n");
57+ }
58+ } else if (ntohs (arp_packet -> opcode ) == ARP_REPLY ) {
59+ // may be we can handle the case where we get a reply after sending a
60+ // request, but i don't think my os will ever need to do so...
61+ // qemu_printf("Got ARP REPLY......................");
62+ } else {
63+ serial_printff ("Got unknown ARP, opcode = %d\n" , arp_packet -> opcode );
64+ }
65+
66+ // now, store the ip-mac address mapping relation
67+ memcpy (& arp_table [arp_table_curr ].ip_addr , dst_protocol_addr , 4 );
68+ memcpy (& arp_table [arp_table_curr ].mac_addr , dst_hardware_addr , 6 );
69+ if (arp_table_size < 512 )
70+ arp_table_size ++ ;
71+ // wrap around
72+ if (arp_table_curr >= 512 )
73+ arp_table_curr = 0 ;
74+ }
75+
76+ void arp_send_packet (uint8_t * dst_hardware_addr , uint8_t * dst_protocol_addr ) {
77+ arp_packet_t arp_packet = {0 };
78+
79+ // set source MAC address, IP address (hardcode the IP address as 10.2.2.3
80+ // until we really get one..)
81+ get_mac_addr (arp_packet .src_hardware_addr );
82+ arp_packet .src_protocol_addr [0 ] = 10 ;
83+ arp_packet .src_protocol_addr [1 ] = 0 ;
84+ arp_packet .src_protocol_addr [2 ] = 2 ;
85+ arp_packet .src_protocol_addr [3 ] = 14 ;
86+
87+ // set destination MAC address, IP address
88+ memcpy (arp_packet .dst_hardware_addr , dst_hardware_addr , 6 );
89+ memcpy (arp_packet .dst_protocol_addr , dst_protocol_addr , 4 );
90+
91+ // set opcode
92+ arp_packet .opcode = htons (ARP_REQUEST );
93+
94+ // set lengths
95+ arp_packet .hardware_addr_len = 6 ;
96+ arp_packet .protocol_addr_len = 4 ;
97+
98+ // set hardware type
99+ arp_packet .hardware_type = htons (HARDWARE_TYPE_ETHERNET );
100+
101+ // set protocol = IPv4
102+ arp_packet .protocol = htons (ETHERNET_TYPE_IP );
103+
104+ // now send it with ethernet
105+ ethernet_send_packet (broadcast_mac_address , (uint8_t * )& arp_packet ,
106+ sizeof (arp_packet_t ), ETHERNET_TYPE_ARP );
107+ }
108+
109+ void arp_lookup_add (uint8_t * ret_hardware_addr , uint8_t * ip_addr ) {
110+ memcpy (& arp_table [arp_table_curr ].ip_addr , ip_addr , 4 );
111+ memcpy (& arp_table [arp_table_curr ].mac_addr , ret_hardware_addr , 6 );
112+ if (arp_table_size < 512 )
113+ arp_table_size ++ ;
114+ // wrap around
115+ if (arp_table_curr >= 512 )
116+ arp_table_curr = 0 ;
117+ }
118+
119+ int arp_lookup (uint8_t * ret_hardware_addr , uint8_t * ip_addr ) {
120+ uint32_t ip_entry = * ((uint32_t * )(ip_addr ));
121+ for (int i = 0 ; i < 512 ; i ++ ) {
122+ if (arp_table [i ].ip_addr == ip_entry ) {
123+ memcpy (ret_hardware_addr , & arp_table [i ].mac_addr , 6 );
124+ return 1 ;
125+ }
126+ }
127+ return 0 ;
128+ }
129+
130+ void arp_init () {
131+ uint8_t broadcast_ip [4 ];
132+ uint8_t broadcast_mac [6 ];
133+
134+ memset (broadcast_ip , 0xff , 4 );
135+ memset (broadcast_mac , 0xff , 6 );
136+ arp_lookup_add (broadcast_mac , broadcast_ip );
137+ }
0 commit comments