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 ETH_TYPE_IPV6 = 0x88dd,
82 };
83
84 enum {
85 ARP_OPER_REQUEST = 0x0001,
86 ARP_OPER_REPLY = 0x0002,
87 };
88
89 extern tx_func_t minip_tx_handler;
90 extern void *minip_tx_arg;
91
92 typedef struct udp_hdr udp_hdr_t;
93 static const uint8_t bcast_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
94 typedef uint32_t ipv4_addr;
95 typedef union {
96 uint32_t u;
97 uint8_t b[4];
98 } ipv4_t;
99
100 // ARP cache
101 void arp_cache_init(void);
102 void arp_cache_update(uint32_t addr, const uint8_t mac[6]);
103 uint8_t *arp_cache_lookup(uint32_t addr);
104 void arp_cache_dump(void);
105 int arp_send_request(uint32_t addr);
106 const uint8_t *arp_get_dest_mac(uint32_t host);
107
108 uint16_t rfc1701_chksum(const uint8_t *buf, size_t len);
109 uint16_t rfc768_chksum(struct ipv4_hdr *ipv4, udp_hdr_t *udp);
110 uint16_t ones_sum16(uint32_t sum, const void *_buf, int len);
111
112 // Helper methods for building headers
113 void minip_build_mac_hdr(struct eth_hdr *pkt, const uint8_t *dst, uint16_t type);
114 void minip_build_ipv4_hdr(struct ipv4_hdr *ipv4, uint32_t dst, uint8_t proto, uint16_t len);
115
116 status_t minip_ipv4_send(pktbuf_t *p, uint32_t dest_addr, uint8_t proto);
117
118 void tcp_input(pktbuf_t *p, uint32_t src_ip, uint32_t dst_ip);
119 void udp_input(pktbuf_t *p, uint32_t src_ip);
120
121 const uint8_t *get_dest_mac(uint32_t host);
122
123 // timers
124 typedef void (*net_timer_callback_t)(void *);
125
126 typedef struct net_timer {
127 struct list_node node;
128
129 lk_time_t sched_time;
130
131 net_timer_callback_t cb;
132 void *arg;
133 } net_timer_t;
134
135 /* set a net timer. returns true if the timer was not set before and is now */
136 bool net_timer_set(net_timer_t *, net_timer_callback_t, void *callback_args, lk_time_t delay) __NONNULL((1));
137
138 /* cancels a net timer. returns true if it was previously set and is not now */
139 bool net_timer_cancel(net_timer_t *) __NONNULL();
140
141 void net_timer_init(void);
142
mac_addr_copy(uint8_t * dest,const uint8_t * src)143 static inline void mac_addr_copy(uint8_t *dest, const uint8_t *src) {
144 memcpy(dest, src, 6);
145 }
146