5252#ifndef ETH_P_IP
5353#define ETH_P_IP ETHERTYPE_IP
5454#endif
55+ #ifndef ETHERTYPE_ARP
56+ #define ETHERTYPE_ARP 0x0806
57+ #endif
5558
5659#define PACKED __attribute__((packed))
5760#define AF_HDR_SIZE 4
@@ -65,6 +68,34 @@ struct eth_hdr {
6568static int utun_fd = -1 ;
6669static uint8_t peer_mac [6 ] = {0x06 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 };
6770static pthread_mutex_t utun_lock = PTHREAD_MUTEX_INITIALIZER ;
71+ static uint8_t pending_frame [LINK_MTU + sizeof (struct eth_hdr )];
72+ static size_t pending_len = 0 ;
73+ static pthread_mutex_t pending_lock = PTHREAD_MUTEX_INITIALIZER ;
74+ static uint32_t host_ip_be ;
75+ static uint32_t peer_ip_be ;
76+
77+ struct arp_packet {
78+ uint16_t htype ;
79+ uint16_t ptype ;
80+ uint8_t hlen ;
81+ uint8_t plen ;
82+ uint16_t opcode ;
83+ uint8_t sha [6 ];
84+ uint32_t spa ;
85+ uint8_t tha [6 ];
86+ uint32_t tpa ;
87+ } PACKED ;
88+
89+ static int enqueue_frame (const void * frame , size_t len )
90+ {
91+ if (len > sizeof (pending_frame ))
92+ return -1 ;
93+ pthread_mutex_lock (& pending_lock );
94+ memcpy (pending_frame , frame , len );
95+ pending_len = len ;
96+ pthread_mutex_unlock (& pending_lock );
97+ return 0 ;
98+ }
6899
69100static int tap_poll (struct wolfIP_ll_dev * ll , void * buf , uint32_t len )
70101{
@@ -77,6 +108,18 @@ static int tap_poll(struct wolfIP_ll_dev *ll, void *buf, uint32_t len)
77108 if (utun_fd < 0 )
78109 return -1 ;
79110
111+ pthread_mutex_lock (& pending_lock );
112+ if (pending_len > 0 ) {
113+ size_t to_copy = pending_len ;
114+ if (to_copy > len )
115+ to_copy = len ;
116+ memcpy (buf , pending_frame , to_copy );
117+ pending_len = 0 ;
118+ pthread_mutex_unlock (& pending_lock );
119+ return (int )to_copy ;
120+ }
121+ pthread_mutex_unlock (& pending_lock );
122+
80123 pfd .fd = utun_fd ;
81124 pfd .events = POLLIN ;
82125
@@ -109,6 +152,7 @@ static int tap_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t len)
109152 uint8_t tmp [LINK_MTU + AF_HDR_SIZE ];
110153 struct eth_hdr * eth ;
111154 size_t ip_len ;
155+ struct arp_packet * arp ;
112156 uint32_t af ;
113157 (void )ll ;
114158
@@ -117,6 +161,35 @@ static int tap_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t len)
117161 if (len < sizeof (struct eth_hdr ))
118162 return 0 ;
119163 eth = (struct eth_hdr * )buf ;
164+ if (ntohs (eth -> type ) == ETHERTYPE_ARP ) {
165+ if (len < sizeof (struct eth_hdr ) + sizeof (struct arp_packet ))
166+ return (int )len ;
167+ arp = (struct arp_packet * )(eth + 1 );
168+ if (ntohs (arp -> opcode ) == 1 /* request */ &&
169+ arp -> tpa == host_ip_be ) {
170+ struct {
171+ struct eth_hdr eth ;
172+ struct arp_packet arp ;
173+ } PACKED reply ;
174+ memset (& reply , 0 , sizeof (reply ));
175+ memcpy (reply .eth .dst , eth -> src , sizeof (reply .eth .dst ));
176+ memcpy (reply .eth .src , peer_mac , sizeof (reply .eth .src ));
177+ reply .eth .type = htons (ETHERTYPE_ARP );
178+ reply .arp .htype = htons (1 );
179+ reply .arp .ptype = htons (ETHERTYPE_IP );
180+ reply .arp .hlen = 6 ;
181+ reply .arp .plen = 4 ;
182+ reply .arp .opcode = htons (2 );
183+ memcpy (reply .arp .sha , peer_mac , sizeof (reply .arp .sha ));
184+ reply .arp .spa = host_ip_be ;
185+ memcpy (reply .arp .tha , arp -> sha , sizeof (reply .arp .tha ));
186+ reply .arp .tpa = arp -> spa ;
187+ printf ("tap_darwin: answering ARP request locally\n" );
188+ enqueue_frame (& reply , sizeof (reply ));
189+ return (int )len ;
190+ }
191+ return (int )len ;
192+ }
120193 if (ntohs (eth -> type ) != ETH_P_IP )
121194 return (int )len ;
122195
@@ -155,6 +228,8 @@ static int tap_setup_ipv4(const char *ifname, uint32_t host_ip, uint32_t peer_ip
155228 if (!inet_ntop (AF_INET , & netmask , netmask_str , sizeof (netmask_str )))
156229 return -1 ;
157230
231+ printf ("tap_setup_ipv4: ifname=%s local=%s peer=%s\n" , ifname , local_str , peer_str );
232+
158233 snprintf (cmd , sizeof (cmd ), "/sbin/ifconfig %s inet %s %s netmask %s up" ,
159234 ifname , local_str , peer_str , netmask_str );
160235 if (system (cmd ) != 0 )
@@ -173,7 +248,10 @@ int tap_init(struct wolfIP_ll_dev *ll, const char *requested_ifname, uint32_t ho
173248 struct sockaddr_ctl sc ;
174249 char ifname_buf [IFNAMSIZ ];
175250 socklen_t optlen ;
176- uint32_t peer_ip = atoip4 (WOLFIP_IP );
251+ uint32_t peer_ip = htonl (atoip4 (WOLFIP_IP ));
252+ host_ip_be = host_ip ;
253+ peer_ip_be = peer_ip ;
254+ printf ("tap_init: host_ip=0x%08x peer_ip=0x%08x\n" , host_ip_be , peer_ip_be );
177255 (void )requested_ifname ;
178256
179257 utun_fd = socket (PF_SYSTEM , SOCK_DGRAM , SYSPROTO_CONTROL );
0 commit comments