Builtin slirp: Added IPv6 support from libslirp code.
TODO: replacements for glib function, debug support, code cleanup.
This commit is contained in:
parent
7dd1a7be9e
commit
64e4671c00
@ -215,13 +215,19 @@
|
||||
<ClCompile Include="..\iodev\network\slirp\arp_table.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\bootp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\cksum.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\dhcpv6.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\dnssearch.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\if.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip6_icmp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip6_input.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip6_output.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip_icmp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip_input.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip_output.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\mbuf.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\misc.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ncsi.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ndp_table.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\sbuf.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\slirp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\socket.cc" />
|
||||
@ -231,6 +237,7 @@
|
||||
<ClCompile Include="..\iodev\network\slirp\tcp_timer.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\tftp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\udp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\udp6.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\util.cc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -238,6 +245,7 @@
|
||||
<ClInclude Include="..\iodev\network\slirp\bootp.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\compat.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\debug.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\dhcpv6.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\if.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\ip.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\ip6.h" />
|
||||
@ -247,6 +255,7 @@
|
||||
<ClInclude Include="..\iodev\network\slirp\main.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\mbuf.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\misc.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\ncsi-pkt.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\sbuf.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\slirp.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\socket.h" />
|
||||
|
@ -233,13 +233,19 @@
|
||||
<ClCompile Include="..\iodev\network\slirp\arp_table.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\bootp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\cksum.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\dhcpv6.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\dnssearch.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\if.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip6_icmp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip6_input.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip6_output.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip_icmp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip_input.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ip_output.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\mbuf.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\misc.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ncsi.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\ndp_table.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\sbuf.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\slirp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\socket.cc" />
|
||||
@ -249,6 +255,7 @@
|
||||
<ClCompile Include="..\iodev\network\slirp\tcp_timer.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\tftp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\udp.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\udp6.cc" />
|
||||
<ClCompile Include="..\iodev\network\slirp\util.cc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -261,6 +268,7 @@
|
||||
<ClInclude Include="..\iodev\network\slirp\bootp.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\compat.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\debug.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\dhcpv6.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\if.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\ip.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\ip6.h" />
|
||||
@ -270,6 +278,7 @@
|
||||
<ClInclude Include="..\iodev\network\slirp\main.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\mbuf.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\misc.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\ncsi-pkt.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\sbuf.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\slirp.h" />
|
||||
<ClInclude Include="..\iodev\network\slirp\socket.h" />
|
||||
|
@ -59,13 +59,19 @@ SLIRP_OBJS = \
|
||||
slirp/arp_table.o \
|
||||
slirp/bootp.o \
|
||||
slirp/cksum.o \
|
||||
slirp/dhcpv6.o \
|
||||
slirp/dnssearch.o \
|
||||
slirp/if.o \
|
||||
slirp/ip6_icmp.o \
|
||||
slirp/ip6_input.o \
|
||||
slirp/ip6_output.o \
|
||||
slirp/ip_icmp.o \
|
||||
slirp/ip_input.o \
|
||||
slirp/ip_output.o \
|
||||
slirp/mbuf.o \
|
||||
slirp/misc.o \
|
||||
slirp/ncsi.o \
|
||||
slirp/ndp_table.o \
|
||||
slirp/sbuf.o \
|
||||
slirp/slirp.o \
|
||||
slirp/socket.o \
|
||||
@ -75,6 +81,7 @@ SLIRP_OBJS = \
|
||||
slirp/tcp_timer.o \
|
||||
slirp/tftp.o \
|
||||
slirp/udp.o \
|
||||
slirp/udp6.o \
|
||||
slirp/util.o
|
||||
|
||||
BX_INCDIRS = -I.. -I../.. -I$(srcdir)/.. -I$(srcdir)/../.. -I../../@INSTRUMENT_DIR@ -I$(srcdir)/../../@INSTRUMENT_DIR@
|
||||
@ -230,118 +237,161 @@ pcipnic.o: pcipnic.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||
slirp/arp_table.o: slirp/arp_table.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/bootp.o: slirp/bootp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/cksum.o: slirp/cksum.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/dhcpv6.o: slirp/dhcpv6.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h slirp/dhcpv6.h
|
||||
slirp/dnssearch.o: slirp/dnssearch.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/if.o: slirp/if.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip6_icmp.o: slirp/ip6_icmp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip6_input.o: slirp/ip6_input.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip6_output.o: slirp/ip6_output.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip_icmp.o: slirp/ip_icmp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip_input.o: slirp/ip_input.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip_output.o: slirp/ip_output.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/mbuf.o: slirp/mbuf.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/misc.o: slirp/misc.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ncsi.o: slirp/ncsi.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h slirp/ncsi-pkt.h
|
||||
slirp/ndp_table.o: slirp/ndp_table.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/sbuf.o: slirp/sbuf.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/slirp.o: slirp/slirp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/socket.o: slirp/socket.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_input.o: slirp/tcp_input.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_output.o: slirp/tcp_output.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_subr.o: slirp/tcp_subr.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_timer.o: slirp/tcp_timer.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tftp.o: slirp/tftp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/udp6.o: slirp/udp6.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h slirp/dhcpv6.h
|
||||
slirp/udp.o: slirp/udp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/util.o: slirp/util.@CPP_SUFFIX@ ../../config.h slirp/util.h slirp/libslirp.h
|
||||
slirp/util.o: slirp/util.@CPP_SUFFIX@ ../../config.h slirp/util.h slirp/libslirp.h \
|
||||
slirp/compat.h
|
||||
e1000.lo: e1000.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h ../../osdep.h \
|
||||
../../logio.h ../../misc/bswap.h ../../plugin.h ../../extplugin.h \
|
||||
../../param_names.h ../../pc_system.h ../../bx_debug/debug.h \
|
||||
@ -398,115 +448,158 @@ pcipnic.lo: pcipnic.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||
slirp/arp_table.lo: slirp/arp_table.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/bootp.lo: slirp/bootp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/cksum.lo: slirp/cksum.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/dhcpv6.lo: slirp/dhcpv6.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h slirp/dhcpv6.h
|
||||
slirp/dnssearch.lo: slirp/dnssearch.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/if.lo: slirp/if.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip6_icmp.lo: slirp/ip6_icmp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip6_input.lo: slirp/ip6_input.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip6_output.lo: slirp/ip6_output.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip_icmp.lo: slirp/ip_icmp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip_input.lo: slirp/ip_input.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ip_output.lo: slirp/ip_output.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/mbuf.lo: slirp/mbuf.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/misc.lo: slirp/misc.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/ncsi.lo: slirp/ncsi.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h slirp/ncsi-pkt.h
|
||||
slirp/ndp_table.lo: slirp/ndp_table.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/sbuf.lo: slirp/sbuf.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/slirp.lo: slirp/slirp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/socket.lo: slirp/socket.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_input.lo: slirp/tcp_input.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_output.lo: slirp/tcp_output.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_subr.lo: slirp/tcp_subr.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tcp_timer.lo: slirp/tcp_timer.@CPP_SUFFIX@ slirp/slirp.h ../../config.h \
|
||||
slirp/compat.h slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h \
|
||||
slirp/ip6.h slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h \
|
||||
slirp/udp.h slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/udp.h slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/tftp.lo: slirp/tftp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/udp6.lo: slirp/udp6.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h slirp/dhcpv6.h
|
||||
slirp/udp.lo: slirp/udp.@CPP_SUFFIX@ slirp/slirp.h ../../config.h slirp/compat.h \
|
||||
slirp/debug.h slirp/util.h slirp/libslirp.h slirp/ip.h slirp/ip6.h \
|
||||
slirp/tcp.h slirp/tcp_var.h slirp/tcpip.h slirp/tcp_timer.h slirp/udp.h \
|
||||
slirp/ip_icmp.h slirp/ip6_icmp.h slirp/mbuf.h slirp/sbuf.h \
|
||||
slirp/socket.h slirp/misc.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/socket.h slirp/misc.h slirp/sbuf.h slirp/ip_icmp.h \
|
||||
slirp/ip6_icmp.h slirp/mbuf.h slirp/if.h slirp/main.h slirp/bootp.h \
|
||||
slirp/tftp.h
|
||||
slirp/util.lo: slirp/util.@CPP_SUFFIX@ ../../config.h slirp/util.h slirp/libslirp.h
|
||||
slirp/util.lo: slirp/util.@CPP_SUFFIX@ ../../config.h slirp/util.h slirp/libslirp.h \
|
||||
slirp/compat.h
|
||||
|
@ -34,6 +34,22 @@
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
#ifdef _WIN32
|
||||
/* as defined in sdkddkver.h */
|
||||
#ifdef _WIN32_WINNT
|
||||
#if _WIN32_WINNT < 0x0601
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0601 /* Windows 7 */
|
||||
#endif
|
||||
/* reduces the number of implicitly included headers */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define CPP_STD _MSVC_LANG
|
||||
#else
|
||||
@ -142,7 +158,6 @@ static int64_t clock_get_ns(void *opaque)
|
||||
return bx_pc_system.time_usec() * 1000;
|
||||
}
|
||||
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
struct timer {
|
||||
SlirpTimerId id;
|
||||
void *cb_opaque;
|
||||
@ -195,7 +210,6 @@ static void timer_mod(void *_timer, int64_t expire_time, void *opaque)
|
||||
timer1->next = *t;
|
||||
*t = timer1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int npoll;
|
||||
|
||||
@ -219,16 +233,12 @@ static struct SlirpCb callbacks = {
|
||||
.send_packet = send_packet,
|
||||
.guest_error = guest_error,
|
||||
.clock_get_ns = clock_get_ns,
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
.timer_free = timer_free,
|
||||
.timer_mod = timer_mod,
|
||||
#endif
|
||||
.register_poll_fd = register_poll_fd,
|
||||
.unregister_poll_fd = unregister_poll_fd,
|
||||
.notify = notify,
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
.timer_new_opaque = timer_new_opaque,
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
static struct SlirpCb callbacks;
|
||||
@ -250,16 +260,12 @@ bx_slirp_pktmover_c::bx_slirp_pktmover_c(const char *netif,
|
||||
callbacks.send_packet = send_packet,
|
||||
callbacks.guest_error = guest_error,
|
||||
callbacks.clock_get_ns = clock_get_ns,
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
callbacks.timer_free = timer_free,
|
||||
callbacks.timer_mod = timer_mod,
|
||||
#endif
|
||||
callbacks.register_poll_fd = register_poll_fd,
|
||||
callbacks.unregister_poll_fd = unregister_poll_fd,
|
||||
callbacks.notify = notify,
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
callbacks.timer_new_opaque = timer_new_opaque,
|
||||
#endif
|
||||
#endif
|
||||
/* default settings according to historic slirp */
|
||||
memset(&config, 0, sizeof(config));
|
||||
@ -307,7 +313,6 @@ bx_slirp_pktmover_c::bx_slirp_pktmover_c(const char *netif,
|
||||
if (!parse_slirp_conf(script)) {
|
||||
BX_ERROR(("reading slirp config failed"));
|
||||
}
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
if (config.in6_enabled) {
|
||||
BX_INFO(("IPv6 enabled (using default QEMU settings)"));
|
||||
inet_pton(AF_INET6, "fec0::", &config.vprefix_addr6);
|
||||
@ -317,7 +322,6 @@ bx_slirp_pktmover_c::bx_slirp_pktmover_c(const char *netif,
|
||||
config.vnameserver6 = config.vprefix_addr6;
|
||||
config.vnameserver6.s6_addr[15] |= 3;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
slirplog = new logfunctions();
|
||||
sprintf(prefix, "SLIRP%d", bx_slirp_instances);
|
||||
@ -551,10 +555,8 @@ bool bx_slirp_pktmover_c::parse_slirp_conf(const char *conf)
|
||||
} else {
|
||||
BX_ERROR(("slirp: wrong format for 'pktlog'"));
|
||||
}
|
||||
#if BX_HAVE_LIBSLIRP
|
||||
} else if (!stricmp(param, "ipv6_enabled")) {
|
||||
config.in6_enabled = (atoi(val) != 0);
|
||||
#endif
|
||||
} else if (!stricmp(param, "tftp_srvname")) {
|
||||
if (len2 < 33) {
|
||||
config.tftp_server_name = (char*)malloc(len2+1);
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
#define SLIRP_N_ELEMENTS(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#define slirp_rand_int_range(min, max) ((rand() % (max - min)) + min)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
228
bochs/iodev/network/slirp/dhcpv6.cc
Normal file
228
bochs/iodev/network/slirp/dhcpv6.cc
Normal file
@ -0,0 +1,228 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* SLIRP stateless DHCPv6
|
||||
*
|
||||
* We only support stateless DHCPv6, e.g. for network booting.
|
||||
* See RFC 3315, RFC 3736, RFC 3646 and RFC 5970 for details.
|
||||
*
|
||||
* Copyright 2016 Thomas Huth, Red Hat Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "slirp.h"
|
||||
#include "dhcpv6.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
/* DHCPv6 message types */
|
||||
#define MSGTYPE_REPLY 7
|
||||
#define MSGTYPE_INFO_REQUEST 11
|
||||
|
||||
/* DHCPv6 option types */
|
||||
#define OPTION_CLIENTID 1
|
||||
#define OPTION_IAADDR 5
|
||||
#define OPTION_ORO 6
|
||||
#define OPTION_DNS_SERVERS 23
|
||||
#define OPTION_BOOTFILE_URL 59
|
||||
|
||||
struct requested_infos {
|
||||
uint8_t *client_id;
|
||||
int client_id_len;
|
||||
bool want_dns;
|
||||
bool want_boot_url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Analyze the info request message sent by the client to see what data it
|
||||
* provided and what it wants to have. The information is gathered in the
|
||||
* "requested_infos" struct. Note that client_id (if provided) points into
|
||||
* the odata region, thus the caller must keep odata valid as long as it
|
||||
* needs to access the requested_infos struct.
|
||||
*/
|
||||
static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t *odata, int olen,
|
||||
struct requested_infos *ri)
|
||||
{
|
||||
int i, req_opt;
|
||||
|
||||
while (olen > 4) {
|
||||
/* Parse one option */
|
||||
int option = odata[0] << 8 | odata[1];
|
||||
int len = odata[2] << 8 | odata[3];
|
||||
|
||||
if (len + 4 > olen) {
|
||||
slirp->cb->guest_error("Guest sent bad DHCPv6 packet!",
|
||||
slirp->opaque);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
switch (option) {
|
||||
case OPTION_IAADDR:
|
||||
/* According to RFC3315, we must discard requests with IA option */
|
||||
return -EINVAL;
|
||||
case OPTION_CLIENTID:
|
||||
if (len > 256) {
|
||||
/* Avoid very long IDs which could cause problems later */
|
||||
return -E2BIG;
|
||||
}
|
||||
ri->client_id = odata + 4;
|
||||
ri->client_id_len = len;
|
||||
break;
|
||||
case OPTION_ORO: /* Option request option */
|
||||
if (len & 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Check which options the client wants to have */
|
||||
for (i = 0; i < len; i += 2) {
|
||||
req_opt = odata[4 + i] << 8 | odata[4 + i + 1];
|
||||
switch (req_opt) {
|
||||
case OPTION_DNS_SERVERS:
|
||||
ri->want_dns = true;
|
||||
break;
|
||||
case OPTION_BOOTFILE_URL:
|
||||
ri->want_boot_url = true;
|
||||
break;
|
||||
default:
|
||||
DEBUG_MISC("dhcpv6: Unsupported option request %d",
|
||||
req_opt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEBUG_MISC("dhcpv6 info req: Unsupported option %d, len=%d", option,
|
||||
len);
|
||||
}
|
||||
|
||||
odata += len + 4;
|
||||
olen -= len + 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle information request messages
|
||||
*/
|
||||
static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas,
|
||||
uint32_t xid, uint8_t *odata, int olen)
|
||||
{
|
||||
struct requested_infos ri = { NULL };
|
||||
struct sockaddr_in6 sa6, da6;
|
||||
struct mbuf *m;
|
||||
uint8_t *resp;
|
||||
|
||||
if (dhcpv6_parse_info_request(slirp, odata, olen, &ri) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m = m_get(slirp);
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
memset(m->m_data, 0, m->m_size);
|
||||
m->m_data += IF_MAXLINKHDR;
|
||||
resp = (uint8_t *)m->m_data + sizeof(struct ip6) + sizeof(struct udphdr);
|
||||
|
||||
/* Fill in response */
|
||||
*resp++ = MSGTYPE_REPLY;
|
||||
*resp++ = (uint8_t)(xid >> 16);
|
||||
*resp++ = (uint8_t)(xid >> 8);
|
||||
*resp++ = (uint8_t)xid;
|
||||
|
||||
if (ri.client_id) {
|
||||
*resp++ = OPTION_CLIENTID >> 8; /* option-code high byte */
|
||||
*resp++ = OPTION_CLIENTID; /* option-code low byte */
|
||||
*resp++ = ri.client_id_len >> 8; /* option-len high byte */
|
||||
*resp++ = ri.client_id_len; /* option-len low byte */
|
||||
memcpy(resp, ri.client_id, ri.client_id_len);
|
||||
resp += ri.client_id_len;
|
||||
}
|
||||
if (ri.want_dns) {
|
||||
*resp++ = OPTION_DNS_SERVERS >> 8; /* option-code high byte */
|
||||
*resp++ = OPTION_DNS_SERVERS; /* option-code low byte */
|
||||
*resp++ = 0; /* option-len high byte */
|
||||
*resp++ = 16; /* option-len low byte */
|
||||
memcpy(resp, &slirp->vnameserver_addr6, 16);
|
||||
resp += 16;
|
||||
}
|
||||
if (ri.want_boot_url) {
|
||||
uint8_t *sa = slirp->vhost_addr6.s6_addr;
|
||||
int slen, smaxlen;
|
||||
|
||||
*resp++ = OPTION_BOOTFILE_URL >> 8; /* option-code high byte */
|
||||
*resp++ = OPTION_BOOTFILE_URL; /* option-code low byte */
|
||||
smaxlen = (uint8_t *)m->m_data + slirp->if_mtu - (resp + 2);
|
||||
slen = slirp_fmt((char *)resp + 2, smaxlen,
|
||||
"tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s",
|
||||
sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7],
|
||||
sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14],
|
||||
sa[15], slirp->bootp_filename);
|
||||
*resp++ = slen >> 8; /* option-len high byte */
|
||||
*resp++ = slen; /* option-len low byte */
|
||||
resp += slen;
|
||||
}
|
||||
|
||||
sa6.sin6_addr = slirp->vhost_addr6;
|
||||
sa6.sin6_port = DHCPV6_SERVER_PORT;
|
||||
da6.sin6_addr = srcsas->sin6_addr;
|
||||
da6.sin6_port = srcsas->sin6_port;
|
||||
m->m_data += sizeof(struct ip6) + sizeof(struct udphdr);
|
||||
m->m_len = resp - (uint8_t *)m->m_data;
|
||||
udp6_output(NULL, m, &sa6, &da6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle DHCPv6 messages sent by the client
|
||||
*/
|
||||
void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m)
|
||||
{
|
||||
uint8_t *data = (uint8_t *)m->m_data + sizeof(struct udphdr);
|
||||
int data_len = m->m_len - sizeof(struct udphdr);
|
||||
uint32_t xid;
|
||||
|
||||
if (data_len < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
xid = ntohl(*(uint32_t *)data) & 0xffffff;
|
||||
|
||||
switch (data[0]) {
|
||||
case MSGTYPE_INFO_REQUEST:
|
||||
dhcpv6_info_request(m->slirp, srcsas, xid, &data[4], data_len - 4);
|
||||
break;
|
||||
default:
|
||||
DEBUG_MISC("dhcpv6_input: Unsupported message type 0x%x", data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
67
bochs/iodev/network/slirp/dhcpv6.h
Normal file
67
bochs/iodev/network/slirp/dhcpv6.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Definitions and prototypes for SLIRP stateless DHCPv6
|
||||
*
|
||||
* Copyright 2016 Thomas Huth, Red Hat Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SLIRP_DHCPV6_H
|
||||
#define SLIRP_DHCPV6_H
|
||||
|
||||
#define DHCPV6_SERVER_PORT 547
|
||||
|
||||
const struct in6_addr ALLDHCP_MULTICAST \
|
||||
{ \
|
||||
0xff, \
|
||||
0x02, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x01, \
|
||||
0x00, \
|
||||
0x02 \
|
||||
};
|
||||
|
||||
#define in6_dhcp_multicast(a) in6_equal(a, &ALLDHCP_MULTICAST)
|
||||
|
||||
/* Process a DHCPv6 packet from the guest */
|
||||
void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m);
|
||||
|
||||
#endif
|
@ -29,9 +29,8 @@ const struct in6_addr ALLNODES_MULTICAST = \
|
||||
0x01 \
|
||||
};
|
||||
|
||||
#define SOLICITED_NODE_PREFIX \
|
||||
const struct in6_addr SOLICITED_NODE_PREFIX \
|
||||
{ \
|
||||
.s6_addr = { \
|
||||
0xff, \
|
||||
0x02, \
|
||||
0x00, \
|
||||
@ -48,12 +47,10 @@ const struct in6_addr ALLNODES_MULTICAST = \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x00 \
|
||||
} \
|
||||
}
|
||||
};
|
||||
|
||||
#define LINKLOCAL_ADDR \
|
||||
const struct in6_addr LINKLOCAL_ADDR \
|
||||
{ \
|
||||
.s6_addr = { \
|
||||
0xfe, \
|
||||
0x80, \
|
||||
0x00, \
|
||||
@ -70,8 +67,7 @@ const struct in6_addr ALLNODES_MULTICAST = \
|
||||
0x00, \
|
||||
0x00, \
|
||||
0x02 \
|
||||
} \
|
||||
}
|
||||
};
|
||||
|
||||
const struct in6_addr ZERO_ADDR = \
|
||||
{ \
|
||||
@ -138,14 +134,14 @@ static inline bool in6_equal_mach(const struct in6_addr *a,
|
||||
#define in6_equal_router(a) \
|
||||
((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \
|
||||
in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len)) || \
|
||||
(in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \
|
||||
(in6_equal_net(a, &LINKLOCAL_ADDR, 64) && \
|
||||
in6_equal_mach(a, &slirp->vhost_addr6, 64)))
|
||||
|
||||
/* Check that the IPv6 is equal to the virtual DNS server */
|
||||
#define in6_equal_dns(a) \
|
||||
((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \
|
||||
in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len)) || \
|
||||
(in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \
|
||||
(in6_equal_net(a, &LINKLOCAL_ADDR, 64) && \
|
||||
in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
|
||||
|
||||
/* Check that the IPv6 is equal to the host */
|
||||
@ -153,7 +149,7 @@ static inline bool in6_equal_mach(const struct in6_addr *a,
|
||||
|
||||
/* Check that the IPv6 is within the sollicited node multicast network */
|
||||
#define in6_solicitednode_multicast(a) \
|
||||
(in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
|
||||
(in6_equal_net(a, &SOLICITED_NODE_PREFIX, 104))
|
||||
|
||||
/* Check that the IPv6 is zero */
|
||||
#define in6_zero(a) (in6_equal(a, &ZERO_ADDR))
|
||||
|
447
bochs/iodev/network/slirp/ip6_icmp.cc
Normal file
447
bochs/iodev/network/slirp/ip6_icmp.cc
Normal file
@ -0,0 +1,447 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
|
||||
*/
|
||||
|
||||
#include "slirp.h"
|
||||
#include "ip6_icmp.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
#define NDP_Interval \
|
||||
slirp_rand_int_range(NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval)
|
||||
|
||||
void icmp6_post_init(Slirp *slirp)
|
||||
{
|
||||
if (!slirp->in6_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
slirp->ra_timer =
|
||||
slirp_timer_new(slirp, SLIRP_TIMER_RA, NULL);
|
||||
slirp->cb->timer_mod(slirp->ra_timer,
|
||||
slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS +
|
||||
NDP_Interval,
|
||||
slirp->opaque);
|
||||
}
|
||||
|
||||
void icmp6_cleanup(Slirp *slirp)
|
||||
{
|
||||
if (!slirp->in6_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
slirp->cb->timer_free(slirp->ra_timer, slirp->opaque);
|
||||
}
|
||||
|
||||
static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
|
||||
struct icmp6 *icmp)
|
||||
{
|
||||
struct mbuf *t = m_get(slirp);
|
||||
t->m_len = sizeof(struct ip6) + ntohs(ip->ip_pl);
|
||||
memcpy(t->m_data, m->m_data, t->m_len);
|
||||
|
||||
/* IPv6 Packet */
|
||||
struct ip6 *rip = mtod(t, struct ip6 *);
|
||||
rip->ip_dst = ip->ip_src;
|
||||
rip->ip_src = ip->ip_dst;
|
||||
|
||||
/* ICMPv6 packet */
|
||||
t->m_data += sizeof(struct ip6);
|
||||
struct icmp6 *ricmp = mtod(t, struct icmp6 *);
|
||||
ricmp->icmp6_type = ICMP6_ECHO_REPLY;
|
||||
ricmp->icmp6_cksum = 0;
|
||||
|
||||
/* Checksum */
|
||||
t->m_data -= sizeof(struct ip6);
|
||||
ricmp->icmp6_cksum = ip6_cksum(t);
|
||||
|
||||
ip6_output(NULL, t, 0);
|
||||
}
|
||||
|
||||
void icmp6_forward_error(struct mbuf *m, uint8_t type, uint8_t code, struct in6_addr *src)
|
||||
{
|
||||
Slirp *slirp = m->slirp;
|
||||
struct mbuf *t;
|
||||
struct ip6 *ip = mtod(m, struct ip6 *);
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
|
||||
DEBUG_CALL("icmp6_send_error");
|
||||
DEBUG_ARG("type = %d, code = %d", type, code);
|
||||
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip->ip_src) || in6_zero(&ip->ip_src)) {
|
||||
/* TODO icmp error? */
|
||||
return;
|
||||
}
|
||||
|
||||
t = m_get(slirp);
|
||||
|
||||
/* IPv6 packet */
|
||||
struct ip6 *rip = mtod(t, struct ip6 *);
|
||||
rip->ip_src = *src;
|
||||
rip->ip_dst = ip->ip_src;
|
||||
inet_ntop(AF_INET6, &rip->ip_dst, addrstr, INET6_ADDRSTRLEN);
|
||||
DEBUG_ARG("target = %s", addrstr);
|
||||
|
||||
rip->ip_nh = IPPROTO_ICMPV6;
|
||||
const int error_data_len = MIN(
|
||||
m->m_len, (int)(slirp->if_mtu - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN)));
|
||||
rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len);
|
||||
t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
|
||||
|
||||
/* ICMPv6 packet */
|
||||
t->m_data += sizeof(struct ip6);
|
||||
struct icmp6 *ricmp = mtod(t, struct icmp6 *);
|
||||
ricmp->icmp6_type = type;
|
||||
ricmp->icmp6_code = code;
|
||||
ricmp->icmp6_cksum = 0;
|
||||
|
||||
switch (type) {
|
||||
case ICMP6_UNREACH:
|
||||
case ICMP6_TIMXCEED:
|
||||
ricmp->icmp6_err.unused = 0;
|
||||
break;
|
||||
case ICMP6_TOOBIG:
|
||||
ricmp->icmp6_err.mtu = htonl(slirp->if_mtu);
|
||||
break;
|
||||
case ICMP6_PARAMPROB:
|
||||
/* TODO: Handle this case */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown ICMP code\n");
|
||||
}
|
||||
t->m_data += ICMP6_ERROR_MINLEN;
|
||||
memcpy(t->m_data, m->m_data, error_data_len);
|
||||
|
||||
/* Checksum */
|
||||
t->m_data -= ICMP6_ERROR_MINLEN;
|
||||
t->m_data -= sizeof(struct ip6);
|
||||
ricmp->icmp6_cksum = ip6_cksum(t);
|
||||
|
||||
ip6_output(NULL, t, 0);
|
||||
}
|
||||
|
||||
void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
|
||||
{
|
||||
struct in6_addr src = LINKLOCAL_ADDR;
|
||||
icmp6_forward_error(m, type, code, &src);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send NDP Router Advertisement
|
||||
*/
|
||||
static void ndp_send_ra(Slirp *slirp)
|
||||
{
|
||||
DEBUG_CALL("ndp_send_ra");
|
||||
|
||||
/* Build IPv6 packet */
|
||||
struct mbuf *t = m_get(slirp);
|
||||
struct ip6 *rip = mtod(t, struct ip6 *);
|
||||
size_t pl_size = 0;
|
||||
struct in6_addr addr;
|
||||
uint32_t scope_id;
|
||||
|
||||
rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
|
||||
rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
|
||||
rip->ip_nh = IPPROTO_ICMPV6;
|
||||
|
||||
/* Build ICMPv6 packet */
|
||||
t->m_data += sizeof(struct ip6);
|
||||
struct icmp6 *ricmp = mtod(t, struct icmp6 *);
|
||||
ricmp->icmp6_type = ICMP6_NDP_RA;
|
||||
ricmp->icmp6_code = 0;
|
||||
ricmp->icmp6_cksum = 0;
|
||||
|
||||
/* NDP */
|
||||
ricmp->icmp6_nra.chl = NDP_AdvCurHopLimit;
|
||||
ricmp->icmp6_nra.M = NDP_AdvManagedFlag;
|
||||
ricmp->icmp6_nra.O = NDP_AdvOtherConfigFlag;
|
||||
ricmp->icmp6_nra.reserved = 0;
|
||||
ricmp->icmp6_nra.lifetime = htons(NDP_AdvDefaultLifetime);
|
||||
ricmp->icmp6_nra.reach_time = htonl(NDP_AdvReachableTime);
|
||||
ricmp->icmp6_nra.retrans_time = htonl(NDP_AdvRetransTime);
|
||||
t->m_data += ICMP6_NDP_RA_MINLEN;
|
||||
pl_size += ICMP6_NDP_RA_MINLEN;
|
||||
|
||||
/* Source link-layer address (NDP option) */
|
||||
struct ndpopt *opt = mtod(t, struct ndpopt *);
|
||||
opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE;
|
||||
opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
|
||||
in6_compute_ethaddr(rip->ip_src, opt->ndpopt_linklayer);
|
||||
t->m_data += NDPOPT_LINKLAYER_LEN;
|
||||
pl_size += NDPOPT_LINKLAYER_LEN;
|
||||
|
||||
/* Prefix information (NDP option) */
|
||||
struct ndpopt *opt2 = mtod(t, struct ndpopt *);
|
||||
opt2->ndpopt_type = NDPOPT_PREFIX_INFO;
|
||||
opt2->ndpopt_len = NDPOPT_PREFIXINFO_LEN / 8;
|
||||
opt2->ndpopt_prefixinfo.prefix_length = slirp->vprefix_len;
|
||||
opt2->ndpopt_prefixinfo.L = 1;
|
||||
opt2->ndpopt_prefixinfo.A = 1;
|
||||
opt2->ndpopt_prefixinfo.reserved1 = 0;
|
||||
opt2->ndpopt_prefixinfo.valid_lt = htonl(NDP_AdvValidLifetime);
|
||||
opt2->ndpopt_prefixinfo.pref_lt = htonl(NDP_AdvPrefLifetime);
|
||||
opt2->ndpopt_prefixinfo.reserved2 = 0;
|
||||
opt2->ndpopt_prefixinfo.prefix = slirp->vprefix_addr6;
|
||||
t->m_data += NDPOPT_PREFIXINFO_LEN;
|
||||
pl_size += NDPOPT_PREFIXINFO_LEN;
|
||||
|
||||
/* Prefix information (NDP option) */
|
||||
if (get_dns6_addr(&addr, &scope_id) >= 0) {
|
||||
/* Host system does have an IPv6 DNS server, announce our proxy. */
|
||||
struct ndpopt *opt3 = mtod(t, struct ndpopt *);
|
||||
opt3->ndpopt_type = NDPOPT_RDNSS;
|
||||
opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8;
|
||||
opt3->ndpopt_rdnss.reserved = 0;
|
||||
opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
|
||||
opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
|
||||
t->m_data += NDPOPT_RDNSS_LEN;
|
||||
pl_size += NDPOPT_RDNSS_LEN;
|
||||
}
|
||||
|
||||
rip->ip_pl = htons(pl_size);
|
||||
t->m_data -= sizeof(struct ip6) + pl_size;
|
||||
t->m_len = sizeof(struct ip6) + pl_size;
|
||||
|
||||
/* ICMPv6 Checksum */
|
||||
ricmp->icmp6_cksum = ip6_cksum(t);
|
||||
|
||||
ip6_output(NULL, t, 0);
|
||||
}
|
||||
|
||||
void ra_timer_handler(Slirp *slirp, void *unused)
|
||||
{
|
||||
slirp->cb->timer_mod(slirp->ra_timer,
|
||||
slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS +
|
||||
NDP_Interval,
|
||||
slirp->opaque);
|
||||
ndp_send_ra(slirp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send NDP Neighbor Solitication
|
||||
*/
|
||||
void ndp_send_ns(Slirp *slirp, struct in6_addr addr)
|
||||
{
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
|
||||
inet_ntop(AF_INET6, &addr, addrstr, INET6_ADDRSTRLEN);
|
||||
|
||||
DEBUG_CALL("ndp_send_ns");
|
||||
DEBUG_ARG("target = %s", addrstr);
|
||||
|
||||
/* Build IPv6 packet */
|
||||
struct mbuf *t = m_get(slirp);
|
||||
struct ip6 *rip = mtod(t, struct ip6 *);
|
||||
rip->ip_src = slirp->vhost_addr6;
|
||||
rip->ip_dst = (struct in6_addr)SOLICITED_NODE_PREFIX;
|
||||
memcpy(&rip->ip_dst.s6_addr[13], &addr.s6_addr[13], 3);
|
||||
rip->ip_nh = IPPROTO_ICMPV6;
|
||||
rip->ip_pl = htons(ICMP6_NDP_NS_MINLEN + NDPOPT_LINKLAYER_LEN);
|
||||
t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
|
||||
|
||||
/* Build ICMPv6 packet */
|
||||
t->m_data += sizeof(struct ip6);
|
||||
struct icmp6 *ricmp = mtod(t, struct icmp6 *);
|
||||
ricmp->icmp6_type = ICMP6_NDP_NS;
|
||||
ricmp->icmp6_code = 0;
|
||||
ricmp->icmp6_cksum = 0;
|
||||
|
||||
/* NDP */
|
||||
ricmp->icmp6_nns.reserved = 0;
|
||||
ricmp->icmp6_nns.target = addr;
|
||||
|
||||
/* Build NDP option */
|
||||
t->m_data += ICMP6_NDP_NS_MINLEN;
|
||||
struct ndpopt *opt = mtod(t, struct ndpopt *);
|
||||
opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE;
|
||||
opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
|
||||
in6_compute_ethaddr(slirp->vhost_addr6, opt->ndpopt_linklayer);
|
||||
|
||||
/* ICMPv6 Checksum */
|
||||
t->m_data -= ICMP6_NDP_NA_MINLEN;
|
||||
t->m_data -= sizeof(struct ip6);
|
||||
ricmp->icmp6_cksum = ip6_cksum(t);
|
||||
|
||||
ip6_output(NULL, t, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send NDP Neighbor Advertisement
|
||||
*/
|
||||
static void ndp_send_na(Slirp *slirp, struct ip6 *ip, struct icmp6 *icmp)
|
||||
{
|
||||
/* Build IPv6 packet */
|
||||
struct mbuf *t = m_get(slirp);
|
||||
struct ip6 *rip = mtod(t, struct ip6 *);
|
||||
rip->ip_src = icmp->icmp6_nns.target;
|
||||
if (in6_zero(&ip->ip_src)) {
|
||||
rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
|
||||
} else {
|
||||
rip->ip_dst = ip->ip_src;
|
||||
}
|
||||
rip->ip_nh = IPPROTO_ICMPV6;
|
||||
rip->ip_pl = htons(ICMP6_NDP_NA_MINLEN + NDPOPT_LINKLAYER_LEN);
|
||||
t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
|
||||
|
||||
/* Build ICMPv6 packet */
|
||||
t->m_data += sizeof(struct ip6);
|
||||
struct icmp6 *ricmp = mtod(t, struct icmp6 *);
|
||||
ricmp->icmp6_type = ICMP6_NDP_NA;
|
||||
ricmp->icmp6_code = 0;
|
||||
ricmp->icmp6_cksum = 0;
|
||||
|
||||
/* NDP */
|
||||
ricmp->icmp6_nna.R = NDP_IsRouter;
|
||||
ricmp->icmp6_nna.S = !IN6_IS_ADDR_MULTICAST(&rip->ip_dst);
|
||||
ricmp->icmp6_nna.O = 1;
|
||||
ricmp->icmp6_nna.reserved_1 = 0;
|
||||
ricmp->icmp6_nna.reserved_2 = 0;
|
||||
ricmp->icmp6_nna.reserved_3 = 0;
|
||||
ricmp->icmp6_nna.target = icmp->icmp6_nns.target;
|
||||
|
||||
/* Build NDP option */
|
||||
t->m_data += ICMP6_NDP_NA_MINLEN;
|
||||
struct ndpopt *opt = mtod(t, struct ndpopt *);
|
||||
opt->ndpopt_type = NDPOPT_LINKLAYER_TARGET;
|
||||
opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
|
||||
in6_compute_ethaddr(ricmp->icmp6_nna.target, opt->ndpopt_linklayer);
|
||||
|
||||
/* ICMPv6 Checksum */
|
||||
t->m_data -= ICMP6_NDP_NA_MINLEN;
|
||||
t->m_data -= sizeof(struct ip6);
|
||||
ricmp->icmp6_cksum = ip6_cksum(t);
|
||||
|
||||
ip6_output(NULL, t, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a NDP message
|
||||
*/
|
||||
static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
|
||||
struct icmp6 *icmp)
|
||||
{
|
||||
assert(M_ROOMBEFORE(m) >= ETH_HLEN);
|
||||
|
||||
m->m_len += ETH_HLEN;
|
||||
m->m_data -= ETH_HLEN;
|
||||
struct ethhdr *eth = mtod(m, struct ethhdr *);
|
||||
m->m_len -= ETH_HLEN;
|
||||
m->m_data += ETH_HLEN;
|
||||
|
||||
switch (icmp->icmp6_type) {
|
||||
case ICMP6_NDP_RS:
|
||||
DEBUG_CALL(" type = Router Solicitation");
|
||||
if (ip->ip_hl == 255 && icmp->icmp6_code == 0 &&
|
||||
ntohs(ip->ip_pl) >= ICMP6_NDP_RS_MINLEN) {
|
||||
/* Gratuitous NDP */
|
||||
ndp_table_add(slirp, ip->ip_src, eth->h_source);
|
||||
|
||||
ndp_send_ra(slirp);
|
||||
}
|
||||
break;
|
||||
|
||||
case ICMP6_NDP_RA:
|
||||
DEBUG_CALL(" type = Router Advertisement");
|
||||
slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't",
|
||||
slirp->opaque);
|
||||
break;
|
||||
|
||||
case ICMP6_NDP_NS:
|
||||
DEBUG_CALL(" type = Neighbor Solicitation");
|
||||
if (ip->ip_hl == 255 && icmp->icmp6_code == 0 &&
|
||||
!IN6_IS_ADDR_MULTICAST(&icmp->icmp6_nns.target) &&
|
||||
ntohs(ip->ip_pl) >= ICMP6_NDP_NS_MINLEN &&
|
||||
(!in6_zero(&ip->ip_src) ||
|
||||
in6_solicitednode_multicast(&ip->ip_dst))) {
|
||||
if (in6_equal_host(&icmp->icmp6_nns.target)) {
|
||||
/* Gratuitous NDP */
|
||||
ndp_table_add(slirp, ip->ip_src, eth->h_source);
|
||||
ndp_send_na(slirp, ip, icmp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ICMP6_NDP_NA:
|
||||
DEBUG_CALL(" type = Neighbor Advertisement");
|
||||
if (ip->ip_hl == 255 && icmp->icmp6_code == 0 &&
|
||||
ntohs(ip->ip_pl) >= ICMP6_NDP_NA_MINLEN &&
|
||||
!IN6_IS_ADDR_MULTICAST(&icmp->icmp6_nna.target) &&
|
||||
(!IN6_IS_ADDR_MULTICAST(&ip->ip_dst) || icmp->icmp6_nna.S == 0)) {
|
||||
ndp_table_add(slirp, icmp->icmp6_nna.target, eth->h_source);
|
||||
}
|
||||
break;
|
||||
|
||||
case ICMP6_NDP_REDIRECT:
|
||||
DEBUG_CALL(" type = Redirect");
|
||||
slirp->cb->guest_error(
|
||||
"Warning: guest sent NDP REDIRECT, but shouldn't", slirp->opaque);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a received ICMPv6 message.
|
||||
*/
|
||||
void icmp6_input(struct mbuf *m)
|
||||
{
|
||||
Slirp *slirp = m->slirp;
|
||||
/* NDP reads the ethernet header for gratuitous NDP */
|
||||
M_DUP_DEBUG(slirp, m, 1, ETH_HLEN);
|
||||
|
||||
struct icmp6 *icmp;
|
||||
struct ip6 *ip = mtod(m, struct ip6 *);
|
||||
int hlen = sizeof(struct ip6);
|
||||
|
||||
DEBUG_CALL("icmp6_input");
|
||||
DEBUG_ARG("m = %p", m);
|
||||
DEBUG_ARG("m_len = %d", m->m_len);
|
||||
|
||||
if (ntohs(ip->ip_pl) < ICMP6_MINLEN) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ip6_cksum(m)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
m->m_len -= hlen;
|
||||
m->m_data += hlen;
|
||||
icmp = mtod(m, struct icmp6 *);
|
||||
m->m_len += hlen;
|
||||
m->m_data -= hlen;
|
||||
|
||||
DEBUG_ARG("icmp6_type = %d", icmp->icmp6_type);
|
||||
switch (icmp->icmp6_type) {
|
||||
case ICMP6_ECHO_REQUEST:
|
||||
if (in6_equal_host(&ip->ip_dst)) {
|
||||
icmp6_send_echoreply(m, slirp, ip, icmp);
|
||||
} else {
|
||||
/* TODO */
|
||||
fprintf(stderr, "external icmpv6 not supported yet\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case ICMP6_NDP_RS:
|
||||
case ICMP6_NDP_RA:
|
||||
case ICMP6_NDP_NS:
|
||||
case ICMP6_NDP_NA:
|
||||
case ICMP6_NDP_REDIRECT:
|
||||
ndp_input(m, slirp, ip, icmp);
|
||||
break;
|
||||
|
||||
case ICMP6_UNREACH:
|
||||
case ICMP6_TOOBIG:
|
||||
case ICMP6_TIMXCEED:
|
||||
case ICMP6_PARAMPROB:
|
||||
/* XXX? report error? close socket? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
m_free(m);
|
||||
}
|
||||
|
||||
#endif
|
92
bochs/iodev/network/slirp/ip6_input.cc
Normal file
92
bochs/iodev/network/slirp/ip6_input.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
|
||||
*/
|
||||
|
||||
#include "slirp.h"
|
||||
#include "ip6_icmp.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
/*
|
||||
* IP initialization: fill in IP protocol switch table.
|
||||
* All protocols not implemented in kernel go to raw IP protocol handler.
|
||||
*/
|
||||
void ip6_post_init(Slirp *slirp)
|
||||
{
|
||||
icmp6_post_init(slirp);
|
||||
}
|
||||
|
||||
void ip6_cleanup(Slirp *slirp)
|
||||
{
|
||||
icmp6_cleanup(slirp);
|
||||
}
|
||||
|
||||
void ip6_input(struct mbuf *m)
|
||||
{
|
||||
Slirp *slirp = m->slirp;
|
||||
/* NDP reads the ethernet header for gratuitous NDP */
|
||||
M_DUP_DEBUG(slirp, m, 1, TCPIPHDR_DELTA + 2 + ETH_HLEN);
|
||||
|
||||
struct ip6 *ip6;
|
||||
|
||||
if (!slirp->in6_enabled) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
DEBUG_CALL("ip6_input");
|
||||
DEBUG_ARG("m = %p", m);
|
||||
DEBUG_ARG("m_len = %d", m->m_len);
|
||||
|
||||
if (m->m_len < sizeof(struct ip6)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ip6 = mtod(m, struct ip6 *);
|
||||
|
||||
if (ip6->ip_v != IP6VERSION) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (ntohs(ip6->ip_pl) + sizeof(struct ip6) > slirp->if_mtu) {
|
||||
icmp6_send_error(m, ICMP6_TOOBIG, 0);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
// Check if the message size is big enough to hold what's
|
||||
// set in the payload length header. If not this is an invalid
|
||||
// packet
|
||||
if (m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* check ip_ttl for a correct ICMP reply */
|
||||
if (ip6->ip_hl == 0) {
|
||||
icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch out to protocol's input routine.
|
||||
*/
|
||||
switch (ip6->ip_nh) {
|
||||
case IPPROTO_TCP:
|
||||
NTOHS(ip6->ip_pl);
|
||||
tcp_input(m, sizeof(struct ip6), (struct socket *)NULL, AF_INET6);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
udp6_input(m);
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
icmp6_input(m);
|
||||
break;
|
||||
default:
|
||||
m_free(m);
|
||||
}
|
||||
return;
|
||||
bad:
|
||||
m_free(m);
|
||||
}
|
||||
|
||||
#endif
|
49
bochs/iodev/network/slirp/ip6_output.cc
Normal file
49
bochs/iodev/network/slirp/ip6_output.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
|
||||
*/
|
||||
|
||||
#include "slirp.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
/* Number of packets queued before we start sending
|
||||
* (to prevent allocing too many mbufs) */
|
||||
#define IF6_THRESH 10
|
||||
|
||||
/*
|
||||
* IPv6 output. The packet in mbuf chain m contains a IP header
|
||||
*/
|
||||
int ip6_output(struct socket *so, struct mbuf *m, int fast)
|
||||
{
|
||||
Slirp *slirp = m->slirp;
|
||||
M_DUP_DEBUG(slirp, m, 0, 0);
|
||||
|
||||
struct ip6 *ip = mtod(m, struct ip6 *);
|
||||
|
||||
DEBUG_CALL("ip6_output");
|
||||
DEBUG_ARG("so = %p", so);
|
||||
DEBUG_ARG("m = %p", m);
|
||||
|
||||
/* Fill IPv6 header */
|
||||
ip->ip_v = IP6VERSION;
|
||||
ip->ip_hl = IP6_HOP_LIMIT;
|
||||
ip->ip_tc_hi = 0;
|
||||
ip->ip_tc_lo = 0;
|
||||
ip->ip_fl_hi = 0;
|
||||
ip->ip_fl_lo = 0;
|
||||
|
||||
if (fast) {
|
||||
/* We cannot fast-send non-multicast, we'd need a NDP NS */
|
||||
assert(IN6_IS_ADDR_MULTICAST(&ip->ip_dst));
|
||||
if_encap(m->slirp, m);
|
||||
m_free(m);
|
||||
} else {
|
||||
if_output(so, m);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
527
bochs/iodev/network/slirp/ncsi-pkt.h
Normal file
527
bochs/iodev/network/slirp/ncsi-pkt.h
Normal file
@ -0,0 +1,527 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright Gavin Shan, IBM Corporation 2016.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef NCSI_PKT_H
|
||||
#define NCSI_PKT_H
|
||||
|
||||
/* from linux/net/ncsi/ncsi-pkt.h */
|
||||
#define __be32 uint32_t
|
||||
#define __be16 uint16_t
|
||||
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_pkt_hdr {
|
||||
unsigned char mc_id; /* Management controller ID */
|
||||
unsigned char revision; /* NCSI version - 0x01 */
|
||||
unsigned char reserved; /* Reserved */
|
||||
unsigned char id; /* Packet sequence number */
|
||||
unsigned char type; /* Packet type */
|
||||
unsigned char channel; /* Network controller ID */
|
||||
__be16 length; /* Payload length */
|
||||
__be32 reserved1[2]; /* Reserved */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_pkt_hdr {
|
||||
struct ncsi_pkt_hdr common; /* Common NCSI packet header */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_pkt_hdr {
|
||||
struct ncsi_pkt_hdr common; /* Common NCSI packet header */
|
||||
__be16 code; /* Response code */
|
||||
__be16 reason; /* Response reason */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_aen_pkt_hdr {
|
||||
struct ncsi_pkt_hdr common; /* Common NCSI packet header */
|
||||
unsigned char reserved2[3]; /* Reserved */
|
||||
unsigned char type; /* AEN packet type */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* NCSI common command packet */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[26];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Select Package */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_sp_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
unsigned char reserved[3]; /* Reserved */
|
||||
unsigned char hw_arbitration; /* HW arbitration */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Disable Channel */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_dc_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
unsigned char reserved[3]; /* Reserved */
|
||||
unsigned char ald; /* Allow link down */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Reset Channel */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_rc_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be32 reserved; /* Reserved */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* AEN Enable */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_ae_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
unsigned char reserved[3]; /* Reserved */
|
||||
unsigned char mc_id; /* MC ID */
|
||||
__be32 mode; /* AEN working mode */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[18];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Set Link */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_sl_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be32 mode; /* Link working mode */
|
||||
__be32 oem_mode; /* OEM link mode */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[18];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Set VLAN Filter */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_svf_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be16 reserved; /* Reserved */
|
||||
__be16 vlan; /* VLAN ID */
|
||||
__be16 reserved1; /* Reserved */
|
||||
unsigned char index; /* VLAN table index */
|
||||
unsigned char enable; /* Enable or disable */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[14];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Enable VLAN */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_ev_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
unsigned char reserved[3]; /* Reserved */
|
||||
unsigned char mode; /* VLAN filter mode */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Set MAC Address */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_sma_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
unsigned char mac[6]; /* MAC address */
|
||||
unsigned char index; /* MAC table index */
|
||||
unsigned char at_e; /* Addr type and operation */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[18];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Enable Broadcast Filter */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_ebf_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be32 mode; /* Filter mode */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Enable Global Multicast Filter */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_egmf_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be32 mode; /* Global MC mode */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Set NCSI Flow Control */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_snfc_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
unsigned char reserved[3]; /* Reserved */
|
||||
unsigned char mode; /* Flow control mode */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* OEM Request Command as per NCSI Specification */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_cmd_oem_pkt {
|
||||
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
|
||||
__be32 mfr_id; /* Manufacture ID */
|
||||
unsigned char data[]; /* OEM Payload Data */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* OEM Response Packet as per NCSI Specification */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_oem_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Command header */
|
||||
__be32 mfr_id; /* Manufacture ID */
|
||||
unsigned char data[]; /* Payload data */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Mellanox Response Data */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_oem_mlx_pkt {
|
||||
unsigned char cmd_rev; /* Command Revision */
|
||||
unsigned char cmd; /* Command ID */
|
||||
unsigned char param; /* Parameter */
|
||||
unsigned char optional; /* Optional data */
|
||||
unsigned char data[]; /* Data */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get Link Status */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gls_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 status; /* Link status */
|
||||
__be32 other; /* Other indications */
|
||||
__be32 oem_status; /* OEM link status */
|
||||
__be32 checksum;
|
||||
unsigned char pad[10];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get Version ID */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gvi_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 ncsi_version; /* NCSI version */
|
||||
unsigned char reserved[3]; /* Reserved */
|
||||
unsigned char alpha2; /* NCSI version */
|
||||
unsigned char fw_name[12]; /* f/w name string */
|
||||
__be32 fw_version; /* f/w version */
|
||||
__be16 pci_ids[4]; /* PCI IDs */
|
||||
__be32 mf_id; /* Manufacture ID */
|
||||
__be32 checksum;
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get Capabilities */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gc_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 cap; /* Capabilities */
|
||||
__be32 bc_cap; /* Broadcast cap */
|
||||
__be32 mc_cap; /* Multicast cap */
|
||||
__be32 buf_cap; /* Buffering cap */
|
||||
__be32 aen_cap; /* AEN cap */
|
||||
unsigned char vlan_cnt; /* VLAN filter count */
|
||||
unsigned char mixed_cnt; /* Mix filter count */
|
||||
unsigned char mc_cnt; /* MC filter count */
|
||||
unsigned char uc_cnt; /* UC filter count */
|
||||
unsigned char reserved[2]; /* Reserved */
|
||||
unsigned char vlan_mode; /* VLAN mode */
|
||||
unsigned char channel_cnt; /* Channel count */
|
||||
__be32 checksum; /* Checksum */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get Parameters */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gp_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
unsigned char mac_cnt; /* Number of MAC addr */
|
||||
unsigned char reserved[2]; /* Reserved */
|
||||
unsigned char mac_enable; /* MAC addr enable flags */
|
||||
unsigned char vlan_cnt; /* VLAN tag count */
|
||||
unsigned char reserved1; /* Reserved */
|
||||
__be16 vlan_enable; /* VLAN tag enable flags */
|
||||
__be32 link_mode; /* Link setting */
|
||||
__be32 bc_mode; /* BC filter mode */
|
||||
__be32 valid_modes; /* Valid mode parameters */
|
||||
unsigned char vlan_mode; /* VLAN mode */
|
||||
unsigned char fc_mode; /* Flow control mode */
|
||||
unsigned char reserved2[2]; /* Reserved */
|
||||
__be32 aen_mode; /* AEN mode */
|
||||
unsigned char mac[6]; /* Supported MAC addr */
|
||||
__be16 vlan; /* Supported VLAN tags */
|
||||
__be32 checksum; /* Checksum */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get Controller Packet Statistics */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gcps_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 cnt_hi; /* Counter cleared */
|
||||
__be32 cnt_lo; /* Counter cleared */
|
||||
__be32 rx_bytes; /* Rx bytes */
|
||||
__be32 tx_bytes; /* Tx bytes */
|
||||
__be32 rx_uc_pkts; /* Rx UC packets */
|
||||
__be32 rx_mc_pkts; /* Rx MC packets */
|
||||
__be32 rx_bc_pkts; /* Rx BC packets */
|
||||
__be32 tx_uc_pkts; /* Tx UC packets */
|
||||
__be32 tx_mc_pkts; /* Tx MC packets */
|
||||
__be32 tx_bc_pkts; /* Tx BC packets */
|
||||
__be32 fcs_err; /* FCS errors */
|
||||
__be32 align_err; /* Alignment errors */
|
||||
__be32 false_carrier; /* False carrier detection */
|
||||
__be32 runt_pkts; /* Rx runt packets */
|
||||
__be32 jabber_pkts; /* Rx jabber packets */
|
||||
__be32 rx_pause_xon; /* Rx pause XON frames */
|
||||
__be32 rx_pause_xoff; /* Rx XOFF frames */
|
||||
__be32 tx_pause_xon; /* Tx XON frames */
|
||||
__be32 tx_pause_xoff; /* Tx XOFF frames */
|
||||
__be32 tx_s_collision; /* Single collision frames */
|
||||
__be32 tx_m_collision; /* Multiple collision frames */
|
||||
__be32 l_collision; /* Late collision frames */
|
||||
__be32 e_collision; /* Excessive collision frames */
|
||||
__be32 rx_ctl_frames; /* Rx control frames */
|
||||
__be32 rx_64_frames; /* Rx 64-bytes frames */
|
||||
__be32 rx_127_frames; /* Rx 65-127 bytes frames */
|
||||
__be32 rx_255_frames; /* Rx 128-255 bytes frames */
|
||||
__be32 rx_511_frames; /* Rx 256-511 bytes frames */
|
||||
__be32 rx_1023_frames; /* Rx 512-1023 bytes frames */
|
||||
__be32 rx_1522_frames; /* Rx 1024-1522 bytes frames */
|
||||
__be32 rx_9022_frames; /* Rx 1523-9022 bytes frames */
|
||||
__be32 tx_64_frames; /* Tx 64-bytes frames */
|
||||
__be32 tx_127_frames; /* Tx 65-127 bytes frames */
|
||||
__be32 tx_255_frames; /* Tx 128-255 bytes frames */
|
||||
__be32 tx_511_frames; /* Tx 256-511 bytes frames */
|
||||
__be32 tx_1023_frames; /* Tx 512-1023 bytes frames */
|
||||
__be32 tx_1522_frames; /* Tx 1024-1522 bytes frames */
|
||||
__be32 tx_9022_frames; /* Tx 1523-9022 bytes frames */
|
||||
__be32 rx_valid_bytes; /* Rx valid bytes */
|
||||
__be32 rx_runt_pkts; /* Rx error runt packets */
|
||||
__be32 rx_jabber_pkts; /* Rx error jabber packets */
|
||||
__be32 checksum; /* Checksum */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get NCSI Statistics */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gns_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 rx_cmds; /* Rx NCSI commands */
|
||||
__be32 dropped_cmds; /* Dropped commands */
|
||||
__be32 cmd_type_errs; /* Command type errors */
|
||||
__be32 cmd_csum_errs; /* Command checksum errors */
|
||||
__be32 rx_pkts; /* Rx NCSI packets */
|
||||
__be32 tx_pkts; /* Tx NCSI packets */
|
||||
__be32 tx_aen_pkts; /* Tx AEN packets */
|
||||
__be32 checksum; /* Checksum */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get NCSI Pass-through Statistics */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gnpts_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 tx_pkts; /* Tx packets */
|
||||
__be32 tx_dropped; /* Tx dropped packets */
|
||||
__be32 tx_channel_err; /* Tx channel errors */
|
||||
__be32 tx_us_err; /* Tx undersize errors */
|
||||
__be32 rx_pkts; /* Rx packets */
|
||||
__be32 rx_dropped; /* Rx dropped packets */
|
||||
__be32 rx_channel_err; /* Rx channel errors */
|
||||
__be32 rx_us_err; /* Rx undersize errors */
|
||||
__be32 rx_os_err; /* Rx oversize errors */
|
||||
__be32 checksum; /* Checksum */
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get package status */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gps_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
__be32 status; /* Hardware arbitration status */
|
||||
__be32 checksum;
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* Get package UUID */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_rsp_gpuuid_pkt {
|
||||
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
||||
unsigned char uuid[16]; /* UUID */
|
||||
__be32 checksum;
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* AEN: Link State Change */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_aen_lsc_pkt {
|
||||
struct ncsi_aen_pkt_hdr aen; /* AEN header */
|
||||
__be32 status; /* Link status */
|
||||
__be32 oem_status; /* OEM link status */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[14];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* AEN: Configuration Required */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_aen_cr_pkt {
|
||||
struct ncsi_aen_pkt_hdr aen; /* AEN header */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[22];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* AEN: Host Network Controller Driver Status Change */
|
||||
SLIRP_PACKED_BEGIN
|
||||
struct ncsi_aen_hncdsc_pkt {
|
||||
struct ncsi_aen_pkt_hdr aen; /* AEN header */
|
||||
__be32 status; /* Status */
|
||||
__be32 checksum; /* Checksum */
|
||||
unsigned char pad[18];
|
||||
} SLIRP_PACKED_END;
|
||||
|
||||
/* NCSI packet revision */
|
||||
#define NCSI_PKT_REVISION 0x01
|
||||
|
||||
/* NCSI packet commands */
|
||||
#define NCSI_PKT_CMD_CIS 0x00 /* Clear Initial State */
|
||||
#define NCSI_PKT_CMD_SP 0x01 /* Select Package */
|
||||
#define NCSI_PKT_CMD_DP 0x02 /* Deselect Package */
|
||||
#define NCSI_PKT_CMD_EC 0x03 /* Enable Channel */
|
||||
#define NCSI_PKT_CMD_DC 0x04 /* Disable Channel */
|
||||
#define NCSI_PKT_CMD_RC 0x05 /* Reset Channel */
|
||||
#define NCSI_PKT_CMD_ECNT 0x06 /* Enable Channel Network Tx */
|
||||
#define NCSI_PKT_CMD_DCNT 0x07 /* Disable Channel Network Tx */
|
||||
#define NCSI_PKT_CMD_AE 0x08 /* AEN Enable */
|
||||
#define NCSI_PKT_CMD_SL 0x09 /* Set Link */
|
||||
#define NCSI_PKT_CMD_GLS 0x0a /* Get Link */
|
||||
#define NCSI_PKT_CMD_SVF 0x0b /* Set VLAN Filter */
|
||||
#define NCSI_PKT_CMD_EV 0x0c /* Enable VLAN */
|
||||
#define NCSI_PKT_CMD_DV 0x0d /* Disable VLAN */
|
||||
#define NCSI_PKT_CMD_SMA 0x0e /* Set MAC address */
|
||||
#define NCSI_PKT_CMD_EBF 0x10 /* Enable Broadcast Filter */
|
||||
#define NCSI_PKT_CMD_DBF 0x11 /* Disable Broadcast Filter */
|
||||
#define NCSI_PKT_CMD_EGMF 0x12 /* Enable Global Multicast Filter */
|
||||
#define NCSI_PKT_CMD_DGMF 0x13 /* Disable Global Multicast Filter */
|
||||
#define NCSI_PKT_CMD_SNFC 0x14 /* Set NCSI Flow Control */
|
||||
#define NCSI_PKT_CMD_GVI 0x15 /* Get Version ID */
|
||||
#define NCSI_PKT_CMD_GC 0x16 /* Get Capabilities */
|
||||
#define NCSI_PKT_CMD_GP 0x17 /* Get Parameters */
|
||||
#define NCSI_PKT_CMD_GCPS 0x18 /* Get Controller Packet Statistics */
|
||||
#define NCSI_PKT_CMD_GNS 0x19 /* Get NCSI Statistics */
|
||||
#define NCSI_PKT_CMD_GNPTS 0x1a /* Get NCSI Pass-throu Statistics */
|
||||
#define NCSI_PKT_CMD_GPS 0x1b /* Get package status */
|
||||
#define NCSI_PKT_CMD_OEM 0x50 /* OEM */
|
||||
#define NCSI_PKT_CMD_PLDM 0x51 /* PLDM request over NCSI over RBT */
|
||||
#define NCSI_PKT_CMD_GPUUID 0x52 /* Get package UUID */
|
||||
|
||||
/* NCSI packet responses */
|
||||
#define NCSI_PKT_RSP_CIS (NCSI_PKT_CMD_CIS + 0x80)
|
||||
#define NCSI_PKT_RSP_SP (NCSI_PKT_CMD_SP + 0x80)
|
||||
#define NCSI_PKT_RSP_DP (NCSI_PKT_CMD_DP + 0x80)
|
||||
#define NCSI_PKT_RSP_EC (NCSI_PKT_CMD_EC + 0x80)
|
||||
#define NCSI_PKT_RSP_DC (NCSI_PKT_CMD_DC + 0x80)
|
||||
#define NCSI_PKT_RSP_RC (NCSI_PKT_CMD_RC + 0x80)
|
||||
#define NCSI_PKT_RSP_ECNT (NCSI_PKT_CMD_ECNT + 0x80)
|
||||
#define NCSI_PKT_RSP_DCNT (NCSI_PKT_CMD_DCNT + 0x80)
|
||||
#define NCSI_PKT_RSP_AE (NCSI_PKT_CMD_AE + 0x80)
|
||||
#define NCSI_PKT_RSP_SL (NCSI_PKT_CMD_SL + 0x80)
|
||||
#define NCSI_PKT_RSP_GLS (NCSI_PKT_CMD_GLS + 0x80)
|
||||
#define NCSI_PKT_RSP_SVF (NCSI_PKT_CMD_SVF + 0x80)
|
||||
#define NCSI_PKT_RSP_EV (NCSI_PKT_CMD_EV + 0x80)
|
||||
#define NCSI_PKT_RSP_DV (NCSI_PKT_CMD_DV + 0x80)
|
||||
#define NCSI_PKT_RSP_SMA (NCSI_PKT_CMD_SMA + 0x80)
|
||||
#define NCSI_PKT_RSP_EBF (NCSI_PKT_CMD_EBF + 0x80)
|
||||
#define NCSI_PKT_RSP_DBF (NCSI_PKT_CMD_DBF + 0x80)
|
||||
#define NCSI_PKT_RSP_EGMF (NCSI_PKT_CMD_EGMF + 0x80)
|
||||
#define NCSI_PKT_RSP_DGMF (NCSI_PKT_CMD_DGMF + 0x80)
|
||||
#define NCSI_PKT_RSP_SNFC (NCSI_PKT_CMD_SNFC + 0x80)
|
||||
#define NCSI_PKT_RSP_GVI (NCSI_PKT_CMD_GVI + 0x80)
|
||||
#define NCSI_PKT_RSP_GC (NCSI_PKT_CMD_GC + 0x80)
|
||||
#define NCSI_PKT_RSP_GP (NCSI_PKT_CMD_GP + 0x80)
|
||||
#define NCSI_PKT_RSP_GCPS (NCSI_PKT_CMD_GCPS + 0x80)
|
||||
#define NCSI_PKT_RSP_GNS (NCSI_PKT_CMD_GNS + 0x80)
|
||||
#define NCSI_PKT_RSP_GNPTS (NCSI_PKT_CMD_GNPTS + 0x80)
|
||||
#define NCSI_PKT_RSP_GPS (NCSI_PKT_CMD_GPS + 0x80)
|
||||
#define NCSI_PKT_RSP_OEM (NCSI_PKT_CMD_OEM + 0x80)
|
||||
#define NCSI_PKT_RSP_PLDM (NCSI_PKT_CMD_PLDM + 0x80)
|
||||
#define NCSI_PKT_RSP_GPUUID (NCSI_PKT_CMD_GPUUID + 0x80)
|
||||
|
||||
/* NCSI response code/reason */
|
||||
#define NCSI_PKT_RSP_C_COMPLETED 0x0000 /* Command Completed */
|
||||
#define NCSI_PKT_RSP_C_FAILED 0x0001 /* Command Failed */
|
||||
#define NCSI_PKT_RSP_C_UNAVAILABLE 0x0002 /* Command Unavailable */
|
||||
#define NCSI_PKT_RSP_C_UNSUPPORTED 0x0003 /* Command Unsupported */
|
||||
#define NCSI_PKT_RSP_R_NO_ERROR 0x0000 /* No Error */
|
||||
#define NCSI_PKT_RSP_R_INTERFACE 0x0001 /* Interface not ready */
|
||||
#define NCSI_PKT_RSP_R_PARAM 0x0002 /* Invalid Parameter */
|
||||
#define NCSI_PKT_RSP_R_CHANNEL 0x0003 /* Channel not Ready */
|
||||
#define NCSI_PKT_RSP_R_PACKAGE 0x0004 /* Package not Ready */
|
||||
#define NCSI_PKT_RSP_R_LENGTH 0x0005 /* Invalid payload length */
|
||||
#define NCSI_PKT_RSP_R_UNKNOWN 0x7fff /* Command type unsupported */
|
||||
|
||||
/* NCSI AEN packet type */
|
||||
#define NCSI_PKT_AEN 0xFF /* AEN Packet */
|
||||
#define NCSI_PKT_AEN_LSC 0x00 /* Link status change */
|
||||
#define NCSI_PKT_AEN_CR 0x01 /* Configuration required */
|
||||
#define NCSI_PKT_AEN_HNCDSC 0x02 /* HNC driver status change */
|
||||
|
||||
/* OEM Vendor Manufacture ID */
|
||||
#define NCSI_OEM_MFR_MLX_ID 0x8119
|
||||
#define NCSI_OEM_MFR_BCM_ID 0x113d
|
||||
#define NCSI_OEM_MFR_INTEL_ID 0x157
|
||||
/* Intel specific OEM command */
|
||||
#define NCSI_OEM_INTEL_CMD_GMA 0x06 /* CMD ID for Get MAC */
|
||||
#define NCSI_OEM_INTEL_CMD_KEEP_PHY 0x20 /* CMD ID for Keep PHY up */
|
||||
/* Broadcom specific OEM Command */
|
||||
#define NCSI_OEM_BCM_CMD_GMA 0x01 /* CMD ID for Get MAC */
|
||||
/* Mellanox specific OEM Command */
|
||||
#define NCSI_OEM_MLX_CMD_GMA 0x00 /* CMD ID for Get MAC */
|
||||
#define NCSI_OEM_MLX_CMD_GMA_PARAM 0x1b /* Parameter for GMA */
|
||||
#define NCSI_OEM_MLX_CMD_SMAF 0x01 /* CMD ID for Set MC Affinity */
|
||||
#define NCSI_OEM_MLX_CMD_SMAF_PARAM 0x07 /* Parameter for SMAF */
|
||||
/* Offset in OEM request */
|
||||
#define MLX_SMAF_MAC_ADDR_OFFSET 8 /* Offset for MAC in SMAF */
|
||||
#define MLX_SMAF_MED_SUPPORT_OFFSET 14 /* Offset for medium in SMAF */
|
||||
/* Mac address offset in OEM response */
|
||||
#define BCM_MAC_ADDR_OFFSET 28
|
||||
#define MLX_MAC_ADDR_OFFSET 8
|
||||
#define INTEL_MAC_ADDR_OFFSET 1
|
||||
|
||||
/* Status offset in OEM response */
|
||||
#define MLX_GMA_STATUS_OFFSET 0
|
||||
/* OEM Response payload length */
|
||||
#define MLX_GMA_PAYLOAD_LEN 24
|
||||
|
||||
#endif /* NCSI_PKT_H */
|
330
bochs/iodev/network/slirp/ncsi.cc
Normal file
330
bochs/iodev/network/slirp/ncsi.cc
Normal file
@ -0,0 +1,330 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* NC-SI (Network Controller Sideband Interface) "echo" model
|
||||
*
|
||||
* Copyright (C) 2016-2018 IBM Corp.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "slirp.h"
|
||||
|
||||
#include "ncsi-pkt.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
static uint32_t ncsi_calculate_checksum(uint8_t *data, int len)
|
||||
{
|
||||
uint32_t checksum = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* 32-bit unsigned sum of the NC-SI packet header and NC-SI packet
|
||||
* payload interpreted as a series of 16-bit unsigned integer values.
|
||||
*/
|
||||
for (i = 0; i < len; i += 2) {
|
||||
checksum += (((uint16_t) data[i]) << 8) + data[i+1];
|
||||
}
|
||||
|
||||
checksum = (~checksum + 1);
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/* Response handler for Mellanox command Get Mac Address */
|
||||
static int ncsi_rsp_handler_oem_mlx_gma(Slirp *slirp,
|
||||
const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
uint8_t oob_eth_addr_allocated = 0;
|
||||
struct ncsi_rsp_oem_pkt *rsp;
|
||||
int i;
|
||||
|
||||
rsp = (struct ncsi_rsp_oem_pkt *)rnh;
|
||||
|
||||
/* Set the payload length */
|
||||
rsp->rsp.common.length = htons(MLX_GMA_PAYLOAD_LEN);
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
if (slirp->oob_eth_addr[i] != 0x00) {
|
||||
oob_eth_addr_allocated = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rsp->data[MLX_GMA_STATUS_OFFSET] = oob_eth_addr_allocated;
|
||||
|
||||
/* Set the allocated management address */
|
||||
memcpy(&rsp->data[MLX_MAC_ADDR_OFFSET], slirp->oob_eth_addr, ETH_ALEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Response handler for Mellanox card */
|
||||
static int ncsi_rsp_handler_oem_mlx(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
const struct ncsi_cmd_oem_pkt *cmd;
|
||||
const struct ncsi_rsp_oem_mlx_pkt *cmd_mlx;
|
||||
struct ncsi_rsp_oem_pkt *rsp;
|
||||
struct ncsi_rsp_oem_mlx_pkt *rsp_mlx;
|
||||
|
||||
/* Get the command header */
|
||||
cmd = (const struct ncsi_cmd_oem_pkt *)nh;
|
||||
cmd_mlx = (const struct ncsi_rsp_oem_mlx_pkt *)cmd->data;
|
||||
|
||||
/* Get the response header */
|
||||
rsp = (struct ncsi_rsp_oem_pkt *)rnh;
|
||||
rsp_mlx = (struct ncsi_rsp_oem_mlx_pkt *)rsp->data;
|
||||
|
||||
/* Ensure the OEM response header matches the command's */
|
||||
rsp_mlx->cmd_rev = cmd_mlx->cmd_rev;
|
||||
rsp_mlx->cmd = cmd_mlx->cmd;
|
||||
rsp_mlx->param = cmd_mlx->param;
|
||||
rsp_mlx->optional = cmd_mlx->optional;
|
||||
|
||||
if (cmd_mlx->cmd == NCSI_OEM_MLX_CMD_GMA &&
|
||||
cmd_mlx->param == NCSI_OEM_MLX_CMD_GMA_PARAM)
|
||||
return ncsi_rsp_handler_oem_mlx_gma(slirp, nh, rnh);
|
||||
|
||||
rsp->rsp.common.length = htons(8);
|
||||
rsp->rsp.code = htons(NCSI_PKT_RSP_C_UNSUPPORTED);
|
||||
rsp->rsp.reason = htons(NCSI_PKT_RSP_R_UNKNOWN);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static const struct ncsi_rsp_oem_handler {
|
||||
unsigned int mfr_id;
|
||||
int (*handler)(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh);
|
||||
} ncsi_rsp_oem_handlers[] = {
|
||||
{ NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
|
||||
{ NCSI_OEM_MFR_BCM_ID, NULL },
|
||||
{ NCSI_OEM_MFR_INTEL_ID, NULL },
|
||||
};
|
||||
|
||||
/* Response handler for OEM command */
|
||||
static int ncsi_rsp_handler_oem(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
const struct ncsi_rsp_oem_handler *nrh = NULL;
|
||||
const struct ncsi_cmd_oem_pkt *cmd = (const struct ncsi_cmd_oem_pkt *)nh;
|
||||
struct ncsi_rsp_oem_pkt *rsp = (struct ncsi_rsp_oem_pkt *)rnh;
|
||||
uint32_t mfr_id = ntohl(cmd->mfr_id);
|
||||
int i;
|
||||
|
||||
rsp->mfr_id = cmd->mfr_id;
|
||||
|
||||
if (mfr_id != slirp->mfr_id) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Check for manufacturer id and Find the handler */
|
||||
for (i = 0; i < SLIRP_N_ELEMENTS(ncsi_rsp_oem_handlers); i++) {
|
||||
if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
|
||||
if (ncsi_rsp_oem_handlers[i].handler)
|
||||
nrh = &ncsi_rsp_oem_handlers[i];
|
||||
else
|
||||
nrh = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nrh) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Process the packet */
|
||||
return nrh->handler(slirp, nh, rnh);
|
||||
|
||||
error:
|
||||
rsp->rsp.common.length = htons(8);
|
||||
rsp->rsp.code = htons(NCSI_PKT_RSP_C_UNSUPPORTED);
|
||||
rsp->rsp.reason = htons(NCSI_PKT_RSP_R_UNKNOWN);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
/* Get Version ID */
|
||||
static int ncsi_rsp_handler_gvi(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
struct ncsi_rsp_gvi_pkt *rsp = (struct ncsi_rsp_gvi_pkt *)rnh;
|
||||
|
||||
rsp->ncsi_version = htonl(0xF1F0F000);
|
||||
rsp->mf_id = htonl(slirp->mfr_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get Capabilities */
|
||||
static int ncsi_rsp_handler_gc(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
struct ncsi_rsp_gc_pkt *rsp = (struct ncsi_rsp_gc_pkt *)rnh;
|
||||
|
||||
rsp->cap = htonl(~0);
|
||||
rsp->bc_cap = htonl(~0);
|
||||
rsp->mc_cap = htonl(~0);
|
||||
rsp->buf_cap = htonl(~0);
|
||||
rsp->aen_cap = htonl(~0);
|
||||
rsp->vlan_mode = 0xff;
|
||||
rsp->uc_cnt = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get Link status */
|
||||
static int ncsi_rsp_handler_gls(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
struct ncsi_rsp_gls_pkt *rsp = (struct ncsi_rsp_gls_pkt *)rnh;
|
||||
|
||||
rsp->status = htonl(0x1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get Parameters */
|
||||
static int ncsi_rsp_handler_gp(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh)
|
||||
{
|
||||
struct ncsi_rsp_gp_pkt *rsp = (struct ncsi_rsp_gp_pkt *)rnh;
|
||||
|
||||
/* no MAC address filters or VLAN filters on the channel */
|
||||
rsp->mac_cnt = 0;
|
||||
rsp->mac_enable = 0;
|
||||
rsp->vlan_cnt = 0;
|
||||
rsp->vlan_enable = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ncsi_rsp_handler {
|
||||
unsigned char type;
|
||||
int payload;
|
||||
int (*handler)(Slirp *slirp, const struct ncsi_pkt_hdr *nh,
|
||||
struct ncsi_rsp_pkt_hdr *rnh);
|
||||
} ncsi_rsp_handlers[] = { { NCSI_PKT_RSP_CIS, 4, NULL },
|
||||
{ NCSI_PKT_RSP_SP, 4, NULL },
|
||||
{ NCSI_PKT_RSP_DP, 4, NULL },
|
||||
{ NCSI_PKT_RSP_EC, 4, NULL },
|
||||
{ NCSI_PKT_RSP_DC, 4, NULL },
|
||||
{ NCSI_PKT_RSP_RC, 4, NULL },
|
||||
{ NCSI_PKT_RSP_ECNT, 4, NULL },
|
||||
{ NCSI_PKT_RSP_DCNT, 4, NULL },
|
||||
{ NCSI_PKT_RSP_AE, 4, NULL },
|
||||
{ NCSI_PKT_RSP_SL, 4, NULL },
|
||||
{ NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
|
||||
{ NCSI_PKT_RSP_SVF, 4, NULL },
|
||||
{ NCSI_PKT_RSP_EV, 4, NULL },
|
||||
{ NCSI_PKT_RSP_DV, 4, NULL },
|
||||
{ NCSI_PKT_RSP_SMA, 4, NULL },
|
||||
{ NCSI_PKT_RSP_EBF, 4, NULL },
|
||||
{ NCSI_PKT_RSP_DBF, 4, NULL },
|
||||
{ NCSI_PKT_RSP_EGMF, 4, NULL },
|
||||
{ NCSI_PKT_RSP_DGMF, 4, NULL },
|
||||
{ NCSI_PKT_RSP_SNFC, 4, NULL },
|
||||
{ NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi },
|
||||
{ NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
|
||||
{ NCSI_PKT_RSP_GP, 40, ncsi_rsp_handler_gp },
|
||||
{ NCSI_PKT_RSP_GCPS, 172, NULL },
|
||||
{ NCSI_PKT_RSP_GNS, 172, NULL },
|
||||
{ NCSI_PKT_RSP_GNPTS, 172, NULL },
|
||||
{ NCSI_PKT_RSP_GPS, 8, NULL },
|
||||
{ NCSI_PKT_RSP_OEM, 0, ncsi_rsp_handler_oem },
|
||||
{ NCSI_PKT_RSP_PLDM, 0, NULL },
|
||||
{ NCSI_PKT_RSP_GPUUID, 20, NULL } };
|
||||
|
||||
/*
|
||||
* packet format : ncsi header + payload + checksum
|
||||
*/
|
||||
#define NCSI_MAX_PAYLOAD 172
|
||||
#define NCSI_MAX_LEN (sizeof(struct ncsi_pkt_hdr) + NCSI_MAX_PAYLOAD + 4)
|
||||
|
||||
void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
|
||||
{
|
||||
const struct ncsi_pkt_hdr *nh =
|
||||
(const struct ncsi_pkt_hdr *)(pkt + ETH_HLEN);
|
||||
uint8_t ncsi_reply[2 + ETH_HLEN + NCSI_MAX_LEN];
|
||||
struct ethhdr *reh = (struct ethhdr *)(ncsi_reply + 2);
|
||||
struct ncsi_rsp_pkt_hdr *rnh =
|
||||
(struct ncsi_rsp_pkt_hdr *)(ncsi_reply + 2 + ETH_HLEN);
|
||||
const struct ncsi_rsp_handler *handler = NULL;
|
||||
int i;
|
||||
int ncsi_rsp_len = sizeof(*nh);
|
||||
uint32_t checksum;
|
||||
uint32_t *pchecksum;
|
||||
|
||||
if (pkt_len < ETH_HLEN + sizeof(struct ncsi_pkt_hdr)) {
|
||||
return; /* packet too short */
|
||||
}
|
||||
|
||||
memset(ncsi_reply, 0, sizeof(ncsi_reply));
|
||||
|
||||
memset(reh->h_dest, 0xff, ETH_ALEN);
|
||||
memset(reh->h_source, 0xff, ETH_ALEN);
|
||||
reh->h_proto = htons(ETH_P_NCSI);
|
||||
|
||||
for (i = 0; i < SLIRP_N_ELEMENTS(ncsi_rsp_handlers); i++) {
|
||||
if (ncsi_rsp_handlers[i].type == nh->type + 0x80) {
|
||||
handler = &ncsi_rsp_handlers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rnh->common.mc_id = nh->mc_id;
|
||||
rnh->common.revision = NCSI_PKT_REVISION;
|
||||
rnh->common.id = nh->id;
|
||||
rnh->common.type = nh->type + 0x80;
|
||||
rnh->common.channel = nh->channel;
|
||||
|
||||
if (handler) {
|
||||
rnh->common.length = htons(handler->payload);
|
||||
rnh->code = htons(NCSI_PKT_RSP_C_COMPLETED);
|
||||
rnh->reason = htons(NCSI_PKT_RSP_R_NO_ERROR);
|
||||
|
||||
if (handler->handler) {
|
||||
handler->handler(slirp, nh, rnh);
|
||||
}
|
||||
ncsi_rsp_len += ntohs(rnh->common.length);
|
||||
} else {
|
||||
rnh->common.length = 0;
|
||||
rnh->code = htons(NCSI_PKT_RSP_C_UNAVAILABLE);
|
||||
rnh->reason = htons(NCSI_PKT_RSP_R_UNKNOWN);
|
||||
}
|
||||
|
||||
/* Add the optional checksum at the end of the frame. */
|
||||
checksum = ncsi_calculate_checksum((uint8_t *)rnh, ncsi_rsp_len);
|
||||
pchecksum = (uint32_t *)((char *)rnh + ncsi_rsp_len);
|
||||
*pchecksum = htonl(checksum);
|
||||
ncsi_rsp_len += 4;
|
||||
|
||||
slirp_send_packet_all(slirp, ncsi_reply + 2, ETH_HLEN + ncsi_rsp_len);
|
||||
}
|
||||
|
||||
#endif
|
102
bochs/iodev/network/slirp/ndp_table.cc
Normal file
102
bochs/iodev/network/slirp/ndp_table.cc
Normal file
@ -0,0 +1,102 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
|
||||
*/
|
||||
|
||||
#include "slirp.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
|
||||
uint8_t ethaddr[ETH_ALEN])
|
||||
{
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
NdpTable *ndp_table = &slirp->ndp_table;
|
||||
int i;
|
||||
char ethaddr_str[ETH_ADDRSTRLEN];
|
||||
|
||||
inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
|
||||
|
||||
DEBUG_CALL("ndp_table_add");
|
||||
DEBUG_ARG("ip = %s", addrstr);
|
||||
DEBUG_ARG("hw addr = %s", slirp_ether_ntoa(ethaddr, ethaddr_str,
|
||||
sizeof(ethaddr_str)));
|
||||
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip_addr) || in6_zero(&ip_addr)) {
|
||||
/* Do not register multicast or unspecified addresses */
|
||||
DEBUG_CALL(" abort: do not register multicast or unspecified address");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search for an entry */
|
||||
for (i = 0; i < NDP_TABLE_SIZE; i++) {
|
||||
if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
|
||||
DEBUG_CALL(" already in table: update the entry");
|
||||
/* Update the entry */
|
||||
memcpy(ndp_table->table[i].eth_addr, ethaddr, ETH_ALEN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No entry found, create a new one */
|
||||
DEBUG_CALL(" create new entry");
|
||||
/* Save the first entry, it is the guest. */
|
||||
if (in6_zero(&ndp_table->guest_in6_addr)) {
|
||||
ndp_table->guest_in6_addr = ip_addr;
|
||||
}
|
||||
ndp_table->table[ndp_table->next_victim].ip_addr = ip_addr;
|
||||
memcpy(ndp_table->table[ndp_table->next_victim].eth_addr, ethaddr,
|
||||
ETH_ALEN);
|
||||
ndp_table->next_victim = (ndp_table->next_victim + 1) % NDP_TABLE_SIZE;
|
||||
}
|
||||
|
||||
bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
|
||||
uint8_t out_ethaddr[ETH_ALEN])
|
||||
{
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
NdpTable *ndp_table = &slirp->ndp_table;
|
||||
int i;
|
||||
char ethaddr_str[ETH_ADDRSTRLEN];
|
||||
|
||||
inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
|
||||
|
||||
DEBUG_CALL("ndp_table_search");
|
||||
DEBUG_ARG("ip = %s", addrstr);
|
||||
|
||||
/* If unspecified address */
|
||||
if (in6_zero(&ip_addr)) {
|
||||
/* return Ethernet broadcast address */
|
||||
memset(out_ethaddr, 0xff, ETH_ALEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Multicast address: fec0::abcd:efgh/8 -> 33:33:ab:cd:ef:gh */
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip_addr)) {
|
||||
out_ethaddr[0] = 0x33;
|
||||
out_ethaddr[1] = 0x33;
|
||||
out_ethaddr[2] = ip_addr.s6_addr[12];
|
||||
out_ethaddr[3] = ip_addr.s6_addr[13];
|
||||
out_ethaddr[4] = ip_addr.s6_addr[14];
|
||||
out_ethaddr[5] = ip_addr.s6_addr[15];
|
||||
DEBUG_ARG("multicast addr = %s",
|
||||
slirp_ether_ntoa(out_ethaddr, ethaddr_str,
|
||||
sizeof(ethaddr_str)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < NDP_TABLE_SIZE; i++) {
|
||||
if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
|
||||
memcpy(out_ethaddr, ndp_table->table[i].eth_addr, ETH_ALEN);
|
||||
DEBUG_ARG("found hw addr = %s",
|
||||
slirp_ether_ntoa(out_ethaddr, ethaddr_str,
|
||||
sizeof(ethaddr_str)));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_CALL(" ip not found in table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -547,6 +547,44 @@ static void slirp_init_once(void)
|
||||
loopback_mask = htonl(IN_CLASSA_NET);
|
||||
}
|
||||
|
||||
static void ra_timer_handler_cb(void *opaque)
|
||||
{
|
||||
Slirp *slirp = (Slirp*)opaque;
|
||||
|
||||
ra_timer_handler(slirp, NULL);
|
||||
}
|
||||
|
||||
void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque)
|
||||
{
|
||||
// g_return_if_fail(id >= 0 && id < SLIRP_TIMER_NUM);
|
||||
|
||||
switch (id) {
|
||||
case SLIRP_TIMER_RA:
|
||||
ra_timer_handler(slirp, cb_opaque);
|
||||
return;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque)
|
||||
{
|
||||
// g_return_val_if_fail(id >= 0 && id < SLIRP_TIMER_NUM, NULL);
|
||||
|
||||
if (slirp->cfg_version >= 4 && slirp->cb->timer_new_opaque) {
|
||||
return slirp->cb->timer_new_opaque(id, cb_opaque, slirp->opaque);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case SLIRP_TIMER_RA:
|
||||
// g_return_val_if_fail(cb_opaque == NULL, NULL);
|
||||
return slirp->cb->timer_new(ra_timer_handler_cb, slirp, slirp->opaque);
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque)
|
||||
{
|
||||
Slirp *slirp = (Slirp*)malloc(sizeof(Slirp));
|
||||
@ -621,6 +659,19 @@ Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque)
|
||||
slirp->disable_dhcp = false;
|
||||
}
|
||||
|
||||
if (slirp->cfg_version >= 4 && slirp->cb->init_completed) {
|
||||
slirp->cb->init_completed(slirp, slirp->opaque);
|
||||
}
|
||||
|
||||
if (cfg->version >= 5) {
|
||||
slirp->mfr_id = cfg->mfr_id;
|
||||
memcpy(slirp->oob_eth_addr, cfg->oob_eth_addr, ETH_ALEN);
|
||||
} else {
|
||||
slirp->mfr_id = 0;
|
||||
memset(slirp->oob_eth_addr, 0, ETH_ALEN);
|
||||
}
|
||||
|
||||
ip6_post_init(slirp);
|
||||
return slirp;
|
||||
}
|
||||
|
||||
@ -1135,12 +1186,12 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
|
||||
if (proto == ETH_P_IP) {
|
||||
ip_input(m);
|
||||
} else if (proto == ETH_P_IPV6) {
|
||||
slirp_warning("IPv6 packet not supported yet", slirp->opaque);
|
||||
ip6_input(m);
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_P_NCSI:
|
||||
slirp_warning("NCSI packet not supported yet", slirp->opaque);
|
||||
ncsi_input(slirp, pkt, pkt_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1213,8 +1264,22 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
|
||||
static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
|
||||
uint8_t ethaddr[ETH_ALEN])
|
||||
{
|
||||
slirp_warning("IPv6 packet not supported yet", slirp->opaque);
|
||||
return 0;
|
||||
const struct ip6 *ip6h = mtod(ifm, const struct ip6 *);
|
||||
if (!ndp_table_search(slirp, ip6h->ip_dst, ethaddr)) {
|
||||
if (!ifm->resolution_requested) {
|
||||
ndp_send_ns(slirp, ip6h->ip_dst);
|
||||
ifm->resolution_requested = true;
|
||||
ifm->expiration_date =
|
||||
slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
eh->h_proto = htons(ETH_P_IPV6);
|
||||
in6_compute_ethaddr(ip6h->ip_src, eh->h_source);
|
||||
|
||||
/* Send this */
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
|
||||
|
@ -133,6 +133,14 @@ typedef struct NdpTable {
|
||||
int next_victim;
|
||||
} NdpTable;
|
||||
|
||||
/* Add a new NDP entry for the given addresses */
|
||||
void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
|
||||
uint8_t ethaddr[ETH_ALEN]);
|
||||
|
||||
/* Look for an NDP entry for the given IPv6 address */
|
||||
bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
|
||||
uint8_t out_ethaddr[ETH_ALEN]);
|
||||
|
||||
/* Slirp configuration, specified by the application */
|
||||
struct Slirp {
|
||||
int cfg_version;
|
||||
@ -212,6 +220,8 @@ struct Slirp {
|
||||
ArpTable arp_table;
|
||||
NdpTable ndp_table;
|
||||
|
||||
void *ra_timer;
|
||||
|
||||
bool enable_emu;
|
||||
|
||||
const SlirpCb *cb;
|
||||
@ -239,6 +249,11 @@ int get_dns_addr(struct in_addr *pdns_addr);
|
||||
/* Get the IPv6 address of the DNS server on the host side */
|
||||
int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
|
||||
|
||||
/* ncsi.c */
|
||||
|
||||
/* Process NCSI packet coming from the guest */
|
||||
void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
@ -290,6 +305,18 @@ void ip_stripoptions(struct mbuf *, struct mbuf *);
|
||||
/* Send IPv4 packet to the guest */
|
||||
int ip_output(struct socket *, struct mbuf *);
|
||||
|
||||
/* ip6_input.c */
|
||||
/* Called from slirp_new, but after other initialization */
|
||||
void ip6_post_init(Slirp *);
|
||||
/* Called from slirp_cleanup */
|
||||
void ip6_cleanup(Slirp *);
|
||||
/* Process IPv6 packet coming from the guest */
|
||||
void ip6_input(struct mbuf *);
|
||||
|
||||
/* ip6_output */
|
||||
/* Send IPv6 packet to the guest */
|
||||
int ip6_output(struct socket *, struct mbuf *, int fast);
|
||||
|
||||
/* tcp_input.c */
|
||||
/* Process TCP datagram coming from the guest */
|
||||
void tcp_input(struct mbuf *, int, struct socket *, unsigned short af);
|
||||
|
@ -555,8 +555,8 @@ void sorecvfrom(struct socket *so)
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *) SO_EE_OFFENDER(ee);
|
||||
// icmp6_forward_error(so->so_m, ee->ee_type, ee->ee_code,
|
||||
// &sin6->sin6_addr);
|
||||
icmp6_forward_error(so->so_m, ee->ee_type, ee->ee_code,
|
||||
&sin6->sin6_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -671,7 +671,7 @@ void sorecvfrom(struct socket *so)
|
||||
}
|
||||
|
||||
DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
|
||||
// icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
|
||||
icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown protocol\n");
|
||||
@ -710,8 +710,8 @@ void sorecvfrom(struct socket *so)
|
||||
"guest address not available yet");
|
||||
break;
|
||||
case AF_INET6:
|
||||
// icmp6_send_error(so->so_m, ICMP6_UNREACH,
|
||||
// ICMP6_UNREACH_ADDRESS);
|
||||
icmp6_send_error(so->so_m, ICMP6_UNREACH,
|
||||
ICMP6_UNREACH_ADDRESS);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown protocol\n");
|
||||
@ -728,8 +728,8 @@ void sorecvfrom(struct socket *so)
|
||||
(struct sockaddr_in *)&daddr, so->so_iptos);
|
||||
break;
|
||||
case AF_INET6:
|
||||
// udp6_output(so, m, (struct sockaddr_in6 *)&saddr,
|
||||
// (struct sockaddr_in6 *)&daddr);
|
||||
udp6_output(so, m, (struct sockaddr_in6 *)&saddr,
|
||||
(struct sockaddr_in6 *)&daddr);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown protocol\n");
|
||||
@ -1117,7 +1117,7 @@ void sotranslate_accept(struct socket *so)
|
||||
unix2inet_cont:
|
||||
if (!so->so_fport) {
|
||||
slirp_warning("Falling back to random port allocation", so->slirp->opaque);
|
||||
so->so_fport = htons((rand() & 0x3fff) + 49152);
|
||||
so->so_fport = htons(slirp_rand_int_range(49152, 65536));
|
||||
}
|
||||
} else if (so->slirp->in6_enabled) {
|
||||
so->so_ffamily = AF_INET6;
|
||||
@ -1160,7 +1160,7 @@ unix2inet_cont:
|
||||
unix2inet6_cont:
|
||||
if (!so->so_fport6) {
|
||||
slirp_warning("Falling back to random port allocation", so->slirp->opaque);
|
||||
so->so_fport6 = htons((rand() & 0x3fff) + 49152);
|
||||
so->so_fport6 = htons(slirp_rand_int_range(49152, 65536));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unknown protocol\n");
|
||||
|
@ -693,7 +693,7 @@ findso:
|
||||
m->m_len -= sizeof(struct tcpiphdr) -
|
||||
(sizeof(struct ip6) + sizeof(struct tcphdr));
|
||||
*ip6 = save_ip6;
|
||||
// icmp6_send_error(m, ICMP6_UNREACH, code);
|
||||
icmp6_send_error(m, ICMP6_UNREACH, code);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown protocol\n");
|
||||
|
@ -476,7 +476,7 @@ send:
|
||||
ip6->ip_src = tcpiph_save.ti_src6;
|
||||
ip6->ip_nh = tcpiph_save.ti_nh6;
|
||||
|
||||
// error = ip6_output(so, m, 0);
|
||||
error = ip6_output(so, m, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -234,7 +234,7 @@ void tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
|
||||
ip6->ip_src = tcpiph_save.ti_src6;
|
||||
ip6->ip_nh = tcpiph_save.ti_nh6;
|
||||
|
||||
// ip6_output(NULL, m, 0);
|
||||
ip6_output(NULL, m, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -588,7 +588,6 @@ uint8_t tcp_tos(struct socket *so)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -630,7 +629,8 @@ int tcp_emu(struct socket *so, struct mbuf *m)
|
||||
switch(so->so_emu) {
|
||||
int x, i;
|
||||
|
||||
case EMU_IDENT:
|
||||
/* TODO: IPv6 */
|
||||
case EMU_IDENT:
|
||||
/*
|
||||
* Identification protocol as per rfc-1413
|
||||
*/
|
||||
|
@ -178,7 +178,7 @@ static void tftp_udp_output(struct tftp_session *spt, struct mbuf *m,
|
||||
da6.sin6_addr = ((struct sockaddr_in6 *)&spt->client_addr)->sin6_addr;
|
||||
da6.sin6_port = spt->client_port;
|
||||
|
||||
// udp6_output(NULL, m, &sa6, &da6);
|
||||
udp6_output(NULL, m, &sa6, &da6);
|
||||
} else {
|
||||
struct sockaddr_in sa4, da4;
|
||||
|
||||
|
@ -96,4 +96,11 @@ struct socket *udpx_listen(Slirp *,
|
||||
/* Send UDP datagram to the guest */
|
||||
int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr,
|
||||
struct sockaddr_in *daddr, int iptos);
|
||||
|
||||
/* Process UDPv6 datagram coming from the guest */
|
||||
void udp6_input(struct mbuf *);
|
||||
/* Send UDPv6 datagram to the guest */
|
||||
int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr,
|
||||
struct sockaddr_in6 *daddr);
|
||||
|
||||
#endif
|
||||
|
200
bochs/iodev/network/slirp/udp6.cc
Normal file
200
bochs/iodev/network/slirp/udp6.cc
Normal file
@ -0,0 +1,200 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* Guillaume Subiron
|
||||
*/
|
||||
|
||||
#include "slirp.h"
|
||||
#include "udp.h"
|
||||
#include "dhcpv6.h"
|
||||
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
void udp6_input(struct mbuf *m)
|
||||
{
|
||||
Slirp *slirp = m->slirp;
|
||||
M_DUP_DEBUG(slirp, m, 0, 0);
|
||||
|
||||
struct ip6 *ip, save_ip;
|
||||
struct udphdr *uh;
|
||||
int iphlen = sizeof(struct ip6);
|
||||
int len;
|
||||
struct socket *so;
|
||||
struct sockaddr_in6 lhost;
|
||||
int hop_limit;
|
||||
|
||||
DEBUG_CALL("udp6_input");
|
||||
DEBUG_ARG("m = %p", m);
|
||||
|
||||
if (slirp->restricted) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ip = mtod(m, struct ip6 *);
|
||||
m->m_len -= iphlen;
|
||||
m->m_data += iphlen;
|
||||
uh = (struct udphdr*)mtod_check(m, sizeof(struct udphdr));
|
||||
if (uh == NULL) {
|
||||
goto bad;
|
||||
}
|
||||
m->m_len += iphlen;
|
||||
m->m_data -= iphlen;
|
||||
|
||||
if (ip6_cksum(m)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
len = ntohs((uint16_t)uh->uh_ulen);
|
||||
|
||||
/*
|
||||
* Make mbuf data length reflect UDP length.
|
||||
* If not enough data to reflect UDP length, drop.
|
||||
*/
|
||||
if (ntohs(ip->ip_pl) != len) {
|
||||
if (len > ntohs(ip->ip_pl)) {
|
||||
goto bad;
|
||||
}
|
||||
m_adj(m, len - ntohs(ip->ip_pl));
|
||||
ip->ip_pl = htons(len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save a copy of the IP header in case we want restore it
|
||||
* for sending an ICMP error message in response.
|
||||
*/
|
||||
save_ip = *ip;
|
||||
|
||||
/* Locate pcb for datagram. */
|
||||
lhost.sin6_family = AF_INET6;
|
||||
lhost.sin6_addr = ip->ip_src;
|
||||
lhost.sin6_port = uh->uh_sport;
|
||||
|
||||
/* handle DHCPv6 */
|
||||
if (ntohs(uh->uh_dport) == DHCPV6_SERVER_PORT &&
|
||||
(in6_equal(&ip->ip_dst, &slirp->vhost_addr6) ||
|
||||
in6_dhcp_multicast(&ip->ip_dst))) {
|
||||
m->m_data += iphlen;
|
||||
m->m_len -= iphlen;
|
||||
dhcpv6_input(&lhost, m);
|
||||
m->m_data -= iphlen;
|
||||
m->m_len += iphlen;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* handle TFTP */
|
||||
if (ntohs(uh->uh_dport) == TFTP_SERVER &&
|
||||
!memcmp(ip->ip_dst.s6_addr, slirp->vhost_addr6.s6_addr, 16)) {
|
||||
m->m_data += iphlen;
|
||||
m->m_len -= iphlen;
|
||||
tftp_input((struct sockaddr_storage *)&lhost, m);
|
||||
m->m_data -= iphlen;
|
||||
m->m_len += iphlen;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
so = solookup(&slirp->udp_last_so, &slirp->udb,
|
||||
(struct sockaddr_storage *)&lhost, NULL);
|
||||
|
||||
if (so == NULL) {
|
||||
/* If there's no socket for this packet, create one. */
|
||||
so = socreate(slirp, IPPROTO_UDP);
|
||||
if (udp_attach(so, AF_INET6) == -1) {
|
||||
DEBUG_MISC(" udp6_attach errno = %d-%s", errno, strerror(errno));
|
||||
sofree(so);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Setup fields */
|
||||
so->so_lfamily = AF_INET6;
|
||||
so->so_laddr6 = ip->ip_src;
|
||||
so->so_lport6 = uh->uh_sport;
|
||||
}
|
||||
|
||||
so->so_ffamily = AF_INET6;
|
||||
so->so_faddr6 = ip->ip_dst; /* XXX */
|
||||
so->so_fport6 = uh->uh_dport; /* XXX */
|
||||
|
||||
iphlen += sizeof(struct udphdr);
|
||||
m->m_len -= iphlen;
|
||||
m->m_data += iphlen;
|
||||
|
||||
/*
|
||||
* Check for TTL
|
||||
*/
|
||||
hop_limit = save_ip.ip_hl-1;
|
||||
if (hop_limit <= 0) {
|
||||
m->m_len += iphlen;
|
||||
m->m_data -= iphlen;
|
||||
*ip = save_ip;
|
||||
DEBUG_MISC("udp ttl exceeded");
|
||||
icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
|
||||
goto bad;
|
||||
}
|
||||
setsockopt(so->s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hop_limit, sizeof(hop_limit));
|
||||
|
||||
/*
|
||||
* Now we sendto() the packet.
|
||||
*/
|
||||
if (sosendto(so, m) == -1) {
|
||||
m->m_len += iphlen;
|
||||
m->m_data -= iphlen;
|
||||
*ip = save_ip;
|
||||
DEBUG_MISC("udp tx errno = %d-%s", errno, strerror(errno));
|
||||
icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
m_free(so->so_m); /* used for ICMP if error on sorecvfrom */
|
||||
|
||||
/* restore the orig mbuf packet */
|
||||
m->m_len += iphlen;
|
||||
m->m_data -= iphlen;
|
||||
*ip = save_ip;
|
||||
so->so_m = m;
|
||||
|
||||
return;
|
||||
bad:
|
||||
m_free(m);
|
||||
}
|
||||
|
||||
int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr,
|
||||
struct sockaddr_in6 *daddr)
|
||||
{
|
||||
Slirp *slirp = m->slirp;
|
||||
M_DUP_DEBUG(slirp, m, 0, (int)(sizeof(struct ip6) + sizeof(struct udphdr)));
|
||||
|
||||
struct ip6 *ip;
|
||||
struct udphdr *uh;
|
||||
|
||||
DEBUG_CALL("udp6_output");
|
||||
DEBUG_ARG("so = %p", so);
|
||||
DEBUG_ARG("m = %p", m);
|
||||
|
||||
/* adjust for header */
|
||||
m->m_data -= sizeof(struct udphdr);
|
||||
m->m_len += sizeof(struct udphdr);
|
||||
uh = mtod(m, struct udphdr *);
|
||||
m->m_data -= sizeof(struct ip6);
|
||||
m->m_len += sizeof(struct ip6);
|
||||
ip = mtod(m, struct ip6 *);
|
||||
|
||||
/* Build IP header */
|
||||
ip->ip_pl = htons(m->m_len - sizeof(struct ip6));
|
||||
ip->ip_nh = IPPROTO_UDP;
|
||||
ip->ip_src = saddr->sin6_addr;
|
||||
ip->ip_dst = daddr->sin6_addr;
|
||||
|
||||
/* Build UDP header */
|
||||
uh->uh_sport = saddr->sin6_port;
|
||||
uh->uh_dport = daddr->sin6_port;
|
||||
uh->uh_ulen = ip->ip_pl;
|
||||
uh->uh_sum = 0;
|
||||
uh->uh_sum = ip6_cksum(m);
|
||||
if (uh->uh_sum == 0) {
|
||||
uh->uh_sum = 0xffff;
|
||||
}
|
||||
|
||||
return ip6_output(so, m, 0);
|
||||
}
|
||||
|
||||
#endif
|
@ -36,9 +36,11 @@
|
||||
#if BX_NETWORKING && BX_NETMOD_SLIRP
|
||||
|
||||
#include "util.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
int slirp_inet_aton(const char *cp, struct in_addr *ia)
|
||||
@ -378,4 +380,65 @@ void slirp_pstrcpy(char *buf, int buf_size, const char *str)
|
||||
*q = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* A snprintf()-like function that:
|
||||
* - returns the number of bytes written (excluding optional \0-ending)
|
||||
* - dies on error
|
||||
* - warn on truncation
|
||||
*/
|
||||
int slirp_fmt(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rv;
|
||||
|
||||
va_start(args, format);
|
||||
rv = vsnprintf(str, size, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (rv >= (int)size) {
|
||||
fprintf(stderr, "slirp_fmt() truncation\n");
|
||||
}
|
||||
|
||||
return MIN(rv, (int)size);
|
||||
}
|
||||
|
||||
/*
|
||||
* A snprintf()-like function that:
|
||||
* - always \0-end (unless size == 0)
|
||||
* - returns the number of bytes actually written, including \0 ending
|
||||
* - dies on error
|
||||
* - warn on truncation
|
||||
*/
|
||||
int slirp_fmt0(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rv;
|
||||
|
||||
va_start(args, format);
|
||||
rv = vsnprintf(str, size, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (rv >= (int)size) {
|
||||
fprintf(stderr, "slirp_fmt0() truncation\n");
|
||||
if (size > 0)
|
||||
str[size - 1] = '\0';
|
||||
rv = size;
|
||||
} else {
|
||||
rv += 1; /* include \0 */
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str,
|
||||
size_t out_str_size)
|
||||
{
|
||||
assert(out_str_size >= ETH_ADDRSTRLEN);
|
||||
|
||||
slirp_fmt0(out_str, out_str_size, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
||||
|
||||
return out_str;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -192,4 +192,14 @@ static inline int slirp_socket_set_fast_reuse(int fd)
|
||||
|
||||
void slirp_pstrcpy(char *buf, int buf_size, const char *str);
|
||||
|
||||
int slirp_fmt(char *str, size_t size, const char *format, ...);
|
||||
int slirp_fmt0(char *str, size_t size, const char *format, ...);
|
||||
|
||||
/*
|
||||
* Pretty print a MAC address into out_str.
|
||||
* As a convenience returns out_str.
|
||||
*/
|
||||
const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str,
|
||||
size_t out_str_len);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user