1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 #ifndef SLIRP_H 3 #define SLIRP_H 4 5 #ifdef _WIN32 6 7 /* as defined in sdkddkver.h */ 8 #ifndef _WIN32_WINNT 9 #define _WIN32_WINNT 0x0600 /* Vista */ 10 #endif 11 /* reduces the number of implicitly included headers */ 12 #ifndef WIN32_LEAN_AND_MEAN 13 #define WIN32_LEAN_AND_MEAN 14 #endif 15 16 #include <winsock2.h> 17 #include <windows.h> 18 #include <ws2tcpip.h> 19 #include <sys/timeb.h> 20 #include <iphlpapi.h> 21 22 #else 23 #if !defined(__HAIKU__) 24 #define O_BINARY 0 25 #endif 26 #endif 27 28 #ifndef _WIN32 29 #include <sys/uio.h> 30 #include <netinet/in.h> 31 #include <arpa/inet.h> 32 #include <sys/socket.h> 33 #include <sys/ioctl.h> 34 #endif 35 36 #ifdef __APPLE__ 37 #include <sys/filio.h> 38 #endif 39 40 /* Avoid conflicting with the libc insque() and remque(), which 41 have different prototypes. */ 42 #define insque slirp_insque 43 #define remque slirp_remque 44 #define quehead slirp_quehead 45 46 #include "debug.h" 47 #include "util.h" 48 49 #include "libslirp.h" 50 #include "ip.h" 51 #include "ip6.h" 52 #include "tcp.h" 53 #include "tcp_timer.h" 54 #include "tcp_var.h" 55 #include "tcpip.h" 56 #include "udp.h" 57 #include "ip_icmp.h" 58 #include "ip6_icmp.h" 59 #include "mbuf.h" 60 #include "sbuf.h" 61 #include "socket.h" 62 #include "if.h" 63 #include "main.h" 64 #include "misc.h" 65 66 #include "bootp.h" 67 #include "tftp.h" 68 69 #define ARPOP_REQUEST 1 /* ARP request */ 70 #define ARPOP_REPLY 2 /* ARP reply */ 71 72 struct ethhdr { 73 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ 74 unsigned char h_source[ETH_ALEN]; /* source ether addr */ 75 unsigned short h_proto; /* packet type ID field */ 76 }; 77 78 struct slirp_arphdr { 79 unsigned short ar_hrd; /* format of hardware address */ 80 unsigned short ar_pro; /* format of protocol address */ 81 unsigned char ar_hln; /* length of hardware address */ 82 unsigned char ar_pln; /* length of protocol address */ 83 unsigned short ar_op; /* ARP opcode (command) */ 84 85 /* 86 * Ethernet looks like this : This bit is variable sized however... 87 */ 88 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ 89 uint32_t ar_sip; /* sender IP address */ 90 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ 91 uint32_t ar_tip; /* target IP address */ 92 } SLIRP_PACKED; 93 94 #define ARP_TABLE_SIZE 16 95 96 typedef struct ArpTable { 97 struct slirp_arphdr table[ARP_TABLE_SIZE]; 98 int next_victim; 99 } ArpTable; 100 101 void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN]); 102 103 bool arp_table_search(Slirp *slirp, uint32_t ip_addr, 104 uint8_t out_ethaddr[ETH_ALEN]); 105 106 struct ndpentry { 107 unsigned char eth_addr[ETH_ALEN]; /* sender hardware address */ 108 struct in6_addr ip_addr; /* sender IP address */ 109 }; 110 111 #define NDP_TABLE_SIZE 16 112 113 typedef struct NdpTable { 114 struct ndpentry table[NDP_TABLE_SIZE]; 115 int next_victim; 116 } NdpTable; 117 118 void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr, 119 uint8_t ethaddr[ETH_ALEN]); 120 bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr, 121 uint8_t out_ethaddr[ETH_ALEN]); 122 123 struct Slirp { 124 unsigned time_fasttimo; 125 unsigned last_slowtimo; 126 bool do_slowtimo; 127 128 bool in_enabled, in6_enabled; 129 130 /* virtual network configuration */ 131 struct in_addr vnetwork_addr; 132 struct in_addr vnetwork_mask; 133 struct in_addr vhost_addr; 134 struct in6_addr vprefix_addr6; 135 uint8_t vprefix_len; 136 struct in6_addr vhost_addr6; 137 struct in_addr vdhcp_startaddr; 138 struct in_addr vnameserver_addr; 139 struct in6_addr vnameserver_addr6; 140 141 struct in_addr client_ipaddr; 142 char client_hostname[33]; 143 144 int restricted; 145 struct gfwd_list *guestfwd_list; 146 147 int if_mtu; 148 int if_mru; 149 150 bool disable_host_loopback; 151 152 /* mbuf states */ 153 struct quehead m_freelist; 154 struct quehead m_usedlist; 155 int mbuf_alloced; 156 157 /* if states */ 158 struct quehead if_fastq; /* fast queue (for interactive data) */ 159 struct quehead if_batchq; /* queue for non-interactive data */ 160 bool if_start_busy; /* avoid if_start recursion */ 161 162 /* ip states */ 163 struct ipq ipq; /* ip reass. queue */ 164 uint16_t ip_id; /* ip packet ctr, for ids */ 165 166 /* bootp/dhcp states */ 167 BOOTPClient bootp_clients[NB_BOOTP_CLIENTS]; 168 char *bootp_filename; 169 size_t vdnssearch_len; 170 uint8_t *vdnssearch; 171 char *vdomainname; 172 173 /* tcp states */ 174 struct socket tcb; 175 struct socket *tcp_last_so; 176 tcp_seq tcp_iss; /* tcp initial send seq # */ 177 uint32_t tcp_now; /* for RFC 1323 timestamps */ 178 179 /* udp states */ 180 struct socket udb; 181 struct socket *udp_last_so; 182 183 /* icmp states */ 184 struct socket icmp; 185 struct socket *icmp_last_so; 186 187 /* tftp states */ 188 char *tftp_prefix; 189 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; 190 char *tftp_server_name; 191 192 ArpTable arp_table; 193 NdpTable ndp_table; 194 195 GRand *grand; 196 void *ra_timer; 197 198 bool enable_emu; 199 200 const SlirpCb *cb; 201 void *opaque; 202 203 struct sockaddr_in *outbound_addr; 204 struct sockaddr_in6 *outbound_addr6; 205 }; 206 207 void if_start(Slirp *); 208 209 int get_dns_addr(struct in_addr *pdns_addr); 210 int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id); 211 212 /* ncsi.c */ 213 void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); 214 215 #ifndef _WIN32 216 #include <netdb.h> 217 #endif 218 219 220 extern bool slirp_do_keepalive; 221 222 #define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL) 223 224 /* dnssearch.c */ 225 int translate_dnssearch(Slirp *s, const char **names); 226 227 /* cksum.c */ 228 int cksum(struct mbuf *m, int len); 229 int ip6_cksum(struct mbuf *m); 230 231 /* if.c */ 232 void if_init(Slirp *); 233 void if_output(struct socket *, struct mbuf *); 234 235 /* ip_input.c */ 236 void ip_init(Slirp *); 237 void ip_cleanup(Slirp *); 238 void ip_input(struct mbuf *); 239 void ip_slowtimo(Slirp *); 240 void ip_stripoptions(register struct mbuf *, struct mbuf *); 241 242 /* ip_output.c */ 243 int ip_output(struct socket *, struct mbuf *); 244 245 /* ip6_input.c */ 246 void ip6_init(Slirp *); 247 void ip6_cleanup(Slirp *); 248 void ip6_input(struct mbuf *); 249 250 /* ip6_output */ 251 int ip6_output(struct socket *, struct mbuf *, int fast); 252 253 /* tcp_input.c */ 254 void tcp_input(register struct mbuf *, int, struct socket *, unsigned short af); 255 int tcp_mss(register struct tcpcb *, unsigned); 256 257 /* tcp_output.c */ 258 int tcp_output(register struct tcpcb *); 259 void tcp_setpersist(register struct tcpcb *); 260 261 /* tcp_subr.c */ 262 void tcp_init(Slirp *); 263 void tcp_cleanup(Slirp *); 264 void tcp_template(struct tcpcb *); 265 void tcp_respond(struct tcpcb *, register struct tcpiphdr *, 266 register struct mbuf *, tcp_seq, tcp_seq, int, unsigned short); 267 struct tcpcb *tcp_newtcpcb(struct socket *); 268 struct tcpcb *tcp_close(register struct tcpcb *); 269 void tcp_sockclosed(struct tcpcb *); 270 int tcp_fconnect(struct socket *, unsigned short af); 271 void tcp_connect(struct socket *); 272 void tcp_attach(struct socket *); 273 uint8_t tcp_tos(struct socket *); 274 int tcp_emu(struct socket *, struct mbuf *); 275 int tcp_ctl(struct socket *); 276 struct tcpcb *tcp_drop(struct tcpcb *tp, int err); 277 278 struct socket *slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, 279 int guest_port); 280 281 void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len); 282 283 #endif 284