1 /*
2 * Copyright (c) 2014 Chris Anderson
3 * Copyright (c) 2014 Brian Swetland
4 *
5 * Use of this source code is governed by a MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT
8 */
9 #pragma once
10
11 #include <lib/minip.h>
12
13 #include <lk/compiler.h>
14 #include <endian.h>
15 #include <lk/list.h>
16 #include <stdint.h>
17 #include <string.h>
18
19 /* Lib configuration */
20 #define MINIP_USE_UDP_CHECKSUM 0
21 #define MINIP_MTU_SIZE 1536
22 #define MINIP_USE_ARP 1
23
24 #pragma pack(push, 1)
25 struct arp_pkt {
26 uint16_t htype;
27 uint16_t ptype;
28 uint8_t hlen;
29 uint8_t plen;
30 uint16_t oper;
31 uint8_t sha[6];
32 uint32_t spa;
33 uint8_t tha[6];
34 uint32_t tpa;
35 };
36
37 struct ipv4_hdr {
38 uint8_t ver_ihl;
39 uint8_t dscp_ecn;
40 uint16_t len;
41 uint16_t id;
42 uint16_t flags_frags;
43 uint8_t ttl;
44 uint8_t proto;
45 uint16_t chksum;
46 uint32_t src_addr;
47 uint32_t dst_addr;
48 uint8_t data[];
49 };
50
51 struct icmp_pkt {
52 uint8_t type;
53 uint8_t code;
54 uint16_t chksum;
55 uint8_t hdr_data[4];
56 uint8_t data[];
57 };
58
59 struct eth_hdr {
60 uint8_t dst_mac[6];
61 uint8_t src_mac[6];
62 uint16_t type;
63 };
64
65 #pragma pack(pop)
66
67 enum {
68 ICMP_ECHO_REPLY = 0,
69 ICMP_ECHO_REQUEST = 8,
70 };
71
72 enum {
73 IP_PROTO_ICMP = 0x1,
74 IP_PROTO_TCP = 0x6,
75 IP_PROTO_UDP = 0x11,
76 };
77
78 enum {
79 ETH_TYPE_IPV4 = 0x0800,
80 ETH_TYPE_ARP = 0x0806,
81 };
82
83 enum {
84 ARP_OPER_REQUEST = 0x0001,
85 ARP_OPER_REPLY = 0x0002,
86 };
87
88 extern tx_func_t minip_tx_handler;
89 typedef struct udp_hdr udp_hdr_t;
90 static const uint8_t bcast_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
91
92 void arp_cache_init(void);
93 void arp_cache_update(uint32_t addr, const uint8_t mac[6]);
94 uint8_t *arp_cache_lookup(uint32_t addr);
95 void arp_cache_dump(void);
96 int arp_send_request(uint32_t addr);
97 const uint8_t *arp_get_dest_mac(uint32_t host);
98
99 uint16_t rfc1701_chksum(const uint8_t *buf, size_t len);
100 uint16_t rfc768_chksum(struct ipv4_hdr *ipv4, udp_hdr_t *udp);
101 uint16_t ones_sum16(uint32_t sum, const void *_buf, int len);
102
103 /* Helper methods for building headers */
104 void minip_build_mac_hdr(struct eth_hdr *pkt, const uint8_t *dst, uint16_t type);
105 void minip_build_ipv4_hdr(struct ipv4_hdr *ipv4, uint32_t dst, uint8_t proto, uint16_t len);
106
107 status_t minip_ipv4_send(pktbuf_t *p, uint32_t dest_addr, uint8_t proto);
108
109 void tcp_input(pktbuf_t *p, uint32_t src_ip, uint32_t dst_ip);
110 void udp_input(pktbuf_t *p, uint32_t src_ip);
111
112 const uint8_t *get_dest_mac(uint32_t host);
113
114 // timers
115 typedef void (*net_timer_callback_t)(void *);
116
117 typedef struct net_timer {
118 struct list_node node;
119
120 lk_time_t sched_time;
121
122 net_timer_callback_t cb;
123 void *arg;
124 } net_timer_t;
125
126 /* set a net timer. returns true if the timer was not set before and is now */
127 bool net_timer_set(net_timer_t *, net_timer_callback_t, void *callback_args, lk_time_t delay) __NONNULL((1));
128
129 /* cancels a net timer. returns true if it was previously set and is not now */
130 bool net_timer_cancel(net_timer_t *) __NONNULL();
131
132 void net_timer_init(void);
133
mac_addr_copy(uint8_t * dest,const uint8_t * src)134 static inline void mac_addr_copy(uint8_t *dest, const uint8_t *src) {
135 *(uint32_t *)dest = *(const uint32_t *)src;
136 *(uint16_t *)(dest + 4) = *(const uint16_t *)(src + 4);
137 }
138