summaryrefslogtreecommitdiff
path: root/ecos/packages/net/tcpip/current
diff options
context:
space:
mode:
authorMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
committerMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
commitae1e4e08a1005a0c487f03ba189d7536e7fdcba6 (patch)
treef1c296f8a966a9a39876b0e98e16d9c5da1776dd /ecos/packages/net/tcpip/current
parentf157da5337118d3c5cd464266796de4262ac9dbd (diff)
Added the OS files
Diffstat (limited to 'ecos/packages/net/tcpip/current')
-rw-r--r--ecos/packages/net/tcpip/current/ChangeLog1759
-rw-r--r--ecos/packages/net/tcpip/current/cdl/openbsd_net.cdl347
-rw-r--r--ecos/packages/net/tcpip/current/doc/accept.html81
-rw-r--r--ecos/packages/net/tcpip/current/doc/accept.man75
-rw-r--r--ecos/packages/net/tcpip/current/doc/bind.html64
-rw-r--r--ecos/packages/net/tcpip/current/doc/bind.man58
-rw-r--r--ecos/packages/net/tcpip/current/doc/bridge.html319
-rw-r--r--ecos/packages/net/tcpip/current/doc/bridge.man314
-rw-r--r--ecos/packages/net/tcpip/current/doc/close.html27
-rw-r--r--ecos/packages/net/tcpip/current/doc/close.man21
-rw-r--r--ecos/packages/net/tcpip/current/doc/connect.html81
-rw-r--r--ecos/packages/net/tcpip/current/doc/connect.man75
-rw-r--r--ecos/packages/net/tcpip/current/doc/ecos_tcpip.html88
-rw-r--r--ecos/packages/net/tcpip/current/doc/gethost.html110
-rw-r--r--ecos/packages/net/tcpip/current/doc/gethost.man104
-rw-r--r--ecos/packages/net/tcpip/current/doc/getpeername.html40
-rw-r--r--ecos/packages/net/tcpip/current/doc/getpeername.man34
-rw-r--r--ecos/packages/net/tcpip/current/doc/getproto.html48
-rw-r--r--ecos/packages/net/tcpip/current/doc/getproto.man42
-rw-r--r--ecos/packages/net/tcpip/current/doc/getserv.html54
-rw-r--r--ecos/packages/net/tcpip/current/doc/getserv.man48
-rw-r--r--ecos/packages/net/tcpip/current/doc/getsockname.html37
-rw-r--r--ecos/packages/net/tcpip/current/doc/getsockname.man31
-rw-r--r--ecos/packages/net/tcpip/current/doc/getsockopt.html70
-rw-r--r--ecos/packages/net/tcpip/current/doc/getsockopt.man65
-rw-r--r--ecos/packages/net/tcpip/current/doc/index.html27
-rw-r--r--ecos/packages/net/tcpip/current/doc/inet_addr.html40
-rw-r--r--ecos/packages/net/tcpip/current/doc/inet_addr.man34
-rw-r--r--ecos/packages/net/tcpip/current/doc/ioctl.html46
-rw-r--r--ecos/packages/net/tcpip/current/doc/ioctl.man40
-rw-r--r--ecos/packages/net/tcpip/current/doc/listen.html42
-rw-r--r--ecos/packages/net/tcpip/current/doc/listen.man36
-rw-r--r--ecos/packages/net/tcpip/current/doc/openbsd-manpages-bridge.sgml450
-rw-r--r--ecos/packages/net/tcpip/current/doc/openbsd-manpages-netintro.sgml308
-rw-r--r--ecos/packages/net/tcpip/current/doc/openbsd-manpages-stp.sgml135
-rwxr-xr-xecos/packages/net/tcpip/current/doc/openbsd.sgml219
-rw-r--r--ecos/packages/net/tcpip/current/doc/read.html61
-rw-r--r--ecos/packages/net/tcpip/current/doc/read.man55
-rw-r--r--ecos/packages/net/tcpip/current/doc/recvfrom.html159
-rw-r--r--ecos/packages/net/tcpip/current/doc/recvfrom.man152
-rw-r--r--ecos/packages/net/tcpip/current/doc/sample_program.html359
-rw-r--r--ecos/packages/net/tcpip/current/doc/select.html108
-rw-r--r--ecos/packages/net/tcpip/current/doc/select.man102
-rw-r--r--ecos/packages/net/tcpip/current/doc/sendto.html106
-rw-r--r--ecos/packages/net/tcpip/current/doc/sendto.man100
-rw-r--r--ecos/packages/net/tcpip/current/doc/setsockopt.html72
-rw-r--r--ecos/packages/net/tcpip/current/doc/setsockopt.man66
-rw-r--r--ecos/packages/net/tcpip/current/doc/shutdown.html33
-rw-r--r--ecos/packages/net/tcpip/current/doc/shutdown.man27
-rw-r--r--ecos/packages/net/tcpip/current/doc/socket.html117
-rw-r--r--ecos/packages/net/tcpip/current/doc/socket.man111
-rw-r--r--ecos/packages/net/tcpip/current/doc/tcpip_config.html22
-rw-r--r--ecos/packages/net/tcpip/current/doc/tcpip_library.html77
-rw-r--r--ecos/packages/net/tcpip/current/doc/tcpip_tests.html98
-rw-r--r--ecos/packages/net/tcpip/current/doc/write.html42
-rw-r--r--ecos/packages/net/tcpip/current/doc/write.man36
-rw-r--r--ecos/packages/net/tcpip/current/include/lib/libkern/libkern.h217
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/cdefs.h33
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/cpu.h33
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/limits.h35
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/param.h138
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/signal.h30
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/stdarg.h31
-rw-r--r--ecos/packages/net/tcpip/current/include/machine/types.h84
-rw-r--r--ecos/packages/net/tcpip/current/include/net/bpf.h307
-rw-r--r--ecos/packages/net/tcpip/current/include/net/bpfdesc.h141
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if.h481
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_arp.h123
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_bridge.h319
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_dl.h117
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_gif.h115
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_llc.h178
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_slvar.h88
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_tun.h86
-rw-r--r--ecos/packages/net/tcpip/current/include/net/if_types.h139
-rw-r--r--ecos/packages/net/tcpip/current/include/net/netisr.h137
-rw-r--r--ecos/packages/net/tcpip/current/include/net/radix.h199
-rw-r--r--ecos/packages/net/tcpip/current/include/net/raw_cb.h105
-rw-r--r--ecos/packages/net/tcpip/current/include/net/route.h383
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/icmp6.h66
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/icmp_var.h108
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/if_arc.h158
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/if_atm.h75
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/if_ether.h314
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/igmp.h131
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/igmp_var.h116
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/in.h680
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/in_gif.h71
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/in_pcb.h308
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/in_systm.h93
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/in_var.h254
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip.h223
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip6.h32
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_ah.h145
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_auth.h96
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_blf.h108
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_cast.h51
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_castsb.h577
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_ecn.h90
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_esp.h139
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_ether.h93
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_fil.h605
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_fil_compat.h865
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_frag.h92
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_icmp.h223
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_ip4.h110
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_ipsp.h600
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_mroute.h269
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_nat.h277
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_proxy.h158
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_rmd160.h66
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_sha1.h52
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_skipjack.h50
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_state.h194
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ip_var.h239
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/ipl.h46
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcp.h155
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcp_debug.h99
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcp_fsm.h123
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcp_seq.h99
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcp_timer.h166
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcp_var.h428
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/tcpip.h95
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/udp.h82
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet/udp_var.h141
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/debug.h244
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/debug_inet6.h55
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/icmp6.h680
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/icmpv6.h110
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/icmpv6_var.h82
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/in6.h682
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/in6_gif.h69
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/in6_ifattach.h79
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/in6_pcb.h207
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/in6_prefix.h121
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/in6_var.h593
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ip6.h316
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ip6_mroute.h277
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ip6_var.h287
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ip6protosw.h158
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ipv6.h153
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ipv6_addrconf.h52
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ipv6_icmp.h287
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ipv6_trans.h56
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/ipv6_var.h385
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/mld6_var.h80
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/nd6.h335
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/nd6_protocol.h129
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/osdep.h147
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/pim6.h102
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/pim6_var.h99
-rw-r--r--ecos/packages/net/tcpip/current/include/netinet6/tcpipv6.h68
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/bsdselect.h55
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/bsdtypes.h194
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/cdefs.h170
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/domain.h102
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/endian.h222
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/errno.h30
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/ioccom.h103
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/ioctl.h122
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/kernel.h101
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/malloc.h469
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/mbuf.h473
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/param.h344
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/protosw.h271
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/queue.h514
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/socket.h454
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/socketvar.h338
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/sockio.h179
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/syscallargs.h1411
-rw-r--r--ecos/packages/net/tcpip/current/include/sys/time.h239
-rw-r--r--ecos/packages/net/tcpip/current/src/ecos/init.cxx59
-rw-r--r--ecos/packages/net/tcpip/current/src/ecos/support.c728
-rw-r--r--ecos/packages/net/tcpip/current/src/ecos/synch.c416
-rw-r--r--ecos/packages/net/tcpip/current/src/ecos/timeout.c314
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/accept.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/bind.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/close.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/connect.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/getpeername.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/getsockname.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/getsockopt.c54
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/ioctl.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/listen.c51
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/read.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/recv.c42
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/recvfrom.c56
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/select.c209
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/sendto.c56
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/setsockopt.c54
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/shutdown.c51
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/socket.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/lib/write.c52
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/kern_subr.c357
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/sockio.c950
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/sys_generic.c1022
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/sys_socket.c279
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/uipc_domain.c308
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/uipc_mbuf.c1093
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/uipc_proto.c105
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket.c1144
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket2.c906
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/kern/uipc_syscalls.c1269
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/bridgestp.c1511
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/if.c959
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/if_bridge.c2349
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/if_ethersubr.c1179
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/if_loop.c446
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/radix.c965
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/raw_cb.c178
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/raw_usrreq.c360
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/route.c1074
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/net/rtsock.c1053
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/if_ether.c996
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/igmp.c614
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/in.c902
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/in_cksum.c196
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/in_pcb.c1089
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/in_proto.c384
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/ip_icmp.c767
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/ip_id.c232
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/ip_input.c1562
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/ip_output.c1757
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/raw_ip.c522
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/tcp_debug.c235
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/tcp_input.c2996
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/tcp_output.c1124
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/tcp_subr.c899
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/tcp_timer.c412
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/tcp_usrreq.c942
-rw-r--r--ecos/packages/net/tcpip/current/src/sys/netinet/udp_usrreq.c1371
231 files changed, 68714 insertions, 0 deletions
diff --git a/ecos/packages/net/tcpip/current/ChangeLog b/ecos/packages/net/tcpip/current/ChangeLog
new file mode 100644
index 0000000..ed23142
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/ChangeLog
@@ -0,0 +1,1759 @@
+2010-09-18 John Dallaway <john@dallaway.org.uk>
+
+ * doc/openbsd.sgml: No longer "recent".
+
+2009-09-10 John Dallaway <john@dallaway.org.uk>
+
+ * src/sys/netinet/tcp_input.c, src/sys/netinet/tcp_timer.c: Remove
+ lvalue casts.
+
+2005-10-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/sys/kern/kern_subr.c (uiomove): Remove lvalue cast to
+ keep GCC4.x happy.
+
+2003-12-10 Gary Thomas <gary@mlbassoc.com>
+
+ * include/netinet/in.h: Prototype for inet_ntoa_r()
+
+2003-11-25 Manu Sharma <manu.sharma@ascom.com>
+ * src/sys/net/bridgestp.c: Code for Spanning Tree Protocol (STP).
+
+ * cdl/openbsd_net.cdl: Changes make provisions for STP code.
+ * doc/openbsd.sgml: Same.
+ * include/net/if.h: Same.
+ * include/net/if_bridge.h: Same.
+ * include/net/if_llc.h: Same.
+ * include/sys/sockio.h: Same.
+ * src/sys/net/if_bridge.c: Same.
+
+ * doc/openbsd-manpages-stp.sgml: Documentation for OpenBSD specific code
+ * doc/openbsd-manpages-netintro.sgml: Same.
+ * doc/openbsd-manpages-bridge.sgml: Same.
+
+2003-09-22 Reinhard Jessich <Reinhard.Jessich@frequentis.com>
+
+ * include/net/if.h: Define macro IF_IS_EMPTY needed by eth_drv.c
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/openbsd_net.cdl: Improve doc links.
+
+2003-01-30 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/sys/net/if_bridge.c (bridge_input): Learn source host addr,
+ not dest host addr.
+ Fix pointed to by Daniel Néri.
+
+2002-12-14 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/sys/netinet/tcp_usrreq.c (tcp_usrreq): Rearranged ifndef on
+ PRU_SENSE case to keep the case in the switch and let it return a
+ sensible result. Otherwise a stat() on a socket causes a panic().
+
+2002-12-03 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/ecos/support.c (show_network_tables): New function used
+ to print network information (interface, routing).
+
+2002-05-21 Jesper Skov <jskov@redhat.com>
+
+ * src/lib/recv.c: Fix warning. socket.h declarations are not
+ available to the kernel code. Added missing argument in the
+ recvfrom call.
+
+2002-05-14 Jesper Skov <jskov@redhat.com>
+
+ * include/netinet6/in6.h: Fixed warnings.
+
+ * src/sys/kern/uipc_socket2.c (sblock): Fixed warning.
+ * src/sys/netinet/tcp_input.c: Same.
+ * src/sys/net/if_loop.c (looutput): Same.
+ * src/sys/kern/sockio.c: Same.
+
+ * include/sys/param.h: Include machine headers after the namespace
+ changing macros to get the desired declarations, thus fixing
+ compiler warnings.
+
+2002-04-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/sys/netinet/ip_input.c: Proper "extern" definition of 'ipstat'.
+
+ * src/sys/netinet/raw_ip.c:
+ * src/sys/netinet/ip_output.c:
+ * include/netinet/ip_var.h: Use of ramdom IP packet id is optional.
+
+2002-04-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/sys/netinet/tcp_usrreq.c:
+ * src/sys/netinet/tcp_output.c:
+ * src/sys/netinet/tcp_input.c:
+ * src/sys/netinet/tcp_debug.c:
+ * include/netinet/tcp_debug.h: Fully conditionalize on TCPDEBUG.
+
+2002-03-27 Jonathan Larmour <jlarmour@redhat.com>
+
+ * doc/openbsd.sgml: Manpages now live in "common" BSD package.
+
+2002-03-19 Gary Thomas <gthomas@redhat.com>
+
+ * src/sys/net/route.c (cyg_route_reinit): Renamed from route_reinit.
+
+2002-03-11 Hugo Tyson <hmt@redhat.com>
+
+ [Case 107110]
+
+ * src/sys/netinet/in.c (in_control): SIOCSIFADDR switch entry
+ moved to before the scan for this same address being in the list
+ already, along with Add and Delete (SIOCAIFADDR,SIOCDIFADDR) arms.
+ It falls through into the same alloc-if-needed code anyway.
+ Thus repeatedly setting the same address does not leak store.
+
+ * src/sys/net/route.c (route_reinit): Rewrite to delete all routes
+ individually rather than en-masse (leaking store).
+ (rt_reinit_rtdelete): New function; callback for individual
+ deletion.
+ (rtioctl): Do not pass in a "route **" to return a pointer to the
+ route removed or added; this results in an extra reference, by the
+ returned pointer, and so a storeleak.
+ (rtrequest): RTM_DELETE arm: do not free a gateway route if the
+ gateway pointer is the same as the route itself - it gets freed
+ *again* at the end of the routine if you do. Just dec the refcnt.
+
+2002-03-07 Gary Thomas <gthomas@redhat.com>
+
+ * include/sys/param.h: Privatize route_reinit(), arc4random().
+
+2002-02-28 Hugo Tyson <hmt@redhat.com>
+2002-02-28 Martin Buck <martin.buck@ascom.ch>
+
+ * src/sys/net/if_ethersubr.c (ether_input): [Bugzilla 60318]
+ ether_input() schedules processing by calling schednetisr(FOO) and
+ then queues the frame afterwards. Where we cannot be preempted
+ eg. in a DSR or in the original BSD kernel, this is OK. In eCos
+ the call to schednetisr(FOO) might cause a context switch *before*
+ the frame is enqueued. This "jams" one packet in the queue,
+ delaying it until the next packet, and so on.
+
+ This change makes ether_input() store up the schednetisr() arg
+ until the end, and do the call then, much like it does with the
+ queue to use. Thanks Martin!
+
+2002-02-22 Hugo Tyson <hmt@redhat.com>
+
+ * doc/openbsd.sgml: New file; separated stack-specific docs from
+ monolithic net doc, and tidied up in various ways.
+
+2002-02-15 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/openbsd_net.cdl: Slight changes in layout required by split
+ of network stacks.
+
+2002-02-13 Jonathan Larmour <jlarmour@redhat.com>
+2002-02-13 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/sys/mbuf.h: Declare variables as extern in header.
+ * src/sys/kern/uipc_mbuf.c: Define mbtypes[] and init it.
+
+2002-02-05 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/openbsd_net.cdl: Place this package below CYGPKG_NET
+ ie. the common networking package. Only affects the view in the
+ GUI CT, no big deal.
+
+2002-01-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/sys/netinet/ip_input.c: inet_ntoa() is now common.
+
+ * cdl/openbsd_net.cdl: Renamed from net.cdl. This package
+ is now a proper sub-package, implementing a network stack.
+
+2002-01-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl: Clarify CYGPKG_NET_ROUTING description.
+
+2002-01-08 Jonathan Larmour <jlarmour@redhat.com>
+
+ * tests/server_test.c (server_test): Correct port conversion.
+
+2001-12-14 Hugo Tyson <hmt@redhat.com>
+
+ * src/sys/net/if_ethersubr.c (ether_output): Never ever print
+ anything! It can recurse unexpectedly if debugging over net.
+
+2001-12-10 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/net.cdl: Add configury to eliminate network timing stats.
+ * src/include/machine/param.h: Timing statistics for things like
+ memcpy, mbuf_alloc etc now use configury to determine if the
+ statistics code should be compiled.
+ * src/ecos/support.c: Ditto.
+ * tests/nc_test_slave.c: Only print timing stats when they
+ are enabled.
+ * tests/tcp_echo.c: Ditto.
+ * tests/nc_test_master.c: Allow building with SNMP lib which has
+ its own gettimeofday(). This should be fixed better a different
+ way but will do for now.
+
+2001-12-06 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/bootp_support.c (init_net): Just re-tabbed and checked
+ the addition to initialize DNS from DHCP info - it had already
+ snuck into the file in the previous change from Andrew. Include
+ of netdb.h added also, from the patch in Bug 57019. Also check
+ CYGINT_ISO_DNS for the setup code instead of CYGPKG_ISO_DNS.
+
+2001-12-04 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/lib/bootp_support.c: Check CYGINT_ISO_DNS (from
+ <pkgconf/isoinfra.h>) instead of CYGPKG_ISO_DNS.
+
+2001-12-03 Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+ * src/lib/bootp_support.c: get_bootp_option(): Take the
+ max length of data we want out of the bootp record.
+ * src/lib/dhcp_prot.c: Pass the length we expect for an option.
+
+2001-08-16 Anssi Pulkkinen <Anssi.Pulkkinen@ascom.ch>
+
+ * src/lib/dhcp_prot.c: Make sure we use the newly calculated xid.
+
+2001-08-02 Anand Srivastava <Anand.Srivastava@ascom.ch>
+
+ * src/lib/dhcp_prot.c do_dhcp: ID calculation must be done only
+ once. moved it out the loop.
+
+2001-11-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/dhcp_support.c (dhcp_mgt_entry): If we have an
+ SNMPAGENT, must recycle it whenever we reinitialize all
+ interfaces; call SnmpdShutDown() to cause this.
+ Also re-initialize all loopback interfaces here too.
+
+2001-11-30 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/dhcp_prot.c (set_default_dhcp_tags): New routine to
+ insert all the extra woffle we need neatly each time, keeping the
+ state machine's case arms to the real work. The new thing this
+ sets is TAG_DHCP_PARM_REQ_LIST, with a list that matches the
+ default set we get from a LINUX dhcpd. This is because M$ servers
+ need explicit requests for eg. TAG_GATEWAY. Note that I have
+ included configuration to override the set of tags requested here
+ in the source, but not yet backed up by CDL - we'll see whether
+ anyone needs this.
+ (set_variable_tag): New routine to insert a variable pointed-to
+ data item rather than an int of 1,2 or 4 bytes.
+ (do_dhcp): Call set_default_dhcp_tags() every time we send a
+ packet, rather than ad hoc additions in each state.
+
+2001-11-29 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/machine/ansi.h: No longer require BSD string function
+ compatibility macros (in fact they confuse things).
+
+ * cdl/net.cdl: Require BSD compatibility functions from <string.h>.
+
+2001-11-19 Hugo Tyson <hmt@redhat.com>
+
+ * include/bootp.h (BP_STD_TX_MINPKTSZ): New symbol defining the
+ minimal DHCP packet size which we should send.
+
+ * src/lib/dhcp_prot.c (scan_dhcp_size): New routine to scan up to
+ the end of the packet, for length determination and padding.
+ (dhcp_size): Now uses scan_dhcp_size().
+ (dhcp_size_for_send): New, uses scan_dhcp_size() and pads with
+ zero up to the min packet size that we should send.
+ (do_dhcp): In every sendto() call, use dhcp_size_for_send(xmit) in
+ order to send padded, full size packets as needed. 5 instances.
+
+ Credit to "Anssi Pulkkinen" <Anssi.Pulkkinen@ascom.ch> for the
+ original version of this patch.
+
+2001-11-08 Jesper Skov <jskov@redhat.com>
+
+ * tests/server_test.c (net_test): Fix compile error.
+
+2001-11-02 Gary Thomas <gthomas@redhat.com>
+
+ * src/ecos/support.c:
+ * include/machine/ansi.h: Add C++ support [externC].
+
+2001-11-11 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ *src/lib/recv.c: Implement the recv() call.
+
+2001-10-29 Hugo Tyson <hmt@redhat.com>
+
+ * src/sys/net/if_ethersubr.c (ether_output): [CASE 106613] Even if
+ the queue is full, and we are dropping the packet, try to start
+ the interface anyway, to give it a chance to empty the queue if
+ the device has recovered from whatever made the queue fill up in
+ the first place - being unplugged from the network for example.
+ This change is belt & braces with a similar policy in the periodic
+ tickle function in the logical ether driver in io/eth/... ; this
+ change will recover the situation immediately if the application
+ continues trying to send despite ENOBUFS.
+
+2001-10-25 Hugo Tyson <hmt@redhat.com>
+
+ * src/sys/net/if_bridge.c (bridge_broadcast): Count if_obytes in
+ destination interfaces as well as the bridge interface; normally
+ this is done in if_ethersubr.c but here we talk directly to the
+ interface, bypassing that layer. Thanks to Andrew Lunn for
+ noticing that.
+
+2001-10-18 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/sys/netinet/in.c (in_lifaddr_ioctl): Silence warnings about
+ trigraphs.
+
+2001-10-10 Hugo Tyson <hmt@redhat.com>
+
+ * tests/ftp_test.c (net_test): This was lacking #ifdefs for
+ CYGHWR_NET_DRIVER_ETH0 and CYGHWR_NET_DRIVER_ETH1. Ooops.
+
+2001-10-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl (CYGPKG_NET_CFLAGS_ADD): Define __INSIDE_NET within
+ this package to allow segregation of definitions only relevant for
+ internal consumption, and definitions allowable for external
+ consumption.
+
+ * include/lib/libkern/libkern.h: Conditionalize on __INSIDE_NET.
+
+2001-10-04 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl (CYGHWR_NET_DRIVER_ETH0): Make flavor bool so it isn't
+ defined when 0.
+ (CYGHWR_NET_DRIVER_ETH1): Ditto.
+
+2001-10-04 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/dhcp_support.c: Some conditional compilation tags were
+ wrong vis a vis ETH1 versus ETH0. Thanks to "Simon"
+ <simoncc@ms46.url.com.tw> for spotting it.
+
+2001-10-04 Jesper Skov <jskov@redhat.com>
+
+ * tests/multi_lo_select.c (cyg_user_start): Added CYG_TEST_INIT
+ call.
+ * tests/ping_lo_test.c (cyg_start): Same.
+ * tests/tcp_lo_test.c (cyg_start): Same.
+ * tests/udp_lo_test.c (cyg_start): Same.
+ * tests/tcp_lo_select.c (cyg_start): Same.
+
+2001-09-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl: Tell isoinfra we support getproto* and getserv*
+ NS functionality.
+ * include/netdb.h: Move to...
+ * include/net/netdb.h: ...here.
+
+2001-09-25 Jesper Skov <jskov@redhat.com>
+
+ * cdl/net.cdl: Don't build tests/nc_test_master as it's a host
+ side tool.
+
+ * src/lib/getserv.c: Added domain service.
+
+ * include/netdb.h: Moved getbyhost()/getbyaddr() declarations and
+ hostent struct definition to the DNS package.
+
+ * src/lib/gethost.c: Removed.
+
+ * cdl/net.cdl: Removed gethost.c (replaced by proper
+ implementation in CYGPKG_NS_DNS).
+
+2001-09-17 Hugo Tyson <hmt@redhat.com>
+2001-09-17 Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+ * src/sys/net/if_bridge.c (bridge_broadcast): Fix a null pointer
+ deference. Supporting VLANs, it seems that during the net_init()
+ function, it sends a packet to the bridge with the source
+ interface being NULL. Stats counting assumed otherwise.
+
+2001-09-14 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/sys/kern/uipc_syscalls.c: Last change to uipc_syscalls.c
+ wasn't right. The parts that were __ECOS__ should simply have
+ been completely removed.
+
+2001-09-13 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/net.cdl: Add configury to control whether we can tickle the
+ network devices if there's a lack of network traffic, and to
+ control the delay time before so doing.
+
+ * src/ecos/timeout.c (alarm_thread): Use a timed wait, if so
+ configured, for the flag; and if it times out, tickle all the
+ devices via the common ether driver routine for so doing.
+
+2001-09-12 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/sys/socketvar.h: Use __ECOS, not __ECOS__.
+ * src/sys/kern/uipc_syscalls.c: Ditto.
+ * src/sys/kern/uipc_socket2.c (sblock): Ditto.
+
+2001-08-02 Jonathan Larmour <jlarmour@redhat.com>
+
+ * tests/linux_echo.c (echo_test): Set socket options before bind.
+ * tests/nc_test_slave.c (do_tcp_test): Ditto.
+ * tests/server_test.c (server_test): Ditto.
+ * tests/tcp_echo.c (echo_test): Ditto.
+ * tests/tcp_lo_test.c (server): Ditto.
+ * tests/tcp_sink.c (sink_test): Ditto.
+ * tests/tcp_source.c (source_test): Ditto.
+
+2001-07-27 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/sys/select.h: Renamed to....
+ * include/sys/bsdselect.h: New file.
+ * include/sys/socketvar.h: Include <sys/bsdselect.h> instead of
+ <sys/select.h>
+ * src/lib/select.c: Include <sys/bsdselect.h>
+
+2001-07-26 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl (CYGPKG_NET_API_LOCAL): Implements select()
+ * include/sys/bsdtypes.h: No need for these select definitions.
+
+2001-06-20 Grant Edwards <grante@visi.com>
+2001-06-20 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/dhcp_prot.c (alarm_function): Change the lease state
+ before re-enabling the alarm so that if it somehow gets times of
+ zero (ie. right now) it quickly completes the state machine rather
+ than recursing to its doom.
+ (new_lease): Test the retcode of get_bootp_option() and use
+ obvious defaults if the T1 and T2 times are not provided - this is
+ RFC compliant! - and use "infinite lease" if the lease time is not
+ provided at all.
+
+2001-06-19 Trenton D. Adams <tadams@extremeeng.com>
+
+ * tests/server_test.c (server_test): Null terminate read string
+ at right place.
+
+2001-06-13 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl: Make debug output an option. Include DHCP.
+
+ * src/lib/dhcp_prot.c: DHCP_CHATTER -> CYGDBG_NET_DHCP_CHATTER
+
+ * src/ecos/support.c (cyg_kmem_init): Only print debug output if
+ requested.
+
+ * cdl/net.cdl: Make requirements on other eCos features more
+ abstract.
+
+2001-05-09 Robin Farine <acnrf@dial.eunet.ch>
+2001-05-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/dhcp_prot.c (do_dhcp): In DHCPSTATE_INIT case, create a
+ new xid. Servers apparantly can use *only* this to distinguish
+ machines, even with different MAC addresses! Therefore we use
+ both the most sensitive randomizer available (arc4random()) which
+ in reality uses a finegrain clock, and salt the value further with
+ the MAC address itself. Thanks again Robin.
+
+ * src/ecos/support.c (arc4random): Make arc4random not always be a
+ multiple of 256; stir the clock into the low bits also.
+
+2001-05-09 Robin Farine <acnrf@dial.eunet.ch>
+2001-05-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/sys/net/if_bridge.c: Patch from Robin; the route aging
+ process took twice as long to timeout because an entry requires
+ *two* executions of bridge_rtage() to actually get removed.
+ Record the timeout over 2 to fix that and also define
+ BRIDGE_RTABLE_TIMEOUT as 300s that the standard specifies as
+ default aging time.
+
+2001-05-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/getserv.c (setreturned): New routine to set up a copy of
+ the service data with the port converted to network order like the
+ API demands. It's this way to make the initialization of the
+ table most readable.
+ (services[]): Added an entry for snmp.
+ (getservbyname): Use setreturned() to return adjusted info.
+ (getservbyport): Use setreturned() to return adjusted info and
+ compare with host-ordered version of the port.
+
+ * src/lib/tftp_client.c (tftp_get):
+ (tftp_put): Do not convert to net order from
+ the getserv structure; it's already net order.
+
+ * src/lib/tftp_server.c (tftpd_server): Convert the socket into
+ host order; it's network order in the getserv API.
+
+ * tests/ftp_test.c (ftp_test): Do not convert to net order from
+ the getserv structure; it's already net order.
+
+ * tests/tftp_client_test.c (PUTFILE): Changed the names of the
+ test files to be fully qualified, this makes the test work with
+ more server machines. /tftpboot/tftp_get and /tftpboot/tftp_put.
+
+2001-04-24 Bart Veer <bartv@redhat.com>
+
+ * cdl/net.cdl:
+ Prevent multiple device drivers from implementing the
+ same eth0/eth1 device.
+
+2001-03-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl (CYGPKG_NET_SYSCTL): Comment out - currently unsupported.
+
+2001-03-28 Richard Panton <rpanton@3glab.com>
+
+ * include/bootp.h: Define func protos with C linkage
+ * include/netdb.h: Ditto
+ * include/network.h: Ditto
+ * include/tftp_support.h: Ditto
+
+ * src/lib/getserv.c: getservbynumber() -> getservbyport()
+
+2001-03-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/network_support.c (init_all_network_interfaces):
+ FIx slightly broken previous attempt in abort code.
+
+2001-03-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/network_support.c (init_all_network_interfaces):
+ Let initialization of PCMCIA devices abort after ~5 seconds.
+
+2001-02-23 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/lib/tftp_server.c (STACK_SIZE): Align
+
+2001-02-20 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/net.cdl: Avoid puts to the CDL header when a CDL
+ define will do.
+ Rename CYGPKG_NET_BRIDGE_CODE -> CYGPKG_NET_BRIDGE
+ Rename CYGPKG_NET_NBRIDGE -> CYGNUM_NET_BRIDGES
+ Rename CYGPKG_NET_BRIDGE_HANDLER -> CYGINT_NET_BRIDGE_HANDLER
+ Make if_bridge.c compilation conditional on CYGPKG_NET_BRIDGE
+
+ * src/sys/net/if_bridge.c: Reflect above renames.
+
+2001-02-20 Hugo Tyson <hmt@redhat.com>
+2001-02-15 Martin Buck <martin.buck@ascom.ch>
+
+ * cdl/net.cdl: Split up CYGPKG_NET_NBRIDGE into 2 parts:
+ CYGPKG_NET_NBRIDGE and CYGPKG_NET_BRIDGE_HANDLER. If
+ CYGPKG_NET_BRIDGE_HANDLER is nonzero, calls to an Ethernet
+ bridge are inserted into the stack's data path. If
+ CYGPKG_NET_NBRIDGE is nonzero, the standard OpenBSD bridge
+ code is added. This setup allows you to implement your own
+ bridge as a separate package which then implements
+ CYGPKG_NET_BRIDGE_HANDLER so it gets called by the stack.
+ NBRIDGE now is the same as CYGPKG_NET_BRIDGE_HANDLER instead
+ of CYGPKG_NET_NBRIDGE. This means it's nonzero if the bridge
+ is wanted, but it no longer contains the number of bridge
+ buffers requested. This shouldn't be a problem, because the
+ only place where the actual number of buffers is required is
+ in if_bridge.c, which now uses CYGPKG_NET_NBRIDGE instead
+ of NBRIDGE.
+
+ * src/sys/net/if_bridge.c: Use CYGPKG_NET_NBRIDGE instead of
+ NBRIDGE, because the latter one now only means that there is
+ a bridge, not that we should implement it.
+
+2001-01-07 Gary Thomas <gthomas@redhat.com>
+
+ * src/ecos/support.c:
+ * cdl/net.cdl: Add interface 'CYGPKG_NET_DRIVER_FRAMEWORK'
+ to describe interdependencies between network stack and driver
+ framework packages.
+
+
+2001-01-03 Hugo Tyson <hmt@redhat.com>
+
+ * tests/linux_echo.c: New file to test for network bandwidth
+ limitations in host side. Builds to a linux version of the
+ tcp_echo middleman.
+
+ * tests/make.linux (all): Build linux_echo.
+
+2001-01-03 Hugo Tyson <hmt@redhat.com>
+
+ * include/dhcp.h (struct dhcp_lease): Define the semaphore pointer
+ field in each lease structure.
+
+ * src/lib/dhcp_support.c: Initialize the dhcp_lease structs to
+ point to the semaphore "dhcp_needs_attention".
+
+ * src/lib/dhcp_prot.c (alarm_function): Post to the semaphore
+ pointed to in the lease structure, rather than one hard-coded.
+ This is much cleaner, in that dhcp_prot.c now uses no external
+ variables, all state goes through the API.
+
+2000-11-15 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/bootp_support.c (init_net): Do a SIOCSIFADDR a 2nd time
+ after setting the netmask (SIOCSIFNETMASK) in order for the newly
+ set netmask to "take" - otherwise a bogus route based on the
+ default netmask lurks within the system.
+
+2000-11-10 Hugo Tyson <hmt@redhat.com>
+
+ * src/ecos/support.c (cyg_net_get_mem_stats): New API for getting
+ info on the various mem pools the stack uses to enable tests to
+ spot store leaks.
+
+ * include/network.h (cyg_net_get_mem_stats): Export this API for
+ automated network testing.
+
+2000-10-24 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/tftp_server.c (tftpd_server): Cut down the chatter to
+ nothing (unless there's an error) if running automated testing.
+
+2000-10-17 Hugo Tyson <hmt@redhat.com>
+2000-10-10 Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+ * src/ecos/support.c (setsoftnet,cyg_panic): Less chatter,
+ particularly not when we're out of MBUFs.
+
+2000-10-17 Hugo Tyson <hmt@redhat.com>
+2000-10-10 Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+ * src/sys/net/if_bridge.c: Intergrated a more up to date version
+ from the OpenBSD sources. This fixes a few bugs.
+
+2000-10-17 Hugo Tyson <hmt@redhat.com>
+
+ * src/ecos/support.c (cyg_ktime_init): Start time at 1 Second so
+ that all visible time values are valid; offset time by 1 Second
+ subsequently, for ever.
+
+ * src/sys/netinet/if_ether.c (arpresolve): Undo the change below;
+ instead make "kernel time" be valid ie. more than 1 second into
+ its life. Dumb stack assumes it takes UNIX-like time to start.
+
+2000-10-16 Hugo Tyson <hmt@redhat.com>
+
+ * src/sys/netinet/if_ether.c (arpresolve): Deal with the initial
+ case when the route timeout is zero (as initialized). Otherwise
+ it never actually sent out the initial ARP request packet. This
+ caused connect() not to work, and thus ftp_test, for example.
+
+ * src/lib/dhcp_support.c (dhcp_start_dhcp_mgt_thread): Also
+ initialize the dhcp semaphore here. The other place it is init'd
+ [correctly] didn't fire if we use the standard support. Fixed
+ some absent return value warnings.
+
+2000-10-10 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/tftp_server.c (tftpd_server): Modify the server to
+ support multiple sessions - ie. starting N servers at once.
+ Mainly this means closing the initial socket whilst servicing a
+ request, so that another server can then bind to it; tell another
+ server to retry that bind via a semaphore, that it waited on when
+ the bind failed initially, rather than just returning.
+
+ * src/lib/tftp_dummy_file.c (dummy_open): Trivial bugfix: scan the
+ list of files as well as incrementing the counter.
+
+2000-10-05 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/ecos/support.c (cyg_ktime_func,cyg_ktime_init,cyg_net_init):
+ Make 'ktime' value valid.
+
+2000-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/tftp_server.c (tftpd_write_file): Restructure this
+ function to match the loop layout of the tftpd_read_file; so that
+ it retries sensibly, and so that a delayed/duplicated packet does
+ not cause a doubling of all traffic with a less smart host.
+
+2000-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * include/tftp_support.h (TFTP_TIMEOUT_MAX): Change this to 50; it
+ refers to total timeouts for a whole session, so it should be
+ greater than the retry count for each packet.
+
+2000-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/tftp_dummy_file.c: Make the fake file slots be a Mb
+ instead of 10k so that you can do meaningful timing tests with it.
+ (dummy_open): Allow re-write of an existing file so that you can
+ do repeated put tests without running out of slots.
+
+2000-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/select.c (_cyg_select): Unlock the scheduler in a couple
+ of other places I missed. Doh.
+
+2000-09-28 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/select.c (_cyg_select): Elect to wait for the flags
+ atomically wrt sockets possibly becoming ready - this was a race
+ condition that would apparently delay a packet until another
+ arrived, eg. a tftp retry. Then two came along all at once.
+
+2000-09-28 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/tftp_server.c: Add lots of instrumentation for
+ debugging. It's switched off, and doesn't have a real config opt,
+ though it easily could have.
+
+2000-09-26 Hugo Tyson <hmt@redhat.com>
+
+ * src/lib/tftp_server.c (tftpd_read_file): Doh! TFTP_TIMEOUT is an
+ internal API thing, not an error we can send in an ERROR packet.
+
+ * include/tftp_support.h: Comment to this effect.
+
+2000-09-26 Hugo Tyson <hmt@redhat.com>
+2000-09-25 Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+ * src/lib/tftp_server.c: Send an ERROR packet when giving up after
+ too many timeouts. This should cause the client to give up as
+ well. Also moved all the replicated code to send an ERROR packet
+ into one function.
+
+ [Huge] I collected another point where we can use the common
+ function also, and used ETIMEOUT instead of EBADOP for the new
+ error packet returns. Thanks Andrew!
+
+2000-09-14 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/net.cdl (CYGOPT_NET_DHCP_DHCP_THREAD_PARAM): Set default to
+ 1 so that the DHCP management thread loops forever. This allows
+ it to recover from a DHCP renewal failure.
+
+ * src/lib/dhcp_prot.c (next_timeout): Harden the DHCP protocol
+ machine against [simulated] failures - otherwise the tests with
+ simulated failures tend just to close down all the interfaces when
+ DHCP packets are lost.
+
+2000-09-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/bootp_support.c (init_net): Set default route correctly.
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ecos/support.c (cyg_net_init): You can't print things while
+ initializing the network! Well, not if connected to GDB over the
+ network anyway. The printf("Init device '%s'...); removed.
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * OVERVIEW: This is part of the change to the network stack to
+ greatly reduce latencies both of (other) DSRs and of thread
+ scheduling. All the work that the network stack *and* individual
+ ether drivers used to do in DSRs (including alarm callbacks and
+ data copies to/from the device memory) is moved into a "fast
+ network thread" instead. It calls a device's "deliver" function
+ to do the work that was previously in the DSR. This is a separate
+ thread so that it can be set higher priority than application
+ threads in order to minimize packet loss (depending on the
+ driver), if required (the application threads presumed to be
+ higher priority in turn than the network thread). A crucial
+ consequence of this is that we are no longer locking against DSRs,
+ so a plain mutex can be used rather than the global scheduler
+ lock, thus simplifying all the splfoo/splx() style functions.
+
+ * src/ecos/timeout.c (alarm_thread): Addition of the "fast network
+ thread" which runs DSR-like activities.
+ (do_timeout): Timeout function morphed for calling from that.
+ (do_alarm, ecos_synch_eth_drv_dsr): new DSR functions to signal to
+ the thread.
+ (timeout): Race condition fixed. splinternal() used for locking
+ instead of scheduler.
+
+ * src/ecos/support.c (cyg_net_init): Splfoo/splx() functions,
+ together with tsleep/wakeup functions, all removed to separate
+ them from the mixed bag of utilities in this file. What remains
+ is mbuf wrapper routines and the like, plus the network "netisr"
+ thread itself, the caller into the stack that does the slower
+ priority work.
+
+ * src/ecos/synch.c: New file; implemtation of new splfoo/splx()
+ functions, together with tsleep/wakeup functions, since they are
+ related now.
+
+ * cdl/net.cdl: Compile new file synch.c; two new options, one for
+ "fast thread" priority, and one for DHCP manager thread priority,
+ as I was adding prio configury. CYGPKG_NET_FAST_THREAD_PRIORITY
+ and CYGPKG_NET_DHCP_THREAD_PRIORITY resp, with suitable default
+ values relative to the CYGPKG_NET_THREAD_PRIORITY.
+
+ * src/lib/dhcp_support.c (dhcp_start_dhcp_mgt_thread): Use the
+ configured priority rather than just "net thread - 1"
+
+2000-08-31 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_echo.c: Change the priorities of the main and loading
+ threads to accommodate the network having helper threads around at
+ adjacent priorities to its main thread prio.
+
+2000-08-24 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sys/net/if.c (ifioctl): Support the two new ioctl() keys; at
+ this level, the struct ifreq at the head of the data area must be
+ filled to select an interface.
+
+ * include/sys/sockio.h (SIOCGIFSTATSUD): Add two new eCos-only
+ ioctl() keys, SIOCGIFSTATSUD and SIOCGIFSTATS, for reading
+ statistical information out of ethernet devices, for SNMP. This
+ should allow SNMP (a) to not explode, (b) to get useful info out
+ of other device implementations than this one.
+
+2000-08-17 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ecos/timeout.c (timeout): Rework the timeout system to
+ record last-time-we-set-the-alarm and whence values, so that new
+ timeouts being added can be set up relative to the correct
+ absolute time. Otherwise adding a new timeout sets them *all*
+ into the future by the expired portion of the previous minimum
+ pending timeout. Also deal better with recursion ie. timeout
+ handlers themselves setting new timeouts as is only natural.
+ Lots of asserts too.
+
+ * src/ecos/support.c (cyg_splsoftnet): Use the new kernel facility
+ to lock mutex &c atomically, with the scheduler locked already.
+ (cyg_tsleep): Similarly, and reclaim the mutex likewise.
+ Also added lots of asserts to both calls the better to document
+ what's going on.
+
+2000-08-17 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/tftp_server.c: Fix contributors field.
+
+2000-08-16 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/tftp_server.c: Improvements to server wrt better error
+ messages and detection of filesystem errors eg. on close-file.
+ Contrib from ASCOM. I tidied up some comments and indent to
+ minimize the diff. [CASE 104354]
+
+2000-08-15 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * doc/bridge.html: New file...
+ * doc/bridge.doc: New file...
+ provided by ASCOM from the OpenBSD version.
+
+2000-08-15 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sys/net/if_bridge.c (bridge_ioctl): SIOCBRDGSTO takes
+ argument in seconds not in ticks. So move around some mul/div by
+ hz ops to get this right.
+
+2000-08-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/ecos/support.c: Use new table definition mechanism.
+
+2000-07-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/dhcp_prot.c (do_dhcp): Use xmit->bp_htype =
+ HTYPE_ETHERNET rather than ifr.ifr_hwaddr.sa_family; sa_family is
+ in a different namespace, despite appearances.
+
+ * src/lib/bootp_support.c (do_bootp): Use bp_htype =
+ HTYPE_ETHERNET rather than ifr.ifr_hwaddr.sa_family; sa_family is
+ in a different namespace, despite appearances.
+
+2000-07-27 Nick Garnett <nickg@cygnus.co.uk>
+
+ * cdl/net.cdl: Require the C library STDIO package to be present
+ if there is more than one loopback interface. This is because it
+ needs sprintf() to form the interface names.
+
+ * src/sys/net/if_loop.c (loopattach):
+ Only use sprintf() to form the loopback interface names when there
+ is more than one. The CDL ensures that this will work.
+
+ * src/lib/network_support.c:
+ Added diag_printf() version of perror() for when STDIO package is
+ absent.
+ Only use sprintf() to form the loopback interface names when there
+ is more than one. The CDL ensures that this will work.
+
+ * tests/multi_lo_select.c:
+ * tests/ping_lo_test.c:
+ * tests/tcp_lo_test.c:
+ Removed dependence on C library by adding a substitute perror()
+ based on diag_printf() that is enabled when the STDIO package is
+ absent.
+
+2000-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/dhcp_prot.c (do_dhcp): Set the broadcast flag where
+ necessary, and the client address too. This makes it talk to a
+ greater range of servers OK.
+
+2000-07-25 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/multi_lo_select.c: Changed definition of NLISTENERS to
+ work correctly with FILEIO package.
+
+ * src/sys/net/if_loop.c (loopattach): Changed initialization of
+ if_xname to "lo0".
+
+ * src/ecos/support.c (cyg_net_init): Removed redundant code to
+ initialize loop-back interface.
+
+2000-07-25 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/getserv.c: Add a list terminator record with NULLs in it
+ so that the search finishes (without throwing asserts about bad
+ strings).
+
+2000-07-21 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sys/net/if_bridge.c: Move the include of stdio.h lower,
+ apparently it confuses local x86 compilers if their host tree is
+ malformed. Or something.
+
+2000-07-21 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Add a lot of description about the way the various
+ fields are used in interface initialization: specifically that
+ "server" so-called is just "someone to talk to" in the absence of
+ bootp - and our tests depend on it!
+
+ * src/lib/bootp_support.c (init_net): Only set up a route if the
+ route address is nonzero - or all manner of confusion occurs with
+ multiple interfaces and route that sends to 0.0.0.0...
+ For setting up the default route, use
+ (SIOCADDRT, 0, 0, TAG_GATEWAY)
+ rather than the bogus
+ (SIOCADDRT, yiaddr & netmask, netmask, TAG_GATEWAY)
+ that we did before.
+
+ * tests/ftp_test.c (ftp_test): Try it with eth1 if available also.
+
+ * tests/ping_test.c (ping_host): If a ping fails, reset the packet
+ size to small just in case the huge packet size is what's causing
+ confusion - helps it as a debug tool.
+
+ * tests/dhcp_test.c (net_test): It didn't compile if DHCP is
+ disabled! Doh. Same change as ping_test also.
+
+2000-07-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/tftp_server.c (tftpd_read_file): Deal with a) [assumed]
+ timeouts on the select, and b) ACKs for old packets.
+ [CASE 104052 and CASE 104055]
+
+2000-07-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/select.c (_cyg_select): Return 0 and do not perturb
+ errno when the timeout occurs. That matches the man page!
+ [CASE 104054]
+
+2000-07-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/machine/param.h: Be more defensive against warnings from
+ external defines such as __linux__/__bsdi__/__FreeBSD__/...
+ [CASE 104090]
+
+2000-07-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/multi_lo_select.c: New test program to test for proper
+ broadcast behaviour of select() implementation. Took some
+ fiddling to get it to work, but it really did fail before the
+ select change below.
+
+ * cdl/net.cdl: Build the new test.
+
+ * src/lib/select.c (_cyg_select): Don't use the CLR flag in the
+ flag wait because that gives unicast semantics. Flags have
+ producer-does-all-the-work behaviour, so setting a value then
+ clearing it right afterwards does the right thing, with broadcast
+ semantics so long as no waiter has set the CLR part.
+ [CASE 104058]
+
+2000-07-18 Hugo Tyson <hmt@cygnus.co.uk>
+
+ All part of the bridge contribution from Andrew Lunn/ASCOM
+ (andrew.lunn@ascom.ch). Bridginess is controlled by NBRIDGE which
+ is itself controlled by CDL option CYGPKG_NET_NBRIDGE aka "Number
+ of bridge buffers?"
+
+ * include/machine/param.h: Add proper definition of untimeout().
+
+ * include/sys/sockio.h (SIOCBRDGFRL): Add this and the other 2
+ bridge ioctl() call definitions.
+
+ * include/sys/param.h (splhigh): Added.
+
+ * src/ecos/timeout.c (untimeout): Implement this properly, it was
+ never used before.
+
+ * src/ecos/support.c: implement cyg_splhigh(), call bridgeintr()
+ when it is scheduled and bridgeattach() if configured.
+
+ * tests/bridge.c: New "test" file - implements an ethernet bridge.
+ Contributed by Andrew Lunn/ASCOM, from the usual OpenBSD external
+ source original.
+
+ * include/net/if_bridge.h: New file, contributed by Andrew Lunn/
+ ASCOM, from OpenBSD original. (Actually did exist in eCos source
+ tree but was not released)
+
+ * src/sys/net/if_bridge.c: New file, contributed by Andrew Lunn/
+ ASCOM, from OpenBSD original.
+
+ * cdl/net.cdl: Build the new files.
+
+2000-07-18 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/tftp_client.c (tftp_get): Fix edge condition when
+ penultimate block is full and end of file which implies that
+ the last block has zero data bytes.
+
+2000-07-18 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/dhcp_prot.c: Ignore NAK messages from the wrong server -
+ we get these because the REQUEST for our chosen IP is broadcast,
+ so other servers think we've asked to use the wrong IP.
+
+2000-07-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/bootp.h: export init_loopback_interface();
+
+2000-07-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Add option controlling whether to have a separate
+ DHCP lease management thread, and what its parameter is to be -
+ which controls whether it loops or quits if a lease fails.
+
+ * src/lib/dhcp_support.c (dhcp_start_dhcp_mgt_thread): Provide the
+ DHCP management thread function and code to instantiate and start
+ the thread if so configured.
+
+ * src/lib/network_support.c (init_all_network_interfaces): Call
+ the function that starts the DHCP management thread function.
+
+ * include/dhcp.h: Declare the DHCP management thread function &c
+ if so configured.
+
+ * tests/dhcp_test.c (net_test): Only poll for need to rebind DHCP
+ leases if there is no service thread to do the same.
+
+2000-07-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/bootp.h (build_bootp_record): Export this, no harm in
+ it, and some folk want to use this rather than configured
+ initialization or bootp/dhcp.
+ Also commented the other APIs somewhat better.
+
+ * src/lib/network_support.c (build_bootp_record): Unconditionally
+ provide this; selective linking will look after it if unused.
+
+2000-07-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/network_support.c (build_bootp_record): [Static
+ configuration of interface parameters] Add the gateway into the
+ options section with TAG_GATEWAY so that init_net() will pick it
+ up and set up a route accordingly.
+
+2000-07-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/dhcp_test.c:
+ * tests/flood.c:
+ * tests/ftp_test.c:
+ * tests/nc_test_master.c:
+ * tests/nc_test_slave.c:
+ * tests/ping_lo_test.c:
+ * tests/ping_test.c:
+ * tests/server_test.c:
+ * tests/set_mac_address.c:
+ * tests/tcp_echo.c:
+ * tests/tftp_client_test.c:
+ * tests/tftp_server_test.c:
+ Up the stack size to cope with full DHCP initialization in
+ init_all_network_interfaces().
+
+2000-07-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Add DHCP enable and interface-specific controls.
+
+ * include/dhcp.h: New file: describe the DHCP APIs and behaviour,
+ as well as some internal APIs that are also available.
+
+ * src/lib/dhcp_support.c: New file: the surrounding management
+ routines, a bit like network_support.c, which know about multiple
+ interfaces and so on.
+
+ * src/lib/dhcp_prot.c: New file: the interface-independent DHCP
+ protocol machine, which is called from dhcp_support.c routines and
+ init_all_network_interfaces() in network_support.c
+
+ * include/bootp.h (struct bootp): Make the packet bigger if DHCP
+ so that a mininal DHCP packet will fit.
+
+ * src/lib/bootp_support.c (do_bootp): If no reply, fail gracefully
+ and tidy up so that other interfaces can be upbrung.
+ (show_bootp): Tell us a lot more about DHCP-specific info in the
+ packet structure.
+ (get_bootp_option): be aware of DHCP extensions to re-use file and
+ sname fields for options.
+
+ * src/lib/network_support.c (init_all_network_interfaces): Call
+ do_dhcp() rather than do_bootp() if so configured, and initialize
+ the per-interface DHCP state variables accordingly.
+
+ * tests/dhcp_test.c (net_test): New test file that diddles the
+ DHCP machine while doing a ping test.
+
+2000-07-11 Gary Thomas <gthomas@redhat.com>
+
+ * include/netdev.h: Add single-inclusion fences.
+
+ * include/sys/param.h: Add traced versions of splx() routines,
+ selectable by a configuration option.
+
+ * src/ecos/support.c: Rework splx() emulation routines to
+ be more robust and realtime friendly.
+
+ * src/lib/network_support.c (init_all_network_interfaces):
+ Add minimal support for PCMCIA based devices.
+
+2000-07-04 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/bootp.h: Fix namespace pollution from "#define int32
+ int" - it fights against application code too much.
+
+2000-07-04 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * cdl/net.cdl: Package requires CYGPKG_MEMALLOC
+
+2000-06-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/ping_test.c (net_test): Added use of the
+ CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff now that the test
+ passes (consequent on the change below); also use larger ping
+ packets now that that is working also.
+
+ * tests/tcp_echo.c (echo_test): Added use of the
+ CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff now that the test
+ passes (consequent on the change below).
+
+2000-06-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ecos/support.c (cyg_splnet): Use the scheduler lock and a
+ mutex instead of disable-interrupts for SPLX type processing. A
+ mutex is used at splsoftnet because that is client threads - we do
+ not want them to pre-empt the rest of the app. This enables the
+ real-time response testing for the EBSA285 to succeed (interrupts
+ every 1mS, DSRs delayed by at most 2mS).
+
+2000-06-23 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ecos/support.c (cyg_net_mbuf_alloc, cyg_kmem_init): Align
+ the mbuf pool to MSIZE [128] bytes. That way dtom() works, nasty
+ though it is. That's needed for ip reassembly in ip_input.c, when
+ dealing with large icmp-layer packets eg. ping -s 2000 ...
+
+2000-06-21 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/lib/libkern/libkern.h: Do not define assert multiple
+ times; guarded by __ECOS.
+
+ * include/sys/param.h (MAX,MIN): Only define if undef.
+
+2000-06-21 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Build the new tests; in fact build them
+ unconditionally.
+
+ * src/lib/network_support.c (init_all_network_interfaces):
+ Initialize loopback device[s] using init_loopback_interface(),
+ providing a sensible default route et al. Multiple devs: lo1 will
+ be 127.0.*1*.1, and so on; class C netmasks will be used.
+
+ init_all_network_interfaces() is also made thread-safe as well as
+ idempotent, so other threads (or daemons) can call it to make sure
+ the net is up.
+
+ * src/ecos/support.c (cyg_net_init): Add a call to loopattach() if
+ there are indeed loopback dev(s) configured. This does the
+ equivalent of the init of a device from the table, but simpler.
+
+ * tests/udp_lo_test.c (udp_server): New testcase...
+ * tests/tcp_lo_select.c (tcp_server): New testcase...
+ * tests/tcp_lo_test.c (tcp_client): New testcase...
+ * tests/ping_lo_test.c (net_test): New testcase, unconditionally
+ built loopback device test. Will run on platforms with no network
+ interfaces.
+
+2000-06-19 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/ecos/support.c:
+ * include/netdev.h:
+ Converted to use of new table construction mechanism.
+
+2000-06-16 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/bootp.h: Remove RCS id tag
+ * include/netinet/ip_auth.h: Ditto
+ * include/netinet/ip_fil.h: Ditto
+ * include/netinet/ip_fil_compat.h: Ditto
+ * include/netinet/ip_frag.h: Ditto
+ * include/netinet/ip_nat.h: Ditto
+ * include/netinet/ip_proxy.h: Ditto
+ * include/netinet/ip_state.h: Ditto
+
+2000-06-15 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/sys/kern/sockio.c: Added cyg_selinit() calls to bad_socket()
+ and bsd_accept() functions.
+
+ * src/ecos/support.c (cyg_tsleep): Changed tests on wakeup from
+ semaphore waits to enable return of EINTR results.
+
+2000-06-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/sys/net/if_loop.c: Substituted sprintf() for a straight
+ strcpy() when initalizing if name. This currently only works for
+ one loopback interface. However, there seems little need to have
+ more than one.
+
+ * src/sys/kern/sockio.c (bsd_select): Added select support.
+
+ * include/sys/time.h: Moved timeval structure definition to
+ isoinfra time.h header since it is needed by the select() API.
+
+ * include/sys/select.h: Added option to use fileio select
+ mechanism if it is present.
+
+ * src/ecos/support.c (cyg_net_init):
+ Added code to bring up the loopback interface. This is to help
+ with testing on platforms without network hardware.
+
+2000-06-08 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/netinet/ip_var.h: Export ipforwarding as well as
+ ip_defttl for monitoring applications.
+
+2000-06-07 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/tcp_echo.c:
+ * tests/socket_test.c:
+ * tests/server_test.c:
+ * tests/ping_test.c:
+ * tests/nc_test_master.c:
+ * tests/nc_test_slave.c:
+ * tests/ftp_test.c:
+ Removed dependence of these programs on STDIO. For most this
+ simply required the use of a diag_printf() based perror() clone is
+ CYGPKG_LIBC_STDIO is not defined. For server_test is also required
+ the substitution of sprintf() with some more primitive string
+ functions.
+
+ * src/sys/netinet/ip_input.c: Rewrote inet_ntoa() to not use
+ sprintf(). This was the only place in the TCP/IP stack that was
+ dependent on a STDIO function. We really should avoid building
+ this kind of casual dependency into the code.
+
+ * src/sys/kern/sockio.c: This new file contain code to support the
+ fileio package. So far only a few of these functions have actually
+ been tested.
+
+ * include/sys/kernel.h (time): The time variable clashes with the
+ C library time() function. To prevent this it is renamed ktime,
+ and a #define allows "kernel" code to continue accessing it as
+ time.
+
+ * src/ecos/support.c: Added definition for ktime variable, as
+ described above. I could not find any definition for struct
+ timeval time. I have a nasty suspicion that it was using the
+ time() function - let's hope that no code that actually uses this
+ has been run.
+
+ * src/lib/bootp_support.c: Another substitution of a diag_printf()
+ based perror() clone when STDIO is absent.
+
+ * include/sys/bsdtypes.h: This is the original
+ include/sys/types.h. Renamed to avoid clashing with <sys/types.h>
+ defined by the isoinfra package.
+
+ * include/sys/types.h: Renamed to bsdtypes.h.
+
+ * include/machine/limits.h:
+ Various changes to make these headers play nicely with those
+ defined in isoinfra package.
+
+ * include/network.h: Added include of <pkgconf/system.h>. Fixed
+ prototypes of functions here to match POSIX specifications.
+
+ * cdl/net.cdl:
+ Split list of files to compile into the common set plus those
+ needed when the fileio package is present and those that are
+ needed when it is absent.
+ Added CDL to export our definitions to <sys/types.h>.
+
+
+2000-05-31 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/lib/network_support.c (init_all_network_interfaces): Make
+ this call idempotent - this is useful for reliable initialization
+ of dependent subsystems.
+
+ * include/lib/libkern/libkern.h: remove protos of random() and
+ srandom() for they are not in fact provided.
+
+ * cdl/net.cdl: Turn off CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS by
+ default - since not all tests currently pass.
+
+2000-05-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl (CYGPKG_NET_TFTPD_THREAD_PRIORITY): New option,
+ control the TFTPD thread priority. These options are *all*
+ CYGPKG_NET. Yuk, sort 'em out later.
+
+ * tests/tftp_server_test.c (tftp_test): Added use of the
+ CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff, same as for the flood
+ ping test. This one passes (with the next change), so committed.
+
+ * src/lib/tftp_server.c (tftpd_server): Cancelled some of the
+ printouts as connections come and go *iff* the tests are set up to
+ use the realtime-ness test harness. This needs generalizing into
+ proper control of the network's chattiness overall.
+ (tftpd_start): Also added configury of the TFTPD thread priority.
+
+2000-05-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Add flood test below. Also add option
+ CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS to decide whether to
+ "Use real-time response test harness (if available)".
+ Consequently moved the test build stuff forward out of the build
+ flags area.
+
+ * tests/flood.c (net_test): New file; performs a flood-ping (well,
+ as fast as we can go) of the server(s) on the two interfaces.
+ Also uses the real-time interrupt response verification stuff from
+ the EBSA285 driver component.
+
+2000-05-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Add new utility (and harmless-by-default test)
+ tests/set_mac_address. You have to edit it to get anything
+ damaging to happen.
+
+ * tests/set_mac_address.c: New file added. It uses SIOCSIFHWADDR
+ to set the MAC address of any interfaces it has been told to.
+
+2000-05-08 Gary Thomas <gthomas@redhat.com>
+
+ * include/machine/cpu.h:
+ * include/machine/cdefs.h: Add copyright boilerplate.
+
+2000-05-05 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/arpa/tftp.h: Aargh. Turns out that removing the align
+ driective and retaining only the packed directive makes the
+ original version work. So, reverted. Apologies for the wasted
+ time.
+
+ * src/lib/tftp_server.c (tftpd_read_file): Coupla warnings
+ reduced, and reverted to match original tftp.h
+
+ * src/lib/tftp_dummy_file.c (dummy_open): Removed use of
+ undeclared malloc().
+
+2000-05-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/tftp_server.c:
+ * src/lib/tftp_client.c: Adjust for changes in header structure.
+
+ * include/arpa/tftp.h: Continuing problems with alignment on ARM.
+ Recourse is very bastardized structure, but it _does_ work.
+
+2000-05-04 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tftp_client_test.c (tftp_test): Print out a coupla more
+ things and test both interfaces if they exist - which does the
+ same thing twice if the same server bootp'd both. Changed the
+ filenames to something more obvious.
+
+ * cdl/net.cdl (CYGPKG_NET_TESTS): Build the tftp tests
+ tests/tftp_client_test tests/tftp_server_test
+
+ * src/ecos/support.c (cyg_kmem_print_stats): New function; prints
+ info about memory usage for some tests to come.
+
+2000-05-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/arpa/tftp.h: Force packed alignment - required on some
+ architectures.
+
+2000-05-01 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/tftp_dummy_file.c: Adding very simple routines - just
+ enough to test TFTP server. This support will come from elsewhere
+ in actual application environments (e.g. a real file system).
+
+ * tests/tftp_server_test.c:
+ * src/lib/tftp_server.c:
+ * include/tftp_support.h: Flesh out TFTP server support.
+
+2000-04-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_echo.c (calibrate_load): Import better background
+ thread loading algorithm with bugfix; if the initial HIGH limit
+ was not large enough, it never got loaded enough.
+
+ * tests/nc_test_slave.c (calibrate_load): Import the fixed version
+ from above back in here.
+
+2000-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/ecos/support.c (cyg_tsleep): Use 'cyg_scheduler_safe_lock()' so
+ this function can be called with the scheduler locked.
+
+ * src/sys/kern/uipc_socket2.c:
+ * include/sys/socketvar.h: Update sblock()/sbunlock() to be eCos safe.
+
+2000-04-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_echo.c: Include <lib/libkern/libkern.h> so that it
+ links - otherwise max() is not around.
+
+2000-04-11 Gary Thomas <gthomas@redhat.com>
+
+ * include/lib/libkern/libkern.h:
+ * include/network.h (NO_LIBKERN_INLINE): Disable kernel inline
+ functions.
+
+2000-04-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/getserv.c: Add TFTP protocol.
+
+ * cdl/net.cdl: Add TFTP library functions.
+
+ * include/tftp_support.h:
+ * src/lib/tftp_dummy_file.c:
+ * src/lib/tftp_server.c:
+ * src/lib/tftp_client.c: New file(s). Basic TFTP support functions.
+
+2000-04-10 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_echo.c (echo_test):
+ * tests/tcp_source.c:
+ * tests/tcp_sink.c:
+ Merge in changes from Grant Edwards <grante@visi.com> presented on
+ ecos-discuss "Mon, 10 Apr 2000 11:01:54 -0500" - fix some
+ warnings, and use ntohl() on the control data that travels netly
+ so that the host tools will work on otherendian machines.
+
+2000-04-07 Gary Thomas <gthomas@redhat.com>
+
+ * tests/nc_test_slave.c: Update background thread loading
+ calibration to use a binary search (better) algorithm.
+
+2000-03-29 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/ftp_test.c (cyg_test_exit):
+ * tests/mbuf_test.c (cyg_start):
+ * tests/nc_test_master.c (cyg_test_exit):
+ * tests/nc_test_slave.c (show_net_times):
+ * tests/ping_test.c (cyg_test_exit):
+ * tests/server_test.c (cyg_test_exit):
+ * tests/socket_test.c (cyg_test_exit):
+ * tests/tcp_echo.c (cyg_test_exit):
+ Some eCos infrastructure changes caused, in some configurations,
+ cyg_test_exit() from the infrastructure to be brought in (in
+ tcdiag.o) even when the Test Case system was not explicitly being
+ invoked. That fought with the convenience copy of cyg_test_exit()
+ in these tests. The neatest fix is to use that provided centrally
+ where relevent, so that is what this change does.
+
+ * tests/tcp_echo.c: Also now use granularity of 5% by default,
+ calibrate the load at 50%, and check and report the load that was
+ actually achieved after the test.
+
+2000-03-29 John Dallaway <jld@cygnus.co.uk>
+
+ * doc/ecos_tcpip.html:
+
+ Remove error-prone cross-reference to another eCos package.
+
+ * doc/index.html:
+
+ Synchronize index page title with web site.
+
+2000-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/lib/bootp_support.c (init_net): Need to start interface,
+ especially for manual/static IP configurations.
+
+ * tests/nc_test_slave.c (calibrate_load): Better calibration for
+ slower targets.
+
+2000-03-18 Gary Thomas <gthomas@redhat.com>
+
+ * src/sys/kern/sys_socket.c:
+ * src/sys/kern/sys_generic.c:
+ * include/sys/sockio.h: Add FIONBIO, FIOASYNC, FIONREAD functions.
+
+ * include/machine/types.h: Make definitions safe for use with libc.
+
+2000-03-08 Gary Thomas <gthomas@redhat.com>
+
+ * src/ecos/support.c: Remove some debug messages.
+ Update timed sleep functions (tsleep) to use scheduler lock
+ instead of brute-force interrupt locks.
+
+2000-03-08 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_echo.c (echo_test): Also enable, log and print out the
+ idle-thread activity during the test - this reassures us that
+ there is no [significant] spare time being wasted idling during
+ the test. This change has no effect on the results at all.
+
+2000-03-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_echo.c (calibrate_load): Improve the accuracy of the
+ calibration with some post-scaling. Change load to an array
+ accessor instead of register-based floating point - this is less
+ load, so more loops are needed, so the initial load level is upped
+ also. More loops means better accuracy anyway, a good thing.
+
+2000-03-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/tcp_source.c (show_results): Print results in Mbit/S also.
+ (source_test): Warnings reduction; add some casts to sending and
+ receiving the control packets.
+ (NUM_BUF): becomes 1024; send more data to get thro'put result.
+
+ * tests/tcp_sink.c (show_results): Print results in Mbit/S also.
+ (sink_test): Warnings reduction; add some casts to sending and
+ receiving the control packets.
+
+ * tests/nc_test_master.c (show_results): Reinstate tot_bytes
+ variable for host testing tool version. Print results in Mbit/S
+ also.
+
+ * tests/nc_test_slave.c (net_test): Comment out starting multiple
+ threads; they fight over a wide-open socket. One thread is
+ enough.
+
+2000-03-06 Gary Thomas <gthomas@redhat.com>
+
+ * include/netdev.h: Update structure for improved API description.
+
+2000-03-05 Gary Thomas <gthomas@redhat.com>
+
+ * include/network.h:
+ * include/sys/syscallargs.h:
+ * src/lib/accept.c:
+ * src/lib/bootp_support.c:
+ * src/lib/close.c:
+ * src/lib/getpeername.c:
+ * src/lib/getsockname.c:
+ * src/lib/recvfrom.c:
+ * tests/ftp_test.c:
+ * tests/nc_test_framework.h:
+ * tests/nc_test_master.c:
+ * tests/nc_test_slave.c:
+ * tests/ping_test.c:
+ * tests/server_test.c:
+ * tests/socket_test.c:
+ * tests/tcp_echo.c:
+ Cleanup to remove compiler warnings.
+
+2000-03-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/machine/param.h:
+ * include/sys/socketvar.h:
+ * src/ecos/timeout.c:
+ * src/sys/kern/kern_subr.c:
+ * src/sys/kern/sys_generic.c:
+ * src/sys/kern/sys_socket.c:
+ * src/sys/kern/uipc_mbuf.c:
+ * src/sys/kern/uipc_socket2.c:
+ * src/sys/kern/uipc_syscalls.c:
+ * src/sys/net/if_ethersubr.c:
+ * src/sys/net/if_loop.c:
+ * src/sys/net/route.c:
+ * src/sys/net/rtsock.c:
+ * src/sys/netinet/in_cksum.c:
+ * src/sys/netinet/in_pcb.c:
+ * src/sys/netinet/ip_input.c:
+ * src/sys/netinet/tcp_input.c:
+ * src/sys/netinet/tcp_output.c:
+ * src/sys/netinet/tcp_subr.c:
+ * src/sys/netinet/udp_usrreq.c:
+ Cleanup to remove compiler warnings.
+
+2000-03-01 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ping_test.c: Reorganize test, display error info.
+
+ * src/lib/bootp_support.c: Add support for DNS options.
+
+2000-02-29 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/sys/sockio.h (SIOCSIFHWADDR): Add function to
+ set hardware (MAC) address via ioctl.
+
+2000-02-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/net.cdl:
+
+ Reparent cdl_interface CYGHWR_NET_DRIVER_ETH0_SETUP under
+ cdl_component CYGHWR_NET_DRIVER_ETH0_SETUP_OPTIONS to
+ avoid a spurious conflict report when the latter is
+ inactive.
+
+2000-02-25 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/net.cdl:
+
+ Reparent cdl_interface CYGHWR_NET_DRIVER_ETH1_SETUP under
+ cdl_component CYGHWR_NET_DRIVER_ETH1_SETUP_OPTIONS to
+ avoid a spurious conflict report when the latter is
+ inactive.
+
+2000-02-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/netinet/if_ether.h:
+ * include/netinet/ip.h:
+ * include/netinet/ip_icmp.h:
+ * include/netinet/tcp.h:
+ * include/netinet/udp.h: More structure alignement fixes.
+
+2000-02-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/netinet/tcpip.h:
+ * include/netinet/udp_var.h: Force structure alignment.
+
+2000-02-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/server_test.c: Target [client] address was wrong.
+
+ * tests/tcp_source.c:
+ * tests/tcp_sink.c:
+ * tests/tcp_echo.c: New test suite.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ping_test.c: Fix typo in startup message.
+
+ * src/sys/net/route.c (route_reinit): New function - only here
+ until BOOTP problems can be found/fixed.
+
+ * src/lib/bootp_support.c (do_bootp): Force any existing routes
+ to be reset since this causes a problem if BOOTP has been previously
+ run. Also, the BOOTP request must be zeroed or the server will
+ get confused.
+
+ * src/lib/network_support.c (init_all_network_interfaces):
+ Rearrange initialization so that all BOOTP activity takes place
+ before any permanent setups are in place.
+
+2000-02-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sys/net/route.c (rtioctl): Add support for deleting routes.
+
+ * src/lib/network_support.c (init_all_network_interfaces):
+ Support predefined IP configurations, as well as BOOTP.
+
+ * tests/ping_test.c: Renamed from 'bootp_test.c'
+
+ * src/lib/inet_addr.c:
+ * include/arpa/ftp.h:
+ * include/arpa/nameser.h:
+ * include/arpa/telnet.h:
+ * include/arpa/inet.h:
+ * include/arpa/tftp.h: New file(s).
+
+2000-02-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/lib/select.c: Add 'cyg_select_with_abort()' interface which
+ will allow 'select()' function to be abnormally terminated. Add
+ new function 'cyg_select_abort()' which does this.
+
+2000-02-15 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/net.cdl: Fix typo; cdl_interface CYGHWR_NET_DRIVER_ETH1 was
+ missing, so EBSA build was conflictual.
+
+2000-02-14 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/bootp_test.c:
+ * tests/ftp_test.c:
+ * tests/nc_test_framework.h:
+ * tests/nc_test_master.c:
+ * tests/nc_test_slave.c:
+ * tests/server_test.c: Rework with automatic network initialization.
+ Includes support for multiple interfaces.
+
+ * src/lib/network_support.c:
+ * include/network.h: New file(s).
+
+ * cdl/net.cdl: New CDL to support multiple interfaces and their
+ configuration. (Not complete yet).
+
+2000-02-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/lib/select.c (select): Add a way to abort selects (EINTR).
+
+2000-02-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/nc_test_slave.c (calibrate_load): Slightly different algorithm,
+ which should work better on all platforms.
+
+2000-02-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/net.cdl: Add CYGPKG_NET_THREAD_PRIORITY to allow user more
+ control over how networking [anonymous] threads behave.
+
+ * tests/nc_test_framework.h:
+ * tests/nc_test_slave.c:
+ * tests/nc_test_master.c: Support test mode with target CPU under
+ various loads.
+
+2000-02-09 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ecos/support.c (bcmp): Fix bug. Missing pointer increments
+ meant that the zeroth byte only was compared. Caused stack to
+ reject ARP packets - depending on MAC address order for particular
+ platform.
+
+2000-02-09 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/bootp_test.c:
+ * tests/ftp_test.c:
+ * tests/nc_test_master.c:
+ * tests/server_test.c:
+ * tests/socket_test.c:
+ Change stacksize of test thread to TYPICAL not MINIMAL - some
+ drivers eat more stack than others. Generally:
+ -#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+ +#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+2000-02-08 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/net.cdl:
+
+ Tidy display strings.
+
+# ####GPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2000, 2001, 2002, 2009, 2010 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/net/tcpip/current/cdl/openbsd_net.cdl b/ecos/packages/net/tcpip/current/cdl/openbsd_net.cdl
new file mode 100644
index 0000000..d28fd5d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/cdl/openbsd_net.cdl
@@ -0,0 +1,347 @@
+# ====================================================================
+#
+# openbsd_net.cdl
+#
+# Networking configuration data
+#
+# ====================================================================
+# ####ECOSPDCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# Permission is granted to use, copy, modify and redistribute this
+# file.
+#
+# -------------------------------------------
+# ####ECOSPDCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 1999-11-29
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_NET_OPENBSD_STACK {
+ display "OpenBSD TCP/IP Stack"
+ parent CYGPKG_NET
+ doc ref/tcpip-openbsd.html
+ include_dir .
+ requires CYGPKG_IO
+ requires CYGPKG_ISOINFRA
+ requires CYGINT_ISO_C_TIME_TYPES
+ requires CYGINT_ISO_STRERROR
+ requires CYGINT_ISO_ERRNO
+ requires CYGINT_ISO_ERRNO_CODES
+ requires CYGINT_ISO_MALLOC
+ requires CYGINT_ISO_STRING_BSD_FUNCS
+ description "Basic networking support, including TCP/IP."
+
+ implements CYGPKG_NET_STACK
+ implements CYGPKG_NET_STACK_INET
+ # Note: separating the stack implementation from the common support leads
+ # to some rather incestious config file relationships.
+ define_proc {
+ puts $::cdl_system_header "/***** Networking stack proc output start *****/"
+ puts $::cdl_header "#include <pkgconf/net.h>"
+ puts $::cdl_system_header "#define CYGDAT_NET_STACK_CFG <pkgconf/net_openbsd_stack.h>"
+ puts $::cdl_system_header "/***** Networking stack proc output end *****/"
+ }
+
+
+ # Export our types to <sys/types.h>
+ implements CYGINT_ISO_BSDTYPES
+ requires { CYGBLD_ISO_BSDTYPES_HEADER == "<sys/bsdtypes.h>" }
+
+ compile ecos/support.c \
+ ecos/synch.c \
+ ecos/timeout.c \
+ ecos/init.cxx \
+ sys/kern/uipc_mbuf.c \
+ sys/kern/uipc_domain.c \
+ sys/kern/uipc_socket.c \
+ sys/kern/uipc_socket2.c \
+ sys/kern/kern_subr.c \
+ sys/net/if.c \
+ sys/net/rtsock.c \
+ sys/net/raw_cb.c \
+ sys/net/raw_usrreq.c \
+ sys/net/route.c \
+ sys/net/radix.c \
+ sys/net/if_ethersubr.c \
+ sys/net/if_loop.c \
+ sys/netinet/igmp.c \
+ sys/netinet/raw_ip.c \
+ sys/netinet/in.c \
+ sys/netinet/in_cksum.c \
+ sys/netinet/in_pcb.c \
+ sys/netinet/in_proto.c \
+ sys/netinet/ip_id.c \
+ sys/netinet/ip_icmp.c \
+ sys/netinet/ip_input.c \
+ sys/netinet/ip_output.c \
+ sys/netinet/if_ether.c \
+ sys/netinet/udp_usrreq.c \
+ sys/netinet/tcp_input.c \
+ sys/netinet/tcp_output.c \
+ sys/netinet/tcp_subr.c \
+ sys/netinet/tcp_debug.c \
+ sys/netinet/tcp_usrreq.c \
+ sys/netinet/tcp_timer.c
+
+ cdl_option CYGPKG_NET_API_LOCAL {
+ display "Implement the socket API locally"
+ flavor bool
+ active_if !CYGPKG_IO_FILEIO
+ default_value 1
+ implements CYGINT_ISO_SELECT
+
+ compile sys/kern/uipc_syscalls.c \
+ sys/kern/sys_socket.c \
+ sys/kern/sys_generic.c \
+ lib/socket.c \
+ lib/close.c \
+ lib/read.c \
+ lib/write.c \
+ lib/bind.c \
+ lib/connect.c \
+ lib/accept.c \
+ lib/listen.c \
+ lib/shutdown.c \
+ lib/sendto.c \
+ lib/recvfrom.c \
+ lib/recv.c \
+ lib/getsockname.c \
+ lib/getpeername.c \
+ lib/getsockopt.c \
+ lib/setsockopt.c \
+ lib/ioctl.c \
+ lib/select.c
+
+ description "
+ This option controls support for the network-stack supplied
+ API."
+ }
+
+ cdl_option CYGPKG_NET_API_FILEIO {
+ display "Implement the socket API via Fileio package"
+ active_if CYGPKG_IO_FILEIO
+ default_value 1
+
+ compile -library=libextras.a sys/kern/sockio.c
+
+ description "
+ This option controls support for the fileio subsystem supplied API."
+ }
+
+ cdl_component CYGPKG_NET_OPENBSD_INET {
+ display "INET support"
+ active_if CYGPKG_NET_INET
+ flavor bool
+ no_define
+ default_value 1
+ description "
+ This option enables support for INET (IP) network processing."
+
+# Placeholder only - not implemented yet
+## cdl_option CYGPKG_NET_OPENBSD_INET6 {
+## display "IPv6 support"
+## active_if CYGPKG_NET_INET6
+## flavor bool
+## default_value 0
+## description "
+## This option enables support for IPv6 networking."
+## }
+ }
+
+# cdl_option CYGPKG_NET_SYSCTL {
+# display "Support BSD 'sysctl()' function"
+# flavor bool
+# default_value 0
+# description "
+# This option includes support for the 'sysctl()' functions."
+# }
+
+ cdl_option CYGPKG_NET_NBPF {
+ display "Number of BPF filters"
+ flavor data
+ default_value 0
+# Placeholder only - not implemented yet
+ legal_values 0
+# Placeholder only - not implemented yet
+ description "
+ This option controls the number of active BPF filters."
+ define NBPFILTER
+ }
+
+ cdl_component CYGPKG_NET_BRIDGE {
+ display "Built-in ethernet bridge code"
+ default_value 0
+ implements CYGINT_NET_BRIDGE_HANDLER
+ no_define
+ description "
+ This option controls whether to include the built-in code for
+ the Ethernet bridge."
+ compile sys/net/if_bridge.c \
+ sys/net/bridgestp.c
+
+ cdl_option CYGNUM_NET_BRIDGES {
+ display "Number of Ethernet bridges"
+ flavor data
+ default_value 1
+ legal_values 1 to 999999
+ }
+
+ cdl_option CYGPKG_NET_BRIDGE_STP_CODE {
+ display "Include code for Spanning Tree Protocol"
+ default_value 0
+ description "
+ This option controls whether to include the code for
+ the Spanning Tree Protocol on Ethernet bridge."
+ }
+ }
+
+ cdl_interface CYGINT_NET_BRIDGE_HANDLER {
+ display "Support for ethernet bridges in the IP stack"
+ define NBRIDGE
+ description "
+ This interface controls whether calls to bridge code are made
+ from the IP stack; these are needed if the built-in bridge code
+ is used, but they can also be enabled in order to call different
+ bridge code from an external component."
+ }
+
+ cdl_option CYGPKG_NET_NGIF {
+ display "Number of GIF things"
+ flavor data
+ default_value 0
+# Placeholder only - not implemented yet
+ legal_values 0
+# Placeholder only - not implemented yet
+ description "
+ This option controls the number of active GIF things."
+ define NGIF
+ }
+
+ cdl_option CYGPKG_NET_NLOOP {
+ display "Number of loopback interfaces"
+ flavor data
+ default_value 1
+ requires { (CYGPKG_NET_NLOOP > 1) ? CYGPKG_LIBC_STDIO : 1 }
+ description "
+ This option controls the number of loopback, i.e. local, interfaces.
+ There is seldom need for this value to be anything other than one.
+ If a different value is required, then the C library STDIO package
+ is required for sprintf()."
+ define NLOOP
+ }
+
+ cdl_option CYGPKG_NET_MEM_USAGE {
+ display "Memory designated for networking buffers."
+ flavor data
+ default_value 256*1024
+ description "
+ This option controls the amount of memory pre-allocated
+ for buffers used by the networking code."
+ }
+
+ cdl_option CYGPKG_NET_NUM_WAKEUP_EVENTS {
+ display "Number of supported pending network events"
+ flavor data
+ default_value 8
+ description "
+ This option controls the number of pending network events
+ used by the networking code."
+ }
+
+ cdl_option CYGPKG_NET_THREAD_PRIORITY {
+ display "Priority level for backgound network processing."
+ flavor data
+ default_value 7
+ description "
+ This option allows the thread priority level used by the
+ networking stack to be adjusted by the user. It should be set
+ high enough that sufficient CPU resources are available to
+ process network data, but may be adjusted so that application
+ threads can have precedence over network processing."
+ }
+
+ cdl_option CYGPKG_NET_FAST_THREAD_PRIORITY {
+ display "Priority level for fast network processing."
+ flavor data
+ default_value CYGPKG_NET_THREAD_PRIORITY - 1
+ description "
+ This option sets the thread priority level used by the fast
+ network thread. The fast network thread runs often but briefly, to
+ service network device interrupts and network timeout events. This
+ thread should have higher priority than the background network
+ thread. It is reasonable to set this thread's priority higher than
+ application threads for best network throughput, or to set it lower
+ than application threads for best latency for those application
+ threads themselves, potentially at a cost to network throughput."
+ }
+
+ cdl_component CYGPKG_NET_FAST_THREAD_TICKLE_DEVS {
+ display "Fast network processing thread 'tickles' drivers"
+ default_value 1
+ description "
+ If this is enabled, the fast network thread will tickle the
+ device(s) periodically, to unblock them when the hardware has
+ become wedged due to a lost interrupt or other hardware
+ race-condition type problem.
+ This is not necessary if a networked app is running which sends
+ packets itself often - or
+ uses TCP, or any similar protocol which exchanges keep-alive
+ packets periodically and often enough.
+ Trying to send a packet passes control into the driver; this is
+ sufficient to detect and unblock jammed hardware."
+
+ cdl_option CYGNUM_NET_FAST_THREAD_TICKLE_DEVS_DELAY {
+ display "Delay in kernel clocks of tickle loop"
+ flavor data
+ default_value 50
+ description "
+ The default is 50, which will usually mean a delay between
+ tests for 'stuck' devices of 500mS, that is half a second.
+ The overhead only applies if no network activity occurred,
+ so it may be acceptable to make this value very small,
+ where high CPU load does not matter during network idle
+ periods, or very large if your application tries often to
+ send packets itself."
+ }
+ }
+
+ cdl_component CYGPKG_NET_OPENBSD_STACK_OPTIONS {
+ display "Networking support build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_NET_OPENBSD_STACK_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS -D__INSIDE_NET" }
+ description "
+ This option modifies the set of compiler flags for
+ building the networking package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_NET_OPENBSD_STACK_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the networking package. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/doc/accept.html b/ecos/packages/net/tcpip/current/doc/accept.html
new file mode 100644
index 0000000..e0c9d62
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/accept.html
@@ -0,0 +1,81 @@
+<html>
+<body>
+<pre>
+NAME
+ accept - accept a connection on a socket
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int accept(int s, struct sockaddr *addr, int *addrlen);
+
+DESCRIPTION
+ The argument s is a socket that has been created with
+ socket(2), bound to an address with bind(2), and is lis-
+ tening for connections after a listen(2). The accept
+ function extracts the first connection request on the
+ queue of pending connections, creates a new socket with
+ the same properties of s, and allocates a new file
+ descriptor for the socket. If no pending connections are
+ present on the queue, and the socket is not marked as non-
+ blocking, accept blocks the caller until a connection is
+ present. If the socket is marked non-blocking and no
+ pending connections are present on the queue, accept
+ returns an error as described below. The socket returned
+ by accept may not be used to accept more connections. The
+ original socket s remains open.
+
+ The argument addr is a result parameter that is filled in
+ with the address of the connecting entity, as known to the
+ communications layer. The exact format of the addr param-
+ eter is determined by the domain in which the communica-
+ tion is occurring. addrlen is a value-result parameter:
+ it should initially contain the amount of space pointed to
+ by addr; on return it will contain the actual length (in
+ bytes) of the address returned. This call is used with
+ connection-based socket types, currently with SOCK_STREAM.
+
+ It is possible to select(2) a socket for the purposes of
+ doing an accept by selecting it for read.
+
+ For certain protocols which require an explicit confirma-
+ tion, such as DECNet, accept can be thought of as merely
+ dequeuing the next connection request and not implying
+ confirmation. Confirmation can be implied by a normal
+ read or write on the new file descriptor, and rejection
+ can be implied by closing the new socket. Currently only
+ DECNet has these semantics on Linux.
+
+NOTES
+ If you want accept to never block the listening socket
+ needs to have the non blocking flag set. Assuming that
+ there is always a connection waiting after select returned
+ true is not reliable, because the connection might be
+ removed by an asynchronous network error between the
+ select/poll returning and the accept call. The application
+ would hang then if the listen socket is not non blocking.
+
+RETURN VALUES
+ The call returns -1 on error. If it succeeds, it returns
+ a non-negative integer that is a descriptor for the
+ accepted socket.
+
+ERRORS
+ EBADF The descriptor is invalid.
+
+ ENOTSOCK
+ The descriptor references a file, not a socket.
+
+ EOPNOTSUPP
+ The referenced socket is not of type SOCK_STREAM.
+
+ EAGAIN The socket is marked non-blocking and no connec-
+ tions are present to be accepted.
+
+ ENOBUFS, ENOMEM
+ Not enough free memory.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/accept.man b/ecos/packages/net/tcpip/current/doc/accept.man
new file mode 100644
index 0000000..0defb38
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/accept.man
@@ -0,0 +1,75 @@
+NAME
+ accept - accept a connection on a socket
+
+SYNOPSIS
+ #include <network.h>
+
+ int accept(int s, struct sockaddr *addr, int *addrlen);
+
+DESCRIPTION
+ The argument s is a socket that has been created with
+ socket(2), bound to an address with bind(2), and is lis-
+ tening for connections after a listen(2). The accept
+ function extracts the first connection request on the
+ queue of pending connections, creates a new socket with
+ the same properties of s, and allocates a new file
+ descriptor for the socket. If no pending connections are
+ present on the queue, and the socket is not marked as non-
+ blocking, accept blocks the caller until a connection is
+ present. If the socket is marked non-blocking and no
+ pending connections are present on the queue, accept
+ returns an error as described below. The socket returned
+ by accept may not be used to accept more connections. The
+ original socket s remains open.
+
+ The argument addr is a result parameter that is filled in
+ with the address of the connecting entity, as known to the
+ communications layer. The exact format of the addr param-
+ eter is determined by the domain in which the communica-
+ tion is occurring. addrlen is a value-result parameter:
+ it should initially contain the amount of space pointed to
+ by addr; on return it will contain the actual length (in
+ bytes) of the address returned. This call is used with
+ connection-based socket types, currently with SOCK_STREAM.
+
+ It is possible to select(2) a socket for the purposes of
+ doing an accept by selecting it for read.
+
+ For certain protocols which require an explicit confirma-
+ tion, such as DECNet, accept can be thought of as merely
+ dequeuing the next connection request and not implying
+ confirmation. Confirmation can be implied by a normal
+ read or write on the new file descriptor, and rejection
+ can be implied by closing the new socket. Currently only
+ DECNet has these semantics on Linux.
+
+NOTES
+ If you want accept to never block the listening socket
+ needs to have the non blocking flag set. Assuming that
+ there is always a connection waiting after select returned
+ true is not reliable, because the connection might be
+ removed by an asynchronous network error between the
+ select/poll returning and the accept call. The application
+ would hang then if the listen socket is not non blocking.
+
+RETURN VALUES
+ The call returns -1 on error. If it succeeds, it returns
+ a non-negative integer that is a descriptor for the
+ accepted socket.
+
+ERRORS
+ EBADF The descriptor is invalid.
+
+ ENOTSOCK
+ The descriptor references a file, not a socket.
+
+ EOPNOTSUPP
+ The referenced socket is not of type SOCK_STREAM.
+
+ EAGAIN The socket is marked non-blocking and no connec-
+ tions are present to be accepted.
+
+ ENOBUFS, ENOMEM
+ Not enough free memory.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/bind.html b/ecos/packages/net/tcpip/current/doc/bind.html
new file mode 100644
index 0000000..a82971d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/bind.html
@@ -0,0 +1,64 @@
+<html>
+<body>
+<pre>
+NAME
+ bind - bind a name to a socket
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int bind(int sockfd, struct sockaddr *my_addr, int
+ addrlen);
+
+DESCRIPTION
+ bind gives the socket sockfd the local address my_addr.
+ my_addr is addrlen bytes long. Traditionally, this is
+ called "assigning a name to a socket." (When a socket is
+ created with socket(2), it exists in a name space (address
+ family) but has no name assigned.)
+
+ Before a SOCK_STREAM socket is put into the LISTEN state
+ to receive connections, you usually need to first assign a
+ local address using bind to make the socket visible.
+
+NOTES
+ Binding a name that is not in the abstract namespace in
+ the UNIX domain creates a socket in the file system that
+ must be deleted by the caller when it is no longer needed
+ (using unlink(2)).
+
+ The rules used in name binding vary between communication
+ domains. Consult the manual entries in section 4 for
+ detailed information. For IP see ip(4) and for PF_UNIX see
+ unix(4). If you want to listen to every local interface
+ for IPv4 set the sin_addr member of the IP-specific sock-
+ addr_in to INADDR_ANY. For IP only one socket may be
+ bound to a specific local address/port pair. For TCP a
+ bound local socket endpoint (address/port pair) is
+ unavailable for some time after closing the socket, unless
+ the SO_REUSEADDR flag is set. Note that carelessly setting
+ SO_REUSEADDR might make TCP more unreliable unless PAWS is
+ used (see tcp(4)); the delay is needed to handle old pack-
+ ets still in the network.
+
+ IP sockets may also bind to a broadcast or multicast
+ address.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF sockfd is not a valid descriptor.
+
+ EINVAL The socket is already bound to an address. This
+ may change in the future: see linux/unix/sock.c
+ for details.
+
+ ENOTSOCK
+ Argument is a descriptor for a file, not a socket.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/bind.man b/ecos/packages/net/tcpip/current/doc/bind.man
new file mode 100644
index 0000000..e5c1fe2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/bind.man
@@ -0,0 +1,58 @@
+NAME
+ bind - bind a name to a socket
+
+SYNOPSIS
+ #include <network.h>
+
+ int bind(int sockfd, struct sockaddr *my_addr, int
+ addrlen);
+
+DESCRIPTION
+ bind gives the socket sockfd the local address my_addr.
+ my_addr is addrlen bytes long. Traditionally, this is
+ called "assigning a name to a socket." (When a socket is
+ created with socket(2), it exists in a name space (address
+ family) but has no name assigned.)
+
+ Before a SOCK_STREAM socket is put into the LISTEN state
+ to receive connections, you usually need to first assign a
+ local address using bind to make the socket visible.
+
+NOTES
+ Binding a name that is not in the abstract namespace in
+ the UNIX domain creates a socket in the file system that
+ must be deleted by the caller when it is no longer needed
+ (using unlink(2)).
+
+ The rules used in name binding vary between communication
+ domains. Consult the manual entries in section 4 for
+ detailed information. For IP see ip(4) and for PF_UNIX see
+ unix(4). If you want to listen to every local interface
+ for IPv4 set the sin_addr member of the IP-specific sock-
+ addr_in to INADDR_ANY. For IP only one socket may be
+ bound to a specific local address/port pair. For TCP a
+ bound local socket endpoint (address/port pair) is
+ unavailable for some time after closing the socket, unless
+ the SO_REUSEADDR flag is set. Note that carelessly setting
+ SO_REUSEADDR might make TCP more unreliable unless PAWS is
+ used (see tcp(4)); the delay is needed to handle old pack-
+ ets still in the network.
+
+ IP sockets may also bind to a broadcast or multicast
+ address.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF sockfd is not a valid descriptor.
+
+ EINVAL The socket is already bound to an address. This
+ may change in the future: see linux/unix/sock.c
+ for details.
+
+ ENOTSOCK
+ Argument is a descriptor for a file, not a socket.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/bridge.html b/ecos/packages/net/tcpip/current/doc/bridge.html
new file mode 100644
index 0000000..7c60680
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/bridge.html
@@ -0,0 +1,319 @@
+<html>
+<body>
+<pre>
+NAME
+ bridge - Ethernet bridge interface
+
+SYNOPSIS
+ pseudo-device bridge 2
+
+DESCRIPTION
+ The bridge device creates a logical link between two or more Ethernet in
+ terfaces. This link between the interfaces selectively forwards frames
+ from each interface on the bridge to every other interface on the bridge.
+ A bridge can serve several services, including, isolation of traffic be
+ tween sets of machines so that traffic local to one set of machines is
+ not available on the wire of another set of machines, and it can act as a
+ transparent filter for ip(4) datagrams.
+
+ The bridges provided by this interface are learning bridges with IP fil
+ tering, see ipf(4). In general a bridge works like a hub, forwarding
+ traffic from one interface to another. It differs from a hub in that it
+ will "learn" which machines are on each of its attached segments by ac
+ tively listening to incoming traffic and examining the headers of each
+ frame. A table is built containing the MAC address and segment to which
+ the MAC address is attached. This allows a bridge to be more selective
+ about what it forwards, which can be used to reduce traffic on a set of
+ segments and also to provide an IP firewall without changing the topology
+ of the network.
+
+ The algorithm works as follows by default, but can be modified via
+ ioctl(2) or the utility brconfig(8). When a frame comes in, the origin
+ segment and the source address are recorded. If the bridge has no knowl
+ edge about where the destination is to be found, the bridge will forward
+ the frame to all attached segments. If the destination is known to be on
+ a different segment from its origin, the bridge will forward the packet
+ only to the destination segment. If the destination is on the same seg
+ ment as the origin segment, the bridge will drop the packet because the
+ receiver has already had a chance to see the frame. Before forwarding a
+ frame, the bridge will check to see if the packet contains an ip(4) data
+ gram; if so, the datagram is run through the ipf(4) interface so that it
+ can be filtered. Only the ipf(4) input rules for the source interface
+ are checked with the datagram; output rules have no effect.
+
+IOCTLS
+ A bridge interface responds to all of the ioctl(2) calls specific to oth
+ er interfaces listed in netintro(4). The following ioctl(2) calls are
+ specific to bridge devices. They are defined in <sys/sockio.h>.
+
+ SIOCBRDGIFS (struct ifbifconf) Retrieve member interface list from a
+ bridge. This request takes an ifbifconf structure (see
+ below) as a value-result parameter. The ifbic_len field
+ should be initially set to the size of the buffer point
+ ed to by ifbic_buf. On return it will contain the
+ length, in bytes, of the configuration list. Alterna
+ tively, if the ifbic_len passed in is set to 0,
+ SIOCBRDGIFS will set ifbic_len to the size that
+ ifbic_buf needs to be to fit the entire configuration
+ list, and will not fill in the other parameters. This
+ is useful for determining the exact size that ifbic_buf
+ needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbreq {
+ char ifbr_name[IFNAMSIZ]; /* brdg nam */
+ char ifbr_ifsname[IFNAMSIZ]; /* if name */
+ u_int32_t ifbr_ifsflags; /* if flags */
+ };
+
+ #define IFBIF_LEARNING 0x1 /* learns addrs */
+ #define IFBIF_DISCOVER 0x2 /* gets fwd'd pkts */
+
+ struct ifbifconf {
+ char ifbic_name[IFNAMSIZ]; /* brdg name */
+ u_int32_t ifbic_len; /* buf size */
+ union {
+ caddr_t ifbicu_buf; /* buffer */
+ struct ifbreq *ifbicu_req;
+ } ifbic_ifbicu;
+ #define ifbic_buf ifbic_ifbicu.ifbicu_buf
+ #define ifbic_req ifbic_ifbicu.ifbicu_req
+ };
+
+ SIOCBRDGADD (struct ifbreq) Add the interface named in ifbr_ifsname
+ to the bridge named in ifbr_name.
+
+ SIOCBRDGDEL (struct ifbreq) Delete the interface named in
+ ifbr_ifsname from the bridge named in ifbr_name.
+
+ SIOCBRDGSIFFLGS (struct ifbreq) Set the bridge member interface flags
+ for the interface named in ifbr_ifsname attached to the
+ bridge ifbr_name. If the flag IFBIF_LEARNING is set on
+ an interface, source addresses from frames received on
+ the interface are recorded in the address cache. If the
+ flag IFBIF_DISCOVER is set, the interface will receive
+ packets destined for unknown destinations, otherwise a
+ frame that has a destination not found in the address
+ cache is not forwarded to this interface. The default
+ for newly added interfaces has both flags set. If the
+ flag IFBIF_BLOCKNONIP is set, packets that are one of
+ ip(4), ip6(4), arp(4), or Reverse ARP, will not be
+ bridged from and to the interface.
+
+ SIOCBRDGGIFFLGS Retrieve the bridge member interface flags for the in
+ terface named in ifbr_ifsname attached to the bridge
+ ifbr_name.
+
+ SIOCBRDGRTS (struct ifbaconf) Retrieve the address cache of the
+ bridge named in ifbac_name. This request takes an
+ ifbaconf structure (see below) as a value result parame
+ ter. The ifbac_len field should be initially set to the
+ size of the buffer pointed to by ifbac_buf. On return,
+ it will contain the length, in bytes, of the configura
+ tion list. Alternatively, if the ifbac_len passed in is
+ set to 0, SIOCBRDGRTS will set it to the size that
+ ifbac_buf needs to be to fit the entire configuration
+ list and not fill in the other parameters. As with
+ SIOCBRDGIFS, this is useful for determining the exact
+ size that ifbac_buf needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbareq {
+ char ifba_name[IFNAMSIZ]; /* brdg nam */
+ char ifba_ifsname[IFNAMSIZ];/* dest ifs */
+ u_int8_t ifba_age; /* addr age */
+ u_int8_t ifba_flags; /* addr flag */
+ struct ether_addr ifba_dst; /* dst addr */
+ };
+
+ #define IFBAF_TYPEMASK 0x03 /* addr type mask */
+ #define IFBAF_DYNAMIC 0x00 /* dynamic addr */
+ #define IFBAF_STATIC 0x01 /* static address */
+
+ struct ifbaconf {
+ char ifbac_name[IFNAMSIZ]; /* brdg name */
+ u_int32_t ifbac_len; /* buf size */
+ union {
+ caddr_t ifbacu_buf; /* buf */
+ struct ifbareq *ifbacu_req;
+ } ifbac_ifbacu;
+ #define ifbac_buf ifbac_ifbacu.ifbacu_buf
+ #define ifbac_req ifbac_ifbacu.ifbacu_req
+ };
+ Address cache entries with the type set to IFBAF_DYNAMIC
+ in ifba_flags are entries learned by the bridge. En
+ tries with the type set to IFBAF_STATIC are manually
+ added entries.
+
+ SIOCBRDGSADDR (struct ifbareq) Add an entry, manually, to the address
+ cache for the bridge named in ifba_name. The address and
+ its associated interface and flags are set in the
+ ifba_dst, ifba_ifsname, ifba_flags fields, respectively.
+
+ SIOCBRDGDADDR (struct ifbareq) Delete an entry from the address cache
+ of the bridge named in ifba_name. Entries are deleted
+ strictly based on the address field ifba_dst.
+
+ SIOCBRDGSCACHE (struct ifbcachereq) Set the maximum address cache size
+ for the bridge named in ifbc_name to ifbc_size entries.
+
+ The argument structure is as follows:
+
+ struct ifbcachereq {
+ char ifbc_name[IFNAMSIZ]; /* bridge */
+ u_int32_t ifbc_size; /* size */
+ };
+
+ SIOCBRDGGCACHE (struct ifbcachereq) Retrieve the maximum size of the
+ address cache for the bridge ifbc_name.
+
+ SIOCBRDGSTO (struct ifbcachetoreq) Set the time, in seconds, that
+ addresses which have not been seen on the network
+ (transmitted a packet) remain in the cache. If the time
+ is set to zero, no aging is performed on the address
+ cache. The argument structure is as follows:
+
+ struct ifbcachetoreq {
+ char ifbct_name[IFNAMSIZ]; /* bridge */
+ u_int32_t ifbct_time; /* time */
+ };
+
+ SIOCBRDGGTO (struct ifbcachetoreq) Retrieve the address cache expi
+ ration time (see above).
+
+ SIOCBRDGFLUSH (struct ifbreq) Flush addresses from the cache.
+ ifbr_name contains the name of the bridge device, and
+ ifbr_ifsflags should be set to IFBF_FLUSHALL to flush
+ all addresses from the cache or IFBF_FLUSHDYN to flush
+ only the dynamically learned addresses from the cache.
+
+ SIOCBRDGARL (struct ifbrlreq) Add a filtering rule to the bridge
+ named in ifbr_name on the interface named in
+ ifbr_ifsname. The argument structure is as follows:
+
+ struct ifbrlreq {
+ char ifbr_name[IFNAMSIZ]; /* bridge */
+ char ifbr_ifsname[IFNAMSIZ]; /* ifs */
+ u_int8_t ifbr_action; /* handling */
+ u_int8_t ifbr_flags; /* flags */
+ struct ether_addr ifbr_src; /* src mac */
+ struct ether_addr ifbr_dst; /* dst mac */
+ };
+ #define BRL_ACTION_BLOCK 0x01
+ #define BRL_ACTION_PASS 0x02
+ #define BRL_FLAG_IN 0x08
+ #define BRL_FLAG_OUT 0x04
+ #define BRL_FLAG_SRCVALID 0x02
+ #define BRL_FLAG_DSTVALID 0x01
+
+ Rules are applied in the order in which they were added
+ to the bridge, and the first matching rule's action pa
+ rameter determines the fate of the packet. The
+ ifbr_action parameter specifies whether a frame matching
+ the rule is to be blocked or passed.
+
+ If the BRL_FLAG_IN bit is set in ifbr_flags, then the
+ rule applies to frames received by the interface. If
+ the BRL_FLAG_OUT bit is set, then the rule applies to
+ frame transmitted by the interface. At least one of
+ BRL_FLAG_IN or BRL_FLAG_OUT must be set.
+
+ The source ethernet address in ifbr_src is checked if
+ the BRL_FLAG_SRCVALID bit is set in ifbr_flags. The des
+ tination address in ifbr_dst is check if the
+ BRL_FLAG_DSTVALID bit is set. If neither bit is set,
+ the rule is matches all frames.
+
+ SIOCBRDGFRL (struct ifbrlreq) Remove all filtering rules from a
+ bridge interface member. ifbr_name contains the name of
+ the bridge device, and ifbr_ifsname contains the name of
+ the bridge member interface.
+
+ SIOCBRDGGRL (struct ifbrlconf) Retrieve all of the rules from the
+ bridge, ifbrl_name, for the member interface,
+ ifbrl_ifsname.
+
+ This request takes an ifbrlconf structure (see below) as
+ a value result parameter. The ifbrl_len field should be
+ initially set to the size of the buffer pointed to by
+ ifbrl_buf. On return, it will contain the length, in
+ bytes, of the configuration list. Alternatively, if the
+ ifbrl_len passed in is set to 0, SIOCBRDGGRL will set it
+ to the size that ifbrl_buf needs to be to fit the entire
+ configuration list and not fill in the other parameters.
+ As with SIOCBRDGIFS, this is useful for determining the
+ exact size that ifbrl_buf needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbrlconf {
+ char ifbrl_name[IFNAMSIZ]; /* brdg nam */
+ char ifbrl_ifsname[IFNAMSIZ];/* ifs name */
+ u_int32_t ifbr_len; /* buf len */
+ union {
+ caddr_t ifbrlu_buf;
+ struct ifbrlreq *ifbrlu_req;
+ } ifrl_ifbrlu;
+ #define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf
+ #define ifbrl_req ifbrl_ifbrlu.ifbrlu_req
+ };
+
+
+ERRORS
+ If the ioctl(2) call fails, errno(2) is set to one of the following val
+ ues:
+
+ [ENOENT] For an add request, this means that the named interface is
+ not configured into the system. For delete operation, it
+ means that the named interface is not a member of the
+ bridge. For a address cache deletion, the address was not
+ found in the table.
+
+ [ENOMEM] Memory could not be allocated for an interface or cache en
+ try to be added to the bridge.
+
+ [EEXIST] The named interface is already a member of the bridge.
+
+ [EBUSY] The named interface is already a member of another bridge.
+
+ [EINVAL] The named interface is not an Ethernet interface or an in
+ valid ioctl was performed on the bridge.
+
+ [ENETDOWN] Address cache operation (flush, add, delete) on a bridge
+ that is in the down state.
+
+ [EPERM] Super-user privilege is required to add and delete inter
+ faces to and from bridges and to set the bridge interface
+ flags.
+
+ [EFAULT] The buffer used in a SIOCBRDGIFS or SIOCBRDGRTS request
+
+ points outside of the process's allocated address space.
+
+ [ESRCH] No such member interface in the bridge.
+
+SEE ALSO
+ errno(2), ioctl(2), ip(4), ipf(4), netintro(4), bridgename.if(5),
+ brconfig(8)
+
+HISTORY
+ The brconfig(8) command and the bridge(4) kernel interface first appeared
+ in
+
+AUTHOR
+ The brconfig(8) command and the bridge(4) kernel interface were written
+ by Jason L. Wright <jason@thought.net> as part of an undergraduate inde
+ pendent study at the University of North Carolina at Greensboro.
+
+BUGS
+ There is currently no loop detection. Care must be taken to make sure
+ that loops are not created when a bridge is brought up.
+
+ Only ipf(4) input rules are checked with incoming packet; there is no
+ easy way to handle output rules.
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/bridge.man b/ecos/packages/net/tcpip/current/doc/bridge.man
new file mode 100644
index 0000000..9ee47d1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/bridge.man
@@ -0,0 +1,314 @@
+
+NAME
+ bridge - Ethernet bridge interface
+
+SYNOPSIS
+ pseudo-device bridge 2
+
+DESCRIPTION
+ The bridge device creates a logical link between two or more Ethernet in
+ terfaces. This link between the interfaces selectively forwards frames
+ from each interface on the bridge to every other interface on the bridge.
+ A bridge can serve several services, including, isolation of traffic be
+ tween sets of machines so that traffic local to one set of machines is
+ not available on the wire of another set of machines, and it can act as a
+ transparent filter for ip(4) datagrams.
+
+ The bridges provided by this interface are learning bridges with IP fil
+ tering, see ipf(4). In general a bridge works like a hub, forwarding
+ traffic from one interface to another. It differs from a hub in that it
+ will "learn" which machines are on each of its attached segments by ac
+ tively listening to incoming traffic and examining the headers of each
+ frame. A table is built containing the MAC address and segment to which
+ the MAC address is attached. This allows a bridge to be more selective
+ about what it forwards, which can be used to reduce traffic on a set of
+ segments and also to provide an IP firewall without changing the topology
+ of the network.
+
+ The algorithm works as follows by default, but can be modified via
+ ioctl(2) or the utility brconfig(8). When a frame comes in, the origin
+ segment and the source address are recorded. If the bridge has no knowl
+ edge about where the destination is to be found, the bridge will forward
+ the frame to all attached segments. If the destination is known to be on
+ a different segment from its origin, the bridge will forward the packet
+ only to the destination segment. If the destination is on the same seg
+ ment as the origin segment, the bridge will drop the packet because the
+ receiver has already had a chance to see the frame. Before forwarding a
+ frame, the bridge will check to see if the packet contains an ip(4) data
+ gram; if so, the datagram is run through the ipf(4) interface so that it
+ can be filtered. Only the ipf(4) input rules for the source interface
+ are checked with the datagram; output rules have no effect.
+
+IOCTLS
+ A bridge interface responds to all of the ioctl(2) calls specific to oth
+ er interfaces listed in netintro(4). The following ioctl(2) calls are
+ specific to bridge devices. They are defined in <sys/sockio.h>.
+
+ SIOCBRDGIFS (struct ifbifconf) Retrieve member interface list from a
+ bridge. This request takes an ifbifconf structure (see
+ below) as a value-result parameter. The ifbic_len field
+ should be initially set to the size of the buffer point
+ ed to by ifbic_buf. On return it will contain the
+ length, in bytes, of the configuration list. Alterna
+ tively, if the ifbic_len passed in is set to 0,
+ SIOCBRDGIFS will set ifbic_len to the size that
+ ifbic_buf needs to be to fit the entire configuration
+ list, and will not fill in the other parameters. This
+ is useful for determining the exact size that ifbic_buf
+ needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbreq {
+ char ifbr_name[IFNAMSIZ]; /* brdg nam */
+ char ifbr_ifsname[IFNAMSIZ]; /* if name */
+ u_int32_t ifbr_ifsflags; /* if flags */
+ };
+
+ #define IFBIF_LEARNING 0x1 /* learns addrs */
+ #define IFBIF_DISCOVER 0x2 /* gets fwd'd pkts */
+
+ struct ifbifconf {
+ char ifbic_name[IFNAMSIZ]; /* brdg name */
+ u_int32_t ifbic_len; /* buf size */
+ union {
+ caddr_t ifbicu_buf; /* buffer */
+ struct ifbreq *ifbicu_req;
+ } ifbic_ifbicu;
+ #define ifbic_buf ifbic_ifbicu.ifbicu_buf
+ #define ifbic_req ifbic_ifbicu.ifbicu_req
+ };
+
+ SIOCBRDGADD (struct ifbreq) Add the interface named in ifbr_ifsname
+ to the bridge named in ifbr_name.
+
+ SIOCBRDGDEL (struct ifbreq) Delete the interface named in
+ ifbr_ifsname from the bridge named in ifbr_name.
+
+ SIOCBRDGSIFFLGS (struct ifbreq) Set the bridge member interface flags
+ for the interface named in ifbr_ifsname attached to the
+ bridge ifbr_name. If the flag IFBIF_LEARNING is set on
+ an interface, source addresses from frames received on
+ the interface are recorded in the address cache. If the
+ flag IFBIF_DISCOVER is set, the interface will receive
+ packets destined for unknown destinations, otherwise a
+ frame that has a destination not found in the address
+ cache is not forwarded to this interface. The default
+ for newly added interfaces has both flags set. If the
+ flag IFBIF_BLOCKNONIP is set, packets that are one of
+ ip(4), ip6(4), arp(4), or Reverse ARP, will not be
+ bridged from and to the interface.
+
+ SIOCBRDGGIFFLGS Retrieve the bridge member interface flags for the in
+ terface named in ifbr_ifsname attached to the bridge
+ ifbr_name.
+
+ SIOCBRDGRTS (struct ifbaconf) Retrieve the address cache of the
+ bridge named in ifbac_name. This request takes an
+ ifbaconf structure (see below) as a value result parame
+ ter. The ifbac_len field should be initially set to the
+ size of the buffer pointed to by ifbac_buf. On return,
+ it will contain the length, in bytes, of the configura
+ tion list. Alternatively, if the ifbac_len passed in is
+ set to 0, SIOCBRDGRTS will set it to the size that
+ ifbac_buf needs to be to fit the entire configuration
+ list and not fill in the other parameters. As with
+ SIOCBRDGIFS, this is useful for determining the exact
+ size that ifbac_buf needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbareq {
+ char ifba_name[IFNAMSIZ]; /* brdg nam */
+ char ifba_ifsname[IFNAMSIZ];/* dest ifs */
+ u_int8_t ifba_age; /* addr age */
+ u_int8_t ifba_flags; /* addr flag */
+ struct ether_addr ifba_dst; /* dst addr */
+ };
+
+ #define IFBAF_TYPEMASK 0x03 /* addr type mask */
+ #define IFBAF_DYNAMIC 0x00 /* dynamic addr */
+ #define IFBAF_STATIC 0x01 /* static address */
+
+ struct ifbaconf {
+ char ifbac_name[IFNAMSIZ]; /* brdg name */
+ u_int32_t ifbac_len; /* buf size */
+ union {
+ caddr_t ifbacu_buf; /* buf */
+ struct ifbareq *ifbacu_req;
+ } ifbac_ifbacu;
+ #define ifbac_buf ifbac_ifbacu.ifbacu_buf
+ #define ifbac_req ifbac_ifbacu.ifbacu_req
+ };
+ Address cache entries with the type set to IFBAF_DYNAMIC
+ in ifba_flags are entries learned by the bridge. En
+ tries with the type set to IFBAF_STATIC are manually
+ added entries.
+
+ SIOCBRDGSADDR (struct ifbareq) Add an entry, manually, to the address
+ cache for the bridge named in ifba_name. The address and
+ its associated interface and flags are set in the
+ ifba_dst, ifba_ifsname, ifba_flags fields, respectively.
+
+ SIOCBRDGDADDR (struct ifbareq) Delete an entry from the address cache
+ of the bridge named in ifba_name. Entries are deleted
+ strictly based on the address field ifba_dst.
+
+ SIOCBRDGSCACHE (struct ifbcachereq) Set the maximum address cache size
+ for the bridge named in ifbc_name to ifbc_size entries.
+
+ The argument structure is as follows:
+
+ struct ifbcachereq {
+ char ifbc_name[IFNAMSIZ]; /* bridge */
+ u_int32_t ifbc_size; /* size */
+ };
+
+ SIOCBRDGGCACHE (struct ifbcachereq) Retrieve the maximum size of the
+ address cache for the bridge ifbc_name.
+
+ SIOCBRDGSTO (struct ifbcachetoreq) Set the time, in seconds, that
+ addresses which have not been seen on the network
+ (transmitted a packet) remain in the cache. If the time
+ is set to zero, no aging is performed on the address
+ cache. The argument structure is as follows:
+
+ struct ifbcachetoreq {
+ char ifbct_name[IFNAMSIZ]; /* bridge */
+ u_int32_t ifbct_time; /* time */
+ };
+
+ SIOCBRDGGTO (struct ifbcachetoreq) Retrieve the address cache expi
+ ration time (see above).
+
+ SIOCBRDGFLUSH (struct ifbreq) Flush addresses from the cache.
+ ifbr_name contains the name of the bridge device, and
+ ifbr_ifsflags should be set to IFBF_FLUSHALL to flush
+ all addresses from the cache or IFBF_FLUSHDYN to flush
+ only the dynamically learned addresses from the cache.
+
+ SIOCBRDGARL (struct ifbrlreq) Add a filtering rule to the bridge
+ named in ifbr_name on the interface named in
+ ifbr_ifsname. The argument structure is as follows:
+
+ struct ifbrlreq {
+ char ifbr_name[IFNAMSIZ]; /* bridge */
+ char ifbr_ifsname[IFNAMSIZ]; /* ifs */
+ u_int8_t ifbr_action; /* handling */
+ u_int8_t ifbr_flags; /* flags */
+ struct ether_addr ifbr_src; /* src mac */
+ struct ether_addr ifbr_dst; /* dst mac */
+ };
+ #define BRL_ACTION_BLOCK 0x01
+ #define BRL_ACTION_PASS 0x02
+ #define BRL_FLAG_IN 0x08
+ #define BRL_FLAG_OUT 0x04
+ #define BRL_FLAG_SRCVALID 0x02
+ #define BRL_FLAG_DSTVALID 0x01
+
+ Rules are applied in the order in which they were added
+ to the bridge, and the first matching rule's action pa
+ rameter determines the fate of the packet. The
+ ifbr_action parameter specifies whether a frame matching
+ the rule is to be blocked or passed.
+
+ If the BRL_FLAG_IN bit is set in ifbr_flags, then the
+ rule applies to frames received by the interface. If
+ the BRL_FLAG_OUT bit is set, then the rule applies to
+ frame transmitted by the interface. At least one of
+ BRL_FLAG_IN or BRL_FLAG_OUT must be set.
+
+ The source ethernet address in ifbr_src is checked if
+ the BRL_FLAG_SRCVALID bit is set in ifbr_flags. The des
+ tination address in ifbr_dst is check if the
+ BRL_FLAG_DSTVALID bit is set. If neither bit is set,
+ the rule is matches all frames.
+
+ SIOCBRDGFRL (struct ifbrlreq) Remove all filtering rules from a
+ bridge interface member. ifbr_name contains the name of
+ the bridge device, and ifbr_ifsname contains the name of
+ the bridge member interface.
+
+ SIOCBRDGGRL (struct ifbrlconf) Retrieve all of the rules from the
+ bridge, ifbrl_name, for the member interface,
+ ifbrl_ifsname.
+
+ This request takes an ifbrlconf structure (see below) as
+ a value result parameter. The ifbrl_len field should be
+ initially set to the size of the buffer pointed to by
+ ifbrl_buf. On return, it will contain the length, in
+ bytes, of the configuration list. Alternatively, if the
+ ifbrl_len passed in is set to 0, SIOCBRDGGRL will set it
+ to the size that ifbrl_buf needs to be to fit the entire
+ configuration list and not fill in the other parameters.
+ As with SIOCBRDGIFS, this is useful for determining the
+ exact size that ifbrl_buf needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbrlconf {
+ char ifbrl_name[IFNAMSIZ]; /* brdg nam */
+ char ifbrl_ifsname[IFNAMSIZ];/* ifs name */
+ u_int32_t ifbr_len; /* buf len */
+ union {
+ caddr_t ifbrlu_buf;
+ struct ifbrlreq *ifbrlu_req;
+ } ifrl_ifbrlu;
+ #define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf
+ #define ifbrl_req ifbrl_ifbrlu.ifbrlu_req
+ };
+
+
+ERRORS
+ If the ioctl(2) call fails, errno(2) is set to one of the following val
+ ues:
+
+ [ENOENT] For an add request, this means that the named interface is
+ not configured into the system. For delete operation, it
+ means that the named interface is not a member of the
+ bridge. For a address cache deletion, the address was not
+ found in the table.
+
+ [ENOMEM] Memory could not be allocated for an interface or cache en
+ try to be added to the bridge.
+
+ [EEXIST] The named interface is already a member of the bridge.
+
+ [EBUSY] The named interface is already a member of another bridge.
+
+ [EINVAL] The named interface is not an Ethernet interface or an in
+ valid ioctl was performed on the bridge.
+
+ [ENETDOWN] Address cache operation (flush, add, delete) on a bridge
+ that is in the down state.
+
+ [EPERM] Super-user privilege is required to add and delete inter
+ faces to and from bridges and to set the bridge interface
+ flags.
+
+ [EFAULT] The buffer used in a SIOCBRDGIFS or SIOCBRDGRTS request
+
+ points outside of the process's allocated address space.
+
+ [ESRCH] No such member interface in the bridge.
+
+SEE ALSO
+ errno(2), ioctl(2), ip(4), ipf(4), netintro(4), bridgename.if(5),
+ brconfig(8)
+
+HISTORY
+ The brconfig(8) command and the bridge(4) kernel interface first appeared
+ in
+
+AUTHOR
+ The brconfig(8) command and the bridge(4) kernel interface were written
+ by Jason L. Wright <jason@thought.net> as part of an undergraduate inde
+ pendent study at the University of North Carolina at Greensboro.
+
+BUGS
+ There is currently no loop detection. Care must be taken to make sure
+ that loops are not created when a bridge is brought up.
+
+ Only ipf(4) input rules are checked with incoming packet; there is no
+ easy way to handle output rules.
+
diff --git a/ecos/packages/net/tcpip/current/doc/close.html b/ecos/packages/net/tcpip/current/doc/close.html
new file mode 100644
index 0000000..346de16
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/close.html
@@ -0,0 +1,27 @@
+<html>
+<body>
+<pre>
+NAME
+ close - close a file descriptor
+
+SYNOPSIS
+
+ int close(int fd);
+
+DESCRIPTION
+ close closes a file descriptor, so that it no longer
+ refers to any file and may be reused.
+
+ If fd is the last copy of a particular file descriptor the
+ resources associated with it are freed.
+
+RETURN VALUE
+ close returns zero on success, or -1 if an error occurred.
+
+ERRORS
+ EBADF fd isn't a valid open file descriptor.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/close.man b/ecos/packages/net/tcpip/current/doc/close.man
new file mode 100644
index 0000000..0c202d2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/close.man
@@ -0,0 +1,21 @@
+NAME
+ close - close a file descriptor
+
+SYNOPSIS
+
+ int close(int fd);
+
+DESCRIPTION
+ close closes a file descriptor, so that it no longer
+ refers to any file and may be reused.
+
+ If fd is the last copy of a particular file descriptor the
+ resources associated with it are freed.
+
+RETURN VALUE
+ close returns zero on success, or -1 if an error occurred.
+
+ERRORS
+ EBADF fd isn't a valid open file descriptor.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/connect.html b/ecos/packages/net/tcpip/current/doc/connect.html
new file mode 100644
index 0000000..b239f8a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/connect.html
@@ -0,0 +1,81 @@
+<html>
+<body>
+<pre>
+NAME
+ connect - initiate a connection on a socket
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int connect(int sockfd, struct sockaddr *serv_addr, int
+ addrlen);
+
+DESCRIPTION
+ The parameter sockfd is a socket. If the socket is of
+ type SOCK_DGRAM, this call specifies the peer with which
+ the socket is to be associated; this address is that to
+ which datagrams are to be sent, and the only address from
+ which datagrams are to be received. If the socket is of
+ type SOCK_STREAM, this call attempts to make a connection
+ to another socket. The other socket is specified by
+ serv_addr, which is an address in the communications space
+ of the socket. Each communications space interprets the
+ serv_addr parameter in its own way. Generally, stream
+ sockets may successfully connect only once; datagram sock-
+ ets may use connect multiple times to change their associ-
+ ation. Datagram sockets may dissolve the association by
+ connecting to an address with the sa_family sockaddr mem-
+ ber set to AF_UNSPEC.
+
+RETURN VALUE
+ If the connection or binding succeeds, zero is returned.
+ On error, -1 is returned, and errno is set appropriately.
+
+ERRORS
+ The following are general socket errors only. There may
+ be other domain-specific error codes.
+
+ EBADF Bad descriptor.
+
+ ENOTSOCK
+ The descriptor is not associated with a socket.
+
+ EISCONN The socket is already connected.
+
+ ECONNREFUSED
+ Connection refused at server.
+
+ ETIMEDOUT
+ Timeout while attempting connection.
+
+ ENETUNREACH
+ Network is unreachable.
+
+ EADDRINUSE
+ Address is already in use.
+
+ EINPROGRESS
+ The socket is non-blocking and the connection can-
+ not be completed immediately. It is possible to
+ select(2) or poll(2) for completion by selecting
+ the socket for writing. After select indicates
+ writability, use getsockopt(2) to read the
+ SO_ERROR option at level SOL_SOCKET to determine
+ whether connect completed successfully (SO_ERROR
+ is zero) or unsuccessfully (SO_ERROR is one of the
+ usual error codes listed above, explaining the
+ reason for the failure).
+
+ EALREADY
+ The socket is non-blocking and a previous connec-
+ tion attempt has not yet been completed.
+
+ EAFNOSUPPORT
+ The passed address didn't have the correct address
+ family in its sa_family field.
+
+ EACCES The user tried to connect to a broadcast address
+ without having the socket broadcast flag enabled.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/connect.man b/ecos/packages/net/tcpip/current/doc/connect.man
new file mode 100644
index 0000000..e7bc378
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/connect.man
@@ -0,0 +1,75 @@
+NAME
+ connect - initiate a connection on a socket
+
+SYNOPSIS
+ #include <network.h>
+
+ int connect(int sockfd, struct sockaddr *serv_addr, int
+ addrlen);
+
+DESCRIPTION
+ The parameter sockfd is a socket. If the socket is of
+ type SOCK_DGRAM, this call specifies the peer with which
+ the socket is to be associated; this address is that to
+ which datagrams are to be sent, and the only address from
+ which datagrams are to be received. If the socket is of
+ type SOCK_STREAM, this call attempts to make a connection
+ to another socket. The other socket is specified by
+ serv_addr, which is an address in the communications space
+ of the socket. Each communications space interprets the
+ serv_addr parameter in its own way. Generally, stream
+ sockets may successfully connect only once; datagram sock-
+ ets may use connect multiple times to change their associ-
+ ation. Datagram sockets may dissolve the association by
+ connecting to an address with the sa_family sockaddr mem-
+ ber set to AF_UNSPEC.
+
+RETURN VALUE
+ If the connection or binding succeeds, zero is returned.
+ On error, -1 is returned, and errno is set appropriately.
+
+ERRORS
+ The following are general socket errors only. There may
+ be other domain-specific error codes.
+
+ EBADF Bad descriptor.
+
+ ENOTSOCK
+ The descriptor is not associated with a socket.
+
+ EISCONN The socket is already connected.
+
+ ECONNREFUSED
+ Connection refused at server.
+
+ ETIMEDOUT
+ Timeout while attempting connection.
+
+ ENETUNREACH
+ Network is unreachable.
+
+ EADDRINUSE
+ Address is already in use.
+
+ EINPROGRESS
+ The socket is non-blocking and the connection can-
+ not be completed immediately. It is possible to
+ select(2) or poll(2) for completion by selecting
+ the socket for writing. After select indicates
+ writability, use getsockopt(2) to read the
+ SO_ERROR option at level SOL_SOCKET to determine
+ whether connect completed successfully (SO_ERROR
+ is zero) or unsuccessfully (SO_ERROR is one of the
+ usual error codes listed above, explaining the
+ reason for the failure).
+
+ EALREADY
+ The socket is non-blocking and a previous connec-
+ tion attempt has not yet been completed.
+
+ EAFNOSUPPORT
+ The passed address didn't have the correct address
+ family in its sa_family field.
+
+ EACCES The user tried to connect to a broadcast address
+ without having the socket broadcast flag enabled.
diff --git a/ecos/packages/net/tcpip/current/doc/ecos_tcpip.html b/ecos/packages/net/tcpip/current/doc/ecos_tcpip.html
new file mode 100644
index 0000000..f260dc8
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/ecos_tcpip.html
@@ -0,0 +1,88 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; U; Linux 2.2.10 i686) [Netscape]">
+</head>
+<body>
+
+<center>
+<h1>
+TCP/IP Networking for eCos</h1></center>
+eCos now provides a complete TCP/IP networking stack.&nbsp; This package
+was derived from the latest stable release of <a href="http://www.openbsd.org/">OpenBSD</a>.&nbsp;&nbsp;
+At this time, the networking support is considered "beta" quality although
+it is already fully featured and well tested within the eCos environment.
+<p>Ethernet drivers are provided for these standard supported platforms:
+<blockquote>
+<li>
+Motorola PowerPC MBX/860</li>
+
+<li>
+Cirrus Logic EDB72xx</li>
+</blockquote>
+Other drivers for supported platforms are planned or underway.
+<h4>
+Networking Stack Features</h4>
+Since this networking package is based on the venerable BSD code, it is
+very complete and robust.&nbsp; The eCos implementation includes support
+for these protocols:
+<blockquote>
+<li>
+IPv4</li>
+
+<li>
+UDP</li>
+
+<li>
+TCP</li>
+
+<li>
+ICMP</li>
+
+<li>
+raw packet interface</li>
+</blockquote>
+These additional features are also present in the package.&nbsp; However
+they are not yet supported:
+<blockquote>
+<li>
+Berkeley Packet Filter</li>
+
+<li>
+Multi-cast and uni-cast support, including multi-casting routing</li>
+
+<li>
+IPv6</li>
+</blockquote>
+
+<h4>
+Provided Documentation</h4>
+Since the networking package is "beta", documentation is still a bit thin.&nbsp;
+However, you will find a complete set of pages documenting the supported
+networking functions (user code API) <a href="tcpip_library.html">here</a>.
+<h4>
+Ethernet Driver Design</h4>
+Note: Currently, the networking stack only supports ethernet based networking.
+<p>The network drivers use a two-layer design.&nbsp; One layer is hardware
+independent but contains all the stack specific code.&nbsp; The other layer
+is platform dependent and communicates with the hardware independent layer
+via a very simple API.&nbsp; In this way, hardware device drivers can actually
+be used with other stacks, if the same API can be provided by that stack.&nbsp;
+We designed the drivers this way to encourage the development of other
+stacks in eCos while allowing reuse of the actual hardware specific code.
+<p>Complete documentation of the ethernet device driver and the associated
+API can be found in the file <tt>net/drivers/eth/common/<i>version</i>/doc/driver_doc</tt>.
+<h4>
+Sample Code</h4>
+Many examples using the networking support are provided.&nbsp; These are
+arranged as eCos test programs, primarily for us to verify the package,
+but also can serve as useful frameworks for program design.&nbsp; We have
+taken a <i>KISS </i>approach to building programs which use the network.&nbsp;
+A single include file <tt>&lt;network.h></tt> is all that is required to
+access the stack.&nbsp; A complete, annotated test program can be found
+<a href="sample_program.html">here</a>.
+<br>&nbsp;
+<br>&nbsp;
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/gethost.html b/ecos/packages/net/tcpip/current/doc/gethost.html
new file mode 100644
index 0000000..4fd252b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/gethost.html
@@ -0,0 +1,110 @@
+<html>
+<body>
+<pre>
+NAME
+ gethostbyname, gethostbyaddr, herror, hstrerror - get network host entry
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ struct hostent *gethostbyname(const char *name);
+
+ struct hostent *gethostbyaddr(const char *addr, int len, int type);
+
+ void herror(const char *s);
+
+ const char * hstrerror(int err);
+
+DESCRIPTION
+ The gethostbyname() function returns a structure of type
+ hostent for the given host name. Here name is either a
+ host name, or an IPv4 address in standard dot notation, or
+ an IPv6 address in colon (and possibly dot) notation. (See
+ RFC 1884 for the description of IPv6 addresses.) If name
+ is an IPv4 or IPv6 address, no lookup is performed and
+ gethostbyname() simply copies name into the h_name field
+ and its struct in_addr equivalent into the h_addr_list[0]
+ field of the returned hostent structure. If name doesn't
+ end in a dot and the environment variable HOSTALIASES is
+ set, the alias file pointed to by HOSTALIASES will first
+ be searched for name. (See hostname(7) for the file for­
+ mat.) The current domain and its parents are searched
+ unless name ends in a dot.
+
+ The gethostbyaddr() function returns a structure of type
+ hostent for the given host address addr of length len and
+ address type type. The only valid address type is cur­
+ rently AF_INET.
+
+ The (obsolete) herror() function prints the error message
+ associated with the current value of h_errno on stderr.
+
+ The (obsolete) hstrerror() function takes an error number
+ (typically h_errno) and returns the corresponding message
+ string.
+
+ The domain name queries carried out by gethostbyname() and
+ gethostbyaddr() use a combination of any or all of the
+ name server named(8), a broken out line from /etc/hosts,
+ and the Network Information Service (NIS or YP), depending
+ upon the contents of the order line in /etc/host.conf.
+ (See resolv+(8)). The default action is to query
+ named(8), followed by /etc/hosts.
+
+ The hostent structure is defined in &lt;netdb.h&gt; as follows:
+
+ struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses */
+ }
+ #define h_addr h_addr_list[0] /* for backward compatibility */
+
+ The members of the hostent structure are:
+
+ h_name The official name of the host.
+
+ h_aliases
+ A zero-terminated array of alternative names for
+ the host.
+
+ h_addrtype
+ The type of address; always AF_INET at present.
+
+ h_length
+ The length of the address in bytes.
+
+ h_addr_list
+ A zero-terminated array of network addresses for
+ the host in network byte order.
+
+ h_addr The first address in h_addr_list for backward com­
+ patibility.
+
+RETURN VALUE
+ The gethostbyname() and gethostbyaddr() functions return
+ the hostent structure or a NULL pointer if an error
+ occurs. On error, the h_errno variable holds an error
+ number.
+
+ERRORS
+ The variable h_errno can have the following values:
+
+ HOST_NOT_FOUND
+ The specified host is unknown.
+
+ NO_ADDRESS or NO_DATA
+ The requested name is valid but does not have an IP
+ address.
+
+ NO_RECOVERY
+ A non-recoverable name server error occurred.
+
+ TRY_AGAIN
+ A temporary error occurred on an authoritative name
+ server. Try again later.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/gethost.man b/ecos/packages/net/tcpip/current/doc/gethost.man
new file mode 100644
index 0000000..1de98b9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/gethost.man
@@ -0,0 +1,104 @@
+NAME
+ gethostbyname, gethostbyaddr, herror, hstrerror - get network host entry
+
+SYNOPSIS
+ #include <network.h>
+
+ struct hostent *gethostbyname(const char *name);
+
+ struct hostent *gethostbyaddr(const char *addr, int len, int type);
+
+ void herror(const char *s);
+
+ const char * hstrerror(int err);
+
+DESCRIPTION
+ The gethostbyname() function returns a structure of type
+ hostent for the given host name. Here name is either a
+ host name, or an IPv4 address in standard dot notation, or
+ an IPv6 address in colon (and possibly dot) notation. (See
+ RFC 1884 for the description of IPv6 addresses.) If name
+ is an IPv4 or IPv6 address, no lookup is performed and
+ gethostbyname() simply copies name into the h_name field
+ and its struct in_addr equivalent into the h_addr_list[0]
+ field of the returned hostent structure. If name doesn't
+ end in a dot and the environment variable HOSTALIASES is
+ set, the alias file pointed to by HOSTALIASES will first
+ be searched for name. (See hostname(7) for the file for­
+ mat.) The current domain and its parents are searched
+ unless name ends in a dot.
+
+ The gethostbyaddr() function returns a structure of type
+ hostent for the given host address addr of length len and
+ address type type. The only valid address type is cur­
+ rently AF_INET.
+
+ The (obsolete) herror() function prints the error message
+ associated with the current value of h_errno on stderr.
+
+ The (obsolete) hstrerror() function takes an error number
+ (typically h_errno) and returns the corresponding message
+ string.
+
+ The domain name queries carried out by gethostbyname() and
+ gethostbyaddr() use a combination of any or all of the
+ name server named(8), a broken out line from /etc/hosts,
+ and the Network Information Service (NIS or YP), depending
+ upon the contents of the order line in /etc/host.conf.
+ (See resolv+(8)). The default action is to query
+ named(8), followed by /etc/hosts.
+
+ The hostent structure is defined in <netdb.h> as follows:
+
+ struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses */
+ }
+ #define h_addr h_addr_list[0] /* for backward compatibility */
+
+ The members of the hostent structure are:
+
+ h_name The official name of the host.
+
+ h_aliases
+ A zero-terminated array of alternative names for
+ the host.
+
+ h_addrtype
+ The type of address; always AF_INET at present.
+
+ h_length
+ The length of the address in bytes.
+
+ h_addr_list
+ A zero-terminated array of network addresses for
+ the host in network byte order.
+
+ h_addr The first address in h_addr_list for backward com­
+ patibility.
+
+RETURN VALUE
+ The gethostbyname() and gethostbyaddr() functions return
+ the hostent structure or a NULL pointer if an error
+ occurs. On error, the h_errno variable holds an error
+ number.
+
+ERRORS
+ The variable h_errno can have the following values:
+
+ HOST_NOT_FOUND
+ The specified host is unknown.
+
+ NO_ADDRESS or NO_DATA
+ The requested name is valid but does not have an IP
+ address.
+
+ NO_RECOVERY
+ A non-recoverable name server error occurred.
+
+ TRY_AGAIN
+ A temporary error occurred on an authoritative name
+ server. Try again later.
diff --git a/ecos/packages/net/tcpip/current/doc/getpeername.html b/ecos/packages/net/tcpip/current/doc/getpeername.html
new file mode 100644
index 0000000..325b75d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getpeername.html
@@ -0,0 +1,40 @@
+<html>
+<body>
+<pre>
+NAME
+ getpeername - get name of connected peer
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int getpeername(int s, struct sockaddr *name, socklen_t
+ *namelen);
+
+DESCRIPTION
+ Getpeername returns the name of the peer connected to
+ socket s. The namelen parameter should be initialized to
+ indicate the amount of space pointed to by name. On
+ return it contains the actual size of the name returned
+ (in bytes). The name is truncated if the buffer provided
+ is too small.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOTCONN
+ The socket is not connected.
+
+ ENOBUFS Insufficient resources were available in the sys-
+ tem to perform the operation.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/getpeername.man b/ecos/packages/net/tcpip/current/doc/getpeername.man
new file mode 100644
index 0000000..4973dc3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getpeername.man
@@ -0,0 +1,34 @@
+NAME
+ getpeername - get name of connected peer
+
+SYNOPSIS
+ #include <network.h>
+
+ int getpeername(int s, struct sockaddr *name, socklen_t
+ *namelen);
+
+DESCRIPTION
+ Getpeername returns the name of the peer connected to
+ socket s. The namelen parameter should be initialized to
+ indicate the amount of space pointed to by name. On
+ return it contains the actual size of the name returned
+ (in bytes). The name is truncated if the buffer provided
+ is too small.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOTCONN
+ The socket is not connected.
+
+ ENOBUFS Insufficient resources were available in the sys-
+ tem to perform the operation.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/getproto.html b/ecos/packages/net/tcpip/current/doc/getproto.html
new file mode 100644
index 0000000..61eaf65
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getproto.html
@@ -0,0 +1,48 @@
+<html>
+<body>
+<pre>
+NAME
+ getprotobyname, getprotobynumber - get protocol entry
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ struct protoent *getprotobyname(const char *name);
+
+ struct protoent *getprotobynumber(int proto);
+
+DESCRIPTION
+ The getprotobyname() function returns a protoent structure
+ for the line from /etc/protocols that matches the protocol
+ name name.
+
+ The getprotobynumber() function returns a protoent struc­
+ ture for the line that matches the protocol number number.
+
+ The protoent structure is defined in <netdb.h> as follows:
+
+ struct protoent {
+ char *p_name; /* official protocol name */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol number */
+ }
+
+ The members of the protoent structure are:
+
+ p_name The official name of the protocol.
+
+ p_aliases
+ A zero terminated list of alternative names for the
+ protocol.
+ p_proto
+ The protocol number.
+
+RETURN VALUE
+ The getprotobyname() and getprotobynumber()
+ functions return the protoent structure, or a NULL pointer
+ if an error occurs.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/getproto.man b/ecos/packages/net/tcpip/current/doc/getproto.man
new file mode 100644
index 0000000..4286b88
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getproto.man
@@ -0,0 +1,42 @@
+NAME
+ getprotobyname, getprotobynumber - get protocol entry
+
+SYNOPSIS
+ #include <network.h>
+
+ struct protoent *getprotobyname(const char *name);
+
+ struct protoent *getprotobynumber(int proto);
+
+DESCRIPTION
+ The getprotobyname() function returns a protoent structure
+ for the line from /etc/protocols that matches the protocol
+ name name.
+
+ The getprotobynumber() function returns a protoent struc­
+ ture for the line that matches the protocol number number.
+
+ The protoent structure is defined in <netdb.h> as follows:
+
+ struct protoent {
+ char *p_name; /* official protocol name */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol number */
+ }
+
+ The members of the protoent structure are:
+
+ p_name The official name of the protocol.
+
+ p_aliases
+ A zero terminated list of alternative names for the
+ protocol.
+ p_proto
+ The protocol number.
+
+RETURN VALUE
+ The getprotobyname() and getprotobynumber()
+ functions return the protoent structure, or a NULL pointer
+ if an error occurs.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/getserv.html b/ecos/packages/net/tcpip/current/doc/getserv.html
new file mode 100644
index 0000000..68562ee
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getserv.html
@@ -0,0 +1,54 @@
+<html>
+<body>
+<pre>
+NAME
+ getservent, getservbyname, getservbyport - get service entry
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ struct servent *getservbyname(const char *name, const char *proto);
+
+ struct servent *getservbyport(int port, const char *proto);
+
+DESCRIPTION
+ The getservbyname() function returns a servent structure
+ for the line from /etc/services that matches the service
+ name using protocol proto.
+
+ The getservbyport() function returns a servent structure
+ for the line that matches the port port given in network
+ byte order using protocol proto.
+
+ The servent structure is defined in &lt;netdb.h&gt; as follows:
+
+ struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port number */
+ char *s_proto; /* protocol to use */
+ }
+
+ The members of the servent structure are:
+
+ s_name The official name of the service.
+
+ s_aliases
+ A zero terminated list of alternative names for the
+ service.
+
+ s_port The port number for the service given in network
+ byte order.
+
+ s_proto
+ The name of the protocol to use with this service.
+
+RETURN VALUE
+ The getservbyname() and getservbyport()
+ functions return the servent structure, or a NULL pointer
+ if an error occurs.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/getserv.man b/ecos/packages/net/tcpip/current/doc/getserv.man
new file mode 100644
index 0000000..3c32189
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getserv.man
@@ -0,0 +1,48 @@
+NAME
+ getservent, getservbyname, getservbyport - get service entry
+
+SYNOPSIS
+ #include <network.h>
+
+ struct servent *getservbyname(const char *name, const char *proto);
+
+ struct servent *getservbyport(int port, const char *proto);
+
+DESCRIPTION
+ The getservbyname() function returns a servent structure
+ for the line from /etc/services that matches the service
+ name using protocol proto.
+
+ The getservbyport() function returns a servent structure
+ for the line that matches the port port given in network
+ byte order using protocol proto.
+
+ The servent structure is defined in <netdb.h> as follows:
+
+ struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port number */
+ char *s_proto; /* protocol to use */
+ }
+
+ The members of the servent structure are:
+
+ s_name The official name of the service.
+
+ s_aliases
+ A zero terminated list of alternative names for the
+ service.
+
+ s_port The port number for the service given in network
+ byte order.
+
+ s_proto
+ The name of the protocol to use with this service.
+
+RETURN VALUE
+ The getservbyname() and getservbyport()
+ functions return the servent structure, or a NULL pointer
+ if an error occurs.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/getsockname.html b/ecos/packages/net/tcpip/current/doc/getsockname.html
new file mode 100644
index 0000000..1aa848b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getsockname.html
@@ -0,0 +1,37 @@
+<html>
+<body>
+<pre>
+NAME
+ getsockname - get socket name
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int getsockname(int s , struct sockaddr * name ,
+ socklen_t * namelen )
+
+DESCRIPTION
+ Getsockname returns the current name for the specified
+ socket. The namelen parameter should be initialized to
+ indicate the amount of space pointed to by name. On
+ return it contains the actual size of the name returned
+ (in bytes).
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately. A 0 is returned if the
+ call succeeds, -1 if it fails.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOBUFS Insufficient resources were available in the sys-
+ tem to perform the operation.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/getsockname.man b/ecos/packages/net/tcpip/current/doc/getsockname.man
new file mode 100644
index 0000000..b281313
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getsockname.man
@@ -0,0 +1,31 @@
+NAME
+ getsockname - get socket name
+
+SYNOPSIS
+ #include <network.h>
+
+ int getsockname(int s , struct sockaddr * name ,
+ socklen_t * namelen )
+
+DESCRIPTION
+ Getsockname returns the current name for the specified
+ socket. The namelen parameter should be initialized to
+ indicate the amount of space pointed to by name. On
+ return it contains the actual size of the name returned
+ (in bytes).
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately. A 0 is returned if the
+ call succeeds, -1 if it fails.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOBUFS Insufficient resources were available in the sys-
+ tem to perform the operation.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/getsockopt.html b/ecos/packages/net/tcpip/current/doc/getsockopt.html
new file mode 100644
index 0000000..39bfdaa
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getsockopt.html
@@ -0,0 +1,70 @@
+<html>
+<body>
+<pre>
+NAME
+ getsockopt, setsockopt - get and set options on sockets
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int getsockopt(int s, int level, int optname, void *opt­
+ val, socklen_t *optlen);
+
+ int setsockopt(int s, int level, int optname, const void
+ *optval, socklen_t optlen);
+
+DESCRIPTION
+ Getsockopt and setsockopt manipulate the options associ­
+ ated with a socket. Options may exist at multiple proto­
+ col levels; they are always present at the uppermost
+ socket level.
+
+ When manipulating socket options the level at which the
+ option resides and the name of the option must be speci­
+ fied. To manipulate options at the socket level, level is
+ specified as SOL_SOCKET. To manipulate options at any
+ other level the protocol number of the appropriate proto­
+ col controlling the option is supplied. For example, to
+ indicate that an option is to be interpreted by the TCP
+ protocol, level should be set to the protocol number of
+ TCP; see getprotoent(3).
+
+ The parameters optval and optlen are used to access option
+ values for setsockopt. For getsockopt they identify a
+ buffer in which the value for the requested option(s) are
+ to be returned. For getsockopt, optlen is a value-result
+ parameter, initially containing the size of the buffer
+ pointed to by optval, and modified on return to indicate
+ the actual size of the value returned. If no option value
+ is to be supplied or returned, optval may be NULL.
+
+ Optname and any specified options are passed uninterpreted
+ to the appropriate protocol module for interpretation.
+ The include file &lt;network.h&gt; contains definitions for
+ socket level options, described below. Options at other
+ protocol levels vary in format and name; consult the
+ appropriate entries in section 4 of the manual.
+
+ Most socket-level options utilize an int parameter for
+ optval. For setsockopt, the parameter should be non-zero
+ to enable a boolean option, or zero if the option is to be
+ disabled.
+
+ For a description of the available socket options see
+ socket(7) and the appropriate protocol man pages.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOPROTOOPT
+ The option is unknown at the level indicated.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/getsockopt.man b/ecos/packages/net/tcpip/current/doc/getsockopt.man
new file mode 100644
index 0000000..e2c7173
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/getsockopt.man
@@ -0,0 +1,65 @@
+NAME
+ getsockopt, setsockopt - get and set options on sockets
+
+SYNOPSIS
+ #include <network.h>
+
+
+ int getsockopt(int s, int level, int optname, void *opt­
+ val, socklen_t *optlen);
+
+ int setsockopt(int s, int level, int optname, const void
+ *optval, socklen_t optlen);
+
+DESCRIPTION
+ Getsockopt and setsockopt manipulate the options associ­
+ ated with a socket. Options may exist at multiple proto­
+ col levels; they are always present at the uppermost
+ socket level.
+
+ When manipulating socket options the level at which the
+ option resides and the name of the option must be speci­
+ fied. To manipulate options at the socket level, level is
+ specified as SOL_SOCKET. To manipulate options at any
+ other level the protocol number of the appropriate proto­
+ col controlling the option is supplied. For example, to
+ indicate that an option is to be interpreted by the TCP
+ protocol, level should be set to the protocol number of
+ TCP; see getprotoent(3).
+
+ The parameters optval and optlen are used to access option
+ values for setsockopt. For getsockopt they identify a
+ buffer in which the value for the requested option(s) are
+ to be returned. For getsockopt, optlen is a value-result
+ parameter, initially containing the size of the buffer
+ pointed to by optval, and modified on return to indicate
+ the actual size of the value returned. If no option value
+ is to be supplied or returned, optval may be NULL.
+
+ Optname and any specified options are passed uninterpreted
+ to the appropriate protocol module for interpretation.
+ The include file <sys/socket.h> contains definitions for
+ socket level options, described below. Options at other
+ protocol levels vary in format and name; consult the
+ appropriate entries in section 4 of the manual.
+
+ Most socket-level options utilize an int parameter for
+ optval. For setsockopt, the parameter should be non-zero
+ to enable a boolean option, or zero if the option is to be
+ disabled.
+
+ For a description of the available socket options see
+ socket(7) and the appropriate protocol man pages.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOPROTOOPT
+ The option is unknown at the level indicated.
diff --git a/ecos/packages/net/tcpip/current/doc/index.html b/ecos/packages/net/tcpip/current/doc/index.html
new file mode 100644
index 0000000..a51cc9f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/index.html
@@ -0,0 +1,27 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; I; Linux 2.2.14 ppc) [Netscape]">
+</head>
+<body>
+
+<center>
+<h1>
+eCos TCP/IP Networking Documentation (beta)</h1></center>
+&nbsp;
+<li>
+<a href="ecos_tcpip.html">Introduction</a></li>
+
+<li>
+<a href="tcpip_library.html">Library Reference</a></li>
+
+<li>
+<a href="tcpip_config.html">Configuration</a></li>
+
+<li>
+<a href="tcpip_tests.html">Tests and Examples</a></li>
+
+<br>&nbsp;
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/inet_addr.html b/ecos/packages/net/tcpip/current/doc/inet_addr.html
new file mode 100644
index 0000000..b8cca4e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/inet_addr.html
@@ -0,0 +1,40 @@
+<html>
+<body>
+<pre>
+NAME
+ inet_aton, inet_addr, inet_ntoa - Internet address
+ manipulation routines
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int inet_aton(const char *cp, struct in_addr *inp);
+
+ unsigned long int inet_addr(const char *cp);
+
+ char *inet_ntoa(struct in_addr in);
+
+DESCRIPTION
+ inet_aton() converts the Internet host address cp from the
+ standard numbers-and-dots notation into binary data and
+ stores it in the structure that inp points to. inet_aton
+ returns nonzero if the address is valid, zero if not.
+
+ The inet_addr() function converts the Internet host
+ address cp from numbers-and-dots notation into binary data
+ in network byte order. If the input is invalid,
+ INADDR_NONE (usually -1) is returned. This is an obsolete
+ interface to inet_aton, described immediately above; it is
+ obsolete because -1 is a valid address (255.255.255.255),
+ and inet_aton provides a cleaner way to indicate error
+ return.
+
+ The inet_ntoa() function converts the Internet host
+ address in given in network byte order to a string in
+ standard numbers-and-dots notation. The string is
+ returned in a statically allocated buffer, which subse­
+ quent calls will overwrite.
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/inet_addr.man b/ecos/packages/net/tcpip/current/doc/inet_addr.man
new file mode 100644
index 0000000..ddfd725
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/inet_addr.man
@@ -0,0 +1,34 @@
+NAME
+ inet_aton, inet_addr, inet_ntoa - Internet address
+ manipulation routines
+
+SYNOPSIS
+ #include <network.h>
+
+ int inet_aton(const char *cp, struct in_addr *inp);
+
+ unsigned long int inet_addr(const char *cp);
+
+ char *inet_ntoa(struct in_addr in);
+
+DESCRIPTION
+ inet_aton() converts the Internet host address cp from the
+ standard numbers-and-dots notation into binary data and
+ stores it in the structure that inp points to. inet_aton
+ returns nonzero if the address is valid, zero if not.
+
+ The inet_addr() function converts the Internet host
+ address cp from numbers-and-dots notation into binary data
+ in network byte order. If the input is invalid,
+ INADDR_NONE (usually -1) is returned. This is an obsolete
+ interface to inet_aton, described immediately above; it is
+ obsolete because -1 is a valid address (255.255.255.255),
+ and inet_aton provides a cleaner way to indicate error
+ return.
+
+ The inet_ntoa() function converts the Internet host
+ address in given in network byte order to a string in
+ standard numbers-and-dots notation. The string is
+ returned in a statically allocated buffer, which subse­
+ quent calls will overwrite.
+
diff --git a/ecos/packages/net/tcpip/current/doc/ioctl.html b/ecos/packages/net/tcpip/current/doc/ioctl.html
new file mode 100644
index 0000000..216b8c1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/ioctl.html
@@ -0,0 +1,46 @@
+<html>
+<body>
+<pre>
+NAME
+ ioctl - control device
+
+SYNOPSIS
+ #include <sys/ioctl.h>
+
+ int ioctl(int d, int request, ...)
+
+ [The "third" argument is traditionally char *argp, and
+ will be so named for this discussion.]
+
+DESCRIPTION
+ The ioctl function manipulates the underlying device
+ parameters of special files. In particular, many operat-
+ ing characteristics of sockets and network devices
+ may be controlled with ioctl requests. The argu-
+ ment d must be an open file descriptor.
+
+ An ioctl request has encoded in it whether the argument is
+ an in parameter or out parameter, and the size of the
+ argument argp in bytes. Macros and defines used in speci-
+ fying an ioctl request are located in the file
+ <sys/ioctl.h>.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF d is not a valid descriptor.
+
+ EFAULT argp references an inaccessible memory area.
+
+ ENOTTY d is not associated with a character special
+ device.
+
+ ENOTTY The specified request does not apply to the kind of
+ object that the descriptor d references.
+
+ EINVAL Request or argp is not valid.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/ioctl.man b/ecos/packages/net/tcpip/current/doc/ioctl.man
new file mode 100644
index 0000000..eac5cdf
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/ioctl.man
@@ -0,0 +1,40 @@
+NAME
+ ioctl - control device
+
+SYNOPSIS
+ #include <sys/ioctl.h>
+
+ int ioctl(int d, int request, ...)
+
+ [The "third" argument is traditionally char *argp, and
+ will be so named for this discussion.]
+
+DESCRIPTION
+ The ioctl function manipulates the underlying device
+ parameters of special files. In particular, many operat-
+ ing characteristics of sockets and network devices
+ may be controlled with ioctl requests. The argu-
+ ment d must be an open file descriptor.
+
+ An ioctl request has encoded in it whether the argument is
+ an in parameter or out parameter, and the size of the
+ argument argp in bytes. Macros and defines used in speci-
+ fying an ioctl request are located in the file
+ <sys/ioctl.h>.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF d is not a valid descriptor.
+
+ EFAULT argp references an inaccessible memory area.
+
+ ENOTTY d is not associated with a character special
+ device.
+
+ ENOTTY The specified request does not apply to the kind of
+ object that the descriptor d references.
+
+ EINVAL Request or argp is not valid.
diff --git a/ecos/packages/net/tcpip/current/doc/listen.html b/ecos/packages/net/tcpip/current/doc/listen.html
new file mode 100644
index 0000000..1e83775
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/listen.html
@@ -0,0 +1,42 @@
+<html>
+<body>
+<pre>
+NAME
+ listen - listen for connections on a socket
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int listen(int s, int backlog);
+
+DESCRIPTION
+ To accept connections, a socket is first created with
+ socket(2), a willingness to accept incoming connections
+ and a queue limit for incoming connections are specified
+ with listen, and then the connections are accepted with
+ accept(2). The listen call applies only to sockets of
+ type SOCK_STREAM or SOCK_SEQPACKET.
+
+ The backlog parameter defines the maximum length the queue
+ of pending connections may grow to. If a connection
+ request arrives with the queue full the client may receive
+ an error with an indication of ECONNREFUSED or, if the
+ underlying protocol supports retransmission, the request
+ may be ignored so that retries may succeed.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is not a socket.
+
+ EOPNOTSUPP
+ The socket is not of a type that supports the lis-
+ ten operation.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/listen.man b/ecos/packages/net/tcpip/current/doc/listen.man
new file mode 100644
index 0000000..3068ce3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/listen.man
@@ -0,0 +1,36 @@
+NAME
+ listen - listen for connections on a socket
+
+SYNOPSIS
+ #include <network.h>
+
+ int listen(int s, int backlog);
+
+DESCRIPTION
+ To accept connections, a socket is first created with
+ socket(2), a willingness to accept incoming connections
+ and a queue limit for incoming connections are specified
+ with listen, and then the connections are accepted with
+ accept(2). The listen call applies only to sockets of
+ type SOCK_STREAM or SOCK_SEQPACKET.
+
+ The backlog parameter defines the maximum length the queue
+ of pending connections may grow to. If a connection
+ request arrives with the queue full the client may receive
+ an error with an indication of ECONNREFUSED or, if the
+ underlying protocol supports retransmission, the request
+ may be ignored so that retries may succeed.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is not a socket.
+
+ EOPNOTSUPP
+ The socket is not of a type that supports the lis-
+ ten operation.
diff --git a/ecos/packages/net/tcpip/current/doc/openbsd-manpages-bridge.sgml b/ecos/packages/net/tcpip/current/doc/openbsd-manpages-bridge.sgml
new file mode 100644
index 0000000..2db2cb2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/openbsd-manpages-bridge.sgml
@@ -0,0 +1,450 @@
+<!-- {{{ Banner -->
+<!-- All of the documentation and software included in the second BSD Networking -->
+<!-- Software Release is copyrighted by The Regents of the University of California. -->
+
+<!-- Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991 The Regents of the -->
+<!-- University of California. -->
+<!-- All rights reserved. -->
+
+<!-- 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 University 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 REGENTS 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 REGENTS 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. -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- openbsd_bridge.sgml -->
+<!-- -->
+<!-- eCos TCP/IP Stacks -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<SECT1 id="openbsd-manpages-bridge">
+<TITLE>Bridging</TITLE>
+<SCREEN>
+
+NAME
+ bridge - Ethernet bridge interface
+
+SYNOPSIS
+ pseudo-device bridge
+
+DESCRIPTION
+ The bridge device creates a logical link between two or more Ethernet
+ interfaces. This link between the interfaces selectively forwards
+ frames from each interface on the bridge to every other interface on
+ the bridge. A bridge can serve several services, including isolation
+ of traffic between sets of machines so that traffic local to one set of
+ machines is not available on the wire of another set of machines, and
+ it can act as a transparent filter for ip4 datagrams.
+
+ The bridges provided by this interface are learning bridges with filter-
+ ing. In general a bridge works like a hub, forwarding traffic from one
+ interface to another. It differs from a hub in that it will "learn" which
+ machines are on each of its attached segments by actively listening to
+ incoming traffic and examining the headers of each frame. A table is
+ built containing the MAC address and segment to which the MAC address is
+ attached. This allows a bridge to be more selective about what it
+ forwards, which can be used to reduce traffic on a set of segments and
+ also to provide an IP firewall without changing the topology of the
+ network.
+
+ The algorithm works as follows by default, but can be modified via ioctl.
+ When a frame comes in, the origin segment and the source address are
+ recorded. If the bridge has no knowledge about where the destination is
+ to be found, the bridge will forward the frame to all attached segments.
+ If the destination is known to be on a different segment from its origin,
+ the bridge will forward the packet only to the destination segment. If the
+ destination is on the same segment as the origin segment, the bridge will
+ drop the packet because the receiver has already had a chance to see the
+ frame.
+
+IOCTLS
+ A bridge interface responds to all of the ioctl calls specific to oth-
+ er interfaces listed in <link linkend="openbsd-manpages-netintro">netintro</link>. The following ioctl calls are
+ specific to bridge devices. They are defined in &lt;sys/sockio.h>.
+
+ SIOCBRDGIFS (struct ifbifconf) Retrieve member interface list from a
+ bridge. This request takes an ifbifconf structure (see
+ below) as a value-result parameter. The ifbic_len field
+ should be initially set to the size of the buffer point-
+ ed to by ifbic_buf. On return it will contain the
+ length, in bytes, of the configuration list. Alterna-
+ tively, if the ifbic_len passed in is set to 0,
+ SIOCBRDGIFS will set ifbic_len to the size that
+ ifbic_buf needs to be to fit the entire configuration
+ list, and will not fill in the other parameters. This
+ is useful for determining the exact size that ifbic_buf
+ needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbreq {
+ char ifbr_name[IFNAMSIZ]; /* brdg nam */
+ char ifbr_ifsname[IFNAMSIZ]; /* if name */
+ u_int32_t ifbr_ifsflags; /* if flags */
+ u_int8_t ifbr_state; /* member stp state */
+ u_int8_t ifbr_priority; /* member stp priority */
+ u_int8_t ifbr_portno; /* member port number */
+ u_int32_t ifbr_path_cost; /* member stp path cost */
+ };
+ /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
+ #define IFBIF_LEARNING 0x0001 /* ifs can learn */
+ #define IFBIF_DISCOVER 0x0002 /* ifs sends packets w/unknown dest */
+ #define IFBIF_BLOCKNONIP 0x0004 /* ifs blocks non-IP/ARP in/out */
+ #define IFBIF_STP 0x0008 /* ifs participates in spanning tree */
+ #define IFBIF_SPAN 0x0100 /* ifs is a span port (ro) */
+ #define IFBIF_RO_MASK 0xff00 /* read only bits */
+
+ struct ifbifconf {
+ char ifbic_name[IFNAMSIZ]; /* brdg name */
+ u_int32_t ifbic_len; /* buf size */
+ union {
+ caddr_t ifbicu_buf; /* buffer */
+ struct ifbreq *ifbicu_req;
+ } ifbic_ifbicu;
+ #define ifbic_buf ifbic_ifbicu.ifbicu_buf
+ #define ifbic_req ifbic_ifbicu.ifbicu_req
+ };
+
+ SIOCBRDGADD (struct ifbreq) Add the interface named in ifbr_ifsname
+ to the bridge named in ifbr_name.
+
+ SIOCBRDGDEL (struct ifbreq) Delete the interface named in
+ ifbr_ifsname from the bridge named in ifbr_name.
+
+ SIOCBRDGADDS (struct ifbreq) Add the interface named in ifbr_ifsname
+ as a span port to the bridge named in ifbr_name.
+
+ SIOCBRDGDELS (struct ifbreq) Delete the interface named in
+ ifbr_ifsname from the list of span ports of the bridge
+ named in ifbr_name.
+
+ SIOCBRDGSIFFLGS (struct ifbreq) Set the bridge member interface flags
+ for the interface named in ifbr_ifsname attached to the
+ bridge ifbr_name. If the flag IFBIF_LEARNING is set on
+ an interface, source addresses from frames received on
+ the interface are recorded in the address cache. If the
+ flag IFBIF_DISCOVER is set, the interface will receive
+ packets destined for unknown destinations, otherwise a
+ frame that has a destination not found in the address
+ cache is not forwarded to this interface. The default
+ for newly added interfaces has both flags set. If the
+ flag IFBIF_BLOCKNONIP is set, packets that are one of
+ ip(4), ip6(4), arp(4), or Reverse ARP, will not be
+ bridged from and to the interface.
+
+ SIOCBRDGGIFFLGS Retrieve the bridge member interface flags for the in-
+ terface named in ifbr_ifsname attached to the bridge
+ ifbr_name.
+
+ SIOCBRDGRTS (struct ifbaconf) Retrieve the address cache of the
+ bridge named in ifbac_name. This request takes an
+ ifbaconf structure (see below) as a value result parame-
+ ter. The ifbac_len field should be initially set to the
+ size of the buffer pointed to by ifbac_buf. On return,
+ it will contain the length, in bytes, of the configura-
+ tion list. Alternatively, if the ifbac_len passed in is
+ set to 0, SIOCBRDGRTS will set it to the size that
+ ifbac_buf needs to be to fit the entire configuration
+ list and not fill in the other parameters. As with
+ SIOCBRDGIFS, this is useful for determining the exact
+ size that ifbac_buf needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbareq {
+ char ifba_name[IFNAMSIZ]; /* brdg nam */
+ char ifba_ifsname[IFNAMSIZ];/* dest ifs */
+ u_int8_t ifba_age; /* addr age */
+ u_int8_t ifba_flags; /* addr flag */
+ struct ether_addr ifba_dst; /* dst addr */
+ };
+
+ #define IFBAF_TYPEMASK 0x03 /* addr type mask */
+ #define IFBAF_DYNAMIC 0x00 /* dynamic addr */
+ #define IFBAF_STATIC 0x01 /* static address */
+
+ struct ifbaconf {
+ char ifbac_name[IFNAMSIZ]; /* brdg name */
+ u_int32_t ifbac_len; /* buf size */
+ union {
+ caddr_t ifbacu_buf; /* buf */
+ struct ifbareq *ifbacu_req;
+ } ifbac_ifbacu;
+ #define ifbac_buf ifbac_ifbacu.ifbacu_buf
+ #define ifbac_req ifbac_ifbacu.ifbacu_req
+ };
+ Address cache entries with the type set to IFBAF_DYNAMIC
+ in ifba_flags are entries learned by the bridge. En-
+ tries with the type set to IFBAF_STATIC are manually
+ added entries.
+
+ SIOCBRDGSADDR (struct ifbareq) Add an entry, manually, to the address
+ cache for the bridge named in ifba_name. The address
+ and its associated interface and flags are set in the
+ ifba_dst, ifba_ifsname, and ifba_flags fields, respec-
+ tively.
+
+ SIOCBRDGDADDR (struct ifbareq) Delete an entry from the address cache
+ of the bridge named in ifba_name. Entries are deleted
+ strictly based on the address field ifba_dst.
+
+ SIOCBRDGSCACHE (struct ifbcachereq) Set the maximum address cache size
+ for the bridge named in ifbc_name to ifbc_size entries.
+
+ The argument structure is as follows:
+
+ struct ifbcachereq {
+ char ifbc_name[IFNAMSIZ]; /* bridge */
+ u_int32_t ifbc_size; /* size */
+ };
+
+ SIOCBRDGGCACHE (struct ifbcachereq) Retrieve the maximum size of the
+ address cache for the bridge ifbc_name.
+
+ SIOCBRDGSTO (struct ifbcachetoreq) Set the time, in seconds, that
+ addresses which have not been seen on the network
+ (transmitted a packet) remain in the cache. If the time
+ is set to zero, no aging is performed on the address
+ cache. The argument structure is as follows:
+
+ struct ifbcachetoreq {
+ char ifbct_name[IFNAMSIZ]; /* bridge */
+ u_int32_t ifbct_time; /* time */
+ };
+
+ SIOCBRDGGTO (struct ifbcachetoreq) Retrieve the address cache expi-
+ ration time (see above).
+
+ SIOCBRDGFLUSH (struct ifbreq) Flush addresses from the cache.
+ ifbr_name contains the name of the bridge device, and
+ ifbr_ifsflags should be set to IFBF_FLUSHALL to flush
+ all addresses from the cache or IFBF_FLUSHDYN to flush
+ only the dynamically learned addresses from the cache.
+
+ SIOCBRDGARL (struct ifbrlreq) Add an Ethernet address filtering rule
+ to the bridge on a specific interface. ifbr_name con-
+ tains the name of the bridge device, and ifbr_ifsname
+ contains the name of the bridge member interface. The
+ ifbr_action field is one of BRL_ACTION_PASS or
+ BRL_ACTION_BLOCK, to pass or block matching frames re-
+ spectively. The ifbr_flags specifies whether the rule
+ should match on input, output, or both be using the
+ flags BRL_FLAG_IN and BRL_FLAG_OUT. It also specifies
+ whether either (or both) of the source and destination
+ addresses should be matched by using the
+ BRL_FLAG_SRCVALID and BRL_FLAG_DSTVALID flags. The
+ ifbr_src field is the source address that triggers the
+ rule (only considered if ifbr_flags has the
+ BRL_FLAG_SRCVALID bit set). The ifbr_src field is the
+ destination address that triggers the rule (only consid-
+ ered if ifbr_flags has the BRL_FLAG_DSTVALID bit set).
+
+ The argument structure is as follows:
+
+ struct ifbrlreq {
+ char ifbr_name[IFNAMSIZ];
+ char ifbr_ifsname[IFNAMSIZ];
+ u_int8_t ifbr_action;
+ u_int8_t ifbr_flags;
+ struct ether_addr ifbr_src;
+ struct ether_addr ifbr_dst;
+ char ifbr_tagname[PF_TAG_NAME_SIZE];
+ };
+ #define BRL_ACTION_BLOCK 0x01
+ #define BRL_ACTION_PASS 0x02
+ #define BRL_FLAG_IN 0x08
+ #define BRL_FLAG_OUT 0x04
+
+ SIOCBRDGFRL (struct ifbrlreq) Remove all filtering rules from a
+ bridge interface member. ifbr_name contains the name of
+ the bridge device, and ifbr_ifsname contains the name of
+ the bridge member interface.
+
+ SIOCBRDGGRL (struct ifbrlconf) Retrieve all of the rules from the
+ bridge, ifbrl_name, for the member interface,
+ ifbrl_ifsname. This request takes an ifbrlconf struc-
+ ture (see below) as a value result parameter. The
+ ifbrl_len field should be initially set to the size of
+ the buffer pointed to by ifbrl_buf. On return, it will
+ contain the length, in bytes, of the configuration list.
+ Alternatively, if the ifbrl_len passed in is set to 0,
+ SIOCBRDGGRL will set it to the size that ifbrl_buf needs
+ to be to fit the entire configuration list and not fill
+ in the other parameters. As with SIOCBRDGIFS, this is
+ useful for determining the exact size that ifbrl_buf
+ needs to be in advance.
+
+ The argument structure is defined as follows:
+
+ struct ifbrlconf {
+ char ifbrl_name[IFNAMSIZ]; /* brdg nam */
+ char ifbrl_ifsname[IFNAMSIZ];/* ifs name */
+ u_int32_t ifbr_len; /* buf len */
+ union {
+ caddr_t ifbrlu_buf;
+ struct ifbrlreq *ifbrlu_req;
+ } ifrl_ifbrlu;
+ #define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf
+ #define ifbrl_req ifbrl_ifbrlu.ifbrlu_req
+ };
+
+ SIOCBRDGARL (struct ifbrlreq) Add a filtering rule to the bridge
+ named in ifbr_name on the interface named in
+ ifbr_ifsname. The argument structure is as follows:
+
+ struct ifbrlreq {
+ char ifbr_name[IFNAMSIZ]; /* bridge */
+ char ifbr_ifsname[IFNAMSIZ]; /* ifs */
+ u_int8_t ifbr_action; /* handling */
+ u_int8_t ifbr_flags; /* flags */
+ struct ether_addr ifbr_src; /* src mac */
+ struct ether_addr ifbr_dst; /* dst mac */
+ };
+ #define BRL_ACTION_BLOCK 0x01
+ #define BRL_ACTION_PASS 0x02
+ #define BRL_FLAG_IN 0x08
+ #define BRL_FLAG_OUT 0x04
+ #define BRL_FLAG_SRCVALID 0x02
+ #define BRL_FLAG_DSTVALID 0x01
+
+ Rules are applied in the order in which they were added
+ to the bridge, and the first matching rule's action pa-
+ rameter determines the fate of the packet. The
+ ifbr_action parameter specifies whether a frame matching
+ the rule is to be blocked or passed.
+
+ If the BRL_FLAG_IN bit is set in ifbr_flags, then the
+ rule applies to frames received by the interface. If
+ the BRL_FLAG_OUT bit is set, then the rule applies to
+ frame transmitted by the interface. At least one of
+ BRL_FLAG_IN or BRL_FLAG_OUT must be set.
+
+ The source Ethernet address in ifbr_src is checked if
+ the BRL_FLAG_SRCVALID bit is set in ifbr_flags. The
+ destination address in ifbr_dst is checked if the
+ BRL_FLAG_DSTVALID bit is set. If neither bit is set,
+ the rule matches all frames.
+
+ SIOCBRDGFRL (struct ifbrlreq) Flush rules from the bridge ifbr_name
+ on the interface ifbr_ifsname.
+
+ SIOCBRDGGRL (struct ifbrlconf) Retrieve an array of rules from the
+ bridge for a particular interface. This request takes
+ an ifbrlconf structure (see below) as a value-result pa-
+ rameter. The ifbrl_len field should be initially set to
+ the size of the buffer pointed to by ifbrl_buf. On re-
+ turn it will contain the length, in bytes, of the rule
+ list. Alternatively, if the ifbrl_len passed in is set
+ to 0, SIOCBRDGGRL will set ifbrl_len to the size that
+ ifbrl_buf needs to be to fit the entire configuration
+ list, and will not fill in the other parameters. This
+ is useful for determining the exact size that ifbrl_buf
+ needs to be in advance.
+
+ The argument structure is as follows:
+
+ struct ifbrlconf {
+ char ifbrl_name[IFNAMSIZ]; /* bridge */
+ char ifbrl_ifsname[IFNAMSIZ];/* member */
+ u_int32_t ifbrl_len; /* buflen */
+ union {
+ caddr_t ifbrlu_buf;
+ struct ifbrlreq *ifbrlu_req;
+ } ifbrl_ifbrlu;
+ #define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf
+ #define ifbrl_req ifbrl_ifbrlu.ifbrlu_req
+ };
+
+ERRORS
+ If the ioctl call fails, errno is set to one of the following values:
+
+ [ENOENT] For an add request, this means that the named interface is
+ not configured into the system. For a delete operation, it
+ means that the named interface is not a member of the
+ bridge. For an address cache deletion, the address was not
+ found in the table.
+
+ [ENOMEM] Memory could not be allocated for an interface or cache en-
+ try to be added to the bridge.
+
+ [EEXIST] The named interface is already a member of the bridge.
+
+ [EBUSY] The named interface is already a member of another bridge.
+
+ [EINVAL] The named interface is not an Ethernet interface or an in-
+ valid ioctl was performed on the bridge.
+
+ [ENETDOWN] Address cache operation (flush, add, delete) on a bridge
+ that is in the down state.
+
+ [ESRCH] No such member interface in the bridge.
+
+SEE ALSO
+ <link linkend="openbsd-manpages-netintro">netintro</link>, <link linkend="openbsd-manpages-stp">spanning-tree</link>
+
+AUTHORS
+ The bridge kernel interface was written by Jason L. Wright
+ &lt;jason@thought.net> as part of an undergraduate independent study at
+ the University of North Carolina at Greensboro.
+
+</SCREEN>
+</SECT1>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:("tcpip.sgml" "book" "chapter")
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+sgml-doctype:"book"
+End:
+-->
diff --git a/ecos/packages/net/tcpip/current/doc/openbsd-manpages-netintro.sgml b/ecos/packages/net/tcpip/current/doc/openbsd-manpages-netintro.sgml
new file mode 100644
index 0000000..b1e3173
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/openbsd-manpages-netintro.sgml
@@ -0,0 +1,308 @@
+<!-- {{{ Banner -->
+
+<!-- All of the documentation and software included in the second BSD Networking -->
+<!-- Software Release is copyrighted by The Regents of the University of California. -->
+
+<!-- Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991 The Regents of the -->
+<!-- University of California. -->
+<!-- All rights reserved. -->
+
+<!-- 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 University 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 REGENTS 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 REGENTS 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. -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- openbsd_netintro.sgml -->
+<!-- -->
+<!-- eCos TCP/IP Stacks -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<SECT1 id="openbsd-manpages-netintro">
+<TITLE>OpenBSD networking facilities</TITLE>
+<SCREEN>
+
+NAME
+ networking - introduction to networking facilities
+
+SYNOPSIS
+ #include &lt;sys/socket.h>
+ #include &lt;net/route.h>
+ #include &lt;net/if.h>
+
+DESCRIPTION
+ This section is a general introduction to the networking facilities
+ available in the system. The general introduction on this page is
+ broken up into three areas: protocol families (domains), protocols,
+ and network interfaces.
+
+ All network protocols are associated with a specific protocol family. A
+ protocol family provides basic services to the protocol implementation
+ to allow it to function within a specific network environment. These
+ services may include packet fragmentation and reassembly, routing,
+ addressing, and basic transport. A protocol family may support multiple
+ methods of addressing, though the current protocol implementations do not.
+ A protocol family is normally comprised of a number of protocols, one per
+ <link linkend="net-common-tcpip-manpages-socket">socket</link> type. It is not required that a protocol family support all
+ socket types. A protocol family may contain multiple protocols support-
+ ing the same socket abstraction.
+
+ A protocol supports one of the socket abstractions detailed in <link linkend="net-common-tcpip-manpages-socket">socket</link>.
+ A specific protocol may be accessed either by creating a socket of the
+ appropriate type and protocol family, or by requesting the protocol ex-
+ plicitly when creating a socket. Protocols normally accept only one type
+ of address format, usually determined by the addressing structure inher-
+ ent in the design of the protocol family/network architecture. Certain
+ semantics of the basic socket abstractions are protocol specific. All
+ protocols are expected to support the basic model for their particular
+ socket type, but may, in addition, provide non-standard facilities or ex-
+ tensions to a mechanism. For example, a protocol supporting the
+ SOCK_STREAM abstraction may allow more than one byte of out-of-band data
+ to be transmitted per out-of-band message.
+
+ A network interface is similar to a device interface. Network interfaces
+ comprise the lowest layer of the networking subsystem, interacting with
+ the actual transport hardware. An interface may support one or more pro-
+ tocol families and/or address formats.
+
+PROTOCOL
+ The system currently supports the Internet protocols. Raw socket interfaces
+ are provided to the IP protocol layer of the Internet.
+
+ADDRESSING
+ Associated with each protocol family is an address format. All network
+ addresses adhere to a general structure, called a sockaddr, described be-
+ low. However, each protocol imposes a finer, more specific structure,
+ generally renaming the variant, which is discussed in the protocol family
+ manual page alluded to above.
+
+ struct sockaddr {
+ u_int8_t sa_len;
+ sa_family_t sa_family;
+ char sa_data[14];
+ };
+
+ The field sa_len contains the total length of the structure, which may
+ exceed 16 bytes. The following address values for sa_family are known to
+ the system (and additional formats are defined for possible future imple-
+ mentation):
+
+ #define AF_UNIX 1 /* local to host (pipes, portals) */
+ #define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+ #define AF_NS 6 /* Xerox NS protocols */
+ #define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+ #define AF_HYLINK 15 /* NSC Hyperchannel */
+ #define AF_APPLETALK 16 /* AppleTalk */
+ #define AF_ISO 18 /* ISO protocols */
+ #define AF_IPX 23 /* Novell Internet Protocol */
+ #define AF_INET6 24 /* IPv6 */
+ #define AF_NATM 27 /* native ATM access */
+
+ROUTING
+ OpenBSD provides some packet routing facilities. The kernel maintains a
+ routing information database, which is used in selecting the appropriate
+ network interface when transmitting packets.
+
+ This facility is however, untested in eCos ports.
+
+INTERFACES
+ Each network interface in a system corresponds to a path through which
+ messages may be sent and received. A network interface usually has a
+ hardware device associated with it, though certain interfaces such as the
+ loopback interface, lo, do not.
+
+ The following ioctl calls may be used to manipulate network interfaces
+ The ioctl is made on a socket (typically of type SOCK_DGRAM) in the desired
+ domain. Most of the requests supported in earlier releases take an ifreq
+ structure as its parameter. This structure has the form
+
+ struct ifreq {
+ #define IFNAMSIZ 16
+ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ short ifru_flags;
+ int ifru_metric;
+ caddr_t ifru_data;
+ } ifr_ifru;
+ #define ifr_addr ifr_ifru.ifru_addr /* address */
+ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
+ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+ #define ifr_flags ifr_ifru.ifru_flags /* flags */
+ #define ifr_metric ifr_ifru.ifru_metric /* metric */
+ #define ifr_media ifr_ifru.ifru_metric /* media options (overload) */
+ #define ifr_data ifr_ifru.ifru_data /* for use by interface */
+ };
+
+ Calls which are now deprecated are:
+
+ SIOCSIFADDR Set interface address for protocol family. Following the
+ address assignment, the ``initialization'' routine for
+ the interface is called.
+
+ SIOCSIFDSTADDR Set point to point address for protocol family and inter-
+ face.
+
+ SIOCSIFBRDADDR Set broadcast address for protocol family and interface.
+
+ ioctl requests to obtain addresses and requests both to set and retrieve
+ other data are still fully supported and use the ifreq structure:
+
+ SIOCGIFADDR Get interface address for protocol family.
+
+ SIOCGIFDSTADDR Get point to point address for protocol family and inter-
+ face.
+
+ SIOCGIFBRDADDR Get broadcast address for protocol family and interface.
+
+ SIOCSIFFLAGS Set interface flags field. If the interface is marked
+ down, any processes currently routing packets through the
+ interface are notified; some interfaces may be reset so
+ that incoming packets are no longer received. When
+ marked up again, the interface is reinitialized.
+
+ SIOCGIFFLAGS Get interface flags.
+
+ SIOCSIFMEDIA Set interface media. See ifmedia(4) for possible values.
+
+ SIOCGIFMEDIA Get interface media. See ifmedia(4) for interpreting
+ this value.
+
+ SIOCSIFMETRIC Set interface routing metric. The metric is used only by
+ user-level routers.
+
+ SIOCGIFMETRIC Get interface metric.
+
+ There are two requests that make use of a new structure:
+
+ SIOCAIFADDR An interface may have more than one address associated
+ with it in some protocols. This request provides a means
+ to add additional addresses (or modify characteristics of
+ the primary address if the default address for the ad-
+ dress family is specified). Rather than making separate
+ calls to set destination or broadcast addresses, or net-
+ work masks (now an integral feature of multiple proto-
+ cols) a separate structure is used to specify all three
+ facets simultaneously (see below). One would use a
+ slightly tailored version of this struct specific to each
+ family (replacing each sockaddr by one of the family-spe-
+ cific type). Where the sockaddr itself is larger than
+ the default size, one needs to modify the ioctl(2) iden-
+ tifier itself to include the total size, as described in
+ ioctl(2).
+
+ SIOCDIFADDR This request deletes the specified address from the list
+ associated with an interface. It also uses the
+ if_aliasreq structure to allow for the possibility of
+ protocols allowing multiple masks or destination address-
+ es, and also adopts the convention that specification of
+ the default address means to delete the first address for
+ the interface belonging to the address family in which
+ the original socket was opened.
+
+ SIOCGIFCONF Get interface configuration list. This request takes an
+ ifconf structure (see below) as a value-result parameter.
+ The ifc_len field should be initially set to the size of
+ the buffer pointed to by ifc_buf. On return it will con-
+ tain the length, in bytes, of the configuration list.
+ Alternately, if the ifc_len passed in is set to 0,
+ SIOCGIFCONF will set ifc_len to the size that ifc_buf
+ needs to be to fit the entire configuration list and not
+ fill in the other parameters. This is useful for deter-
+ mining the exact size that ifc_buf needs to be in ad-
+ vance. Note, however, that this is an extension that not
+ all operating systems support.
+
+ /*
+ * Structure used in SIOCAIFADDR request.
+ */
+ struct ifaliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr ifra_addr;
+ struct sockaddr ifra_broadaddr;
+ struct sockaddr ifra_mask;
+ };
+
+ /*
+ * Structure used in SIOCGIFCONF request.
+ * Used to retrieve interface configuration
+ * for machine (useful for programs which
+ * must know all networks accessible).
+ */
+ struct ifconf {
+ int ifc_len; /* size of associated buffer */
+ union {
+ caddr_t ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+ #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
+ #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
+ };
+
+SEE ALSO
+ <link linkend="openbsd-manpages-bridge">bridge</link>, <link linkend="openbsd-manpages-stp">spanning-tree</link>
+
+</SCREEN>
+</SECT1>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:("tcpip.sgml" "book" "chapter")
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+sgml-doctype:"book"
+End:
+-->
+
diff --git a/ecos/packages/net/tcpip/current/doc/openbsd-manpages-stp.sgml b/ecos/packages/net/tcpip/current/doc/openbsd-manpages-stp.sgml
new file mode 100644
index 0000000..7483563
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/openbsd-manpages-stp.sgml
@@ -0,0 +1,135 @@
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- openbsd-manpages-stp.sgml -->
+<!-- -->
+<!-- eCos TCP/IP Stacks -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<SECT1 id="openbsd-manpages-stp">
+<TITLE>Spanning Tree Protocol</TITLE>
+<SCREEN>
+NAME
+ stp - Spanning Tree Protocol
+
+SYNOPSIS
+
+
+DESCRIPTION
+ Spanning Tree (STP) is a layer 2 protocol designed to run on bridges. The
+ main purpose of STP is to ensure that there are no loop situations when
+ redundant paths are provisioned in the network. STP detects and disables
+ creation of network loops by blocking certain ports on some of the bridges
+ in the network. The process of selection of blocking ports (on occurance
+ of redundant paths) is governed by the following three parameters :
+
+ - Relative priority of each bridge. A higher value means lower priority.
+ - Relative priority of each port within a bridge. A higher value means
+ lower priority.
+ - Path cost (based on physical media type) associated with each port.
+
+ A given port/interface participates in STP if the flag IFBIF_STP is
+ set for the interface. A possible time for setting this flag is at the
+ time when the interface in context is added to bridge.
+
+IOCTLS
+ The STP code is invoked for all ioctl calls specified in <link linkend="openbsd-manpages-bridge">bridge</link> section.
+ The following ioctl calls are specific to STP functionality. They are
+ defined in &lt;sys/sockio.h>.
+
+ SIOCBRDGGPRI (struct ifbrparam) Get the configured priority of this
+ bridge. The priority value could vary from 0 to 65535.
+ 0 being the highest priority and 65535 the lowest. The
+ configured value is returned in field ifbrp_prio.
+
+ SIOCBRDGSPRI (struct ifbrparam) Set priority of this bridge to the
+ value specified in field ifbrp_prio.
+
+ SIOCBRDGGHT (struct ifbrparam) Get the configured frequency of
+ transmission of hello packets from non-blocking
+ interfaces on this bridge. The configured frequency is
+ returned in field ifbrp_hellotime.
+
+ SIOCBRDGSHT (struct ifbrparam) Set the frequency of transmission
+ of hello packets to the value specified in field
+ ifbrp_hellotime. The specified value should be greater
+ than 0, else EINVAL is returned.
+
+ SIOCBRDGGFD (struct ifbrparam) Get the forwarding delay time
+ associated with ports/interfaces on this bridge. The
+ forwarding delay time is the time taken by a port
+ to transit from one state to other (for eg. from
+ LEARNING state to FORWARDING state). The configured
+ value if returned in field ifbrp_fwddelay.
+
+ SIOCBRDGSFD (struct ifbrparam) Set the forwarding delay for ports
+ attached to this bridge to a value specified in
+ field ifbrp_fwddelay. The specified value should be
+ greater than 0, else EINVAL is returned.
+
+ SIOCBRDGGMA (struct ifbrparam) Get aging timeout values of
+ spanning data. The timeout value is returned in field
+ ifbrp_maxage.
+
+ SIOCBRDGSMA (struct ifbrparam) Set the aging timeout value of
+ BPDUs to the value specified in ifbrp_maxage. The
+ specified value should be greater than 0, else
+ EINVAL is returned.
+
+ SIOCBRDGSIFPRIO (struct ifbreq) Set the priority of specified
+ interface to the value given in field ifbr_priority.
+
+ SIOCBRDGSIFCOST (struct ifbreq) Set the cost associated with the
+ given interface to the value specified in field
+ ifbr_path_cost.
+
+
+ERRORS
+ Same as the ones specified for <link linkend="openbsd-manpages-bridge">bridge</link>.
+
+SEE ALSO
+ <link linkend="openbsd-manpages-netintro">netintro</link>, <link linkend="openbsd-manpages-bridge">bridge</link>
+
+</SCREEN>
+</SECT1>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:("tcpip.sgml" "book" "chapter")
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+sgml-doctype:"book"
+End:
+-->
+
diff --git a/ecos/packages/net/tcpip/current/doc/openbsd.sgml b/ecos/packages/net/tcpip/current/doc/openbsd.sgml
new file mode 100755
index 0000000..b63ae8a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/openbsd.sgml
@@ -0,0 +1,219 @@
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- openbsd.sgml -->
+<!-- -->
+<!-- eCos TCP/IP Stacks -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2010 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART id="tcpip-openbsd">
+<TITLE>OpenBSD TCP/IP Stack port for eCos</TITLE>
+<PARTINTRO>
+<PARA> <productname>TCP/IP Networking for eCos</productname>
+ now provides a complete
+ TCP/IP networking stack, which is derived from a
+ stable release of OpenBSD. The networking support is
+ fully featured and well tested within the eCos environment.
+ </PARA>
+</PARTINTRO>
+
+<CHAPTER id="tcpip-openbsd-networking-stack-features">
+<TITLE>Networking Stack Features</TITLE>
+<SECT1 id="tcpip-openbsd-tcpip-features">
+<TITLE>Introduction</TITLE>
+<PARA>Since this networking package is based on BSD code, it is
+very complete and robust. The eCos implementation includes support
+for the following protocols: </PARA>
+<itemizedlist>
+<LISTITEM><PARA>IPv4</para></listitem>
+<LISTITEM><PARA>UDP</para></listitem>
+<LISTITEM><PARA>TCP</para></listitem>
+<LISTITEM><PARA>ICMP</para></listitem>
+<LISTITEM><PARA>raw packet interface</para></listitem>
+</itemizedlist>
+<PARA>Along with support for the above mentioned protocols, the OpenBSD
+stack also supports ethernet bridging.
+</PARA>
+<PARA>The following additional features are also present in the package,
+ but are not supported:</PARA>
+<itemizedlist>
+<LISTITEM><PARA>Berkeley Packet Filter </PARA></LISTITEM>
+<LISTITEM><PARA>Multi-cast and uni-cast support, including multi-cast
+routing </PARA></LISTITEM>
+<LISTITEM><PARA>IPv6 </PARA></LISTITEM>
+ </itemizedlist>
+</SECT1>
+</CHAPTER>
+<CHAPTER id="tcpip-openbsd-stack-port">
+<TITLE>OpenBSD TCP/IP stack port</TITLE>
+<PARA>This document describes how to get started with the OpenBSD
+TCP/IP network stack. </PARA>
+<SECT1 id="tcpip-openbsd-tcpip-targets">
+<TITLE>Targets</TITLE>
+<PARA>A number of ethernet devices may be supported. The default configuration
+supports two instances of the interface by default,
+and you will need to write your own driver instantiation code,
+and supplemental startup and initialization code,
+if you should add additional ones.</PARA>
+<PARA>The target for your board will normally be supplied with an
+ethernet driver, in which case including the network stack and
+generic ethernet driver package to your build will automatically
+enable usage of the ethernet device driver.
+If your target is not supplied with an ethernet
+driver, you will need to use loopback (see
+<xref linkend="net-common-loopback-tests">).</PARA>
+</SECT1>
+<SECT1 id="tcpip-openbsd-building-the-network-stack">
+<TITLE><!--<conditionaltext>-->Building the Network Stack</TITLE>
+<PARA>Using the <EMPHASIS>Build-&gt;Packages</EMPHASIS> dialog,
+add the packages &ldquo;Networking&rdquo;,
+&ldquo;OpenBSD TCP/IP Stack&rdquo;
+and &ldquo;Common Ethernet Support&rdquo;
+to your configuration. Their package names
+are CYGPKG_NET, CYGPKG_NET_OPENBSD_STACK and CYGPKG_NET_ETH_DRIVERS
+respectively.</PARA>
+<para>A short-cut way to do this is by
+using the &ldquo;net&rdquo; <emphasis>template</emphasis>
+if it is available for your platform.</para>
+<PARA>The platform-specific ethernet device driver for your platform
+will be added as part of the target selection (in the
+<EMPHASIS>Build-&gt;Templates</EMPHASIS> &ldquo;Hardware&rdquo; item),
+along with the
+PCI I/O subsystem (if relevent) and the appropriate serial device driver.
+</para><para>
+For example, the PowerPC MBX target selection adds the package
+PKG_NET_QUICC_ETH_DRIVERS,
+and the Cirrus Logic EDB7xxx target selection adds the package
+CYGPKG_NET_EDB7XXX_ETH_DRIVERS.
+After this, eCos and its tests can be built exactly as usual.</PARA>
+<NOTE>
+<PARA>By default, most of the network tests are not built. This
+is because some of them require manual intervention, i.e. they are
+to be run &ldquo;by hand&rdquo;, and are not suitable for
+automated testing. To build the full set of network tests, set
+the configuration option CYGPKG_NET_BUILD_TESTS &ldquo;Build
+networking tests (demo programs)&rdquo; within &ldquo;Networking
+support build options&rdquo;.</PARA>
+</NOTE>
+</SECT1>
+<SECT1 id="tcpip-openbsd-building-the-bridge-code">
+<TITLE>Inclusion of bridge code</TITLE>
+
+<PARA>The OpenBSD stack does not by default result in the inclusion of
+the bridge code. To include bridging functionality the CDL option
+CYGPKG_NET_BRIDGE must be enable . It is also possible to enable more
+than one concurrent bridge. The number of bridges active in a device
+is configured by the CDL option CYGNUM_NET_BRIDGES, which has a
+default value of 1.</PARA>
+
+<PARA>The default behavior of a bridge is to operate without the
+spanning tree protocol. When devices are operated in this default mode
+it must be ensured the network topology is loop-free. Any loops will
+cause broadcast storms and general mayhem on the network. Including
+spanning tree code during the build process will allow the bridge to
+communicate with other bridges. They can then detect such loops and by
+disabling selected interfaces break the loop. To enable spanning tree enable
+the CDL option CYGPKG_NET_BRIDGE_STP_CODE.</PARA>
+</SECT1>
+</CHAPTER>
+<CHAPTER id="tcpip-openbsd-tcpip-apis">
+<TITLE>APIs</TITLE>
+<SECT1 id="tcpip-openbsd-standard-networking-api">
+<TITLE>Standard networking</TITLE>
+<PARA>The APIs for the standard networking calls such as
+<FUNCTION>socket()</FUNCTION>, <FUNCTION>recv()</FUNCTION> and so on, are
+in header files relative to the top-level
+include directory, within the standard subdirectories as conventionally
+found in <FILENAME>/usr/include</FILENAME>. For example:
+<PROGRAMLISTING>
+ install/include/arpa/tftp.h
+ install/include/netinet/tcpip.h
+ install/include/sys/socket.h
+ install/include/sys/socketvar.h
+ install/include/sys/sockio.h
+</PROGRAMLISTING>
+</PARA><PARA>
+<filename>network.h</filename> at the top level
+defines various extensions, for example the API
+<function>init_all_network_interfaces(void)</function>
+described
+above. We advise including <filename>network.h</filename> whether
+you use these features or not.</PARA>
+<PARA>In general, using the networking code may require definition
+of two symbols: _KERNEL and __ECOS. _KERNEL
+is not normally required; __ECOS is normally required.
+So add this to your compile lines for files which use the network
+stack:</PARA>
+<PROGRAMLISTING> -D__ECOS</PROGRAMLISTING>
+<PARA>To expand a little, it&rsquo;s like this because this is
+a port of a standard distribution external to Red Hat. One goal
+is to perturb the sources as little as possible, so that upgrading
+and maintenance from the external distribution is simplified. The __ECOS
+symbol marks out Red Hat&rsquo;s additions in making the port.
+The _KERNEL symbol is traditional UNIX practice: it distinguishes
+a compilation which is to be linked into the kernel from one which
+is part of an application. eCos applications are fully linked,
+so this distinction does not apply. _KERNEL can however
+be used to control the visibility of the internals of the stack,
+so depending on what features your application uses, it may or may
+not be necessary.</PARA>
+<PARA>The include file <filename>network.h</filename> undefines _KERNEL
+unconditionally, to provide an application-like compilation environment.
+If you were writing code which, for example,
+enumerates the stack&rsquo;s internal
+structures, that is a kernel-like compilation environment, so you
+would need to define _KERNEL (in addition to __ECOS)
+and avoid including <filename>network.h</filename>.</PARA>
+</SECT1>
+<SECT1 id="tcpip-openbsd-enhanced-select">
+<TITLE>Enhanced Select()</TITLE>
+<PARA>The network stack supports an extension to the standard select
+semantics which allows all threads that are waiting to be restarted
+even if the select conditions are not satisfied.</PARA>
+<PARA>The standard select() API: </PARA>
+<PROGRAMLISTING>int
+<function>select</function>(int nfd,
+ fd_set &ast;in, fd_set &ast;out, fd_set &ast;ex,
+ struct timeval &ast;tv); </PROGRAMLISTING>
+<PARA>does not support the restart.</PARA>
+<PARA>The additional API: </PARA>
+<PROGRAMLISTING>int
+<function>cyg_select_with_abort</function>(int nfd,
+ fd_set &ast;in, fd_set &ast;out, fd_set &ast;ex,
+ struct timeval &ast;tv)
+</PROGRAMLISTING>
+<PARA>behaves exactly as select() with the additional feature that
+a call to</PARA>
+<PROGRAMLISTING>
+void <function>cyg_select_abort</function>(void)
+</PROGRAMLISTING>
+<PARA>will cause all threads waiting in any
+<function>cyg_select_with_abort()</function> call
+to cease waiting and continue execution.</PARA>
+</SECT1>
+&net-tcpip-openbsd-manpages-netintro-sgml
+&net-tcpip-openbsd-manpages-bridge-sgml
+&net-tcpip-openbsd-manpages-stp-sgml
+</CHAPTER>
+</PART>
diff --git a/ecos/packages/net/tcpip/current/doc/read.html b/ecos/packages/net/tcpip/current/doc/read.html
new file mode 100644
index 0000000..1e4bf7d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/read.html
@@ -0,0 +1,61 @@
+<html>
+<body>
+<pre>
+NAME
+ read - read from a file descriptor
+
+SYNOPSIS
+ ssize_t read(int fd, void *buf, size_t count);
+
+DESCRIPTION
+ read() attempts to read up to count bytes from file
+ descriptor fd into the buffer starting at buf.
+
+ If count is zero, read() returns zero and has no other
+ results.
+
+
+RETURN VALUE
+ On success, the number of bytes read is returned (zero
+ indicates end of file), and the file position is advanced
+ by this number. It is not an error if this number is
+ smaller than the number of bytes requested; this may hap-
+ pen for example because fewer bytes are actually available
+ right now (maybe because we were close to end-of-file, or
+ because we are reading from a pipe, or from a terminal),
+ or because read() was interrupted by a signal. On error,
+ -1 is returned, and errno is set appropriately. In this
+ case it is left unspecified whether the file position (if
+ any) changes.
+
+ERRORS
+ EINTR The call was interrupted by a signal before any
+ data was read.
+
+ EAGAIN Non-blocking I/O has been selected using O_NON-
+ BLOCK and no data was immediately available for
+ reading.
+
+ EIO I/O error. This will happen for example when the
+ process is in a background process group, tries to
+ read from its controlling tty, and either it is
+ ignoring or blocking SIGTTIN or its process group
+ is orphaned. It may also occur when there is a
+ low-level I/O error while reading from a disk or
+ tape.
+
+ EISDIR fd refers to a directory.
+
+ EBADF fd is not a valid file descriptor or is not open
+ for reading.
+
+ EINVAL fd is attached to an object which is unsuitable
+ for reading.
+
+ Other errors may occur, depending on the object connected
+ to fd. POSIX allows a read that is interrupted after
+ reading some data to return -1 (with errno set to EINTR)
+ or to return the number of bytes already read.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/read.man b/ecos/packages/net/tcpip/current/doc/read.man
new file mode 100644
index 0000000..7f861bb
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/read.man
@@ -0,0 +1,55 @@
+NAME
+ read - read from a file descriptor
+
+SYNOPSIS
+ ssize_t read(int fd, void *buf, size_t count);
+
+DESCRIPTION
+ read() attempts to read up to count bytes from file
+ descriptor fd into the buffer starting at buf.
+
+ If count is zero, read() returns zero and has no other
+ results.
+
+
+RETURN VALUE
+ On success, the number of bytes read is returned (zero
+ indicates end of file), and the file position is advanced
+ by this number. It is not an error if this number is
+ smaller than the number of bytes requested; this may hap-
+ pen for example because fewer bytes are actually available
+ right now (maybe because we were close to end-of-file, or
+ because we are reading from a pipe, or from a terminal),
+ or because read() was interrupted by a signal. On error,
+ -1 is returned, and errno is set appropriately. In this
+ case it is left unspecified whether the file position (if
+ any) changes.
+
+ERRORS
+ EINTR The call was interrupted by a signal before any
+ data was read.
+
+ EAGAIN Non-blocking I/O has been selected using O_NON-
+ BLOCK and no data was immediately available for
+ reading.
+
+ EIO I/O error. This will happen for example when the
+ process is in a background process group, tries to
+ read from its controlling tty, and either it is
+ ignoring or blocking SIGTTIN or its process group
+ is orphaned. It may also occur when there is a
+ low-level I/O error while reading from a disk or
+ tape.
+
+ EISDIR fd refers to a directory.
+
+ EBADF fd is not a valid file descriptor or is not open
+ for reading.
+
+ EINVAL fd is attached to an object which is unsuitable
+ for reading.
+
+ Other errors may occur, depending on the object connected
+ to fd. POSIX allows a read that is interrupted after
+ reading some data to return -1 (with errno set to EINTR)
+ or to return the number of bytes already read.
diff --git a/ecos/packages/net/tcpip/current/doc/recvfrom.html b/ecos/packages/net/tcpip/current/doc/recvfrom.html
new file mode 100644
index 0000000..cdb0dba
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/recvfrom.html
@@ -0,0 +1,159 @@
+<html>
+<body>
+<pre>
+NAME
+ recvfrom - receive a message from a socket
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int recvfrom(int s, void *buf, int len, unsigned int flags
+ struct sockaddr *from, int *fromlen);
+
+DESCRIPTION
+ The recvfrom call is used to receive messages from a socket,
+ and may be used to receive data on a socket whether or not it
+ is connection-oriented.
+
+
+ If from is not NULL, and the socket is not connection-ori­
+ ented, the source address of the message is filled in.
+ Fromlen is a value-result parameter, initialized to the
+ size of the buffer associated with from, and modified on
+ return to indicate the actual size of the address stored
+ there.
+
+ The routine returns the length of the message on
+ successful completion. If a message is too long to fit in
+ the supplied buffer, excess bytes may be discarded depend­
+ ing on the type of socket the message is received from
+ (see socket(2)).
+
+ If no messages are available at the socket, the receive
+ calls wait for a message to arrive, unless the socket is
+ nonblocking (see fcntl(2)) in which case the value -1 is
+ returned and the external variable errno set to EAGAIN.
+ The receive calls normally return any data available, up
+ to the requested amount, rather than waiting for receipt
+ of the full amount requested.
+
+ The select(2) call may be used to determine
+ when more data arrives.
+
+ The flags argument to a recvfrom call is formed by OR'ing one
+ or more of the following values:
+
+ MSG_OOB
+ This flag requests receipt of out-of-band data that
+ would not be received in the normal data stream.
+ Some protocols place expedited data at the head of
+ the normal data queue, and thus this flag cannot be
+ used with such protocols.
+
+ MSG_PEEK
+ This flag causes the receive operation to return
+ data from the beginning of the receive queue with­
+ out removing that data from the queue. Thus, a
+ subsequent receive call will return the same data.
+
+ MSG_WAITALL
+ This flag requests that the operation block until
+ the full request is satisfied. However, the call
+ may still return less data than requested if a sig­
+ nal is caught, an error or disconnect occurs, or
+ the next data to be received is of a different type
+ than that returned.
+
+ MSG_ERRQUEUE
+ Receive packet from the error queue
+
+ MSG_NOSIGNAL
+ This flag turns off raising of SIGPIPE on stream
+ sockets when the other end disappears.
+
+ MSG_ERRQUEUE
+ This flag specifies that queued errors should be
+ received from the socket error queue. The error is
+ passed in a ancilliary message with a type depen­
+ dent on the protocol (for IP IP_RECVERR). The
+ error is supplied in a sock_extended_error struc­
+ ture:
+
+ #define SO_EE_ORIGIN_NONE 0
+ #define SO_EE_ORIGIN_LOCAL 1
+ #define SO_EE_ORIGIN_ICMP 2
+ #define SO_EE_ORIGIN_ICMP6 3
+
+ struct sock_extended_err
+ {
+ __u32 ee_errno; /* error number */
+ __u8 ee_origin; /* where the error originated */
+ __u8 ee_type; /* type */
+ __u8 ee_code; /* code */
+ __u8 ee_pad;
+ __u32 ee_info; /* additional information */
+ __u32 ee_data; /* other data */
+ };
+
+ struct sockaddr *SOCK_EE_OFFENDER(struct sock_extended_err *);
+
+ ee_errno contains the errno number of the queued
+ error. ee_origin is the origin code of where the
+ error originated. The other fields are protocol
+ specific. SOCK_EE_OFFENDER returns a pointer to
+ the address of the network object where the error
+ originated from. If this address is not known, the
+ sa_family member of the sockaddr contains AF_UNSPEC
+ and the other fields of the sockaddr are undefined.
+ The payload of the packet that caused the error is
+ passed as normal data.
+
+ For local errors, no address is passed (this can be
+ checked with the cmsg_len member of the cmsghdr).
+ For error receives, the MSG_ERRQUEUE is set in the
+ msghdr. After a error has been passed, the pending
+ socket error is regenerated based on the next
+ queued error and will be passed on the next socket
+ operation.
+
+
+ The msg_flags field is set on return according to the mes­
+ sage received. MSG_EOR indicates end-of-record; the data
+ returned completed a record (generally used with sockets
+ of type SOCK_SEQPACKET). MSG_TRUNC indicates that the
+ trailing portion of a datagram was discarded because the
+ datagram was larger than the buffer supplied. MSG_CTRUNC
+ indicates that some control data were discarded due to
+ lack of space in the buffer for ancillary data. MSG_OOB
+ is returned to indicate that expedited or out-of-band data
+ were received. MSG_ERRQUEUE indicates that no data was
+ received but an extended error from the socket error
+ queue.
+
+RETURN VALUES
+ These calls return the number of bytes received, or -1 if
+ an error occurred.
+
+ERRORS
+ These are some standard errors generated by the socket
+ layer. Additional errors may be generated and returned
+ from the underlying protocol modules; see their manual
+ pages.
+
+ EBADF The argument s is an invalid descriptor.
+
+ ENOTSOCK
+ The argument s does not refer to a socket.
+
+ EAGAIN The socket is marked non-blocking and the receive
+ operation would block, or a receive timeout had
+ been set and the timeout expired before data was
+ received.
+
+ EINTR The receive was interrupted by delivery of a sig­
+ nal before any data were available.
+
+ EINVAL Invalid argument passed.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/recvfrom.man b/ecos/packages/net/tcpip/current/doc/recvfrom.man
new file mode 100644
index 0000000..a92871d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/recvfrom.man
@@ -0,0 +1,152 @@
+NAME
+ recvfrom - receive a message from a socket
+
+SYNOPSIS
+ #include <network.h>
+
+ int recvfrom(int s, void *buf, int len, unsigned int flags
+ struct sockaddr *from, int *fromlen);
+
+DESCRIPTION
+ The recvfrom call is used to receive messages from a socket,
+ and may be used to receive data on a socket whether or not it
+ is connection-oriented.
+
+ If from is not NULL, and the socket is not connection-ori­
+ ented, the source address of the message is filled in.
+ Fromlen is a value-result parameter, initialized to the
+ size of the buffer associated with from, and modified on
+ return to indicate the actual size of the address stored
+ there.
+
+ The routine returns the length of the message on
+ successful completion. If a message is too long to fit in
+ the supplied buffer, excess bytes may be discarded depend­
+ ing on the type of socket the message is received from
+ (see socket(2)).
+
+ If no messages are available at the socket, the receive
+ calls wait for a message to arrive, unless the socket is
+ nonblocking (see fcntl(2)) in which case the value -1 is
+ returned and the external variable errno set to EAGAIN.
+ The receive calls normally return any data available, up
+ to the requested amount, rather than waiting for receipt
+ of the full amount requested.
+
+ The select(2) call may be used to determine
+ when more data arrives.
+
+ The flags argument to a recvfrom call is formed by OR'ing one
+ or more of the following values:
+
+ MSG_OOB
+ This flag requests receipt of out-of-band data that
+ would not be received in the normal data stream.
+ Some protocols place expedited data at the head of
+ the normal data queue, and thus this flag cannot be
+ used with such protocols.
+
+ MSG_PEEK
+ This flag causes the receive operation to return
+ data from the beginning of the receive queue with­
+ out removing that data from the queue. Thus, a
+ subsequent receive call will return the same data.
+
+ MSG_WAITALL
+ This flag requests that the operation block until
+ the full request is satisfied. However, the call
+ may still return less data than requested if a sig­
+ nal is caught, an error or disconnect occurs, or
+ the next data to be received is of a different type
+ than that returned.
+
+ MSG_ERRQUEUE
+ Receive packet from the error queue
+
+ MSG_NOSIGNAL
+ This flag turns off raising of SIGPIPE on stream
+ sockets when the other end disappears.
+
+ MSG_ERRQUEUE
+ This flag specifies that queued errors should be
+ received from the socket error queue. The error is
+ passed in a ancilliary message with a type depen­
+ dent on the protocol (for IP IP_RECVERR). The
+ error is supplied in a sock_extended_error struc­
+ ture:
+
+ #define SO_EE_ORIGIN_NONE 0
+ #define SO_EE_ORIGIN_LOCAL 1
+ #define SO_EE_ORIGIN_ICMP 2
+ #define SO_EE_ORIGIN_ICMP6 3
+
+ struct sock_extended_err
+ {
+ __u32 ee_errno; /* error number */
+ __u8 ee_origin; /* where the error originated */
+ __u8 ee_type; /* type */
+ __u8 ee_code; /* code */
+ __u8 ee_pad;
+ __u32 ee_info; /* additional information */
+ __u32 ee_data; /* other data */
+ };
+
+ struct sockaddr *SOCK_EE_OFFENDER(struct sock_extended_err *);
+
+ ee_errno contains the errno number of the queued
+ error. ee_origin is the origin code of where the
+ error originated. The other fields are protocol
+ specific. SOCK_EE_OFFENDER returns a pointer to
+ the address of the network object where the error
+ originated from. If this address is not known, the
+ sa_family member of the sockaddr contains AF_UNSPEC
+ and the other fields of the sockaddr are undefined.
+ The payload of the packet that caused the error is
+ passed as normal data.
+
+ For local errors, no address is passed (this can be
+ checked with the cmsg_len member of the cmsghdr).
+ For error receives, the MSG_ERRQUEUE is set in the
+ msghdr. After a error has been passed, the pending
+ socket error is regenerated based on the next
+ queued error and will be passed on the next socket
+ operation.
+
+
+ The msg_flags field is set on return according to the mes­
+ sage received. MSG_EOR indicates end-of-record; the data
+ returned completed a record (generally used with sockets
+ of type SOCK_SEQPACKET). MSG_TRUNC indicates that the
+ trailing portion of a datagram was discarded because the
+ datagram was larger than the buffer supplied. MSG_CTRUNC
+ indicates that some control data were discarded due to
+ lack of space in the buffer for ancillary data. MSG_OOB
+ is returned to indicate that expedited or out-of-band data
+ were received. MSG_ERRQUEUE indicates that no data was
+ received but an extended error from the socket error
+ queue.
+
+RETURN VALUES
+ These calls return the number of bytes received, or -1 if
+ an error occurred.
+
+ERRORS
+ These are some standard errors generated by the socket
+ layer. Additional errors may be generated and returned
+ from the underlying protocol modules; see their manual
+ pages.
+
+ EBADF The argument s is an invalid descriptor.
+
+ ENOTSOCK
+ The argument s does not refer to a socket.
+
+ EAGAIN The socket is marked non-blocking and the receive
+ operation would block, or a receive timeout had
+ been set and the timeout expired before data was
+ received.
+
+ EINTR The receive was interrupted by delivery of a sig­
+ nal before any data were available.
+
+ EINVAL Invalid argument passed.
diff --git a/ecos/packages/net/tcpip/current/doc/sample_program.html b/ecos/packages/net/tcpip/current/doc/sample_program.html
new file mode 100644
index 0000000..cd00253
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/sample_program.html
@@ -0,0 +1,359 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; I; Linux 2.2.14 ppc) [Netscape]">
+</head>
+<body>
+
+<center>
+<h1>
+Sample Networking Program</h1></center>
+
+<p><br>This example is derived from the test program <tt>".../net/tcpip/v1_3_1/tests/ping_test.c"</tt>.
+<br>&nbsp;
+<blockquote><tt><font size=-1>//==========================================================================</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tests/ping_test.c</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Simple test of PING
+(ICMP) and networking support</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>//==========================================================================</font></tt>
+<br><tt><font size=-1>//==========================================================================</font></tt>
+<br><tt><font size=-1>//#####DESCRIPTIONBEGIN####</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>// Author(s):&nbsp;&nbsp;&nbsp; gthomas</font></tt>
+<br><tt><font size=-1>// Contributors: gthomas</font></tt>
+<br><tt><font size=-1>// Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+2000-01-10</font></tt>
+<br><tt><font size=-1>// Purpose:</font></tt>
+<br><tt><font size=-1>// Description:</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>//####DESCRIPTIONEND####</font></tt>
+<br><tt><font size=-1>//</font></tt>
+<br><tt><font size=-1>//==========================================================================</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>// PING test code</font></tt><b><tt><font size=-1></font></tt></b>
+<p><b><tt><font size=-1>#include &lt;network.h></font></tt></b></blockquote>
+This single include directive is all that is required to pick up the networking
+support, including complete configuration information.
+<blockquote><tt><font size=-1>#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL</font></tt>
+<br><tt><font size=-1>static char stack[STACK_SIZE];</font></tt>
+<br><tt><font size=-1>static cyg_thread thread_data;</font></tt>
+<br><tt><font size=-1>static cyg_handle_t thread_handle;</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>#define NUM_PINGS 16</font></tt>
+<br><tt><font size=-1>#define MAX_PACKET 4096</font></tt>
+<br><tt><font size=-1>static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET];</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>#define UNIQUEID 0x1234</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>void</font></tt>
+<br><tt><font size=-1>cyg_test_exit(void)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("... Done\n");</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; while (1) ;</font></tt>
+<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>void</font></tt>
+<br><tt><font size=-1>pexit(char *s)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; perror(s);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_test_exit();</font></tt>
+<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>// Compute INET checksum</font></tt>
+<br><tt><font size=-1>int</font></tt>
+<br><tt><font size=-1>inet_cksum(u_short *addr, int len)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register int nleft = len;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register u_short *w = addr;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register u_short answer;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register u_int sum = 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; u_short odd_byte = 0;</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; /*</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; Our algorithm is
+simple, using a 32 bit accumulator (sum),</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; we add sequential
+16 bit words to it, and at the end, fold</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; back all the carry
+bits from the top 16 bits into the lower</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 16 bits.</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; */</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; while( nleft > 1 )&nbsp; {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum +=
+*w++;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nleft
+-= 2;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; /* mop up an odd byte, if necessary
+*/</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if( nleft == 1 ) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *(u_char
+*)(&amp;odd_byte) = *(u_char *)w;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum +=
+odd_byte;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; /*</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; * add back carry outs from
+top 16 bits to low 16 bits</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; */</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; sum = (sum >> 16) + (sum &amp;
+0x0000ffff); /* add hi 16 to low 16 */</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; sum += (sum >> 16);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+/* add carry */</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; answer = ~sum;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+/* truncate to 16 bits */</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; return (answer);</font></tt>
+<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>static int</font></tt>
+<br><tt><font size=-1>show_icmp(unsigned char *pkt, int len,</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+struct sockaddr_in *from, struct sockaddr_in *to)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_tick_count_t *tp, tv;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct ip *ip;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct icmp *icmp;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tv = cyg_current_time();</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; ip = (struct ip *)pkt;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if ((len &lt; sizeof(*ip)) ||
+ip->ip_v != IPVERSION) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diag_printf("%s:
+Short packet or not IP! - Len: %d, Version: %d\n",</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+inet_ntoa(from->sin_addr), len, ip->ip_v);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
+0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; icmp = (struct icmp *)(pkt + sizeof(*ip));</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; len -= (sizeof(*ip) + 8);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tp = (cyg_tick_count_t *)&amp;icmp->icmp_data;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (icmp->icmp_type != ICMP_ECHOREPLY)
+{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diag_printf("%s:
+Invalid ICMP - type: %d\n",</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+inet_ntoa(from->sin_addr), icmp->icmp_type);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
+0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (icmp->icmp_id != UNIQUEID)
+{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diag_printf("%s:
+ICMP received for wrong id - sent: %x, recvd: %x\n",</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+inet_ntoa(from->sin_addr), UNIQUEID, icmp->icmp_id);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("%d bytes from %s:
+", len, inet_ntoa(from->sin_addr));</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("icmp_seq=%d", icmp->icmp_seq);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf(", time=%dms\n", (int)(tv
+- *tp)*10);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; return (from->sin_addr.s_addr
+== to->sin_addr.s_addr);</font></tt>
+<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>static void</font></tt>
+<br><tt><font size=-1>ping_host(int s, struct sockaddr_in *host)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct icmp *icmp = (struct icmp
+*)pkt1;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int icmp_len = 64;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int seq, ok_recv, bogus_recv;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_tick_count_t *tp;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; long *dp;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct sockaddr_in from;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int i, len, fromlen;</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; ok_recv = 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; bogus_recv = 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("PING server %s\n",
+<b>inet_ntoa(host->sin_addr)</b>);</font></tt></blockquote>
+This function takes an IP address and returns a string representation.&nbsp;
+Useful for printing the address.
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; for (seq = 0;&nbsp; seq
+&lt; NUM_PINGS;&nbsp; seq++) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Build
+ICMP packet</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_type
+= ICMP_ECHO;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_code
+= 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_cksum
+= 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_seq
+= seq;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_id
+= 0x1234;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set
+up ping data</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tp = (cyg_tick_count_t
+*)&amp;icmp->icmp_data;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *tp++
+= cyg_current_time();</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dp = (long
+*)tp;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i
+= sizeof(*tp);&nbsp; i &lt; icmp_len;&nbsp; i += sizeof(*dp)) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+*dp++ = i;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add
+checksum</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_cksum
+= inet_cksum( (u_short *)icmp, icmp_len+8);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Send
+it off</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>if
+(sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host))
+&lt; 0) {</b></font></tt></blockquote>
+This function sends a single packet, in this case via the ICMP protocol.&nbsp;
+The destination address is specified by the <tt>host</tt> argument.
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+perror("sendto");</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+continue;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Wait
+for a response</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fromlen
+= sizeof(from);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>len
+= recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&amp;from, &amp;fromlen);</b></font></tt></blockquote>
+This function waits for a packet to be sent to this interface.&nbsp; Note:
+this operation can fail if no packet is received with a given amount of
+time (this timeout value is setup in the <tt>ping_test()</tt> routine below).
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if (len &lt; 0) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+perror("recvfrom");</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else
+{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+if (show_icmp(pkt2, len, &amp;from, host)) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ok_recv++;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+} else {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+bogus_recv++;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+}</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("Sent %d packets,
+received %d OK, %d bad\n", NUM_PINGS, ok_recv, bogus_recv);</font></tt>
+<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>static void</font></tt>
+<br><tt><font size=-1>ping_test(struct bootp *bp)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct protoent *p;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct timeval tv;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct sockaddr_in host;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int s;</font></tt><tt><font size=-1></font></tt>
+<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>if ((p = getprotobyname("icmp"))
+== (struct protoent *)0) {</b></font></tt></blockquote>
+This function gets information about the ICMP protocol.&nbsp; This will
+be used below to set up the "socket" (the handle to a network connection).
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+perror("getprotobyname");</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>s = socket(AF_INET, SOCK_RAW,
+p->p_proto);</b></font></tt></blockquote>
+Create the socket "s".&nbsp; A socket is an abstract object (sometimes
+called a handle or endpoint).&nbsp; Sockets come in many flavors, RAW sockets
+are used for communicating with non-structured protocols.&nbsp; DATAGRAM
+sockets are used for packet oriented protocols, such as UDP.&nbsp; STREAM
+sockets are used for reliable, sequenced byte streams, such as those provided
+by TCP.
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (s &lt; 0) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("socket");</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tv.tv_sec = 1;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tv.tv_usec = 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+&amp;tv, sizeof(tv));</b></font></tt></blockquote>
+This function instructs the system that receive operations (see <tt>ping_host()</tt>
+above) must complete within 1 second or issue a timed out error condition.
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; // Set up host address</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_family = AF_INET;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_addr = bp->bp_siaddr;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_port = 0;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; ping_host(s, &amp;host);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; // Now try a bogus host</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_addr.s_addr = htonl(ntohl(host.sin_addr.s_addr)
++ 32);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; ping_host(s, &amp;host);</font></tt>
+<br><tt><font size=-1>}</font></tt>
+<br><tt><font size=-1></font></tt>&nbsp;</blockquote>
+This function drives the test.
+<blockquote><tt><font size=-1>void</font></tt>
+<br><tt><font size=-1>net_test(cyg_addrword_t p)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("Start PING test\n");</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>init_all_network_interfaces();</b></font></tt></blockquote>
+This is a call to the network initialization code.&nbsp; Note that it must
+be executed from a thread context, thus we can't put it in the <tt>cyg_start()
+</tt>function which follows.&nbsp; The <tt>init_all_network_interfaces()</tt>
+routine will cause the networking system to be initialized and any hardware
+interfaces will be set up.&nbsp; Using the system configuration information,
+an interface can be started using either <b>BOOTP</b>,&nbsp; or a predefined
+configuration with static IP information.&nbsp; It is also possible to
+indicate that an interface will be configured by the user code, outside
+of "<tt>init_all_network_interfaces()</tt>".
+<br><tt><font size=-1>&nbsp;</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; #ifdef CYGHWR_NET_DRIVER_ETH0</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (eth0_up)
+{</font></tt>
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ping_test(&amp;eth0_bootp_data);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>#endif</font></tt></blockquote>
+Notice that there is a BOOTP information structure kept about all hardware
+interfaces.&nbsp; This is created and initialized by the call to <tt>init_all_network_interfaces()</tt>,
+unless manual configuration is selected.&nbsp; This information can be
+used by the application to learn things such as the local IP address, server
+name, etc.
+<blockquote><tt><font size=-1>#ifdef CYGHWR_NET_DRIVER_ETH1</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (eth1_up) {</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ping_test(&amp;eth1_bootp_data);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
+<br><tt><font size=-1>#endif</font></tt></blockquote>
+Multiple hardware interfaces can be supported, depending on the hardware
+platform.&nbsp; If the platform provides a single ethernet device then&nbsp;
+<b><tt>CYGHWR_NET_DRIVER_ETH0 </tt></b>will be defined.&nbsp; If there
+is a second interface, then will <b><tt>CYGHWR_NET_DRIVER_ETH1 </tt></b>be
+defined.
+<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_test_exit();</font></tt>
+<br><tt><font size=-1>}</font></tt>
+<br><tt><font size=-1></font></tt>&nbsp;</blockquote>
+The following function creates an initial thread which runs the program.&nbsp;
+This could just as easily be done by naming the <tt>net_test()</tt> function
+<tt>main()</tt>.
+<blockquote><tt><font size=-1>void</font></tt>
+<br><tt><font size=-1>cyg_start(void)</font></tt>
+<br><tt><font size=-1>{</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; // Create a main thread, so we
+can run the scheduler and have time 'pass'</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_thread_create(10,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Priority - just a number</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+net_test,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // entry</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// entry parameter</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+"Network test",&nbsp;&nbsp;&nbsp; // Name</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&amp;stack[0],&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Stack</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+STACK_SIZE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Size</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&amp;thread_handle,&nbsp;&nbsp;&nbsp; // Handle</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&amp;thread_data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Thread data structure</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+);</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_thread_resume(thread_handle);&nbsp;
+// Start it</font></tt>
+<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_scheduler_start();</font></tt>
+<br><tt><font size=-1>}</font></tt></blockquote>
+
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/select.html b/ecos/packages/net/tcpip/current/doc/select.html
new file mode 100644
index 0000000..25a3d94
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/select.html
@@ -0,0 +1,108 @@
+<html>
+<body>
+<pre>
+NAME
+ select, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchronous
+ I/O multiplexing
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int select(int n, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout);
+
+ FD_CLR(int fd, fd_set *set);
+ FD_ISSET(int fd, fd_set *set);
+ FD_SET(int fd, fd_set *set);
+ FD_ZERO(fd_set *set);
+
+DESCRIPTION
+ select waits for a number of file descriptors to change
+ status.
+
+ Three independent sets of descriptors are watched. Those
+ listed in readfds will be watched to see if characters
+ become available for reading, those in writefds will be
+ watched to see if it is ok to immediately write on them,
+ and those in exceptfds will be watched for exceptions. On
+ exit, the sets are modified in place to indicate which
+ descriptors actually changed status.
+
+ Four macros are provided to manipulate the sets. FD_ZERO
+ will clear a set. FD_SET and FD_CLR add or remove a given
+ descriptor from a set. FD_ISSET tests to see if a
+ descriptor is part of the set; this is useful after select
+ returns.
+
+ n is the highest-numbered descriptor in any of the three
+ sets, plus 1.
+
+ timeout is an upper bound on the amount of time elapsed
+ before select returns. It may be zero, causing select to
+ return immediately. If timeout is NULL (no timeout),
+ select can block indefinitely.
+
+RETURN VALUE
+ On success, select returns the number of descriptors con-
+ tained in the descriptor sets, which may be zero if the
+ timeout expires before anything interesting happens. On
+ error, -1 is returned, and errno is set appropriately; the
+ sets and timeout become undefined, so do not rely on their
+ contents after an error.
+
+ERRORS
+ EBADF An invalid file descriptor was given in one of the
+ sets.
+
+ EINTR A non blocked signal was caught.
+
+ EINVAL n is negative.
+
+ ENOMEM select was unable to allocate memory for internal
+ tables.
+
+NOTES
+ Some code calls select with all three sets empty, n zero,
+ and a non-null timeout as a fairly portable way to sleep
+ with subsecond precision.
+
+EXAMPLE
+ #include <stdio.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+
+ int
+ main(void)
+ {
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
+
+ /* Watch stdin (fd 0) to see when it has input. */
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+ /* Wait up to five seconds. */
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+
+ retval = select(1, &rfds, NULL, NULL, &tv);
+ /* Don't rely on the value of tv now! */
+
+ if (retval)
+ printf("Data is available now.\n");
+ /* FD_ISSET(0, &rfds) will be true. */
+ else
+ printf("No data within five seconds.\n");
+
+ exit(0);
+ }
+
+ Generally portable to/from non-BSD systems supporting
+ clones of the BSD socket layer (including System V vari-
+ ants). However, note that the System V variant typically
+ sets the timeout variable before exit, but the BSD variant
+ does not.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/select.man b/ecos/packages/net/tcpip/current/doc/select.man
new file mode 100644
index 0000000..d92c026
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/select.man
@@ -0,0 +1,102 @@
+NAME
+ select, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchronous
+ I/O multiplexing
+
+SYNOPSIS
+ #include <network.h>
+
+ int select(int n, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout);
+
+ FD_CLR(int fd, fd_set *set);
+ FD_ISSET(int fd, fd_set *set);
+ FD_SET(int fd, fd_set *set);
+ FD_ZERO(fd_set *set);
+
+DESCRIPTION
+ select waits for a number of file descriptors to change
+ status.
+
+ Three independent sets of descriptors are watched. Those
+ listed in readfds will be watched to see if characters
+ become available for reading, those in writefds will be
+ watched to see if it is ok to immediately write on them,
+ and those in exceptfds will be watched for exceptions. On
+ exit, the sets are modified in place to indicate which
+ descriptors actually changed status.
+
+ Four macros are provided to manipulate the sets. FD_ZERO
+ will clear a set. FD_SET and FD_CLR add or remove a given
+ descriptor from a set. FD_ISSET tests to see if a
+ descriptor is part of the set; this is useful after select
+ returns.
+
+ n is the highest-numbered descriptor in any of the three
+ sets, plus 1.
+
+ timeout is an upper bound on the amount of time elapsed
+ before select returns. It may be zero, causing select to
+ return immediately. If timeout is NULL (no timeout),
+ select can block indefinitely.
+
+RETURN VALUE
+ On success, select returns the number of descriptors con-
+ tained in the descriptor sets, which may be zero if the
+ timeout expires before anything interesting happens. On
+ error, -1 is returned, and errno is set appropriately; the
+ sets and timeout become undefined, so do not rely on their
+ contents after an error.
+
+ERRORS
+ EBADF An invalid file descriptor was given in one of the
+ sets.
+
+ EINTR A non blocked signal was caught.
+
+ EINVAL n is negative.
+
+ ENOMEM select was unable to allocate memory for internal
+ tables.
+
+NOTES
+ Some code calls select with all three sets empty, n zero,
+ and a non-null timeout as a fairly portable way to sleep
+ with subsecond precision.
+
+EXAMPLE
+ #include <stdio.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+
+ int
+ main(void)
+ {
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
+
+ /* Watch stdin (fd 0) to see when it has input. */
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+ /* Wait up to five seconds. */
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+
+ retval = select(1, &rfds, NULL, NULL, &tv);
+ /* Don't rely on the value of tv now! */
+
+ if (retval)
+ printf("Data is available now.\n");
+ /* FD_ISSET(0, &rfds) will be true. */
+ else
+ printf("No data within five seconds.\n");
+
+ exit(0);
+ }
+
+ Generally portable to/from non-BSD systems supporting
+ clones of the BSD socket layer (including System V vari-
+ ants). However, note that the System V variant typically
+ sets the timeout variable before exit, but the BSD variant
+ does not.
diff --git a/ecos/packages/net/tcpip/current/doc/sendto.html b/ecos/packages/net/tcpip/current/doc/sendto.html
new file mode 100644
index 0000000..c24db85
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/sendto.html
@@ -0,0 +1,106 @@
+<html>
+<body>
+<pre>
+NAME
+ sendto - send a message from a socket
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int sendto(int s, const void *msg, int len, unsigned int
+ flags, const struct sockaddr *to, int tolen);
+
+DESCRIPTION
+ Sendto is used to transmit a message
+ to another socket.
+
+ The address of the target is given by to with tolen speci­
+ fying its size. The length of the message is given by
+ len. If the message is too long to pass atomically
+ through the underlying protocol, the error EMSGSIZE is
+ returned, and the message is not transmitted.
+
+ No indication of failure to deliver is implicit in a send.
+ Locally detected errors are indicated by a return value of
+ -1.
+
+ When the message does not fit into the send buffer of the
+ socket, send normally blocks, unless the socket has been
+ placed in non-blocking I/O mode. In non-blocking mode it
+ would return EAGAIN in this case. The select(2) call may
+ be used to determine when it is possible to send more
+ data.
+
+ The flags parameter may include one or more of the follow­
+ ing:
+
+ #define MSG_OOB 0x1 /* process out-of-band data */
+ #define MSG_DONTROUTE 0x4 /* bypass routing, use direct interface */
+ #define MSG_DONTWAIT 0x40 /* don't block */
+ #define MSG_NOSIGNAL 0x2000 /* don't raise SIGPIPE */
+
+ MSG_OOB
+ Sends out-of-band data on sockets that support this
+ notion (e.g. SOCK_STREAM); the underlying protocol
+ must also support out-of-band data.
+
+ MSG_DONTROUTE
+ Bypasses the usual routing table lookup and sends
+ the packet directly to the interface described by
+ the destination address. This is usually used only
+ by diagnostic or routing programs.
+
+ MSG_DONTWAIT
+ Enables non-blocking operation; if the operation
+ would block, EAGAIN is returned.
+
+ MSG_NOSIGNAL
+ Requests not to send SIGPIPE on errors on stream
+ oriented sockets when the other end breaks the con­
+ nection. The EPIPE error is still returned.
+
+ See recv(2) for a description of the msghdr structure. You
+ may send control information using the msg_control and
+ msg_controllen members. The maximum control buffer length
+ the kernel can process is limited by the net.core.opt­
+ mem_max sysctl; see socket(4).
+
+RETURN VALUES
+ The calls return the number of characters sent, or -1 if
+ an error occurred.
+
+ERRORS
+ These are some standard errors generated by the socket
+ layer. Additional errors may be generated and returned
+ from the underlying protocol modules; see their respective
+ manual pages.
+
+ EBADF An invalid descriptor was specified.
+
+ ENOTSOCK
+ The argument s is not a socket.
+
+ EMSGSIZE
+ The socket requires that message be sent atomi­
+ cally, and the size of the message to be sent made
+ this impossible.
+
+ EAGAIN The socket is marked non-blocking and the
+ requested operation would block.
+
+ ENOBUFS The system was unable to allocate an internal mem­
+ ory block. The operation may succeed when buffers
+ become available.
+
+ EINTR A signal occurred.
+
+ ENOMEM No memory available.
+
+ EINVAL Invalid argument passed.
+
+ EPIPE The local end has been shut down on a connection
+ oriented socket. In this case the process will
+ also receive a SIGPIPE unless MSG_NOSIGNAL is set.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/sendto.man b/ecos/packages/net/tcpip/current/doc/sendto.man
new file mode 100644
index 0000000..a694f2c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/sendto.man
@@ -0,0 +1,100 @@
+NAME
+ sendto - send a message from a socket
+
+SYNOPSIS
+ #include <network.h>
+
+ int sendto(int s, const void *msg, int len, unsigned int
+ flags, const struct sockaddr *to, int tolen);
+
+DESCRIPTION
+ Sendto is used to transmit a message
+ to another socket.
+
+ The address of the target is given by to with tolen speci­
+ fying its size. The length of the message is given by
+ len. If the message is too long to pass atomically
+ through the underlying protocol, the error EMSGSIZE is
+ returned, and the message is not transmitted.
+
+ No indication of failure to deliver is implicit in a send.
+ Locally detected errors are indicated by a return value of
+ -1.
+
+ When the message does not fit into the send buffer of the
+ socket, send normally blocks, unless the socket has been
+ placed in non-blocking I/O mode. In non-blocking mode it
+ would return EAGAIN in this case. The select(2) call may
+ be used to determine when it is possible to send more
+ data.
+
+ The flags parameter may include one or more of the follow­
+ ing:
+
+ #define MSG_OOB 0x1 /* process out-of-band data */
+ #define MSG_DONTROUTE 0x4 /* bypass routing, use direct interface */
+ #define MSG_DONTWAIT 0x40 /* don't block */
+ #define MSG_NOSIGNAL 0x2000 /* don't raise SIGPIPE */
+
+ MSG_OOB
+ Sends out-of-band data on sockets that support this
+ notion (e.g. SOCK_STREAM); the underlying protocol
+ must also support out-of-band data.
+
+ MSG_DONTROUTE
+ Bypasses the usual routing table lookup and sends
+ the packet directly to the interface described by
+ the destination address. This is usually used only
+ by diagnostic or routing programs.
+
+ MSG_DONTWAIT
+ Enables non-blocking operation; if the operation
+ would block, EAGAIN is returned.
+
+ MSG_NOSIGNAL
+ Requests not to send SIGPIPE on errors on stream
+ oriented sockets when the other end breaks the con­
+ nection. The EPIPE error is still returned.
+
+ See recv(2) for a description of the msghdr structure. You
+ may send control information using the msg_control and
+ msg_controllen members. The maximum control buffer length
+ the kernel can process is limited by the net.core.opt­
+ mem_max sysctl; see socket(4).
+
+RETURN VALUES
+ The calls return the number of characters sent, or -1 if
+ an error occurred.
+
+ERRORS
+ These are some standard errors generated by the socket
+ layer. Additional errors may be generated and returned
+ from the underlying protocol modules; see their respective
+ manual pages.
+
+ EBADF An invalid descriptor was specified.
+
+ ENOTSOCK
+ The argument s is not a socket.
+
+ EMSGSIZE
+ The socket requires that message be sent atomi­
+ cally, and the size of the message to be sent made
+ this impossible.
+
+ EAGAIN The socket is marked non-blocking and the
+ requested operation would block.
+
+ ENOBUFS The system was unable to allocate an internal mem­
+ ory block. The operation may succeed when buffers
+ become available.
+
+ EINTR A signal occurred.
+
+ ENOMEM No memory available.
+
+ EINVAL Invalid argument passed.
+
+ EPIPE The local end has been shut down on a connection
+ oriented socket. In this case the process will
+ also receive a SIGPIPE unless MSG_NOSIGNAL is set.
diff --git a/ecos/packages/net/tcpip/current/doc/setsockopt.html b/ecos/packages/net/tcpip/current/doc/setsockopt.html
new file mode 100644
index 0000000..80015f3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/setsockopt.html
@@ -0,0 +1,72 @@
+<html>
+<body>
+<pre>
+NAME
+ getsockopt, setsockopt - get and set options on sockets
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int getsockopt(int s, int level, int optname, void *opt­
+ val, socklen_t *optlen);
+
+ int setsockopt(int s, int level, int optname, const void
+ *optval, socklen_t optlen);
+
+DESCRIPTION
+ Getsockopt and setsockopt manipulate the options associ­
+ ated with a socket. Options may exist at multiple proto­
+ col levels; they are always present at the uppermost
+ socket level.
+
+ When manipulating socket options the level at which the
+ option resides and the name of the option must be speci­
+ fied. To manipulate options at the socket level, level is
+ specified as SOL_SOCKET. To manipulate options at any
+ other level the protocol number of the appropriate proto­
+ col controlling the option is supplied. For example, to
+ indicate that an option is to be interpreted by the TCP
+ protocol, level should be set to the protocol number of
+ TCP; see getprotoent(3).
+
+ The parameters optval and optlen are used to access option
+ values for setsockopt. For getsockopt they identify a
+ buffer in which the value for the requested option(s) are
+ to be returned. For getsockopt, optlen is a value-result
+ parameter, initially containing the size of the buffer
+ pointed to by optval, and modified on return to indicate
+ the actual size of the value returned. If no option value
+ is to be supplied or returned, optval may be NULL.
+
+ Optname and any specified options are passed uninterpreted
+ to the appropriate protocol module for interpretation.
+ The include file &lt;network.h&gt; contains definitions for
+ socket level options, described below. Options at other
+ protocol levels vary in format and name; consult the
+ appropriate entries in section 4 of the manual.
+
+ Most socket-level options utilize an int parameter for
+ optval. For setsockopt, the parameter should be non-zero
+ to enable a boolean option, or zero if the option is to be
+ disabled.
+
+ For a description of the available socket options see
+ socket(7) and the appropriate protocol man pages.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOPROTOOPT
+ The option is unknown at the level indicated.
+
+
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/setsockopt.man b/ecos/packages/net/tcpip/current/doc/setsockopt.man
new file mode 100644
index 0000000..0427e15
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/setsockopt.man
@@ -0,0 +1,66 @@
+NAME
+ getsockopt, setsockopt - get and set options on sockets
+
+SYNOPSIS
+ #include <network.h>
+
+ int getsockopt(int s, int level, int optname, void *opt­
+ val, socklen_t *optlen);
+
+ int setsockopt(int s, int level, int optname, const void
+ *optval, socklen_t optlen);
+
+DESCRIPTION
+ Getsockopt and setsockopt manipulate the options associ­
+ ated with a socket. Options may exist at multiple proto­
+ col levels; they are always present at the uppermost
+ socket level.
+
+ When manipulating socket options the level at which the
+ option resides and the name of the option must be speci­
+ fied. To manipulate options at the socket level, level is
+ specified as SOL_SOCKET. To manipulate options at any
+ other level the protocol number of the appropriate proto­
+ col controlling the option is supplied. For example, to
+ indicate that an option is to be interpreted by the TCP
+ protocol, level should be set to the protocol number of
+ TCP; see getprotoent(3).
+
+ The parameters optval and optlen are used to access option
+ values for setsockopt. For getsockopt they identify a
+ buffer in which the value for the requested option(s) are
+ to be returned. For getsockopt, optlen is a value-result
+ parameter, initially containing the size of the buffer
+ pointed to by optval, and modified on return to indicate
+ the actual size of the value returned. If no option value
+ is to be supplied or returned, optval may be NULL.
+
+ Optname and any specified options are passed uninterpreted
+ to the appropriate protocol module for interpretation.
+ The include file <sys/socket.h> contains definitions for
+ socket level options, described below. Options at other
+ protocol levels vary in format and name; consult the
+ appropriate entries in section 4 of the manual.
+
+ Most socket-level options utilize an int parameter for
+ optval. For setsockopt, the parameter should be non-zero
+ to enable a boolean option, or zero if the option is to be
+ disabled.
+
+ For a description of the available socket options see
+ socket(7) and the appropriate protocol man pages.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF The argument s is not a valid descriptor.
+
+ ENOTSOCK
+ The argument s is a file, not a socket.
+
+ ENOPROTOOPT
+ The option is unknown at the level indicated.
+
+
diff --git a/ecos/packages/net/tcpip/current/doc/shutdown.html b/ecos/packages/net/tcpip/current/doc/shutdown.html
new file mode 100644
index 0000000..919ebd4
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/shutdown.html
@@ -0,0 +1,33 @@
+<html>
+<body>
+<pre>
+NAME
+ shutdown - shut down part of a full-duplex connection
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int shutdown(int s, int how);
+
+DESCRIPTION
+ The shutdown call causes all or part of a full-duplex con-
+ nection on the socket associated with s to be shut down.
+ If how is 0, further receives will be disallowed. If how
+ is 1, further sends will be disallowed. If how is 2, fur-
+ ther sends and receives will be disallowed.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF s is not a valid descriptor.
+
+ ENOTSOCK
+ s is a file, not a socket.
+
+ ENOTCONN
+ The specified socket is not connected.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/shutdown.man b/ecos/packages/net/tcpip/current/doc/shutdown.man
new file mode 100644
index 0000000..668f55f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/shutdown.man
@@ -0,0 +1,27 @@
+NAME
+ shutdown - shut down part of a full-duplex connection
+
+SYNOPSIS
+ #include <network.h>
+
+ int shutdown(int s, int how);
+
+DESCRIPTION
+ The shutdown call causes all or part of a full-duplex con-
+ nection on the socket associated with s to be shut down.
+ If how is 0, further receives will be disallowed. If how
+ is 1, further sends will be disallowed. If how is 2, fur-
+ ther sends and receives will be disallowed.
+
+RETURN VALUE
+ On success, zero is returned. On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF s is not a valid descriptor.
+
+ ENOTSOCK
+ s is a file, not a socket.
+
+ ENOTCONN
+ The specified socket is not connected.
diff --git a/ecos/packages/net/tcpip/current/doc/socket.html b/ecos/packages/net/tcpip/current/doc/socket.html
new file mode 100644
index 0000000..f560bd6
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/socket.html
@@ -0,0 +1,117 @@
+<html>
+<body>
+<pre>
+NAME
+ socket - create an endpoint for communication
+
+SYNOPSIS
+ #include &lt;network.h&gt;
+
+ int socket(int domain, int type, int protocol);
+
+DESCRIPTION
+ Socket creates an endpoint for communication and returns a
+ descriptor.
+
+ The domain parameter specifies a communications domain
+ within which communication will take place; this selects
+ the protocol family which should be used. These families
+ are defined in &lt;network.h&gt;. The currently understood
+ formats include:
+
+ PF_INET
+ IPv4 Internet protocols; see ip(4)
+
+ The socket has the indicated type, which specifies the
+ semantics of communication. Currently defined types are:
+
+ SOCK_STREAM
+ Provides sequenced, reliable, two-way connection-
+ based byte streams. An out-of-band data transmis-
+ sion mechanism may be supported.
+
+ SOCK_DGRAM
+ Supports datagrams (connectionless, unreliable mes-
+ sages of a fixed maximum length).
+
+ SOCK_SEQPACKET
+ Provides a sequenced, reliable, two-way connection-
+ based data transmission path for datagrams of fixed
+ maximum length; a consumer is required to read an
+ entire packet with each read system call.
+
+ SOCK_RAW
+ Provides raw network protocol access.
+
+ The protocol specifies a particular protocol to be used
+ with the socket. Normally only a single protocol exists
+ to support a particular socket type within a given proto-
+ col family. However, it is possible that many protocols
+ may exist, in which case a particular protocol must be
+ specified in this manner. The protocol number to use is
+ particular to the "communication domain" in which communi-
+ cation is to take place; see protocols(5). See getpro-
+ toent(3) on how to map protocol name strings to protocol
+ numbers.
+
+ Sockets of type SOCK_STREAM are full-duplex byte streams,
+ similar to pipes. A stream socket must be in a connected
+ state before any data may be sent or received on it. A
+ connection to another socket is created with a connect(2)
+ call. Once connected, data may be transferred using
+ read(2) and write(2) calls or some variant of the send(2)
+ and recv(2) calls. When a session has been completed a
+ close(2) may be performed. Out-of-band data may also be
+ transmitted as described in send(2) and received as
+ described in recv(2).
+
+ The communications protocols which implement a SOCK_STREAM
+ ensure that data is not lost or duplicated. If a piece of
+ data for which the peer protocol has buffer space cannot
+ be successfully transmitted within a reasonable length of
+ time, then the connection is considered When SO_KEEPALIVE
+ is enabled on the socket the protocol checks in a proto-
+ col-specific manner if the other end is still alive.
+
+ SOCK_DGRAM and SOCK_RAW sockets allow sending of datagrams
+ to correspondents named in send(2) calls. Datagrams are
+ generally received with recvfrom(2), which returns the
+ next datagram with its return address.
+
+ When the network signals an error condition to the proto-
+ col module (e.g. using a ICMP message for IP) the pending
+ error flag is set for the socket. The next operation on
+ this socket will return the error code of the pending
+ error. For some protocols it is possible to enable a per-
+ socket error queue to retrieve detailed information about
+ the error; see IP_RECVERR in ip(4).
+
+ The operation of sockets is controlled by socket level
+ options. These options are defined in <sys/socket.h>.
+ Setsockopt(2) and getsockopt(2) are used to set and get
+ options, respectively.
+
+RETURN VALUES
+ -1 is returned if an error occurs; otherwise the return
+ value is a descriptor referencing the socket.
+
+ERRORS
+ EPROTONOSUPPORT
+ The protocol type or the specified protocol is not
+ supported within this domain.
+
+ EMFILE There are too many open files.
+
+ EACCES Permission to create a socket of the specified
+ type and/or protocol is denied.
+
+ ENOBUFS or ENOMEM
+ Insufficient memory is available. The socket can-
+ not be created until sufficient resources are
+ freed.
+
+ EINVAL Unknown protocol, or protocol family not avail-
+ able.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/socket.man b/ecos/packages/net/tcpip/current/doc/socket.man
new file mode 100644
index 0000000..cc5f18a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/socket.man
@@ -0,0 +1,111 @@
+NAME
+ socket - create an endpoint for communication
+
+SYNOPSIS
+ #include <network.h>
+
+ int socket(int domain, int type, int protocol);
+
+DESCRIPTION
+ Socket creates an endpoint for communication and returns a
+ descriptor.
+
+ The domain parameter specifies a communications domain
+ within which communication will take place; this selects
+ the protocol family which should be used. These families
+ are defined in <sys/socket.h>. The currently understood
+ formats include:
+
+ PF_INET
+ IPv4 Internet protocols; see ip(4)
+
+ The socket has the indicated type, which specifies the
+ semantics of communication. Currently defined types are:
+
+ SOCK_STREAM
+ Provides sequenced, reliable, two-way connection-
+ based byte streams. An out-of-band data transmis-
+ sion mechanism may be supported.
+
+ SOCK_DGRAM
+ Supports datagrams (connectionless, unreliable mes-
+ sages of a fixed maximum length).
+
+ SOCK_SEQPACKET
+ Provides a sequenced, reliable, two-way connection-
+ based data transmission path for datagrams of fixed
+ maximum length; a consumer is required to read an
+ entire packet with each read system call.
+
+ SOCK_RAW
+ Provides raw network protocol access.
+
+ The protocol specifies a particular protocol to be used
+ with the socket. Normally only a single protocol exists
+ to support a particular socket type within a given proto-
+ col family. However, it is possible that many protocols
+ may exist, in which case a particular protocol must be
+ specified in this manner. The protocol number to use is
+ particular to the "communication domain" in which communi-
+ cation is to take place; see protocols(5). See getpro-
+ toent(3) on how to map protocol name strings to protocol
+ numbers.
+
+ Sockets of type SOCK_STREAM are full-duplex byte streams,
+ similar to pipes. A stream socket must be in a connected
+ state before any data may be sent or received on it. A
+ connection to another socket is created with a connect(2)
+ call. Once connected, data may be transferred using
+ read(2) and write(2) calls or some variant of the send(2)
+ and recv(2) calls. When a session has been completed a
+ close(2) may be performed. Out-of-band data may also be
+ transmitted as described in send(2) and received as
+ described in recv(2).
+
+ The communications protocols which implement a SOCK_STREAM
+ ensure that data is not lost or duplicated. If a piece of
+ data for which the peer protocol has buffer space cannot
+ be successfully transmitted within a reasonable length of
+ time, then the connection is considered When SO_KEEPALIVE
+ is enabled on the socket the protocol checks in a proto-
+ col-specific manner if the other end is still alive.
+
+ SOCK_DGRAM and SOCK_RAW sockets allow sending of datagrams
+ to correspondents named in send(2) calls. Datagrams are
+ generally received with recvfrom(2), which returns the
+ next datagram with its return address.
+
+ When the network signals an error condition to the proto-
+ col module (e.g. using a ICMP message for IP) the pending
+ error flag is set for the socket. The next operation on
+ this socket will return the error code of the pending
+ error. For some protocols it is possible to enable a per-
+ socket error queue to retrieve detailed information about
+ the error; see IP_RECVERR in ip(4).
+
+ The operation of sockets is controlled by socket level
+ options. These options are defined in <sys/socket.h>.
+ Setsockopt(2) and getsockopt(2) are used to set and get
+ options, respectively.
+
+RETURN VALUES
+ -1 is returned if an error occurs; otherwise the return
+ value is a descriptor referencing the socket.
+
+ERRORS
+ EPROTONOSUPPORT
+ The protocol type or the specified protocol is not
+ supported within this domain.
+
+ EMFILE There are too many open files.
+
+ EACCES Permission to create a socket of the specified
+ type and/or protocol is denied.
+
+ ENOBUFS or ENOMEM
+ Insufficient memory is available. The socket can-
+ not be created until sufficient resources are
+ freed.
+
+ EINVAL Unknown protocol, or protocol family not avail-
+ able.
diff --git a/ecos/packages/net/tcpip/current/doc/tcpip_config.html b/ecos/packages/net/tcpip/current/doc/tcpip_config.html
new file mode 100644
index 0000000..d9253c1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/tcpip_config.html
@@ -0,0 +1,22 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; U; Linux 2.2.10 i686) [Netscape]">
+</head>
+<body>
+
+<center>
+<h1>
+eCos TCP/IP Package Configuration</h1></center>
+&nbsp;Follow these steps to enable networking:
+<blockquote><tt>% ecosconfig add CYGPKG_NET</tt>
+<br><tt>% ecosconfig add CYGPKG_NET_ETH_DRIVERS</tt></blockquote>
+For the Motorola PowerPC (MBX/860) board:
+<blockquote><tt>% ecosconfig add CYGPKG_NET_QUICC_ETH_DRIVERS</tt></blockquote>
+For the Cirrus Logic EDB7xxx board:
+<blockquote><tt>% ecosconfig add CYGPKG_NET_EDB7XXX_ETH_DRIVERS</tt></blockquote>
+
+<br>&nbsp;
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/tcpip_library.html b/ecos/packages/net/tcpip/current/doc/tcpip_library.html
new file mode 100644
index 0000000..b51177c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/tcpip_library.html
@@ -0,0 +1,77 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; I; Linux 2.2.14 ppc) [Netscape]">
+</head>
+<body>
+
+<center>
+<h1>
+TCP/IP Library Reference</h1></center>
+
+<li>
+<a href="accept.html">accept</a></li>
+
+<li>
+<a href="bind.html">bind</a></li>
+
+<li>
+<a href="close.html">close</a></li>
+
+<li>
+<a href="connect.html">connect</a></li>
+
+<li>
+<a href="gethost.html">gethostbyname, gethostbyaddr</a></li>
+
+<li>
+<a href="getpeername.html">getpeername</a></li>
+
+<li>
+<a href="getproto.html">getprotobyname, getprotobynumber</a></li>
+
+<li>
+<a href="getserv.html">getservbyname, getservbyport</a></li>
+
+<li>
+<a href="getsockname.html">getsockname</a></li>
+
+<li>
+<a href="getsockopt.html">getsockopt</a></li>
+
+<li>
+<a href="inet_addr.html">inet_aton, inet_addr, inet_addr</a></li>
+
+<li>
+<a href="ioctl.html">ioctl</a></li>
+
+<li>
+<a href="listen.html">listen</a></li>
+
+<li>
+<a href="read.html">read</a></li>
+
+<li>
+<a href="recvfrom.html">recvfrom</a></li>
+
+<li>
+<a href="select.html">select</a></li>
+
+<li>
+<a href="sendto.html">sendto</a></li>
+
+<li>
+<a href="setsockopt.html">setsockopt</a></li>
+
+<li>
+<a href="shutdown.html">shutdown</a></li>
+
+<li>
+<a href="socket.html">socket</a></li>
+
+<li>
+<a href="write.html">write</a></li>
+
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/tcpip_tests.html b/ecos/packages/net/tcpip/current/doc/tcpip_tests.html
new file mode 100644
index 0000000..cc258f3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/tcpip_tests.html
@@ -0,0 +1,98 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; I; Linux 2.2.14 ppc) [Netscape]">
+</head>
+<body>
+
+<center>
+<h1>
+eCos TCP/IP Networking Tests and Examples</h1></center>
+A number of test/example programs are currently provided with the TCP/IP
+networking package.&nbsp; These are not "tests" in the traditional eCos
+test suite sense, but rather simple programs which exercise various parts
+of the networking stack.&nbsp; Also included are a set of performance tests,
+used to measure throughput and latency in an embedded eCos system.
+<p>The following paragraphs list the various tests and how they might be
+used.&nbsp;&nbsp; They are enumerated in the order in which they should
+be run to verify a system configuration.
+<p>Note: none of these tests are built by default.&nbsp; The user must
+enable the <b><tt>CYGPKG_NET_BUILD_TESTS </tt></b>option and then "<tt>make
+tests</tt>" to create them for the target environment.&nbsp; Also, these
+tests require that the hardware interfaces be configured to use either
+BOOTP or static initialization methods.
+<h3>
+mbuf_test.c</h3>
+This should be the first test run on a new system.&nbsp; It simply tests
+that the networking system can be initialized and that the internal memory
+management (used by the stack) is functioning.
+<h3>
+socket_test.c</h3>
+This test exercises some of the basic library interfaces.
+<h3>
+server_test.c</h3>
+This test creates a server process on the target hardware which listens
+on port TCP/7734.&nbsp; To verify that it is working, try to connect to
+this port from some other [host] system.&nbsp; E.g. on Linux, use the command
+"<tt>telnet <i>eCos</i> 7734</tt>", where "<i><tt>eCos</tt></i>" is the
+name associated with the target hardware.&nbsp; Once connected, the eCos
+application will respond with a "Hello" message and wait for a single line
+of input text, which will be displayed on the diagnostic channel of the
+target system.
+<h3>
+ping_test.c</h3>
+This tests attempts to issue an ICMP "echo" request to the "server" host
+(provided as part of the BOOTP or static configuration information).&nbsp;
+The output will be similar to the analogous Linux program, "<tt>ping</tt>".&nbsp;
+The test program also attempts to ping an additional host whose IP address
+is the server IP+32.&nbsp; This second test is present to verify that the
+ICMP (actually <tt>receive</tt>) time-out mechanism is working (assuming
+that the second host is non-existent).
+<h3>
+ftp_test.c</h3>
+This test attempts to make a connection to an FTP server, assuming the
+default server host.&nbsp; This is an additional test which verifies that
+the basic TCP functionality is working.
+<h3>
+nc_test_master.c</h3>
+
+<h3>
+nc_test_slave.c</h3>
+This pair of programs can be used to measure throughput and latencies in
+the target system.&nbsp; While both programs have been written in such
+a way that they can be built and used on either Linux or eCos, the primary
+use will be to run the "<tt>nc_test_master</tt>" program on a Linux host
+and the "<tt>nc_test_slave</tt>" on the target hardware.&nbsp; If run in
+this configuration, the master program will attempt to connect to the slave
+and make various measurements using both UDP and TCP protocols.&nbsp; Additionally,
+measurements will be made on an eCos slave of the actual CPU utilization
+by the networking stack.
+<p>To build the Linux versions, simply execute (in the eCos source tree,
+not the install tree):
+<blockquote><tt>make -f make.linux</tt></blockquote>
+
+<h3>
+tcp_echo.c</h3>
+
+<h3>
+tcp_sink.c</h3>
+
+<h3>
+tcp_source.c</h3>
+This set of programs is similar to the <i><tt>nc_test_XXX</tt></i> programs
+described above.&nbsp; However, they are designed to measure overall throughput
+of the eCos system.&nbsp; The setup allows for one Linux host to run "<tt>tcp_source
+<i>eCos</i></tt>" and another Linux host to run "<tt>tcp_sink <i>eCos</i></tt>".&nbsp;
+The "<tt>tcp_echo</tt>" program is run on the target hardware.&nbsp; The
+tests then measure the throughput and latency of sending TCP data from
+one host, though the eCos target system and on to another host.&nbsp; Note:
+the two Linux host systems may be the same computer in which case this
+becomes a single wire echo test.&nbsp; This test suite is unique in that
+it attempts to load the target system down with additional background processing
+at various levels.&nbsp; This is done to simulate a real world environment
+where the networking is ancillary to the main processing on the target
+system.
+<br>&nbsp;
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/write.html b/ecos/packages/net/tcpip/current/doc/write.html
new file mode 100644
index 0000000..a130784
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/write.html
@@ -0,0 +1,42 @@
+<html>
+<body>
+<pre>
+NAME
+ write - write to a file descriptor
+
+SYNOPSIS
+ ssize_t write(int fd, const void *buf, size_t count);
+
+DESCRIPTION
+ write writes up to count bytes to the file referenced by
+ the file descriptor fd from the buffer starting at buf.
+
+RETURN VALUE
+ On success, the number of bytes written are returned (zero
+ indicates nothing was written). On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF fd is not a valid file descriptor or is not open
+ for writing.
+
+ EINVAL fd is attached to an object which is unsuitable for
+ writing.
+
+ EPIPE fd is connected to a socket whose reading
+ end is closed.
+
+ EAGAIN Non-blocking I/O has been selected using O_NONBLOCK
+ and there was no room in the pipe or socket con­
+ nected to fd to write the data immediately.
+
+ EINTR The call was interrupted before any
+ data was written.
+
+ ENOSPC The device containing the file referred to by fd
+ has no room for the data.
+
+ EIO A low-level I/O error occurred.
+</pre>
+</body>
+</html>
diff --git a/ecos/packages/net/tcpip/current/doc/write.man b/ecos/packages/net/tcpip/current/doc/write.man
new file mode 100644
index 0000000..b0861f3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/doc/write.man
@@ -0,0 +1,36 @@
+NAME
+ write - write to a file descriptor
+
+SYNOPSIS
+ ssize_t write(int fd, const void *buf, size_t count);
+
+DESCRIPTION
+ write writes up to count bytes to the file referenced by
+ the file descriptor fd from the buffer starting at buf.
+
+RETURN VALUE
+ On success, the number of bytes written are returned (zero
+ indicates nothing was written). On error, -1 is returned,
+ and errno is set appropriately.
+
+ERRORS
+ EBADF fd is not a valid file descriptor or is not open
+ for writing.
+
+ EINVAL fd is attached to an object which is unsuitable for
+ writing.
+
+ EPIPE fd is connected to a socket whose reading
+ end is closed.
+
+ EAGAIN Non-blocking I/O has been selected using O_NONBLOCK
+ and there was no room in the pipe or socket con­
+ nected to fd to write the data immediately.
+
+ EINTR The call was interrupted before any
+ data was written.
+
+ ENOSPC The device containing the file referred to by fd
+ has no room for the data.
+
+ EIO A low-level I/O error occurred.
diff --git a/ecos/packages/net/tcpip/current/include/lib/libkern/libkern.h b/ecos/packages/net/tcpip/current/include/lib/libkern/libkern.h
new file mode 100644
index 0000000..25c0245
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/lib/libkern/libkern.h
@@ -0,0 +1,217 @@
+//==========================================================================
+//
+// include/lib/libkern/libkern.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: libkern.h,v 1.14 1997/11/30 21:47:45 mickey Exp $ */
+/* $NetBSD: libkern.h,v 1.7 1996/03/14 18:52:08 christos Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)libkern.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef __LIBKERN_H__
+#define __LIBKERN_H__
+
+#ifdef __INSIDE_NET
+
+#include <sys/types.h>
+
+#ifndef LIBKERN_INLINE
+#ifndef NO_LIBKERN_INLINE
+#define LIBKERN_INLINE static __inline
+#define LIBKERN_BODY
+#else
+#define LIBKERN_INLINE
+#endif
+#endif
+
+
+LIBKERN_INLINE int imax __P((int, int));
+LIBKERN_INLINE int imin __P((int, int));
+LIBKERN_INLINE u_int max __P((u_int, u_int));
+LIBKERN_INLINE u_int min __P((u_int, u_int));
+LIBKERN_INLINE long lmax __P((long, long));
+LIBKERN_INLINE long lmin __P((long, long));
+LIBKERN_INLINE u_long ulmax __P((u_long, u_long));
+LIBKERN_INLINE u_long ulmin __P((u_long, u_long));
+LIBKERN_INLINE int abs __P((int));
+
+#ifdef LIBKERN_BODY
+LIBKERN_INLINE int
+imax(a, b)
+ int a, b;
+{
+ return (a > b ? a : b);
+}
+LIBKERN_INLINE int
+imin(a, b)
+ int a, b;
+{
+ return (a < b ? a : b);
+}
+LIBKERN_INLINE long
+lmax(a, b)
+ long a, b;
+{
+ return (a > b ? a : b);
+}
+LIBKERN_INLINE long
+lmin(a, b)
+ long a, b;
+{
+ return (a < b ? a : b);
+}
+LIBKERN_INLINE u_int
+max(a, b)
+ u_int a, b;
+{
+ return (a > b ? a : b);
+}
+LIBKERN_INLINE u_int
+min(a, b)
+ u_int a, b;
+{
+ return (a < b ? a : b);
+}
+LIBKERN_INLINE u_long
+ulmax(a, b)
+ u_long a, b;
+{
+ return (a > b ? a : b);
+}
+LIBKERN_INLINE u_long
+ulmin(a, b)
+ u_long a, b;
+{
+ return (a < b ? a : b);
+}
+
+LIBKERN_INLINE int
+abs(j)
+ int j;
+{
+ return(j < 0 ? -j : j);
+}
+#endif
+
+#ifndef __ECOS
+#ifdef NDEBUG /* tradition! */
+#define assert(e) ((void)0)
+#else
+#ifdef __STDC__
+#define assert(e) ((e) ? (void)0 : \
+ __assert("", __FILE__, __LINE__, #e))
+#else
+#define assert(e) ((e) ? (void)0 : \
+ __assert("", __FILE__, __LINE__, "e"))
+#endif
+#endif
+
+#ifndef DIAGNOSTIC
+#define KASSERT(e) ((void)0)
+#else
+#ifdef __STDC__
+#define KASSERT(e) ((e) ? (void)0 : \
+ __assert("diagnostic ", __FILE__, __LINE__, #e))
+#else
+#define KASSERT(e) ((e) ? (void)0 : \
+ __assert("diagnostic ", __FILE__, __LINE__, "e"))
+#endif
+#endif
+
+#ifndef DEBUG
+#define KDASSERT(e) ((void)0)
+#else
+#ifdef __STDC__
+#define KDASSERT(e) ((e) ? (void)0 : \
+ __assert("debugging ", __FILE__, __LINE__, #e))
+#else
+#define KDASSERT(e) ((e) ? (void)0 : \
+ __assert("debugging ", __FILE__, __LINE__, "e"))
+#endif
+#endif
+#endif
+
+/* Prototypes for non-quad routines. */
+#ifndef __ECOS
+void __assert __P((const char *, const char *, int, const char *))
+ __attribute__ ((__noreturn__));
+#endif
+int bcmp __P((const void *, const void *, size_t));
+int ffs __P((int));
+int locc __P((int, char *, u_int));
+void *memchr __P((const void *, int, size_t));
+int scanc __P((u_int, const u_char *, const u_char *, int));
+int skpc __P((int, size_t, u_char *));
+size_t strlen __P((const char *));
+char *strcat __P((char *, const char *));
+char *strcpy __P((char *, const char *));
+char *strncpy __P((char *, const char *, size_t));
+int strcmp __P((const char *, const char *));
+int strncmp __P((const char *, const char *, size_t));
+int strncasecmp __P((const char *, const char *, size_t));
+int getsn __P((char *, int));
+
+extern u_int8_t const __bcd2bin[], __bin2bcd[];
+#define bcd2bin(b) (__bcd2bin[(b)&0xff])
+#define bin2bcd(b) (__bin2bcd[(b)&0xff])
+
+#endif /* __INSIDE_NET */
+
+#endif /* __LIBKERN_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/machine/cdefs.h b/ecos/packages/net/tcpip/current/include/machine/cdefs.h
new file mode 100644
index 0000000..fe027bf
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/cdefs.h
@@ -0,0 +1,33 @@
+//==========================================================================
+//
+// include/machine/cdefs.h
+//
+// Architecture/platform specific parameters
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#ifndef _MACHINE_CDEFS_H_
+#define _MACHINE_CDEFS_H_
+
+#endif // _MACHINE_CDEFS_H_
diff --git a/ecos/packages/net/tcpip/current/include/machine/cpu.h b/ecos/packages/net/tcpip/current/include/machine/cpu.h
new file mode 100644
index 0000000..cd0c166
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/cpu.h
@@ -0,0 +1,33 @@
+//==========================================================================
+//
+// include/machine/cpu.h
+//
+// Architecture/platform specific parameters
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#ifndef _MACHINE_CPU_H_
+#define _MACHINE_CPU_H_
+
+#endif // _MACHINE_CPU_H_
diff --git a/ecos/packages/net/tcpip/current/include/machine/limits.h b/ecos/packages/net/tcpip/current/include/machine/limits.h
new file mode 100644
index 0000000..516be12
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/limits.h
@@ -0,0 +1,35 @@
+//==========================================================================
+//
+// include/machine/limits.h
+//
+// Architecture/platform specific limits
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#ifndef _MACHINE_LIMITS_H_
+#define _MACHINE_LIMITS_H_
+
+#include <limits.h> // Compiler provided
+
+#endif /* _MACHINE_LIMITS_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/machine/param.h b/ecos/packages/net/tcpip/current/include/machine/param.h
new file mode 100644
index 0000000..5f41b25
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/param.h
@@ -0,0 +1,138 @@
+//==========================================================================
+//
+// include/machine/param.h
+//
+// Architecture/platform specific parameters
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#ifndef _MACHINE_PARAM_H_
+#define _MACHINE_PARAM_H_
+
+#include <pkgconf/net.h>
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than CLBYTES (the software page size), and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+#define MSIZE 128 /* size of an mbuf */
+#define MCLSHIFT 11 /* convert bytes to m_buf clusters */
+#define MCLBYTES (1 << MCLSHIFT) /* size of a m_buf cluster */
+#define MCLOFSET (MCLBYTES - 1) /* offset within a m_buf cluster */
+#define CLBYTES 4096 /* size of actual cluster */
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...). The result is u_int and
+ * must be cast to any desired pointer type.
+ */
+#define ALIGNBYTES (sizeof(int) - 1)
+#define ALIGN(p) (((u_int)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
+// These symbols are used in the IPV6 stuff
+// (be more defensive about external setup)
+#ifdef __linux__
+#undef __linux__
+#endif
+#ifdef __bsdi__
+#undef __bsdi__
+#endif
+#ifdef __FreeBSD__
+#undef __FreeBSD__
+#endif
+#ifdef __OpenBSD__
+#undef __OpenBSD__
+#endif
+#ifdef __NetBSD__
+#undef __NetBSD__
+#endif
+
+
+#define __linux__ 0
+#define __bsdi__ 0
+#define __FreeBSD__ 0
+#define __OpenBSD__ 1
+#define __NetBSD__ 0
+
+// These definitions here to avoid needing <sys/systm.h>
+// This probably doesn't belong here, but we need these definitions
+#include <lib/libkern/libkern.h>
+#define SCARG(p,k) ((p)->k.datum) /* get arg from args pointer */
+#include <stdarg.h>
+
+// TEMP
+
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/kernel/kapi.h>
+#include <cyg/io/file.h>
+
+struct net_stats {
+ int count;
+ cyg_uint32 min_time, max_time, total_time;
+};
+
+#ifdef CYGDBG_NET_TIMING_STATS
+#define START_STATS() \
+ cyg_uint32 start_time, end_time, elapsed_time; \
+ HAL_CLOCK_READ(&start_time);
+#define FINISH_STATS(stats) \
+ HAL_CLOCK_READ(&end_time); \
+ if (end_time < start_time) { \
+ elapsed_time = (end_time+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - start_time; \
+ } else { \
+ elapsed_time = end_time - start_time; \
+ } \
+ if (stats.min_time == 0) { \
+ stats.min_time = 0x7FFFFFFF; \
+ } \
+ if (elapsed_time < stats.min_time) \
+ stats.min_time = elapsed_time; \
+ if (elapsed_time > stats.max_time) \
+ stats.max_time = elapsed_time; \
+ stats.total_time += elapsed_time; \
+ stats.count++;
+#else
+#define START_STATS()
+#define FINISH_STATS(X)
+#endif
+
+// timeout support
+typedef void (timeout_fun)(void *);
+extern cyg_uint32 timeout(timeout_fun *fun, void *arg, cyg_int32 delta);
+extern void untimeout(timeout_fun *fun, void *arg);
+extern int uiomove(caddr_t cp, int n, struct uio *uio);
+extern int copyout(const void *s, void *d, size_t len);
+extern int copyin(const void *s, void *d, size_t len);
+extern void ovbcopy(const void *s, void *d, size_t len);
+extern void get_mono_time(void);
+extern int arc4random(void);
+extern void get_random_bytes(void *buf, size_t len);
+
+extern void *hashinit(int elements, int type, int flags, u_long *hashmask);
+
+#endif // _MACHINE_PARAM_H_
diff --git a/ecos/packages/net/tcpip/current/include/machine/signal.h b/ecos/packages/net/tcpip/current/include/machine/signal.h
new file mode 100644
index 0000000..713237f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/signal.h
@@ -0,0 +1,30 @@
+//==========================================================================
+//
+// include/machine/signal.h
+//
+// Architecture specific 'signal' support
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// None defined
diff --git a/ecos/packages/net/tcpip/current/include/machine/stdarg.h b/ecos/packages/net/tcpip/current/include/machine/stdarg.h
new file mode 100644
index 0000000..e691eb3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/stdarg.h
@@ -0,0 +1,31 @@
+//==========================================================================
+//
+// include/machine/stdarg.h
+//
+// Architecture/compiler specifics
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// Get this from the compiler
+#include <stdarg.h>
diff --git a/ecos/packages/net/tcpip/current/include/machine/types.h b/ecos/packages/net/tcpip/current/include/machine/types.h
new file mode 100644
index 0000000..255d94d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/machine/types.h
@@ -0,0 +1,84 @@
+//==========================================================================
+//
+// include/machine/types.h
+//
+// Architecture/platform specific support for data types
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#ifndef _MACHINE_TYPES_H_
+#define _MACHINE_TYPES_H_
+
+#include <sys/cdefs.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+
+#define __BIT_TYPES_DEFINED__
+typedef __signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef unsigned int uint32_t;
+typedef long long int64_t;
+typedef unsigned long long u_int64_t;
+typedef unsigned long long uint64_t;
+
+// Types inherited from HAL
+
+typedef CYG_ADDRESS vaddr_t;
+typedef CYG_ADDRWORD vsize_t;
+typedef CYG_ADDRESS paddr_t;
+typedef CYG_ADDRWORD psize_t;
+
+typedef CYG_ADDRESS vm_offset_t;
+typedef CYG_ADDRWORD vm_size_t;
+
+// No good HAL definition for this
+
+typedef CYG_ADDRWORD register_t;
+
+
+// From <arch/ansi.h>
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#define _BSD_CLOCKID_T_ int
+#define _BSD_TIMER_T_ int
+#ifndef __time_t_defined // As defined/used by eCos libc
+#define _BSD_CLOCK_T_ cyg_int64 /* clock() */
+#define _BSD_TIME_T_ cyg_count32 /* time() */
+#endif
+
+#endif // _MACHINE_TYPES_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/bpf.h b/ecos/packages/net/tcpip/current/include/net/bpf.h
new file mode 100644
index 0000000..47665ba
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/bpf.h
@@ -0,0 +1,307 @@
+//==========================================================================
+//
+// include/net/bpf.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: bpf.h,v 1.12 1999/08/08 00:43:00 niklas Exp $ */
+/* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)bpf.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_BPF_H_
+#define _NET_BPF_H_
+
+/* BSD style release date */
+#define BPF_RELEASE 199606
+
+typedef int32_t bpf_int32;
+typedef u_int32_t bpf_u_int32;
+/*
+ * Alignment macros. BPF_WORDALIGN rounds up to the next even multiple of
+ * BPF_ALIGNMENT (which is at least as much as what a timeval needs).
+ */
+#define BPF_ALIGNMENT sizeof(long)
+#define BPF_WORDALIGN(x) (((x) + (BPF_ALIGNMENT - 1)) & ~(BPF_ALIGNMENT - 1))
+
+#define BPF_MAXINSNS 512
+#define BPF_MAXBUFSIZE 0x80000
+#define BPF_MINBUFSIZE 32
+
+/*
+ * Structure for BIOCSETF.
+ */
+struct bpf_program {
+ u_int bf_len;
+ struct bpf_insn *bf_insns;
+};
+
+/*
+ * Struct returned by BIOCGSTATS.
+ */
+struct bpf_stat {
+ u_int bs_recv; /* number of packets received */
+ u_int bs_drop; /* number of packets dropped */
+};
+
+/*
+ * Struct return by BIOCVERSION. This represents the version number of
+ * the filter language described by the instruction encodings below.
+ * bpf understands a program iff kernel_major == filter_major &&
+ * kernel_minor >= filter_minor, that is, if the value returned by the
+ * running kernel has the same major number and a minor number equal
+ * equal to or less than the filter being downloaded. Otherwise, the
+ * results are undefined, meaning an error may be returned or packets
+ * may be accepted haphazardly.
+ * It has nothing to do with the source code version.
+ */
+struct bpf_version {
+ u_short bv_major;
+ u_short bv_minor;
+};
+/* Current version number of filter architecture. */
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+/*
+ * BPF ioctls
+ *
+ * The first set is for compatibility with Sun's pcc style
+ * header files. If you're using gcc, we assume that you
+ * have run fixincludes so the latter set should work.
+ */
+#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
+#define BIOCGBLEN _IOR(B,102, u_int)
+#define BIOCSBLEN _IOWR(B,102, u_int)
+#define BIOCSETF _IOW(B,103, struct bpf_program)
+#define BIOCFLUSH _IO(B,104)
+#define BIOCPROMISC _IO(B,105)
+#define BIOCGDLT _IOR(B,106, u_int)
+#define BIOCGETIF _IOR(B,107, struct ifreq)
+#define BIOCSETIF _IOW(B,108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
+#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
+#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW(B,112, u_int)
+#define BIOCVERSION _IOR(B,113, struct bpf_version)
+#define BIOCSRSIG _IOW(B,114, u_int)
+#define BIOCGRSIG _IOR(B,115, u_int)
+#else
+#define BIOCGBLEN _IOR('B',102, u_int)
+#define BIOCSBLEN _IOWR('B',102, u_int)
+#define BIOCSETF _IOW('B',103, struct bpf_program)
+#define BIOCFLUSH _IO('B',104)
+#define BIOCPROMISC _IO('B',105)
+#define BIOCGDLT _IOR('B',106, u_int)
+#define BIOCGETIF _IOR('B',107, struct ifreq)
+#define BIOCSETIF _IOW('B',108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
+#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
+#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW('B',112, u_int)
+#define BIOCVERSION _IOR('B',113, struct bpf_version)
+#define BIOCSRSIG _IOW('B',114, u_int)
+#define BIOCGRSIG _IOR('B',115, u_int)
+#endif
+
+/*
+ * Structure prepended to each packet.
+ */
+struct bpf_hdr {
+ struct timeval bh_tstamp; /* time stamp */
+ u_int32_t bh_caplen; /* length of captured portion */
+ u_int32_t bh_datalen; /* original length of packet */
+ u_int16_t bh_hdrlen; /* length of bpf header (this struct
+ plus alignment padding) */
+};
+/*
+ * Because the structure above is not a multiple of 4 bytes, some compilers
+ * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
+ * Only the kernel needs to know about it; applications use bh_hdrlen.
+ * XXX To save a few bytes on 32-bit machines, we avoid end-of-struct
+ * XXX padding by using the size of the header data elements. This is
+ * XXX fail-safe: on new machines, we just use the 'safe' sizeof.
+ */
+#ifdef _KERNEL
+#if defined(__arm32__) || defined(__i386__) || defined(__m68k__) || \
+ defined(__mips__) || defined(__ns32k__) || defined(__sparc__) || \
+ defined(__vax__)
+#define SIZEOF_BPF_HDR 18
+#else
+#define SIZEOF_BPF_HDR sizeof(struct bpf_hdr)
+#endif
+#endif
+
+/*
+ * Data-link level type codes.
+ */
+#define DLT_NULL 0 /* no link-layer encapsulation */
+#define DLT_EN10MB 1 /* Ethernet (10Mb) */
+#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
+#define DLT_AX25 3 /* Amateur Radio AX.25 */
+#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
+#define DLT_CHAOS 5 /* Chaos */
+#define DLT_IEEE802 6 /* IEEE 802 Networks */
+#define DLT_ARCNET 7 /* ARCNET */
+#define DLT_SLIP 8 /* Serial Line IP */
+#define DLT_PPP 9 /* Point-to-point Protocol */
+#define DLT_FDDI 10 /* FDDI */
+#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
+#define DLT_LOOP 12 /* loopback type (af header) */
+#define DLT_ENC 13 /* IPSEC enc type (af header, spi, flags) */
+#define DLT_RAW 14 /* raw IP */
+#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
+#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
+
+/*
+ * The instruction encodings.
+ */
+/* instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define BPF_RVAL(code) ((code) & 0x18)
+#define BPF_A 0x10
+
+/* misc */
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define BPF_TAX 0x00
+#define BPF_TXA 0x80
+
+/*
+ * The instruction data structure.
+ */
+struct bpf_insn {
+ u_int16_t code;
+ u_char jt;
+ u_char jf;
+ int32_t k;
+};
+
+/*
+ * Macros for insn array initializers.
+ */
+#define BPF_STMT(code, k) { (u_int16_t)(code), 0, 0, k }
+#define BPF_JUMP(code, k, jt, jf) { (u_int16_t)(code), jt, jf, k }
+
+#ifdef _KERNEL
+int bpf_validate __P((struct bpf_insn *, int));
+void bpf_tap __P((caddr_t, u_char *, u_int));
+void bpf_mtap __P((caddr_t, struct mbuf *));
+void bpfattach __P((caddr_t *, struct ifnet *, u_int, u_int));
+void bpfdetach __P((struct ifnet *));
+void bpfilterattach __P((int));
+u_int bpf_filter __P((struct bpf_insn *, u_char *, u_int, u_int));
+#endif
+
+/*
+ * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
+ */
+#define BPF_MEMWORDS 16
+
+extern int ticks; /* from kern/kern_clock.c; incremented each */
+ /* clock tick. */
+
+#endif /* _NET_BPF_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/net/bpfdesc.h b/ecos/packages/net/tcpip/current/include/net/bpfdesc.h
new file mode 100644
index 0000000..5ab584f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/bpfdesc.h
@@ -0,0 +1,141 @@
+//==========================================================================
+//
+// include/net/bpfdesc.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: bpfdesc.h,v 1.5 1999/08/08 00:43:00 niklas Exp $ */
+/* $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)bpfdesc.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_BPFDESC_H_
+#define _NET_BPFDESC_H_
+
+#include <sys/select.h>
+
+/*
+ * Descriptor associated with each open bpf file.
+ */
+struct bpf_d {
+ struct bpf_d *bd_next; /* Linked list of descriptors */
+ /*
+ * Buffer slots: two mbuf clusters buffer the incoming packets.
+ * The model has three slots. Sbuf is always occupied.
+ * sbuf (store) - Receive interrupt puts packets here.
+ * hbuf (hold) - When sbuf is full, put cluster here and
+ * wakeup read (replace sbuf with fbuf).
+ * fbuf (free) - When read is done, put cluster here.
+ * On receiving, if sbuf is full and fbuf is 0, packet is dropped.
+ */
+ caddr_t bd_sbuf; /* store slot */
+ caddr_t bd_hbuf; /* hold slot */
+ caddr_t bd_fbuf; /* free slot */
+ int bd_slen; /* current length of store buffer */
+ int bd_hlen; /* current length of hold buffer */
+
+ int bd_bufsize; /* absolute length of buffers */
+
+ struct bpf_if * bd_bif; /* interface descriptor */
+ u_long bd_rtout; /* Read timeout in 'ticks' */
+ u_long bd_rdStart; /* when the read started */
+ struct bpf_insn *bd_filter; /* filter code */
+ u_long bd_rcount; /* number of packets received */
+ u_long bd_dcount; /* number of packets dropped */
+
+ u_char bd_promisc; /* true if listening promiscuously */
+ u_char bd_state; /* idle, waiting, or timed out */
+ u_char bd_immediate; /* true to return on packet arrival */
+ int bd_async; /* non-zero if packet reception should generate signal */
+ int bd_sig; /* signal to send upon packet reception */
+ pid_t bd_pgid; /* process or group id for signal */
+ uid_t bd_siguid; /* uid for process that set pgid */
+ uid_t bd_sigeuid; /* euid for process that set pgid */
+#if BSD < 199103
+ u_char bd_selcoll; /* true if selects collide */
+ int bd_timedout;
+ struct proc * bd_selproc; /* process that last selected us */
+#else
+ u_char bd_pad; /* explicit alignment */
+ struct selinfo bd_sel; /* bsd select info */
+#endif
+};
+
+/*
+ * Descriptor associated with each attached hardware interface.
+ */
+struct bpf_if {
+ struct bpf_if *bif_next; /* list of all interfaces */
+ struct bpf_d *bif_dlist; /* descriptor list */
+ struct bpf_if **bif_driverp; /* pointer into softc */
+ u_int bif_dlt; /* link layer type */
+ u_int bif_hdrlen; /* length of header (with padding) */
+ struct ifnet *bif_ifp; /* correspoding interface */
+};
+
+#ifdef _KERNEL
+int bpf_setf __P((struct bpf_d *, struct bpf_program *));
+#endif
+
+#endif // _NET_BPFDESC_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/if.h b/ecos/packages/net/tcpip/current/include/net/if.h
new file mode 100644
index 0000000..cc8b060
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if.h
@@ -0,0 +1,481 @@
+//==========================================================================
+//
+// include/net/if.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if.h,v 1.14 1999/12/08 06:50:17 itojun Exp $ */
+/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_IF_H_
+#define _NET_IF_H_
+
+#include <sys/queue.h>
+
+/*
+ * Structures defining a network interface, providing a packet
+ * transport mechanism (ala level 0 of the PUP protocols).
+ *
+ * Each interface accepts output datagrams of a specified maximum
+ * length, and provides higher level routines with input datagrams
+ * received from its medium.
+ *
+ * Output occurs when the routine if_output is called, with four parameters:
+ * (*ifp->if_output)(ifp, m, dst, rt)
+ * Here m is the mbuf chain to be sent and dst is the destination address.
+ * The output routine encapsulates the supplied datagram if necessary,
+ * and then transmits it on its medium.
+ *
+ * On input, each interface unwraps the data received by it, and either
+ * places it on the input queue of a internetwork datagram routine
+ * and posts the associated software interrupt, or passes the datagram to a raw
+ * packet input routine.
+ *
+ * Routines exist for locating interfaces by their addresses
+ * or for locating a interface on a certain network, as well as more general
+ * routing and gateway routines maintaining information used to locate
+ * interfaces. These routines live in the files if.c and route.c
+ */
+#include <sys/time.h>
+
+struct mbuf;
+struct proc;
+struct rtentry;
+struct socket;
+struct ether_header;
+struct arpcom;
+
+/*
+ * Structure defining statistics and other data kept regarding a network
+ * interface.
+ */
+struct if_data {
+ /* generic interface information */
+ u_char ifi_type; /* ethernet, tokenring, etc. */
+ u_char ifi_addrlen; /* media address length */
+ u_char ifi_hdrlen; /* media header length */
+ u_long ifi_mtu; /* maximum transmission unit */
+ u_long ifi_metric; /* routing metric (external only) */
+ u_long ifi_baudrate; /* linespeed */
+ /* volatile statistics */
+ u_long ifi_ipackets; /* packets received on interface */
+ u_long ifi_ierrors; /* input errors on interface */
+ u_long ifi_opackets; /* packets sent on interface */
+ u_long ifi_oerrors; /* output errors on interface */
+ u_long ifi_collisions; /* collisions on csma interfaces */
+ u_long ifi_ibytes; /* total number of octets received */
+ u_long ifi_obytes; /* total number of octets sent */
+ u_long ifi_imcasts; /* packets received via multicast */
+ u_long ifi_omcasts; /* packets sent via multicast */
+ u_long ifi_iqdrops; /* dropped on input, this interface */
+ u_long ifi_noproto; /* destined for unsupported protocol */
+ struct timeval ifi_lastchange; /* last updated */
+};
+
+/*
+ * Structure defining a queue for a network interface.
+ *
+ * (Would like to call this struct ``if'', but C isn't PL/1.)
+ */
+TAILQ_HEAD(ifnet_head, ifnet); /* the actual queue head */
+
+/*
+ * Length of interface external name, including terminating '\0'.
+ * Note: this is the same size as a generic device's external name.
+ */
+#define IFNAMSIZ 16
+#define IF_NAMESIZE IFNAMSIZ
+
+struct ifnet { /* and the entries */
+ void *if_softc; /* lower-level data for this if */
+ TAILQ_ENTRY(ifnet) if_list; /* all struct ifnets are chained */
+ TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */
+ char if_xname[IFNAMSIZ]; /* external name (name + unit) */
+ int if_pcount; /* number of promiscuous listeners */
+ caddr_t if_bpf; /* packet filter structure */
+ caddr_t if_bridge; /* bridge structure */
+ u_short if_index; /* numeric abbreviation for this if */
+ short if_timer; /* time 'til if_watchdog called */
+ short if_flags; /* up/down, broadcast, etc. */
+ struct if_data if_data; /* statistics and other data about if */
+/* procedure handles */
+ int (*if_output) /* output routine (enqueue) */
+ __P((struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *));
+ void (*if_start) /* initiate output routine */
+ __P((struct ifnet *));
+ int (*if_ioctl) /* ioctl routine */
+ __P((struct ifnet *, u_long, caddr_t));
+ int (*if_reset) /* XXX bus reset routine */
+ __P((struct ifnet *));
+ void (*if_watchdog) /* timer routine */
+ __P((struct ifnet *));
+ struct ifqueue {
+ struct mbuf *ifq_head;
+ struct mbuf *ifq_tail;
+ int ifq_len;
+ int ifq_maxlen;
+ int ifq_drops;
+ } if_snd; /* output queue */
+ struct ifprefix *if_prefixlist; /* linked list of prefixes per if */
+};
+#define if_mtu if_data.ifi_mtu
+#define if_type if_data.ifi_type
+#define if_addrlen if_data.ifi_addrlen
+#define if_hdrlen if_data.ifi_hdrlen
+#define if_metric if_data.ifi_metric
+#define if_baudrate if_data.ifi_baudrate
+#define if_ipackets if_data.ifi_ipackets
+#define if_ierrors if_data.ifi_ierrors
+#define if_opackets if_data.ifi_opackets
+#define if_oerrors if_data.ifi_oerrors
+#define if_collisions if_data.ifi_collisions
+#define if_ibytes if_data.ifi_ibytes
+#define if_obytes if_data.ifi_obytes
+#define if_imcasts if_data.ifi_imcasts
+#define if_omcasts if_data.ifi_omcasts
+#define if_iqdrops if_data.ifi_iqdrops
+#define if_noproto if_data.ifi_noproto
+#define if_lastchange if_data.ifi_lastchange
+
+#define IFF_UP 0x1 /* interface is up */
+#define IFF_BROADCAST 0x2 /* broadcast address valid */
+#define IFF_DEBUG 0x4 /* turn on debugging */
+#define IFF_LOOPBACK 0x8 /* is a loopback net */
+#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
+#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
+#define IFF_RUNNING 0x40 /* resources allocated */
+#define IFF_NOARP 0x80 /* no address resolution protocol */
+#define IFF_PROMISC 0x100 /* receive all packets */
+#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
+#define IFF_OACTIVE 0x400 /* transmission in progress */
+#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
+#define IFF_LINK0 0x1000 /* per link layer defined bit */
+#define IFF_LINK1 0x2000 /* per link layer defined bit */
+#define IFF_LINK2 0x4000 /* per link layer defined bit */
+#define IFF_MULTICAST 0x8000 /* supports multicast */
+
+/* flags set internally only: */
+#define IFF_CANTCHANGE \
+ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
+ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
+
+/*
+ * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
+ * input routines have queues of messages stored on ifqueue structures
+ * (defined above). Entries are added to and deleted from these structures
+ * by these macros, which should be called with ipl raised to splimp().
+ */
+#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
+#define IF_DROP(ifq) ((ifq)->ifq_drops++)
+#define IF_ENQUEUE(ifq, m) { \
+ (m)->m_nextpkt = 0; \
+ if ((ifq)->ifq_tail == 0) \
+ (ifq)->ifq_head = m; \
+ else \
+ (ifq)->ifq_tail->m_nextpkt = m; \
+ (ifq)->ifq_tail = m; \
+ (ifq)->ifq_len++; \
+}
+#define IF_PREPEND(ifq, m) { \
+ (m)->m_nextpkt = (ifq)->ifq_head; \
+ if ((ifq)->ifq_tail == 0) \
+ (ifq)->ifq_tail = (m); \
+ (ifq)->ifq_head = (m); \
+ (ifq)->ifq_len++; \
+}
+#define IF_DEQUEUE(ifq, m) { \
+ (m) = (ifq)->ifq_head; \
+ if (m) { \
+ if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \
+ (ifq)->ifq_tail = 0; \
+ (m)->m_nextpkt = 0; \
+ (ifq)->ifq_len--; \
+ } \
+}
+#define IF_IS_EMPTY(ifq) ((ifq)->ifq_len == 0)
+
+#define IFQ_ENQUEUE(ifq, m, pattr, err) \
+do { \
+ if (IF_QFULL((ifq))) { \
+ m_freem((m)); \
+ (err) = ENOBUFS; \
+ } else { \
+ IF_ENQUEUE((ifq), (m)); \
+ (err) = 0; \
+ } \
+ if ((err)) \
+ (ifq)->ifq_drops++; \
+} while (0)
+
+#define IFQ_MAXLEN 50
+#define IFNET_SLOWHZ 1 /* granularity is 1 second */
+
+/*
+ * The ifaddr structure contains information about one address
+ * of an interface. They are maintained by the different address families,
+ * are allocated and attached when an address is set, and are linked
+ * together so all addresses for an interface can be located.
+ */
+struct ifaddr {
+ struct sockaddr *ifa_addr; /* address of interface */
+ struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
+#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
+ struct sockaddr *ifa_netmask; /* used to determine subnet */
+ struct ifnet *ifa_ifp; /* back-pointer to interface */
+ TAILQ_ENTRY(ifaddr) ifa_list; /* list of addresses for interface */
+ void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */
+ __P((int, struct rtentry *, struct sockaddr *));
+ u_short ifa_flags; /* mostly rt_flags for cloning */
+ u_int ifa_refcnt; /* count of references */
+ int ifa_metric; /* cost of going out this interface */
+};
+#define IFA_ROUTE RTF_UP /* route installed */
+
+/*
+ * The prefix structure contains information about one prefix
+ * of an interface. They are maintained by the different address families,
+ * are allocated and attached when an prefix or an address is set,
+ * and are linked together so all prfefixes for an interface can be located.
+ */
+struct ifprefix {
+ struct sockaddr *ifpr_prefix; /* prefix of interface */
+ struct ifnet *ifpr_ifp; /* back-pointer to interface */
+ struct ifprefix *ifpr_next;
+ u_char ifpr_plen; /* prefix length in bits */
+ u_char ifpr_type; /* protocol dependent prefix type */
+};
+
+/*
+ * Message format for use in obtaining information about interfaces
+ * from sysctl and the routing socket.
+ */
+struct if_msghdr {
+ u_short ifm_msglen; /* to skip over non-understood messages */
+ u_char ifm_version; /* future binary compatability */
+ u_char ifm_type; /* message type */
+ int ifm_addrs; /* like rtm_addrs */
+ int ifm_flags; /* value of if_flags */
+ u_short ifm_index; /* index for associated ifp */
+ struct if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
+ * Message format for use in obtaining information about interface addresses
+ * from sysctl and the routing socket.
+ */
+struct ifa_msghdr {
+ u_short ifam_msglen; /* to skip over non-understood messages */
+ u_char ifam_version; /* future binary compatability */
+ u_char ifam_type; /* message type */
+ int ifam_addrs; /* like rtm_addrs */
+ int ifam_flags; /* value of ifa_flags */
+ u_short ifam_index; /* index for associated ifp */
+ int ifam_metric; /* value of ifa_metric */
+};
+
+/*
+ * Interface request structure used for socket
+ * ioctl's. All interface ioctl's must have parameter
+ * definitions which begin with ifr_name. The
+ * remainder may be interface specific.
+ */
+struct ifreq {
+#define IFHWADDRLEN 6
+ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_hwaddr;
+ short ifru_flags;
+ int ifru_metric;
+ caddr_t ifru_data;
+ } ifr_ifru;
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_flags ifr_ifru.ifru_flags /* flags */
+#define ifr_metric ifr_ifru.ifru_metric /* metric */
+#define ifr_media ifr_ifru.ifru_metric /* media options (overload) */
+#define ifr_data ifr_ifru.ifru_data /* for use by interface */
+};
+
+struct ifaliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr ifra_addr;
+ struct sockaddr ifra_dstaddr;
+#define ifra_broadaddr ifra_dstaddr
+ struct sockaddr ifra_mask;
+};
+
+struct ifmediareq {
+ char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ int ifm_current; /* current media options */
+ int ifm_mask; /* don't care mask */
+ int ifm_status; /* media status */
+ int ifm_active; /* active options */
+ int ifm_count; /* # entries in ifm_ulist
+ array */
+ int *ifm_ulist; /* media words */
+};
+
+/*
+ * Structure used in SIOCGIFCONF request.
+ * Used to retrieve interface configuration
+ * for machine (useful for programs which
+ * must know all networks accessible).
+ */
+struct ifconf {
+ int ifc_len; /* size of associated buffer */
+ union {
+ caddr_t ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
+#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
+};
+
+/*
+ * Structure for SIOC[AGD]LIFADDR
+ */
+struct if_laddrreq {
+ char iflr_name[IFNAMSIZ];
+ unsigned int flags;
+#define IFLR_PREFIX 0x8000 /* in: prefix given out: kernel fills id */
+ unsigned int prefixlen; /* in/out */
+ struct sockaddr_storage addr; /* in/out */
+ struct sockaddr_storage dstaddr; /* out */
+};
+
+struct if_nameindex {
+ unsigned int if_index;
+ char *if_name;
+};
+
+#ifndef _KERNEL
+__BEGIN_DECLS
+unsigned int if_nametoindex __P((const char *));
+char *if_indextoname __P((unsigned int, char *));
+struct if_nameindex *if_nameindex __P((void));
+__END_DECLS
+#define if_freenameindex(x) free(x)
+#endif
+
+#include <net/if_arp.h>
+
+#ifdef _KERNEL
+#define IFAFREE(ifa) { \
+ if ((ifa)->ifa_refcnt <= 0) \
+ ifafree(ifa); \
+ else \
+ (ifa)->ifa_refcnt--; \
+ }
+
+struct ifnet_head ifnet;
+struct ifnet **ifindex2ifnet;
+#if 0
+struct ifnet loif[];
+#endif
+int if_index;
+
+void ether_ifattach __P((struct ifnet *));
+void ether_ifdetach __P((struct ifnet *));
+int ether_ioctl __P((struct ifnet *, struct arpcom *, u_long, caddr_t));
+void ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *));
+int ether_output __P((struct ifnet *,
+ struct mbuf *, struct sockaddr *, struct rtentry *));
+char *ether_sprintf __P((u_char *));
+
+void if_attach __P((struct ifnet *));
+void if_attachtail __P((struct ifnet *));
+void if_attachhead __P((struct ifnet *));
+void if_detach __P((struct ifnet *));
+void if_down __P((struct ifnet *));
+void if_qflush __P((struct ifqueue *));
+void if_slowtimo __P((void *));
+void if_up __P((struct ifnet *));
+int ifconf __P((u_long, caddr_t));
+void ifinit __P((void));
+int ifioctl __P((struct socket *, u_long, caddr_t, struct proc *));
+int ifpromisc __P((struct ifnet *, int));
+struct ifnet *ifunit __P((char *));
+struct ifnet *if_withname __P((struct sockaddr *));
+
+struct ifaddr *ifa_ifwithaddr __P((struct sockaddr *));
+struct ifaddr *ifa_ifwithaf __P((int));
+struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *));
+struct ifaddr *ifa_ifwithnet __P((struct sockaddr *));
+struct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *,
+ struct sockaddr *));
+struct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *));
+void ifafree __P((struct ifaddr *));
+void link_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+
+int loioctl __P((struct ifnet *, u_long, caddr_t));
+void loopattach __P((int));
+int looutput __P((struct ifnet *,
+ struct mbuf *, struct sockaddr *, struct rtentry *));
+void lortrequest __P((int, struct rtentry *, struct sockaddr *));
+#endif /* _KERNEL */
+
+#endif // _NET_IF_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/if_arp.h b/ecos/packages/net/tcpip/current/include/net/if_arp.h
new file mode 100644
index 0000000..cf9f4db
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_arp.h
@@ -0,0 +1,123 @@
+//==========================================================================
+//
+// include/net/if_arp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_arp.h,v 1.3 1999/07/30 22:22:19 fgsch Exp $ */
+/* $NetBSD: if_arp.h,v 1.8 1995/03/08 02:56:52 cgd Exp $ */
+
+/*
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_arp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_IF_ARP_H_
+#define _NET_IF_ARP_H_
+
+/*
+ * Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. ARP packets are variable
+ * in size; the arphdr structure defines the fixed-length portion.
+ * Protocol type values are the same as those for 10 Mb/s Ethernet.
+ * It is followed by the variable-sized fields ar_sha, arp_spa,
+ * arp_tha and arp_tpa in that order, according to the lengths
+ * specified. Field names used correspond to RFC 826.
+ */
+struct arphdr {
+ u_int16_t ar_hrd; /* format of hardware address */
+#define ARPHRD_ETHER 1 /* ethernet hardware format */
+#define ARPHRD_IEEE802 6 /* IEEE 802 hardware format */
+#define ARPHRD_FRELAY 15 /* frame relay hardware format */
+ u_int16_t ar_pro; /* format of protocol address */
+ u_int8_t ar_hln; /* length of hardware address */
+ u_int8_t ar_pln; /* length of protocol address */
+ u_int16_t ar_op; /* one of: */
+#define ARPOP_REQUEST 1 /* request to resolve address */
+#define ARPOP_REPLY 2 /* response to previous request */
+#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
+#define ARPOP_REVREPLY 4 /* response giving protocol address */
+#define ARPOP_INVREQUEST 8 /* request to identify peer */
+#define ARPOP_INVREPLY 9 /* response identifying peer */
+/*
+ * The remaining fields are variable in size,
+ * according to the sizes above.
+ */
+#ifdef COMMENT_ONLY
+ u_int8_t ar_sha[]; /* sender hardware address */
+ u_int8_t ar_spa[]; /* sender protocol address */
+ u_int8_t ar_tha[]; /* target hardware address */
+ u_int8_t ar_tpa[]; /* target protocol address */
+#endif
+};
+
+/*
+ * ARP ioctl request
+ */
+struct arpreq {
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+};
+/* arp_flags and at_flags field values */
+#define ATF_INUSE 0x01 /* entry in use */
+#define ATF_COM 0x02 /* completed entry (enaddr valid) */
+#define ATF_PERM 0x04 /* permanent entry */
+#define ATF_PUBL 0x08 /* publish entry (respond for other host) */
+#define ATF_USETRAILERS 0x10 /* has requested trailers */
+
+#endif // _NET_IF_ARP_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/if_bridge.h b/ecos/packages/net/tcpip/current/include/net/if_bridge.h
new file mode 100644
index 0000000..7fcb33e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_bridge.h
@@ -0,0 +1,319 @@
+//==========================================================================
+//
+// include/net/if_bridge.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jason L. Wright (jason@thought.net)
+// Contributors: andrew.lunn@ascom.ch (Andrew Lunn), hmt, manu.sharma@ascom.ch
+// Date: 2000-07-18
+// Purpose: Ethernet bridge
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: if_bridge.h,v 1.25 2003/07/15 03:41:15 jason Exp $ */
+
+/*
+ * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ */
+
+/*
+ * Bridge control request: add/delete member interfaces.
+ */
+struct ifbreq {
+ char ifbr_name[IFNAMSIZ]; /* bridge ifs name */
+ char ifbr_ifsname[IFNAMSIZ]; /* member ifs name */
+ u_int32_t ifbr_ifsflags; /* member ifs flags */
+ u_int8_t ifbr_state; /* member stp state */
+ u_int8_t ifbr_priority; /* member stp priority */
+ u_int8_t ifbr_portno; /* member port number */
+ u_int32_t ifbr_path_cost; /* member stp path cost */
+};
+/* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
+#define IFBIF_LEARNING 0x0001 /* ifs can learn */
+#define IFBIF_DISCOVER 0x0002 /* ifs sends packets w/unknown dest */
+#define IFBIF_BLOCKNONIP 0x0004 /* ifs blocks non-IP/ARP in/out */
+#define IFBIF_STP 0x0008 /* ifs participates in spanning tree */
+#define IFBIF_SPAN 0x0100 /* ifs is a span port (ro) */
+#define IFBIF_RO_MASK 0xff00 /* read only bits */
+/* SIOCBRDGFLUSH */
+#define IFBF_FLUSHDYN 0x0 /* flush dynamic addresses only */
+#define IFBF_FLUSHALL 0x1 /* flush all addresses from cache */
+
+/* port states */
+#define BSTP_IFSTATE_DISABLED 0
+#define BSTP_IFSTATE_LISTENING 1
+#define BSTP_IFSTATE_LEARNING 2
+#define BSTP_IFSTATE_FORWARDING 3
+#define BSTP_IFSTATE_BLOCKING 4
+
+/*
+ * Interface list structure
+ */
+struct ifbifconf {
+ char ifbic_name[IFNAMSIZ]; /* bridge ifs name */
+ u_int32_t ifbic_len; /* buffer size */
+ union {
+ caddr_t ifbicu_buf;
+ struct ifbreq *ifbicu_req;
+ } ifbic_ifbicu;
+#define ifbic_buf ifbic_ifbicu.ifbicu_buf
+#define ifbic_req ifbic_ifbicu.ifbicu_req
+};
+
+/*
+ * Bridge address request
+ */
+struct ifbareq {
+ char ifba_name[IFNAMSIZ]; /* bridge name */
+ char ifba_ifsname[IFNAMSIZ]; /* destination ifs */
+ u_int8_t ifba_age; /* address age */
+ u_int8_t ifba_flags; /* address flags */
+ struct ether_addr ifba_dst; /* destination addr */
+};
+
+#define IFBAF_TYPEMASK 0x03 /* address type mask */
+#define IFBAF_DYNAMIC 0x00 /* dynamically learned */
+#define IFBAF_STATIC 0x01 /* static address */
+
+struct ifbaconf {
+ char ifbac_name[IFNAMSIZ]; /* bridge ifs name */
+ u_int32_t ifbac_len; /* buffer size */
+ union {
+ caddr_t ifbacu_buf; /* buffer */
+ struct ifbareq *ifbacu_req; /* request pointer */
+ } ifbac_ifbacu;
+#define ifbac_buf ifbac_ifbacu.ifbacu_buf
+#define ifbac_req ifbac_ifbacu.ifbacu_req
+};
+
+struct ifbrparam {
+ char ifbrp_name[IFNAMSIZ];
+ union {
+ u_int32_t ifbrpu_csize; /* cache size */
+ int ifbrpu_ctime; /* cache time (sec) */
+ u_int16_t ifbrpu_prio; /* bridge priority */
+ u_int8_t ifbrpu_hellotime; /* hello time (sec) */
+ u_int8_t ifbrpu_fwddelay; /* fwd delay (sec) */
+ u_int8_t ifbrpu_maxage; /* max age (sec) */
+ } ifbrp_ifbrpu;
+};
+#define ifbrp_csize ifbrp_ifbrpu.ifbrpu_csize
+#define ifbrp_ctime ifbrp_ifbrpu.ifbrpu_ctime
+#define ifbrp_prio ifbrp_ifbrpu.ifbrpu_prio
+#define ifbrp_hellotime ifbrp_ifbrpu.ifbrpu_hellotime
+#define ifbrp_fwddelay ifbrp_ifbrpu.ifbrpu_fwddelay
+#define ifbrp_maxage ifbrp_ifbrpu.ifbrpu_maxage
+
+/*
+ * Bridge cache size get/set
+ */
+struct ifbcachereq {
+ char ifbc_name[IFNAMSIZ]; /* bridge ifs name */
+ u_int32_t ifbc_size; /* cache size */
+};
+
+/*
+ * Bridge cache timeout get/set
+ */
+struct ifbcachetoreq {
+ char ifbct_name[IFNAMSIZ]; /* bridge ifs name */
+ u_int32_t ifbct_time; /* cache time (sec) */
+};
+
+/*
+ * Bridge mac rules
+ */
+struct ifbrlreq {
+ char ifbr_name[IFNAMSIZ]; /* bridge ifs name */
+ char ifbr_ifsname[IFNAMSIZ]; /* member ifs name */
+ u_int8_t ifbr_action; /* disposition */
+ u_int8_t ifbr_flags; /* flags */
+ struct ether_addr ifbr_src; /* source mac */
+ struct ether_addr ifbr_dst; /* destination mac */
+};
+#define BRL_ACTION_BLOCK 0x01 /* block frame */
+#define BRL_ACTION_PASS 0x02 /* pass frame */
+#define BRL_FLAG_IN 0x08 /* input rule */
+#define BRL_FLAG_OUT 0x04 /* output rule */
+#define BRL_FLAG_SRCVALID 0x02 /* src valid */
+#define BRL_FLAG_DSTVALID 0x01 /* dst valid */
+
+struct ifbrlconf {
+ char ifbrl_name[IFNAMSIZ]; /* bridge ifs name */
+ char ifbrl_ifsname[IFNAMSIZ]; /* member ifs name */
+ u_int32_t ifbrl_len; /* buffer size */
+ union {
+ caddr_t ifbrlu_buf;
+ struct ifbrlreq *ifbrlu_req;
+ } ifbrl_ifbrlu;
+#define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf
+#define ifbrl_req ifbrl_ifbrlu.ifbrlu_req
+};
+
+/*
+ * Bridge filtering rules
+ */
+SIMPLEQ_HEAD(brl_head, brl_node);
+
+struct brl_node {
+ SIMPLEQ_ENTRY(brl_node) brl_next; /* next rule */
+ struct ether_addr brl_src; /* source mac address */
+ struct ether_addr brl_dst; /* destination mac address */
+ u_int16_t brl_tag; /* pf tag ID */
+ u_int8_t brl_action; /* what to do with match */
+ u_int8_t brl_flags; /* comparision flags */
+};
+
+struct bridge_timer {
+ u_int16_t active;
+ u_int16_t value;
+};
+
+struct bstp_config_unit {
+ u_int64_t cu_rootid;
+ u_int64_t cu_bridge_id;
+ u_int32_t cu_root_path_cost;
+ u_int16_t cu_message_age;
+ u_int16_t cu_max_age;
+ u_int16_t cu_hello_time;
+ u_int16_t cu_forward_delay;
+ u_int16_t cu_port_id;
+ u_int8_t cu_message_type;
+ u_int8_t cu_topology_change_acknowledgment;
+ u_int8_t cu_topology_change;
+};
+
+struct bstp_tcn_unit {
+ u_int8_t tu_message_type;
+};
+
+/*
+ * Bridge interface list
+ */
+struct bridge_iflist {
+ LIST_ENTRY(bridge_iflist) next; /* next in list */
+ u_int64_t bif_designated_root;
+ u_int64_t bif_designated_bridge;
+ u_int32_t bif_path_cost;
+ u_int32_t bif_designated_cost;
+ struct bridge_timer bif_hold_timer;
+ struct bridge_timer bif_message_age_timer;
+ struct bridge_timer bif_forward_delay_timer;
+ struct bstp_config_unit bif_config_bpdu;
+ u_int16_t bif_port_id;
+ u_int16_t bif_designated_port;
+ u_int8_t bif_state;
+ u_int8_t bif_topology_change_acknowledge;
+ u_int8_t bif_config_pending;
+ u_int8_t bif_change_detection_enabled;
+ u_int8_t bif_priority;
+ struct brl_head bif_brlin; /* input rules */
+ struct brl_head bif_brlout; /* output rules */
+ struct ifnet *ifp; /* member interface */
+ u_int32_t bif_flags; /* member flags */
+};
+
+/*
+ * Bridge route node
+ */
+struct bridge_rtnode {
+ LIST_ENTRY(bridge_rtnode) brt_next; /* next in list */
+ struct ifnet *brt_if; /* destination ifs */
+ u_int8_t brt_flags; /* address flags */
+ u_int8_t brt_age; /* age counter */
+ struct ether_addr brt_addr; /* dst addr */
+};
+
+/*
+ * Software state for each bridge
+ */
+struct bridge_softc {
+ struct ifnet sc_if; /* the interface */
+ u_int64_t sc_designated_root;
+ u_int64_t sc_bridge_id;
+ struct bridge_iflist *sc_root_port;
+ u_int32_t sc_root_path_cost;
+ u_int16_t sc_max_age;
+ u_int16_t sc_hello_time;
+ u_int16_t sc_forward_delay;
+ u_int16_t sc_bridge_max_age;
+ u_int16_t sc_bridge_hello_time;
+ u_int16_t sc_bridge_forward_delay;
+ u_int16_t sc_topology_change_time;
+ u_int16_t sc_hold_time;
+ u_int16_t sc_bridge_priority;
+ u_int8_t sc_topology_change_detected;
+ u_int8_t sc_topology_change;
+ struct bridge_timer sc_hello_timer;
+ struct bridge_timer sc_topology_change_timer;
+ struct bridge_timer sc_tcn_timer;
+ u_int32_t sc_brtmax; /* max # addresses */
+ u_int32_t sc_brtcnt; /* current # addrs */
+ int sc_brttimeout; /* timeout ticks */
+ u_int32_t sc_hashkey; /* hash key */
+#ifndef __ECOS
+ struct timeout sc_brtimeout; /* timeout state */
+ struct timeout sc_bstptimeout; /* stp timeout */
+#endif
+ LIST_HEAD(, bridge_iflist) sc_iflist; /* interface list */
+ LIST_HEAD(bridge_rthead, bridge_rtnode) *sc_rts;/* hash table */
+ LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports */
+};
+
+#ifdef _KERNEL
+extern u_int8_t bstp_etheraddr[];
+
+void bridge_ifdetach(struct ifnet *);
+struct mbuf *bridge_input(struct ifnet *, struct ether_header *,
+ struct mbuf *);
+int bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *);
+struct mbuf *bstp_input(struct bridge_softc *, struct ifnet *,
+ struct ether_header *, struct mbuf *);
+void bstp_initialization(struct bridge_softc *);
+int bstp_ioctl(struct ifnet *, u_long, caddr_t);
+void bridge_rtdelete(struct bridge_softc *, struct ifnet *, int);
+#endif /* _KERNEL */
diff --git a/ecos/packages/net/tcpip/current/include/net/if_dl.h b/ecos/packages/net/tcpip/current/include/net/if_dl.h
new file mode 100644
index 0000000..2dba2a0
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_dl.h
@@ -0,0 +1,117 @@
+//==========================================================================
+//
+// include/net/if_dl.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_dl.h,v 1.2 1997/02/24 13:33:58 niklas Exp $ */
+/* $NetBSD: if_dl.h,v 1.8 1995/03/26 20:30:13 jtc Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_dl.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_IF_DL_H_
+#define _NET_IF_DL_H_
+
+/*
+ * A Link-Level Sockaddr may specify the interface in one of two
+ * ways: either by means of a system-provided index number (computed
+ * anew and possibly differently on every reboot), or by a human-readable
+ * string such as "il0" (for managerial convenience).
+ *
+ * Census taking actions, such as something akin to SIOCGCONF would return
+ * both the index and the human name.
+ *
+ * High volume transactions (such as giving a link-level ``from'' address
+ * in a recvfrom or recvmsg call) may be likely only to provide the indexed
+ * form, (which requires fewer copy operations and less space).
+ *
+ * The form and interpretation of the link-level address is purely a matter
+ * of convention between the device driver and its consumers; however, it is
+ * expected that all drivers for an interface of a given if_type will agree.
+ */
+
+/*
+ * Structure of a Link-Level sockaddr:
+ */
+struct sockaddr_dl {
+ u_char sdl_len; /* Total length of sockaddr */
+ u_char sdl_family; /* AF_DLI */
+ u_int16_t sdl_index; /* if != 0, system given index for interface */
+ u_char sdl_type; /* interface type */
+ u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */
+ u_char sdl_alen; /* link level address length */
+ u_char sdl_slen; /* link layer selector length */
+ char sdl_data[12]; /* minimum work area, can be larger;
+ contains both if name and ll address */
+};
+
+#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void link_addr __P((const char *, struct sockaddr_dl *));
+char *link_ntoa __P((const struct sockaddr_dl *));
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif // _NET_IF_DL_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/if_gif.h b/ecos/packages/net/tcpip/current/include/net/if_gif.h
new file mode 100644
index 0000000..52c8d5d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_gif.h
@@ -0,0 +1,115 @@
+//==========================================================================
+//
+// include/net/if_gif.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_gif.h,v 1.1 1999/12/08 06:50:18 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * if_gif.h
+ */
+
+#ifndef _NET_IF_GIF_H_
+#define _NET_IF_GIF_H_
+
+
+#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__)
+#if defined(_KERNEL) && !defined(_LKM)
+#include "opt_inet.h"
+#endif
+#endif
+
+#include <netinet/in.h>
+/* xxx sigh, why route have struct route instead of pointer? */
+
+struct gif_softc {
+ struct ifnet gif_if; /* common area */
+ struct sockaddr *gif_psrc; /* Physical src addr */
+ struct sockaddr *gif_pdst; /* Physical dst addr */
+ union {
+ struct route gifscr_ro; /* xxx */
+#ifdef INET6
+ struct route_in6 gifscr_ro6; /* xxx */
+#endif
+ } gifsc_gifscr;
+ int gif_flags;
+};
+
+#define gif_ro gifsc_gifscr.gifscr_ro
+#ifdef INET6
+#define gif_ro6 gifsc_gifscr.gifscr_ro6
+#endif
+
+#define GIFF_INUSE 0x1 /* gif is in use */
+
+#define GIF_MTU (1280) /* Default MTU */
+#define GIF_MTU_MIN (1280) /* Minimum MTU */
+#define GIF_MTU_MAX (8192) /* Maximum MTU */
+
+extern int ngif;
+extern struct gif_softc *gif;
+
+/* Prototypes */
+void gif_input __P((struct mbuf *, int, struct ifnet *));
+int gif_output __P((struct ifnet *, struct mbuf *,
+ struct sockaddr *, struct rtentry *));
+#if defined(__FreeBSD__) && __FreeBSD__ < 3
+int gif_ioctl __P((struct ifnet *, int, caddr_t));
+#else
+int gif_ioctl __P((struct ifnet *, u_long, caddr_t));
+#endif
+
+#endif /* _NET_IF_GIF_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/net/if_llc.h b/ecos/packages/net/tcpip/current/include/net/if_llc.h
new file mode 100644
index 0000000..a4e5adc
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_llc.h
@@ -0,0 +1,178 @@
+//==========================================================================
+//
+// include/net/if_llc.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_llc.h,v 1.3 1999/07/28 20:02:41 fgsch Exp $ */
+/* $NetBSD: if_llc.h,v 1.6 1995/03/08 02:56:57 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_llc.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_IF_LLC_H_
+#define _NET_IF_LLC_H_
+
+/*
+ * IEEE 802.2 Link Level Control headers, for use in conjunction with
+ * 802.{3,4,5} media access control methods.
+ *
+ * Headers here do not use bit fields due to shortcommings in many
+ * compilers.
+ */
+
+struct llc {
+ u_int8_t llc_dsap;
+ u_int8_t llc_ssap;
+ union {
+ struct {
+ u_int8_t control;
+ u_int8_t format_id;
+ u_int8_t class;
+ u_int8_t window_x2;
+ } type_u;
+ struct {
+ u_int8_t num_snd_x2;
+ u_int8_t num_rcv_x2;
+ } type_i;
+ struct {
+ u_int8_t control;
+ u_int8_t num_rcv_x2;
+ } type_s;
+ struct {
+ u_int8_t control;
+ struct frmrinfo {
+ u_int8_t rej_pdu_0;
+ u_int8_t rej_pdu_1;
+ u_int8_t frmr_control;
+ u_int8_t frmr_control_ext;
+ u_int8_t frmr_cause;
+ } frmrinfo;
+ } type_frmr;
+ struct {
+ u_int8_t control;
+ u_int8_t org_code[3];
+ u_int16_t ether_type;
+ } type_snap;
+ struct {
+ u_int8_t control;
+ u_int8_t control_ext;
+ } type_raw;
+ } llc_un;
+};
+#define llc_control llc_un.type_u.control
+#define llc_control_ext llc_un.type_raw.control_ext
+#define llc_fid llc_un.type_u.format_id
+#define llc_class llc_un.type_u.class
+#define llc_window llc_un.type_u.window_x2
+#define llc_frmrinfo llc_un.type_frmr.frmrinfo
+#define llc_frmr_pdu0 llc_un.type_frmr.frmrinfo.rej_pdu0
+#define llc_frmr_pdu1 llc_un.type_frmr.frmrinfo.rej_pdu1
+#define llc_frmr_control llc_un.type_frmr.frmrinfo.frmr_control
+#define llc_frmr_control_ext llc_un.type_frmr.frmrinfo.frmr_control_ext
+#define llc_frmr_cause llc_un.type_frmr.frmrinfo.frmr_control_ext
+
+/*
+ * Don't use sizeof(struct llc_un) for LLC header sizes
+ */
+#define LLC_UFRAMELEN 3
+#define LLC_ISFRAMELEN 4
+#define LLC_FRMRLEN 7
+#define LLC_SNAPFRAMELEN 8
+
+/*
+ * Unnumbered LLC format commands
+ */
+#define LLC_UI 0x3
+#define LLC_UI_P 0x13
+#define LLC_DISC 0x43
+#define LLC_DISC_P 0x53
+#define LLC_UA 0x63
+#define LLC_UA_P 0x73
+#define LLC_TEST 0xe3
+#define LLC_TEST_P 0xf3
+#define LLC_FRMR 0x87
+#define LLC_FRMR_P 0x97
+#define LLC_DM 0x0f
+#define LLC_DM_P 0x1f
+#define LLC_XID 0xaf
+#define LLC_XID_P 0xbf
+#define LLC_SABME 0x6f
+#define LLC_SABME_P 0x7f
+
+/*
+ * Supervisory LLC commands
+ */
+#define LLC_RR 0x01
+#define LLC_RNR 0x05
+#define LLC_REJ 0x09
+
+/*
+ * Info format - dummy only
+ */
+#define LLC_INFO 0x00
+
+/*
+ * ISO PDTR 10178 contains among others
+ */
+#define LLC_8021D_LSAP 0x42
+#define LLC_X25_LSAP 0x7e
+#define LLC_SNAP_LSAP 0xaa
+#define LLC_ISO_LSAP 0xfe
+
+#endif // _NET_IF_LLC_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/if_slvar.h b/ecos/packages/net/tcpip/current/include/net/if_slvar.h
new file mode 100644
index 0000000..55e87f8
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_slvar.h
@@ -0,0 +1,88 @@
+/* $OpenBSD: if_slvar.h,v 1.4 1997/02/24 13:34:01 niklas Exp $ */
+/* $NetBSD: if_slvar.h,v 1.16 1996/05/07 02:40:46 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_slvar.h 8.3 (Berkeley) 2/1/94
+ */
+
+/*
+ * Definitions for SLIP interface data structures
+ *
+ * (This exists so programs like slstats can get at the definition
+ * of sl_softc.)
+ */
+struct sl_softc {
+ struct ifnet sc_if; /* network-visible interface */
+ int sc_unit; /* XXX unit number */
+ struct ifqueue sc_fastq; /* interactive output queue */
+ struct tty *sc_ttyp; /* pointer to tty structure */
+ u_char *sc_mp; /* pointer to next available buf char */
+ u_char *sc_ep; /* pointer to last available buf char */
+ u_char *sc_buf; /* input buffer */
+ u_int sc_flags; /* see below */
+ u_int sc_escape; /* =1 if last char input was FRAME_ESCAPE */
+ long sc_lasttime; /* last time a char arrived */
+ long sc_abortcount; /* number of abort esacpe chars */
+ long sc_starttime; /* time of first abort in window */
+ long sc_oqlen; /* previous output queue size */
+ long sc_otimeout; /* number of times output's stalled */
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ int sc_oldbufsize; /* previous output buffer size */
+ int sc_oldbufquot; /* previous output buffer quoting */
+#endif
+#ifdef INET /* XXX */
+ struct slcompress sc_comp; /* tcp compression data */
+#endif
+ caddr_t sc_bpf; /* BPF data */
+};
+
+/* internal flags */
+#define SC_ERROR 0x0001 /* had an input error */
+
+/* visible flags */
+#define SC_COMPRESS IFF_LINK0 /* compress TCP traffic */
+#define SC_NOICMP IFF_LINK1 /* supress ICMP traffic */
+#define SC_AUTOCOMP IFF_LINK2 /* auto-enable TCP compression */
+
+#ifdef _KERNEL
+void slattach __P((void));
+void slclose __P((struct tty *));
+void slinput __P((int, struct tty *));
+int slioctl __P((struct ifnet *, u_long, caddr_t));
+int slopen __P((dev_t, struct tty *));
+int sloutput __P((struct ifnet *,
+ struct mbuf *, struct sockaddr *, struct rtentry *));
+void slstart __P((struct tty *));
+int sltioctl __P((struct tty *, u_long, caddr_t, int));
+#endif /* _KERNEL */
diff --git a/ecos/packages/net/tcpip/current/include/net/if_tun.h b/ecos/packages/net/tcpip/current/include/net/if_tun.h
new file mode 100644
index 0000000..b1e754a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_tun.h
@@ -0,0 +1,86 @@
+//==========================================================================
+//
+// include/net/if_tun.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_tun.h,v 1.8 1998/08/02 07:17:44 brian Exp $ */
+
+/*
+ * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
+ * Nottingham University 1987.
+ *
+ * This source may be freely distributed, however I would be interested
+ * in any changes that are made.
+ *
+ * This driver takes packets off the IP i/f and hands them up to a
+ * user process to have it's wicked way with. This driver has it's
+ * roots in a similar driver written by Phil Cockcroft (formerly) at
+ * UCL. This driver is based much more on read/write/select mode of
+ * operation though.
+ *
+ * from: @Header: if_tnreg.h,v 1.1.2.1 1992/07/16 22:39:16 friedl Exp
+ */
+
+#ifndef _NET_IF_TUN_H_
+#define _NET_IF_TUN_H_
+
+#include <sys/ioccom.h>
+
+#define TUN_OPEN 0x0001
+#define TUN_INITED 0x0002
+#define TUN_RCOLL 0x0004
+#define TUN_IASET 0x0008
+#define TUN_DSTADDR 0x0010
+#define TUN_RWAIT 0x0040
+#define TUN_ASYNC 0x0080
+#define TUN_NBIO 0x0100
+#define TUN_BRDADDR 0x0200
+#define TUN_STAYUP 0x0400
+
+#define TUN_READY (TUN_OPEN | TUN_INITED | TUN_IASET)
+
+/* Maximum packet size */
+#define TUNMTU 3000
+
+/* Maximum receive packet size (hard limit) */
+#define TUNMRU 16384
+
+/* ioctl's for get/set debug */
+#define TUNSDEBUG _IOW('t', 89, int)
+#define TUNGDEBUG _IOR('t', 90, int)
+
+/* iface info */
+struct tuninfo {
+ u_int mtu;
+ u_short type;
+ u_short flags;
+ u_int baudrate;
+};
+#define TUNSIFINFO _IOW('t', 91, struct tuninfo)
+#define TUNGIFINFO _IOR('t', 92, struct tuninfo)
+
+#endif /* !_NET_IF_TUN_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/net/if_types.h b/ecos/packages/net/tcpip/current/include/net/if_types.h
new file mode 100644
index 0000000..60e10aa
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/if_types.h
@@ -0,0 +1,139 @@
+//==========================================================================
+//
+// include/net/if_types.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_types.h,v 1.4 1999/12/08 06:50:18 itojun Exp $ */
+/* $NetBSD: if_types.h,v 1.7 1995/02/27 09:10:24 glass Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_types.h 8.2 (Berkeley) 4/20/94
+ */
+
+#ifndef _NET_IF_TYPES_H_
+#define _NET_IF_TYPES_H_
+
+/*
+ * Interface types for benefit of parsing media address headers.
+ * This list is derived from the SNMP list of ifTypes, currently
+ * documented in RFC1573.
+ */
+
+#define IFT_OTHER 0x1 /* none of the following */
+#define IFT_1822 0x2 /* old-style arpanet imp */
+#define IFT_HDH1822 0x3 /* HDH arpanet imp */
+#define IFT_X25DDN 0x4 /* x25 to imp */
+#define IFT_X25 0x5 /* PDN X25 interface (RFC877) */
+#define IFT_ETHER 0x6 /* Ethernet CSMACD */
+#define IFT_ISO88023 0x7 /* CMSA CD */
+#define IFT_ISO88024 0x8 /* Token Bus */
+#define IFT_ISO88025 0x9 /* Token Ring */
+#define IFT_ISO88026 0xa /* MAN */
+#define IFT_STARLAN 0xb
+#define IFT_P10 0xc /* Proteon 10MBit ring */
+#define IFT_P80 0xd /* Proteon 80MBit ring */
+#define IFT_HY 0xe /* Hyperchannel */
+#define IFT_FDDI 0xf
+#define IFT_LAPB 0x10
+#define IFT_SDLC 0x11
+#define IFT_T1 0x12
+#define IFT_CEPT 0x13 /* E1 - european T1 */
+#define IFT_ISDNBASIC 0x14
+#define IFT_ISDNPRIMARY 0x15
+#define IFT_PTPSERIAL 0x16 /* Proprietary PTP serial */
+#define IFT_PPP 0x17 /* RFC 1331 */
+#define IFT_LOOP 0x18 /* loopback */
+#define IFT_EON 0x19 /* ISO over IP */
+#define IFT_XETHER 0x1a /* obsolete 3MB experimental ethernet */
+#define IFT_NSIP 0x1b /* XNS over IP */
+#define IFT_SLIP 0x1c /* IP over generic TTY */
+#define IFT_ULTRA 0x1d /* Ultra Technologies */
+#define IFT_DS3 0x1e /* Generic T3 */
+#define IFT_SIP 0x1f /* SMDS */
+#define IFT_FRELAY 0x20 /* Frame Relay DTE only */
+#define IFT_RS232 0x21
+#define IFT_PARA 0x22 /* parallel-port */
+#define IFT_ARCNET 0x23
+#define IFT_ARCNETPLUS 0x24
+#define IFT_ATM 0x25 /* ATM cells */
+#define IFT_MIOX25 0x26
+#define IFT_SONET 0x27 /* SONET or SDH */
+#define IFT_X25PLE 0x28
+#define IFT_ISO88022LLC 0x29
+#define IFT_LOCALTALK 0x2a
+#define IFT_SMDSDXI 0x2b
+#define IFT_FRELAYDCE 0x2c /* Frame Relay DCE */
+#define IFT_V35 0x2d
+#define IFT_HSSI 0x2e
+#define IFT_HIPPI 0x2f
+#define IFT_MODEM 0x30 /* Generic Modem */
+#define IFT_AAL5 0x31 /* AAL5 over ATM */
+#define IFT_SONETPATH 0x32
+#define IFT_SONETVT 0x33
+#define IFT_SMDSICIP 0x34 /* SMDS InterCarrier Interface */
+#define IFT_PROPVIRTUAL 0x35 /* Proprietary Virtual/internal */
+#define IFT_PROPMUX 0x36 /* Proprietary Multiplexing */
+#define IFT_ENC 0x37 /* Encapsulation */
+
+/* private usage... how should we define these? */
+#define IFT_GIF 0xf0
+#define IFT_DUMMY 0xf1
+#define IFT_PVC 0xf2
+#define IFT_FAITH 0xf3
+
+#endif // _NET_IF_TYPES_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/netisr.h b/ecos/packages/net/tcpip/current/include/net/netisr.h
new file mode 100644
index 0000000..6c37e33
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/netisr.h
@@ -0,0 +1,137 @@
+//==========================================================================
+//
+// include/net/netisr.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: netisr.h,v 1.14 1999/12/08 15:58:30 itojun Exp $ */
+/* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1980, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)netisr.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_NETISR_H_
+#define _NET_NETISR_H_
+
+/*
+ * The networking code runs off software interrupts.
+ *
+ * You can switch into the network by doing splsoftnet() and return by splx().
+ * The software interrupt level for the network is higher than the software
+ * level for the clock (so you can enter the network in routines called
+ * at timeout time).
+ *
+ * The routine to request a network software interrupt, setsoftnet(),
+ * is defined in the machine-specific include files.
+ */
+
+/*
+ * Each ``pup-level-1'' input queue has a bit in a ``netisr'' status
+ * word which is used to de-multiplex a single software
+ * interrupt used for scheduling the network code to calls
+ * on the lowest level routine of each protocol.
+ */
+#ifdef __ECOS
+#define NETISR_SOFTNET 1 // Just used to force an interrupt
+#endif
+#define NETISR_IP 2 /* same as AF_INET */
+#define NETISR_IMP 3 /* same as AF_IMPLINK */
+#define NETISR_NS 6 /* same as AF_NS */
+#define NETISR_ISO 7 /* same as AF_ISO */
+#define NETISR_CCITT 10 /* same as AF_CCITT */
+#define NETISR_ATALK 16 /* same as AF_APPLETALK */
+#define NETISR_ARP 18 /* same as AF_LINK */
+#define NETISR_IPX 23 /* same as AF_IPX */
+#define NETISR_IPV6 24 /* same as AF_INET6 */
+#define NETISR_ISDN 26 /* same as AF_E164 */
+#define NETISR_NATM 27 /* same as AF_ATM */
+#define NETISR_PPP 28 /* for PPP processing */
+#define NETISR_BRIDGE 29 /* for bridge processing */
+
+#ifndef _LOCORE
+#ifdef _KERNEL
+#ifdef __ECOS
+#include <cyg/kernel/kapi.h>
+extern cyg_flag_t netint_flags;
+#else
+int netisr; /* scheduling bits for network */
+#endif
+
+void arpintr __P((void));
+void ipintr __P((void));
+void ip6intr __P((void));
+void atintr __P((void));
+void nsintr __P((void));
+void clnlintr __P((void));
+void natmintr __P((void));
+void pppintr __P((void));
+void ccittintr __P((void));
+void bridgeintr __P((void));
+
+#ifdef __ECOS
+#define schednetisr(anisr) cyg_flag_setbits(&netint_flags, 1<<(anisr));
+#else
+#include <dev/rndvar.h>
+
+#define schednetisr(anisr) \
+ { netisr |= 1<<(anisr); add_net_randomness(anisr); setsoftnet(); }
+#endif
+#endif
+#endif
+
+#endif // _NET_NETISR_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/radix.h b/ecos/packages/net/tcpip/current/include/net/radix.h
new file mode 100644
index 0000000..a176186
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/radix.h
@@ -0,0 +1,199 @@
+//==========================================================================
+//
+// include/net/radix.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: radix.h,v 1.3 1996/09/05 08:42:34 mickey Exp $ */
+/* $NetBSD: radix.h,v 1.8 1996/02/13 22:00:37 christos Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)radix.h 8.2 (Berkeley) 10/31/94
+ */
+
+#ifndef _NET_RADIX_H_
+#define _NET_RADIX_H_
+
+/*
+ * Radix search tree node layout.
+ */
+
+struct radix_node {
+ struct radix_mask *rn_mklist; /* list of masks contained in subtree */
+ struct radix_node *rn_p; /* parent */
+ short rn_b; /* bit offset; -1-index(netmask) */
+ char rn_bmask; /* node: mask for bit test*/
+ u_char rn_flags; /* enumerated next */
+#define RNF_NORMAL 1 /* leaf contains normal route */
+#define RNF_ROOT 2 /* leaf is root leaf for tree */
+#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */
+ union {
+ struct { /* leaf only data: */
+ caddr_t rn_Key; /* object of search */
+ caddr_t rn_Mask; /* netmask, if present */
+ struct radix_node *rn_Dupedkey;
+ } rn_leaf;
+ struct { /* node only data: */
+ int rn_Off; /* where to start compare */
+ struct radix_node *rn_L;/* progeny */
+ struct radix_node *rn_R;/* progeny */
+ } rn_node;
+ } rn_u;
+#ifdef RN_DEBUG
+ int rn_info;
+ struct radix_node *rn_twin;
+ struct radix_node *rn_ybro;
+#endif
+};
+
+#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey
+#define rn_key rn_u.rn_leaf.rn_Key
+#define rn_mask rn_u.rn_leaf.rn_Mask
+#define rn_off rn_u.rn_node.rn_Off
+#define rn_l rn_u.rn_node.rn_L
+#define rn_r rn_u.rn_node.rn_R
+
+/*
+ * Annotations to tree concerning potential routes applying to subtrees.
+ */
+
+extern struct radix_mask {
+ short rm_b; /* bit offset; -1-index(netmask) */
+ char rm_unused; /* cf. rn_bmask */
+ u_char rm_flags; /* cf. rn_flags */
+ struct radix_mask *rm_mklist; /* more masks to try */
+ union {
+ caddr_t rmu_mask; /* the mask */
+ struct radix_node *rmu_leaf; /* for normal routes */
+ } rm_rmu;
+ int rm_refs; /* # of references to this struct */
+} *rn_mkfreelist;
+
+#define rm_mask rm_rmu.rmu_mask
+#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */
+
+#define MKGet(m) {\
+ if (rn_mkfreelist) {\
+ m = rn_mkfreelist; \
+ rn_mkfreelist = (m)->rm_mklist; \
+ } else \
+ R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\
+
+#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}
+
+struct radix_node_head {
+ struct radix_node *rnh_treetop;
+ int rnh_addrsize; /* permit, but not require fixed keys */
+ int rnh_pktsize; /* permit, but not require fixed keys */
+ struct radix_node *(*rnh_addaddr) /* add based on sockaddr */
+ __P((void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]));
+ struct radix_node *(*rnh_addpkt) /* add based on packet hdr */
+ __P((void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]));
+ struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */
+ __P((void *v, void *mask, struct radix_node_head *head));
+ struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */
+ __P((void *v, void *mask, struct radix_node_head *head));
+ struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */
+ __P((void *v, struct radix_node_head *head));
+ struct radix_node *(*rnh_lookup) /* locate based on sockaddr */
+ __P((void *v, void *mask, struct radix_node_head *head));
+ struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */
+ __P((void *v, struct radix_node_head *head));
+ int (*rnh_walktree) /* traverse tree */
+ __P((struct radix_node_head *,
+ int (*)(struct radix_node *, void *), void *));
+ struct radix_node rnh_nodes[3]; /* empty tree for common case */
+};
+
+
+#ifndef _KERNEL
+#define Bcmp(a, b, n) bcmp(((char *)(a)), ((char *)(b)), (n))
+#define Bcopy(a, b, n) bcopy(((char *)(a)), ((char *)(b)), (unsigned)(n))
+#define Bzero(p, n) bzero((char *)(p), (int)(n));
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n)))
+#define Free(p) free((char *)p);
+#else
+#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n));
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_DONTWAIT))
+#define Free(p) free((caddr_t)p, M_RTABLE);
+#endif /* !_KERNEL */
+
+#if defined(_KERNEL) || defined(_ROUTED)
+void rn_init __P((void));
+int rn_inithead __P((void **, int));
+int rn_refines __P((void *, void *));
+int rn_walktree __P((struct radix_node_head *,
+ int (*)(struct radix_node *, void *), void *));
+struct radix_node
+ *rn_addmask __P((void *, int, int)),
+ *rn_addroute __P((void *, void *, struct radix_node_head *,
+ struct radix_node [2])),
+ *rn_delete __P((void *, void *, struct radix_node_head *)),
+ *rn_insert __P((void *, struct radix_node_head *, int *,
+ struct radix_node [2])),
+ *rn_lookup __P((void *, void *, struct radix_node_head *)),
+ *rn_match __P((void *, struct radix_node_head *)),
+ *rn_newpair __P((void *, int, struct radix_node[2])),
+ *rn_search __P((void *, struct radix_node *)),
+ *rn_search_m __P((void *, struct radix_node *, void *));
+#endif /* define(_KERNEL) || defined(_ROUTED) */
+
+#endif /* !_NET_RADIX_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/net/raw_cb.h b/ecos/packages/net/tcpip/current/include/net/raw_cb.h
new file mode 100644
index 0000000..68c0a25
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/raw_cb.h
@@ -0,0 +1,105 @@
+//==========================================================================
+//
+// include/net/raw_cb.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: raw_cb.h,v 1.2 1996/03/03 21:07:17 niklas Exp $ */
+/* $NetBSD: raw_cb.h,v 1.9 1996/02/13 22:00:41 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)raw_cb.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_RAW_CB_H_
+#define _NET_RAW_CB_H_
+
+/*
+ * Raw protocol interface control block. Used
+ * to tie a socket to the generic raw interface.
+ */
+struct rawcb {
+ LIST_ENTRY(rawcb) rcb_list; /* doubly linked list */
+ struct socket *rcb_socket; /* back pointer to socket */
+ struct sockaddr *rcb_faddr; /* destination address */
+ struct sockaddr *rcb_laddr; /* socket's address */
+ struct sockproto rcb_proto; /* protocol family, protocol */
+};
+
+#define sotorawcb(so) ((struct rawcb *)(so)->so_pcb)
+
+/*
+ * Nominal space allocated to a raw socket.
+ */
+#define RAWSNDQ 8192
+#define RAWRCVQ 8192
+
+#ifdef _KERNEL
+LIST_HEAD(, rawcb) rawcb; /* head of list */
+
+int raw_attach __P((struct socket *, int));
+void *raw_ctlinput __P((int, struct sockaddr *, void *));
+void raw_detach __P((struct rawcb *));
+void raw_disconnect __P((struct rawcb *));
+void raw_init __P((void));
+void raw_input __P((struct mbuf *, ...));
+int raw_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+
+#endif /* _KERNEL */
+
+#endif // _NET_RAW_CB_H_
diff --git a/ecos/packages/net/tcpip/current/include/net/route.h b/ecos/packages/net/tcpip/current/include/net/route.h
new file mode 100644
index 0000000..622beb2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/net/route.h
@@ -0,0 +1,383 @@
+//==========================================================================
+//
+// include/net/route.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: route.h,v 1.7 1999/12/08 06:50:18 itojun Exp $ */
+/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)route.h 8.3 (Berkeley) 4/19/94
+ */
+
+#ifndef _NET_ROUTE_H_
+#define _NET_ROUTE_H_
+
+#include <sys/queue.h>
+
+/*
+ * Kernel resident routing tables.
+ *
+ * The routing tables are initialized when interface addresses
+ * are set by making entries for all directly connected interfaces.
+ */
+
+/*
+ * A route consists of a destination address and a reference
+ * to a routing entry. These are often held by protocols
+ * in their control blocks, e.g. inpcb.
+ */
+struct route {
+ struct rtentry *ro_rt;
+ struct sockaddr ro_dst;
+};
+
+/*
+ * These numbers are used by reliable protocols for determining
+ * retransmission behavior and are included in the routing structure.
+ */
+struct rt_metrics {
+ u_long rmx_locks; /* Kernel must leave these values alone */
+ u_long rmx_mtu; /* MTU for this path */
+ u_long rmx_hopcount; /* max hops expected */
+ u_long rmx_expire; /* lifetime for route, e.g. redirect */
+ u_long rmx_recvpipe; /* inbound delay-bandwith product */
+ u_long rmx_sendpipe; /* outbound delay-bandwith product */
+ u_long rmx_ssthresh; /* outbound gateway buffer limit */
+ u_long rmx_rtt; /* estimated round trip time */
+ u_long rmx_rttvar; /* estimated rtt variance */
+ u_long rmx_pksent; /* packets sent using this route */
+};
+
+/*
+ * rmx_rtt and rmx_rttvar are stored as microseconds;
+ * RTTTOPRHZ(rtt) converts to a value suitable for use
+ * by a protocol slowtimo counter.
+ */
+#define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */
+#define RTTTOPRHZ(r) ((r) / (RTM_RTTUNIT / PR_SLOWHZ))
+
+/*
+ * We distinguish between routes to hosts and routes to networks,
+ * preferring the former if available. For each route we infer
+ * the interface to use from the gateway address supplied when
+ * the route was entered. Routes that forward packets through
+ * gateways are marked so that the output routines know to address the
+ * gateway rather than the ultimate destination.
+ */
+#ifndef RNF_NORMAL
+#include <net/radix.h>
+#endif
+struct rtentry {
+ struct radix_node rt_nodes[2]; /* tree glue, and other values */
+#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key))
+#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask))
+ struct sockaddr *rt_gateway; /* value */
+ u_int rt_flags; /* up/down?, host/net */
+ short rt_refcnt; /* # held references */
+ short rt_filler; /* XXX */
+ u_long rt_use; /* raw # packets forwarded */
+ struct ifnet *rt_ifp; /* the answer: interface to use */
+ struct ifaddr *rt_ifa; /* the answer: interface to use */
+ struct sockaddr *rt_genmask; /* for generation of cloned routes */
+ caddr_t rt_llinfo; /* pointer to link level info cache */
+ struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */
+ struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */
+ struct rtentry *rt_parent; /* If cloned, parent of this route. */
+ LIST_HEAD(, rttimer) rt_timer; /* queue of timeouts for misc funcs */
+};
+#define rt_use rt_rmx.rmx_pksent
+
+#ifdef __ECOS
+/*
+ * This structure modelled after the Linux 'route' functions
+ * Used by the SIOCADDRT and SIOCDELRT calls
+ */
+struct ecos_rtentry
+ {
+ struct sockaddr rt_dst; /* Target address. */
+ struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */
+ struct sockaddr rt_genmask; /* Target network mask (IP). */
+ unsigned short int rt_flags;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+ short int rt_metric; /* +1 for binary compatibility! */
+ char *rt_dev; /* Forcing the device at add. */
+ unsigned long int rt_mtu; /* Per route MTU/Window. */
+ unsigned long int rt_window; /* Window clamping. */
+ unsigned short int rt_irtt; /* Initial RTT. */
+ };
+/* Compatibility hack. */
+#define rt_mss rt_mtu
+#endif
+
+/*
+ * Following structure necessary for 4.3 compatibility;
+ * We should eventually move it to a compat file.
+ */
+struct ortentry {
+ u_int32_t rt_hash; /* to speed lookups */
+ struct sockaddr rt_dst; /* key */
+ struct sockaddr rt_gateway; /* value */
+ int16_t rt_flags; /* up/down?, host/net */
+ int16_t rt_refcnt; /* # held references */
+ u_int32_t rt_ouse; /* raw # packets forwarded (was: rt_use) */
+ struct ifnet *rt_ifp; /* the answer: interface to use */
+};
+
+#define RTF_UP 0x1 /* route usable */
+#define RTF_GATEWAY 0x2 /* destination is a gateway */
+#define RTF_HOST 0x4 /* host entry (net otherwise) */
+#define RTF_REJECT 0x8 /* host or net unreachable */
+#define RTF_DYNAMIC 0x10 /* created dynamically (by redirect) */
+#define RTF_MODIFIED 0x20 /* modified dynamically (by redirect) */
+#define RTF_DONE 0x40 /* message confirmed */
+#define RTF_MASK 0x80 /* subnet mask present */
+#define RTF_CLONING 0x100 /* generate new routes on use */
+#define RTF_XRESOLVE 0x200 /* external daemon resolves name */
+#define RTF_LLINFO 0x400 /* generated by ARP or ESIS */
+#define RTF_STATIC 0x800 /* manually added */
+#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */
+#define RTF_PROTO3 0x2000 /* protocol specific routing flag */
+#define RTF_PROTO2 0x4000 /* protocol specific routing flag */
+#define RTF_PROTO1 0x8000 /* protocol specific routing flag */
+
+/*
+ * New IPv6 routing flags.
+ *
+ * PROTO1 and PROTO2 are used, and defined in netinet6/ipv6_var.h.
+ */
+#define RTF_TUNNEL 0x100000 /* Tunnelling bit. */
+
+/*
+ * Routing statistics.
+ */
+struct rtstat {
+ u_int32_t rts_badredirect; /* bogus redirect calls */
+ u_int32_t rts_dynamic; /* routes created by redirects */
+ u_int32_t rts_newgateway; /* routes modified by redirects */
+ u_int32_t rts_unreach; /* lookups which failed */
+ u_int32_t rts_wildcard; /* lookups satisfied by a wildcard */
+};
+
+/*
+ * Structures for routing messages.
+ */
+struct rt_msghdr {
+ u_short rtm_msglen; /* to skip over non-understood messages */
+ u_char rtm_version; /* future binary compatibility */
+ u_char rtm_type; /* message type */
+ u_short rtm_index; /* index for associated ifp */
+ int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
+ int rtm_addrs; /* bitmask identifying sockaddrs in msg */
+ pid_t rtm_pid; /* identify sender */
+ int rtm_seq; /* for sender to identify action */
+ int rtm_errno; /* why failed */
+ int rtm_use; /* from rtentry */
+ u_long rtm_inits; /* which metrics we are initializing */
+ struct rt_metrics rtm_rmx; /* metrics themselves */
+};
+
+#define RTM_VERSION 3 /* Up the ante and ignore older versions */
+
+#define RTM_ADD 0x1 /* Add Route */
+#define RTM_DELETE 0x2 /* Delete Route */
+#define RTM_CHANGE 0x3 /* Change Metrics or flags */
+#define RTM_GET 0x4 /* Report Metrics */
+#define RTM_LOSING 0x5 /* Kernel Suspects Partitioning */
+#define RTM_REDIRECT 0x6 /* Told to use different route */
+#define RTM_MISS 0x7 /* Lookup failed on this address */
+#define RTM_LOCK 0x8 /* fix specified metrics */
+#define RTM_OLDADD 0x9 /* caused by SIOCADDRT */
+#define RTM_OLDDEL 0xa /* caused by SIOCDELRT */
+#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */
+#define RTM_NEWADDR 0xc /* address being added to iface */
+#define RTM_DELADDR 0xd /* address being removed from iface */
+#define RTM_IFINFO 0xe /* iface going up/down etc. */
+
+#define RTV_MTU 0x1 /* init or lock _mtu */
+#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */
+#define RTV_EXPIRE 0x4 /* init or lock _hopcount */
+#define RTV_RPIPE 0x8 /* init or lock _recvpipe */
+#define RTV_SPIPE 0x10 /* init or lock _sendpipe */
+#define RTV_SSTHRESH 0x20 /* init or lock _ssthresh */
+#define RTV_RTT 0x40 /* init or lock _rtt */
+#define RTV_RTTVAR 0x80 /* init or lock _rttvar */
+
+/*
+ * Bitmask values for rtm_addr.
+ */
+#define RTA_DST 0x1 /* destination sockaddr present */
+#define RTA_GATEWAY 0x2 /* gateway sockaddr present */
+#define RTA_NETMASK 0x4 /* netmask sockaddr present */
+#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */
+#define RTA_IFP 0x10 /* interface name sockaddr present */
+#define RTA_IFA 0x20 /* interface addr sockaddr present */
+#define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */
+#define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */
+
+/*
+ * Index offsets for sockaddr array for alternate internal encoding.
+ */
+#define RTAX_DST 0 /* destination sockaddr present */
+#define RTAX_GATEWAY 1 /* gateway sockaddr present */
+#define RTAX_NETMASK 2 /* netmask sockaddr present */
+#define RTAX_GENMASK 3 /* cloning mask sockaddr present */
+#define RTAX_IFP 4 /* interface name sockaddr present */
+#define RTAX_IFA 5 /* interface addr sockaddr present */
+#define RTAX_AUTHOR 6 /* sockaddr for author of redirect */
+#define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */
+#define RTAX_MAX 8 /* size of array to allocate */
+
+struct rt_addrinfo {
+ int rti_addrs;
+ struct sockaddr *rti_info[RTAX_MAX];
+};
+
+struct route_cb {
+ int ip_count;
+ int ip6_count;
+ int ns_count;
+ int iso_count;
+ int any_count;
+};
+
+/*
+ * This structure, and the prototypes for the rt_timer_{init,remove_all,
+ * add,timer} functions all used with the kind permission of BSDI.
+ * These allow functions to be called for routes at specific times.
+ */
+
+struct rttimer {
+ TAILQ_ENTRY(rttimer) rtt_next; /* entry on timer queue */
+ LIST_ENTRY(rttimer) rtt_link; /* multiple timers per rtentry */
+ struct rttimer_queue *rtt_queue;/* back pointer to queue */
+ struct rtentry *rtt_rt; /* Back pointer to the route */
+ void (*rtt_func) __P((struct rtentry *,
+ struct rttimer *));
+ time_t rtt_time; /* When this timer was registered */
+};
+
+struct rttimer_queue {
+ long rtq_timeout;
+ TAILQ_HEAD(, rttimer) rtq_head;
+ LIST_ENTRY(rttimer_queue) rtq_link;
+};
+
+#ifdef _KERNEL
+#define RTFREE(rt) do { \
+ if ((rt)->rt_refcnt <= 1) \
+ rtfree(rt); \
+ else \
+ (rt)->rt_refcnt--; \
+} while (0)
+
+/*
+ * Values for additional argument to rtalloc_noclone() and rtalloc2()
+ */
+#define ALL_CLONING 0
+#define ONNET_CLONING 1
+#define NO_CLONING 2
+
+struct route_cb route_cb;
+struct rtstat rtstat;
+struct radix_node_head *rt_tables[AF_MAX+1];
+
+struct socket;
+void route_init __P((void));
+int route_output __P((struct mbuf *, ...));
+int route_usrreq __P((struct socket *, int, struct mbuf *,
+ struct mbuf *, struct mbuf *));
+void rt_ifmsg __P((struct ifnet *));
+void rt_maskedcopy __P((struct sockaddr *,
+ struct sockaddr *, struct sockaddr *));
+void rt_missmsg __P((int, struct rt_addrinfo *, int, int));
+void rt_newaddrmsg __P((int, struct ifaddr *, int, struct rtentry *));
+int rt_setgate __P((struct rtentry *, struct sockaddr *,
+ struct sockaddr *));
+void rt_setmetrics __P((u_long, struct rt_metrics *, struct rt_metrics *));
+int rt_timer_add __P((struct rtentry *,
+ void(*)(struct rtentry *, struct rttimer *),
+ struct rttimer_queue *));
+void rt_timer_init __P((void));
+struct rttimer_queue *
+ rt_timer_queue_create __P((u_int));
+void rt_timer_queue_change __P((struct rttimer_queue *, long));
+void rt_timer_queue_destroy __P((struct rttimer_queue *, int));
+void rt_timer_remove_all __P((struct rtentry *));
+void rt_timer_timer __P((void *));
+void rtable_init __P((void **));
+void rtalloc __P((struct route *));
+struct rtentry *
+ rtalloc1 __P((struct sockaddr *, int));
+void rtalloc_noclone __P((struct route *, int));
+struct rtentry *
+ rtalloc2 __P((struct sockaddr *, int, int));
+void rtfree __P((struct rtentry *));
+int rtinit __P((struct ifaddr *, int, int));
+int rtioctl __P((u_long, caddr_t, struct proc *));
+void rtredirect __P((struct sockaddr *, struct sockaddr *,
+ struct sockaddr *, int, struct sockaddr *,
+ struct rtentry **));
+int rtrequest __P((int, struct sockaddr *,
+ struct sockaddr *, struct sockaddr *, int,
+ struct rtentry **));
+void ipv4_tunnelsetup __P((struct rtentry *));
+#endif /* _KERNEL */
+
+#endif // _NET_ROUTE_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/icmp6.h b/ecos/packages/net/tcpip/current/include/netinet/icmp6.h
new file mode 100644
index 0000000..2c53488
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/icmp6.h
@@ -0,0 +1,66 @@
+//==========================================================================
+//
+// include/netinet/icmp6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: icmp6.h,v 1.1 1999/12/08 06:50:18 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET_ICMP6_H_
+#define _NETINET_ICMP6_H_
+
+#include <netinet6/icmp6.h>
+
+#endif /* !_NETINET_ICMP6_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/icmp_var.h b/ecos/packages/net/tcpip/current/include/netinet/icmp_var.h
new file mode 100644
index 0000000..8ba142b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/icmp_var.h
@@ -0,0 +1,108 @@
+//==========================================================================
+//
+// include/netinet/icmp_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: icmp_var.h,v 1.4 1998/01/06 01:38:35 deraadt Exp $ */
+/* $NetBSD: icmp_var.h,v 1.8 1995/03/26 20:32:19 jtc Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_ICMP_VAR_H_
+#define _NETINET_ICMP_VAR_H_
+
+/*
+ * Variables related to this implementation
+ * of the internet control message protocol.
+ */
+struct icmpstat {
+/* statistics related to icmp packets generated */
+ u_long icps_error; /* # of calls to icmp_error */
+ u_long icps_oldshort; /* no error 'cuz old ip too short */
+ u_long icps_oldicmp; /* no error 'cuz old was icmp */
+ u_long icps_outhist[ICMP_MAXTYPE + 1];
+/* statistics related to input messages processed */
+ u_long icps_badcode; /* icmp_code out of range */
+ u_long icps_tooshort; /* packet < ICMP_MINLEN */
+ u_long icps_checksum; /* bad checksum */
+ u_long icps_badlen; /* calculated bound mismatch */
+ u_long icps_reflect; /* number of responses */
+ u_long icps_bmcastecho; /* rejected broadcast icmps */
+ u_long icps_inhist[ICMP_MAXTYPE + 1];
+};
+
+/*
+ * Names for ICMP sysctl objects
+ */
+#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */
+#define ICMPCTL_BMCASTECHO 2 /* reply to icmps to broadcast/mcast */
+#define ICMPCTL_MAXID 3
+
+#define ICMPCTL_NAMES { \
+ { 0, 0 }, \
+ { "maskrepl", CTLTYPE_INT }, \
+ { "bmcastecho", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+struct icmpstat icmpstat;
+#endif
+
+#endif // _NETINET_ICMP_VAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/if_arc.h b/ecos/packages/net/tcpip/current/include/netinet/if_arc.h
new file mode 100644
index 0000000..424e4d3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/if_arc.h
@@ -0,0 +1,158 @@
+//==========================================================================
+//
+// include/netinet/if_arc.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_arc.h,v 1.2 1997/02/24 14:06:34 niklas Exp $ */
+/* $NetBSD: if_arc.h,v 1.5 1995/06/07 00:14:04 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * from: NetBSD: if_ether.h,v 1.10 1994/06/29 06:37:55 cgd Exp
+ * @(#)if_ether.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IF_ARC_H_
+#define _NETINET_IF_ARC_H_
+
+/*
+ * Arcnet address - 1 octets
+ * don't know who uses this.
+ */
+struct arc_addr {
+ u_int8_t arc_addr_octet[1];
+};
+
+/*
+ * Structure of a 2.5MB/s Arcnet header.
+ * as given to interface code.
+ */
+struct arc_header {
+ u_int8_t arc_shost;
+ u_int8_t arc_dhost;
+ u_int8_t arc_type;
+ /*
+ * only present for newstyle encoding with LL fragmentation.
+ * Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead.
+ */
+ u_int8_t arc_flag;
+ u_int16_t arc_seqid;
+
+ /*
+ * only present in exception packets (arc_flag == 0xff)
+ */
+ u_int8_t arc_type2; /* same as arc_type */
+ u_int8_t arc_flag2; /* real flag value */
+ u_int16_t arc_seqid2; /* real seqid value */
+};
+
+#define ARC_ADDR_LEN 1
+
+#define ARC_HDRLEN 3
+#define ARC_HDRNEWLEN 6
+
+/* these lengths are data link layer length - 2*ARC_ADDR_LEN */
+#define ARC_MIN_LEN 1
+#define ARC_MIN_FORBID_LEN 254
+#define ARC_MAX_FORBID_LEN 256
+#define ARC_MAX_LEN 508
+
+
+/* RFC 1051 */
+#define ARCTYPE_IP_OLD 240 /* IP protocol */
+#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
+
+/* RFC 1201 */
+#define ARCTYPE_IP 212 /* IP protocol */
+#define ARCTYPE_ARP 213 /* address resolution protocol */
+#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
+
+#define ARCTYPE_ATALK 221 /* Appletalk */
+#define ARCTYPE_BANIAN 247 /* Banyan Vines */
+#define ARCTYPE_IPX 250 /* Novell IPX */
+
+#define ARCMTU 507
+#define ARCMIN 0
+
+struct arccom {
+ struct ifnet ac_if; /* network-visible interface */
+ u_int8_t ac_anaddr; /* arcnet hardware address */
+ struct in_addr ac_ipaddr; /* copy of ip address- XXX */
+
+ u_int16_t ac_seqid; /* seq. id used by PHDS encap. */
+
+ struct ac_frag {
+ u_int8_t af_maxflag; /* from first packet */
+ u_int8_t af_lastseen; /* last split flag seen */
+ u_int16_t af_seqid;
+ struct mbuf *af_packet;
+ } ac_fragtab[256]; /* indexed by sender ll address */
+
+};
+
+#ifdef _KERNEL
+u_int8_t arcbroadcastaddr;
+
+void arc_ifattach __P((struct ifnet *));
+char *arc_sprintf __P((u_int8_t *));
+void arc_input __P((struct ifnet *, struct mbuf *));
+int arc_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *));
+int arc_isphds __P((int));
+#endif
+
+#endif // _NETINET_IF_ARC_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/if_atm.h b/ecos/packages/net/tcpip/current/include/netinet/if_atm.h
new file mode 100644
index 0000000..9b62458
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/if_atm.h
@@ -0,0 +1,75 @@
+//==========================================================================
+//
+// include/netinet/if_atm.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_atm.h,v 1.3 1996/07/03 17:14:32 chuck Exp $ */
+
+/*
+ *
+ * Copyright (c) 1996 Charles D. Cranor and Washington University.
+ * All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Charles D. Cranor and
+ * Washington University.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _NETINET_IF_ATM_H_
+#define _NETINET_IF_ATM_H_
+
+/*
+ * if_atm.h
+ */
+
+void atm_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+int atmresolve __P((struct rtentry *, struct mbuf *, struct sockaddr *,
+ struct atm_pseudohdr *));
+
+#endif // _NETINET_IF_ATM_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/if_ether.h b/ecos/packages/net/tcpip/current/include/netinet/if_ether.h
new file mode 100644
index 0000000..9b70fb9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/if_ether.h
@@ -0,0 +1,314 @@
+//==========================================================================
+//
+// include/netinet/if_ether.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_ether.h,v 1.10 1999/12/08 06:50:19 itojun Exp $ */
+/* $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_ether.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IF_ETHER_H_
+#define _NETINET_IF_ETHER_H_
+
+/*
+ * Ethernet address - 6 octets
+ * this is only used by the ethers(3) functions.
+ */
+struct ether_addr {
+ u_int8_t ether_addr_octet[6];
+} __attribute__ ((aligned(1), packed));
+
+/*
+ * Structure of a Ethernet header.
+ */
+#define ETHER_ADDR_LEN 6
+
+struct ether_header {
+ u_int8_t ether_dhost[ETHER_ADDR_LEN];
+ u_int8_t ether_shost[ETHER_ADDR_LEN];
+ u_int16_t ether_type;
+} __attribute__ ((aligned(1), packed));
+
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_ARP 0x0806 /* address resolution protocol */
+#define ETHERTYPE_REVARP 0x8035 /* reverse addr resolution protocol */
+#define ETHERTYPE_IPV6 0x86DD /* IPv6 protocol */
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+#define ETHERMTU 1500
+#define ETHERMIN (60-14)
+
+#ifdef _KERNEL
+/*
+ * Macro to map an IP multicast address to an Ethernet multicast address.
+ * The high-order 25 bits of the Ethernet address are statically assigned,
+ * and the low-order 23 bits are taken from the low end of the IP address.
+ */
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ /* struct in_addr *ipaddr; */ \
+ /* u_int8_t enaddr[ETHER_ADDR_LEN]; */ \
+{ \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((u_int8_t *)ipaddr)[2]; \
+ (enaddr)[5] = ((u_int8_t *)ipaddr)[3]; \
+}
+
+/*
+ * Macro to map an IPv6 multicast address to an Ethernet multicast address.
+ * The high-order 16 bits of the Ethernet address are statically assigned,
+ * and the low-order 32 bits are taken from the low end of the IPv6 address.
+ */
+#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \
+ /* struct in6_addr *ip6addr; */ \
+ /* u_int8_t enaddr[ETHER_ADDR_LEN]; */ \
+{ \
+ (enaddr)[0] = 0x33; \
+ (enaddr)[1] = 0x33; \
+ (enaddr)[2] = ((u_int8_t *)ip6addr)[12]; \
+ (enaddr)[3] = ((u_int8_t *)ip6addr)[13]; \
+ (enaddr)[4] = ((u_int8_t *)ip6addr)[14]; \
+ (enaddr)[5] = ((u_int8_t *)ip6addr)[15]; \
+}
+#endif
+
+/*
+ * Ethernet Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. Structure below is adapted
+ * to resolving internet addresses. Field names used correspond to
+ * RFC 826.
+ */
+struct ether_arp {
+ struct arphdr ea_hdr; /* fixed-size header */
+ u_int8_t arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
+ u_int8_t arp_spa[4]; /* sender protocol address */
+ u_int8_t arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
+ u_int8_t arp_tpa[4]; /* target protocol address */
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+/*
+ * Structure shared between the ethernet driver modules and
+ * the address resolution code. For example, each ec_softc or il_softc
+ * begins with this structure.
+ */
+struct arpcom {
+ struct ifnet ac_if; /* network-visible interface */
+ u_int8_t ac_enaddr[ETHER_ADDR_LEN]; /* ethernet hardware address */
+ char ac__pad[2]; /* pad for some machines */
+ LIST_HEAD(, ether_multi) ac_multiaddrs; /* list of ether multicast addrs */
+ int ac_multicnt; /* length of ac_multiaddrs list */
+};
+
+struct llinfo_arp {
+ LIST_ENTRY(llinfo_arp) la_list;
+ struct rtentry *la_rt;
+ struct mbuf *la_hold; /* last packet until resolved/timeout */
+ long la_asked; /* last time we QUERIED for this addr */
+#define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */
+};
+
+struct sockaddr_inarp {
+ u_int8_t sin_len;
+ u_int8_t sin_family;
+ u_int16_t sin_port;
+ struct in_addr sin_addr;
+ struct in_addr sin_srcaddr;
+ u_int16_t sin_tos;
+ u_int16_t sin_other;
+#define SIN_PROXY 1
+};
+
+/*
+ * IP and ethernet specific routing flags
+ */
+#define RTF_USETRAILERS RTF_PROTO1 /* use trailers */
+#define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */
+#define RTF_PERMANENT_ARP RTF_PROTO3 /* only manual overwrite of entry */
+
+#ifdef _KERNEL
+extern u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN];
+extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
+extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
+extern struct ifqueue arpintrq;
+
+void arpwhohas __P((struct arpcom *, struct in_addr *));
+void arpintr __P((void));
+int arpresolve __P((struct arpcom *,
+ struct rtentry *, struct mbuf *, struct sockaddr *, u_char *));
+void arp_ifinit __P((struct arpcom *, struct ifaddr *));
+void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+
+int ether_addmulti __P((struct ifreq *, struct arpcom *));
+int ether_delmulti __P((struct ifreq *, struct arpcom *));
+#endif /* _KERNEL */
+
+/*
+ * Ethernet multicast address structure. There is one of these for each
+ * multicast address or range of multicast addresses that we are supposed
+ * to listen to on a particular interface. They are kept in a linked list,
+ * rooted in the interface's arpcom structure. (This really has nothing to
+ * do with ARP, or with the Internet address family, but this appears to be
+ * the minimally-disrupting place to put it.)
+ */
+struct ether_multi {
+ u_int8_t enm_addrlo[ETHER_ADDR_LEN]; /* low or only address of range */
+ u_int8_t enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */
+ struct arpcom *enm_ac; /* back pointer to arpcom */
+ u_int enm_refcount; /* no. claims to this addr/range */
+ LIST_ENTRY(ether_multi) enm_list;
+};
+
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of the ether_multi records.
+ */
+struct ether_multistep {
+ struct ether_multi *e_enm;
+};
+
+/*
+ * Macro for looking up the ether_multi record for a given range of Ethernet
+ * multicast addresses connected to a given arpcom structure. If no matching
+ * record is found, "enm" returns NULL.
+ */
+#define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \
+ /* u_int8_t addrlo[ETHER_ADDR_LEN]; */ \
+ /* u_int8_t addrhi[ETHER_ADDR_LEN]; */ \
+ /* struct arpcom *ac; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ for ((enm) = (ac)->ac_multiaddrs.lh_first; \
+ (enm) != NULL && \
+ (bcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 || \
+ bcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0); \
+ (enm) = (enm)->enm_list.le_next); \
+}
+
+/*
+ * Macro to step through all of the ether_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. ETHER_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "enm" when there
+ * are no remaining records.
+ */
+#define ETHER_NEXT_MULTI(step, enm) \
+ /* struct ether_multistep step; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ if (((enm) = (step).e_enm) != NULL) \
+ (step).e_enm = (enm)->enm_list.le_next; \
+}
+
+#define ETHER_FIRST_MULTI(step, ac, enm) \
+ /* struct ether_multistep step; */ \
+ /* struct arpcom *ac; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ (step).e_enm = (ac)->ac_multiaddrs.lh_first; \
+ ETHER_NEXT_MULTI((step), (enm)); \
+}
+
+#ifdef _KERNEL
+
+extern struct ifnet *myip_ifp;
+
+void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+int arpresolve __P((struct arpcom *, struct rtentry *, struct mbuf *,
+ struct sockaddr *, u_char *));
+void arpintr __P((void));
+int arpioctl __P((u_long, caddr_t));
+void arp_ifinit __P((struct arpcom *, struct ifaddr *));
+void revarpinput __P((struct mbuf *));
+void in_revarpinput __P((struct mbuf *));
+void revarprequest __P((struct ifnet *));
+int revarpwhoarewe __P((struct ifnet *, struct in_addr *, struct in_addr *));
+int revarpwhoami __P((struct in_addr *, struct ifnet *));
+int db_show_arptab __P((void));
+
+#else
+
+char *ether_ntoa __P((struct ether_addr *));
+struct ether_addr *ether_aton __P((char *));
+int ether_ntohost __P((char *, struct ether_addr *));
+int ether_hostton __P((char *, struct ether_addr *));
+int ether_line __P((char *, struct ether_addr *, char *));
+
+#endif // _KERNEL
+
+#endif // _NETINET_IF_ETHER_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/igmp.h b/ecos/packages/net/tcpip/current/include/netinet/igmp.h
new file mode 100644
index 0000000..4220ce2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/igmp.h
@@ -0,0 +1,131 @@
+//==========================================================================
+//
+// include/netinet/igmp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: igmp.h,v 1.3 1999/08/08 00:43:00 niklas Exp $ */
+/* $NetBSD: igmp.h,v 1.6 1995/05/31 06:08:21 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988 Stephen Deering.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)igmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IGMP_H_
+#define _NETINET_IGMP_H_
+
+/*
+ * Internet Group Management Protocol (IGMP) definitions.
+ *
+ * MULTICAST 1.3
+ */
+
+/*
+ * IGMP packet format.
+ */
+struct igmp {
+ u_int8_t igmp_type; /* version & type of IGMP message */
+ u_int8_t igmp_code; /* code for routing sub-messages */
+ u_int16_t igmp_cksum; /* IP-style checksum */
+ struct in_addr igmp_group; /* group address being reported */
+}; /* (zero for queries) */
+
+#define IGMP_MINLEN 8
+
+#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* membership query */
+#define IGMP_v1_HOST_MEMBERSHIP_REPORT 0x12 /* v1 membership report */
+#define IGMP_DVMRP 0x13 /* DVMRP routing message */
+#define IGMP_PIM 0x14 /* PIM routing message */
+#define IGMP_v2_HOST_MEMBERSHIP_REPORT 0x16 /* v2 membership report */
+#define IGMP_HOST_LEAVE_MESSAGE 0x17 /* leave-group message */
+#define IGMP_MTRACE_REPLY 0x1e /* traceroute reply */
+#define IGMP_MTRACE_QUERY 0x1f /* traceroute query */
+
+#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */
+ /* query (in seconds) */
+
+#define IGMP_TIMER_SCALE 10 /* denominator for igmp_timer */
+
+/*
+ * States for the IGMP v2 state table.
+ */
+#define IGMP_DELAYING_MEMBER 1
+#define IGMP_IDLE_MEMBER 2
+#define IGMP_LAZY_MEMBER 3
+#define IGMP_SLEEPING_MEMBER 4
+#define IGMP_AWAKENING_MEMBER 5
+
+/*
+ * States for IGMP router version cache.
+ */
+#define IGMP_v1_ROUTER 1
+#define IGMP_v2_ROUTER 2
+
+/*
+ * Revert to v2 if we haven't heard from the router in this amount of time.
+ */
+#define IGMP_AGE_THRESHOLD 540
+
+#ifdef _KERNEL
+void rti_delete __P((struct ifnet *));
+#endif
+
+#endif // _NETINET_IGMP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/igmp_var.h b/ecos/packages/net/tcpip/current/include/netinet/igmp_var.h
new file mode 100644
index 0000000..3a1820d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/igmp_var.h
@@ -0,0 +1,116 @@
+//==========================================================================
+//
+// include/netinet/igmp_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: igmp_var.h,v 1.3 1997/02/05 15:48:22 deraadt Exp $ */
+/* $NetBSD: igmp_var.h,v 1.9 1996/02/13 23:41:31 christos Exp $ */
+
+/*
+ * Copyright (c) 1988 Stephen Deering.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)igmp_var.h 8.1 (Berkeley) 7/19/93
+ */
+
+#ifndef _NETINET_IGMP_VAR_H_
+#define _NETINET_IGMP_VAR_H_
+
+/*
+ * Internet Group Management Protocol (IGMP),
+ * implementation-specific definitions.
+ *
+ * Written by Steve Deering, Stanford, May 1988.
+ * Modified by Rosen Sharma, Stanford, Aug 1994.
+ * Modified by Bill Fenner, Xerox PARC, Feb 1995.
+ *
+ * MULTICAST 1.3
+ */
+
+struct igmpstat {
+ u_long igps_rcv_total; /* total IGMP messages received */
+ u_long igps_rcv_tooshort; /* received with too few bytes */
+ u_long igps_rcv_badsum; /* received with bad checksum */
+ u_long igps_rcv_queries; /* received membership queries */
+ u_long igps_rcv_badqueries; /* received invalid queries */
+ u_long igps_rcv_reports; /* received membership reports */
+ u_long igps_rcv_badreports; /* received invalid reports */
+ u_long igps_rcv_ourreports; /* received reports for our groups */
+ u_long igps_snd_reports; /* sent membership reports */
+};
+
+#ifdef _KERNEL
+struct igmpstat igmpstat;
+
+/*
+ * Macro to compute a random timer value between 1 and (IGMP_MAX_REPORTING_
+ * DELAY * countdown frequency). We assume that the routine random()
+ * is defined somewhere (and that it returns a positive number).
+ */
+#define IGMP_RANDOM_DELAY(X) (arc4random() % (X) + 1)
+
+void igmp_init __P((void));
+void igmp_input __P((struct mbuf *, ...));
+void igmp_joingroup __P((struct in_multi *));
+void igmp_leavegroup __P((struct in_multi *));
+void igmp_fasttimo __P((void));
+void igmp_slowtimo __P((void));
+#endif
+
+#endif // _NETINET_IGMP_VAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/in.h b/ecos/packages/net/tcpip/current/include/netinet/in.h
new file mode 100644
index 0000000..128149b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/in.h
@@ -0,0 +1,680 @@
+//==========================================================================
+//
+// include/netinet/in.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in.h,v 1.27 1999/12/16 21:30:34 deraadt Exp $ */
+/* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in.h 8.3 (Berkeley) 1/3/94
+ */
+
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981, and numerous additions.
+ */
+
+#ifndef _NETINET_IN_H_
+#define _NETINET_IN_H_
+
+/*
+ * Protocols
+ */
+#define IPPROTO_IP 0 /* dummy for IP */
+#define IPPROTO_HOPOPTS IPPROTO_IP /* Hop-by-hop option header. */
+#define IPPROTO_ICMP 1 /* control message protocol */
+#define IPPROTO_IGMP 2 /* group mgmt protocol */
+#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
+#define IPPROTO_IPIP 4 /* IP inside IP */
+#define IPPROTO_IPV4 IPPROTO_IPIP /* IP inside IP */
+#define IPPROTO_TCP 6 /* tcp */
+#define IPPROTO_EGP 8 /* exterior gateway protocol */
+#define IPPROTO_PUP 12 /* pup */
+#define IPPROTO_UDP 17 /* user datagram protocol */
+#define IPPROTO_IDP 22 /* xns idp */
+#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */
+#define IPPROTO_IPV6 41 /* IPv6 in IPv6 */
+#define IPPROTO_ROUTING 43 /* Routing header. */
+#define IPPROTO_FRAGMENT 44 /* Fragmentation/reassembly header. */
+#define IPPROTO_RSVP 46 /* resource reservation */
+#define IPPROTO_ESP 50 /* Encap. Security Payload */
+#define IPPROTO_AH 51 /* Authentication header */
+#define IPPROTO_ICMPV6 58 /* ICMP for IPv6 */
+#define IPPROTO_NONE 59 /* No next header */
+#define IPPROTO_DSTOPTS 60 /* Destination options header. */
+#define IPPROTO_EON 80 /* ISO cnlp */
+#define IPPROTO_ETHERIP 97 /* Ethernet in IPv4 */
+#define IPPROTO_ENCAP 98 /* encapsulation header */
+#define IPPROTO_PIM 103 /* Protocol indep. multicast */
+#define IPPROTO_IPCOMP 108 /* IP Payload Comp. Protocol */
+#define IPPROTO_RAW 255 /* raw IP packet */
+
+#define IPPROTO_MAX 256
+
+/*
+ * From FreeBSD:
+ *
+ * Local port number conventions:
+ *
+ * When a user does a bind(2) or connect(2) with a port number of zero,
+ * a non-conflicting local port address is chosen.
+ * The default range is IPPORT_RESERVED through
+ * IPPORT_USERRESERVED, although that is settable by sysctl.
+ *
+ * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
+ * default assignment range.
+ *
+ * The value IP_PORTRANGE_DEFAULT causes the default behavior.
+ *
+ * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers
+ * into the "high" range. These are reserved for client outbound connections
+ * which do not want to be filtered by any firewalls.
+ *
+ * The value IP_PORTRANGE_LOW changes the range to the "low" are
+ * that is (by convention) restricted to privileged processes. This
+ * convention is based on "vouchsafe" principles only. It is only secure
+ * if you trust the remote host to restrict these ports.
+ *
+ * The default range of ports and the high range can be changed by
+ * sysctl(3). (net.inet.ip.port{hi}{first,last})
+ *
+ * Changing those values has bad security implications if you are
+ * using a a stateless firewall that is allowing packets outside of that
+ * range in order to allow transparent outgoing connections.
+ *
+ * Such a firewall configuration will generally depend on the use of these
+ * default values. If you change them, you may find your Security
+ * Administrator looking for you with a heavy object.
+ */
+
+/*
+ * Ports < IPPORT_RESERVED are reserved for
+ * privileged processes (e.g. root).
+ * Ports > IPPORT_USERRESERVED are reserved
+ * for servers, not necessarily privileged.
+ */
+#define IPPORT_RESERVED 1024
+#define IPPORT_USERRESERVED 49151
+
+/*
+ * Default local port range to use by setting IP_PORTRANGE_HIGH
+ */
+#define IPPORT_HIFIRSTAUTO 49152
+#define IPPORT_HILASTAUTO 65535
+
+/*
+ * IP Version 4 Internet address (a structure for historical reasons)
+ */
+struct in_addr {
+ in_addr_t s_addr;
+};
+
+#if 0 /*NRL IPv6*/
+/*
+ * IP Version 6 Internet address
+ */
+struct in6_addr {
+ union {
+ u_int8_t s6u_addr8[16];
+ u_int16_t s6u_addr16[8];
+ u_int32_t s6u_addr32[4];
+ } s6_u;
+#define s6_addr s6_u.s6u_addr8
+/*
+ * The rest are common, but not guaranteed to be portable. 64 bit access are
+ * not available because the in6_addr in a sockaddr_in6 is not 64 bit aligned.
+ */
+#define s6_addr8 s6_u.s6u_addr8
+#define s6_addr16 s6_u.s6u_addr16
+#define s6_addr32 s6_u.s6u_addr32
+};
+#endif
+
+/* last return value of *_input(), meaning "all job for this pkt is done". */
+#define IPPROTO_DONE 257
+
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ *
+ * By byte-swapping the constants, we avoid ever having to byte-swap IP
+ * addresses inside the kernel. Unfortunately, user-level programs rely
+ * on these macros not doing byte-swapping.
+ */
+#ifdef _KERNEL
+#define __IPADDR(x) ((u_int32_t) htonl((u_int32_t)(x)))
+#else
+#define __IPADDR(x) ((u_int32_t)(x))
+#endif
+
+#define IN_CLASSA(i) (((u_int32_t)(i) & __IPADDR(0x80000000)) == \
+ __IPADDR(0x00000000))
+#define IN_CLASSA_NET __IPADDR(0xff000000)
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST __IPADDR(0x00ffffff)
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(i) (((u_int32_t)(i) & __IPADDR(0xc0000000)) == \
+ __IPADDR(0x80000000))
+#define IN_CLASSB_NET __IPADDR(0xffff0000)
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST __IPADDR(0x0000ffff)
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((u_int32_t)(i) & __IPADDR(0xe0000000)) == \
+ __IPADDR(0xc0000000))
+#define IN_CLASSC_NET __IPADDR(0xffffff00)
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST __IPADDR(0x000000ff)
+
+#define IN_CLASSD(i) (((u_int32_t)(i) & __IPADDR(0xf0000000)) == \
+ __IPADDR(0xe0000000))
+/* These ones aren't really net and host fields, but routing needn't know. */
+#define IN_CLASSD_NET __IPADDR(0xf0000000)
+#define IN_CLASSD_NSHIFT 28
+#define IN_CLASSD_HOST __IPADDR(0x0fffffff)
+#define IN_MULTICAST(i) IN_CLASSD(i)
+
+#define IN_EXPERIMENTAL(i) (((u_int32_t)(i) & __IPADDR(0xf0000000)) == \
+ __IPADDR(0xf0000000))
+#define IN_BADCLASS(i) (((u_int32_t)(i) & __IPADDR(0xf0000000)) == \
+ __IPADDR(0xf0000000))
+
+#define IN_LOCAL_GROUP(i) (((u_int32_t)(i) & __IPADDR(0xffffff00)) == \
+ __IPADDR(0xe0000000))
+
+#define INADDR_ANY __IPADDR(0x00000000)
+#define INADDR_LOOPBACK __IPADDR(0x7f000001)
+#define INADDR_BROADCAST __IPADDR(0xffffffff) /* must be masked */
+#ifndef _KERNEL
+#define INADDR_NONE __IPADDR(0xffffffff) /* -1 return */
+#endif
+
+#define INADDR_UNSPEC_GROUP __IPADDR(0xe0000000) /* 224.0.0.0 */
+#define INADDR_ALLHOSTS_GROUP __IPADDR(0xe0000001) /* 224.0.0.1 */
+#define INADDR_MAX_LOCAL_GROUP __IPADDR(0xe00000ff) /* 224.0.0.255 */
+
+#define IN_LOOPBACKNET 127 /* official! */
+
+#if 0 /*NRL IPv6*/
+/*
+ * Tests for IPv6 address types
+ */
+
+#define IN6_IS_ADDR_LINKLOCAL(addr) \
+ (((addr)->s6_addr32[0] & htonl(0xffc00000)) == htonl(0xfe800000))
+
+#define IN6_IS_ADDR_LOOPBACK(addr) \
+ (((addr)->s6_addr32[0] == 0) && ((addr)->s6_addr32[1] == 0) && \
+ ((addr)->s6_addr32[2] == 0) && ((addr)->s6_addr32[3] == htonl(1)))
+
+#define IN6_IS_ADDR_MULTICAST(addr) \
+ ((addr)->s6_addr8[0] == 0xff)
+
+#define IN6_IS_ADDR_SITELOCAL(addr) \
+ (((addr)->s6_addr32[0] & htonl(0xffc00000)) == htonl(0xfec00000))
+
+#define IN6_IS_ADDR_UNSPECIFIED(addr) \
+ (((addr)->s6_addr32[0] == 0) && ((addr)->s6_addr32[1] == 0) && \
+ ((addr)->s6_addr32[2] == 0) && ((addr)->s6_addr32[3] == 0))
+
+#define IN6_IS_ADDR_V4COMPAT(addr) \
+ (((addr)->s6_addr32[0] == 0) && ((addr)->s6_addr32[1] == 0) && \
+ ((addr)->s6_addr32[2] == 0) && ((addr)->s6_addr32[3] & ~htonl(1)))
+
+#define IN6_IS_ADDR_V4MAPPED(addr) \
+ (((addr)->s6_addr32[0] == 0) && ((addr)->s6_addr32[1] == 0) && \
+ ((addr)->s6_addr32[2] == htonl(0xffff)))
+
+#define IN6_ARE_ADDR_EQUAL(addr1, addr2) \
+ (((addr1)->s6_addr32[0] == (addr2)->s6_addr32[0]) && \
+ ((addr1)->s6_addr32[1] == (addr2)->s6_addr32[1]) && \
+ ((addr1)->s6_addr32[2] == (addr2)->s6_addr32[2]) && \
+ ((addr1)->s6_addr32[3] == (addr2)->s6_addr32[3]))
+
+/*
+ * IPv6 Multicast scoping. The scope is stored
+ * in the bottom 4 bits of the second byte of the
+ * multicast address.
+ */
+ /* 0x0 */ /* reserved */
+#define IN6_NODE_LOCAL 0x1 /* node-local scope */
+#define IN6_LINK_LOCAL 0x2 /* link-local scope */
+ /* 0x3 */ /* (unassigned) */
+ /* 0x4 */ /* (unassigned) */
+#define IN6_SITE_LOCAL 0x5 /* site-local scope */
+ /* 0x6 */ /* (unassigned) */
+ /* 0x7 */ /* (unassigned) */
+#define IN6_ORG_LOCAL 0x8 /* organization-local scope */
+ /* 0x9 */ /* (unassigned) */
+ /* 0xA */ /* (unassigned) */
+ /* 0xB */ /* (unassigned) */
+ /* 0xC */ /* (unassigned) */
+ /* 0xD */ /* (unassigned) */
+#define IN6_GLOBAL 0xE /* global scope */
+ /* 0xF */ /* reserved */
+
+#define IN6_MSCOPE(addr) ((addr)->s6_addr8[1] & 0x0f)
+
+#define IN6_IS_ADDR_MC_NODELOCAL(addr) \
+ (IN6_IS_ADDR_MULTICAST(addr) && (IN6_MSCOPE(addr) == IN6_NODE_LOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(addr) \
+ (IN6_IS_ADDR_MULTICAST(addr) && (IN6_MSCOPE(addr) == IN6_LINK_LOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(addr) \
+ (IN6_IS_ADDR_MULTICAST(addr) && (IN6_MSCOPE(addr) == IN6_SITE_LOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(addr) \
+ (IN6_IS_ADDR_MULTICAST(addr) && (IN6_MSCOPE(addr) == IN6_ORG_LOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(addr) \
+ (IN6_IS_ADDR_MULTICAST(addr) && (IN6_MSCOPE(addr) == IN6_GLOBAL))
+
+/*
+ * Definitions of the IPv6 special addresses
+ */
+extern const struct in6_addr in6addr_any;
+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
+
+extern const struct in6_addr in6addr_loopback;
+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
+#endif
+
+/*
+ * IP Version 4 socket address.
+ */
+struct sockaddr_in {
+ u_int8_t sin_len;
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ int8_t sin_zero[8];
+};
+
+#if 0 /*NRL IPv6*/
+/*
+ * IP Version 6 socket address.
+ */
+#define SIN6_LEN 1
+struct sockaddr_in6 {
+ u_int8_t sin6_len;
+ sa_family_t sin6_family;
+ in_port_t sin6_port;
+ u_int32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ u_int32_t sin6_scope_id;
+};
+#endif
+
+#define INET_ADDRSTRLEN 16
+
+/*
+ * Structure used to describe IP options.
+ * Used to store options internally, to pass them to a process,
+ * or to restore options retrieved earlier.
+ * The ip_dst is used for the first-hop gateway when using a source route
+ * (this gets put into the header proper).
+ */
+struct ip_opts {
+ struct in_addr ip_dst; /* first hop, 0 w/o src rt */
+#if defined(__cplusplus)
+ int8_t Ip_opts[40]; /* cannot have same name as class */
+#else
+ int8_t ip_opts[40]; /* actually variable in size */
+#endif
+};
+
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ * First word of comment is data type; bool is stored in int.
+ */
+#define IP_OPTIONS 1 /* buf/ip_opts; set/get IP options */
+#define IP_HDRINCL 2 /* int; header is included with data */
+#define IP_TOS 3 /* int; IP type of service and preced. */
+#define IP_TTL 4 /* int; IP time to live */
+#define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */
+#define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */
+#define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */
+#define IP_RETOPTS 8 /* ip_opts; set/get IP options */
+#define IP_MULTICAST_IF 9 /* in_addr; set/get IP multicast i/f */
+#define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */
+#define IP_MULTICAST_LOOP 11 /* u_char; set/get IP multicast loopback */
+#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */
+#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */
+
+/* 14-17 left empty for future compatibility with FreeBSD */
+
+#define IP_PORTRANGE 19 /* int; range to choose for unspec port */
+#define IP_AUTH_LEVEL 20 /* u_char; authentication used */
+#define IP_ESP_TRANS_LEVEL 21 /* u_char; transport encryption */
+#define IP_ESP_NETWORK_LEVEL 22 /* u_char; full-packet encryption */
+
+#if 0 /* NRL IPv6 */
+#define IPV6_MULTICAST_IF 23 /* u_int; set/get multicast interface */
+#define IPV6_MULTICAST_HOPS 24 /* int; set/get multicast hop limit */
+#define IPV6_MULTICAST_LOOP 25 /* u_int; set/get multicast loopback */
+#define IPV6_JOIN_GROUP 26 /* ipv6_mreq; join multicast group */
+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP /* XXX - for compatibility */
+#define IPV6_LEAVE_GROUP 27 /* ipv6_mreq: leave multicast group */
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP /* XXX - for compatibility */
+#define IPV6_ADDRFORM 28 /* int; get/set form of returned addrs */
+#define IPV6_UNICAST_HOPS 29 /* int; get/set unicast hop limit */
+#define IPV6_PKTINFO 30 /* int; receive in6_pktinfo as cmsg */
+#define IPV6_HOPLIMIT 31 /* int; receive int hoplimit as cmsg */
+#define IPV6_NEXTHOP 32 /* int; receive sockaddr_in6 as cmsg */
+#define IPV6_HOPOPTS 33 /* int; receive hop options as cmsg */
+#define IPV6_DSTOPTS 34 /* int; receive dst options as cmsg */
+#define IPV6_RTHDR 35 /* int; receive routing header as cmsg */
+#define IPV6_PKTOPTIONS 36 /* int; send/receive cmsgs for TCP */
+#define IPV6_CHECKSUM 37 /* int; offset to place send checksum */
+#define ICMPV6_FILTER 38 /* struct icmpv6_filter; get/set filter */
+#define ICMP6_FILTER ICMP6_FILTER
+#endif
+
+#define IPSEC_OUTSA 39 /* set the outbound SA for a socket */
+
+#if 0 /*KAME IPSEC*/
+#define IP_IPSEC_POLICY ?? /* struct; get/set security policy */
+#endif
+
+/*
+ * Security levels - IPsec, not IPSO
+ */
+
+#define IPSEC_LEVEL_BYPASS 0x00 /* Bypass policy altogether */
+#define IPSEC_LEVEL_NONE 0x00 /* Send clear, accept any */
+#define IPSEC_LEVEL_AVAIL 0x01 /* Send secure if SA available */
+#define IPSEC_LEVEL_USE 0x02 /* Send secure, accept any */
+#define IPSEC_LEVEL_REQUIRE 0x03 /* Require secure inbound, also use */
+#define IPSEC_LEVEL_UNIQUE 0x04 /* Use outbound SA that is unique */
+#define IPSEC_LEVEL_DEFAULT IPSEC_LEVEL_AVAIL
+
+#define IPSEC_AUTH_LEVEL_DEFAULT IPSEC_LEVEL_DEFAULT
+#define IPSEC_ESP_TRANS_LEVEL_DEFAULT IPSEC_LEVEL_DEFAULT
+#define IPSEC_ESP_NETWORK_LEVEL_DEFAULT IPSEC_LEVEL_DEFAULT
+
+#if 0 /* NRL IPv6 */
+/*
+ * IPv6 Routing header types
+ */
+#define IPV6_RTHDR_TYPE_0 0 /* IPv6 Routing header type 0 */
+
+#define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor */
+#define IPV6_RTHDR_STRICT 1 /* this hop must be a neighbor */
+#endif
+
+/*
+ * Defaults and limits for options
+ */
+#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */
+#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
+#define IP_MAX_MEMBERSHIPS 20 /* per socket; must fit in one mbuf */
+
+/*
+ * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
+ */
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+
+#if 0 /* NRL IPv6 */
+/*
+ * Argument structure for IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMBERSHIP.
+ */
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */
+ unsigned int ipv6mr_interface; /* Interface index */
+};
+
+/*
+ * Argument structure for IPV6_PKTINFO control messages
+ */
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ unsigned int ipi6_ifindex;
+};
+#endif
+
+/*
+ * Argument for IP_PORTRANGE:
+ * - which range to search when port is unspecified at bind() or connect()
+ */
+#define IP_PORTRANGE_DEFAULT 0 /* default range */
+#define IP_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */
+#define IP_PORTRANGE_LOW 2 /* "low" - vouchsafe security */
+
+/*
+ * Buffer lengths for strings containing printable IP addresses
+ */
+#define INET_ADDRSTRLEN 16
+#if 0 /* NRL IPv6 */
+#define INET6_ADDRSTRLEN 46
+#endif
+
+/*
+ * Definitions for inet sysctl operations.
+ *
+ * Third level is protocol number.
+ * Fourth level is desired variable within that protocol.
+ */
+#define IPPROTO_MAXID (IPPROTO_AH + 1) /* don't list to IPPROTO_MAX */
+
+#define CTL_IPPROTO_NAMES { \
+ { "ip", CTLTYPE_NODE }, \
+ { "icmp", CTLTYPE_NODE }, \
+ { "igmp", CTLTYPE_NODE }, \
+ { "ggp", CTLTYPE_NODE }, \
+ { "ip4", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { "tcp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { "egp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "pup", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "udp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "esp", CTLTYPE_NODE }, \
+ { "ah", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "etherip", CTLTYPE_NODE }, \
+}
+
+/*
+ * Names for IP sysctl objects
+ */
+#define IPCTL_FORWARDING 1 /* act as router */
+#define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */
+#define IPCTL_DEFTTL 3 /* default TTL */
+#ifdef notyet
+#define IPCTL_DEFMTU 4 /* default MTU */
+#endif
+#define IPCTL_SOURCEROUTE 5 /* may perform source routes */
+#define IPCTL_DIRECTEDBCAST 6 /* default broadcast behavior */
+#define IPCTL_IPPORT_FIRSTAUTO 7
+#define IPCTL_IPPORT_LASTAUTO 8
+#define IPCTL_IPPORT_HIFIRSTAUTO 9
+#define IPCTL_IPPORT_HILASTAUTO 10
+#define IPCTL_IPPORT_MAXQUEUE 11
+#define IPCTL_ENCDEBUG 12
+#define IPCTL_GIF_TTL 13 /* default TTL for gif encap packet */
+#define IPCTL_MAXID 14
+
+#define IPCTL_NAMES { \
+ { 0, 0 }, \
+ { "forwarding", CTLTYPE_INT }, \
+ { "redirect", CTLTYPE_INT }, \
+ { "ttl", CTLTYPE_INT }, \
+ /* { "mtu", CTLTYPE_INT }, */ { 0, 0 }, \
+ { "sourceroute", CTLTYPE_INT }, \
+ { "directed-broadcast", CTLTYPE_INT }, \
+ { "portfirst", CTLTYPE_INT }, \
+ { "portlast", CTLTYPE_INT }, \
+ { "porthifirst", CTLTYPE_INT }, \
+ { "porthilast", CTLTYPE_INT }, \
+ { "maxqueue", CTLTYPE_INT }, \
+ { "encdebug", CTLTYPE_INT }, \
+ { "gifttl", CTLTYPE_INT }, \
+}
+
+/* INET6 stuff */
+#include <netinet6/in6.h>
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int bindresvport __P((int, struct sockaddr_in *));
+int bindresvport_af __P((int, struct sockaddr *, int af));
+__END_DECLS
+
+#else
+int in_broadcast __P((struct in_addr, struct ifnet *));
+int in_canforward __P((struct in_addr));
+int in_cksum __P((struct mbuf *, int));
+int in_localaddr __P((struct in_addr));
+void in_socktrim __P((struct sockaddr_in *));
+char *inet_ntoa __P((struct in_addr));
+char *inet_ntoa_r __P((struct in_addr, char *));
+
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+#define sintosa(sin) ((struct sockaddr *)(sin))
+#define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
+#endif
+#endif /* !_NETINET_IN_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/in_gif.h b/ecos/packages/net/tcpip/current/include/netinet/in_gif.h
new file mode 100644
index 0000000..a8e5e2f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/in_gif.h
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// include/netinet/in_gif.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_gif.h,v 1.1 1999/12/08 06:50:19 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET_IN_GIF_H_
+#define _NETINET_IN_GIF_H_
+
+#define GIF_TTL 30
+
+extern int ip_gif_ttl;
+
+void in_gif_input __P((struct mbuf *, ...));
+int in_gif_output __P((struct ifnet *, int, struct mbuf *, struct rtentry *));
+
+#endif /*_NETINET_IN_GIF_H_*/
diff --git a/ecos/packages/net/tcpip/current/include/netinet/in_pcb.h b/ecos/packages/net/tcpip/current/include/netinet/in_pcb.h
new file mode 100644
index 0000000..c65b070
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/in_pcb.h
@@ -0,0 +1,308 @@
+//==========================================================================
+//
+// include/netinet/in_pcb.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_pcb.h,v 1.19 1999/12/12 12:10:43 itojun Exp $ */
+/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_pcb.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IN_PCB_H_
+#define _NETINET_IN_PCB_H_
+
+#include <sys/queue.h>
+#if 0 /*KAME IPSEC*/
+#include <netinet6/ipsec.h>
+#endif
+#include <netinet6/ip6.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/icmp6.h>
+#include <netinet/ip_ipsp.h>
+
+union inpaddru {
+ struct in6_addr iau_addr6;
+ struct {
+ uint8_t pad[12];
+ struct in_addr inaddr; /* easier transition */
+ } iau_a4u;
+};
+
+/*
+ * Common structure pcb for internet protocol implementation.
+ * Here are stored pointers to local and foreign host table
+ * entries, local and foreign socket numbers, and pointers
+ * up (to a socket structure) and down (to a protocol-specific)
+ * control block.
+ */
+struct inpcb {
+ LIST_ENTRY(inpcb) inp_hash;
+ CIRCLEQ_ENTRY(inpcb) inp_queue;
+ struct inpcbtable *inp_table;
+ union inpaddru inp_faddru; /* Foreign address. */
+ union inpaddru inp_laddru; /* Local address. */
+#define inp_faddr inp_faddru.iau_a4u.inaddr
+#define inp_faddr6 inp_faddru.iau_addr6
+#define inp_laddr inp_laddru.iau_a4u.inaddr
+#define inp_laddr6 inp_laddru.iau_addr6
+ u_int16_t inp_fport; /* foreign port */
+ u_int16_t inp_lport; /* local port */
+ struct socket *inp_socket; /* back pointer to socket */
+ caddr_t inp_ppcb; /* pointer to per-protocol pcb */
+ union { /* Route (notice increased size). */
+ struct route ru_route;
+ struct route_in6 ru_route6;
+ } inp_ru;
+#define inp_route inp_ru.ru_route
+#define inp_route6 inp_ru.ru_route6
+ int inp_flags; /* generic IP/datagram flags */
+ union { /* Header prototype. */
+ struct ip hu_ip;
+ struct ip6_hdr hu_ipv6;
+ } inp_hu;
+#define inp_ip inp_hu.hu_ip
+#define inp_ipv6 inp_hu.hu_ipv6
+ struct mbuf *inp_options; /* IP options */
+ struct ip6_pktopts *inp_outputopts6; /* IP6 options for outgoing packets */
+ int inp_hops;
+ union {
+ struct ip_moptions *mou_mo; /* IPv4 multicast options */
+ struct ip6_moptions *mou_mo6; /* IPv6 multicast options */
+ } inp_mou;
+#define inp_moptions inp_mou.mou_mo
+#define inp_moptions6 inp_mou.mou_mo6
+ u_char inp_seclevel[3]; /* Only the first 3 are used for now */
+#define SL_AUTH 0 /* Authentication level */
+#define SL_ESP_TRANS 1 /* ESP transport level */
+#define SL_ESP_NETWORK 2 /* ESP network (encapsulation) level */
+ u_int8_t inp_secrequire:4, /* Condensed State from above */
+ inp_secresult:4; /* Result from Key Management */
+#define SR_FAILED 1 /* Negotiation failed permanently */
+#define SR_SUCCESS 2 /* SA successfully established */
+#define SR_WAIT 3 /* Waiting for SA */
+ TAILQ_ENTRY(inpcb) inp_tdb_next;
+ struct tdb *inp_tdb; /* If tdb_dst matches our dst, use */
+ int inp_fflowinfo; /* Foreign flowlabel & priority */
+ int inp_csumoffset;
+ struct icmp6_filter *inp_icmp6filt;
+#if 0 /*KAME IPSEC*/
+ struct secpolicy *inp_sp; /* security policy. It may not be
+ * used according to policy selection.
+ */
+#endif
+};
+
+struct inpcbtable {
+ CIRCLEQ_HEAD(, inpcb) inpt_queue;
+ LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl;
+ u_long inpt_hash;
+ u_int16_t inpt_lastport;
+};
+
+/* flags in inp_flags: */
+#define INP_RECVOPTS 0x001 /* receive incoming IP options */
+#define INP_RECVRETOPTS 0x002 /* receive IP options for reply */
+#define INP_RECVDSTADDR 0x004 /* receive IP dst address */
+
+#define INP_RXDSTOPTS INP_RECVOPTS
+#define INP_RXHOPOPTS INP_RECVRETOPTS
+#define INP_RXINFO INP_RECVDSTADDR
+#define INP_RXSRCRT 0x010
+#define INP_HOPLIMIT 0x020
+
+#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR| \
+ INP_RXSRCRT|INP_HOPLIMIT)
+
+#define INP_HDRINCL 0x008 /* user supplies entire IP header */
+#define INP_HIGHPORT 0x010 /* user wants "high" port binding */
+#define INP_LOWPORT 0x020 /* user wants "low" port binding */
+
+/*
+ * These flags' values should be determined by either the transport
+ * protocol at PRU_BIND, PRU_LISTEN, PRU_CONNECT, etc, or by in_pcb*().
+ */
+#define INP_IPV6 0x100 /* sotopf(inp->inp_socket) == PF_INET6 */
+#define INP_IPV6_UNDEC 0x200 /* PCB is PF_INET6, but listens for V4/V6 */
+#define INP_IPV6_MAPPED 0x400 /* PF_INET6 PCB which is connected to
+ * an IPv4 host, or is bound to
+ * an IPv4 address (specified with
+ * the mapped form of v6 addresses) */
+#define INP_IPV6_MCAST 0x800 /* Set if inp_moptions points to ipv6 ones */
+
+#if 1 /*KAME*/
+/* flags in in6p_flags */
+#define IN6P_RECVOPTS INP_RECVOPTS /* receive incoming IP6 options */
+#define IN6P_RECVRETOPTS INP_RECVRETOPTS /* receive IP6 options for reply */
+#define IN6P_RECVDSTADDR INP_RECVDSTADDR /* receive IP6 dst address */
+#define IN6P_HIGHPORT INP_HIGHPORT /* user wants "high" port binding */
+#define IN6P_LOWPORT INP_LOWPORT /* user wants "low" port binding */
+#define IN6P_ANONPORT 0x40 /* port chosen for user */
+#define IN6P_FAITH 0x80 /* accept FAITH'ed connections */
+#define IN6P_PKTINFO 0x010000
+#define IN6P_HOPLIMIT 0x020000
+#define IN6P_NEXTHOP 0x040000
+#define IN6P_HOPOPTS 0x080000
+#define IN6P_DSTOPTS 0x100000
+#define IN6P_RTHDR 0x200000
+#define IN6P_CONTROLOPTS (0x3f0000 | IN6P_RECVOPTS | IN6P_RECVRETOPTS | IN6P_RECVDSTADDR)
+#endif
+
+#define INPLOOKUP_WILDCARD 1
+#define INPLOOKUP_SETLOCAL 2
+#define INPLOOKUP_IPV6 4
+
+#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
+
+/* macros for handling bitmap of ports not to allocate dynamically */
+#define DP_MAPBITS (sizeof(u_int32_t) * NBBY)
+#define DP_MAPSIZE (howmany(IPPORT_RESERVED/2, DP_MAPBITS))
+#define DP_SET(m, p) ((m)[((p) - IPPORT_RESERVED/2) / DP_MAPBITS] |= (1 << ((p) % DP_MAPBITS)))
+#define DP_CLR(m, p) ((m)[((p) - IPPORT_RESERVED/2) / DP_MAPBITS] &= ~(1 << ((p) % DP_MAPBITS)))
+#define DP_ISSET(m, p) ((m)[((p) - IPPORT_RESERVED/2) / DP_MAPBITS] & (1 << ((p) % DP_MAPBITS)))
+
+/* default values for baddynamicports [see ip_init()] */
+#define DEFBADDYNAMICPORTS_TCP { 749, 750, 751, 760, 761, 871, 0 }
+#define DEFBADDYNAMICPORTS_UDP { 750, 751, 0 }
+
+struct baddynamicports {
+ u_int32_t tcp[DP_MAPSIZE];
+ u_int32_t udp[DP_MAPSIZE];
+};
+
+#ifdef _KERNEL
+
+#define sotopf(so) (so->so_proto->pr_domain->dom_family)
+
+void in_losing __P((struct inpcb *));
+int in_pcballoc __P((struct socket *, void *));
+int in_pcbbind __P((void *, struct mbuf *));
+int in_pcbconnect __P((void *, struct mbuf *));
+void in_pcbdetach __P((void *));
+void in_pcbdisconnect __P((void *));
+struct inpcb *
+ in_pcbhashlookup __P((struct inpcbtable *, struct in_addr,
+ u_int, struct in_addr, u_int));
+#ifdef INET6
+struct inpcb *
+ in6_pcbhashlookup __P((struct inpcbtable *, struct in6_addr *,
+ u_int, struct in6_addr *, u_int));
+int in6_pcbbind __P((struct inpcb *, struct mbuf *));
+int in6_pcbconnect __P((struct inpcb *, struct mbuf *));
+int in6_setsockaddr __P((struct inpcb *, struct mbuf *));
+int in6_setpeeraddr __P((struct inpcb *, struct mbuf *));
+#endif /* INET6 */
+void in_pcbinit __P((struct inpcbtable *, int));
+struct inpcb *
+ in_pcblookup __P((struct inpcbtable *, void *, u_int, void *,
+ u_int, int));
+void in_pcbnotify __P((struct inpcbtable *, struct sockaddr *,
+ u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));
+void in_pcbnotifyall __P((struct inpcbtable *, struct sockaddr *,
+ int, void (*)(struct inpcb *, int)));
+void in_pcbrehash __P((struct inpcb *));
+void in_rtchange __P((struct inpcb *, int));
+void in_setpeeraddr __P((struct inpcb *, struct mbuf *));
+void in_setsockaddr __P((struct inpcb *, struct mbuf *));
+int in_baddynamic __P((u_int16_t, u_int16_t));
+extern struct sockaddr_in *in_selectsrc __P((struct sockaddr_in *,
+ struct route *, int, struct ip_moptions *, int *));
+
+/* INET6 stuff */
+int in6_pcbnotify __P((struct inpcbtable *, struct sockaddr *,
+ u_int, struct in6_addr *, u_int, int,
+ void (*)(struct inpcb *, int)));
+struct in6_addr *in6_selectsrc __P((struct sockaddr_in6 *,
+ struct ip6_pktopts *,
+ struct ip6_moptions *,
+ struct route_in6 *,
+ struct in6_addr *, int *));
+int in6_selecthlim __P((struct inpcb *, struct ifnet *));
+#endif
+
+#endif // _NETINET_IN_PCB_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/in_systm.h b/ecos/packages/net/tcpip/current/include/netinet/in_systm.h
new file mode 100644
index 0000000..77cba0a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/in_systm.h
@@ -0,0 +1,93 @@
+//==========================================================================
+//
+// include/netinet/in_systm.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_systm.h,v 1.2 1997/02/24 14:06:35 niklas Exp $ */
+/* $NetBSD: in_systm.h,v 1.8 1995/04/13 06:29:22 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_systm.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IN_SYSTM_H_
+#define _NETINET_IN_SYSTM_H_
+
+/*
+ * Miscellaneous internetwork
+ * definitions for kernel.
+ */
+
+/*
+ * Network types.
+ *
+ * Internally the system keeps counters in the headers with the bytes
+ * swapped so that VAX instructions will work on them. It reverses
+ * the bytes before transmission at each protocol level. The n_ types
+ * represent the types with the bytes in ``high-ender'' order.
+ */
+typedef u_int16_t n_short; /* short as received from the net */
+typedef u_int32_t n_long; /* long as received from the net */
+
+typedef u_int32_t n_time; /* ms since 00:00 GMT, byte rev */
+
+#ifdef _KERNEL
+n_time iptime __P((void));
+#endif
+
+#endif // _NETINET_IN_SYSTM_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/in_var.h b/ecos/packages/net/tcpip/current/include/netinet/in_var.h
new file mode 100644
index 0000000..db2a44e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/in_var.h
@@ -0,0 +1,254 @@
+//==========================================================================
+//
+// include/netinet/in_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_var.h,v 1.3 1999/12/08 06:50:19 itojun Exp $ */
+/* $NetBSD: in_var.h,v 1.16 1996/02/13 23:42:15 christos Exp $ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_var.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IN_VAR_H_
+#define _NETINET_IN_VAR_H_
+
+#include <sys/queue.h>
+
+/*
+ * Interface address, Internet version. One of these structures
+ * is allocated for each interface with an Internet address.
+ * The ifaddr structure contains the protocol-independent part
+ * of the structure and is assumed to be first.
+ */
+struct in_ifaddr {
+ struct ifaddr ia_ifa; /* protocol-independent info */
+#define ia_ifp ia_ifa.ifa_ifp
+#define ia_flags ia_ifa.ifa_flags
+ /* ia_{,sub}net{,mask} in host order */
+ u_int32_t ia_net; /* network number of interface */
+ u_int32_t ia_netmask; /* mask of net part */
+ u_int32_t ia_subnet; /* subnet number, including net */
+ u_int32_t ia_subnetmask; /* mask of subnet part */
+ struct in_addr ia_netbroadcast; /* to recognize net broadcasts */
+ TAILQ_ENTRY(in_ifaddr) ia_list; /* list of internet addresses */
+ struct sockaddr_in ia_addr; /* reserve space for interface name */
+ struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
+#define ia_broadaddr ia_dstaddr
+ struct sockaddr_in ia_sockmask; /* reserve space for general netmask */
+ LIST_HEAD(, in_multi) ia_multiaddrs; /* list of multicast addresses */
+};
+
+struct in_aliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr_in ifra_addr;
+ struct sockaddr_in ifra_dstaddr;
+#define ifra_broadaddr ifra_dstaddr
+ struct sockaddr_in ifra_mask;
+};
+/*
+ * Given a pointer to an in_ifaddr (ifaddr),
+ * return a pointer to the addr as a sockaddr_in.
+ */
+#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr))
+
+
+#ifdef _KERNEL
+TAILQ_HEAD(in_ifaddrhead, in_ifaddr);
+extern struct in_ifaddrhead in_ifaddr;
+extern struct ifqueue ipintrq; /* ip packet input queue */
+extern int inetctlerrmap[];
+void in_socktrim __P((struct sockaddr_in *));
+
+
+/*
+ * Macro for finding the interface (ifnet structure) corresponding to one
+ * of our IP addresses.
+ */
+#define INADDR_TO_IFP(addr, ifp) \
+ /* struct in_addr addr; */ \
+ /* struct ifnet *ifp; */ \
+{ \
+ register struct in_ifaddr *ia; \
+\
+ for (ia = in_ifaddr.tqh_first; \
+ ia != NULL && ia->ia_addr.sin_addr.s_addr != (addr).s_addr; \
+ ia = ia->ia_list.tqe_next) \
+ continue; \
+ (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
+}
+
+/*
+ * Macro for finding the internet address structure (in_ifaddr) corresponding
+ * to a given interface (ifnet structure).
+ */
+#define IFP_TO_IA(ifp, ia) \
+ /* struct ifnet *ifp; */ \
+ /* struct in_ifaddr *ia; */ \
+{ \
+ for ((ia) = in_ifaddr.tqh_first; \
+ (ia) != NULL && (ia)->ia_ifp != (ifp); \
+ (ia) = (ia)->ia_list.tqe_next) \
+ continue; \
+}
+#endif
+
+/*
+ * Per-interface router version information.
+ */
+struct router_info {
+ struct ifnet *rti_ifp;
+ int rti_type; /* type of router on this interface */
+ int rti_age; /* time since last v1 query */
+ struct router_info *rti_next;
+};
+
+/*
+ * Internet multicast address structure. There is one of these for each IP
+ * multicast group to which this host belongs on a given network interface.
+ * They are kept in a linked list, rooted in the interface's in_ifaddr
+ * structure.
+ */
+struct in_multi {
+ struct in_addr inm_addr; /* IP multicast address */
+ struct ifnet *inm_ifp; /* back pointer to ifnet */
+ struct in_ifaddr *inm_ia; /* back pointer to in_ifaddr */
+ u_int inm_refcount; /* no. membership claims by sockets */
+ u_int inm_timer; /* IGMP membership report timer */
+ LIST_ENTRY(in_multi) inm_list; /* list of multicast addresses */
+ u_int inm_state; /* state of membership */
+ struct router_info *inm_rti; /* router version info */
+};
+
+#ifdef _KERNEL
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of the in_multi records.
+ */
+struct in_multistep {
+ struct in_ifaddr *i_ia;
+ struct in_multi *i_inm;
+};
+
+/*
+ * Macro for looking up the in_multi record for a given IP multicast address
+ * on a given interface. If no matching record is found, "inm" returns NULL.
+ */
+#define IN_LOOKUP_MULTI(addr, ifp, inm) \
+ /* struct in_addr addr; */ \
+ /* struct ifnet *ifp; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ register struct in_ifaddr *ia; \
+\
+ IFP_TO_IA((ifp), ia); \
+ if (ia == NULL) \
+ (inm) = NULL; \
+ else \
+ for ((inm) = ia->ia_multiaddrs.lh_first; \
+ (inm) != NULL && (inm)->inm_addr.s_addr != (addr).s_addr; \
+ (inm) = inm->inm_list.le_next) \
+ continue; \
+}
+
+/*
+ * Macro to step through all of the in_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. IN_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "inm" when there
+ * are no remaining records.
+ */
+#define IN_NEXT_MULTI(step, inm) \
+ /* struct in_multistep step; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ if (((inm) = (step).i_inm) != NULL) \
+ (step).i_inm = (inm)->inm_list.le_next; \
+ else \
+ while ((step).i_ia != NULL) { \
+ (inm) = (step).i_ia->ia_multiaddrs.lh_first; \
+ (step).i_ia = (step).i_ia->ia_list.tqe_next; \
+ if ((inm) != NULL) { \
+ (step).i_inm = (inm)->inm_list.le_next; \
+ break; \
+ } \
+ } \
+}
+
+#define IN_FIRST_MULTI(step, inm) \
+ /* struct in_multistep step; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ (step).i_ia = in_ifaddr.tqh_first; \
+ (step).i_inm = NULL; \
+ IN_NEXT_MULTI((step), (inm)); \
+}
+
+int in_ifinit __P((struct ifnet *,
+ struct in_ifaddr *, struct sockaddr_in *, int));
+struct in_multi *in_addmulti __P((struct in_addr *, struct ifnet *));
+void in_delmulti __P((struct in_multi *));
+void in_ifscrub __P((struct ifnet *, struct in_ifaddr *));
+int in_control __P((struct socket *, u_long, caddr_t, struct ifnet *));
+#endif
+
+
+/* INET6 stuff */
+#include <netinet6/in6_var.h>
+
+#endif // _NETINET_IN_VAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip.h b/ecos/packages/net/tcpip/current/include/netinet/ip.h
new file mode 100644
index 0000000..4e4813b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip.h
@@ -0,0 +1,223 @@
+//==========================================================================
+//
+// include/netinet/ip.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip.h,v 1.6 1999/12/08 06:50:19 itojun Exp $ */
+/* $NetBSD: ip.h,v 1.9 1995/05/15 01:22:44 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP_H_
+#define _NETINET_IP_H_
+
+#include <netinet/in_systm.h>
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+#define IPVERSION 4
+
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int8_t ip_hl:4, /* header length */
+ ip_v:4; /* version */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t ip_v:4, /* version */
+ ip_hl:4; /* header length */
+#endif
+ u_int8_t ip_tos; /* type of service */
+ u_int16_t ip_len; /* total length */
+ u_int16_t ip_id; /* identification */
+ u_int16_t ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_int16_t ip_sum; /* checksum */
+ struct in_addr ip_src, ip_dst; /* source and dest address */
+} __attribute__ ((aligned(1), packed));
+
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+/* IPTOS_LOWCOST 0x02 XXX */
+#if 1
+/* ECN bits proposed by Sally Floyd */
+#define IPTOS_CE 0x01 /* congestion experienced */
+#define IPTOS_ECT 0x02 /* ECN-capable transport */
+#endif
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPIED(o) ((o)&0x80)
+#define IPOPT_CLASS(o) ((o)&0x60)
+#define IPOPT_NUMBER(o) ((o)&0x1f)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_NOP 1 /* no operation */
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SSRR 137 /* strict source route */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp {
+ u_int8_t ipt_code; /* IPOPT_TS */
+ u_int8_t ipt_len; /* size of structure (variable) */
+ u_int8_t ipt_ptr; /* index of current entry */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int8_t ipt_flg:4, /* flags, see below */
+ ipt_oflw:4; /* overflow counter */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t ipt_oflw:4, /* overflow counter */
+ ipt_flg:4; /* flags, see below */
+#endif
+ union ipt_timestamp {
+ n_time ipt_time[1];
+ struct ipt_ta {
+ struct in_addr ipt_addr;
+ n_time ipt_time;
+ } ipt_ta[1];
+ } ipt_timestamp;
+} __attribute__ ((aligned(1), packed));
+
+/* flag bits for ipt_flg */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
+
+#define IP_MSS 576 /* default maximum segment size */
+
+/*
+ * This is the real IPv4 psuedo header, used for computing the TCP and UDP
+ * checksums. For the Internet checksum, struct ipovly can be used instead.
+ * For stronger checksums, the real thing must be used.
+ */
+struct ippseudo {
+ struct in_addr ippseudo_src; /* source internet address */
+ struct in_addr ippseudo_dst; /* destination internet address */
+ u_int8_t ippseudo_pad; /* pad, must be zero */
+ u_int8_t ippseudo_p; /* protocol */
+ u_int16_t ippseudo_len; /* protocol length */
+} __attribute__ ((aligned(1), packed));
+
+#endif // _NETINET_IP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip6.h b/ecos/packages/net/tcpip/current/include/netinet/ip6.h
new file mode 100644
index 0000000..2d91f94
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip6.h
@@ -0,0 +1,32 @@
+//==========================================================================
+//
+// include/netinet/ip6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip6.h,v 1.1 1999/12/08 06:50:19 itojun Exp $ */
+
+#include <netinet6/ip6.h>
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_ah.h b/ecos/packages/net/tcpip/current/include/netinet/ip_ah.h
new file mode 100644
index 0000000..c958373
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_ah.h
@@ -0,0 +1,145 @@
+//==========================================================================
+//
+// include/netinet/ip_ah.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_ah.h,v 1.19 1999/12/09 10:11:11 angelos Exp $ */
+
+/*
+ * The authors of this code are John Ioannidis (ji@tla.org),
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Niels Provos (provos@physnet.uni-hamburg.de).
+ *
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Additional features in 1999 by Angelos D. Keromytis.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
+ * Angelos D. Keromytis and Niels Provos.
+ *
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef _NETINET_IP_AH_H_
+#define _NETINET_IP_AH_H_
+
+/*
+ * Authentication Header Processing
+ * Per RFC1826 (Atkinson, 1995)
+ */
+
+struct ah_old
+{
+ u_int8_t ah_nh; /* Next header (protocol) */
+ u_int8_t ah_hl; /* AH length, in 32-bit words */
+ u_int16_t ah_rv; /* reserved, must be 0 */
+ u_int32_t ah_spi; /* Security Parameters Index */
+ u_int8_t ah_data[1]; /* More, really */
+};
+
+#define AH_OLD_FLENGTH 8 /* size of fixed part */
+
+struct ahstat
+{
+ u_int32_t ahs_hdrops; /* packet shorter than header shows */
+ u_int32_t ahs_notdb;
+ u_int32_t ahs_badkcr;
+ u_int32_t ahs_badauth;
+ u_int32_t ahs_noxform;
+ u_int32_t ahs_qfull;
+ u_int32_t ahs_wrap;
+ u_int32_t ahs_replay;
+ u_int32_t ahs_badauthl; /* bad authenticator length */
+ u_int32_t ahs_input; /* Input AH packets */
+ u_int32_t ahs_output; /* Output AH packets */
+ u_int32_t ahs_invalid; /* Trying to use an invalid TDB */
+ u_int64_t ahs_ibytes; /* input bytes */
+ u_int64_t ahs_obytes; /* output bytes */
+ u_int32_t ahs_toobig; /* packet got larger than IP_MAXPACKET */
+ u_int32_t ahs_pdrops; /* packet blocked due to policy */
+};
+
+struct ah_new
+{
+ u_int8_t ah_nh; /* Next header (protocol) */
+ u_int8_t ah_hl; /* AH length, in 32-bit words */
+ u_int16_t ah_rv; /* reserved, must be 0 */
+ u_int32_t ah_spi; /* Security Parameters Index */
+ u_int32_t ah_rpl; /* Replay prevention */
+ u_int8_t ah_data[AH_HMAC_HASHLEN];/* Authenticator */
+};
+
+#define AH_NEW_FLENGTH (sizeof(struct ah_new))
+
+/* Size of the largest hash function output used in AH-new, in bytes */
+#define AH_MAX_HASHLEN 20
+
+/*
+ * Names for AH sysctl objects
+ */
+#define AHCTL_ENABLE 1 /* Enable AH processing */
+#define AHCTL_MAXID 2
+
+#define AHCTL_NAMES { \
+ { 0, 0 }, \
+ { "enable", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+void ah_input __P((struct mbuf *, ...));
+int ah_output __P((struct mbuf *, struct tdb *, struct mbuf **));
+int ah_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+
+#ifdef INET6
+void ah6_input __P((struct mbuf *, ...));
+#endif /* INET6 */
+
+extern int ah_enable;
+struct ahstat ahstat;
+#endif /* _KERNEL */
+
+#endif // _NETINET_IP_AH_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_auth.h b/ecos/packages/net/tcpip/current/include/netinet/ip_auth.h
new file mode 100644
index 0000000..3324621
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_auth.h
@@ -0,0 +1,96 @@
+//==========================================================================
+//
+// include/netinet/ip_auth.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_auth.h,v 1.4 1999/12/15 05:20:21 kjell Exp $ */
+/*
+ * Copyright (C) 1997-1998 by Darren Reed & Guido Van Rooij.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ */
+
+#ifndef _NETINET_IP_AUTH_H__
+#define _NETINET_IP_AUTH_H__
+
+#define FR_NUMAUTH 32
+
+typedef struct frauth {
+ int fra_age;
+ int fra_index;
+ u_32_t fra_pass;
+ fr_info_t fra_info;
+#if SOLARIS
+ queue_t *fra_q;
+#endif
+} frauth_t;
+
+typedef struct frauthent {
+ struct frentry fae_fr;
+ struct frauthent *fae_next;
+ u_long fae_age;
+} frauthent_t;
+
+typedef struct fr_authstat {
+ U_QUAD_T fas_hits;
+ U_QUAD_T fas_miss;
+ u_long fas_nospace;
+ u_long fas_added;
+ u_long fas_sendfail;
+ u_long fas_sendok;
+ u_long fas_queok;
+ u_long fas_quefail;
+ u_long fas_expire;
+ frauthent_t *fas_faelist;
+} fr_authstat_t;
+
+
+extern frentry_t *ipauth;
+extern struct fr_authstat fr_authstats;
+extern int fr_defaultauthage;
+extern int fr_authstart;
+extern int fr_authend;
+extern int fr_authsize;
+extern int fr_authused;
+extern u_32_t fr_checkauth __P((ip_t *, fr_info_t *));
+extern void fr_authexpire __P((void));
+extern void fr_authunload __P((void));
+extern mb_t *fr_authpkts[];
+#if defined(_KERNEL) && SOLARIS
+extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *));
+#else
+extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
+#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **));
+#else
+extern int fr_auth_ioctl __P((caddr_t, int, frentry_t *, frentry_t **));
+#endif
+#endif /* _NETINET_IP_AUTH_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_blf.h b/ecos/packages/net/tcpip/current/include/netinet/ip_blf.h
new file mode 100644
index 0000000..c08fd2b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_blf.h
@@ -0,0 +1,108 @@
+//==========================================================================
+//
+// include/netinet/ip_blf.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_blf.h,v 1.2 1999/02/23 05:15:09 angelos Exp $ */
+/*
+ * Blowfish - a fast block cipher designed by Bruce Schneier
+ *
+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
+ * All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Niels Provos.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _NETINET_IP_BLF_H_
+#define _NETINET_IP_BLF_H_
+
+/* Schneier states the maximum key length to be 56 bytes.
+ * The way how the subkeys are initalized by the key up
+ * to (N+2)*4 i.e. 72 bytes are utilized.
+ * Warning: For normal blowfish encryption only 56 bytes
+ * of the key affect all cipherbits.
+ */
+
+#define BLF_N 16 /* Number of Subkeys */
+#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
+
+/* Blowfish context */
+typedef struct BlowfishContext {
+ u_int32_t S[4][256]; /* S-Boxes */
+ u_int32_t P[BLF_N + 2]; /* Subkeys */
+} blf_ctx;
+
+/* Raw access to customized Blowfish
+ * blf_key is just:
+ * Blowfish_initstate( state )
+ * Blowfish_expand0state( state, key, keylen )
+ */
+
+void Blowfish_encipher __P((blf_ctx *, u_int32_t *, u_int32_t *));
+void Blowfish_decipher __P((blf_ctx *, u_int32_t *, u_int32_t *));
+void Blowfish_initstate __P((blf_ctx *));
+void Blowfish_expand0state __P((blf_ctx *, const u_int8_t *, u_int16_t));
+void Blowfish_expandstate
+ __P((blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t));
+
+/* Standard Blowfish */
+
+void blf_key __P((blf_ctx *, const u_int8_t *, u_int16_t));
+void blf_enc __P((blf_ctx *, u_int32_t *, u_int16_t));
+void blf_dec __P((blf_ctx *, u_int32_t *, u_int16_t));
+
+/* Converts u_int8_t to u_int32_t */
+u_int32_t Blowfish_stream2word __P((const u_int8_t *, u_int16_t ,
+ u_int16_t *));
+
+void blf_ecb_encrypt __P((blf_ctx *, u_int8_t *, u_int32_t));
+void blf_ecb_decrypt __P((blf_ctx *, u_int8_t *, u_int32_t));
+
+#endif // _NETINET_IP_BLF_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_cast.h b/ecos/packages/net/tcpip/current/include/netinet/ip_cast.h
new file mode 100644
index 0000000..4df26fd
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_cast.h
@@ -0,0 +1,51 @@
+//==========================================================================
+//
+// include/netinet/ip_cast.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_cast.h,v 1.3 1999/02/17 18:09:55 deraadt Exp $ */
+
+/*
+ * CAST-128 in C
+ * Written by Steve Reid <sreid@sea-to-sky.net>
+ * 100% Public Domain - no warranty
+ * Released 1997.10.11
+ */
+
+#ifndef _NETINET_IP_CAST_H_
+#define _NETINET_IP_CAST_H_
+
+typedef struct {
+ u_int32_t xkey[32]; /* Key, after expansion */
+ int rounds; /* Number of rounds to use, 12 or 16 */
+} cast_key;
+
+void cast_setkey __P((cast_key * key, u_int8_t * rawkey, int keybytes));
+void cast_encrypt __P((cast_key * key, u_int8_t * inblock, u_int8_t * outblock));
+void cast_decrypt __P((cast_key * key, u_int8_t * inblock, u_int8_t * outblock));
+
+#endif /* ifndef _NETINET_IP_CAST_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_castsb.h b/ecos/packages/net/tcpip/current/include/netinet/ip_castsb.h
new file mode 100644
index 0000000..7447e77
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_castsb.h
@@ -0,0 +1,577 @@
+//==========================================================================
+//
+// include/netinet/ip_castsb.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_castsb.h,v 1.2 1999/02/17 18:09:55 deraadt Exp $ */
+/*
+ * CAST-128 in C
+ * Written by Steve Reid <sreid@sea-to-sky.net>
+ * 100% Public Domain - no warranty
+ * Released 1997.10.11
+ */
+
+#ifndef _NETINET_IP_CASTSB_H_
+#define _NETINET_IP_CASTSB_H_
+
+static const u_int32_t cast_sbox1[256] = {
+ 0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A,
+ 0x1E213F2F, 0x9C004DD3, 0x6003E540, 0xCF9FC949,
+ 0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,
+ 0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E,
+ 0x28683B6F, 0xC07FD059, 0xFF2379C8, 0x775F50E2,
+ 0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D,
+ 0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F,
+ 0x2ABE32E1, 0xAA54166B, 0x22568E3A, 0xA2D341D0,
+ 0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
+ 0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7,
+ 0xB82CBAEF, 0xD751D159, 0x6FF7F0ED, 0x5A097A1F,
+ 0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
+ 0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D,
+ 0xB7332290, 0xE93B159F, 0xB48EE411, 0x4BFF345D,
+ 0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
+ 0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50,
+ 0x882240F2, 0x0C6E4F38, 0xA4E4BFD7, 0x4F5BA272,
+ 0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
+ 0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D,
+ 0x57538AD5, 0x6A390493, 0xE63D37E0, 0x2A54F6B3,
+ 0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
+ 0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167,
+ 0x38901091, 0xC6B505EB, 0x84C7CB8C, 0x2AD75A0F,
+ 0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
+ 0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9,
+ 0x6C00B32D, 0x73E2BB14, 0xA0BEBC3C, 0x54623779,
+ 0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
+ 0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2,
+ 0x81383F05, 0x6963C5C8, 0x76CB5AD6, 0xD49974C9,
+ 0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
+ 0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E,
+ 0x31366241, 0x051EF495, 0xAA573B04, 0x4A805D8D,
+ 0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
+ 0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5,
+ 0x6B54BFAB, 0x2B0B1426, 0xAB4CC9D7, 0x449CCD82,
+ 0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
+ 0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC,
+ 0xEADF55B3, 0xD5BD9E98, 0xE31231B2, 0x2AD5AD6C,
+ 0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
+ 0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC,
+ 0x7B5A41F0, 0xD37CFBAD, 0x1B069505, 0x41ECE491,
+ 0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
+ 0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE,
+ 0xE01063DA, 0x4736F464, 0x5AD328D8, 0xB347CC96,
+ 0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
+ 0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A,
+ 0x3F04442F, 0x6188B153, 0xE0397A2E, 0x5727CB79,
+ 0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
+ 0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779,
+ 0x4744EAD4, 0xB11C3274, 0xDD24CB9E, 0x7E1C54BD,
+ 0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
+ 0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6,
+ 0x580304F0, 0xCA042CF1, 0x011A37EA, 0x8DBFAADB,
+ 0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
+ 0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0,
+ 0x7C63B2CF, 0x700B45E1, 0xD5EA50F1, 0x85A92872,
+ 0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
+ 0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C,
+ 0x474D6AD7, 0x7C0C5E5C, 0xD1231959, 0x381B7298,
+ 0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E,
+ 0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571,
+ 0x962BDA1C, 0xE1E696FF, 0xB141AB08, 0x7CCA89B9,
+ 0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,
+ 0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF
+};
+
+static const u_int32_t cast_sbox2[256] = {
+ 0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380,
+ 0xFE61CF7A, 0xEEC5207A, 0x55889C94, 0x72FC0651,
+ 0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,
+ 0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3,
+ 0xA0B52F7B, 0x59E83605, 0xEE15B094, 0xE9FFD909,
+ 0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB,
+ 0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B,
+ 0x01420DDB, 0xE4E7EF5B, 0x25A1FF41, 0xE180F806,
+ 0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
+ 0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B,
+ 0xE113C85B, 0xACC40083, 0xD7503525, 0xF7EA615F,
+ 0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
+ 0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21,
+ 0x071F6181, 0x39F7627F, 0x361E3084, 0xE4EB573B,
+ 0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
+ 0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C,
+ 0x10843094, 0x2537A95E, 0xF46F6FFE, 0xA1FF3B1F,
+ 0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
+ 0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D,
+ 0x8A45388C, 0x1D804366, 0x721D9BFD, 0xA58684BB,
+ 0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
+ 0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD,
+ 0xC5D655DD, 0xEB667064, 0x77840B4D, 0xA1B6A801,
+ 0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
+ 0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755,
+ 0xB5625DBF, 0x68561BE6, 0x83CA6B94, 0x2D6ED23B,
+ 0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
+ 0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304,
+ 0x81ED6F61, 0x20E74364, 0xB45E1378, 0xDE18639B,
+ 0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
+ 0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C,
+ 0x488CB402, 0x1BA4FE5B, 0xA4B09F6B, 0x1CA815CF,
+ 0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
+ 0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C,
+ 0xEE41E729, 0x6E1D2D7C, 0x50045286, 0x1E6685F3,
+ 0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
+ 0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9,
+ 0xCDFF33A6, 0xA02B1741, 0x7CBAD9A2, 0x2180036F,
+ 0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
+ 0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6,
+ 0xCDF0B680, 0x17844D3B, 0x31EEF84D, 0x7E0824E4,
+ 0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
+ 0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43,
+ 0xB3FAEC54, 0x157FD7FA, 0xEF8579CC, 0xD152DE58,
+ 0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
+ 0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906,
+ 0xB8DA230C, 0x80823028, 0xDCDEF3C8, 0xD35FB171,
+ 0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
+ 0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89,
+ 0x8B1C34BC, 0x301E16E6, 0x273BE979, 0xB0FFEAA6,
+ 0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
+ 0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4,
+ 0xDC8637A0, 0x16A7D3B1, 0x9FC393B7, 0xA7136EEB,
+ 0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
+ 0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E,
+ 0xDB92F2FB, 0x5EEA29CB, 0x145892F5, 0x91584F7F,
+ 0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
+ 0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249,
+ 0xB284600C, 0xD835731D, 0xDCB1C647, 0xAC4C56EA,
+ 0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA,
+ 0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD,
+ 0x649DA589, 0xA345415E, 0x5C038323, 0x3E5D3BB9,
+ 0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,
+ 0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1
+};
+
+static const u_int32_t cast_sbox3[256] = {
+ 0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907,
+ 0x47607FFF, 0x369FE44B, 0x8C1FC644, 0xAECECA90,
+ 0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,
+ 0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5,
+ 0x11107D9F, 0x07647DB9, 0xB2E3E4D4, 0x3D4F285E,
+ 0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E,
+ 0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC,
+ 0x21FFFCEE, 0x825B1BFD, 0x9255C5ED, 0x1257A240,
+ 0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
+ 0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5,
+ 0xA8C01DB7, 0x579FC264, 0x67094F31, 0xF2BD3F5F,
+ 0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
+ 0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99,
+ 0xA197C81C, 0x4A012D6E, 0xC5884A28, 0xCCC36F71,
+ 0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
+ 0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04,
+ 0xA747D2D0, 0x1651192E, 0xAF70BF3E, 0x58C31380,
+ 0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
+ 0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8,
+ 0x8427F4A0, 0x1EAC5790, 0x796FB449, 0x8252DC15,
+ 0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
+ 0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2,
+ 0x23EFE941, 0xA903F12E, 0x60270DF2, 0x0276E4B6,
+ 0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
+ 0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E,
+ 0x842F7D83, 0x340CE5C8, 0x96BBB682, 0x93B4B148,
+ 0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
+ 0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC,
+ 0x8B907CEE, 0xB51FD240, 0xE7C07CE3, 0xE566B4A1,
+ 0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
+ 0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C,
+ 0xF76CEDD9, 0xBDA8229C, 0x127DADAA, 0x438A074E,
+ 0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
+ 0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51,
+ 0x68CC7BFB, 0xD90F2788, 0x12490181, 0x5DE5FFD4,
+ 0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
+ 0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B,
+ 0x6D498623, 0x193CBCFA, 0x27627545, 0x825CF47A,
+ 0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
+ 0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B,
+ 0x285BA1C8, 0x3C62F44F, 0x35C0EAA5, 0xE805D231,
+ 0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
+ 0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889,
+ 0x694BCC11, 0x236A5CAE, 0x12DECA4D, 0x2C3F8CC5,
+ 0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
+ 0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45,
+ 0x3A609437, 0xEC00C9A9, 0x44715253, 0x0A874B49,
+ 0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
+ 0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D,
+ 0x07478CD1, 0x006E1888, 0xA2E53F55, 0xB9E6D4BC,
+ 0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
+ 0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0,
+ 0x947B0001, 0x570075D2, 0xF9BB88F8, 0x8942019E,
+ 0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
+ 0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767,
+ 0xCF1FEBD2, 0x61EFC8C2, 0xF1AC2571, 0xCC8239C2,
+ 0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
+ 0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49,
+ 0x5727C148, 0x2BE98A1D, 0x8AB41738, 0x20E1BE24,
+ 0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D,
+ 0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0,
+ 0x642B1E31, 0x9C305A00, 0x52BCE688, 0x1B03588A,
+ 0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,
+ 0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783
+};
+
+static const u_int32_t cast_sbox4[256] = {
+ 0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298,
+ 0x4A4F7BDB, 0x64AD8C57, 0x85510443, 0xFA020ED1,
+ 0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,
+ 0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF,
+ 0x28147F5F, 0x4FA2B8CD, 0xC9430040, 0x0CC32220,
+ 0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15,
+ 0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE,
+ 0x1A05645F, 0x0C13FEFE, 0x081B08CA, 0x05170121,
+ 0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
+ 0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25,
+ 0xCE84FFDF, 0xF5718801, 0x3DD64B04, 0xA26F263B,
+ 0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
+ 0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93,
+ 0xD3772061, 0x11B638E1, 0x72500E03, 0xF80EB2BB,
+ 0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
+ 0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5,
+ 0x4D351805, 0x7F3D5CE3, 0xA6C866C6, 0x5D5BCCA9,
+ 0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
+ 0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB,
+ 0x022083B8, 0x3FB6180C, 0x18F8931E, 0x281658E6,
+ 0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
+ 0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23,
+ 0x69DEAD38, 0x1574CA16, 0xDF871B62, 0x211C40B7,
+ 0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
+ 0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340,
+ 0x557BE8DE, 0x00EAE4A7, 0x0CE5C2EC, 0x4DB4BBA6,
+ 0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
+ 0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119,
+ 0x6E85CB75, 0xBE07C002, 0xC2325577, 0x893FF4EC,
+ 0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
+ 0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205,
+ 0xAAC9548A, 0xECA1D7C7, 0x041AFA32, 0x1D16625A,
+ 0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
+ 0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79,
+ 0x026A4CEB, 0x52437EFF, 0x2F8F76B4, 0x0DF980A5,
+ 0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
+ 0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C,
+ 0x1741A254, 0xE5B6A035, 0x213D42F6, 0x2C1C7C26,
+ 0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
+ 0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB,
+ 0x63315C21, 0x5E0A72EC, 0x49BAFEFD, 0x187908D9,
+ 0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
+ 0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF,
+ 0x71EAE2A1, 0x1F9AF36E, 0xCFCBD12F, 0xC1DE8417,
+ 0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
+ 0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2,
+ 0x6F7DE532, 0x58FD7EB6, 0xD01EE900, 0x24ADFFC2,
+ 0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
+ 0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF,
+ 0x29908415, 0x7FBB977F, 0xAF9EB3DB, 0x29C9ED2A,
+ 0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
+ 0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919,
+ 0x77079103, 0xDEA03AF6, 0x78A8565E, 0xDEE356DF,
+ 0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
+ 0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF,
+ 0xAFE67AFB, 0xF470C4B2, 0xF3E0EB5B, 0xD6CC9876,
+ 0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
+ 0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB,
+ 0xB5676E69, 0x9BD3DDDA, 0xDF7E052F, 0xDB25701C,
+ 0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04,
+ 0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43,
+ 0x41823979, 0x932BCDF6, 0xB657C34D, 0x4EDFD282,
+ 0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E,
+ 0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2
+};
+
+static const u_int32_t cast_sbox5[256] = {
+ 0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911,
+ 0xB86A7FFF, 0x1DD358F5, 0x44DD9D44, 0x1731167F,
+ 0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
+ 0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A,
+ 0xE6A2E77F, 0xF0C720CD, 0xC4494816, 0xCCF5C180,
+ 0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
+ 0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2,
+ 0x4E40B48D, 0x248EB6FB, 0x8DBA1CFE, 0x41A99B02,
+ 0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
+ 0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A,
+ 0xF2F3F763, 0x68AF8040, 0xED0C9E56, 0x11B4958B,
+ 0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
+ 0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571,
+ 0x0C05372A, 0x578535F2, 0x2261BE02, 0xD642A0C9,
+ 0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
+ 0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981,
+ 0x5C1FF900, 0xFE38D399, 0x0C4EFF0B, 0x062407EA,
+ 0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
+ 0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263,
+ 0xDF65001F, 0x0EC50966, 0xDFDD55BC, 0x29DE0655,
+ 0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
+ 0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2,
+ 0xBCF3F0AA, 0x87AC36E9, 0xE53A7426, 0x01B3D82B,
+ 0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
+ 0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284,
+ 0x636737B6, 0x50F5B616, 0xF24766E3, 0x8ECA36C1,
+ 0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
+ 0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA,
+ 0x26E46695, 0xB7566419, 0xF654EFC5, 0xD08D58B7,
+ 0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
+ 0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE,
+ 0xC62BF3CD, 0x9E0885F9, 0x68CB3E47, 0x086C010F,
+ 0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
+ 0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA,
+ 0x0AB378D5, 0xD951FB0C, 0xDED7DA56, 0x4124BBE4,
+ 0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
+ 0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561,
+ 0xC3DC0280, 0x05687715, 0x646C6BD7, 0x44904DB3,
+ 0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
+ 0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840,
+ 0x76F0AE02, 0x083BE84D, 0x28421C9A, 0x44489406,
+ 0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
+ 0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472,
+ 0x3CA5D717, 0x7D161BBA, 0x9CAD9010, 0xAF462BA2,
+ 0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
+ 0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7,
+ 0x445F7382, 0x175683F4, 0xCDC66A97, 0x70BE0288,
+ 0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
+ 0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2,
+ 0x1C5C1572, 0xF6721B2C, 0x1AD2FFF3, 0x8C25404E,
+ 0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
+ 0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E,
+ 0x44094F85, 0x3F481D87, 0xFCFEAE7B, 0x77B5FF76,
+ 0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
+ 0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0,
+ 0xDF3B0874, 0x95055110, 0x1B5AD7A8, 0xF61ED5AD,
+ 0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
+ 0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0,
+ 0x5CE96C28, 0xE176EDA3, 0x6BAC307F, 0x376829D2,
+ 0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
+ 0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE,
+ 0xF9E0659A, 0xEEB9491D, 0x34010718, 0xBB30CAB8,
+ 0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
+ 0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4
+};
+
+static const u_int32_t cast_sbox6[256] = {
+ 0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C,
+ 0x95DB08E7, 0x016843B4, 0xECED5CBC, 0x325553AC,
+ 0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
+ 0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138,
+ 0x33F14961, 0xC01937BD, 0xF506C6DA, 0xE4625E7E,
+ 0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
+ 0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866,
+ 0xA084DB2D, 0x09A8486F, 0xA888614A, 0x2900AF98,
+ 0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
+ 0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072,
+ 0xFD41197E, 0x9305A6B0, 0xE86BE3DA, 0x74BED3CD,
+ 0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
+ 0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53,
+ 0x5C3D9C01, 0x64BDB941, 0x2C0E636A, 0xBA7DD9CD,
+ 0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
+ 0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8,
+ 0x284CAF89, 0xAA928223, 0x9334BE53, 0x3B3A21BF,
+ 0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
+ 0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807,
+ 0x5B7C5ECC, 0x221DB3A6, 0x9A69A02F, 0x68818A54,
+ 0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
+ 0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387,
+ 0x53BDDB65, 0xE76FFBE7, 0xE967FD78, 0x0BA93563,
+ 0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
+ 0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0,
+ 0xE81F994F, 0x9528CD89, 0xFD339FED, 0xB87834BF,
+ 0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
+ 0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF,
+ 0x4EC75B95, 0x24F2C3C0, 0x42D15D99, 0xCD0D7FA0,
+ 0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
+ 0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2,
+ 0x372B74AF, 0x692573E4, 0xE9A9D848, 0xF3160289,
+ 0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
+ 0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950,
+ 0x36F73523, 0x4CFB6E87, 0x7DA4CEC0, 0x6C152DAA,
+ 0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
+ 0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9,
+ 0x2B05D08D, 0x48B9D585, 0xDC049441, 0xC8098F9B,
+ 0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
+ 0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE,
+ 0xBF32679D, 0xD45B5B75, 0xB353FD00, 0xCBB0E358,
+ 0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
+ 0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397,
+ 0x47CF8E7A, 0xB6C85283, 0x3CC2ACFB, 0x3FC06976,
+ 0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
+ 0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0,
+ 0x3007CD3E, 0x74719EEF, 0xDC872681, 0x073340D4,
+ 0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
+ 0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F,
+ 0x6FE4AC98, 0xB173ECC0, 0xBC60B42A, 0x953498DA,
+ 0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
+ 0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC,
+ 0xE8816F4A, 0x3814F200, 0xA3F94043, 0x9C7A54C2,
+ 0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
+ 0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB,
+ 0xBA5AC7B5, 0xB6F6DEAF, 0x3A479C3A, 0x5302DA25,
+ 0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
+ 0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121,
+ 0xB81A928A, 0x60ED5869, 0x97C55B96, 0xEAEC991B,
+ 0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
+ 0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855,
+ 0xD36B4CF1, 0xF544EDEB, 0xB0E93524, 0xBEBB8FBD,
+ 0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
+ 0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F
+};
+
+static const u_int32_t cast_sbox7[256] = {
+ 0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693,
+ 0x2A8D7F6F, 0xAB9BC912, 0xDE6008A1, 0x2028DA1F,
+ 0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
+ 0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE,
+ 0xA05FBCF6, 0xCD4181E9, 0xE150210C, 0xE24EF1BD,
+ 0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
+ 0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F,
+ 0x089766BE, 0xBAEEADF4, 0x1286BECF, 0xB6EACB19,
+ 0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
+ 0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2,
+ 0x107789BE, 0xB3B2E9CE, 0x0502AA8F, 0x0BC0351E,
+ 0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
+ 0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83,
+ 0x334266CE, 0x8C9341B7, 0xD0D854C0, 0xCB3A6C88,
+ 0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
+ 0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816,
+ 0x0A961288, 0xE1A5C06E, 0x13749E67, 0x72FC081A,
+ 0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
+ 0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F,
+ 0xBC8EC511, 0x38BC46E9, 0xC6E6FA14, 0xBAE8584A,
+ 0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
+ 0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264,
+ 0x92544A8B, 0x009B4FC3, 0xABA68CED, 0x9AC96F78,
+ 0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
+ 0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D,
+ 0xF7DEBB85, 0x61FE033C, 0x16746233, 0x3C034C28,
+ 0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
+ 0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3,
+ 0x0C4FB99A, 0xBB325778, 0x3EC6D97B, 0x6E77A6A9,
+ 0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
+ 0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302,
+ 0xB96D8C32, 0xEBD4E7BE, 0xBE8B9D2D, 0x7979FB06,
+ 0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
+ 0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033,
+ 0xF28EBFB0, 0xF5B9C310, 0xA0EAC280, 0x08B9767A,
+ 0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
+ 0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4,
+ 0x826D2BEF, 0x4EEB8476, 0x488DCF25, 0x36C9D566,
+ 0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
+ 0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509,
+ 0xF22B017D, 0xA4173F70, 0xDD1E16C3, 0x15E0D7F9,
+ 0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
+ 0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C,
+ 0x93D29A22, 0xE32DBF9A, 0x058745B9, 0x3453DC1E,
+ 0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
+ 0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C,
+ 0x66626C1C, 0x7154C24C, 0xEA082B2A, 0x93EB2939,
+ 0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
+ 0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E,
+ 0xD3A0C108, 0xA1E7160E, 0xE4F2DFA6, 0x693ED285,
+ 0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
+ 0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301,
+ 0xC79F022F, 0x3C997E7E, 0x5E4F9504, 0x3FFAFBBD,
+ 0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
+ 0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567,
+ 0x5592A33D, 0xB5229301, 0xCFD2A87F, 0x60AEB767,
+ 0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
+ 0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647,
+ 0x97FD61A9, 0xEA7759F4, 0x2D57539D, 0x569A58CF,
+ 0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
+ 0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2,
+ 0x3FFA50BC, 0x3D40F021, 0xC3C0BDAE, 0x4958C24C,
+ 0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
+ 0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3
+};
+
+static const u_int32_t cast_sbox8[256] = {
+ 0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095,
+ 0x7789F8B7, 0xE6C1121B, 0x0E241600, 0x052CE8B5,
+ 0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
+ 0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC,
+ 0xDE9ADEB1, 0x0A0CC32C, 0xBE197029, 0x84A00940,
+ 0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
+ 0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42,
+ 0xC7ECE831, 0x3F8F95E7, 0x72DF191B, 0x7580330D,
+ 0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
+ 0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2,
+ 0x12A8DDEC, 0xFDAA335D, 0x176F43E8, 0x71FB46D4,
+ 0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
+ 0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0,
+ 0x4CFDE06F, 0xC28EC4B8, 0x57E8726E, 0x647A78FC,
+ 0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
+ 0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C,
+ 0xBBD35049, 0x2998DF04, 0x980CF42A, 0x9B6DF491,
+ 0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
+ 0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B,
+ 0x3CF1D2E2, 0x19B47A38, 0x424F7618, 0x35856039,
+ 0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
+ 0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8,
+ 0x7170C608, 0x2D5E3354, 0xD4DE495A, 0x64C6D006,
+ 0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
+ 0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564,
+ 0xF8D7E54E, 0x3E378160, 0x7895CDA5, 0x859C15A5,
+ 0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
+ 0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472,
+ 0x835FFCB8, 0x6DF4C1F2, 0x96F5B195, 0xFD0AF0FC,
+ 0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
+ 0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8,
+ 0xC4618187, 0xEA7A6E98, 0x7CD16EFC, 0x1436876C,
+ 0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
+ 0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB,
+ 0xA842EEDF, 0xFDBA60B4, 0xF1907B75, 0x20E3030F,
+ 0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
+ 0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504,
+ 0xF1E47D8D, 0x844A1BE5, 0xBAE7DFDC, 0x42CBDA70,
+ 0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
+ 0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC,
+ 0x77853B53, 0x37EFFCB5, 0xC5068778, 0xE580B3E6,
+ 0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
+ 0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD,
+ 0xDD06CAA2, 0x37DF932B, 0xC4248289, 0xACF3EBC3,
+ 0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
+ 0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4,
+ 0xE87B40E4, 0xE98EA084, 0x5889E9E1, 0xEFD390FC,
+ 0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
+ 0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA,
+ 0x646F1282, 0x7523D24A, 0xE0779695, 0xF9C17A8F,
+ 0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
+ 0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E,
+ 0x11403092, 0x00DA6D77, 0x4A0CDD61, 0xAD1F4603,
+ 0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
+ 0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37,
+ 0x2DE705CA, 0x8951570F, 0xDF09822B, 0xBD691A6C,
+ 0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
+ 0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384,
+ 0x5938FA0F, 0x42399EF3, 0x36997B07, 0x0E84093D,
+ 0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
+ 0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347,
+ 0x589E8D82, 0x0D2059D1, 0xA466BB1E, 0xF8DA0A82,
+ 0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
+ 0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E
+};
+
+#endif // _NETINET_IP_CASTSB_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_ecn.h b/ecos/packages/net/tcpip/current/include/netinet/ip_ecn.h
new file mode 100644
index 0000000..08e43f2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_ecn.h
@@ -0,0 +1,90 @@
+//==========================================================================
+//
+// include/netinet/ip_ecn.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_ecn.h,v 1.1 1999/12/08 06:50:19 itojun Exp $ */
+
+/*
+ * Copyright (C) 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ *
+ * KAME Id: ip_ecn.h,v 1.2 1999/08/19 12:57:44 itojun Exp
+ */
+
+#ifndef _NETINET_IP_ECN_H_
+#define _NETINET_IP_ECN_H_
+
+/*
+ * ECN consideration on tunnel ingress/egress operation.
+ * http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
+ */
+
+#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__)
+#if defined(_KERNEL) && !defined(_LKM)
+#include "opt_inet.h"
+#endif
+#endif
+
+#define ECN_ALLOWED 1 /* ECN allowed */
+#define ECN_FORBIDDEN 0 /* ECN forbidden */
+#define ECN_NOCARE (-1) /* no consideration to ECN */
+
+#if defined(KERNEL) || defined(_KERNEL)
+extern void ip_ecn_ingress __P((int, u_int8_t *, u_int8_t *));
+extern void ip_ecn_egress __P((int, u_int8_t *, u_int8_t *));
+#ifdef INET6
+extern void ip6_ecn_ingress __P((int, u_int32_t *, u_int32_t *));
+extern void ip6_ecn_egress __P((int, u_int32_t *, u_int32_t *));
+#endif
+#endif
+
+#endif // _NETINET_IP_ECN_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_esp.h b/ecos/packages/net/tcpip/current/include/netinet/ip_esp.h
new file mode 100644
index 0000000..1c65473
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_esp.h
@@ -0,0 +1,139 @@
+//==========================================================================
+//
+// include/netinet/ip_esp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_esp.h,v 1.26 1999/12/09 00:33:29 angelos Exp $ */
+
+/*
+ * The authors of this code are John Ioannidis (ji@tla.org),
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Niels Provos (provos@physnet.uni-hamburg.de).
+ *
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Additional features in 1999 by Angelos D. Keromytis.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
+ * Angelos D. Keromytis and Niels Provos.
+ *
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef _NETINET_IP_ESP_H_
+#define _NETINET_IP_ESP_H_
+
+/*
+ * Encapsulation Security Payload Processing
+ * Per RFC1827 (Atkinson, 1995)
+ */
+
+/* Various defines for the "new" ESP */
+#define ESP_NEW_ALEN 12 /* 96bits authenticator */
+
+struct esp_old
+{
+ u_int32_t esp_spi; /* Security Parameters Index */
+ u_int8_t esp_iv[8]; /* iv[4] may actually be data! */
+};
+
+#define ESP_OLD_FLENGTH 12
+#define ESP_NEW_FLENGTH 16
+
+struct esp_new
+{
+ u_int32_t esp_spi; /* Security Parameter Index */
+ u_int32_t esp_rpl; /* Sequence Number, Replay Counter */
+ u_int8_t esp_iv[8]; /* Data may start already at iv[0]! */
+};
+
+struct espstat
+{
+ u_int32_t esps_hdrops; /* packet shorter than header shows */
+ u_int32_t esps_notdb;
+ u_int32_t esps_badkcr;
+ u_int32_t esps_qfull;
+ u_int32_t esps_noxform;
+ u_int32_t esps_badilen;
+ u_int32_t esps_wrap; /* Replay counter wrapped around */
+ u_int32_t esps_badenc; /* Bad encryption detected */
+ u_int32_t esps_badauth; /* Only valid for transforms with auth */
+ u_int32_t esps_replay; /* Possible packet replay detected */
+ u_int32_t esps_input; /* Input ESP packets */
+ u_int32_t esps_output; /* Output ESP packets */
+ u_int32_t esps_invalid; /* Trying to use an invalid TDB */
+ u_int64_t esps_ibytes; /* input bytes */
+ u_int64_t esps_obytes; /* output bytes */
+ u_int32_t esps_toobig; /* packet got larger than IP_MAXPACKET */
+ u_int32_t esps_pdrops; /* packet blocked due to policy */
+};
+
+/*
+ * Names for ESP sysctl objects
+ */
+#define ESPCTL_ENABLE 1 /* Enable ESP processing */
+#define ESPCTL_MAXID 2
+
+#define ESPCTL_NAMES { \
+ { 0, 0 }, \
+ { "enable", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+void esp_input __P((struct mbuf *, ...));
+int esp_output __P((struct mbuf *, struct tdb *, struct mbuf **));
+int esp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+
+#ifdef INET6
+void esp6_input __P((struct mbuf *, ...));
+#endif /* INET6 */
+
+extern int esp_enable;
+struct espstat espstat;
+#endif /* _Kernel */
+
+#endif // _NETINET_IP_ESP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_ether.h b/ecos/packages/net/tcpip/current/include/netinet/ip_ether.h
new file mode 100644
index 0000000..bac3985
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_ether.h
@@ -0,0 +1,93 @@
+//==========================================================================
+//
+// include/netinet/ip_ether.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_ether.h,v 1.2 1999/10/29 02:00:23 angelos Exp $ */
+
+/*
+ * The author of this code is Angelos D. Keromytis (angelos@adk.gr)
+ *
+ * This code was written by Angelos D. Keromytis in October 1999.
+ *
+ * Copyright (C) 1999, by Angelos D. Keromytis.
+ *
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef _NETINET_IP_ETHER_H_
+#define _NETINET_IP_ETHER_H_
+
+/*
+ * Ethernet-inside-IP processing.
+ */
+
+struct etheripstat
+{
+ u_int32_t etherip_hdrops; /* packet shorter than header shows */
+ u_int32_t etherip_qfull; /* bridge queue full, packet dropped */
+ u_int32_t etherip_noifdrops; /* no interface/bridge information */
+ u_int32_t etherip_pdrops; /* packet dropped due to policy */
+ u_int32_t etherip_adrops; /* all other drops */
+ u_int32_t etherip_ipackets; /* total input packets */
+ u_int32_t etherip_opackets; /* total output packets */
+ u_int64_t etherip_ibytes; /* input bytes */
+ u_int64_t etherip_obytes; /* output bytes */
+};
+
+/*
+ * Names for IP4 sysctl objects
+ */
+#define ETHERIPCTL_ALLOW 1 /* accept incoming EtherIP packets */
+#define ETHERIPCTL_MAXID 2
+
+#define ETHERIPCTL_NAMES { \
+ { 0, 0 }, \
+ { "allow", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+int etherip_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+
+extern int etherip_allow;
+extern struct etheripstat etheripstat;
+#endif
+
+#endif // _NETINET_IP_ETHER_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_fil.h b/ecos/packages/net/tcpip/current/include/netinet/ip_fil.h
new file mode 100644
index 0000000..8924e01
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_fil.h
@@ -0,0 +1,605 @@
+//==========================================================================
+//
+// include/netinet/ip_fil.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_fil.h,v 1.13 1999/12/15 05:20:21 kjell Exp $ */
+/*
+ * Copyright (C) 1993-1998 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * @(#)ip_fil.h 1.35 6/5/96
+ */
+
+#ifndef _NETINET_IP_FIL_H__
+#define _NETINET_IP_FIL_H__
+
+/*
+ * Pathnames for various IP Filter control devices. Used by LKM
+ * and userland, so defined here.
+ */
+#define IPNAT_NAME "/dev/ipnat"
+#define IPSTATE_NAME "/dev/ipstate"
+#define IPAUTH_NAME "/dev/ipauth"
+
+#ifndef SOLARIS
+# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#endif
+
+#if defined(KERNEL) && !defined(_KERNEL)
+# define _KERNEL
+#endif
+
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+#if defined(__STDC__) || defined(__GNUC__)
+# define SIOCADAFR _IOW('r', 60, struct frentry)
+# define SIOCRMAFR _IOW('r', 61, struct frentry)
+# define SIOCSETFF _IOW('r', 62, u_int)
+# define SIOCGETFF _IOR('r', 63, u_int)
+# define SIOCGETFS _IOR('r', 64, struct friostat)
+# define SIOCIPFFL _IOWR('r', 65, int)
+# define SIOCIPFFB _IOR('r', 66, int)
+# define SIOCADIFR _IOW('r', 67, struct frentry)
+# define SIOCRMIFR _IOW('r', 68, struct frentry)
+# define SIOCSWAPA _IOR('r', 69, u_int)
+# define SIOCINAFR _IOW('r', 70, struct frentry)
+# define SIOCINIFR _IOW('r', 71, struct frentry)
+# define SIOCFRENB _IOW('r', 72, u_int)
+# define SIOCFRSYN _IOW('r', 73, u_int)
+# define SIOCFRZST _IOWR('r', 74, struct friostat)
+# define SIOCZRLST _IOWR('r', 75, struct frentry)
+# define SIOCAUTHW _IOWR('r', 76, struct fr_info)
+# define SIOCAUTHR _IOWR('r', 77, struct fr_info)
+# define SIOCATHST _IOWR('r', 78, struct fr_authstat)
+#else
+# define SIOCADAFR _IOW(r, 60, struct frentry)
+# define SIOCRMAFR _IOW(r, 61, struct frentry)
+# define SIOCSETFF _IOW(r, 62, u_int)
+# define SIOCGETFF _IOR(r, 63, u_int)
+# define SIOCGETFS _IOR(r, 64, struct friostat)
+# define SIOCIPFFL _IOWR(r, 65, int)
+# define SIOCIPFFB _IOR(r, 66, int)
+# define SIOCADIFR _IOW(r, 67, struct frentry)
+# define SIOCRMIFR _IOW(r, 68, struct frentry)
+# define SIOCSWAPA _IOR(r, 69, u_int)
+# define SIOCINAFR _IOW(r, 70, struct frentry)
+# define SIOCINIFR _IOW(r, 71, struct frentry)
+# define SIOCFRENB _IOW(r, 72, u_int)
+# define SIOCFRSYN _IOW(r, 73, u_int)
+# define SIOCFRZST _IOWR(r, 74, struct friostat)
+# define SIOCZRLST _IOWR(r, 75, struct frentry)
+# define SIOCAUTHW _IOWR(r, 76, struct fr_info)
+# define SIOCAUTHR _IOWR(r, 77, struct fr_info)
+# define SIOCATHST _IOWR(r, 78, struct fr_authstat)
+#endif
+#define SIOCADDFR SIOCADAFR
+#define SIOCDELFR SIOCRMAFR
+#define SIOCINSFR SIOCINAFR
+
+typedef struct fr_ip {
+ u_char fi_v:4; /* IP version */
+ u_char fi_fl:4; /* packet flags */
+ u_char fi_tos; /* IP packet TOS */
+ u_char fi_ttl; /* IP packet TTL */
+ u_char fi_p; /* IP packet protocol */
+ struct in_addr fi_src; /* source address from packet */
+ struct in_addr fi_dst; /* destination address from packet */
+ u_32_t fi_optmsk; /* bitmask composed from IP options */
+ u_short fi_secmsk; /* bitmask composed from IP security options */
+ u_short fi_auth; /* authentication code from IP sec. options */
+} fr_ip_t;
+
+#define FI_OPTIONS (FF_OPTIONS >> 24)
+#define FI_TCPUDP (FF_TCPUDP >> 24) /* TCP/UCP implied comparison*/
+#define FI_FRAG (FF_FRAG >> 24)
+#define FI_SHORT (FF_SHORT >> 24)
+#define FI_CMP (FI_OPTIONS|FI_TCPUDP|FI_SHORT)
+
+/*
+ * These are both used by the state and NAT code to indicate that one port or
+ * the other should be treated as a wildcard.
+ */
+#define FI_W_SPORT 0x00000100
+#define FI_W_DPORT 0x00000200
+#define FI_WILD (FI_W_SPORT|FI_W_DPORT)
+
+typedef struct fr_info {
+ void *fin_ifp; /* interface packet is `on' */
+ struct fr_ip fin_fi; /* IP Packet summary */
+ u_short fin_data[2]; /* TCP/UDP ports, ICMP code/type */
+ u_char fin_out; /* in or out ? 1 == out, 0 == in */
+ u_char fin_rev; /* state only: 1 = reverse */
+ u_short fin_hlen; /* length of IP header in bytes */
+ u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
+ /* From here on is packet specific */
+ u_char fin_icode; /* ICMP error to return */
+ u_short fin_rule; /* rule # last matched */
+ u_short fin_group; /* group number, -1 for none */
+ struct frentry *fin_fr; /* last matching rule */
+ char *fin_dp; /* start of data past IP header */
+ u_short fin_dlen; /* length of data portion of packet */
+ u_short fin_id; /* IP packet id field */
+ void *fin_mp; /* pointer to pointer to mbuf */
+#if SOLARIS && defined(_KERNEL)
+ void *fin_qfm; /* pointer to mblk where pkt starts */
+ void *fin_qif;
+#endif
+} fr_info_t;
+
+/*
+ * Size for compares on fr_info structures
+ */
+#define FI_CSIZE offsetof(fr_info_t, fin_icode)
+
+/*
+ * Size for copying cache fr_info structure
+ */
+#define FI_COPYSIZE offsetof(fr_info_t, fin_dp)
+
+typedef struct frdest {
+ void *fd_ifp;
+ struct in_addr fd_ip;
+ char fd_ifname[IFNAMSIZ];
+} frdest_t;
+
+typedef struct frentry {
+ struct frentry *fr_next;
+ u_short fr_group; /* group to which this rule belongs */
+ u_short fr_grhead; /* group # which this rule starts */
+ struct frentry *fr_grp;
+ int fr_ref; /* reference count - for grouping */
+ void *fr_ifa;
+#if BSD >= 199306
+ void *fr_oifa;
+#endif
+ /*
+ * These are only incremented when a packet matches this rule and
+ * it is the last match
+ */
+ U_QUAD_T fr_hits;
+ U_QUAD_T fr_bytes;
+ /*
+ * Fields after this may not change whilst in the kernel.
+ */
+ struct fr_ip fr_ip;
+ struct fr_ip fr_mip; /* mask structure */
+
+ u_char fr_tcpfm; /* tcp flags mask */
+ u_char fr_tcpf; /* tcp flags */
+
+ u_short fr_icmpm; /* data for ICMP packets (mask) */
+ u_short fr_icmp;
+
+ u_char fr_scmp; /* data for port comparisons */
+ u_char fr_dcmp;
+ u_short fr_dport;
+ u_short fr_sport;
+ u_short fr_stop; /* top port for <> and >< */
+ u_short fr_dtop; /* top port for <> and >< */
+ u_32_t fr_flags; /* per-rule flags && options (see below) */
+ u_short fr_skip; /* # of rules to skip */
+ u_short fr_loglevel; /* syslog log facility + priority */
+ int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
+ char fr_icode; /* return ICMP code */
+ char fr_ifname[IFNAMSIZ];
+#if BSD >= 199306
+ char fr_oifname[IFNAMSIZ];
+#endif
+ struct frdest fr_tif; /* "to" interface */
+ struct frdest fr_dif; /* duplicate packet interfaces */
+} frentry_t;
+
+#define fr_proto fr_ip.fi_p
+#define fr_ttl fr_ip.fi_ttl
+#define fr_tos fr_ip.fi_tos
+#define fr_dst fr_ip.fi_dst
+#define fr_src fr_ip.fi_src
+#define fr_dmsk fr_mip.fi_dst
+#define fr_smsk fr_mip.fi_src
+
+#ifndef offsetof
+#define offsetof(t,m) (int)((&((t *)0L)->m))
+#endif
+#define FR_CMPSIZ (sizeof(struct frentry) - offsetof(frentry_t, fr_ip))
+
+/*
+ * fr_flags
+ */
+#define FR_BLOCK 0x00001 /* do not allow packet to pass */
+#define FR_PASS 0x00002 /* allow packet to pass */
+#define FR_OUTQUE 0x00004 /* outgoing packets */
+#define FR_INQUE 0x00008 /* ingoing packets */
+#define FR_LOG 0x00010 /* Log */
+#define FR_LOGB 0x00011 /* Log-fail */
+#define FR_LOGP 0x00012 /* Log-pass */
+#define FR_LOGBODY 0x00020 /* Log the body */
+#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
+#define FR_RETRST 0x00080 /* Return TCP RST packet - reset connection */
+#define FR_RETICMP 0x00100 /* Return ICMP unreachable packet */
+#define FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
+#define FR_NOMATCH 0x00200 /* no match occured */
+#define FR_ACCOUNT 0x00400 /* count packet bytes */
+#define FR_KEEPFRAG 0x00800 /* keep fragment information */
+#define FR_KEEPSTATE 0x01000 /* keep `connection' state information */
+#define FR_INACTIVE 0x02000
+#define FR_QUICK 0x04000 /* match & stop processing list */
+#define FR_FASTROUTE 0x08000 /* bypass normal routing */
+#define FR_CALLNOW 0x10000 /* call another function (fr_func) if matches */
+#define FR_DUP 0x20000 /* duplicate packet */
+#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
+#define FR_NOTSRCIP 0x80000 /* not the src IP# */
+#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
+#define FR_AUTH 0x200000 /* use authentication */
+#define FR_PREAUTH 0x400000 /* require preauthentication */
+#define FR_DONTCACHE 0x800000 /* don't cache the result */
+
+#define FR_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB)
+#define FR_RETMASK (FR_RETICMP|FR_RETRST|FR_FAKEICMP)
+
+/*
+ * These correspond to #define's for FI_* and are stored in fr_flags
+ */
+#define FF_OPTIONS 0x01000000
+#define FF_TCPUDP 0x02000000
+#define FF_FRAG 0x04000000
+#define FF_SHORT 0x08000000
+/*
+ * recognized flags for SIOCGETFF and SIOCSETFF, and get put in fr_flags
+ */
+#define FF_LOGPASS 0x10000000
+#define FF_LOGBLOCK 0x20000000
+#define FF_LOGNOMATCH 0x40000000
+#define FF_LOGGING (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH)
+#define FF_BLOCKNONIP 0x80000000 /* Solaris2 Only */
+
+#define FR_NONE 0
+#define FR_EQUAL 1
+#define FR_NEQUAL 2
+#define FR_LESST 3
+#define FR_GREATERT 4
+#define FR_LESSTE 5
+#define FR_GREATERTE 6
+#define FR_OUTRANGE 7
+#define FR_INRANGE 8
+
+typedef struct filterstats {
+ u_long fr_pass; /* packets allowed */
+ u_long fr_block; /* packets denied */
+ u_long fr_nom; /* packets which don't match any rule */
+ u_long fr_ppkl; /* packets allowed and logged */
+ u_long fr_bpkl; /* packets denied and logged */
+ u_long fr_npkl; /* packets unmatched and logged */
+ u_long fr_pkl; /* packets logged */
+ u_long fr_skip; /* packets to be logged but buffer full */
+ u_long fr_ret; /* packets for which a return is sent */
+ u_long fr_acct; /* packets for which counting was performed */
+ u_long fr_bnfr; /* bad attempts to allocate fragment state */
+ u_long fr_nfr; /* new fragment state kept */
+ u_long fr_cfr; /* add new fragment state but complete pkt */
+ u_long fr_bads; /* bad attempts to allocate packet state */
+ u_long fr_ads; /* new packet state kept */
+ u_long fr_chit; /* cached hit */
+ u_long fr_tcpbad; /* TCP checksum check failures */
+ u_long fr_pull[2]; /* good and bad pullup attempts */
+#if SOLARIS
+ u_long fr_notdata; /* PROTO/PCPROTO that have no data */
+ u_long fr_nodata; /* mblks that have no data */
+ u_long fr_bad; /* bad IP packets to the filter */
+ u_long fr_notip; /* packets passed through no on ip queue */
+ u_long fr_drop; /* packets dropped - no info for them! */
+#endif
+} filterstats_t;
+
+/*
+ * For SIOCGETFS
+ */
+typedef struct friostat {
+ struct filterstats f_st[2];
+ struct frentry *f_fin[2];
+ struct frentry *f_fout[2];
+ struct frentry *f_acctin[2];
+ struct frentry *f_acctout[2];
+ struct frentry *f_auth;
+ struct frgroup *f_groups[3][2];
+ u_long f_froute[2];
+ int f_active; /* 1 or 0 - active rule set */
+ int f_defpass; /* default pass - from fr_pass */
+ int f_running; /* 1 if running, else 0 */
+ int f_logging; /* 1 if enabled, else 0 */
+ char f_version[32]; /* version string */
+} friostat_t;
+
+typedef struct optlist {
+ u_short ol_val;
+ int ol_bit;
+} optlist_t;
+
+
+/*
+ * Group list structure.
+ */
+typedef struct frgroup {
+ u_short fg_num;
+ struct frgroup *fg_next;
+ struct frentry *fg_head;
+ struct frentry **fg_start;
+} frgroup_t;
+
+
+/*
+ * Log structure. Each packet header logged is prepended by one of these.
+ * Following this in the log records read from the device will be an ipflog
+ * structure which is then followed by any packet data.
+ */
+typedef struct iplog {
+ u_32_t ipl_magic;
+ u_int ipl_count;
+ u_long ipl_sec;
+ u_long ipl_usec;
+ size_t ipl_dsize;
+ struct iplog *ipl_next;
+} iplog_t;
+
+#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+
+typedef struct ipflog {
+#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ u_char fl_ifname[IFNAMSIZ];
+#else
+ u_int fl_unit;
+ u_char fl_ifname[4];
+#endif
+ u_char fl_plen; /* extra data after hlen */
+ u_char fl_hlen; /* length of IP headers saved */
+ u_short fl_rule; /* assume never more than 64k rules, total */
+ u_short fl_group;
+ u_short fl_loglevel; /* syslog log level */
+ u_32_t fl_flags;
+ u_32_t fl_lflags;
+} ipflog_t;
+
+
+#if !defined(__OpenBSD__)
+# ifndef ICMP_UNREACH_FILTER
+# define ICMP_UNREACH_FILTER 13
+# endif
+#endif
+
+#ifndef IPF_LOGGING
+# define IPF_LOGGING 0
+#endif
+#ifndef IPF_DEFAULT_PASS
+# define IPF_DEFAULT_PASS FR_PASS
+#endif
+
+#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
+#define IPLLOGSIZE 8192
+
+/*
+ * Device filenames for reading log information. Use ipf on Solaris2 because
+ * ipl is already a name used by something else.
+ */
+#ifndef IPL_NAME
+# if SOLARIS
+# define IPL_NAME "/dev/ipf"
+# else
+# define IPL_NAME "/dev/ipl"
+# endif
+#endif
+#define IPL_NAT IPNAT_NAME
+#define IPL_STATE IPSTATE_NAME
+#define IPL_AUTH IPAUTH_NAME
+
+#define IPL_LOGIPF 0 /* Minor device #'s for accessing logs */
+#define IPL_LOGNAT 1
+#define IPL_LOGSTATE 2
+#define IPL_LOGAUTH 3
+#define IPL_LOGMAX 3
+
+#if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \
+ (__FreeBSD_version >= 220000)
+# define CDEV_MAJOR 79
+#endif
+
+/*
+ * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
+ * on those hooks. We don't need any special mods in non-IP Filter code
+ * with this!
+ */
+#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
+ (defined(NetBSD1_2) && NetBSD1_2 > 1)
+# if (NetBSD >= 199905)
+# define PFIL_HOOKS
+# endif
+# ifdef PFIL_HOOKS
+# define NETBSD_PF
+# endif
+#endif
+
+
+#ifndef _KERNEL
+extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
+extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
+extern int send_reset __P((ip_t *, struct ifnet *));
+extern int icmp_error __P((ip_t *, struct ifnet *));
+extern int ipf_log __P((void));
+extern int ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
+extern struct ifnet *get_unit __P((char *));
+# if defined(__NetBSD__) || defined(__OpenBSD__) || \
+ (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
+extern int iplioctl __P((dev_t, u_long, caddr_t, int));
+# else
+extern int iplioctl __P((dev_t, int, caddr_t, int));
+# endif
+extern int iplopen __P((dev_t, int));
+extern int iplclose __P((dev_t, int));
+#else /* #ifndef _KERNEL */
+# if defined(__NetBSD__) && defined(PFIL_HOOKS)
+extern void ipfilterattach __P((int));
+# endif
+
+#if !defined(__OpenBSD__)
+/*
+ * OpenBSD has this call in the kernel but doesn't export it to userland.
+ * See ip_fil.c for actual hook and more details.
+ */
+extern int iplattach __P((void));
+#endif
+
+extern int ipl_enable __P((void));
+extern int ipl_disable __P((void));
+extern void ipflog_init __P((void));
+extern int ipflog_clear __P((minor_t));
+extern int ipflog_read __P((minor_t, struct uio *));
+extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
+extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
+# if SOLARIS
+extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **));
+extern int (*fr_checkp) __P((ip_t *, int, void *,
+ int, qif_t *, mb_t **));
+extern int icmp_error __P((ip_t *, int, int, qif_t *, struct in_addr));
+# if SOLARIS2 >= 7
+extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
+# else
+extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *));
+# endif
+extern int iplopen __P((dev_t *, int, int, cred_t *));
+extern int iplclose __P((dev_t, int, int, cred_t *));
+extern int ipfsync __P((void));
+extern int send_reset __P((fr_info_t *, ip_t *, qif_t *));
+extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **,
+ fr_info_t *, frdest_t *));
+extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *));
+extern void copyout_mblk __P((mblk_t *, size_t, size_t, char *));
+extern int fr_qin __P((queue_t *, mblk_t *));
+extern int fr_qout __P((queue_t *, mblk_t *));
+# ifdef IPFILTER_LOG
+extern int iplread __P((dev_t, struct uio *, cred_t *));
+# endif
+# else /* SOLARIS */
+extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
+extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
+# ifdef linux
+extern int send_reset __P((tcpiphdr_t *, struct ifnet *));
+# else
+extern int send_reset __P((fr_info_t *, struct ip *));
+extern int send_icmp_err __P((ip_t *, int, int, void *, struct in_addr));
+# endif
+extern int ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
+extern size_t mbufchainlen __P((mb_t *));
+# ifdef __sgi
+# include <sys/cred.h>
+extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *));
+extern int iplopen __P((dev_t *, int, int, cred_t *));
+extern int iplclose __P((dev_t, int, int, cred_t *));
+extern int iplread __P((dev_t, struct uio *, cred_t *));
+extern int ipfsync __P((void));
+extern int ipfilter_sgi_attach __P((void));
+extern void ipfilter_sgi_detach __P((void));
+extern void ipfilter_sgi_intfsync __P((void));
+# else
+# ifdef IPFILTER_LKM
+extern int iplidentify __P((char *));
+# endif
+# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
+ (NetBSD >= 199511) || defined(__OpenBSD__)
+# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \
+ defined(__OpenBSD__) || (__FreeBSD_version >= 300000)
+extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+# else
+extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
+# endif
+extern int iplopen __P((dev_t, int, int, struct proc *));
+extern int iplclose __P((dev_t, int, int, struct proc *));
+# else
+# ifndef linux
+extern int iplopen __P((dev_t, int));
+extern int iplclose __P((dev_t, int));
+extern int iplioctl __P((dev_t, int, caddr_t, int));
+# else
+extern int iplioctl(struct inode *, struct file *, u_int, u_long);
+extern int iplopen __P((struct inode *, struct file *));
+extern void iplclose __P((struct inode *, struct file *));
+# endif /* !linux */
+# endif /* (_BSDI_VERSION >= 199510) */
+# if BSD >= 199306
+extern int iplread __P((dev_t, struct uio *, int));
+# else
+# ifndef linux
+extern int iplread __P((dev_t, struct uio *));
+# else
+extern int iplread(struct inode *, struct file *, char *, int);
+# endif /* !linux */
+# endif /* BSD >= 199306 */
+# endif /* __ sgi */
+# endif /* SOLARIS */
+#endif /* #ifndef _KERNEL */
+
+extern void fixskip __P((frentry_t **, frentry_t *, int));
+extern int countbits __P((u_32_t));
+extern int ipldetach __P((void));
+extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
+extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
+extern u_short ipf_cksum __P((u_short *, int));
+extern int fr_copytolog __P((int, char *, int));
+extern void fr_forgetifp __P((void *));
+extern int frflush __P((minor_t, int));
+extern void frsync __P((void));
+extern frgroup_t *fr_addgroup __P((u_int, frentry_t *, minor_t, int));
+extern frgroup_t *fr_findgroup __P((u_int, u_32_t, minor_t, int, frgroup_t ***));
+extern void fr_delgroup __P((u_int, u_32_t, minor_t, int));
+extern void fr_makefrip __P((int, ip_t *, fr_info_t *));
+extern int fr_ifpaddr __P((void *, struct in_addr *));
+extern char *memstr __P((char *, char *, int, int));
+extern int ipl_unreach;
+extern int ipl_inited;
+extern u_long ipl_frouteok[2];
+extern int fr_pass;
+extern int fr_flags;
+extern int fr_active;
+extern fr_info_t frcache[2];
+extern char ipfilter_version[];
+#ifdef IPFILTER_LOG
+extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
+extern size_t iplused[IPL_LOGMAX + 1];
+#endif
+extern struct frentry *ipfilter[2][2], *ipacct[2][2];
+extern struct frgroup *ipfgroups[3][2];
+extern struct filterstats frstats[];
+
+#endif /* _NETINET_IP_FIL_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_fil_compat.h b/ecos/packages/net/tcpip/current/include/netinet/ip_fil_compat.h
new file mode 100644
index 0000000..e6f77cd
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_fil_compat.h
@@ -0,0 +1,865 @@
+//==========================================================================
+//
+// include/netinet/ip_compat.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_fil_compat.h,v 1.11 1999/12/15 05:20:21 kjell Exp $ */
+/*
+ * Copyright (C) 1993-1998 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * @(#)ip_compat.h 1.8 1/14/96
+ */
+
+#ifndef _NETINET_IP_COMPAT_H__
+#define _NETINET_IP_COMPAT_H__
+
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+#ifndef __STDC__
+# undef const
+# define const
+#endif
+
+#ifndef SOLARIS
+#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#endif
+
+#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
+# undef KERNEL
+# undef _KERNEL
+# undef __KERNEL__
+# define KERNEL
+# define _KERNEL
+# define __KERNEL__
+#endif
+
+#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
+#define index strchr
+# if !defined(KERNEL)
+# define bzero(a,b) memset(a,0,b)
+# define bcmp memcmp
+# define bcopy(a,b,c) memmove(b,a,c)
+# endif
+#endif
+
+#ifndef offsetof
+#define offsetof(t,m) (int)((&((t *)0L)->m))
+#endif
+
+#if defined(__sgi) || defined(bsdi)
+struct ether_addr {
+ u_char ether_addr_octet[6];
+};
+#endif
+
+#if defined(__sgi) && !defined(IPFILTER_LKM)
+# ifdef __STDC__
+# define IPL_EXTERN(ep) ipfilter##ep
+# else
+# define IPL_EXTERN(ep) ipfilter/**/ep
+# endif
+#else
+# ifdef __STDC__
+# define IPL_EXTERN(ep) ipl##ep
+# else
+# define IPL_EXTERN(ep) ipl/**/ep
+# endif
+#endif
+
+#ifdef linux
+# include <sys/sysmacros.h>
+#endif
+#if SOLARIS
+# define MTYPE(m) ((m)->b_datap->db_type)
+# include <sys/isa_defs.h>
+# include <sys/ioccom.h>
+# include <sys/sysmacros.h>
+# include <sys/kmem.h>
+/*
+ * because Solaris 2 defines these in two places :-/
+ */
+# undef IPOPT_EOL
+# undef IPOPT_NOP
+# undef IPOPT_LSRR
+# undef IPOPT_RR
+# undef IPOPT_SSRR
+# ifndef KERNEL
+# define _KERNEL
+# undef RES_INIT
+# include <inet/common.h>
+# include <inet/ip.h>
+# include <inet/ip_ire.h>
+# undef _KERNEL
+# else /* _KERNEL */
+# include <inet/common.h>
+# include <inet/ip.h>
+# include <inet/ip_ire.h>
+# endif /* _KERNEL */
+# if SOLARIS2 >= 8
+# include <netinet/ip6.h>
+# include <inet/ip6.h>
+# define ipif_local_addr ipif_lcl_addr
+# endif
+#else
+# if !defined(__sgi)
+typedef int minor_t;
+#endif
+#endif /* SOLARIS */
+#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
+
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+#if BSD > 199306
+# define USE_QUAD_T
+# define U_QUAD_T u_quad_t
+# define QUAD_T quad_t
+#else /* BSD > 199306 */
+# define U_QUAD_T u_long
+# define QUAD_T long
+#endif /* BSD > 199306 */
+
+/*
+ * These operating systems already take care of the problem for us.
+ */
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
+ defined(__sgi)
+typedef u_int32_t u_32_t;
+#else
+/*
+ * Really, any arch where sizeof(long) != sizeof(int).
+ */
+# if defined(__alpha__) || defined(__alpha) || defined(_LP64)
+typedef unsigned int u_32_t;
+# else
+typedef unsigned long u_32_t;
+# endif
+#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+/*
+ * Security Options for Intenet Protocol (IPSO) as defined in RFC 1108.
+ *
+ * Basic Option
+ *
+ * 00000001 - (Reserved 4)
+ * 00111101 - Top Secret
+ * 01011010 - Secret
+ * 10010110 - Confidential
+ * 01100110 - (Reserved 3)
+ * 11001100 - (Reserved 2)
+ * 10101011 - Unclassified
+ * 11110001 - (Reserved 1)
+ */
+#define IPSO_CLASS_RES4 0x01
+#define IPSO_CLASS_TOPS 0x3d
+#define IPSO_CLASS_SECR 0x5a
+#define IPSO_CLASS_CONF 0x96
+#define IPSO_CLASS_RES3 0x66
+#define IPSO_CLASS_RES2 0xcc
+#define IPSO_CLASS_UNCL 0xab
+#define IPSO_CLASS_RES1 0xf1
+
+#define IPSO_AUTH_GENSER 0x80
+#define IPSO_AUTH_ESI 0x40
+#define IPSO_AUTH_SCI 0x20
+#define IPSO_AUTH_NSA 0x10
+#define IPSO_AUTH_DOE 0x08
+#define IPSO_AUTH_UN 0x06
+#define IPSO_AUTH_FTE 0x01
+
+/*
+ * IP option #defines
+ */
+/*#define IPOPT_RR 7 */
+#define IPOPT_ZSU 10 /* ZSU */
+#define IPOPT_MTUP 11 /* MTUP */
+#define IPOPT_MTUR 12 /* MTUR */
+#define IPOPT_ENCODE 15 /* ENCODE */
+/*#define IPOPT_TS 68 */
+#define IPOPT_TR 82 /* TR */
+/*#define IPOPT_SECURITY 130 */
+/*#define IPOPT_LSRR 131 */
+#define IPOPT_E_SEC 133 /* E-SEC */
+#define IPOPT_CIPSO 134 /* CIPSO */
+/*#define IPOPT_SATID 136 */
+#ifndef IPOPT_SID
+# define IPOPT_SID IPOPT_SATID
+#endif
+/*#define IPOPT_SSRR 137 */
+#define IPOPT_ADDEXT 147 /* ADDEXT */
+#define IPOPT_VISA 142 /* VISA */
+#define IPOPT_IMITD 144 /* IMITD */
+#define IPOPT_EIP 145 /* EIP */
+#define IPOPT_FINN 205 /* FINN */
+
+
+#if defined(__FreeBSD__) && defined(KERNEL)
+# if __FreeBSD__ < 3
+# include <machine/spl.h>
+# endif
+# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
+# define ACTUALLY_LKM_NOT_KERNEL
+# endif
+#endif /* __FreeBSD__ && KERNEL */
+
+/*
+ * Build some macros and #defines to enable the same code to compile anywhere
+ * Well, that's the idea, anyway :-)
+ */
+#ifdef KERNEL
+# if SOLARIS
+# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
+ mutex_exit(&ipf_rw); }
+# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
+ mutex_exit(&ipf_rw); }
+# define MUTEX_ENTER(x) mutex_enter(x)
+# if 1
+# define KRWLOCK_T krwlock_t
+# define READ_ENTER(x) rw_enter(x, RW_READER)
+# define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
+# define RW_UPGRADE(x) { if (rw_tryupgrade(x) == 0) { \
+ rw_exit(x); \
+ rw_enter(x, RW_WRITER); } \
+ }
+# define MUTEX_DOWNGRADE(x) rw_downgrade(x)
+# define RWLOCK_INIT(x, y, z) rw_init((x), (y), RW_DRIVER, (z))
+# define RWLOCK_EXIT(x) rw_exit(x)
+# define RW_DESTROY(x) rw_destroy(x)
+# else
+# define KRWLOCK_T kmutex_t
+# define READ_ENTER(x) mutex_enter(x)
+# define WRITE_ENTER(x) mutex_enter(x)
+# define MUTEX_DOWNGRADE(x) ;
+# define RWLOCK_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
+# define RWLOCK_EXIT(x) mutex_exit(x)
+# define RW_DESTROY(x) mutex_destroy(x)
+# endif
+# define MUTEX_EXIT(x) mutex_exit(x)
+# define MTOD(m,t) (t)((m)->b_rptr)
+# define IRCOPY(a,b,c) copyin((a), (b), (c))
+# define IWCOPY(a,b,c) copyout((a), (b), (c))
+# define FREE_MB_T(m) freemsg(m)
+# define SPL_NET(x) ;
+# define SPL_IMP(x) ;
+# undef SPL_X
+# define SPL_X(x) ;
+# ifdef sparc
+# define ntohs(x) (x)
+# define ntohl(x) (x)
+# define htons(x) (x)
+# define htonl(x) (x)
+# endif /* sparc */
+# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
+# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
+# define GET_MINOR(x) getminor(x)
+typedef struct qif {
+ struct qif *qf_next;
+ ill_t *qf_ill;
+ kmutex_t qf_lock;
+ void *qf_iptr;
+ void *qf_optr;
+ queue_t *qf_in;
+ queue_t *qf_out;
+ struct qinit *qf_wqinfo;
+ struct qinit *qf_rqinfo;
+ struct qinit qf_wqinit;
+ struct qinit qf_rqinit;
+ mblk_t *qf_m; /* These three fields are for passing data up from */
+ queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
+ size_t qf_off;
+ size_t qf_len; /* this field is used for in ipfr_fastroute */
+ char qf_name[8];
+ /*
+ * in case the ILL has disappeared...
+ */
+ size_t qf_hl; /* header length */
+} qif_t;
+extern ill_t *get_unit __P((char *));
+# define GETUNIT(n) get_unit((n))
+# else /* SOLARIS */
+# if defined(__sgi)
+# define hz HZ
+# include <sys/ksynch.h>
+# define IPF_LOCK_PL plhi
+# include <sys/sema.h>
+#undef kmutex_t
+typedef struct {
+ lock_t *l;
+ int pl;
+} kmutex_t;
+# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
+ (x)++; MUTEX_EXIT(&ipf_rw); }
+# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
+ (x)--; MUTEX_EXIT(&ipf_rw); }
+# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
+# define KRWLOCK_T kmutex_t
+# define READ_ENTER(x) MUTEX_ENTER(x)
+# define WRITE_ENTER(x) MUTEX_ENTER(x)
+# define RW_UPGRADE(x) ;
+# define MUTEX_DOWNGRADE(x) ;
+# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
+# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
+# else /* __sgi */
+# define ATOMIC_INC(x) (x)++
+# define ATOMIC_DEC(x) (x)--
+# define MUTEX_ENTER(x) ;
+# define READ_ENTER(x) ;
+# define WRITE_ENTER(x) ;
+# define RW_UPGRADE(x) ;
+# define MUTEX_DOWNGRADE(x) ;
+# define RWLOCK_EXIT(x) ;
+# define MUTEX_EXIT(x) ;
+# endif /* __sgi */
+# ifndef linux
+# define FREE_MB_T(m) m_freem(m)
+# define MTOD(m,t) mtod(m,t)
+# define IRCOPY(a,b,c) bcopy((a), (b), (c))
+# define IWCOPY(a,b,c) bcopy((a), (b), (c))
+# endif /* !linux */
+# endif /* SOLARIS */
+
+# ifdef sun
+# if !SOLARIS
+# include <sys/kmem_alloc.h>
+# define GETUNIT(n) ifunit((n), IFNAMSIZ)
+# endif
+# else
+# ifndef linux
+# define GETUNIT(n) ifunit((n))
+# endif
+# endif /* sun */
+
+# if defined(sun) && !defined(linux) || defined(__sgi)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
+# define SLEEP(id, n) sleep((id), PZERO+1)
+# define WAKEUP(id) wakeup(id)
+# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
+# define KFREES(x,s) kmem_free((char *)(x), (s))
+# if !SOLARIS
+extern void m_copydata __P((struct mbuf *, int, int, caddr_t));
+extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
+# endif
+# ifdef __sgi
+# include <sys/kmem.h>
+# include <sys/ddi.h>
+# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
+# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
+# define GET_MINOR(x) getminor(x)
+# else
+# if !SOLARIS
+# define KMALLOC(a,b) (a) = (b)new_kmem_alloc(sizeof(*(a)), \
+ KMEM_NOSLEEP)
+# define KMALLOCS(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP)
+# endif /* SOLARIS */
+# endif /* __sgi */
+# endif /* sun && !linux */
+# ifndef GET_MINOR
+# define GET_MINOR(x) minor(x)
+# endif
+# if (BSD >= 199306) || defined(__FreeBSD__)
+# include <vm/vm.h>
+# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
+# include <vm/vm_extern.h>
+# include <sys/proc.h>
+extern vm_map_t kmem_map;
+# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
+# include <vm/vm_kern.h>
+# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
+# ifdef M_PFIL
+# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFIL, M_NOWAIT)
+# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
+# define KFREE(x) FREE((x), M_PFIL)
+# define KFREES(x,s) FREE((x), M_PFIL)
+# else
+# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT)
+# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
+# define KFREE(x) FREE((x), M_TEMP)
+# define KFREES(x,s) FREE((x), M_TEMP)
+# endif /* M_PFIL */
+# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
+# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
+# define WAKEUP(id) wakeup(id)
+# endif /* BSD */
+# if defined(NetBSD) && NetBSD <= 1991011 && NetBSD >= 199407
+# define SPL_NET(x) x = splsoftnet()
+# define SPL_X(x) (void) splx(x)
+# else
+# if !SOLARIS && !defined(linux)
+# define SPL_IMP(x) x = splimp()
+# define SPL_NET(x) x = splnet()
+# define SPL_X(x) (void) splx(x)
+# endif
+# endif /* NetBSD && NetBSD <= 1991011 && NetBSD >= 199407 */
+# define PANIC(x,y) if (x) panic y
+#else /* KERNEL */
+# define SLEEP(x,y) ;
+# define WAKEUP(x) ;
+# define PANIC(x,y) ;
+# define ATOMIC_INC(x) (x)++
+# define ATOMIC_DEC(x) (x)--
+# define MUTEX_ENTER(x) ;
+# define READ_ENTER(x) ;
+# define WRITE_ENTER(x) ;
+# define RW_UPGRADE(x) ;
+# define MUTEX_DOWNGRADE(x) ;
+# define RWLOCK_EXIT(x) ;
+# define MUTEX_EXIT(x) ;
+# define SPL_NET(x) ;
+# define SPL_IMP(x) ;
+# undef SPL_X
+# define SPL_X(x) ;
+# define KMALLOC(a,b) (a) = (b)malloc(sizeof(*a))
+# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
+# define KFREE(x) free(x)
+# define KFREES(x,s) free(x)
+# define GETUNIT(x) get_unit(x)
+# define IRCOPY(a,b,c) bcopy((a), (b), (c))
+# define IWCOPY(a,b,c) bcopy((a), (b), (c))
+#endif /* KERNEL */
+
+#if SOLARIS
+typedef mblk_t mb_t;
+# if SOLARIS2 >= 7
+# ifdef lint
+# define ALIGN32(ptr) (ptr ? 0L : 0L)
+# define ALIGN16(ptr) (ptr ? 0L : 0L)
+# else
+# define ALIGN32(ptr) (ptr)
+# define ALIGN16(ptr) (ptr)
+# endif
+# endif
+#else
+# ifdef linux
+# ifndef kernel
+typedef struct mb {
+ struct mb *next;
+ u_int len;
+ u_char *data;
+} mb_t;
+# else
+typedef struct sk_buff mb_t;
+# endif
+# else
+typedef struct mbuf mb_t;
+# endif
+#endif /* SOLARIS */
+
+#if defined(linux) || defined(__sgi)
+/*
+ * These #ifdef's are here mainly for linux, but who knows, they may
+ * not be in other places or maybe one day linux will grow up and some
+ * of these will turn up there too.
+ */
+#ifndef ICMP_MINLEN
+# define ICMP_MINLEN 8
+#endif
+#ifndef ICMP_UNREACH
+# define ICMP_UNREACH ICMP_DEST_UNREACH
+#endif
+#ifndef ICMP_SOURCEQUENCH
+# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
+#endif
+#ifndef ICMP_TIMXCEED
+# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
+#endif
+#ifndef ICMP_PARAMPROB
+# define ICMP_PARAMPROB ICMP_PARAMETERPROB
+#endif
+#ifndef ICMP_TSTAMP
+# define ICMP_TSTAMP ICMP_TIMESTAMP
+#endif
+#ifndef ICMP_TSTAMPREPLY
+# define ICMP_TSTAMPREPLY ICMP_TIMESTAMPREPLY
+#endif
+#ifndef ICMP_IREQ
+# define ICMP_IREQ ICMP_INFO_REQUEST
+#endif
+#ifndef ICMP_IREQREPLY
+# define ICMP_IREQREPLY ICMP_INFO_REPLY
+#endif
+#ifndef ICMP_MASKREQ
+# define ICMP_MASKREQ ICMP_ADDRESS
+#endif
+#ifndef ICMP_MASKREPLY
+# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
+#endif
+#ifndef IPVERSION
+# define IPVERSION 4
+#endif
+#ifndef IPOPT_MINOFF
+# define IPOPT_MINOFF 4
+#endif
+#ifndef IPOPT_COPIED
+# define IPOPT_COPIED(x) ((x)&0x80)
+#endif
+#ifndef IPOPT_EOL
+# define IPOPT_EOL 0
+#endif
+#ifndef IPOPT_NOP
+# define IPOPT_NOP 1
+#endif
+#ifndef IP_MF
+# define IP_MF ((u_short)0x2000)
+#endif
+#ifndef ETHERTYPE_IP
+# define ETHERTYPE_IP ((u_short)0x0800)
+#endif
+#ifndef TH_FIN
+# define TH_FIN 0x01
+#endif
+#ifndef TH_SYN
+# define TH_SYN 0x02
+#endif
+#ifndef TH_RST
+# define TH_RST 0x04
+#endif
+#ifndef TH_PUSH
+# define TH_PUSH 0x08
+#endif
+#ifndef TH_ACK
+# define TH_ACK 0x10
+#endif
+#ifndef TH_URG
+# define TH_URG 0x20
+#endif
+#ifndef IPOPT_EOL
+# define IPOPT_EOL 0
+#endif
+#ifndef IPOPT_NOP
+# define IPOPT_NOP 1
+#endif
+#ifndef IPOPT_RR
+# define IPOPT_RR 7
+#endif
+#ifndef IPOPT_TS
+# define IPOPT_TS 68
+#endif
+#ifndef IPOPT_SECURITY
+# define IPOPT_SECURITY 130
+#endif
+#ifndef IPOPT_LSRR
+# define IPOPT_LSRR 131
+#endif
+#ifndef IPOPT_SATID
+# define IPOPT_SATID 136
+#endif
+#ifndef IPOPT_SSRR
+# define IPOPT_SSRR 137
+#endif
+#ifndef IPOPT_SECUR_UNCLASS
+# define IPOPT_SECUR_UNCLASS ((u_short)0x0000)
+#endif
+#ifndef IPOPT_SECUR_CONFID
+# define IPOPT_SECUR_CONFID ((u_short)0xf135)
+#endif
+#ifndef IPOPT_SECUR_EFTO
+# define IPOPT_SECUR_EFTO ((u_short)0x789a)
+#endif
+#ifndef IPOPT_SECUR_MMMM
+# define IPOPT_SECUR_MMMM ((u_short)0xbc4d)
+#endif
+#ifndef IPOPT_SECUR_RESTR
+# define IPOPT_SECUR_RESTR ((u_short)0xaf13)
+#endif
+#ifndef IPOPT_SECUR_SECRET
+# define IPOPT_SECUR_SECRET ((u_short)0xd788)
+#endif
+#ifndef IPOPT_SECUR_TOPSECRET
+# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5)
+#endif
+#ifndef IPOPT_OLEN
+# define IPOPT_OLEN 1
+#endif
+#endif /* linux || __sgi */
+
+#ifdef linux
+#include <linux/in_systm.h>
+/*
+ * TCP States
+ */
+#define TCPS_CLOSED 0 /* closed */
+#define TCPS_LISTEN 1 /* listening for connection */
+#define TCPS_SYN_SENT 2 /* active, have sent syn */
+#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
+/* states < TCPS_ESTABLISHED are those where connections not established */
+#define TCPS_ESTABLISHED 4 /* established */
+#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
+/* states > TCPS_CLOSE_WAIT are those where user has closed */
+#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
+#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
+#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
+/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
+#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
+#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
+
+/*
+ * file flags.
+ */
+#ifdef WRITE
+#define FWRITE WRITE
+#define FREAD READ
+#else
+#define FWRITE _IOC_WRITE
+#define FREAD _IOC_READ
+#endif
+/*
+ * mbuf related problems.
+ */
+#define mtod(m,t) (t)((m)->data)
+#define m_len len
+#define m_next next
+
+#ifdef IP_DF
+#undef IP_DF
+#endif
+#define IP_DF 0x4000
+
+typedef struct {
+ __u16 th_sport;
+ __u16 th_dport;
+ __u32 th_seq;
+ __u32 th_ack;
+# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
+ defined(vax)
+ __u8 th_res:4;
+ __u8 th_off:4;
+#else
+ __u8 th_off:4;
+ __u8 th_res:4;
+#endif
+ __u8 th_flags;
+ __u16 th_win;
+ __u16 th_sum;
+ __u16 th_urp;
+} tcphdr_t;
+
+typedef struct {
+ __u16 uh_sport;
+ __u16 uh_dport;
+ __u16 uh_ulen;
+ __u16 uh_sum;
+} udphdr_t;
+
+typedef struct {
+# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
+ defined(vax)
+ __u8 ip_hl:4;
+ __u8 ip_v:4;
+# else
+ __u8 ip_v:4;
+ __u8 ip_hl:4;
+# endif
+ __u8 ip_tos;
+ __u16 ip_len;
+ __u16 ip_id;
+ __u16 ip_off;
+ __u8 ip_ttl;
+ __u8 ip_p;
+ __u16 ip_sum;
+ struct in_addr ip_src;
+ struct in_addr ip_dst;
+} ip_t;
+
+/*
+ * Structure of an icmp header.
+ */
+typedef struct icmp {
+ __u8 icmp_type; /* type of message, see below */
+ __u8 icmp_code; /* type sub code */
+ __u16 icmp_cksum; /* ones complement cksum of struct */
+ union {
+ __u8 ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
+ struct ih_idseq {
+ __u16 icd_id;
+ __u16 icd_seq;
+ } ih_idseq;
+ int ih_void;
+ } icmp_hun;
+# define icmp_pptr icmp_hun.ih_pptr
+# define icmp_gwaddr icmp_hun.ih_gwaddr
+# define icmp_id icmp_hun.ih_idseq.icd_id
+# define icmp_seq icmp_hun.ih_idseq.icd_seq
+# define icmp_void icmp_hun.ih_void
+ union {
+ struct id_ts {
+ n_time its_otime;
+ n_time its_rtime;
+ n_time its_ttime;
+ } id_ts;
+ struct id_ip {
+ ip_t idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ u_long id_mask;
+ char id_data[1];
+ } icmp_dun;
+# define icmp_otime icmp_dun.id_ts.its_otime
+# define icmp_rtime icmp_dun.id_ts.its_rtime
+# define icmp_ttime icmp_dun.id_ts.its_ttime
+# define icmp_ip icmp_dun.id_ip.idi_ip
+# define icmp_mask icmp_dun.id_mask
+# define icmp_data icmp_dun.id_data
+} icmphdr_t;
+
+# ifndef LINUX_IPOVLY
+# define LINUX_IPOVLY
+struct ipovly {
+ caddr_t ih_next, ih_prev; /* for protocol sequence q's */
+ u_char ih_x1; /* (unused) */
+ u_char ih_pr; /* protocol */
+ short ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+# endif
+
+typedef struct {
+ __u8 ether_dhost[6];
+ __u8 ether_shost[6];
+ __u16 ether_type;
+} ether_header_t;
+
+typedef struct uio {
+ int uio_resid;
+ int uio_rw;
+ caddr_t uio_buf;
+} uio_t;
+
+# define UIO_READ 0
+# define UIO_WRITE 1
+# define UIOMOVE(a, b, c, d) uiomove(a,b,c,d)
+
+/*
+ * For masking struct ifnet onto struct device
+ */
+# define if_name name
+
+# ifdef KERNEL
+# define GETUNIT(x) dev_get(x)
+# define FREE_MB_T(m) kfree_skb(m, FREE_WRITE)
+# define uniqtime do_gettimeofday
+# undef INT_MAX
+# undef UINT_MAX
+# undef LONG_MAX
+# undef ULONG_MAX
+# include <linux/netdevice.h>
+# define SPL_X(x)
+# define SPL_NET(x)
+# define SPL_IMP(x)
+
+# define bcmp(a,b,c) memcmp(a,b,c)
+# define bcopy(a,b,c) memcpy(b,a,c)
+# define bzero(a,c) memset(a,0,c)
+
+# define UNITNAME(n) dev_get((n))
+
+# define KMALLOC(a,b) (a) = (b)kmalloc(sizeof(*(a)), GFP_ATOMIC)
+# define KMALLOCS(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
+# define KFREE(x) kfree_s((x), sizeof(*(x)))
+# define KFREES(x,s) kfree_s((x), (s))
+# define IRCOPY(a,b,c) { \
+ error = verify_area(VERIFY_READ, (a) ,(c)); \
+ if (!error) \
+ memcpy_fromfs((b), (a), (c)); \
+ }
+# define IWCOPY(a,b,c) { \
+ error = verify_area(VERIFY_WRITE, (b), (c)); \
+ if (!error) \
+ memcpy_tofs((b), (a), (c)); \
+ }
+# else
+# define __KERNEL__
+# undef INT_MAX
+# undef UINT_MAX
+# undef LONG_MAX
+# undef ULONG_MAX
+# define s8 __s8
+# define u8 __u8
+# define s16 __s16
+# define u16 __u16
+# define s32 __s32
+# define u32 __u32
+# include <linux/netdevice.h>
+# undef __KERNEL__
+# endif
+# define ifnet device
+#else
+typedef struct tcphdr tcphdr_t;
+typedef struct udphdr udphdr_t;
+typedef struct icmp icmphdr_t;
+typedef struct ip ip_t;
+typedef struct ether_header ether_header_t;
+#endif /* linux */
+typedef struct tcpiphdr tcpiphdr_t;
+
+#if defined(hpux) || defined(linux)
+struct ether_addr {
+ char ether_addr_octet[6];
+};
+#endif
+
+/*
+ * XXX - This is one of those *awful* hacks which nobody likes
+ */
+#ifdef ultrix
+#define A_A
+#else
+#define A_A &
+#endif
+
+#ifndef ICMP_ROUTERADVERT
+# define ICMP_ROUTERADVERT 9
+#endif
+#ifndef ICMP_ROUTERSOLICIT
+# define ICMP_ROUTERSOLICIT 10
+#endif
+/*
+ * ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data,
+ * another IP header and then 64 bits of data, totalling 56. Of course,
+ * the last 64 bits is dependant on that being available.
+ */
+#define ICMPERR_ICMPHLEN 8
+#define ICMPERR_IPICMPHLEN (20 + 8)
+#define ICMPERR_MINPKTLEN (20 + 8 + 20)
+#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
+
+#endif /* _NETINET_IP_COMPAT_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_frag.h b/ecos/packages/net/tcpip/current/include/netinet/ip_frag.h
new file mode 100644
index 0000000..c61df9d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_frag.h
@@ -0,0 +1,92 @@
+//==========================================================================
+//
+// include/netinet/ip_fil.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_frag.h,v 1.9 1999/12/15 05:20:22 kjell Exp $ */
+/*
+ * Copyright (C) 1993-1998 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * @(#)ip_frag.h 1.5 3/24/96
+ */
+
+#ifndef _NETINET_IP_FRAG_H__
+#define _NETINET_IP_FRAG_H__
+
+#define IPFT_SIZE 257
+
+typedef struct ipfr {
+ struct ipfr *ipfr_next, *ipfr_prev;
+ void *ipfr_data;
+ struct in_addr ipfr_src;
+ struct in_addr ipfr_dst;
+ u_short ipfr_id;
+ u_char ipfr_p;
+ u_char ipfr_tos;
+ u_short ipfr_off;
+ u_short ipfr_ttl;
+ frentry_t *ipfr_rule;
+} ipfr_t;
+
+
+typedef struct ipfrstat {
+ u_long ifs_exists; /* add & already exists */
+ u_long ifs_nomem;
+ u_long ifs_new;
+ u_long ifs_hits;
+ u_long ifs_expire;
+ u_long ifs_inuse;
+ struct ipfr **ifs_table;
+ struct ipfr **ifs_nattab;
+} ipfrstat_t;
+
+#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
+
+extern int fr_ipfrttl;
+extern ipfrstat_t *ipfr_fragstats __P((void));
+extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int));
+extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *));
+extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
+extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *));
+extern void ipfr_forget __P((void *));
+extern void ipfr_unload __P((void));
+
+#if (BSD >= 199306) || SOLARIS || defined(__sgi)
+# if defined(SOLARIS2) && (SOLARIS2 < 7)
+extern void ipfr_slowtimer __P((void));
+# else
+extern void ipfr_slowtimer __P((void *));
+# endif
+#else
+extern int ipfr_slowtimer __P((void));
+#endif
+
+#endif /* _NETINET_IP_FIL_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_icmp.h b/ecos/packages/net/tcpip/current/include/netinet/ip_icmp.h
new file mode 100644
index 0000000..fd92260
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_icmp.h
@@ -0,0 +1,223 @@
+//==========================================================================
+//
+// include/netinet/ip_icmp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_icmp.h,v 1.9 1999/01/07 09:20:17 deraadt Exp $ */
+/* $NetBSD: ip_icmp.h,v 1.10 1996/02/13 23:42:28 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP_ICMP_H_
+#define _NETINET_IP_ICMP_H_
+
+/*
+ * Interface Control Message Protocol Definitions.
+ * Per RFC 792, September 1981.
+ */
+
+/*
+ * ICMP Router Advertisement data
+ */
+struct icmp_ra_addr {
+ n_long ira_addr;
+ n_long ira_preference;
+} __attribute__ ((aligned(1), packed));
+
+/*
+ * Structure of an icmp header.
+ */
+struct icmp {
+ u_int8_t icmp_type; /* type of message, see below */
+ u_int8_t icmp_code; /* type sub code */
+ u_int16_t icmp_cksum; /* ones complement cksum of struct */
+ union {
+ u_int8_t ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
+ struct ih_idseq {
+ n_short icd_id;
+ n_short icd_seq;
+ } ih_idseq;
+ int32_t ih_void;
+
+ /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
+ struct ih_pmtu {
+ n_short ipm_void;
+ n_short ipm_nextmtu;
+ } ih_pmtu;
+
+ struct ih_rtradv {
+ u_int8_t irt_num_addrs;
+ u_int8_t irt_wpa;
+ n_short irt_lifetime;
+ } ih_rtradv;
+ } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
+ union {
+ struct id_ts {
+ n_time its_otime;
+ n_time its_rtime;
+ n_time its_ttime;
+ } id_ts;
+ struct id_ip {
+ struct ip idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ u_int32_t id_mask;
+ int8_t id_data[1];
+ } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+} __attribute__ ((aligned(1), packed));
+
+/*
+ * For IPv6 transition related ICMP errors.
+ */
+#define ICMP_V6ADVLENMIN (8 + sizeof(struct ip) + 40)
+#define ICMP_V6ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 40)
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enought to contain the returned ip header.
+ * Only then can we do the check to see if 64 bits of packet
+ * data have been returned, since we need to check the returned
+ * ip header length.
+ */
+#define ICMP_MINLEN 8 /* abs minimum */
+#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
+#define ICMP_MASKLEN 12 /* address mask */
+#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
+#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+ /* N.B.: must separately check that ip_hl >= 5 */
+
+/*
+ * Definition of type and code field values.
+ */
+#define ICMP_ECHOREPLY 0 /* echo reply */
+#define ICMP_UNREACH 3 /* dest unreachable, codes: */
+#define ICMP_UNREACH_NET 0 /* bad net */
+#define ICMP_UNREACH_HOST 1 /* bad host */
+#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
+#define ICMP_UNREACH_PORT 3 /* bad port */
+#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
+#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
+#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
+#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
+#define ICMP_UNREACH_NET_PROHIB 9 /* for crypto devs */
+#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
+#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
+#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
+#define ICMP_UNREACH_FILTER_PROHIB 13 /* prohibited access */
+#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* precedence violat'n*/
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
+#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+#define ICMP_REDIRECT 5 /* shorter route, codes: */
+#define ICMP_REDIRECT_NET 0 /* for network */
+#define ICMP_REDIRECT_HOST 1 /* for host */
+#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
+#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+#define ICMP_ECHO 8 /* echo service */
+#define ICMP_ROUTERADVERT 9 /* router advertisement */
+#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
+#define ICMP_TIMXCEED 11 /* time exceeded, code: */
+#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
+#define ICMP_TSTAMP 13 /* timestamp request */
+#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
+#define ICMP_IREQ 15 /* information request */
+#define ICMP_IREQREPLY 16 /* information reply */
+#define ICMP_MASKREQ 17 /* address mask request */
+#define ICMP_MASKREPLY 18 /* address mask reply */
+
+#define ICMP_MAXTYPE 18
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#ifdef _KERNEL
+void icmp_error __P((struct mbuf *, int, int, n_long, struct ifnet *));
+void icmp_input __P((struct mbuf *, ...));
+void icmp_reflect __P((struct mbuf *));
+void icmp_send __P((struct mbuf *, struct mbuf *));
+int icmp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+#endif
+
+#endif // _NETINET_IP_ICMP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_ip4.h b/ecos/packages/net/tcpip/current/include/netinet/ip_ip4.h
new file mode 100644
index 0000000..c5ab059
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_ip4.h
@@ -0,0 +1,110 @@
+//==========================================================================
+//
+// include/netinet/ip_ip4.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_ip4.h,v 1.16 1999/12/09 09:02:59 angelos Exp $ */
+
+/*
+ * The authors of this code are John Ioannidis (ji@tla.org),
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Niels Provos (provos@physnet.uni-hamburg.de).
+ *
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Additional features in 1999 by Angelos D. Keromytis.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
+ * Angelos D. Keromytis and Niels Provos.
+ *
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef _NETINET_IP_IP4_H_
+#define _NETINET_IP_IP4_H_
+
+/*
+ * IP-inside-IP processing.
+ * Not quite all the functionality of RFC-1853, but the main idea is there.
+ */
+
+struct ip4stat
+{
+ u_int32_t ip4s_ipackets; /* total input packets */
+ u_int32_t ip4s_opackets; /* total output packets */
+ u_int32_t ip4s_hdrops; /* packet shorter than header shows */
+ u_int32_t ip4s_qfull;
+ u_int64_t ip4s_ibytes;
+ u_int64_t ip4s_obytes;
+ u_int32_t ip4s_pdrops; /* packet dropped due to policy */
+ u_int32_t ip4s_spoof; /* IP spoofing attempts */
+ u_int32_t ip4s_family; /* Protocol family mismatch */
+ u_int32_t ip4s_unspec; /* Missing tunnel endpoint address */
+};
+
+#define IP4_DEFAULT_TTL 0
+#define IP4_SAME_TTL -1
+
+/*
+ * Names for IP4 sysctl objects
+ */
+#define IP4CTL_ALLOW 1 /* accept incoming IP4 packets */
+#define IP4CTL_MAXID 2
+
+#define IP4CTL_NAMES { \
+ { 0, 0 }, \
+ { "allow", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+int ip4_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+
+extern int ip4_allow;
+extern struct ip4stat ip4stat;
+#endif
+
+#endif // _NETINET_IP_IP4_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_ipsp.h b/ecos/packages/net/tcpip/current/include/netinet/ip_ipsp.h
new file mode 100644
index 0000000..98f1e4f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_ipsp.h
@@ -0,0 +1,600 @@
+//==========================================================================
+//
+// include/netinet/ipsp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_ipsp.h,v 1.50 1999/12/08 12:10:25 angelos Exp $ */
+
+/*
+ * The authors of this code are John Ioannidis (ji@tla.org),
+ * Angelos D. Keromytis (kermit@csd.uch.gr),
+ * Niels Provos (provos@physnet.uni-hamburg.de) and
+ * Niklas Hallqvist (niklas@appli.se).
+ *
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
+ *
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
+ * Angelos D. Keromytis and Niels Provos.
+ * Copyright (c) 1999 Niklas Hallqvist.
+ *
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef _NETINET_IPSP_H_
+#define _NETINET_IPSP_H_
+
+/*
+ * IPSP global definitions.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+#ifndef __ECOS
+#include <sys/md5k.h>
+#endif
+#include <netinet/ip_sha1.h>
+#include <netinet/ip_rmd160.h>
+#include <netinet/ip_blf.h>
+#include <netinet/ip_cast.h>
+#include <netinet/ip_skipjack.h>
+
+union sockaddr_union
+{
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+};
+
+/* HMAC key sizes */
+#define MD5HMAC96_KEYSIZE 16
+#define SHA1HMAC96_KEYSIZE 20
+#define RIPEMD160HMAC96_KEYSIZE 20
+
+/* IV lengths */
+#define ESP_DES_IVS 8
+#define ESP_3DES_IVS 8
+#define ESP_BLF_IVS 8
+#define ESP_CAST_IVS 8
+#define ESP_SKIPJACK_IVS 8
+#define ESP_MAX_IVS 8 /* Keep updated */
+
+/* Block sizes -- it is assumed that they're powers of 2 */
+#define ESP_DES_BLKS 8
+#define ESP_3DES_BLKS 8
+#define ESP_BLF_BLKS 8
+#define ESP_CAST_BLKS 8
+#define ESP_SKIPJACK_BLKS 8
+#define ESP_MAX_BLKS 8 /* Keep updated */
+
+#define HMAC_BLOCK_LEN 64
+
+#define AH_HMAC_HASHLEN 12 /* 96 bits of authenticator */
+#define AH_HMAC_RPLENGTH 4 /* 32 bits of replay counter */
+#define AH_HMAC_INITIAL_RPL 1 /* Replay counter initial value */
+
+/* HMAC definitions */
+#define HMAC_IPAD_VAL 0x36
+#define HMAC_OPAD_VAL 0x5C
+#define HMAC_BLOCK_LEN 64
+
+/* Authenticator lengths */
+#define AH_MD5_ALEN 16
+#define AH_SHA1_ALEN 20
+#define AH_RMD160_ALEN 20
+#define AH_ALEN_MAX 20 /* Keep updated */
+
+/* Reserved SPI numbers */
+#define SPI_LOCAL_USE 0
+#define SPI_RESERVED_MIN 1
+#define SPI_RESERVED_MAX 255
+
+struct sockaddr_encap
+{
+ u_int8_t sen_len; /* length */
+ u_int8_t sen_family; /* PF_KEY */
+ u_int16_t sen_type; /* see SENT_* */
+ union
+ {
+ u_int8_t Data[16]; /* other stuff mapped here */
+
+ struct /* SENT_IP4 */
+ {
+ struct in_addr Src;
+ struct in_addr Dst;
+ u_int16_t Sport;
+ u_int16_t Dport;
+ u_int8_t Proto;
+ u_int8_t Filler[3];
+ } Sip4;
+
+ struct /* SENT_IP6 */
+ {
+ struct in6_addr Src;
+ struct in6_addr Dst;
+ u_int16_t Sport;
+ u_int16_t Dport;
+ u_int8_t Proto;
+ u_int8_t Filler[3];
+ } Sip6;
+
+ struct /* SENT_IPSP */
+ {
+ struct in_addr Dst;
+ u_int32_t Spi;
+ u_int8_t Sproto;
+ u_int8_t Filler[7];
+ } Sipsp;
+
+ struct /* SENT_IPSP6 */
+ {
+ struct in6_addr Dst;
+ u_int32_t Spi;
+ u_int8_t Sproto;
+ u_int8_t Filler[7];
+ } Sipsp6;
+ } Sen;
+};
+
+#define sen_data Sen.Data
+#define sen_ip_src Sen.Sip4.Src
+#define sen_ip_dst Sen.Sip4.Dst
+#define sen_proto Sen.Sip4.Proto
+#define sen_sport Sen.Sip4.Sport
+#define sen_dport Sen.Sip4.Dport
+#define sen_ip6_src Sen.Sip6.Src
+#define sen_ip6_dst Sen.Sip6.Dst
+#define sen_ip6_proto Sen.Sip6.Proto
+#define sen_ip6_sport Sen.Sip6.Sport
+#define sen_ip6_dport Sen.Sip6.Dport
+#define sen_ipsp_dst Sen.Sipsp.Dst
+#define sen_ipsp_spi Sen.Sipsp.Spi
+#define sen_ipsp_sproto Sen.Sipsp.Sproto
+#define sen_ipsp6_dst Sen.Sipsp6.Dst
+#define sen_ipsp6_spi Sen.Sipsp6.Spi
+#define sen_ipsp6_sproto Sen.Sipsp6.Sproto
+
+/*
+ * The "type" is really part of the address as far as the routing
+ * system is concerned. By using only one bit in the type field
+ * for each type, we sort-of make sure that different types of
+ * encapsulation addresses won't be matched against the wrong type.
+ *
+ */
+
+#define SENT_IP4 0x0001 /* data is two struct in_addr */
+#define SENT_IPSP 0x0002 /* data as in IP4/6 plus SPI */
+#define SENT_IP6 0x0004
+#define SENT_IPSP6 0x0008
+
+/*
+ * SENT_HDRLEN is the length of the "header"
+ * SENT_*_LEN are the lengths of various forms of sen_data
+ * SENT_*_OFF are the offsets in the sen_data array of various fields
+ */
+
+#define SENT_HDRLEN (2 * sizeof(u_int8_t) + sizeof(u_int16_t))
+
+#define SENT_IP4_SRCOFF (0)
+#define SENT_IP4_DSTOFF (sizeof (struct in_addr))
+
+#define SENT_IP6_SRCOFF (0)
+#define SENT_IP6_DSTOFF (sizeof (struct in6_addr))
+
+#define SENT_IP4_LEN 20
+#define SENT_IPSP_LEN 20
+#define SENT_IP6_LEN 44
+#define SENT_IPSP6_LEN 32
+
+#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
+#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
+#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
+
+#define NOTIFY_SATYPE_CONF 1 /* SA should do encryption */
+#define NOTIFY_SATYPE_AUTH 2 /* SA should do authentication */
+#define NOTIFY_SATYPE_TUNNEL 4 /* SA should use tunneling */
+
+/*
+ * For encapsulation routes are possible not only for the destination
+ * address but also for the protocol, source and destination ports
+ * if available
+ */
+
+struct route_enc {
+ struct rtentry *re_rt;
+ struct sockaddr_encap re_dst;
+};
+
+struct flow
+{
+ struct flow *flow_next; /* Next in flow chain */
+ struct flow *flow_prev; /* Previous in flow chain */
+ struct tdb *flow_sa; /* Pointer to the SA */
+ union sockaddr_union flow_src; /* Source address */
+ union sockaddr_union flow_srcmask; /* Source netmask */
+ union sockaddr_union flow_dst; /* Destination address */
+ union sockaddr_union flow_dstmask; /* Destination netmask */
+ u_int8_t flow_proto; /* Transport protocol, if applicable */
+ u_int8_t foo[3]; /* Alignment */
+};
+
+struct tdb /* tunnel descriptor block */
+{
+ struct tdb *tdb_hnext; /* Next in hash chain */
+ struct tdb *tdb_onext; /* Next in output */
+ struct tdb *tdb_inext; /* Previous in output */
+
+ struct xformsw *tdb_xform; /* Transformation to use */
+ struct enc_xform *tdb_encalgxform; /* Encryption algorithm xform */
+ struct auth_hash *tdb_authalgxform; /* Authentication algorithm xform */
+
+#define TDBF_UNIQUE 0x00001 /* This should not be used by others */
+#define TDBF_TIMER 0x00002 /* Absolute expiration timer in use */
+#define TDBF_BYTES 0x00004 /* Check the byte counters */
+#define TDBF_ALLOCATIONS 0x00008 /* Check the flows counters */
+#define TDBF_INVALID 0x00010 /* This SPI is not valid yet/anymore */
+#define TDBF_FIRSTUSE 0x00020 /* Expire after first use */
+#define TDBF_HALFIV 0x00040 /* Use half-length IV (ESP old only) */
+#define TDBF_SOFT_TIMER 0x00080 /* Soft expiration */
+#define TDBF_SOFT_BYTES 0x00100 /* Soft expiration */
+#define TDBF_SOFT_ALLOCATIONS 0x00200 /* Soft expiration */
+#define TDBF_SOFT_FIRSTUSE 0x00400 /* Soft expiration */
+#define TDBF_PFS 0x00800 /* Ask for PFS from Key Mgmt. */
+#define TDBF_TUNNELING 0x01000 /* Force IP-IP encapsulation */
+ u_int32_t tdb_flags; /* Flags related to this TDB */
+
+ TAILQ_ENTRY(tdb) tdb_expnext; /* Expiration cluster list link */
+ TAILQ_ENTRY(tdb) tdb_explink; /* Expiration ordered list link */
+
+ u_int32_t tdb_exp_allocations; /* Expire after so many flows */
+ u_int32_t tdb_soft_allocations; /* Expiration warning */
+ u_int32_t tdb_cur_allocations; /* Total number of allocations */
+
+ u_int64_t tdb_exp_bytes; /* Expire after so many bytes passed */
+ u_int64_t tdb_soft_bytes; /* Expiration warning */
+ u_int64_t tdb_cur_bytes; /* Current count of bytes */
+
+ u_int64_t tdb_exp_timeout; /* When does the SPI expire */
+ u_int64_t tdb_soft_timeout; /* Send a soft-expire warning */
+ u_int64_t tdb_established; /* When was the SPI established */
+ u_int64_t tdb_timeout; /* Next absolute expiration time. */
+
+ u_int64_t tdb_first_use; /* When was it first used */
+ u_int64_t tdb_soft_first_use; /* Soft warning */
+ u_int64_t tdb_exp_first_use; /* Expire if tdb_first_use +
+ * tdb_exp_first_use <= curtime */
+
+ u_int32_t tdb_spi; /* SPI */
+ u_int16_t tdb_amxkeylen; /* AH-old only */
+ u_int16_t tdb_ivlen; /* IV length */
+ u_int8_t tdb_sproto; /* IPsec protocol */
+ u_int8_t tdb_wnd; /* Replay window */
+ u_int8_t tdb_satype; /* SA type (RFC2367, PF_KEY) */
+ u_int8_t tdb_FILLER; /* Padding */
+
+ union sockaddr_union tdb_dst; /* Destination address for this SA */
+ union sockaddr_union tdb_src; /* Source address for this SA */
+ union sockaddr_union tdb_proxy;
+
+ u_int8_t *tdb_key; /* Key material (schedules) */
+ u_int8_t *tdb_ictx; /* Authentication contexts */
+ u_int8_t *tdb_octx;
+ u_int8_t *tdb_srcid; /* Source ID for this SA */
+ u_int8_t *tdb_dstid; /* Destination ID for this SA */
+ u_int8_t *tdb_amxkey; /* AH-old only */
+
+ union
+ {
+ u_int8_t Iv[ESP_3DES_IVS]; /* That's enough space */
+ u_int32_t Ivl; /* Make sure this is 4 bytes */
+ u_int64_t Ivq; /* Make sure this is 8 bytes! */
+ }IV;
+#define tdb_iv IV.Iv
+#define tdb_ivl IV.Ivl
+#define tdb_ivq IV.Ivq
+
+ u_int32_t tdb_rpl; /* Replay counter */
+ u_int32_t tdb_bitmap; /* Used for replay sliding window */
+ u_int32_t tdb_initial; /* Initial replay value */
+
+ u_int32_t tdb_epoch; /* Used by the kernfs interface */
+ u_int16_t tdb_srcid_len;
+ u_int16_t tdb_dstid_len;
+ u_int16_t tdb_srcid_type;
+ u_int16_t tdb_dstid_type;
+
+ caddr_t tdb_interface;
+ struct flow *tdb_flow; /* Which flows use this SA */
+
+ struct tdb *tdb_bind_out; /* Outgoing SA to use */
+ TAILQ_HEAD(tdb_bind_head, tdb) tdb_bind_in;
+ TAILQ_ENTRY(tdb) tdb_bind_in_next; /* Refering Incoming SAs */
+ TAILQ_HEAD(tdb_inp_head, inpcb) tdb_inp;
+};
+
+#ifndef __ECOS
+union authctx_old {
+ MD5_CTX md5ctx;
+ SHA1_CTX sha1ctx;
+};
+
+union authctx {
+ MD5_CTX md5ctx;
+ SHA1_CTX sha1ctx;
+ RMD160_CTX rmd160ctx;
+};
+#endif
+
+struct tdb_ident {
+ u_int32_t spi;
+ union sockaddr_union dst;
+ u_int8_t proto;
+};
+
+struct auth_hash {
+ int type;
+ char *name;
+ u_int16_t keysize;
+ u_int16_t hashsize;
+ u_int16_t ctxsize;
+ void (*Init)(void *);
+ void (*Update)(void *, u_int8_t *, u_int16_t);
+ void (*Final)(u_int8_t *, void *);
+};
+
+struct enc_xform {
+ int type;
+ char *name;
+ u_int16_t blocksize, ivsize;
+ u_int16_t minkey, maxkey;
+ u_int32_t ivmask; /* Or all possible modes, zero iv = 1 */
+ void (*encrypt)(struct tdb *, u_int8_t *);
+ void (*decrypt)(struct tdb *, u_int8_t *);
+ void (*setkey)(u_int8_t **, u_int8_t *, int len);
+ void (*zerokey)(u_int8_t **);
+};
+
+struct ipsecinit
+{
+ u_int8_t *ii_enckey;
+ u_int8_t *ii_authkey;
+ u_int16_t ii_enckeylen;
+ u_int16_t ii_authkeylen;
+ u_int8_t ii_encalg;
+ u_int8_t ii_authalg;
+};
+
+struct xformsw
+{
+ u_short xf_type; /* Unique ID of xform */
+ u_short xf_flags; /* flags (see below) */
+ char *xf_name; /* human-readable name */
+ int (*xf_attach)(void); /* called at config time */
+ int (*xf_init)(struct tdb *, struct xformsw *, struct ipsecinit *);
+ int (*xf_zeroize)(struct tdb *); /* termination */
+ struct mbuf *(*xf_input)(struct mbuf *, struct tdb *, int, int); /* input */
+ int (*xf_output)(struct mbuf *, struct tdb *, struct mbuf **, int, int); /* output */
+};
+
+/* xform IDs */
+#define XF_IP4 1 /* IP inside IP */
+#define XF_OLD_AH 2 /* RFCs 1828 & 1852 */
+#define XF_OLD_ESP 3 /* RFCs 1829 & 1851 */
+#define XF_NEW_AH 4 /* AH HMAC 96bits */
+#define XF_NEW_ESP 5 /* ESP + auth 96bits + replay counter */
+#define XF_TCPSIGNATURE 6 /* TCP MD5 Signature option, RFC 2358 */
+
+/* xform attributes */
+#define XFT_AUTH 0x0001
+#define XFT_CONF 0x0100
+
+#define IPSEC_ZEROES_SIZE 256 /* Larger than an IP6 extension hdr. */
+#define IPSEC_KERNFS_BUFSIZE 4096
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+static __inline u_int64_t
+htonq(u_int64_t q)
+{
+ register u_int32_t u, l;
+ u = q >> 32;
+ l = (u_int32_t) q;
+
+ return htonl(u) | ((u_int64_t)htonl(l) << 32);
+}
+
+#define ntohq(_x) htonq(_x)
+
+#elif BYTE_ORDER == BIG_ENDIAN
+
+#define htonq(_x) (_x)
+#define ntohq(_x) htonq(_x)
+
+#else
+#error "Please fix <machine/endian.h>"
+#endif
+
+#ifdef _KERNEL
+
+/*
+ * Protects all tdb lists.
+ * Must at least be splsoftnet (note: do not use splsoftclock as it is
+ * special on some architectures, assuming it is always an spl lowering
+ * operation).
+ */
+#define spltdb splsoftnet
+
+extern int encdebug;
+extern int ipsec_in_use;
+extern u_int8_t hmac_ipad_buffer[64];
+extern u_int8_t hmac_opad_buffer[64];
+
+extern TAILQ_HEAD(expclusterlist_head, tdb) expclusterlist;
+extern TAILQ_HEAD(explist_head, tdb) explist;
+extern struct xformsw xformsw[], *xformswNXFORMSW;
+
+/* Check if a given tdb has encryption, authentication and/or tunneling */
+#define TDB_ATTRIB(x) (((x)->tdb_encalgxform ? NOTIFY_SATYPE_CONF : 0)| \
+ ((x)->tdb_authalgxform ? NOTIFY_SATYPE_AUTH : 0))
+
+/* Traverse spi chain and get attributes */
+
+#define SPI_CHAIN_ATTRIB(have, TDB_DIR, TDBP) do {\
+ int s = spltdb(); \
+ struct tdb *tmptdb = (TDBP); \
+ \
+ (have) = 0; \
+ while (tmptdb && tmptdb->tdb_xform) { \
+ if (tmptdb == NULL || tmptdb->tdb_flags & TDBF_INVALID) \
+ break; \
+ (have) |= TDB_ATTRIB(tmptdb); \
+ tmptdb = tmptdb->TDB_DIR; \
+ } \
+ splx(s); \
+} while (0)
+
+/* Misc. */
+extern char *inet_ntoa4(struct in_addr);
+
+#ifdef INET6
+extern char *inet6_ntoa4(struct in6_addr);
+#endif /* INET6 */
+
+extern char *ipsp_address(union sockaddr_union);
+
+/* TDB management routines */
+extern void tdb_add_inp(struct tdb *tdb, struct inpcb *inp);
+extern u_int32_t reserve_spi(u_int32_t, u_int32_t, union sockaddr_union *,
+ union sockaddr_union *, u_int8_t, int *);
+extern struct tdb *gettdb(u_int32_t, union sockaddr_union *, u_int8_t);
+extern void puttdb(struct tdb *);
+extern void tdb_delete(struct tdb *, int, int);
+extern int tdb_init(struct tdb *, u_int16_t, struct ipsecinit *);
+extern void tdb_expiration(struct tdb *, int);
+/* Flag values for the last argument of tdb_expiration(). */
+#define TDBEXP_EARLY 1 /* The tdb is likely to end up early. */
+#define TDBEXP_TIMEOUT 2 /* Maintain expiration timeout. */
+extern int tdb_walk(int (*)(struct tdb *, void *), void *);
+extern void handle_expirations(void *);
+
+/* Flow management routines */
+extern struct flow *get_flow(void);
+extern void put_flow(struct flow *, struct tdb *);
+extern void delete_flow(struct flow *, struct tdb *);
+extern struct flow *find_flow(union sockaddr_union *, union sockaddr_union *,
+ union sockaddr_union *, union sockaddr_union *,
+ u_int8_t, struct tdb *);
+extern struct flow *find_global_flow(union sockaddr_union *,
+ union sockaddr_union *,
+ union sockaddr_union *,
+ union sockaddr_union *, u_int8_t);
+
+/* XF_IP4 */
+extern int ipe4_attach(void);
+extern int ipe4_init(struct tdb *, struct xformsw *, struct ipsecinit *);
+extern int ipe4_zeroize(struct tdb *);
+extern int ipe4_output(struct mbuf *, struct tdb *, struct mbuf **, int, int);
+extern void ipe4_input __P((struct mbuf *, ...));
+extern void ip4_input __P((struct mbuf *, ...));
+
+/* XF_ETHERIP */
+extern int etherip_output(struct mbuf *, struct tdb *, struct mbuf **,
+ int, int);
+extern void etherip_input __P((struct mbuf *, ...));
+
+/* XF_OLD_AH */
+extern int ah_old_attach(void);
+extern int ah_old_init(struct tdb *, struct xformsw *, struct ipsecinit *);
+extern int ah_old_zeroize(struct tdb *);
+extern int ah_old_output(struct mbuf *, struct tdb *, struct mbuf **,
+ int, int);
+extern struct mbuf *ah_old_input(struct mbuf *, struct tdb *, int, int);
+
+/* XF_NEW_AH */
+extern int ah_new_attach(void);
+extern int ah_new_init(struct tdb *, struct xformsw *, struct ipsecinit *);
+extern int ah_new_zeroize(struct tdb *);
+extern int ah_new_output(struct mbuf *, struct tdb *, struct mbuf **,
+ int, int);
+extern struct mbuf *ah_new_input(struct mbuf *, struct tdb *, int, int);
+
+/* XF_OLD_ESP */
+extern int esp_old_attach(void);
+extern int esp_old_init(struct tdb *, struct xformsw *, struct ipsecinit *);
+extern int esp_old_zeroize(struct tdb *);
+extern int esp_old_output(struct mbuf *, struct tdb *, struct mbuf **,
+ int, int);
+extern struct mbuf *esp_old_input(struct mbuf *, struct tdb *, int, int);
+
+/* XF_NEW_ESP */
+extern int esp_new_attach(void);
+extern int esp_new_init(struct tdb *, struct xformsw *, struct ipsecinit *);
+extern int esp_new_zeroize(struct tdb *);
+extern int esp_new_output(struct mbuf *, struct tdb *, struct mbuf **,
+ int, int);
+extern struct mbuf *esp_new_input(struct mbuf *, struct tdb *, int, int);
+
+/* XF_TCPSIGNATURE */
+extern int tcp_signature_tdb_attach __P((void));
+extern int tcp_signature_tdb_init __P((struct tdb *, struct xformsw *,
+ struct ipsecinit *));
+extern int tcp_signature_tdb_zeroize __P((struct tdb *));
+extern struct mbuf *tcp_signature_tdb_input __P((struct mbuf *, struct tdb *));
+extern int tcp_signature_tdb_output __P((struct mbuf *, struct tdb *,
+ struct mbuf **));
+
+/* Padding */
+extern caddr_t m_pad(struct mbuf *, int, int);
+
+/* Replay window */
+extern int checkreplaywindow32(u_int32_t, u_int32_t, u_int32_t *, u_int32_t,
+ u_int32_t *);
+
+extern unsigned char ipseczeroes[];
+#endif /* _KERNEL */
+#endif /* _NETINET_IPSP_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_mroute.h b/ecos/packages/net/tcpip/current/include/netinet/ip_mroute.h
new file mode 100644
index 0000000..19edf20
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_mroute.h
@@ -0,0 +1,269 @@
+//==========================================================================
+//
+// include/netinet/ip_mroute.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_mroute.h,v 1.5 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: ip_mroute.h,v 1.10 1996/02/13 23:42:55 christos Exp $ */
+
+/*
+ * Definitions for IP multicast forwarding.
+ *
+ * Written by David Waitzman, BBN Labs, August 1988.
+ * Modified by Steve Deering, Stanford, February 1989.
+ * Modified by Ajit Thyagarajan, PARC, August 1993.
+ * Modified by Ajit Thyagarajan, PARC, August 1994.
+ *
+ * MROUTING Revision: 1.2
+ */
+
+#ifndef _NETINET_IP_MROUTE_H_
+#define _NETINET_IP_MROUTE_H_
+
+#include <sys/queue.h>
+
+/*
+ * Multicast Routing set/getsockopt commands.
+ */
+#define MRT_INIT 100 /* initialize forwarder */
+#define MRT_DONE 101 /* shut down forwarder */
+#define MRT_ADD_VIF 102 /* create virtual interface */
+#define MRT_DEL_VIF 103 /* delete virtual interface */
+#define MRT_ADD_MFC 104 /* insert forwarding cache entry */
+#define MRT_DEL_MFC 105 /* delete forwarding cache entry */
+#define MRT_VERSION 106 /* get kernel version number */
+#define MRT_ASSERT 107 /* enable PIM assert processing */
+
+
+/*
+ * Types and macros for handling bitmaps with one bit per virtual interface.
+ */
+#define MAXVIFS 32
+typedef u_int32_t vifbitmap_t;
+typedef u_int16_t vifi_t; /* type of a vif index */
+
+#define VIFM_SET(n, m) ((m) |= (1 << (n)))
+#define VIFM_CLR(n, m) ((m) &= ~(1 << (n)))
+#define VIFM_ISSET(n, m) ((m) & (1 << (n)))
+#define VIFM_SETALL(m) ((m) = 0xffffffff)
+#define VIFM_CLRALL(m) ((m) = 0x00000000)
+#define VIFM_COPY(mfrom, mto) ((mto) = (mfrom))
+#define VIFM_SAME(m1, m2) ((m1) == (m2))
+
+#define VIFF_TUNNEL 0x1 /* vif represents a tunnel end-point */
+#define VIFF_SRCRT 0x2 /* tunnel uses IP src routing */
+
+/*
+ * Argument structure for MRT_ADD_VIF.
+ * (MRT_DEL_VIF takes a single vifi_t argument.)
+ */
+struct vifctl {
+ vifi_t vifc_vifi; /* the index of the vif to be added */
+ u_int8_t vifc_flags; /* VIFF_ flags defined below */
+ u_int8_t vifc_threshold; /* min ttl required to forward on vif */
+ u_int32_t vifc_rate_limit; /* max rate */
+ struct in_addr vifc_lcl_addr;/* local interface address */
+ struct in_addr vifc_rmt_addr;/* remote address (tunnels only) */
+};
+
+/*
+ * Argument structure for MRT_ADD_MFC and MRT_DEL_MFC.
+ * (mfcc_tos to be added at a future point)
+ */
+struct mfcctl {
+ struct in_addr mfcc_origin; /* ip origin of mcasts */
+ struct in_addr mfcc_mcastgrp; /* multicast group associated */
+ vifi_t mfcc_parent; /* incoming vif */
+ u_int8_t mfcc_ttls[MAXVIFS]; /* forwarding ttls on vifs */
+};
+
+/*
+ * Argument structure used by mrouted to get src-grp pkt counts.
+ */
+struct sioc_sg_req {
+ struct in_addr src;
+ struct in_addr grp;
+ u_long pktcnt;
+ u_long bytecnt;
+ u_long wrong_if;
+};
+
+/*
+ * Argument structure used by mrouted to get vif pkt counts.
+ */
+struct sioc_vif_req {
+ vifi_t vifi; /* vif number */
+ u_long icount; /* input packet count on vif */
+ u_long ocount; /* output packet count on vif */
+ u_long ibytes; /* input byte count on vif */
+ u_long obytes; /* output byte count on vif */
+};
+
+
+/*
+ * The kernel's multicast routing statistics.
+ */
+struct mrtstat {
+ u_long mrts_mfc_lookups; /* # forw. cache hash table hits */
+ u_long mrts_mfc_misses; /* # forw. cache hash table misses */
+ u_long mrts_upcalls; /* # calls to mrouted */
+ u_long mrts_no_route; /* no route for packet's origin */
+ u_long mrts_bad_tunnel; /* malformed tunnel options */
+ u_long mrts_cant_tunnel; /* no room for tunnel options */
+ u_long mrts_wrong_if; /* arrived on wrong interface */
+ u_long mrts_upq_ovflw; /* upcall Q overflow */
+ u_long mrts_cache_cleanups; /* # entries with no upcalls */
+ u_long mrts_drop_sel; /* pkts dropped selectively */
+ u_long mrts_q_overflow; /* pkts dropped - Q overflow */
+ u_long mrts_pkt2large; /* pkts dropped - size > BKT SIZE */
+ u_long mrts_upq_sockfull; /* upcalls dropped - socket full */
+};
+
+
+#ifdef _KERNEL
+
+/*
+ * Token bucket filter at each vif
+ */
+struct tbf {
+ u_int32_t last_pkt_t; /* arr. time of last pkt */
+ u_int32_t n_tok; /* no of tokens in bucket */
+ u_int32_t q_len; /* length of queue at this vif */
+};
+
+/*
+ * The kernel's virtual-interface structure.
+ */
+struct vif {
+ u_int8_t v_flags; /* VIFF_ flags defined above */
+ u_int8_t v_threshold; /* min ttl required to forward on vif */
+ u_int32_t v_rate_limit; /* max rate */
+ struct tbf v_tbf; /* token bucket structure at intf. */
+ struct in_addr v_lcl_addr; /* local interface address */
+ struct in_addr v_rmt_addr; /* remote address (tunnels only) */
+ struct ifnet *v_ifp; /* pointer to interface */
+ u_long v_pkt_in; /* # pkts in on interface */
+ u_long v_pkt_out; /* # pkts out on interface */
+ u_long v_bytes_in; /* # bytes in on interface */
+ u_long v_bytes_out; /* # bytes out on interface */
+ struct route v_route; /* cached route if this is a tunnel */
+#ifdef RSVP_ISI
+ int v_rsvp_on; /* # RSVP listening on this vif */
+ struct socket *v_rsvpd; /* # RSVPD daemon */
+#endif /* RSVP_ISI */
+};
+
+/*
+ * The kernel's multicast forwarding cache entry structure.
+ * (A field for the type of service (mfc_tos) is to be added
+ * at a future point.)
+ */
+struct mfc {
+ LIST_ENTRY(mfc) mfc_hash;
+ struct in_addr mfc_origin; /* ip origin of mcasts */
+ struct in_addr mfc_mcastgrp; /* multicast group associated */
+ vifi_t mfc_parent; /* incoming vif */
+ u_int8_t mfc_ttls[MAXVIFS]; /* forwarding ttls on vifs */
+ u_long mfc_pkt_cnt; /* pkt count for src-grp */
+ u_long mfc_byte_cnt; /* byte count for src-grp */
+ u_long mfc_wrong_if; /* wrong if for src-grp */
+ int mfc_expire; /* time to clean entry up */
+ struct timeval mfc_last_assert; /* last time I sent an assert */
+ struct rtdetq *mfc_stall; /* pkts waiting for route */
+};
+
+/*
+ * Structure used to communicate from kernel to multicast router.
+ * (Note the convenient similarity to an IP packet.)
+ */
+struct igmpmsg {
+ u_int32_t unused1;
+ u_int32_t unused2;
+ u_int8_t im_msgtype; /* what type of message */
+#define IGMPMSG_NOCACHE 1
+#define IGMPMSG_WRONGVIF 2
+ u_int8_t im_mbz; /* must be zero */
+ u_int8_t im_vif; /* vif rec'd on */
+ u_int8_t unused3;
+ struct in_addr im_src, im_dst;
+};
+
+/*
+ * Argument structure used for pkt info. while upcall is made.
+ */
+struct rtdetq {
+ struct mbuf *m; /* a copy of the packet */
+ struct ifnet *ifp; /* interface pkt came in on */
+#ifdef UPCALL_TIMING
+ struct timeval t; /* timestamp */
+#endif /* UPCALL_TIMING */
+ struct rtdetq *next;
+};
+
+#define MFCTBLSIZ 256
+#define MAX_UPQ 4 /* max. no of pkts in upcall Q */
+
+/*
+ * Token bucket filter code
+ */
+#define MAX_BKT_SIZE 10000 /* 10K bytes size */
+#define MAXQSIZE 10 /* max. no of pkts in token queue */
+
+/*
+ * Queue structure at each vif
+ */
+struct pkt_queue {
+ u_int32_t pkt_len; /* length of packet in queue */
+ struct mbuf *pkt_m; /* pointer to packet mbuf */
+ struct ip *pkt_ip; /* pointer to ip header */
+};
+
+int ip_mrouter_set __P((int, struct socket *, struct mbuf **));
+int ip_mrouter_get __P((int, struct socket *, struct mbuf **));
+int mrt_ioctl __P((u_long, caddr_t));
+int ip_mrouter_done __P((void));
+void reset_vif __P((struct vif *));
+void vif_delete __P((struct ifnet *));
+#ifdef RSVP_ISI
+int ip_mforward __P((struct mbuf *, struct ifnet *, struct ip_moptions *));
+int legal_vif_num __P((int));
+int ip_rsvp_vif_init __P((struct socket *, struct mbuf *));
+int ip_rsvp_vif_done __P((struct socket *, struct mbuf *));
+void ip_rsvp_force_done __P((struct socket *));
+#if 0
+void rsvp_input __P((struct mbuf *, struct ifnet *));
+#else
+void rsvp_input __P((struct mbuf *, int, int));
+#endif
+#else
+int ip_mforward __P((struct mbuf *, struct ifnet *));
+#endif
+void ipip_input __P((struct mbuf *, ...));
+
+#endif /* _KERNEL */
+
+#endif // _NETINET_IP_MROUTE_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_nat.h b/ecos/packages/net/tcpip/current/include/netinet/ip_nat.h
new file mode 100644
index 0000000..3afc4a9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_nat.h
@@ -0,0 +1,277 @@
+//==========================================================================
+//
+// include/netinet/ip_nat.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_nat.h,v 1.13 1999/12/15 05:20:22 kjell Exp $ */
+/*
+ * Copyright (C) 1995-1998 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * @(#)ip_nat.h 1.5 2/4/96
+ */
+
+#ifndef _NETINET_IP_NAT_H__
+#define _NETINET_IP_NAT_H__
+
+#ifndef SOLARIS
+#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#endif
+
+#if defined(__STDC__) || defined(__GNUC__)
+#define SIOCADNAT _IOW('r', 80, struct ipnat)
+#define SIOCRMNAT _IOW('r', 81, struct ipnat)
+#define SIOCGNATS _IOR('r', 82, struct natstat)
+#define SIOCGNATL _IOWR('r', 83, struct natlookup)
+#define SIOCGFRST _IOR('r', 84, struct ipfrstat)
+#define SIOCGIPST _IOR('r', 85, struct ips_stat)
+#define SIOCFLNAT _IOWR('r', 86, int)
+#define SIOCCNATL _IOWR('r', 87, int)
+#else
+#define SIOCADNAT _IOW(r, 80, struct ipnat)
+#define SIOCRMNAT _IOW(r, 81, struct ipnat)
+#define SIOCGNATS _IOR(r, 82, struct natstat)
+#define SIOCGNATL _IOWR(r, 83, struct natlookup)
+#define SIOCGFRST _IOR(r, 84, struct ipfrstat)
+#define SIOCGIPST _IOR(r, 85, struct ips_stat)
+#define SIOCFLNAT _IOWR(r, 86, int)
+#define SIOCCNATL _IOWR(r, 87, int)
+#endif
+
+#undef LARGE_NAT /* define this if you're setting up a system to NAT
+ * LARGE numbers of networks/hosts - i.e. in the
+ * hundreds or thousands. In such a case, you should
+ * also change the RDR_SIZE and NAT_SIZE below to more
+ * appropriate sizes. The figures below were used for
+ * a setup with 1000-2000 networks to NAT.
+ */
+#define NAT_SIZE 127
+#define RDR_SIZE 127
+#define NAT_TABLE_SZ 127
+#ifdef LARGE_NAT
+#undef NAT_SIZE
+#undef RDR_SIZE
+#undef NAT_TABLE_SZ
+#define NAT_SIZE 2047
+#define RDR_SIZE 2047
+#define NAT_TABLE_SZ 16383
+#endif
+#ifndef APR_LABELLEN
+#define APR_LABELLEN 16
+#endif
+#define NAT_HW_CKSUM 0x80000000
+
+#define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */
+
+typedef struct nat {
+ u_long nat_age;
+ int nat_flags;
+ u_32_t nat_sumd[2];
+ u_32_t nat_ipsumd;
+ void *nat_data;
+ void *nat_aps; /* proxy session */
+ frentry_t *nat_fr; /* filter rule ptr if appropriate */
+ struct in_addr nat_inip;
+ struct in_addr nat_outip;
+ struct in_addr nat_oip; /* other ip */
+ U_QUAD_T nat_pkts;
+ U_QUAD_T nat_bytes;
+ u_short nat_oport; /* other port */
+ u_short nat_inport;
+ u_short nat_outport;
+ u_short nat_use;
+ u_char nat_tcpstate[2];
+ u_char nat_p; /* protocol for NAT */
+ struct ipnat *nat_ptr; /* pointer back to the rule */
+ struct nat *nat_next;
+ struct nat *nat_hnext[2];
+ struct nat **nat_hstart[2];
+ void *nat_ifp;
+ int nat_dir;
+} nat_t;
+
+typedef struct ipnat {
+ struct ipnat *in_next;
+ struct ipnat *in_rnext;
+ struct ipnat *in_mnext;
+ void *in_ifp;
+ void *in_apr;
+ u_long in_space;
+ u_int in_use;
+ u_int in_hits;
+ struct in_addr in_nextip;
+ u_short in_pnext;
+ u_short in_ppip; /* ports per IP */
+ u_short in_ippip; /* IP #'s per IP# */
+ u_short in_flags; /* From here to in_dport must be reflected */
+ u_short in_port[2]; /* correctly in IPN_CMPSIZ */
+ struct in_addr in_in[2];
+ struct in_addr in_out[2];
+ struct in_addr in_src[2];
+ int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
+ char in_ifname[IFNAMSIZ];
+ char in_plabel[APR_LABELLEN]; /* proxy label */
+ char in_p; /* protocol */
+ u_short in_dport;
+} ipnat_t;
+
+#define in_pmin in_port[0] /* Also holds static redir port */
+#define in_pmax in_port[1]
+#define in_nip in_nextip.s_addr
+#define in_inip in_in[0].s_addr
+#define in_inmsk in_in[1].s_addr
+#define in_outip in_out[0].s_addr
+#define in_outmsk in_out[1].s_addr
+#define in_srcip in_src[0].s_addr
+#define in_srcmsk in_src[1].s_addr
+
+#define NAT_OUTBOUND 0
+#define NAT_INBOUND 1
+
+#define NAT_MAP 0x01
+#define NAT_REDIRECT 0x02
+#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
+#define NAT_MAPBLK 0x04
+
+#define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */
+#define USABLE_PORTS (65536 - MAPBLK_MINPORT)
+
+#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
+
+typedef struct natlookup {
+ struct in_addr nl_inip;
+ struct in_addr nl_outip;
+ struct in_addr nl_realip;
+ int nl_flags;
+ u_short nl_inport;
+ u_short nl_outport;
+ u_short nl_realport;
+} natlookup_t;
+
+typedef struct natstat {
+ u_long ns_mapped[2];
+ u_long ns_rules;
+ u_long ns_added;
+ u_long ns_expire;
+ u_long ns_inuse;
+ u_long ns_logged;
+ u_long ns_logfail;
+ nat_t **ns_table[2];
+ ipnat_t *ns_list;
+ void *ns_apslist;
+ u_int ns_nattab_sz;
+ u_int ns_rultab_sz;
+ u_int ns_rdrtab_sz;
+ nat_t *ns_instances;
+} natstat_t;
+
+#define IPN_ANY 0x00
+#define IPN_TCP 0x01
+#define IPN_UDP 0x02
+#define IPN_TCPUDP (IPN_TCP|IPN_UDP)
+#define IPN_DELETE 0x04
+#define IPN_ICMPERR 0x08
+#define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
+#define IPN_AUTOPORTMAP 0x10
+#define IPN_RANGE 0x20
+#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_RANGE)
+
+
+typedef struct natlog {
+ struct in_addr nl_origip;
+ struct in_addr nl_outip;
+ struct in_addr nl_inip;
+ u_short nl_origport;
+ u_short nl_outport;
+ u_short nl_inport;
+ u_short nl_type;
+ int nl_rule;
+ U_QUAD_T nl_pkts;
+ U_QUAD_T nl_bytes;
+} natlog_t;
+
+
+#define NL_NEWMAP NAT_MAP
+#define NL_NEWRDR NAT_REDIRECT
+#define NL_EXPIRE 0xffff
+
+#define NAT_HASH_FN(k,m) (((k) + ((k) >> 12)) % (m))
+
+#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16))
+
+#define CALC_SUMD(s1, s2, sd) { \
+ (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
+ (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
+ /* Do it twice */ \
+ (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
+ (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
+ /* Because ~1 == -2, We really need ~1 == -1 */ \
+ if ((s1) > (s2)) (s2)--; \
+ (sd) = (s2) - (s1); \
+ (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
+
+
+extern u_int ipf_nattable_sz;
+extern u_int ipf_natrules_sz;
+extern u_int ipf_rdrrules_sz;
+extern void ip_natsync __P((void *));
+extern u_long fr_defnatage;
+extern u_long fr_defnaticmpage;
+extern nat_t **nat_table[2];
+extern nat_t *nat_instances;
+extern ipnat_t **nat_rules;
+extern ipnat_t **rdr_rules;
+extern natstat_t nat_stats;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int nat_ioctl __P((caddr_t, u_long, int));
+#else
+extern int nat_ioctl __P((caddr_t, int, int));
+#endif
+extern void nat_ifdetach __P((struct ifnet *));
+extern int nat_init __P((void));
+extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
+extern nat_t *nat_outlookup __P((void *, u_int, u_int, struct in_addr,
+ struct in_addr, u_32_t));
+extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
+ struct in_addr, u_32_t));
+extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
+ struct in_addr));
+extern nat_t *nat_lookupredir __P((natlookup_t *));
+extern nat_t *nat_icmpinlookup __P((ip_t *, fr_info_t *));
+extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, u_int *));
+
+extern int ip_natout __P((ip_t *, fr_info_t *));
+extern int ip_natin __P((ip_t *, fr_info_t *));
+extern void ip_natunload __P((void)), ip_natexpire __P((void));
+extern void nat_log __P((struct nat *, u_int));
+extern void fix_incksum __P((u_short *, u_32_t, int));
+extern void fix_outcksum __P((u_short *, u_32_t, int));
+
+#endif /* _NETINET_IP_NAT_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_proxy.h b/ecos/packages/net/tcpip/current/include/netinet/ip_proxy.h
new file mode 100644
index 0000000..c66ac1e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_proxy.h
@@ -0,0 +1,158 @@
+//==========================================================================
+//
+// include/netinet/ip_proxy.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_proxy.h,v 1.4 1999/12/15 05:20:23 kjell Exp $ */
+/*
+ * Copyright (C) 1997-1998 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ */
+
+#ifndef _NETINET_IP_PROXY_H__
+#define _NETINET_IP_PROXY_H__
+
+#ifndef SOLARIS
+#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#endif
+
+#ifndef APR_LABELLEN
+#define APR_LABELLEN 16
+#endif
+#define AP_SESS_SIZE 53
+
+struct nat;
+struct ipnat;
+
+typedef struct ap_tcp {
+ u_short apt_sport; /* source port */
+ u_short apt_dport; /* destination port */
+ short apt_sel[2]; /* {seq,ack}{off,min} set selector */
+ short apt_seqoff[2]; /* sequence # difference */
+ tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */
+ short apt_ackoff[2]; /* sequence # difference */
+ tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */
+ u_char apt_state[2]; /* connection state */
+} ap_tcp_t;
+
+typedef struct ap_udp {
+ u_short apu_sport; /* source port */
+ u_short apu_dport; /* destination port */
+} ap_udp_t;
+
+typedef struct ap_session {
+ struct aproxy *aps_apr;
+ union {
+ struct ap_tcp apu_tcp;
+ struct ap_udp apu_udp;
+ } aps_un;
+ u_int aps_flags;
+ U_QUAD_T aps_bytes; /* bytes sent */
+ U_QUAD_T aps_pkts; /* packets sent */
+ void *aps_nat; /* pointer back to nat struct */
+ void *aps_data; /* private data */
+ int aps_p; /* protocol */
+ int aps_psiz; /* size of private data */
+ struct ap_session *aps_hnext;
+ struct ap_session *aps_next;
+} ap_session_t ;
+
+#define aps_sport aps_un.apu_tcp.apt_sport
+#define aps_dport aps_un.apu_tcp.apt_dport
+#define aps_sel aps_un.apu_tcp.apt_sel
+#define aps_seqoff aps_un.apu_tcp.apt_seqoff
+#define aps_seqmin aps_un.apu_tcp.apt_seqmin
+#define aps_state aps_un.apu_tcp.apt_state
+#define aps_ackoff aps_un.apu_tcp.apt_ackoff
+#define aps_ackmin aps_un.apu_tcp.apt_ackmin
+
+
+typedef struct aproxy {
+ char apr_label[APR_LABELLEN]; /* Proxy label # */
+ u_char apr_p; /* protocol */
+ int apr_ref; /* +1 per rule referencing it */
+ int apr_flags;
+ int (* apr_init) __P((void));
+ int (* apr_new) __P((fr_info_t *, ip_t *,
+ ap_session_t *, struct nat *));
+ int (* apr_inpkt) __P((fr_info_t *, ip_t *,
+ ap_session_t *, struct nat *));
+ int (* apr_outpkt) __P((fr_info_t *, ip_t *,
+ ap_session_t *, struct nat *));
+} aproxy_t;
+
+#define APR_DELETE 1
+
+
+/*
+ * Real audio proxy structure and #defines
+ */
+typedef struct {
+ int rap_seenpna;
+ int rap_seenver;
+ int rap_version;
+ int rap_eos; /* End Of Startup */
+ int rap_gotid;
+ int rap_gotlen;
+ int rap_mode;
+ int rap_sdone;
+ u_short rap_plport;
+ u_short rap_prport;
+ u_short rap_srport;
+ char rap_svr[19];
+ u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have
+ * been filled
+ */
+ tcp_seq rap_sseq;
+} raudio_t;
+
+#define RA_ID_END 0
+#define RA_ID_UDP 1
+#define RA_ID_ROBUST 7
+
+#define RAP_M_UDP 1
+#define RAP_M_ROBUST 2
+#define RAP_M_TCP 4
+#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
+
+
+extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
+extern ap_session_t *ap_sess_list;
+extern aproxy_t ap_proxies[];
+
+extern int appr_init __P((void));
+extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
+extern void appr_free __P((aproxy_t *));
+extern void aps_free __P((ap_session_t *));
+extern int appr_check __P((ip_t *, fr_info_t *, struct nat *));
+extern aproxy_t *appr_match __P((u_int, char *));
+
+#endif /* _NETINET_IP_PROXY_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_rmd160.h b/ecos/packages/net/tcpip/current/include/netinet/ip_rmd160.h
new file mode 100644
index 0000000..ce94ca1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_rmd160.h
@@ -0,0 +1,66 @@
+//==========================================================================
+//
+// include/netinet/rmd160.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_rmd160.h,v 1.3 1999/02/17 18:10:08 deraadt Exp $ */
+
+/*
+ * FILE: rmd160.h
+ *
+ * CONTENTS: Header file for a sample C-implementation of the
+ * RIPEMD-160 hash-function.
+ * TARGET: any computer with an ANSI C compiler
+ *
+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
+ * DATE: 1 March 1996
+ * VERSION: 1.0
+ *
+ * Copyright (c) Katholieke Universiteit Leuven
+ * 1996, All Rights Reserved
+ *
+ */
+
+#ifndef _NETINET_RMD160_H /* make sure this file is read only once */
+#define _NETINET_RMD160_H
+
+typedef struct {
+ u_int32_t state[5]; /* state (ABCDE) */
+ u_int32_t length[2]; /* number of bits */
+ u_char bbuffer[64]; /* overflow buffer */
+ u_int32_t buflen; /* number of chars in bbuffer */
+} RMD160_CTX;
+
+void RMD160Init __P((RMD160_CTX *context));
+void RMD160Transform __P((u_int32_t state[5], const u_int32_t block[16]));
+void RMD160Update __P((RMD160_CTX *context, const u_char *data, u_int nbytes));
+void RMD160Final __P((u_char digest[20], RMD160_CTX *context));
+char *RMD160End __P((RMD160_CTX *, char *));
+char *RMD160File __P((char *, char *));
+char *RMD160Data __P((const u_char *, size_t, char *));
+
+#endif /* _NETINET_RMD160_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_sha1.h b/ecos/packages/net/tcpip/current/include/netinet/ip_sha1.h
new file mode 100644
index 0000000..02d2fe1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_sha1.h
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// include/netinet/sha1.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_sha1.h,v 1.5 1999/02/17 18:10:24 deraadt Exp $ */
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ */
+
+#ifndef _NETINET_SHA1_H_
+#define _NETINET_SHA1_H_
+
+typedef struct {
+ u_int32_t state[5];
+ u_int32_t count[2];
+ unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform __P((u_int32_t state[5], unsigned char buffer[64]));
+void SHA1Init __P((SHA1_CTX* context));
+void SHA1Update __P((SHA1_CTX* context, unsigned char* data, unsigned int len));
+void SHA1Final __P((unsigned char digest[20], SHA1_CTX* context));
+
+#endif /* _NETINET_SHA1_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_skipjack.h b/ecos/packages/net/tcpip/current/include/netinet/ip_skipjack.h
new file mode 100644
index 0000000..3a1ea20
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_skipjack.h
@@ -0,0 +1,50 @@
+//==========================================================================
+//
+// include/netinet/ip_skipjack.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+ * Further optimized test implementation of SKIPJACK algorithm
+ * Mark Tillotson <markt@chaos.org.uk>, 25 June 98
+ * Optimizations suit RISC (lots of registers) machine best.
+ *
+ * based on unoptimized implementation of
+ * Panu Rissanen <bande@lut.fi> 960624
+ *
+ * SKIPJACK and KEA Algorithm Specifications
+ * Version 2.0
+ * 29 May 1998
+*/
+
+#ifndef _NETINET_IP_SKIPJACK_H_
+#define _NETINET_IP_SKIPJACK_H_
+
+extern void skipjack_forwards __P((u_int8_t *plain, u_int8_t *cipher, u_int8_t **key));
+extern void skipjack_backwards __P((u_int8_t *cipher, u_int8_t *plain, u_int8_t **key));
+extern void subkey_table_gen __P((u_int8_t *key, u_int8_t **key_tables));
+
+#endif // _NETINET_IP_SKIPJACK_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_state.h b/ecos/packages/net/tcpip/current/include/netinet/ip_state.h
new file mode 100644
index 0000000..8b488f1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_state.h
@@ -0,0 +1,194 @@
+//==========================================================================
+//
+// include/netinet/ip_state.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_state.h,v 1.10 1999/12/15 05:20:23 kjell Exp $ */
+/*
+ * Copyright (C) 1995-1998 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
+ */
+
+#ifndef _NETINET_IP_STATE_H__
+#define _NETINET_IP_STATE_H__
+
+#define IPSTATE_SIZE 257
+#define IPSTATE_MAX 2048 /* Maximum number of states held */
+
+#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
+ (((s1) == (d2)) && ((d1) == (s2))))
+#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \
+ (s2).s_addr, (d2).s_addr)
+
+
+typedef struct udpstate {
+ u_short us_sport;
+ u_short us_dport;
+} udpstate_t;
+
+typedef struct icmpstate {
+ u_short ics_id;
+ u_short ics_seq;
+ u_char ics_type;
+} icmpstate_t;
+
+typedef struct tcpdata {
+ u_32_t td_end;
+ u_32_t td_maxend;
+ u_short td_maxwin;
+} tcpdata_t;
+
+typedef struct tcpstate {
+ u_short ts_sport;
+ u_short ts_dport;
+ tcpdata_t ts_data[2];
+ u_char ts_state[2];
+} tcpstate_t;
+
+typedef struct ipstate {
+ struct ipstate *is_next;
+ u_long is_age;
+ u_int is_pass;
+ U_QUAD_T is_pkts;
+ U_QUAD_T is_bytes;
+ void *is_ifpin;
+ void *is_ifpout;
+ frentry_t *is_rule;
+ struct in_addr is_src;
+ struct in_addr is_dst;
+ u_char is_p; /* Protocol */
+ u_char is_rout; /* Is rule in/out ? */
+ u_32_t is_flags;
+ u_32_t is_opt; /* packet options set */
+ u_32_t is_optmsk; /* " " mask */
+ u_short is_sec; /* security options set */
+ u_short is_secmsk; /* " " mask */
+ u_short is_auth; /* authentication options set */
+ u_short is_authmsk; /* " " mask */
+ union {
+ icmpstate_t is_ics;
+ tcpstate_t is_ts;
+ udpstate_t is_us;
+ } is_ps;
+} ipstate_t;
+
+#define is_icmp is_ps.is_ics
+#define is_type is_icmp.ics_type
+#define is_code is_icmp.ics_code
+#define is_tcp is_ps.is_ts
+#define is_udp is_ps.is_us
+#define is_send is_tcp.ts_data[0].td_end
+#define is_dend is_tcp.ts_data[1].td_end
+#define is_maxswin is_tcp.ts_data[0].td_maxwin
+#define is_maxdwin is_tcp.ts_data[1].td_maxwin
+#define is_maxsend is_tcp.ts_data[0].td_maxend
+#define is_maxdend is_tcp.ts_data[1].td_maxend
+#define is_sport is_tcp.ts_sport
+#define is_dport is_tcp.ts_dport
+#define is_state is_tcp.ts_state
+
+#define TH_OPENING (TH_SYN|TH_ACK)
+/*
+ * is_flags:
+ * Bits 0 - 3 are use as a mask with the current packet's bits to check for
+ * whether it is short, tcp/udp, a fragment or the presence of IP options.
+ * Bits 4 - 7 are set from the initial packet and contain what the packet
+ * anded with bits 0-3 must match.
+ * Bits 8,9 are used to indicate wildcard source/destination port matching.
+ */
+
+
+typedef struct ipslog {
+ U_QUAD_T isl_pkts;
+ U_QUAD_T isl_bytes;
+ struct in_addr isl_src;
+ struct in_addr isl_dst;
+ u_char isl_p;
+ u_char isl_flags;
+ u_char isl_state[2];
+ u_short isl_type;
+ union {
+ u_short isl_filler[2];
+ u_short isl_ports[2];
+ u_short isl_icmp;
+ } isl_ps;
+} ipslog_t;
+
+#define isl_sport isl_ps.isl_ports[0]
+#define isl_dport isl_ps.isl_ports[1]
+#define isl_itype isl_ps.isl_icmp
+
+#define ISL_NEW 0
+#define ISL_EXPIRE 0xffff
+#define ISL_FLUSH 0xfffe
+
+
+typedef struct ips_stat {
+ u_long iss_hits;
+ u_long iss_miss;
+ u_long iss_max;
+ u_long iss_tcp;
+ u_long iss_udp;
+ u_long iss_icmp;
+ u_long iss_nomem;
+ u_long iss_expire;
+ u_long iss_fin;
+ u_long iss_active;
+ u_long iss_logged;
+ u_long iss_logfail;
+ u_long iss_inuse;
+ ipstate_t **iss_table;
+} ips_stat_t;
+
+
+extern u_long fr_tcpidletimeout;
+extern u_long fr_tcpclosewait;
+extern u_long fr_tcplastack;
+extern u_long fr_tcptimeout;
+extern u_long fr_tcpclosed;
+extern u_long fr_udptimeout;
+extern u_long fr_icmptimeout;
+extern int fr_stateinit __P((void));
+extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *));
+extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, u_int));
+extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
+extern void fr_timeoutstate __P((void));
+extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int));
+extern void fr_stateunload __P((void));
+extern void ipstate_log __P((struct ipstate *, u_int));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int fr_state_ioctl __P((caddr_t, u_long, int));
+#else
+extern int fr_state_ioctl __P((caddr_t, int, int));
+#endif
+
+#endif /* _NETINET_IP_STATE_H__ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ip_var.h b/ecos/packages/net/tcpip/current/include/netinet/ip_var.h
new file mode 100644
index 0000000..301c1c1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ip_var.h
@@ -0,0 +1,239 @@
+//==========================================================================
+//
+// include/netinet/ip_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_var.h,v 1.12 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_var.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP_VAR_H_
+#define _NETINET_IP_VAR_H_
+
+#include <sys/queue.h>
+
+/*
+ * Overlay for ip header used by other protocols (tcp, udp).
+ */
+struct ipovly {
+ u_int8_t ih_x1[9]; /* (unused) */
+ u_int8_t ih_pr; /* protocol */
+ u_int16_t ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+
+/*
+ * Ip (reassembly or sequence) queue structures.
+ *
+ * XXX -- The following explains why the ipqe_m field is here, for TCP's use:
+ * We want to avoid doing m_pullup on incoming packets but that
+ * means avoiding dtom on the tcp reassembly code. That in turn means
+ * keeping an mbuf pointer in the reassembly queue (since we might
+ * have a cluster). As a quick hack, the source & destination
+ * port numbers (which are no longer needed once we've located the
+ * tcpcb) are overlayed with an mbuf pointer.
+ */
+LIST_HEAD(ipqehead, ipqent);
+struct ipqent {
+ LIST_ENTRY(ipqent) ipqe_q;
+ union {
+ struct ip *_ip;
+ struct tcphdr *_tcp;
+ } _ipqe_u1;
+ union {
+ u_int8_t _mff; /* for IP fragmentation */
+ struct mbuf *_m; /* XXX for TCP; see above */
+ } _ipqe_u2;
+};
+#define ipqe_ip _ipqe_u1._ip
+#define ipqe_tcp _ipqe_u1._tcp
+#define ipqe_mff _ipqe_u2._mff
+#define ipqe_m _ipqe_u2._m
+
+/*
+ * Ip reassembly queue structure. Each fragment
+ * being reassembled is attached to one of these structures.
+ * They are timed out after ipq_ttl drops to 0, and may also
+ * be reclaimed if memory becomes tight.
+ */
+struct ipq {
+ LIST_ENTRY(ipq) ipq_q; /* to other reass headers */
+ u_int8_t ipq_ttl; /* time for reass q to live */
+ u_int8_t ipq_p; /* protocol of this fragment */
+ u_int16_t ipq_id; /* sequence id for reassembly */
+ struct ipqehead ipq_fragq; /* to ip fragment queue */
+ struct in_addr ipq_src, ipq_dst;
+};
+
+/*
+ * Structure stored in mbuf in inpcb.ip_options
+ * and passed to ip_output when ip options are in use.
+ * The actual length of the options (including ipopt_dst)
+ * is in m_len.
+ */
+#define MAX_IPOPTLEN 40
+
+struct ipoption {
+ struct in_addr ipopt_dst; /* first-hop dst if source routed */
+ int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
+};
+
+/*
+ * Structure attached to inpcb.ip_moptions and
+ * passed to ip_output when IP multicast options are in use.
+ */
+struct ip_moptions {
+ struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
+ u_int8_t imo_multicast_ttl; /* TTL for outgoing multicasts */
+ u_int8_t imo_multicast_loop; /* 1 => hear sends if a member */
+ u_int16_t imo_num_memberships; /* no. memberships this socket */
+ struct in_multi *imo_membership[IP_MAX_MEMBERSHIPS];
+};
+
+struct ipstat {
+ u_long ips_total; /* total packets received */
+ u_long ips_badsum; /* checksum bad */
+ u_long ips_tooshort; /* packet too short */
+ u_long ips_toosmall; /* not enough data */
+ u_long ips_badhlen; /* ip header length < data size */
+ u_long ips_badlen; /* ip length < ip header length */
+ u_long ips_fragments; /* fragments received */
+ u_long ips_fragdropped; /* frags dropped (dups, out of space) */
+ u_long ips_fragtimeout; /* fragments timed out */
+ u_long ips_forward; /* packets forwarded */
+ u_long ips_cantforward; /* packets rcvd for unreachable dest */
+ u_long ips_redirectsent; /* packets forwarded on same net */
+ u_long ips_noproto; /* unknown or unsupported protocol */
+ u_long ips_delivered; /* datagrams delivered to upper level*/
+ u_long ips_localout; /* total ip packets generated here */
+ u_long ips_odropped; /* lost packets due to nobufs, etc. */
+ u_long ips_reassembled; /* total packets reassembled ok */
+ u_long ips_fragmented; /* datagrams sucessfully fragmented */
+ u_long ips_ofragments; /* output fragments created */
+ u_long ips_cantfrag; /* don't fragment flag was set, etc. */
+ u_long ips_badoptions; /* error in option processing */
+ u_long ips_noroute; /* packets discarded due to no route */
+ u_long ips_badvers; /* ip version != 4 */
+ u_long ips_rawout; /* total raw ip packets generated */
+ u_long ips_badfrags; /* malformed fragments (bad length) */
+ u_long ips_rcvmemdrop; /* frags dropped for lack of memory */
+ u_long ips_toolong; /* ip length > max ip packet size */
+ u_long ips_nogif; /* no match gif found */
+};
+
+#ifdef _KERNEL
+/* flags passed to ip_output as last parameter */
+#define IP_FORWARDING 0x1 /* most of ip header exists */
+#define IP_RAWOUTPUT 0x2 /* raw ip header exists */
+#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
+#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
+
+#ifdef IPSEC
+#define IP_ENCAPSULATED 0x0800 /* encapsulated already */
+#endif
+
+extern struct ipstat ipstat;
+#ifndef RANDOM_IP_ID
+extern u_short ip_id; /* ip packet ctr, for ids */
+#endif
+LIST_HEAD(ipqhead, ipq) ipq; /* ip reass. queue */
+extern int ip_defttl; /* default IP ttl */
+extern int ipforwarding; /* IPforwarding state */
+
+int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+int ip_dooptions __P((struct mbuf *));
+void ip_drain __P((void));
+void ip_flush __P((void));
+void ip_forward __P((struct mbuf *, int));
+void ip_freef __P((struct ipq *));
+void ip_freemoptions __P((struct ip_moptions *));
+int ip_getmoptions __P((int, struct ip_moptions *, struct mbuf **));
+void ip_init __P((void));
+int ip_mforward __P((struct mbuf *, struct ifnet *));
+int ip_optcopy __P((struct ip *, struct ip *));
+int ip_output __P((struct mbuf *, ...));
+int ip_pcbopts __P((struct mbuf **, struct mbuf *));
+struct ip *
+ ip_reass __P((struct ipqent *, struct ipq *));
+struct in_ifaddr *
+ in_iawithaddr __P((struct in_addr, struct mbuf *));
+struct in_ifaddr *
+ ip_rtaddr __P((struct in_addr));
+u_int16_t
+ ip_randomid __P((void));
+int ip_setmoptions __P((int, struct ip_moptions **, struct mbuf *));
+void ip_slowtimo __P((void));
+struct mbuf *
+ ip_srcroute __P((void));
+void ip_stripoptions __P((struct mbuf *, struct mbuf *));
+int ip_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+void ipintr __P((void));
+void ipv4_input __P((struct mbuf *, ...));
+int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+void rip_init __P((void));
+void rip_input __P((struct mbuf *, ...));
+int rip_output __P((struct mbuf *, ...));
+int rip_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+#endif
+
+#endif // _NETINET_IP_VAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/ipl.h b/ecos/packages/net/tcpip/current/include/netinet/ipl.h
new file mode 100644
index 0000000..71540b1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/ipl.h
@@ -0,0 +1,46 @@
+//==========================================================================
+//
+// include/netinet/ipl.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ipl.h,v 1.2 1999/12/17 06:17:08 kjell Exp $ */
+/*
+ * Copyright (C) 1993-1999 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * @(#)ipl.h 1.21 6/5/96
+ */
+
+#ifndef __IPL_H__
+#define __IPL_H__
+
+#define IPL_VERSION "IP Filter: v3.3.5"
+
+#endif
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcp.h b/ecos/packages/net/tcpip/current/include/netinet/tcp.h
new file mode 100644
index 0000000..2c65b81
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcp.h
@@ -0,0 +1,155 @@
+//==========================================================================
+//
+// include/netinet/tcp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp.h,v 1.8 1999/07/06 20:17:52 cmetz Exp $ */
+/* $NetBSD: tcp.h,v 1.8 1995/04/17 05:32:58 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_H_
+#define _NETINET_TCP_H_
+
+typedef u_int32_t tcp_seq;
+
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int8_t th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#endif
+ u_int8_t th_flags;
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+} __attribute__ ((aligned(1), packed));
+#define th_reseqlen th_urp /* TCP data length for
+ resequencing/reassembly */
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WINDOW 3
+#define TCPOLEN_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOPT_SACK 5 /* Experimental */
+#define TCPOLEN_SACK 8 /* 2*sizeof(tcp_seq) */
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+#define TCPOPT_SIGNATURE 19
+#define TCPOLEN_SIGNATURE 18
+
+#define MAX_TCPOPTLEN 40 /* Absolute maximum TCP options len */
+
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+/* Option definitions */
+#define TCPOPT_SACK_PERMIT_HDR \
+(TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_SACK_PERMITTED<<8|TCPOLEN_SACK_PERMITTED)
+#define TCPOPT_SACK_HDR (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_SACK<<8)
+/* Miscellaneous constants */
+#define MAX_SACK_BLKS 6 /* Max # SACK blocks stored at sender side */
+#define TCP_MAX_SACK 3 /* MAX # SACKs sent in any segment */
+
+#define TCP_MAXBURST 4 /* Max # packets after leaving Fast Rxmit */
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as min(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+#define TCP_MSS 512
+
+#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+
+#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce pkts */
+#define TCP_MAXSEG 0x02 /* set maximum segment size */
+#define TCP_SIGNATURE_ENABLE 0x04 /* enable TCP MD5 signature option */
+#define TCP_SACK_DISABLE 0x300 /* disable SACKs (if enabled by def.) */
+
+#endif /* !_NETINET_TCP_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcp_debug.h b/ecos/packages/net/tcpip/current/include/netinet/tcp_debug.h
new file mode 100644
index 0000000..44093fe
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcp_debug.h
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// include/netinet/tcp_debug.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_debug.h,v 1.4 1999/01/11 02:01:35 deraadt Exp $ */
+/* $NetBSD: tcp_debug.h,v 1.5 1994/06/29 06:38:38 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_debug.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_DEBUG_H_
+#define _NETINET_TCP_DEBUG_H_
+
+#include <netinet6/tcpipv6.h>
+
+#ifdef TCPDEBUG
+struct tcp_debug {
+ n_time td_time;
+ short td_act;
+ short td_ostate;
+ caddr_t td_tcb;
+ struct tcpiphdr td_ti;
+ struct tcpipv6hdr td_ti6;
+ short td_req;
+ struct tcpcb td_cb;
+};
+
+#define TA_INPUT 0
+#define TA_OUTPUT 1
+#define TA_USER 2
+#define TA_RESPOND 3
+#define TA_DROP 4
+
+char *tanames[] =
+ { "input", "output", "user", "respond", "drop" };
+
+#define TCP_NDEBUG 100
+struct tcp_debug tcp_debug[TCP_NDEBUG];
+int tcp_debx;
+#endif
+
+#endif // _NETINET_TCP_DEBUG_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcp_fsm.h b/ecos/packages/net/tcpip/current/include/netinet/tcp_fsm.h
new file mode 100644
index 0000000..5bda84c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcp_fsm.h
@@ -0,0 +1,123 @@
+//==========================================================================
+//
+// include/netinet_tcp_fsm.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_fsm.h,v 1.4 1997/11/08 19:54:12 deraadt Exp $ */
+/* $NetBSD: tcp_fsm.h,v 1.6 1994/10/14 16:01:48 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_fsm.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_FSM_H_
+#define _NETINET_TCP_FSM_H_
+
+/*
+ * TCP FSM state definitions.
+ * Per RFC793, September, 1981.
+ */
+
+#define TCP_NSTATES 11
+
+#define TCPS_CLOSED 0 /* closed */
+#define TCPS_LISTEN 1 /* listening for connection */
+#define TCPS_SYN_SENT 2 /* active, have sent syn */
+#define TCPS_SYN_RECEIVED 3 /* have sent and received syn */
+/* states < TCPS_ESTABLISHED are those where connections not established */
+#define TCPS_ESTABLISHED 4 /* established */
+#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
+/* states > TCPS_CLOSE_WAIT are those where user has closed */
+#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
+#define TCPS_CLOSING 7 /* closed xchd FIN; await ACK */
+#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
+/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
+#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
+#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
+
+#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED)
+#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
+#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT)
+
+#ifdef TCPOUTFLAGS
+/*
+ * Flags used when sending segments in tcp_output.
+ * Basic flags (TH_RST,TH_ACK,TH_SYN,TH_FIN) are totally
+ * determined by state, with the proviso that TH_FIN is sent only
+ * if all data queued for output is included in the segment.
+ */
+u_char tcp_outflags[TCP_NSTATES] = {
+ TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
+ TH_ACK, TH_ACK,
+ TH_FIN|TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
+};
+#endif
+
+#ifdef KPROF
+int tcp_acounts[TCP_NSTATES][PRU_NREQ];
+#endif
+
+#ifdef TCPSTATES
+char *tcpstates[] = {
+ "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD",
+ "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",
+ "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",
+};
+#endif
+
+#endif // _NETINET_TCP_FSM_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcp_seq.h b/ecos/packages/net/tcpip/current/include/netinet/tcp_seq.h
new file mode 100644
index 0000000..462ac53
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcp_seq.h
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// include/netinet_tcp_seq.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_seq.h,v 1.2 1997/02/24 14:06:46 niklas Exp $ */
+/* $NetBSD: tcp_seq.h,v 1.6 1995/03/26 20:32:35 jtc Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_seq.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_SEQ_H_
+#define _NETINET_TCP_SEQ_H_
+
+/*
+ * TCP sequence numbers are 32 bit integers operated
+ * on with modular arithmetic. These macros can be
+ * used to compare such integers.
+ */
+#define SEQ_LT(a,b) ((int)((a)-(b)) < 0)
+#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
+#define SEQ_GT(a,b) ((int)((a)-(b)) > 0)
+#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0)
+
+/*
+ * Macros to initialize tcp sequence numbers for
+ * send and receive from initial send and receive
+ * sequence numbers.
+ */
+#define tcp_rcvseqinit(tp) \
+ (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1
+
+#define tcp_sendseqinit(tp) \
+ (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = \
+ (tp)->iss
+
+#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */
+
+#ifdef _KERNEL
+tcp_seq tcp_iss; /* tcp initial send seq # */
+#endif
+
+#endif // _NETINET_TCP_SEQ_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcp_timer.h b/ecos/packages/net/tcpip/current/include/netinet/tcp_timer.h
new file mode 100644
index 0000000..920441c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcp_timer.h
@@ -0,0 +1,166 @@
+//==========================================================================
+//
+// include/netinet_tcp_timer.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_timer.h,v 1.3 1997/02/24 14:06:46 niklas Exp $ */
+/* $NetBSD: tcp_timer.h,v 1.6 1995/03/26 20:32:37 jtc Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_TIMER_H_
+#define _NETINET_TCP_TIMER_H_
+
+/*
+ * Definitions of the TCP timers. These timers are counted
+ * down PR_SLOWHZ times a second.
+ */
+#define TCPT_NTIMERS 4
+
+#define TCPT_REXMT 0 /* retransmit */
+#define TCPT_PERSIST 1 /* retransmit persistance */
+#define TCPT_KEEP 2 /* keep alive */
+#define TCPT_2MSL 3 /* 2*msl quiet time timer */
+
+/*
+ * The TCPT_REXMT timer is used to force retransmissions.
+ * The TCP has the TCPT_REXMT timer set whenever segments
+ * have been sent for which ACKs are expected but not yet
+ * received. If an ACK is received which advances tp->snd_una,
+ * then the retransmit timer is cleared (if there are no more
+ * outstanding segments) or reset to the base value (if there
+ * are more ACKs expected). Whenever the retransmit timer goes off,
+ * we retransmit one unacknowledged segment, and do a backoff
+ * on the retransmit timer.
+ *
+ * The TCPT_PERSIST timer is used to keep window size information
+ * flowing even if the window goes shut. If all previous transmissions
+ * have been acknowledged (so that there are no retransmissions in progress),
+ * and the window is too small to bother sending anything, then we start
+ * the TCPT_PERSIST timer. When it expires, if the window is nonzero,
+ * we go to transmit state. Otherwise, at intervals send a single byte
+ * into the peer's window to force him to update our window information.
+ * We do this at most as often as TCPT_PERSMIN time intervals,
+ * but no more frequently than the current estimate of round-trip
+ * packet time. The TCPT_PERSIST timer is cleared whenever we receive
+ * a window update from the peer.
+ *
+ * The TCPT_KEEP timer is used to keep connections alive. If an
+ * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time,
+ * but not yet established, then we drop the connection. Once the connection
+ * is established, if the connection is idle for TCPTV_KEEP_IDLE time
+ * (and keepalives have been enabled on the socket), we begin to probe
+ * the connection. We force the peer to send us a segment by sending:
+ * <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
+ * This segment is (deliberately) outside the window, and should elicit
+ * an ack segment in response from the peer. If, despite the TCPT_KEEP
+ * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE
+ * amount of time probing, then we drop the connection.
+ */
+
+/*
+ * Time constants.
+ */
+#define TCPTV_MSL ( 30*PR_SLOWHZ) /* max seg lifetime (hah!) */
+#define TCPTV_SRTTBASE 0 /* base roundtrip time;
+ if 0, no idea yet */
+#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */
+
+#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistance */
+#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */
+
+#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */
+#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */
+#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */
+#define TCPTV_KEEPCNT 8 /* max probes before drop */
+
+#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */
+#define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) /* max allowable REXMT value */
+
+#define TCP_LINGERTIME 120 /* linger at most 2 minutes */
+
+#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
+
+#ifdef TCPTIMERS
+char *tcptimers[] =
+ { "REXMT", "PERSIST", "KEEP", "2MSL" };
+#endif
+
+/*
+ * Force a time value to be in a certain range.
+ */
+#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \
+ (tv) = (value); \
+ if ((tv) < (tvmin)) \
+ (tv) = (tvmin); \
+ else if ((tv) > (tvmax)) \
+ (tv) = (tvmax); \
+}
+
+#ifdef _KERNEL
+extern int tcptv_keep_init;
+extern int tcp_keepidle; /* time before keepalive probes begin */
+extern int tcp_keepintvl; /* time between keepalive probes */
+extern int tcp_maxidle; /* time to drop after starting probes */
+extern int tcp_ttl; /* time to live for TCP segs */
+extern int tcp_backoff[];
+#endif
+
+#endif // _NETINET_TCP_TIMER_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcp_var.h b/ecos/packages/net/tcpip/current/include/netinet/tcp_var.h
new file mode 100644
index 0000000..f495240
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcp_var.h
@@ -0,0 +1,428 @@
+//==========================================================================
+//
+// include/netinet_tcp_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_var.h,v 1.25 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94
+ */
+
+#ifndef _NETINET_TCP_VAR_H_
+#define _NETINET_TCP_VAR_H_
+
+struct sackblk {
+ tcp_seq start; /* start seq no. of sack block */
+ tcp_seq end; /* end seq no. */
+};
+
+struct sackhole {
+ tcp_seq start; /* start seq no. of hole */
+ tcp_seq end; /* end seq no. */
+ int dups; /* number of dup(s)acks for this hole */
+ tcp_seq rxmit; /* next seq. no in hole to be retransmitted */
+ struct sackhole *next; /* next in list */
+};
+
+/*
+ * Kernel variables for tcp.
+ */
+
+/*
+ * Tcp control block, one per tcp; fields:
+ */
+struct tcpcb {
+ struct ipqehead segq; /* sequencing queue */
+ short t_state; /* state of this connection */
+ short t_timer[TCPT_NTIMERS]; /* tcp timers */
+ short t_rxtshift; /* log(2) of rexmt exp. backoff */
+ short t_rxtcur; /* current retransmit value */
+ short t_dupacks; /* consecutive dup acks recd */
+ u_short t_maxseg; /* maximum segment size */
+ char t_force; /* 1 if forcing out a byte */
+ u_short t_flags;
+#define TF_ACKNOW 0x0001 /* ack peer immediately */
+#define TF_DELACK 0x0002 /* ack, but try to delay it */
+#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */
+#define TF_NOOPT 0x0008 /* don't use tcp options */
+#define TF_SENTFIN 0x0010 /* have sent FIN */
+#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */
+#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */
+#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */
+#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */
+#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */
+#define TF_SIGNATURE 0x0400 /* require TCP MD5 signature */
+
+ struct mbuf *t_template; /* skeletal packet for transmit */
+ struct inpcb *t_inpcb; /* back pointer to internet pcb */
+/*
+ * The following fields are used as in the protocol specification.
+ * See RFC783, Dec. 1981, page 21.
+ */
+/* send sequence variables */
+ tcp_seq snd_una; /* send unacknowledged */
+ tcp_seq snd_nxt; /* send next */
+ tcp_seq snd_up; /* send urgent pointer */
+ tcp_seq snd_wl1; /* window update seg seq number */
+ tcp_seq snd_wl2; /* window update seg ack number */
+ tcp_seq iss; /* initial send sequence number */
+ u_long snd_wnd; /* send window */
+#ifdef TCP_SACK
+ int sack_disable; /* disable SACK for this connection */
+ int snd_numholes; /* number of holes seen by sender */
+ struct sackhole *snd_holes; /* linked list of holes (sorted) */
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ tcp_seq snd_fack; /* for FACK congestion control */
+ u_long snd_awnd; /* snd_nxt - snd_fack + */
+ /* retransmitted data */
+ int retran_data; /* amount of outstanding retx. data */
+#endif /* TCP_FACK */
+#endif /* TCP_SACK */
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ tcp_seq snd_last; /* for use in fast recovery */
+#endif
+/* receive sequence variables */
+ u_long rcv_wnd; /* receive window */
+ tcp_seq rcv_nxt; /* receive next */
+ tcp_seq rcv_up; /* receive urgent pointer */
+ tcp_seq irs; /* initial receive sequence number */
+#ifdef TCP_SACK
+ tcp_seq rcv_laststart; /* start of last segment recd. */
+ tcp_seq rcv_lastend; /* end of ... */
+ tcp_seq rcv_lastsack; /* last seq number(+1) sack'd by rcv'r*/
+ int rcv_numsacks; /* # distinct sack blks present */
+ struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */
+#endif
+
+/*
+ * Additional variables for this implementation.
+ */
+/* receive variables */
+ tcp_seq rcv_adv; /* advertised window */
+/* retransmit variables */
+ tcp_seq snd_max; /* highest sequence number sent;
+ * used to recognize retransmits
+ */
+/* congestion control (for slow start, source quench, retransmit after loss) */
+ u_long snd_cwnd; /* congestion-controlled window */
+ u_long snd_ssthresh; /* snd_cwnd size threshhold for
+ * for slow start exponential to
+ * linear switch
+ */
+ u_int t_maxopd; /* mss plus options */
+
+/*
+ * transmit timing stuff. See below for scale of srtt and rttvar.
+ * "Variance" is actually smoothed difference.
+ */
+ short t_idle; /* inactivity time */
+ short t_rtt; /* round trip time */
+ tcp_seq t_rtseq; /* sequence number being timed */
+ short t_srtt; /* smoothed round-trip time */
+ short t_rttvar; /* variance in round-trip time */
+ u_short t_rttmin; /* minimum rtt allowed */
+ u_long max_sndwnd; /* largest window peer has offered */
+
+/* out-of-band data */
+ char t_oobflags; /* have some */
+ char t_iobc; /* input character */
+#define TCPOOB_HAVEDATA 0x01
+#define TCPOOB_HADDATA 0x02
+ short t_softerror; /* possible error not yet reported */
+
+/* RFC 1323 variables */
+ u_char snd_scale; /* window scaling for send window */
+ u_char rcv_scale; /* window scaling for recv window */
+ u_char request_r_scale; /* pending window scaling */
+ u_char requested_s_scale;
+ u_int32_t ts_recent; /* timestamp echo data */
+ u_int32_t ts_recent_age; /* when last updated */
+ tcp_seq last_ack_sent;
+
+/* TUBA stuff */
+ caddr_t t_tuba_pcb; /* next level down pcb for TCP over z */
+
+ int pf;
+};
+
+#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
+#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
+
+/*
+ * The smoothed round-trip time and estimated variance
+ * are stored as fixed point numbers scaled by the values below.
+ * For convenience, these scales are also used in smoothing the average
+ * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
+ * With these scales, srtt has 3 bits to the right of the binary point,
+ * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the
+ * binary point, and is smoothed with an ALPHA of 0.75.
+ */
+#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */
+#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */
+#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */
+#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */
+
+/*
+ * The initial retransmission should happen at rtt + 4 * rttvar.
+ * Because of the way we do the smoothing, srtt and rttvar
+ * will each average +1/2 tick of bias. When we compute
+ * the retransmit timer, we want 1/2 tick of rounding and
+ * 1 extra tick because of +-1/2 tick uncertainty in the
+ * firing of the timer. The bias will give us exactly the
+ * 1.5 tick we need. But, because the bias is
+ * statistical, we have to test that we don't drop below
+ * the minimum feasible timer (which is 2 ticks).
+ * This macro assumes that the value of TCP_RTTVAR_SCALE
+ * is the same as the multiplier for rttvar.
+ */
+#define TCP_REXMTVAL(tp) \
+ ((((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) >> 2)
+
+/*
+ * TCP statistics.
+ * Many of these should be kept per connection,
+ * but that's inconvenient at the moment.
+ */
+struct tcpstat {
+ u_int32_t tcps_connattempt; /* connections initiated */
+ u_int32_t tcps_accepts; /* connections accepted */
+ u_int32_t tcps_connects; /* connections established */
+ u_int32_t tcps_drops; /* connections dropped */
+ u_int32_t tcps_conndrops; /* embryonic connections dropped */
+ u_int32_t tcps_closed; /* conn. closed (includes drops) */
+ u_int32_t tcps_segstimed; /* segs where we tried to get rtt */
+ u_int32_t tcps_rttupdated; /* times we succeeded */
+ u_int32_t tcps_delack; /* delayed acks sent */
+ u_int32_t tcps_timeoutdrop; /* conn. dropped in rxmt timeout */
+ u_int32_t tcps_rexmttimeo; /* retransmit timeouts */
+ u_int32_t tcps_persisttimeo; /* persist timeouts */
+ u_int32_t tcps_persistdrop; /* connections dropped in persist */
+ u_int32_t tcps_keeptimeo; /* keepalive timeouts */
+ u_int32_t tcps_keepprobe; /* keepalive probes sent */
+ u_int32_t tcps_keepdrops; /* connections dropped in keepalive */
+
+ u_int32_t tcps_sndtotal; /* total packets sent */
+ u_int32_t tcps_sndpack; /* data packets sent */
+ u_int64_t tcps_sndbyte; /* data bytes sent */
+ u_int32_t tcps_sndrexmitpack; /* data packets retransmitted */
+ u_int64_t tcps_sndrexmitbyte; /* data bytes retransmitted */
+ u_int64_t tcps_sndrexmitfast; /* Fast retransmits */
+ u_int32_t tcps_sndacks; /* ack-only packets sent */
+ u_int32_t tcps_sndprobe; /* window probes sent */
+ u_int32_t tcps_sndurg; /* packets sent with URG only */
+ u_int32_t tcps_sndwinup; /* window update-only packets sent */
+ u_int32_t tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */
+
+ u_int32_t tcps_rcvtotal; /* total packets received */
+ u_int32_t tcps_rcvpack; /* packets received in sequence */
+ u_int64_t tcps_rcvbyte; /* bytes received in sequence */
+ u_int32_t tcps_rcvbadsum; /* packets received with ccksum errs */
+ u_int32_t tcps_rcvbadoff; /* packets received with bad offset */
+ u_int32_t tcps_rcvmemdrop; /* packets dropped for lack of memory */
+ u_int32_t tcps_rcvnosec; /* packets dropped for lack of ipsec */
+ u_int32_t tcps_rcvshort; /* packets received too short */
+ u_int32_t tcps_rcvduppack; /* duplicate-only packets received */
+ u_int64_t tcps_rcvdupbyte; /* duplicate-only bytes received */
+ u_int32_t tcps_rcvpartduppack; /* packets with some duplicate data */
+ u_int64_t tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */
+ u_int32_t tcps_rcvoopack; /* out-of-order packets received */
+ u_int64_t tcps_rcvoobyte; /* out-of-order bytes received */
+ u_int32_t tcps_rcvpackafterwin; /* packets with data after window */
+ u_int64_t tcps_rcvbyteafterwin; /* bytes rcvd after window */
+ u_int32_t tcps_rcvafterclose; /* packets rcvd after "close" */
+ u_int32_t tcps_rcvwinprobe; /* rcvd window probe packets */
+ u_int32_t tcps_rcvdupack; /* rcvd duplicate acks */
+ u_int32_t tcps_rcvacktoomuch; /* rcvd acks for unsent data */
+ u_int32_t tcps_rcvackpack; /* rcvd ack packets */
+ u_int64_t tcps_rcvackbyte; /* bytes acked by rcvd acks */
+ u_int32_t tcps_rcvwinupd; /* rcvd window update packets */
+ u_int32_t tcps_pawsdrop; /* segments dropped due to PAWS */
+ u_int32_t tcps_predack; /* times hdr predict ok for acks */
+ u_int32_t tcps_preddat; /* times hdr predict ok for data pkts */
+
+ u_int32_t tcps_pcbhashmiss; /* input packets missing pcb hash */
+ u_int32_t tcps_noport; /* no socket on port */
+ u_int32_t tcps_badsyn; /* SYN packet with src==dst rcv'ed */
+
+ u_int32_t tcps_rcvbadsig; /* rcvd bad/missing TCP signatures */
+ u_int64_t tcps_rcvgoodsig; /* rcvd good TCP signatures */
+};
+
+/*
+ * Names for TCP sysctl objects.
+ */
+
+#define TCPCTL_RFC1323 1 /* enable/disable RFC1323 timestamps/scaling */
+#define TCPCTL_KEEPINITTIME 2 /* TCPT_KEEP value */
+#define TCPCTL_KEEPIDLE 3 /* allow tcp_keepidle to be changed */
+#define TCPCTL_KEEPINTVL 4 /* allow tcp_keepintvl to be changed */
+#define TCPCTL_SLOWHZ 5 /* return kernel idea of PR_SLOWHZ */
+#define TCPCTL_BADDYNAMIC 6 /* return bad dynamic port bitmap */
+#define TCPCTL_RECVSPACE 7 /* receive buffer space */
+#define TCPCTL_SENDSPACE 8 /* send buffer space */
+#define TCPCTL_IDENT 9 /* get connection owner */
+#define TCPCTL_SACK 10 /* selective acknowledgement, rfc 2018 */
+#define TCPCTL_MSSDFLT 11 /* Default maximum segment size */
+#define TCPCTL_MAXID 12
+
+#define TCPCTL_NAMES { \
+ { 0, 0 }, \
+ { "rfc1323", CTLTYPE_INT }, \
+ { "keepinittime", CTLTYPE_INT }, \
+ { "keepidle", CTLTYPE_INT }, \
+ { "keepintvl", CTLTYPE_INT }, \
+ { "slowhz", CTLTYPE_INT }, \
+ { "baddynamic", CTLTYPE_STRUCT }, \
+ { "recvspace", CTLTYPE_INT }, \
+ { "sendspace", CTLTYPE_INT }, \
+ { "ident", CTLTYPE_STRUCT }, \
+ { "sack", CTLTYPE_INT }, \
+ { "mssdflt", CTLTYPE_INT }, \
+}
+
+struct tcp_ident_mapping {
+ struct sockaddr faddr, laddr;
+ int euid, ruid;
+};
+
+#ifdef _KERNEL
+struct inpcbtable tcbtable; /* head of queue of active tcpcb's */
+struct tcpstat tcpstat; /* tcp statistics */
+u_int32_t tcp_now; /* for RFC 1323 timestamps */
+extern int tcp_do_rfc1323; /* enabled/disabled? */
+extern int tcp_mssdflt; /* default maximum segment size */
+#ifdef TCP_SACK
+extern int tcp_do_sack; /* SACK enabled/disabled */
+#endif
+
+int tcp_attach __P((struct socket *));
+void tcp_canceltimers __P((struct tcpcb *));
+struct tcpcb *
+ tcp_close __P((struct tcpcb *));
+#if defined(INET6) && !defined(TCP6)
+void tcp6_ctlinput __P((int, struct sockaddr *, void *));
+#endif
+void *tcp_ctlinput __P((int, struct sockaddr *, void *));
+int tcp_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+struct tcpcb *
+ tcp_disconnect __P((struct tcpcb *));
+struct tcpcb *
+ tcp_drop __P((struct tcpcb *, int));
+void tcp_dooptions __P((struct tcpcb *, u_char *, int, struct tcphdr *,
+ int *, u_int32_t *, u_int32_t *));
+void tcp_drain __P((void));
+void tcp_fasttimo __P((void));
+void tcp_init __P((void));
+#if defined(INET6) && !defined(TCP6)
+int tcp6_input __P((struct mbuf **, int *, int));
+#endif
+void tcp_input __P((struct mbuf *, ...));
+int tcp_mss __P((struct tcpcb *, u_int));
+struct tcpcb *
+ tcp_newtcpcb __P((struct inpcb *));
+void tcp_notify __P((struct inpcb *, int));
+int tcp_output __P((struct tcpcb *));
+void tcp_pulloutofband __P((struct socket *, u_int, struct mbuf *, int));
+void tcp_quench __P((struct inpcb *, int));
+int tcp_reass __P((struct tcpcb *, struct tcphdr *, struct mbuf *, int *));
+void tcp_respond __P((struct tcpcb *, caddr_t, struct mbuf *, tcp_seq,
+ tcp_seq, int));
+void tcp_setpersist __P((struct tcpcb *));
+void tcp_slowtimo __P((void));
+struct mbuf *
+ tcp_template __P((struct tcpcb *));
+struct tcpcb *
+ tcp_timers __P((struct tcpcb *, int));
+void tcp_trace __P((int, int, struct tcpcb *, caddr_t, int, int));
+struct tcpcb *
+ tcp_usrclosed __P((struct tcpcb *));
+int tcp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+#if defined(INET6) && !defined(TCP6)
+int tcp6_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *));
+#endif
+int tcp_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+void tcp_xmit_timer __P((struct tcpcb *, int));
+void tcpdropoldhalfopen __P((struct tcpcb *, u_int16_t));
+#ifdef TCP_SACK
+int tcp_sack_option __P((struct tcpcb *,struct tcphdr *,u_char *,int));
+void tcp_update_sack_list __P((struct tcpcb *tp));
+void tcp_del_sackholes __P((struct tcpcb *, struct tcphdr *));
+void tcp_clean_sackreport __P((struct tcpcb *tp));
+void tcp_sack_adjust __P((struct tcpcb *tp));
+struct sackhole *
+ tcp_sack_output __P((struct tcpcb *tp));
+int tcp_sack_partialack __P((struct tcpcb *, struct tcphdr *));
+#ifdef DEBUG
+void tcp_print_holes __P((struct tcpcb *tp));
+#endif
+#endif /* TCP_SACK */
+#if defined(TCP_NEWRENO) || defined(TCP_SACK)
+int tcp_newreno __P((struct tcpcb *, struct tcphdr *));
+u_long tcp_seq_subtract __P((u_long, u_long ));
+#endif /* TCP_NEWRENO || TCP_SACK */
+#ifdef TCP_SIGNATURE
+int tcp_signature_apply __P((caddr_t, caddr_t, unsigned int));
+#endif /* TCP_SIGNATURE */
+
+#endif /* _KERNEL */
+
+#endif // _NETINET_TCP_VAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/tcpip.h b/ecos/packages/net/tcpip/current/include/netinet/tcpip.h
new file mode 100644
index 0000000..d8c59b3
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/tcpip.h
@@ -0,0 +1,95 @@
+//==========================================================================
+//
+// include/netinet/tcpip.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcpip.h,v 1.4 1997/08/26 20:02:35 deraadt Exp $ */
+/* $NetBSD: tcpip.h,v 1.6 1995/11/21 01:07:44 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcpip.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCPIP_H_
+#define _NETINET_TCPIP_H_
+
+/*
+ * Tcp+ip header, after ip options removed.
+ */
+struct tcpiphdr {
+ /* overlaid ip structure */
+ struct ipovly ti_i __attribute__ ((aligned(1), packed));
+ struct tcphdr ti_t; /* tcp header */
+};
+#define ti_x1 ti_i.ih_x1
+#define ti_pr ti_i.ih_pr
+#define ti_len ti_i.ih_len
+#define ti_src ti_i.ih_src
+#define ti_dst ti_i.ih_dst
+#define ti_sport ti_t.th_sport
+#define ti_dport ti_t.th_dport
+#define ti_seq ti_t.th_seq
+#define ti_ack ti_t.th_ack
+#define ti_x2 ti_t.th_x2
+#define ti_off ti_t.th_off
+#define ti_flags ti_t.th_flags
+#define ti_win ti_t.th_win
+#define ti_sum ti_t.th_sum
+#define ti_urp ti_t.th_urp
+
+#endif // _NETINET_TCPIP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/udp.h b/ecos/packages/net/tcpip/current/include/netinet/udp.h
new file mode 100644
index 0000000..644497d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/udp.h
@@ -0,0 +1,82 @@
+//==========================================================================
+//
+// include/netinet/udp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: udp.h,v 1.3 1997/02/24 14:06:47 niklas Exp $ */
+/* $NetBSD: udp.h,v 1.6 1995/04/13 06:37:10 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)udp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_UDP_H_
+#define _NETINET_UDP_H_
+
+/*
+ * Udp protocol header.
+ * Per RFC 768, September, 1981.
+ */
+struct udphdr {
+ u_int16_t uh_sport; /* source port */
+ u_int16_t uh_dport; /* destination port */
+ u_int16_t uh_ulen; /* udp length */
+ u_int16_t uh_sum; /* udp checksum */
+} __attribute__ ((aligned(1), packed));
+
+#endif // _NETINET_UDP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet/udp_var.h b/ecos/packages/net/tcpip/current/include/netinet/udp_var.h
new file mode 100644
index 0000000..62949db
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet/udp_var.h
@@ -0,0 +1,141 @@
+//==========================================================================
+//
+// include/netinet/udp_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: udp_var.h,v 1.9 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)udp_var.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_UDP_VAR_H_
+#define _NETINET_UDP_VAR_H_
+
+/*
+ * UDP kernel structures and variables.
+ */
+struct udpiphdr {
+ /* overlaid ip structure */
+ struct ipovly ui_i __attribute__ ((aligned(1), packed));
+ struct udphdr ui_u; /* udp header */
+};
+#define ui_x1 ui_i.ih_x1
+#define ui_pr ui_i.ih_pr
+#define ui_len ui_i.ih_len
+#define ui_src ui_i.ih_src
+#define ui_dst ui_i.ih_dst
+#define ui_sport ui_u.uh_sport
+#define ui_dport ui_u.uh_dport
+#define ui_ulen ui_u.uh_ulen
+#define ui_sum ui_u.uh_sum
+
+struct udpstat {
+ /* input statistics: */
+ u_long udps_ipackets; /* total input packets */
+ u_long udps_hdrops; /* packet shorter than header */
+ u_long udps_badsum; /* checksum error */
+ u_long udps_nosum; /* no checksum */
+ u_long udps_badlen; /* data length larger than packet */
+ u_long udps_noport; /* no socket on port */
+ u_long udps_noportbcast; /* of above, arrived as broadcast */
+ u_long udps_nosec; /* dropped for lack of ipsec */
+ u_long udps_fullsock; /* not delivered, input socket full */
+ u_long udps_pcbhashmiss; /* input packets missing pcb hash */
+ /* output statistics: */
+ u_long udps_opackets; /* total output packets */
+};
+
+/*
+ * Names for UDP sysctl objects
+ */
+#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
+#define UDPCTL_BADDYNAMIC 2 /* return bad dynamic port bitmap */
+#define UDPCTL_RECVSPACE 3 /* receive buffer space */
+#define UDPCTL_SENDSPACE 4 /* send buffer space */
+#define UDPCTL_MAXID 5
+
+#define UDPCTL_NAMES { \
+ { 0, 0 }, \
+ { "checksum", CTLTYPE_INT }, \
+ { "baddynamic", CTLTYPE_STRUCT }, \
+ { "recvspace", CTLTYPE_INT }, \
+ { "sendspace", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+struct inpcbtable udbtable;
+struct udpstat udpstat;
+
+#if defined(INET6) && !defined(TCP6)
+void udp6_ctlinput __P((int, struct sockaddr *, void *));
+int udp6_input __P((struct mbuf **, int *, int));
+int udp6_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *));
+#endif
+void *udp_ctlinput __P((int, struct sockaddr *, void *));
+void udp_init __P((void));
+void udp_input __P((struct mbuf *, ...));
+int udp_output __P((struct mbuf *, ...));
+int udp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+int udp_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+#endif
+
+#endif // _NETINET_UDP_VAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/debug.h b/ecos/packages/net/tcpip/current/include/netinet6/debug.h
new file mode 100644
index 0000000..6ea57f7
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/debug.h
@@ -0,0 +1,244 @@
+//==========================================================================
+//
+// include/netinet6_sys_debug.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_SYS_DEBUG_H
+#define _NETINET6_SYS_DEBUG_H 1
+
+#ifdef DEBUG_NRL
+#include <sys/osdep.h>
+#else /* DEBUG_NRL */
+#if __OpenBSD__
+#include <netinet6/osdep.h>
+#else /* __OpenBSD__ */
+#include <sys/osdep.h>
+#endif /* __OpenBSD__ */
+#endif /* DEBUG_NRL */
+
+/* Non-ANSI compilers don't stand a chance. You PROBABLY need GNU C. */
+#ifndef __STDC__
+#error An ANSI C compiler is required here.
+#endif /* __STDC__ */
+
+#ifndef _KERN_DEBUG_GENERIC_C
+extern int debug_level;
+#endif /* _KERN_DEBUG_GENERIC_DEBUG_C */
+
+/* Debugging levels */
+
+#define __DEBUG_LEVEL_ALL (INT_MAX-1) /* Report all messages. */
+#define __DEBUG_LEVEL_NONE 0 /* Report no messages. */
+
+#define __DEBUG_LEVEL_CRITICAL 3
+#define __DEBUG_LEVEL_ERROR 7
+#define __DEBUG_LEVEL_MAJOREVENT 10
+#define __DEBUG_LEVEL_EVENT 15
+#define __DEBUG_LEVEL_GROSSEVENT 20
+#define __DEBUG_LEVEL_FINISHED 1000
+
+/* Compatibility macros */
+
+#define __DEBUG_LEVEL_MAJOR_EVENT __DEBUG_LEVEL_MAJOREVENT
+#define __DEBUG_LEVEL_GROSS_EVENT __DEBUG_LEVEL_GROSSEVENT
+#define __DEBUG_LEVEL_IDL_CRITICAL __DEBUG_LEVEL_CRITICAL
+#define __DEBUG_LEVEL_IDL_ERROR __DEBUG_LEVEL_ERROR
+#define __DEBUG_LEVEL_IDL_MAJOR_EVENT __DEBUG_LEVEL_MAJOREVENT
+#define __DEBUG_LEVEL_IDL_EVENT __DEBUG_LEVEL_EVENT
+#define __DEBUG_LEVEL_IDL_GROSS_EVENT __DEBUG_LEVEL_GROSSEVENT
+#define __DEBUG_LEVEL_IDL_FINISHED __DEBUG_LEVEL_FINISHED
+
+/* Unless you have optimization turned off and your compiler is drain bamaged,
+ this will turn in to a syntactically inert no-op - cmetz */
+#define __DEBUG_NOP do { } while (0)
+
+#ifdef DEBUG_NRL
+/*
+ * Make sure argument for DPRINTF is in parentheses.
+ *
+ * For both DPRINTF and DDO, and attempt was made to make both macros
+ * be usable as normal C statments. There is a small amount of compiler
+ * trickery (if-else clauses with effectively null statements), which may
+ * cause a few compilers to complain.
+ */
+
+#ifndef __GENERIC_DEBUG_LEVEL
+#define __GENERIC_DEBUG_LEVEL debug_level
+#endif /* __GENERIC_DEBUG_LEVEL */
+
+/*
+ * DPRINTF() is a general printf statement. The "arg" is literally what
+ * would follow the function name printf, which means it has to be in
+ * parenthesis. Unlimited arguments can be used this way.
+ *
+ * EXAMPLE:
+ * DPRINTF(IDL_MAJOR_EVENT,("Hello, world. IP version %d.\n",vers));
+ */
+#undef DPRINTF
+#define DPRINTF(lev,arg) \
+ if (__DEBUG_LEVEL_ ## lev <= __GENERIC_DEBUG_LEVEL) { \
+ printf arg; \
+ } else \
+ __DEBUG_NOP
+
+/*
+ * DDO() executes a series of statements at a certain debug level. The
+ * "stmt" argument is a statement in the sense of a "statement list" in a
+ * C grammar. "stmt" does not have to end with a semicolon.
+ *
+ * EXAMPLE:
+ * DDO(IDL_CRITICAL,dump_ipv6(header), dump_inpcb(inp));
+ */
+#undef DDO
+#define DDO(lev,stmt) \
+ if (__DEBUG_LEVEL_ ## lev <= __GENERIC_DEBUG_LEVEL) { \
+ stmt ; \
+ } else \
+ __DEBUG_NOP
+
+/*
+ * DP() is a shortcut for DPRINTF(). Basically:
+ *
+ * DP(lev, var, fmt) == DPRINTF(IDL_lev, ("var = %fmt\n", var))
+ *
+ * It is handy for printing single variables without a lot of typing.
+ *
+ * EXAMPLE:
+ *
+ * DP(CRITICAL,length,d);
+ * same as DPRINTF(IDL_CRITICAL, ("length = %d\n", length))
+ */
+#undef DP
+#define DP(lev, var, fmt) \
+ DPRINTF(lev, (#var " = %" #fmt "\n", var))
+
+#undef DEBUG_STATUS
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+#define DEBUG_STATUS debug_status(__FILE__ ":" __FUNCTION__, __LINE__, __builtin_return_address(0))
+#else /* defined(__GNUC__) && (__GNUC__ >= 2) */
+#define DEBUG_STATUS debug_status(__FILE__, __LINE__, (void *)0)
+#endif /* defined(__GNUC__) && (__GNUC__ >= 2) */
+
+/* Call as:
+
+ DS();
+*/
+#undef DS
+#define DS() DPRINTF(IDL_CRITICAL, ("%s\n", DEBUG_STATUS))
+#else /* DEBUG_NRL */
+#undef DPRINTF
+#define DPRINTF(lev,arg) __DEBUG_NOP
+#undef DDO
+#define DDO(lev, stmt) __DEBUG_NOP
+#undef DP
+#define DP(x, y, z) __DEBUG_NOP
+#undef DS
+#define DS() __DEBUG_NOP
+#endif /* DEBUG_NRL */
+
+#ifdef DEBUG_MALLOC
+void *debug_malloc_malloc(unsigned int n, char *creator);
+void debug_malloc_free(void *p);
+void debug_malloc_dump(void);
+void debug_malloc_flush(void);
+#endif /* DEBUG_MALLOC */
+
+#ifdef DEBUG_NRL
+char *debug_status(char *filefunction, unsigned int line, void *returnaddress);
+void dump_buf_small(void *, int);
+void debug_dump_buf(void *, int);
+void dump_packet(void *buf, int len);
+
+struct dump_flags {
+ int val;
+ char *name;
+};
+void dump_flags(struct dump_flags *, int);
+
+struct sockaddr;
+void dump_sockaddr(struct sockaddr *);
+void dump_smart_sockaddr(void *);
+
+#ifdef __linux__
+struct sk_buff;
+void dump_skb(struct sk_buff *);
+#endif /* __linux__ */
+
+#ifdef OSDEP_BSD
+struct sockaddr_dl;
+void dump_sockaddr_dl(struct sockaddr_dl *);
+struct mbuf;
+void dump_mbuf_flags(struct mbuf *);
+void dump_mbuf_hdr(struct mbuf *);
+void dump_mbuf(struct mbuf *);
+void dump_mchain_hdr(struct mbuf *);
+void dump_mchain(struct mbuf *);
+void dump_mbuf_tcpdump(struct mbuf *);
+struct ifaddr;
+void dump_ifa(struct ifaddr *);
+struct ifnet;
+void dump_ifp(struct ifnet *);
+struct route;
+void dump_route(struct route *);
+struct rtentry;
+void dump_rtentry(struct rtentry *);
+struct inpcb;
+void dump_inpcb(struct inpcb *);
+#if __NetBSD__ || __OpenBSD__
+struct inpcbtable;
+void dump_inpcbs(struct inpcbtable *);
+#else /* __NetBSD__ || __OpenBSD__ */
+void dump_inpcbs(struct inpcb *);
+#endif /* __NetBSD__ || __OpenBSD__ */
+#endif /* OSDEP_BSD */
+
+#ifdef INET
+struct in_addr;
+void dump_in_addr(struct in_addr *);
+struct sockaddr_in;
+void dump_sockaddr_in(struct sockaddr_in *);
+#endif /* INET */
+
+#ifdef INET6
+#include <netinet6/debug_inet6.h>
+#endif /* INET6 */
+#endif /* DEBUG_NRL */
+
+#endif /* _NETINET6_SYS_DEBUG_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/debug_inet6.h b/ecos/packages/net/tcpip/current/include/netinet6/debug_inet6.h
new file mode 100644
index 0000000..6e6dc95
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/debug_inet6.h
@@ -0,0 +1,55 @@
+//==========================================================================
+//
+// include/netinet6_debug_inet6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_DEBUG_INET6_H
+#define _NETINET6_DEBUG_INET6_H 1
+
+struct in6_addr;
+void dump_in6_addr(struct in6_addr *);
+struct sockaddr_in6;
+void dump_sockaddr_in6(struct sockaddr_in6 *);
+struct ipv6;
+void dump_ipv6(struct ipv6 *ipv6);
+struct ipv6_icmp;
+void dump_ipv6_icmp(struct ipv6_icmp *icp);
+struct discq;
+void dump_discq(struct discq *dq);
+#endif /* _NETINET6_DEBUG_INET6_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/icmp6.h b/ecos/packages/net/tcpip/current/include/netinet6/icmp6.h
new file mode 100644
index 0000000..bf3076d
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/icmp6.h
@@ -0,0 +1,680 @@
+//==========================================================================
+//
+// include/netinet6_icmpv6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: icmp6.h,v 1.2 1999/12/10 10:04:27 angelos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET6_ICMPV6_H_
+#define _NETINET6_ICMPV6_H_
+
+#define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr)
+ - sizeof(struct icmp6_hdr) */
+
+struct icmp6_hdr {
+ u_int8_t icmp6_type; /* type field */
+ u_int8_t icmp6_code; /* code field */
+ u_int16_t icmp6_cksum; /* checksum field */
+ union {
+ u_int32_t icmp6_un_data32[1]; /* type-specific field */
+ u_int16_t icmp6_un_data16[2]; /* type-specific field */
+ u_int8_t icmp6_un_data8[4]; /* type-specific field */
+ } icmp6_dataun;
+};
+
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr icmp6_data32[0] /* parameter prob */
+#define icmp6_mtu icmp6_data32[0] /* packet too big */
+#define icmp6_id icmp6_data16[0] /* echo request/reply */
+#define icmp6_seq icmp6_data16[1] /* echo request/reply */
+#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
+
+#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
+#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
+#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
+#define ICMP6_PARAM_PROB 4 /* ip6 header bad */
+
+#define ICMP6_ECHO_REQUEST 128 /* echo service */
+#define ICMP6_ECHO_REPLY 129 /* echo reply */
+#define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */
+#define MLD6_LISTENER_QUERY 130 /* multicast listener query */
+#define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */
+#define MLD6_LISTENER_REPORT 131 /* multicast listener report */
+#define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */
+#define MLD6_LISTENER_DONE 132 /* multicast listener done */
+
+#define ND_ROUTER_SOLICIT 133 /* router solicitation */
+#define ND_ROUTER_ADVERT 134 /* router advertisment */
+#define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
+#define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisment */
+#define ND_REDIRECT 137 /* redirect */
+
+#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
+
+#define ICMP6_WRUREQUEST 139 /* who are you request */
+#define ICMP6_WRUREPLY 140 /* who are you reply */
+#define ICMP6_FQDN_QUERY 139 /* FQDN query */
+#define ICMP6_FQDN_REPLY 140 /* FQDN reply */
+#define ICMP6_NI_QUERY 139 /* node information request */
+#define ICMP6_NI_REPLY 140 /* node information reply */
+
+/* The definitions below are experimental. TBA */
+#define MLD6_MTRACE_RESP 141 /* mtrace response(to sender) */
+#define MLD6_MTRACE 142 /* mtrace messages */
+
+#define ICMP6_MAXTYPE 142
+
+#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
+#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
+#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
+#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
+#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
+
+#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
+#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
+
+#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
+#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */
+#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */
+
+#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
+
+#define ICMP6_NI_SUCESS 0 /* node information successful reply */
+#define ICMP6_NI_REFUSED 1 /* node information request is refused */
+#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
+
+#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */
+#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */
+#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */
+
+/* Used in kernel only */
+#define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */
+#define ND_REDIRECT_ROUTER 1 /* redirect to a better router */
+
+/*
+ * Multicast Listener Discovery
+ */
+struct mld6_hdr {
+ struct icmp6_hdr mld6_hdr;
+ struct in6_addr mld6_addr; /* multicast address */
+};
+
+#define mld6_type mld6_hdr.icmp6_type
+#define mld6_code mld6_hdr.icmp6_code
+#define mld6_cksum mld6_hdr.icmp6_cksum
+#define mld6_maxdelay mld6_hdr.icmp6_data16[0]
+#define mld6_reserved mld6_hdr.icmp6_data16[1]
+
+/*
+ * Neighbor Discovery
+ */
+
+struct nd_router_solicit { /* router solicitation */
+ struct icmp6_hdr nd_rs_hdr;
+ /* could be followed by options */
+};
+
+#define nd_rs_type nd_rs_hdr.icmp6_type
+#define nd_rs_code nd_rs_hdr.icmp6_code
+#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert { /* router advertisement */
+ struct icmp6_hdr nd_ra_hdr;
+ u_int32_t nd_ra_reachable; /* reachable time */
+ u_int32_t nd_ra_retransmit; /* retransmit timer */
+ /* could be followed by options */
+};
+
+#define nd_ra_type nd_ra_hdr.icmp6_type
+#define nd_ra_code nd_ra_hdr.icmp6_code
+#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED 0x80
+#define ND_RA_FLAG_OTHER 0x40
+#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit { /* neighbor solicitation */
+ struct icmp6_hdr nd_ns_hdr;
+ struct in6_addr nd_ns_target; /*target address */
+ /* could be followed by options */
+};
+
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert { /* neighbor advertisement */
+ struct icmp6_hdr nd_na_hdr;
+ struct in6_addr nd_na_target; /* target address */
+ /* could be followed by options */
+};
+
+#define nd_na_type nd_na_hdr.icmp6_type
+#define nd_na_code nd_na_hdr.icmp6_code
+#define nd_na_cksum nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
+#if BYTE_ORDER == BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80000000
+#define ND_NA_FLAG_SOLICITED 0x40000000
+#define ND_NA_FLAG_OVERRIDE 0x20000000
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80
+#define ND_NA_FLAG_SOLICITED 0x40
+#define ND_NA_FLAG_OVERRIDE 0x20
+#endif
+#endif
+
+struct nd_redirect { /* redirect */
+ struct icmp6_hdr nd_rd_hdr;
+ struct in6_addr nd_rd_target; /* target address */
+ struct in6_addr nd_rd_dst; /* destination address */
+ /* could be followed by options */
+};
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr { /* Neighbor discovery option header */
+ u_int8_t nd_opt_type;
+ u_int8_t nd_opt_len;
+ /* followed by option specific data*/
+};
+
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define ND_OPT_PREFIX_INFORMATION 3
+#define ND_OPT_REDIRECTED_HEADER 4
+#define ND_OPT_MTU 5
+
+struct nd_opt_prefix_info { /* prefix information */
+ u_int8_t nd_opt_pi_type;
+ u_int8_t nd_opt_pi_len;
+ u_int8_t nd_opt_pi_prefix_len;
+ u_int8_t nd_opt_pi_flags_reserved;
+ u_int32_t nd_opt_pi_valid_time;
+ u_int32_t nd_opt_pi_preferred_time;
+ u_int32_t nd_opt_pi_reserved2;
+ struct in6_addr nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK 0x80
+#define ND_OPT_PI_FLAG_AUTO 0x40
+
+struct nd_opt_rd_hdr { /* redirected header */
+ u_int8_t nd_opt_rh_type;
+ u_int8_t nd_opt_rh_len;
+ u_int16_t nd_opt_rh_reserved1;
+ u_int32_t nd_opt_rh_reserved2;
+ /* followed by IP header and data */
+};
+
+struct nd_opt_mtu { /* MTU option */
+ u_int8_t nd_opt_mtu_type;
+ u_int8_t nd_opt_mtu_len;
+ u_int16_t nd_opt_mtu_reserved;
+ u_int32_t nd_opt_mtu_mtu;
+};
+
+/*
+ * icmp6 namelookup
+ */
+
+struct icmp6_namelookup {
+ struct icmp6_hdr icmp6_nl_hdr;
+ u_int64_t icmp6_nl_nonce;
+ u_int32_t icmp6_nl_ttl;
+#if 0
+ u_int8_t icmp6_nl_len;
+ u_int8_t icmp6_nl_name[3];
+#endif
+ /* could be followed by options */
+};
+
+/*
+ * icmp6 node information
+ */
+struct icmp6_nodeinfo {
+ struct icmp6_hdr icmp6_ni_hdr;
+ u_int64_t icmp6_ni_nonce;
+ /* could be followed by reply data */
+};
+
+#define ni_type icmp6_ni_hdr.icmp6_type
+#define ni_code icmp6_ni_hdr.icmp6_code
+#define ni_cksum icmp6_ni_hdr.icmp6_cksum
+#define ni_qtype icmp6_ni_hdr.icmp6_data16[0]
+#define ni_flags icmp6_ni_hdr.icmp6_data16[1]
+
+
+#define NI_QTYPE_NOOP 0 /* NOOP */
+#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */
+#define NI_QTYPE_FQDN 2 /* FQDN */
+#define NI_QTYPE_NODEADDR 3 /* Node Addresses. XXX: spec says 2, but it may be a typo... */
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_SUPTYPE_FLAG_COMPRESS 0x1
+#define NI_FQDN_FLAG_VALIDTTL 0x1
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x1
+#define NI_NODEADDR_FLAG_SITELOCAL 0x2
+#define NI_NODEADDR_FLAG_GLOBAL 0x4
+#define NI_NODEADDR_FLAG_ALL 0x8
+#define NI_NODEADDR_FLAG_TRUNCATE 0x10
+#define NI_NODEADDR_FLAG_ANYCAST 0x20 /* just experimental. not in spec */
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_SUPTYPE_FLAG_COMPRESS 0x0100
+#define NI_FQDN_FLAG_VALIDTTL 0x0100
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x0100
+#define NI_NODEADDR_FLAG_SITELOCAL 0x0200
+#define NI_NODEADDR_FLAG_GLOBAL 0x0400
+#define NI_NODEADDR_FLAG_ALL 0x0800
+#define NI_NODEADDR_FLAG_TRUNCATE 0x1000
+#define NI_NODEADDR_FLAG_ANYCAST 0x2000 /* just experimental. not in spec */
+#endif
+
+struct ni_reply_fqdn {
+ u_int32_t ni_fqdn_ttl; /* TTL */
+ u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */
+ u_int8_t ni_fqdn_name[3]; /* XXX: alignment */
+};
+
+/*
+ * Router Renumbering. as router-renum-08.txt
+ */
+#if BYTE_ORDER == BIG_ENDIAN /* net byte order */
+struct icmp6_router_renum { /* router renumbering header */
+ struct icmp6_hdr rr_hdr;
+ u_int8_t rr_segnum;
+ u_int8_t rr_test : 1;
+ u_int8_t rr_reqresult : 1;
+ u_int8_t rr_forceapply : 1;
+ u_int8_t rr_specsite : 1;
+ u_int8_t rr_prevdone : 1;
+ u_int8_t rr_flags_reserved : 3;
+ u_int16_t rr_maxdelay;
+ u_int32_t rr_reserved;
+};
+#elif BYTE_ORDER == LITTLE_ENDIAN
+struct icmp6_router_renum { /* router renumbering header */
+ struct icmp6_hdr rr_hdr;
+ u_int8_t rr_segnum;
+ u_int8_t rr_flags_reserved : 3;
+ u_int8_t rr_prevdone : 1;
+ u_int8_t rr_specsite : 1;
+ u_int8_t rr_forceapply : 1;
+ u_int8_t rr_reqresult : 1;
+ u_int8_t rr_test : 1;
+ u_int16_t rr_maxdelay;
+ u_int32_t rr_reserved;
+};
+#endif /* BYTE_ORDER */
+
+#define rr_type rr_hdr.icmp6_type
+#define rr_code rr_hdr.icmp6_code
+#define rr_cksum rr_hdr.icmp6_cksum
+#define rr_seqnum rr_hdr.icmp6_data32[0]
+
+struct rr_pco_match { /* match prefix part */
+ u_int8_t rpm_code;
+ u_int8_t rpm_len;
+ u_int8_t rpm_ordinal;
+ u_int8_t rpm_matchlen;
+ u_int8_t rpm_minlen;
+ u_int8_t rpm_maxlen;
+ u_int16_t rpm_reserved;
+ struct in6_addr rpm_prefix;
+};
+
+#define RPM_PCO_ADD 1
+#define RPM_PCO_CHANGE 2
+#define RPM_PCO_SETGLOBAL 3
+#define RPM_PCO_MAX 4
+
+#if BYTE_ORDER == BIG_ENDIAN /* net byte order */
+struct rr_pco_use { /* use prefix part */
+ u_int8_t rpu_uselen;
+ u_int8_t rpu_keeplen;
+ u_int8_t rpu_mask_onlink : 1;
+ u_int8_t rpu_mask_autonomous : 1;
+ u_int8_t rpu_mask_reserved : 6;
+ u_int8_t rpu_onlink : 1;
+ u_int8_t rpu_autonomous : 1;
+ u_int8_t rpu_raflags_reserved : 6;
+ u_int32_t rpu_vltime;
+ u_int32_t rpu_pltime;
+ u_int32_t rpu_decr_vltime : 1;
+ u_int32_t rpu_decr_pltime : 1;
+ u_int32_t rpu_flags_reserved : 6;
+ u_int32_t rpu_reserved : 24;
+ struct in6_addr rpu_prefix;
+};
+#elif BYTE_ORDER == LITTLE_ENDIAN
+struct rr_pco_use { /* use prefix part */
+ u_int8_t rpu_uselen;
+ u_int8_t rpu_keeplen;
+ u_int8_t rpu_mask_reserved : 6;
+ u_int8_t rpu_mask_autonomous : 1;
+ u_int8_t rpu_mask_onlink : 1;
+ u_int8_t rpu_raflags_reserved : 6;
+ u_int8_t rpu_autonomous : 1;
+ u_int8_t rpu_onlink : 1;
+ u_int32_t rpu_vltime;
+ u_int32_t rpu_pltime;
+ u_int32_t rpu_flags_reserved : 6;
+ u_int32_t rpu_decr_pltime : 1;
+ u_int32_t rpu_decr_vltime : 1;
+ u_int32_t rpu_reserved : 24;
+ struct in6_addr rpu_prefix;
+};
+#endif /* BYTE_ORDER */
+
+#if BYTE_ORDER == BIG_ENDIAN /* net byte order */
+struct rr_result { /* router renumbering result message */
+ u_int8_t rrr_reserved;
+ u_int8_t rrr_flags_reserved : 6;
+ u_int8_t rrr_outofbound : 1;
+ u_int8_t rrr_forbidden : 1;
+ u_int8_t rrr_ordinal;
+ u_int8_t rrr_matchedlen;
+ u_int32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+};
+#elif BYTE_ORDER == LITTLE_ENDIAN
+struct rr_result { /* router renumbering result message */
+ u_int8_t rrr_reserved;
+ u_int8_t rrr_forbidden : 1;
+ u_int8_t rrr_outofbound : 1;
+ u_int8_t rrr_flags_reserved : 6;
+ u_int8_t rrr_ordinal;
+ u_int8_t rrr_matchedlen;
+ u_int32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+};
+#endif /* BYTE_ORDER */
+
+/*
+ * icmp6 filter structures.
+ */
+
+struct icmp6_filter {
+ u_int32_t icmp6_filter[8];
+};
+
+#ifdef _KERNEL
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+ { \
+ int i; u_char *p; \
+ p = (u_char *)filterp; \
+ for (i = 0; i < sizeof(struct icmp6_filter); i++) \
+ p[i] = 0xff; \
+ }
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+ bzero(filterp, sizeof(struct icmp6_filter))
+#else /* _KERNEL */
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+ memset(filterp, 0xff, sizeof(struct icmp6_filter))
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+ memset(filterp, 0x00, sizeof(struct icmp6_filter))
+#endif /* _KERNEL */
+
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+ (((filterp)->icmp6_filter[(type) >> 5]) |= (1 << ((type) & 31)))
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+ (((filterp)->icmp6_filter[(type) >> 5]) &= ~(1 << ((type) & 31)))
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+ ((((filterp)->icmp6_filter[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filter[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+
+/*
+ * Variables related to this implementation
+ * of the internet control message protocol version 6.
+ */
+struct icmp6stat {
+/* statistics related to icmp6 packets generated */
+ u_quad_t icp6s_error; /* # of calls to icmp6_error */
+ u_quad_t icp6s_canterror; /* no error 'cuz old was icmp */
+ u_quad_t icp6s_toofreq; /* no error 'cuz rate limitation */
+ u_quad_t icp6s_outhist[256];
+/* statistics related to input message processed */
+ u_quad_t icp6s_badcode; /* icmp6_code out of range */
+ u_quad_t icp6s_tooshort; /* packet < sizeof(struct icmp6_hdr) */
+ u_quad_t icp6s_checksum; /* bad checksum */
+ u_quad_t icp6s_badlen; /* calculated bound mismatch */
+ u_quad_t icp6s_reflect; /* number of responses */
+ u_quad_t icp6s_inhist[256];
+ u_quad_t icp6s_nd_toomanyopt; /* too many ND options */
+};
+
+/*
+ * Names for ICMP sysctl objects
+ */
+#define ICMPV6CTL_STATS 1
+#define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */
+#define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */
+#define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */
+#define ICMPV6CTL_ND6_PRUNE 6
+#define ICMPV6CTL_ND6_DELAY 8
+#define ICMPV6CTL_ND6_UMAXTRIES 9
+#define ICMPV6CTL_ND6_MMAXTRIES 10
+#define ICMPV6CTL_ND6_USELOOPBACK 11
+#define ICMPV6CTL_ND6_PROXYALL 12
+#define ICMPV6CTL_MAXID 13
+
+#define ICMPV6CTL_NAMES { \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "rediraccept", CTLTYPE_INT }, \
+ { "redirtimeout", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { "errratelimit", CTLTYPE_INT }, \
+ { "nd6_prune", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { "nd6_delay", CTLTYPE_INT }, \
+ { "nd6_umaxtries", CTLTYPE_INT }, \
+ { "nd6_mmaxtries", CTLTYPE_INT }, \
+ { "nd6_useloopback", CTLTYPE_INT }, \
+ { "nd6_proxyall", CTLTYPE_INT }, \
+}
+
+#define ICMPV6CTL_VARS { \
+ 0, \
+ 0, \
+ &icmp6_rediraccept, \
+ &icmp6_redirtimeout, \
+ 0, \
+ 0, \
+ &icmp6errratelim, \
+ &nd6_prune, \
+ 0, \
+ &nd6_delay, \
+ &nd6_umaxtries, \
+ &nd6_mmaxtries, \
+ &nd6_useloopback, \
+ &nd6_proxyall, \
+}
+
+#define RTF_PROBEMTU RTF_PROTO1
+
+#ifdef _KERNEL
+# ifdef __STDC__
+struct rtentry;
+struct rttimer;
+struct in6_multi;
+# endif
+void icmp6_init __P((void));
+void icmp6_paramerror __P((struct mbuf *, int));
+void icmp6_error __P((struct mbuf *, int, int, int));
+int icmp6_input __P((struct mbuf **, int *, int));
+void icmp6_fasttimo __P((void));
+void icmp6_reflect __P((struct mbuf *, size_t));
+void icmp6_prepare __P((struct mbuf *));
+void icmp6_redirect_input __P((struct mbuf *, int));
+void icmp6_redirect_output __P((struct mbuf *, struct rtentry *));
+int icmp6_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+
+/* XXX: is this the right place for these macros? */
+#define icmp6_ifstat_inc(ifp, tag) \
+do { \
+ if ((ifp) && (ifp)->if_index <= if_index \
+ && (ifp)->if_index < icmp6_ifstatmax \
+ && icmp6_ifstat && icmp6_ifstat[(ifp)->if_index]) { \
+ icmp6_ifstat[(ifp)->if_index]->tag++; \
+ } \
+} while (0)
+
+#define icmp6_ifoutstat_inc(ifp, type, code) \
+do { \
+ icmp6_ifstat_inc(ifp, ifs6_out_msg); \
+ if (type < ICMP6_INFOMSG_MASK) \
+ icmp6_ifstat_inc(ifp, ifs6_out_error); \
+ switch(type) { \
+ case ICMP6_DST_UNREACH: \
+ icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \
+ if (code == ICMP6_DST_UNREACH_ADMIN) \
+ icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \
+ break; \
+ case ICMP6_PACKET_TOO_BIG: \
+ icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \
+ break; \
+ case ICMP6_TIME_EXCEEDED: \
+ icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \
+ break; \
+ case ICMP6_PARAM_PROB: \
+ icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \
+ break; \
+ case ICMP6_ECHO_REQUEST: \
+ icmp6_ifstat_inc(ifp, ifs6_out_echo); \
+ break; \
+ case ICMP6_ECHO_REPLY: \
+ icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \
+ break; \
+ case MLD6_LISTENER_QUERY: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \
+ break; \
+ case MLD6_LISTENER_REPORT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \
+ break; \
+ case MLD6_LISTENER_DONE: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \
+ break; \
+ case ND_ROUTER_SOLICIT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \
+ break; \
+ case ND_ROUTER_ADVERT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \
+ break; \
+ case ND_NEIGHBOR_SOLICIT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \
+ break; \
+ case ND_NEIGHBOR_ADVERT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \
+ break; \
+ case ND_REDIRECT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_redirect); \
+ break; \
+ } \
+} while (0)
+
+extern int icmp6_rediraccept; /* accept/process redirects */
+extern int icmp6_redirtimeout; /* cache time for redirect routes */
+#endif /* _KERNEL */
+
+#endif /* not _NETINET6_ICMPV6_H_ */
+
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/icmpv6.h b/ecos/packages/net/tcpip/current/include/netinet6/icmpv6.h
new file mode 100644
index 0000000..0bc4903
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/icmpv6.h
@@ -0,0 +1,110 @@
+//==========================================================================
+//
+// include/netinet6_icmpv6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% portions-copyright-nrl-97
+Portions of this software are Copyright 1997-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_ICMPV6_H
+#define _NETINET6_ICMPV6_H 1
+
+#include <netinet6/ipv6.h>
+
+struct icmpv6hdr {
+ uint8_t icmpv6_type; /* type field */
+ uint8_t icmpv6_code; /* code field */
+ uint16_t icmpv6_cksum; /* checksum field */
+ union {
+ uint32_t un_data32[1]; /* type-specific field */
+ uint16_t un_data16[2]; /* type-specific field */
+ uint8_t un_data8[4]; /* type-specific field */
+ } icmpv6_dataun;
+};
+
+#define icmpv6_data32 icmpv6_dataun.un_data32
+#define icmpv6_data16 icmpv6_dataun.un_data16
+#define icmpv6_data8 icmpv6_dataun.un_data8
+#define icmpv6_pptr icmpv6_data32[0] /* parameter prob */
+#define icmpv6_mtu icmpv6_data32[0] /* packet too big */
+#define icmpv6_id icmpv6_data16[0] /* echo request/reply */
+#define icmpv6_seq icmpv6_data16[1] /* echo request/reply */
+#define icmpv6_maxdelay icmpv6_data16[0] /* mcast group membership */
+
+#define ICMPV6_DST_UNREACH 1
+#define ICMPV6_PACKET_TOOBIG 2
+#define ICMPV6_TIME_EXCEEDED 3
+#define ICMPV6_PARAMETER_PROBLEM 4
+
+#define ICMPV6_INFOMSG_MASK 128 /* all informational messages */
+#define ICMPV6_ECHO_REQUEST 128
+#define ICMPV6_ECHO_REPLY 129
+#define ICMPV6_MEMBERSHIP_QUERY 130
+#define ICMPV6_MEMBERSHIP_REPORT 131
+#define ICMPV6_MEMBERSHIP_REDUCTION 132
+
+#define ICMPV6_UNREACH_NOROUTE 0
+#define ICMPV6_UNREACH_ADMIN 1 /* administratively prohibited */
+#define ICMPV6_UNREACH_NOTNEIGHBOR 2 /* not a neighbor (and must be) */
+#define ICMPV6_UNREACH_ADDRESS 3
+#define ICMPV6_UNREACH_PORT 4
+
+#define ICMPV6_EXCEEDED_HOPS 0 /* Hop Limit == 0 in transit */
+#define ICMPV6_EXCEEDED_REASSEMBLY 1 /* Reassembly time out */
+
+#define ICMPV6_PARAMPROB_HDR 0 /* erroneous header field */
+#define ICMPV6_PARAMPROB_NEXTHDR 1 /* unrecognized Next Header */
+#define ICMPV6_PARAMPROB_OPTION 2 /* unrecognized option */
+
+struct icmpv6_filter {
+ uint32_t data[8]; /* 8*32 = 256 bits */
+};
+
+#define ICMPV6_FILTER_WILLPASS(type, filterp) \
+ ((((filterp)->data[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+#define ICMPV6_FILTER_WILLBLOCK(type, filterp) \
+ ((((filterp)->data[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+#define ICMPV6_FILTER_SETPASS(type, filterp) \
+ ((((filterp)->data[(type) >> 5]) &= ~(1 << ((type) & 31))))
+#define ICMPV6_FILTER_SETBLOCK(type, filterp) \
+ ((((filterp)->data[(type) >> 5]) |= (1 << ((type) & 31))))
+#define ICMPV6_FILTER_SETPASSALL(filterp) \
+ memset((filterp), 0, sizeof(struct icmpv6_filter))
+#define ICMPV6_FILTER_SETBLOCKALL(filterp) \
+ memset((filterp), 0xff, sizeof(struct icmpv6_filter))
+
+#endif /* _NETINET6_ICMPV6_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/icmpv6_var.h b/ecos/packages/net/tcpip/current/include/netinet6/icmpv6_var.h
new file mode 100644
index 0000000..2c29a76
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/icmpv6_var.h
@@ -0,0 +1,82 @@
+//==========================================================================
+//
+// include/netinet6_icmpv6_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_ICMPV6_VAR_H
+#define _NETINET6_ICMPV6_VAR_H 1
+
+#if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802
+#define _ICMPV6STAT_TYPE u_quad_t
+#else /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802 */
+#define _ICMPV6STAT_TYPE u_long
+#endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802 */
+
+struct icmpv6stat
+{
+ _ICMPV6STAT_TYPE icps_error;
+ _ICMPV6STAT_TYPE icps_tooshort;
+ _ICMPV6STAT_TYPE icps_checksum;
+ _ICMPV6STAT_TYPE icps_outhist[ICMPV6_MAXTYPE+1];
+ _ICMPV6STAT_TYPE icps_badlen;
+ _ICMPV6STAT_TYPE icps_badcode;
+ _ICMPV6STAT_TYPE icps_reflect; /* Number of in-kernel responses */
+ _ICMPV6STAT_TYPE icps_inhist[ICMPV6_MAXTYPE+1];
+};
+
+/*
+ * Names for ICMPV6 sysctl objects
+ */
+#define ICMPV6CTL_STATS 1 /* statistics */
+#define ICMPV6CTL_MAXID 2
+
+#define ICMPV6CTL_NAMES { \
+ { 0, 0 }, \
+ { "stats", CTLTYPE_STRUCT }, \
+}
+
+#define ICMPV6CTL_VARS { \
+ 0, \
+ 0, \
+}
+
+#if defined(_KERNEL) || defined(KERNEL)
+struct icmpv6stat icmpv6stat;
+#endif /* defined(_KERNEL) || defined(KERNEL) */
+#endif /* _NETINET6_ICMPV6_VAR_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/in6.h b/ecos/packages/net/tcpip/current/include/netinet6/in6.h
new file mode 100644
index 0000000..e5b572e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/in6.h
@@ -0,0 +1,682 @@
+//==========================================================================
+//
+// include/netinet6_in6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in6.h,v 1.9 1999/12/10 08:53:17 angelos Exp $ */
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in.h 8.3 (Berkeley) 1/3/94
+ */
+
+#ifndef _NETINET6_IN6_H_
+#define _NETINET6_IN6_H_
+
+#if !defined(_XOPEN_SOURCE)
+#include <sys/queue.h>
+#endif
+
+/*
+ * Identification of the network protocol stack
+ */
+#define __KAME__
+#define __KAME_VERSION "19991208/OpenBSD-current"
+
+/*
+ * Local port number conventions:
+ *
+ * Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root),
+ * unless a kernel is compiled with IPNOPRIVPORTS defined.
+ *
+ * When a user does a bind(2) or connect(2) with a port number of zero,
+ * a non-conflicting local port address is chosen.
+ *
+ * The default range is IPPORT_ANONMIX to IPPORT_ANONMAX, although
+ * that is settable by sysctl(3); net.inet.ip.anonportmin and
+ * net.inet.ip.anonportmax respectively.
+ *
+ * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
+ * default assignment range.
+ *
+ * The value IP_PORTRANGE_DEFAULT causes the default behavior.
+ *
+ * The value IP_PORTRANGE_HIGH is the same as IP_PORTRANGE_DEFAULT,
+ * and exists only for FreeBSD compatibility purposes.
+ *
+ * The value IP_PORTRANGE_LOW changes the range to the "low" are
+ * that is (by convention) restricted to privileged processes.
+ * This convention is based on "vouchsafe" principles only.
+ * It is only secure if you trust the remote host to restrict these ports.
+ * The range is IPPORT_RESERVEDMIN to IPPORT_RESERVEDMAX.
+ */
+
+#define IPV6PORT_RESERVED 1024
+#define IPV6PORT_ANONMIN 49152
+#define IPV6PORT_ANONMAX 65535
+#define IPV6PORT_RESERVEDMIN 600
+#define IPV6PORT_RESERVEDMAX (IPV6PORT_RESERVED-1)
+
+/*
+ * IPv6 address
+ */
+struct in6_addr {
+ union {
+ u_int8_t __u6_addr8[16];
+ u_int16_t __u6_addr16[8];
+ u_int32_t __u6_addr32[4];
+ } __u6_addr; /* 128-bit IP6 address */
+};
+
+#define s6_addr __u6_addr.__u6_addr8
+#ifdef _KERNEL /*XXX nonstandard*/
+#define s6_addr8 __u6_addr.__u6_addr8
+#define s6_addr16 __u6_addr.__u6_addr16
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
+#define INET6_ADDRSTRLEN 46
+
+/*
+ * Socket address for IPv6
+ */
+#if !defined(_XOPEN_SOURCE)
+#define SIN6_LEN
+#endif
+struct sockaddr_in6 {
+ u_char sin6_len; /* length of this struct(sa_family_t)*/
+ u_char sin6_family; /* AF_INET6 (sa_family_t) */
+ u_int16_t sin6_port; /* Transport layer port # (in_port_t)*/
+ u_int32_t sin6_flowinfo; /* IP6 flow information */
+ struct in6_addr sin6_addr; /* IP6 address */
+ u_int32_t sin6_scope_id; /* intface scope id */
+};
+
+/*
+ * Local definition for masks
+ */
+#ifdef _KERNEL /*XXX nonstandard*/
+#define IN6MASK0 {{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}}
+#define IN6MASK32 {{{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK64 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK96 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK128 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}
+#endif
+
+#ifdef _KERNEL
+extern const struct in6_addr in6mask0;
+extern const struct in6_addr in6mask32;
+extern const struct in6_addr in6mask64;
+extern const struct in6_addr in6mask96;
+extern const struct in6_addr in6mask128;
+#endif /* _KERNEL */
+
+/*
+ * Macros started with IPV6_ADDR is KAME local
+ */
+#ifdef _KERNEL /*XXX nonstandard*/
+#if BYTE_ORDER == BIG_ENDIAN
+#define IPV6_ADDR_INT32_ONE 1
+#define IPV6_ADDR_INT32_TWO 2
+#define IPV6_ADDR_INT32_MNL 0xff010000
+#define IPV6_ADDR_INT32_MLL 0xff020000
+#define IPV6_ADDR_INT32_SMP 0x0000ffff
+#define IPV6_ADDR_INT16_ULL 0xfe80
+#define IPV6_ADDR_INT16_USL 0xfec0
+#define IPV6_ADDR_INT16_MLL 0xff02
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define IPV6_ADDR_INT32_ONE 0x01000000
+#define IPV6_ADDR_INT32_TWO 0x02000000
+#define IPV6_ADDR_INT32_MNL 0x000001ff
+#define IPV6_ADDR_INT32_MLL 0x000002ff
+#define IPV6_ADDR_INT32_SMP 0xffff0000
+#define IPV6_ADDR_INT16_ULL 0x80fe
+#define IPV6_ADDR_INT16_USL 0xc0fe
+#define IPV6_ADDR_INT16_MLL 0x02ff
+#endif
+#endif
+
+/*
+ * Definition of some useful macros to handle IP6 addresses
+ */
+#define IN6ADDR_ANY_INIT \
+ {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6ADDR_LOOPBACK_INIT \
+ {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_NODELOCAL_ALLNODES_INIT \
+ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
+ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
+#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
+ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
+
+extern const struct in6_addr in6addr_any;
+extern const struct in6_addr in6addr_loopback;
+extern const struct in6_addr in6addr_nodelocal_allnodes;
+extern const struct in6_addr in6addr_linklocal_allnodes;
+extern const struct in6_addr in6addr_linklocal_allrouters;
+
+/*
+ * Equality
+ * NOTE: Some of kernel programming environment (for example, openbsd/sparc)
+ * does not supply memcmp(). For userland memcmp() is preferred as it is
+ * in ANSI standard.
+ */
+#ifdef _KERNEL
+#define IN6_ARE_ADDR_EQUAL(a, b) \
+ (bcmp((a), (b), sizeof(struct in6_addr)) == 0)
+#else
+#define IN6_ARE_ADDR_EQUAL(a, b) \
+ (memcmp((a), (b), sizeof(struct in6_addr)) == 0)
+#endif
+
+/*
+ * Unspecified
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ ((*(u_int32_t *)(&(a)->s6_addr[0]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[4]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[8]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[12]) == 0))
+
+/*
+ * Loopback
+ */
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ ((*(u_int32_t *)(&(a)->s6_addr[0]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[4]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[8]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[12]) == ntohl(1)))
+
+/*
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ ((*(u_int32_t *)(&(a)->s6_addr[0]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[4]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[8]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[12]) != 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[12]) != ntohl(1)))
+
+/*
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ ((*(u_int32_t *)(&(a)->s6_addr[0]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[4]) == 0) && \
+ (*(u_int32_t *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+
+/*
+ * KAME Scope Values
+ */
+
+#ifdef _KERNEL /*XXX nonstandard*/
+#define IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+#define IPV6_ADDR_SCOPE_SITELOCAL 0x05
+#define IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */
+#define IPV6_ADDR_SCOPE_GLOBAL 0x0e
+#else
+#define __IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define __IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+#define __IPV6_ADDR_SCOPE_SITELOCAL 0x05
+#define __IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */
+#define __IPV6_ADDR_SCOPE_GLOBAL 0x0e
+#endif
+
+/*
+ * Unicast Scope
+ * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
+ */
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+
+/*
+ * Multicast
+ */
+#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)
+
+#ifdef _KERNEL /*XXX nonstandard*/
+#define IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
+#else
+#define __IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
+#endif
+
+/*
+ * Multicast Scope
+ */
+#ifdef _KERNEL /*refers nonstandard items */
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
+#else
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL))
+#endif
+
+/*
+ * Wildcard Socket
+ */
+#if 0 /*pre-RFC2553*/
+#define IN6_IS_ADDR_ANY(a) IN6_IS_ADDR_UNSPECIFIED(a)
+#endif
+
+/*
+ * KAME Scope
+ */
+#ifdef _KERNEL /*nonstandard*/
+#define IN6_IS_SCOPE_LINKLOCAL(a) \
+ ((IN6_IS_ADDR_LINKLOCAL(a)) || \
+ (IN6_IS_ADDR_MC_LINKLOCAL(a)))
+#endif
+
+/*
+ * IP6 route structure
+ */
+#if !defined(_XOPEN_SOURCE)
+struct route_in6 {
+ struct rtentry *ro_rt;
+ struct sockaddr_in6 ro_dst;
+};
+#endif
+
+/*
+ * Options for use with [gs]etsockopt at the IPV6 level.
+ * First word of comment is data type; bool is stored in int.
+ */
+#define IPV6_OPTIONS 1 /* buf/ip6_opts; set/get IP6 options */
+/* no hdrincl */
+#define IPV6_SOCKOPT_RESERVED1 3 /* reserved for future use */
+#define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */
+#define IPV6_RECVOPTS 5 /* bool; receive all IP6 opts w/dgram */
+#define IPV6_RECVRETOPTS 6 /* bool; receive IP6 opts for response */
+#define IPV6_RECVDSTADDR 7 /* bool; receive IP6 dst addr w/dgram */
+#define IPV6_RETOPTS 8 /* ip6_opts; set/get IP6 options */
+#define IPV6_MULTICAST_IF 9 /* u_char; set/get IP6 multicast i/f */
+#define IPV6_MULTICAST_HOPS 10 /* u_char; set/get IP6 multicast hops */
+#define IPV6_MULTICAST_LOOP 11 /* u_char; set/get IP6 multicast loopback */
+#define IPV6_JOIN_GROUP 12 /* ip6_mreq; join a group membership */
+#define IPV6_LEAVE_GROUP 13 /* ip6_mreq; leave a group membership */
+#define IPV6_PORTRANGE 14 /* int; range to choose for unspec port */
+#define ICMP6_FILTER 18 /* icmp6_filter; icmp6 filter */
+#define IPV6_PKTINFO 19 /* bool; send/rcv if, src/dst addr */
+#define IPV6_HOPLIMIT 20 /* bool; hop limit */
+#define IPV6_NEXTHOP 21 /* bool; next hop addr */
+#define IPV6_HOPOPTS 22 /* bool; hop-by-hop option */
+#define IPV6_DSTOPTS 23 /* bool; destination option */
+#define IPV6_RTHDR 24 /* bool; routing header */
+#define IPV6_PKTOPTIONS 25 /* buf/cmsghdr; set/get IPv6 options */
+#define IPV6_CHECKSUM 26 /* int; checksum offset for raw socket */
+#define IPV6_BINDV6ONLY 27 /* bool; only bind INET6 at null bind */
+
+#if 1 /*IPSEC*/
+#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */
+#endif
+#define IPV6_FAITH 29 /* bool; accept FAITH'ed connections */
+
+#if 1 /*IPV6FIREWALL*/
+#define IPV6_FW_ADD 30 /* add a firewall rule to chain */
+#define IPV6_FW_DEL 31 /* delete a firewall rule from chain */
+#define IPV6_FW_FLUSH 32 /* flush firewall rule chain */
+#define IPV6_FW_ZERO 33 /* clear single/all firewall counter(s) */
+#define IPV6_FW_GET 34 /* get entire firewall rule chain */
+#endif
+
+#define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. XXX old spec */
+#define IPV6_RTHDR_STRICT 1 /* this hop must be a neighbor. XXX old spec */
+#define IPV6_RTHDR_TYPE_0 0 /* IPv6 routing header type 0 */
+
+/*
+ * Defaults and limits for options
+ */
+#define IPV6_DEFAULT_MULTICAST_HOPS 1 /* normally limit m'casts to 1 hop */
+#define IPV6_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
+
+/*
+ * Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP.
+ */
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr;
+ u_int ipv6mr_interface;
+};
+
+/*
+ * IPV6_PKTINFO: Packet information(RFC2292 sec 5)
+ */
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
+ u_int ipi6_ifindex; /* send/recv interface index */
+};
+
+/*
+ * Argument for IPV6_PORTRANGE:
+ * - which range to search when port is unspecified at bind() or connect()
+ */
+#define IPV6_PORTRANGE_DEFAULT 0 /* default range */
+#define IPV6_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */
+#define IPV6_PORTRANGE_LOW 2 /* "low" - vouchsafe security */
+
+#if !defined(_XOPEN_SOURCE)
+/*
+ * Definitions for inet6 sysctl operations.
+ *
+ * Third level is protocol number.
+ * Fourth level is desired variable within that protocol.
+ */
+#define IPV6PROTO_MAXID (IPPROTO_PIM + 1) /* don't list to IPV6PROTO_MAX */
+
+#define CTL_IPV6PROTO_NAMES { \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, \
+ { "tcp6", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "udp6", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, \
+ { "ip6", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, \
+ { "ipsec6", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "icmp6", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "pim6", CTLTYPE_NODE }, \
+}
+
+/*
+ * Names for IP sysctl objects
+ */
+#define IPV6CTL_FORWARDING 1 /* act as router */
+#define IPV6CTL_SENDREDIRECTS 2 /* may send redirects when forwarding*/
+#define IPV6CTL_DEFHLIM 3 /* default Hop-Limit */
+#ifdef notyet
+#define IPV6CTL_DEFMTU 4 /* default MTU */
+#endif
+#define IPV6CTL_FORWSRCRT 5 /* forward source-routed dgrams */
+#define IPV6CTL_STATS 6 /* stats */
+#define IPV6CTL_MRTSTATS 7 /* multicast forwarding stats */
+#define IPV6CTL_MRTPROTO 8 /* multicast routing protocol */
+#define IPV6CTL_MAXFRAGPACKETS 9 /* max packets reassembly queue */
+#define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */
+#define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimume logging interval */
+#define IPV6CTL_ACCEPT_RTADV 12
+#define IPV6CTL_KEEPFAITH 13
+#define IPV6CTL_LOG_INTERVAL 14
+#define IPV6CTL_HDRNESTLIMIT 15
+#define IPV6CTL_DAD_COUNT 16
+#define IPV6CTL_AUTO_FLOWLABEL 17
+#define IPV6CTL_DEFMCASTHLIM 18
+#define IPV6CTL_GIF_HLIM 19 /* default HLIM for gif encap packet */
+#define IPV6CTL_KAME_VERSION 20
+#define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */
+#define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */
+#ifdef MAPPED_ADDR_ENABLED
+#define IPV6CTL_MAPPED_ADDR 23
+#endif /* MAPPED_ADDR_ENABLED */
+/* New entries should be added here from current IPV6CTL_MAXID value. */
+#define IPV6CTL_MAXID 24
+
+#ifdef MAPPED_ADDR_ENABLED
+#define IPV6CTL_NAMES_MAPPED_ADDR "mapped_addr"
+#define IPV6CTL_TYPE_MAPPED_ADDR CTLTYPE_INT
+#define IPV6CTL_VARS_MAPPED_ADDR &ip6_mapped_addr_on
+#else /* MAPPED_ADDR_ENABLED */
+#define IPV6CTL_NAMES_MAPPED_ADDR 0
+#define IPV6CTL_TYPE_MAPPED_ADDR 0
+#define IPV6CTL_VARS_MAPPED_ADDR 0
+#endif /* MAPPED_ADDR_ENABLED */
+
+#define IPV6CTL_NAMES { \
+ { 0, 0 }, \
+ { "forwarding", CTLTYPE_INT }, \
+ { "redirect", CTLTYPE_INT }, \
+ { "hlim", CTLTYPE_INT }, \
+ { "mtu", CTLTYPE_INT }, \
+ { "forwsrcrt", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "mrtproto", CTLTYPE_INT }, \
+ { "maxfragpackets", CTLTYPE_INT }, \
+ { "sourcecheck", CTLTYPE_INT }, \
+ { "sourcecheck_logint", CTLTYPE_INT }, \
+ { "accept_rtadv", CTLTYPE_INT }, \
+ { "keepfaith", CTLTYPE_INT }, \
+ { "log_interval", CTLTYPE_INT }, \
+ { "hdrnestlimit", CTLTYPE_INT }, \
+ { "dad_count", CTLTYPE_INT }, \
+ { "auto_flowlabel", CTLTYPE_INT }, \
+ { "defmcasthlim", CTLTYPE_INT }, \
+ { "gifhlim", CTLTYPE_INT }, \
+ { "kame_version", CTLTYPE_STRING }, \
+ { "use_deprecated", CTLTYPE_INT }, \
+ { "rr_prune", CTLTYPE_INT }, \
+ { IPV6CTL_NAMES_MAPPED_ADDR, IPV6CTL_TYPE_MAPPED_ADDR }, \
+}
+
+#define IPV6CTL_VARS { \
+ 0, \
+ &ip6_forwarding, \
+ &ip6_sendredirects, \
+ &ip6_defhlim, \
+ 0, \
+ &ip6_forward_srcrt, \
+ 0, \
+ 0, \
+ 0, \
+ &ip6_maxfragpackets, \
+ &ip6_sourcecheck, \
+ &ip6_sourcecheck_interval, \
+ &ip6_accept_rtadv, \
+ &ip6_keepfaith, \
+ &ip6_log_interval, \
+ &ip6_hdrnestlimit, \
+ &ip6_dad_count, \
+ &ip6_auto_flowlabel, \
+ &ip6_defmcasthlim, \
+ &ip6_gif_hlim, \
+ 0, \
+ &ip6_use_deprecated, \
+ &ip6_rr_prune, \
+ IPV6CTL_VARS_MAPPED_ADDR, \
+}
+#endif /* !_XOPEN_SOURCE */
+
+#ifdef _KERNEL
+struct cmsghdr;
+struct mbuf;
+struct ifnet;
+
+int in6_canforward __P((struct in6_addr *, struct in6_addr *));
+int in6_cksum __P((struct mbuf *, u_int8_t, u_int32_t, u_int32_t));
+int in6_localaddr __P((struct in6_addr *));
+int in6_addrscope __P((struct in6_addr *));
+struct in6_ifaddr *in6_ifawithscope __P((struct ifnet *, struct in6_addr *));
+struct in6_ifaddr *in6_ifawithifp __P((struct ifnet *, struct in6_addr *));
+extern void in6_if_up __P((struct ifnet *));
+#ifdef MAPPED_ADDR_ENABLED
+struct sockaddr;
+
+void in6_sin6_2_sin __P((struct sockaddr_in *sin,
+ struct sockaddr_in6 *sin6));
+void in6_sin_2_v4mapsin6 __P((struct sockaddr_in *sin,
+ struct sockaddr_in6 *sin6));
+void in6_sin6_2_sin_in_sock __P((struct sockaddr *nam));
+void in6_sin_2_v4mapsin6_in_sock __P((struct sockaddr **nam));
+#endif /* MAPPED_ADDR_ENABLED */
+
+#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
+#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
+#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))
+#endif /* _KERNEL */
+
+__BEGIN_DECLS
+struct cmsghdr;
+
+extern int inet6_option_space(int);
+extern int inet6_option_init(void *, struct cmsghdr **, int);
+extern int inet6_option_append(struct cmsghdr *, const u_int8_t *, int, int);
+extern u_int8_t *inet6_option_alloc(struct cmsghdr *, int, int, int);
+extern int inet6_option_next(const struct cmsghdr *, u_int8_t **);
+extern int inet6_option_find(const struct cmsghdr *, u_int8_t **, int);
+
+extern size_t inet6_rthdr_space __P((int, int));
+extern struct cmsghdr *inet6_rthdr_init __P((void *, int));
+extern int inet6_rthdr_add __P((struct cmsghdr *, const struct in6_addr *,
+ unsigned int));
+extern int inet6_rthdr_lasthop __P((struct cmsghdr *, unsigned int));
+#if 0 /* not implemented yet */
+extern int inet6_rthdr_reverse __P((const struct cmsghdr *, struct cmsghdr *));
+#endif
+extern int inet6_rthdr_segments __P((const struct cmsghdr *));
+extern struct in6_addr *inet6_rthdr_getaddr __P((struct cmsghdr *, int));
+extern int inet6_rthdr_getflags __P((const struct cmsghdr *, int));
+__END_DECLS
+
+#endif /* !_NETINET6_IN6_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/in6_gif.h b/ecos/packages/net/tcpip/current/include/netinet6/in6_gif.h
new file mode 100644
index 0000000..ff3caf9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/in6_gif.h
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// include/netinet6_in6_gif.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in6_gif.h,v 1.1 1999/12/08 06:50:21 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET6_IN6_GIF_H_
+#define _NETINET6_IN6_GIF_H_
+
+#define GIF_HLIM 30
+
+int in6_gif_input __P((struct mbuf **, int *, int));
+int in6_gif_output __P((struct ifnet *, int, struct mbuf *, struct rtentry *));
+
+#endif /*_NETINET6_IN6_GIF_H_*/
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/in6_ifattach.h b/ecos/packages/net/tcpip/current/include/netinet6/in6_ifattach.h
new file mode 100644
index 0000000..45d96a1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/in6_ifattach.h
@@ -0,0 +1,79 @@
+//==========================================================================
+//
+// include/netinet6_in6_ifattach.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in6_ifattach.h,v 1.1 1999/12/08 06:50:21 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET6_IN6_IFATTACH_H_
+#define _NETINET6_IN6_IFATTACH_H_
+
+#ifdef _KERNEL
+extern int found_first_ifid;
+
+int in6_ifattach_getifid __P((struct ifnet *));
+void in6_ifattach_p2p __P((void));
+void in6_ifattach __P((struct ifnet *, u_int, caddr_t, int));
+void in6_ifdetach __P((struct ifnet *));
+#endif /* _KERNEL */
+
+#define IN6_IFT_LOOP 1
+#define IN6_IFT_P2P 2
+#define IN6_IFT_802 3
+#define IN6_IFT_P2P802 4
+#define IN6_IFT_ARCNET 5
+
+#endif /* _NETINET6_IN6_IFATTACH_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/in6_pcb.h b/ecos/packages/net/tcpip/current/include/netinet6/in6_pcb.h
new file mode 100644
index 0000000..29cca2e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/in6_pcb.h
@@ -0,0 +1,207 @@
+//==========================================================================
+//
+// include/netinet6_in6_pcb.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in6_pcb.h,v 1.1 1999/12/08 06:50:21 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_pcb.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET6_IN6_PCB_H_
+#define _NETINET6_IN6_PCB_H_
+
+#include <sys/queue.h>
+
+/*
+ * Common structure pcb for internet protocol implementation.
+ * Here are stored pointers to local and foreign host table
+ * entries, local and foreign socket numbers, and pointers
+ * up (to a socket structure) and down (to a protocol-specific)
+ * control block.
+ */
+struct icmp6_filter;
+struct inpcbpolicy;
+
+struct in6pcb {
+ struct in6pcb *in6p_next, *in6p_prev;
+ /* pointers to other pcb's */
+ struct in6pcb *in6p_head; /* pointer back to chain of
+ in6pcb's for this protocol */
+ struct in6_addr in6p_faddr; /* foreign host table entry */
+ u_short in6p_fport; /* foreign port */
+ struct in6_addr in6p_laddr; /* local host table entry */
+ u_short in6p_lport; /* local port */
+ u_int32_t in6p_flowinfo; /* priority and flowlabel */
+ struct socket *in6p_socket; /* back pointer to socket */
+ caddr_t in6p_ppcb; /* pointer to per-protocol pcb */
+ struct route_in6 in6p_route; /* placeholder for routing entry */
+ int in6p_flags; /* generic IP6/datagram flags */
+ int in6p_hops; /* default hop limit */
+ struct ip6_hdr in6p_ip6; /* header prototype */
+ struct mbuf *in6p_options; /* IP6 options */
+ struct ip6_pktopts *in6p_outputopts; /* IP6 options for outgoing packets */
+ struct ip6_moptions *in6p_moptions; /* IP6 multicast options */
+ u_short in6p_ifindex;
+ /* should move the following just after next/prev */
+ LIST_ENTRY(in6pcb) in6p_hlist; /* hash chain */
+ u_long in6p_hash; /* hash value */
+#if 1 /*IPSEC*/
+ struct inpcbpolicy *in6p_sp; /* security policy. */
+#endif
+ struct icmp6_filter *in6p_icmp6filt;
+ int in6p_cksum; /* IPV6_CHECKSUM setsockopt */
+};
+
+#define in6p_ip6_nxt in6p_ip6.ip6_nxt /* for KAME src sync over BSD*'s */
+
+/* flags in in6p_flags */
+#define IN6P_RECVOPTS 0x01 /* receive incoming IP6 options */
+#define IN6P_RECVRETOPTS 0x02 /* receive IP6 options for reply */
+#define IN6P_RECVDSTADDR 0x04 /* receive IP6 dst address */
+#define IN6P_HIGHPORT 0x10 /* user wants "high" port binding */
+#define IN6P_LOWPORT 0x20 /* user wants "low" port binding */
+#define IN6P_ANONPORT 0x40 /* port chosen for user */
+#define IN6P_FAITH 0x80 /* accept FAITH'ed connections */
+#define IN6P_PKTINFO 0x010000
+#define IN6P_HOPLIMIT 0x020000
+#define IN6P_NEXTHOP 0x040000
+#define IN6P_HOPOPTS 0x080000
+#define IN6P_DSTOPTS 0x100000
+#define IN6P_RTHDR 0x200000
+#define IN6P_CONTROLOPTS (0x3f0000 | IN6P_RECVOPTS | IN6P_RECVRETOPTS | IN6P_RECVDSTADDR)
+
+#define IN6PLOOKUP_WILDCARD 1
+#define IN6PLOOKUP_SETLOCAL 2
+
+/* compute hash value for foreign and local in6_addr and port */
+#define IN6_HASH(faddr, fport, laddr, lport) \
+ (((faddr)->s6_addr32[0] ^ (faddr)->s6_addr32[1] ^ \
+ (faddr)->s6_addr32[2] ^ (faddr)->s6_addr32[3] ^ \
+ (laddr)->s6_addr32[0] ^ (laddr)->s6_addr32[1] ^ \
+ (laddr)->s6_addr32[2] ^ (laddr)->s6_addr32[3]) \
+ + (fport) + (lport))
+
+#define sotoin6pcb(so) ((struct in6pcb *)(so)->so_pcb)
+
+#ifdef _KERNEL
+void in6_losing __P((struct in6pcb *));
+int in6_pcballoc __P((struct socket *, struct in6pcb *));
+int in6_pcbbind __P((struct in6pcb *, struct mbuf *));
+int in6_pcbconnect __P((struct in6pcb *, struct mbuf *));
+void in6_pcbdetach __P((struct in6pcb *));
+void in6_pcbdisconnect __P((struct in6pcb *));
+struct in6pcb *
+ in6_pcblookup __P((struct in6pcb *,
+ struct in6_addr *, u_int, struct in6_addr *,
+ u_int, int));
+int in6_pcbnotify __P((struct in6pcb *, struct sockaddr *,
+ u_int, struct in6_addr *, u_int, int,
+ void (*)(struct in6pcb *, int)));
+int in6_pcbsetport __P((struct in6_addr *, struct in6pcb *));
+void in6_rtchange __P((struct in6pcb *, int));
+void in6_setpeeraddr __P((struct in6pcb *, struct mbuf *));
+void in6_setsockaddr __P((struct in6pcb *, struct mbuf *));
+struct in6_addr *in6_selectsrc __P((struct sockaddr_in6 *,
+ struct ip6_pktopts *,
+ struct ip6_moptions *,
+ struct route_in6 *,
+ struct in6_addr *, int *));
+int in6_selecthlim __P((struct in6pcb *, struct ifnet *));
+
+#ifndef TCP6
+extern struct rtentry *
+ in6_pcbrtentry __P((struct in6pcb *));
+extern struct in6pcb *in6_pcblookup_connect __P((struct in6pcb *,
+ struct in6_addr *, u_int, struct in6_addr *, u_int, int));
+extern struct in6pcb *in6_pcblookup_bind __P((struct in6pcb *,
+ struct in6_addr *, u_int, int));
+#endif
+#endif /* _KERNEL */
+
+#endif /* !_NETINET6_IN6_PCB_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/in6_prefix.h b/ecos/packages/net/tcpip/current/include/netinet6/in6_prefix.h
new file mode 100644
index 0000000..1b3781a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/in6_prefix.h
@@ -0,0 +1,121 @@
+//==========================================================================
+//
+// include/netinet6_in6_prefix.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in6_prefix.h,v 1.1 1999/12/08 06:50:21 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, 1998 and 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET6_IN6_PREFIX_H_
+#define _NETINET6_IN6_PREFIX_H_
+
+struct rr_prefix {
+ struct ifprefix rp_ifpr;
+ LIST_ENTRY(rr_prefix) rp_entry;
+ LIST_HEAD(rp_addrhead, rp_addr) rp_addrhead;
+ struct sockaddr_in6 rp_prefix; /* prefix */
+ u_int32_t rp_vltime; /* advertised valid lifetime */
+ u_int32_t rp_pltime; /* advertised preferred lifetime */
+ time_t rp_expire; /* expiration time of the prefix */
+ time_t rp_preferred; /* preferred time of the prefix */
+ struct in6_prflags rp_flags;
+ u_char rp_origin; /* from where this prefix info is obtained */
+ struct rp_stateflags {
+ /* if some prefix should be added to this prefix */
+ u_char addmark : 1;
+ u_char delmark : 1; /* if this prefix will be deleted */
+ } rp_stateflags;
+};
+
+#define rp_type rp_ifpr.ifpr_type
+#define rp_ifp rp_ifpr.ifpr_ifp
+#define rp_plen rp_ifpr.ifpr_plen
+
+#define rp_raf rp_flags.prf_ra
+#define rp_raf_onlink rp_flags.prf_ra.onlink
+#define rp_raf_auto rp_flags.prf_ra.autonomous
+
+#define rp_statef_addmark rp_stateflags.addmark
+#define rp_statef_delmark rp_stateflags.delmark
+
+#define rp_rrf rp_flags.prf_rr
+#define rp_rrf_decrvalid rp_flags.prf_rr.decrvalid
+#define rp_rrf_decrprefd rp_flags.prf_rr.decrprefd
+
+struct rp_addr {
+ LIST_ENTRY(rp_addr) ra_entry;
+ struct in6_addr ra_ifid;
+ struct in6_ifaddr *ra_addr;
+ struct ra_flags {
+ u_char anycast : 1;
+ } ra_flags;
+};
+
+#define ifpr2rp(ifpr) ((struct rr_prefix *)(ifpr))
+#define rp2ifpr(rp) ((struct ifprefix *)(rp))
+
+#define RP_IN6(rp) (&(rp)->rp_prefix.sin6_addr)
+
+#define RR_INFINITE_LIFETIME 0xffffffff
+
+
+LIST_HEAD(rr_prhead, rr_prefix);
+
+extern struct rr_prhead rr_prefix;
+
+void in6_rr_timer __P((void *));
+int delete_each_prefix __P((struct socket *so, struct rr_prefix *rpp,
+ u_char origin));
+#endif // _NETINET6_IN6_PREFIX_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/in6_var.h b/ecos/packages/net/tcpip/current/include/netinet6/in6_var.h
new file mode 100644
index 0000000..5858346
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/in6_var.h
@@ -0,0 +1,593 @@
+//==========================================================================
+//
+// include/netinet6_in6_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in6_var.h,v 1.6 1999/12/10 10:04:28 angelos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_var.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET6_IN6_VAR_H_
+#define _NETINET6_IN6_VAR_H_
+
+/*
+ * Interface address, Internet version. One of these structures
+ * is allocated for each interface with an Internet address.
+ * The ifaddr structure contains the protocol-independent part
+ * of the structure and is assumed to be first.
+ */
+
+/*
+ * pltime/vltime are just for future reference (required to implements 2
+ * hour rule for hosts). they should never be modified by nd6_timeout or
+ * anywhere else.
+ * userland -> kernel: accept pltime/vltime
+ * kernel -> userland: throuw up everything
+ * in kernel: modify preferred/expire only
+ */
+struct in6_addrlifetime {
+ time_t ia6t_expire; /* valid lifetime expiration time */
+ time_t ia6t_preferred; /* preferred lifetime expiration time */
+ u_int32_t ia6t_vltime; /* valid lifetime */
+ u_int32_t ia6t_pltime; /* prefix lifetime */
+};
+
+struct in6_ifaddr {
+ struct ifaddr ia_ifa; /* protocol-independent info */
+#define ia_ifp ia_ifa.ifa_ifp
+#define ia_flags ia_ifa.ifa_flags
+ struct sockaddr_in6 ia_addr; /* interface address */
+ struct sockaddr_in6 ia_net; /* network number of interface */
+ struct sockaddr_in6 ia_dstaddr; /* space for destination addr */
+ struct sockaddr_in6 ia_prefixmask; /* prefix mask */
+ u_int32_t ia_plen; /* prefix length */
+ struct in6_ifaddr *ia_next; /* next in6 list of IP6 addresses */
+ LIST_HEAD(in6_multihead, in6_multi) ia6_multiaddrs;
+ /* list of multicast addresses */
+ int ia6_flags;
+
+ struct in6_addrlifetime ia6_lifetime; /* NULL = infty */
+ struct ifprefix *ia6_ifpr; /* back pointer to ifprefix */
+};
+
+/*
+ * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12).
+ */
+struct in6_ifstat {
+ u_quad_t ifs6_in_receive; /* # of total input datagram */
+ u_quad_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */
+ u_quad_t ifs6_in_toobig; /* # of datagrams exceeded MTU */
+ u_quad_t ifs6_in_noroute; /* # of datagrams with no route */
+ u_quad_t ifs6_in_addrerr; /* # of datagrams with invalid dst */
+ u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_in_truncated; /* # of truncated datagrams */
+ u_quad_t ifs6_in_discard; /* # of discarded datagrams */
+ /* NOTE: fragment timeout is not here */
+ u_quad_t ifs6_in_deliver; /* # of datagrams delivered to ULP */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_out_forward; /* # of datagrams forwarded */
+ /* NOTE: increment on outgoing if */
+ u_quad_t ifs6_out_request; /* # of outgoing datagrams from ULP */
+ /* NOTE: does not include forwrads */
+ u_quad_t ifs6_out_discard; /* # of discarded datagrams */
+ u_quad_t ifs6_out_fragok; /* # of datagrams fragmented */
+ u_quad_t ifs6_out_fragfail; /* # of datagrams failed on fragment */
+ u_quad_t ifs6_out_fragcreat; /* # of fragment datagrams */
+ /* NOTE: this is # after fragment */
+ u_quad_t ifs6_reass_reqd; /* # of incoming fragmented packets */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_reass_ok; /* # of reassembled packets */
+ /* NOTE: this is # after reass */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_reass_fail; /* # of reass failures */
+ /* NOTE: may not be packet count */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_in_mcast; /* # of inbound multicast datagrams */
+ u_quad_t ifs6_out_mcast; /* # of outbound multicast datagrams */
+};
+
+/*
+ * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry.
+ * XXX: I'm not sure if this file is the right place for this structure...
+ */
+struct icmp6_ifstat {
+ /*
+ * Input statistics
+ */
+ /* ipv6IfIcmpInMsgs, total # of input messages */
+ u_quad_t ifs6_in_msg;
+ /* ipv6IfIcmpInErrors, # of input error messages */
+ u_quad_t ifs6_in_error;
+ /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
+ u_quad_t ifs6_in_dstunreach;
+ /* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */
+ u_quad_t ifs6_in_adminprohib;
+ /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
+ u_quad_t ifs6_in_timeexceed;
+ /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
+ u_quad_t ifs6_in_paramprob;
+ /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
+ u_quad_t ifs6_in_pkttoobig;
+ /* ipv6IfIcmpInEchos, # of input echo requests */
+ u_quad_t ifs6_in_echo;
+ /* ipv6IfIcmpInEchoReplies, # of input echo replies */
+ u_quad_t ifs6_in_echoreply;
+ /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
+ u_quad_t ifs6_in_routersolicit;
+ /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
+ u_quad_t ifs6_in_routeradvert;
+ /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
+ u_quad_t ifs6_in_neighborsolicit;
+ /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */
+ u_quad_t ifs6_in_neighboradvert;
+ /* ipv6IfIcmpInRedirects, # of input redirects */
+ u_quad_t ifs6_in_redirect;
+ /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
+ u_quad_t ifs6_in_mldquery;
+ /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
+ u_quad_t ifs6_in_mldreport;
+ /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
+ u_quad_t ifs6_in_mlddone;
+
+ /*
+ * Output statistics. We should solve unresolved routing problem...
+ */
+ /* ipv6IfIcmpOutMsgs, total # of output messages */
+ u_quad_t ifs6_out_msg;
+ /* ipv6IfIcmpOutErrors, # of output error messages */
+ u_quad_t ifs6_out_error;
+ /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
+ u_quad_t ifs6_out_dstunreach;
+ /* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */
+ u_quad_t ifs6_out_adminprohib;
+ /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
+ u_quad_t ifs6_out_timeexceed;
+ /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
+ u_quad_t ifs6_out_paramprob;
+ /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
+ u_quad_t ifs6_out_pkttoobig;
+ /* ipv6IfIcmpOutEchos, # of output echo requests */
+ u_quad_t ifs6_out_echo;
+ /* ipv6IfIcmpOutEchoReplies, # of output echo replies */
+ u_quad_t ifs6_out_echoreply;
+ /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
+ u_quad_t ifs6_out_routersolicit;
+ /* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */
+ u_quad_t ifs6_out_routeradvert;
+ /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
+ u_quad_t ifs6_out_neighborsolicit;
+ /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */
+ u_quad_t ifs6_out_neighboradvert;
+ /* ipv6IfIcmpOutRedirects, # of output redirects */
+ u_quad_t ifs6_out_redirect;
+ /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
+ u_quad_t ifs6_out_mldquery;
+ /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
+ u_quad_t ifs6_out_mldreport;
+ /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
+ u_quad_t ifs6_out_mlddone;
+};
+
+struct in6_ifreq {
+ char ifr_name[IFNAMSIZ];
+ union {
+ struct sockaddr_in6 ifru_addr;
+ struct sockaddr_in6 ifru_dstaddr;
+ short ifru_flags;
+ int ifru_flags6;
+ int ifru_metric;
+ caddr_t ifru_data;
+ struct in6_addrlifetime ifru_lifetime;
+ struct in6_ifstat ifru_stat;
+ struct icmp6_ifstat ifru_icmp6stat;
+ } ifr_ifru;
+};
+
+struct in6_aliasreq {
+ char ifra_name[IFNAMSIZ];
+ struct sockaddr_in6 ifra_addr;
+ struct sockaddr_in6 ifra_dstaddr;
+ struct sockaddr_in6 ifra_prefixmask;
+ int ifra_flags;
+ struct in6_addrlifetime ifra_lifetime;
+};
+
+/* prefix type macro */
+#define IN6_PREFIX_ND 1
+#define IN6_PREFIX_RR 2
+
+/*
+ * prefix related flags passed between kernel(NDP related part) and
+ * user land command(ifconfig) and daemon(rtadvd).
+ */
+struct in6_prflags {
+ struct prf_ra {
+ u_char onlink : 1;
+ u_char autonomous : 1;
+ u_char reserved : 6;
+ } prf_ra;
+ u_char prf_reserved1;
+ u_short prf_reserved2;
+ /* want to put this on 4byte offset */
+ struct prf_rr {
+ u_char decrvalid : 1;
+ u_char decrprefd : 1;
+ u_char reserved : 6;
+ } prf_rr;
+ u_char prf_reserved3;
+ u_short prf_reserved4;
+};
+
+struct in6_prefixreq {
+ char ipr_name[IFNAMSIZ];
+ u_char ipr_origin;
+ u_char ipr_plen;
+ u_int32_t ipr_vltime;
+ u_int32_t ipr_pltime;
+ struct in6_prflags ipr_flags;
+ struct sockaddr_in6 ipr_prefix;
+};
+
+#define PR_ORIG_RA 0
+#define PR_ORIG_RR 1
+#define PR_ORIG_STATIC 2
+#define PR_ORIG_KERNEL 3
+
+#define ipr_raf_onlink ipr_flags.prf_ra.onlink
+#define ipr_raf_auto ipr_flags.prf_ra.autonomous
+
+#define ipr_statef_onlink ipr_flags.prf_state.onlink
+
+#define ipr_rrf_decrvalid ipr_flags.prf_rr.decrvalid
+#define ipr_rrf_decrprefd ipr_flags.prf_rr.decrprefd
+
+struct in6_rrenumreq {
+ char irr_name[IFNAMSIZ];
+ u_char irr_origin;
+ u_char irr_m_len; /* match len for matchprefix */
+ u_char irr_m_minlen; /* minlen for matching prefix */
+ u_char irr_m_maxlen; /* maxlen for matching prefix */
+ u_char irr_u_uselen; /* uselen for adding prefix */
+ u_char irr_u_keeplen; /* keeplen from matching prefix */
+ struct irr_raflagmask {
+ u_char onlink : 1;
+ u_char autonomous : 1;
+ u_char reserved : 6;
+ } irr_raflagmask;
+ u_int32_t irr_vltime;
+ u_int32_t irr_pltime;
+ struct in6_prflags irr_flags;
+ struct sockaddr_in6 irr_matchprefix;
+ struct sockaddr_in6 irr_useprefix;
+};
+
+#define irr_raf_mask_onlink irr_raflagmask.onlink
+#define irr_raf_mask_auto irr_raflagmask.autonomous
+#define irr_raf_mask_reserved irr_raflagmask.reserved
+
+#define irr_raf_onlink irr_flags.prf_ra.onlink
+#define irr_raf_auto irr_flags.prf_ra.autonomous
+
+#define irr_statef_onlink irr_flags.prf_state.onlink
+
+#define irr_rrf irr_flags.prf_rr
+#define irr_rrf_decrvalid irr_flags.prf_rr.decrvalid
+#define irr_rrf_decrprefd irr_flags.prf_rr.decrprefd
+
+/*
+ * Given a pointer to an in6_ifaddr (ifaddr),
+ * return a pointer to the addr as a sockaddr_in6
+ */
+#define IA6_IN6(ia) (&((ia)->ia_addr.sin6_addr))
+#define IA6_DSTIN6(ia) (&((ia)->ia_dstaddr.sin6_addr))
+#define IA6_MASKIN6(ia) (&((ia)->ia_prefixmask.sin6_addr))
+#define IA6_SIN6(ia) (&((ia)->ia_addr))
+#define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr))
+#define IFA_IN6(x) (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr)
+#define IFA_DSTIN6(x) (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr)
+
+#define IFPR_IN6(x) (&((struct sockaddr_in6 *)((x)->ifpr_prefix))->sin6_addr)
+
+#ifdef _KERNEL
+#define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
+ (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
+ (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
+ (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
+ (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
+#endif
+
+#define SIOCSIFADDR_IN6 _IOW('i', 12, struct in6_ifreq)
+#define SIOCGIFADDR_IN6 _IOWR('i', 33, struct in6_ifreq)
+#define SIOCSIFDSTADDR_IN6 _IOW('i', 14, struct in6_ifreq)
+#define SIOCGIFDSTADDR_IN6 _IOWR('i', 34, struct in6_ifreq)
+#define SIOCSIFNETMASK_IN6 _IOW('i', 22, struct in6_ifreq)
+#define SIOCGIFNETMASK_IN6 _IOWR('i', 37, struct in6_ifreq)
+
+#define SIOCDIFADDR_IN6 _IOW('i', 25, struct in6_ifreq)
+#define SIOCAIFADDR_IN6 _IOW('i', 26, struct in6_aliasreq)
+
+#define SIOCSIFPHYADDR_IN6 _IOW('i', 70, struct in6_aliasreq)
+#define SIOCGIFPSRCADDR_IN6 _IOWR('i', 71, struct in6_ifreq)
+#define SIOCGIFPDSTADDR_IN6 _IOWR('i', 72, struct in6_ifreq)
+
+#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
+
+#define SIOCGDRLST_IN6 _IOWR('i', 74, struct in6_drlist)
+#define SIOCGPRLST_IN6 _IOWR('i', 75, struct in6_prlist)
+#define SIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ndireq)
+#define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
+#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
+#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
+#define SIOCSRTRFLUSH_IN6 _IOWR('i', 80, struct in6_ifreq)
+
+#define SIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq)
+#define SIOCSIFALIFETIME_IN6 _IOWR('i', 82, struct in6_ifreq)
+#define SIOCGIFSTAT_IN6 _IOWR('i', 83, struct in6_ifreq)
+#define SIOCGIFSTAT_ICMP6 _IOWR('i', 84, struct in6_ifreq)
+
+#define SIOCSIFPREFIX_IN6 _IOW('i', 100, struct in6_prefixreq) /* set */
+#define SIOCGIFPREFIX_IN6 _IOWR('i', 101, struct in6_prefixreq) /* get */
+#define SIOCDIFPREFIX_IN6 _IOW('i', 102, struct in6_prefixreq) /* del */
+#define SIOCAIFPREFIX_IN6 _IOW('i', 103, struct in6_rrenumreq) /* add */
+#define SIOCCIFPREFIX_IN6 _IOW('i', 104, \
+ struct in6_rrenumreq) /* change */
+#define SIOCSGIFPREFIX_IN6 _IOW('i', 105, \
+ struct in6_rrenumreq) /* set global */
+
+#define SIOCGETSGCNT_IN6 _IOWR('u', 106, \
+ struct sioc_sg_req6) /* get s,g pkt cnt */
+#define SIOCGETMIFCNT_IN6 _IOWR('u', 107, \
+ struct sioc_mif_req6) /* get pkt cnt per if */
+
+#define IN6_IFF_ANYCAST 0x01 /* anycast address */
+#define IN6_IFF_TENTATIVE 0x02 /* tentative address */
+#define IN6_IFF_DUPLICATED 0x04 /* DAD detected duplicate */
+#define IN6_IFF_DETACHED 0x08 /* may be detached from the link */
+#define IN6_IFF_DEPRECATED 0x10 /* deprecated address */
+
+/* do not input/output */
+#define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED)
+
+#ifdef _KERNEL
+extern struct in6_ifaddr *in6_ifaddr;
+
+extern struct in6_ifstat **in6_ifstat;
+extern size_t in6_ifstatmax;
+extern struct icmp6stat icmp6stat;
+extern struct icmp6_ifstat **icmp6_ifstat;
+extern size_t icmp6_ifstatmax;
+#define in6_ifstat_inc(ifp, tag) \
+do { \
+ if ((ifp) && (ifp)->if_index <= if_index \
+ && (ifp)->if_index < in6_ifstatmax \
+ && in6_ifstat && in6_ifstat[(ifp)->if_index]) { \
+ in6_ifstat[(ifp)->if_index]->tag++; \
+ } \
+} while (0)
+
+extern struct ifqueue ip6intrq; /* IP6 packet input queue */
+extern struct in6_addr zeroin6_addr;
+extern u_char inet6ctlerrmap[];
+extern unsigned long in6_maxmtu;
+
+/*
+ * Macro for finding the internet address structure (in6_ifaddr) corresponding
+ * to a given interface (ifnet structure).
+ */
+#define IFP_TO_IA6(ifp, ia) \
+/* struct ifnet *ifp; */ \
+/* struct in6_ifaddr *ia; */ \
+do { \
+ struct ifaddr *ifa; \
+ for (ifa = (ifp)->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) { \
+ if (!ifa->ifa_addr) \
+ continue; \
+ if (ifa->ifa_addr->sa_family == AF_INET6) \
+ break; \
+ } \
+ (ia) = (struct in6_ifaddr *)ifa; \
+} while (0)
+#endif /* _KERNEL */
+
+/*
+ * Multi-cast membership entry. One for each group/ifp that a PCB
+ * belongs to.
+ */
+struct in6_multi_mship {
+ struct in6_multi *i6mm_maddr; /* Multicast address pointer */
+ LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */
+};
+
+struct in6_multi {
+ LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
+ struct in6_addr in6m_addr; /* IP6 multicast address */
+ struct ifnet *in6m_ifp; /* back pointer to ifnet */
+ struct in6_ifaddr *in6m_ia; /* back pointer to in6_ifaddr */
+ u_int in6m_refcount; /* # membership claims by sockets */
+ u_int in6m_state; /* state of the membership */
+ u_int in6m_timer; /* MLD6 listener report timer */
+};
+
+#ifdef _KERNEL
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of eht in6_multi records.
+ */
+struct in6_multistep {
+ struct in6_ifaddr *i_ia;
+ struct in6_multi *i_in6m;
+};
+
+/*
+ * Macros for looking up the in6_multi record for a given IP6 multicast
+ * address on a given interface. If no matching record is found, "in6m"
+ * returns NLL.
+ */
+
+#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \
+/* struct in6_addr addr; */ \
+/* struct ifnet *ifp; */ \
+/* struct in6_multi *in6m; */ \
+do { \
+ register struct in6_ifaddr *ia; \
+ \
+ IFP_TO_IA6((ifp), ia); \
+ if (ia == NULL) \
+ (in6m) = NULL; \
+ else \
+ for ((in6m) = ia->ia6_multiaddrs.lh_first; \
+ (in6m) != NULL && \
+ !IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, &(addr)); \
+ (in6m) = in6m->in6m_entry.le_next) \
+ continue; \
+} while (0)
+
+/*
+ * Macro to step through all of the in6_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. IN6_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "in6m" when there
+ * are no remaining records.
+ */
+#define IN6_NEXT_MULTI(step, in6m) \
+/* struct in6_multistep step; */ \
+/* struct in6_multi *in6m; */ \
+do { \
+ if (((in6m) = (step).i_in6m) != NULL) \
+ (step).i_in6m = (in6m)->in6m_entry.le_next; \
+ else \
+ while ((step).i_ia != NULL) { \
+ (in6m) = (step).i_ia->ia6_multiaddrs.lh_first; \
+ (step).i_ia = (step).i_ia->ia_next; \
+ if ((in6m) != NULL) { \
+ (step).i_in6m = (in6m)->in6m_entry.le_next; \
+ break; \
+ } \
+ } \
+} while (0)
+
+#define IN6_FIRST_MULTI(step, in6m) \
+/* struct in6_multistep step; */ \
+/* struct in6_multi *in6m */ \
+do { \
+ (step).i_ia = in6_ifaddr; \
+ (step).i_in6m = NULL; \
+ IN6_NEXT_MULTI((step), (in6m)); \
+} while (0)
+
+int in6_ifinit __P((struct ifnet *,
+ struct in6_ifaddr *, struct sockaddr_in6 *, int));
+struct in6_multi *in6_addmulti __P((struct in6_addr *, struct ifnet *,
+ int *));
+void in6_delmulti __P((struct in6_multi *));
+void in6_ifscrub __P((struct ifnet *, struct in6_ifaddr *));
+extern int in6_ifindex2scopeid __P((int));
+extern int in6_mask2len __P((struct in6_addr *));
+extern void in6_len2mask __P((struct in6_addr *, int));
+int in6_control __P((struct socket *,
+ u_long, caddr_t, struct ifnet *, struct proc *));
+void in6_savemkludge __P((struct in6_ifaddr *));
+void in6_setmaxmtu __P((void));
+void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
+struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *));
+struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *,
+ struct in6_addr *));
+char *ip6_sprintf __P((struct in6_addr *));
+int in6_matchlen __P((struct in6_addr *, struct in6_addr *));
+int in6_are_prefix_equal __P((struct in6_addr *p1, struct in6_addr *p2,
+ int len));
+void in6_prefixlen2mask __P((struct in6_addr *maskp, int len));
+int in6_prefix_ioctl __P((struct socket *so, u_long cmd, caddr_t data,
+ struct ifnet *ifp));
+int in6_prefix_add_ifid __P((int iilen, struct in6_ifaddr *ia));
+void in6_prefix_remove_ifid __P((int iilen, struct in6_ifaddr *ia));
+#endif /* _KERNEL */
+
+#endif /* _NETINET6_IN6_VAR_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ip6.h b/ecos/packages/net/tcpip/current/include/netinet6/ip6.h
new file mode 100644
index 0000000..7c923cc
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ip6.h
@@ -0,0 +1,316 @@
+//==========================================================================
+//
+// include/netinet6_ipv6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip6.h,v 1.1 1999/12/08 06:50:21 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET6_IPV6_H_
+#define _NETINET6_IPV6_H_
+
+/*
+ * Definition for internet protocol version 6.
+ * RFC 2460
+ */
+
+struct ip6_hdr {
+ union {
+ struct ip6_hdrctl {
+ u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
+ u_int16_t ip6_un1_plen; /* payload length */
+ u_int8_t ip6_un1_nxt; /* next header */
+ u_int8_t ip6_un1_hlim; /* hop limit */
+ } ip6_un1;
+ u_int8_t ip6_un2_vfc; /* 4 bits version, 4 bits class */
+ } ip6_ctlun;
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* destination address */
+};
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+#define IPV6_VERSION 0x60
+#define IPV6_VERSION_MASK 0xf0
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */
+#endif /* LITTLE_ENDIAN */
+#endif
+#if 1
+/* ECN bits proposed by Sally Floyd */
+#define IP6TOS_CE 0x01 /* congestion experienced */
+#define IP6TOS_ECT 0x02 /* ECN-capable transport */
+#endif
+
+/*
+ * Extension Headers
+ */
+
+struct ip6_ext {
+ u_char ip6e_nxt;
+ u_char ip6e_len;
+};
+
+/* Hop-by-Hop options header */
+/* XXX should we pad it to force alignment on an 8-byte boundary? */
+struct ip6_hbh {
+ u_int8_t ip6h_nxt; /* next header */
+ u_int8_t ip6h_len; /* length in units of 8 octets */
+ /* followed by options */
+};
+
+/* Destination options header */
+/* XXX should we pad it to force alignment on an 8-byte boundary? */
+struct ip6_dest {
+ u_int8_t ip6d_nxt; /* next header */
+ u_int8_t ip6d_len; /* length in units of 8 octets */
+ /* followed by options */
+};
+
+/* Option types and related macros */
+#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
+#define IP6OPT_PADN 0x01 /* 00 0 00001 */
+#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
+#define IP6OPT_JUMBO_LEN 6
+#define IP6OPT_RTALERT 0x05 /* 00 0 00101 */
+#define IP6OPT_RTALERT_LEN 4
+#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
+#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
+#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
+#define IP6OPT_MINLEN 2
+
+#define IP6OPT_TYPE(o) ((o) & 0xC0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xC0
+
+#define IP6OPT_MUTABLE 0x20
+
+/* Routing header */
+struct ip6_rthdr {
+ u_int8_t ip6r_nxt; /* next header */
+ u_int8_t ip6r_len; /* length in units of 8 octets */
+ u_int8_t ip6r_type; /* routing type */
+ u_int8_t ip6r_segleft; /* segments left */
+ /* followed by routing type specific data */
+};
+
+/* Type 0 Routing header */
+struct ip6_rthdr0 {
+ u_int8_t ip6r0_nxt; /* next header */
+ u_int8_t ip6r0_len; /* length in units of 8 octets */
+ u_int8_t ip6r0_type; /* always zero */
+ u_int8_t ip6r0_segleft; /* segments left */
+ u_int8_t ip6r0_reserved; /* reserved field */
+ u_int8_t ip6r0_slmap[3]; /* strict/loose bit map */
+ struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
+};
+
+/* Fragment header */
+struct ip6_frag {
+ u_int8_t ip6f_nxt; /* next header */
+ u_int8_t ip6f_reserved; /* reserved field */
+ u_int16_t ip6f_offlg; /* offset, reserved, and flag */
+ u_int32_t ip6f_ident; /* identification */
+};
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+#define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Internet implementation parameters.
+ */
+#define IPV6_MAXHLIM 255 /* maximun hoplimit */
+#define IPV6_DEFHLIM 64 /* default hlim */
+#define IPV6_FRAGTTL 120 /* ttl for fragment packets, in slowtimo tick */
+#define IPV6_HLIMDEC 1 /* subtracted when forwaeding */
+
+#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
+#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
+
+/*
+ * IP6_EXTHDR_CHECK ensures that region between the IP6 header and the
+ * target header (including IPv6 itself, extension headers and
+ * TCP/UDP/ICMP6 headers) are continuous. KAME requires drivers
+ * to store incoming data into one internal mbuf or one or more external
+ * mbufs(never into two or more internal mbufs). Thus, the third case is
+ * supposed to never be matched but is prepared just in case.
+ */
+
+#define IP6_EXTHDR_CHECK(m, off, hlen, ret) \
+do { \
+ if ((m)->m_next != NULL) { \
+ if (((m)->m_flags & M_LOOP) && \
+ ((m)->m_len < (off) + (hlen)) && \
+ (((m) = m_pullup((m), (off) + (hlen))) == NULL)) { \
+ ip6stat.ip6s_exthdrtoolong++; \
+ return ret; \
+ } else if ((m)->m_flags & M_EXT) { \
+ if ((m)->m_len < (off) + (hlen)) { \
+ ip6stat.ip6s_exthdrtoolong++; \
+ m_freem(m); \
+ return ret; \
+ } \
+ } else { \
+ if ((m)->m_len < (off) + (hlen)) { \
+ ip6stat.ip6s_exthdrtoolong++; \
+ m_freem(m); \
+ return ret; \
+ } \
+ } \
+ } \
+ else { \
+ if ((m)->m_len < (off) + (hlen)) { \
+ ip6stat.ip6s_tooshort++; \
+ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); \
+ m_freem(m); \
+ return ret; \
+ } \
+ } \
+} while (0)
+
+#ifdef __NetBSD__
+/*
+ * IP6_EXTHDR_GET ensures that intermediate protocol header (from "off" to
+ * "len") is located in single mbuf, on contiguous memory region.
+ * The pointer to the region will be returned to pointer variable "val",
+ * with type "typ".
+ * IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the
+ * very top of mbuf. GET0 is likely to make memory copy than GET.
+ *
+ * XXX we're now testing this, needs m_pulldown()
+ */
+#define IP6_EXTHDR_GET(val, typ, m, off, len) \
+do { \
+ struct mbuf *t; \
+ int tmp; \
+ t = m_pulldown((m), (off), (len), &tmp); \
+ if (t) { \
+ if (t->m_len < tmp + (len)) \
+ panic("m_pulldown malfunction"); \
+ (val) = (typ)(mtod(t, caddr_t) + tmp); \
+ } else \
+ (val) = (typ)NULL; \
+} while (0)
+
+#define IP6_EXTHDR_GET0(val, typ, m, off, len) \
+do { \
+ struct mbuf *t; \
+ t = m_pulldown((m), (off), (len), NULL); \
+ if (t) { \
+ if (t->m_len < (len)) \
+ panic("m_pulldown malfunction"); \
+ (val) = (typ)mtod(t, caddr_t); \
+ } else \
+ (val) = (typ)NULL; \
+} while (0)
+
+#endif /*NetBSD*/
+
+#endif /* not _NETINET_IPV6_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ip6_mroute.h b/ecos/packages/net/tcpip/current/include/netinet6/ip6_mroute.h
new file mode 100644
index 0000000..b50f1a1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ip6_mroute.h
@@ -0,0 +1,277 @@
+//==========================================================================
+//
+// include/netinet6_ip6_mroute.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: ip6_mroute.h,v 1.2 1999/12/10 10:04:28 angelos Exp $ */
+
+/*
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/* BSDI ip_mroute.h,v 2.5 1996/10/11 16:01:48 pjd Exp */
+
+/*
+ * Definitions for IP multicast forwarding.
+ *
+ * Written by David Waitzman, BBN Labs, August 1988.
+ * Modified by Steve Deering, Stanford, February 1989.
+ * Modified by Ajit Thyagarajan, PARC, August 1993.
+ * Modified by Ajit Thyagarajan, PARC, August 1994.
+ * Modified by Ahmed Helmy, USC, September 1996.
+ *
+ * MROUTING Revision: 1.2
+ */
+
+#ifndef _NETINET6_IP6_MROUTE_H_
+#define _NETINET6_IP6_MROUTE_H_
+
+/*
+ * Multicast Routing set/getsockopt commands.
+ */
+#define MRT6_INIT 100 /* initialize forwarder */
+#define MRT6_DONE 101 /* shut down forwarder */
+#define MRT6_ADD_MIF 102 /* add multicast interface */
+#define MRT6_DEL_MIF 103 /* delete multicast interface */
+#define MRT6_ADD_MFC 104 /* insert forwarding cache entry */
+#define MRT6_DEL_MFC 105 /* delete forwarding cache entry */
+#define MRT6_PIM 107 /* enable pim code */
+
+#if BSD >= 199103
+#define GET_TIME(t) microtime(&t)
+#elif defined(sun)
+#define GET_TIME(t) uniqtime(&t)
+#else
+#define GET_TIME(t) ((t) = time)
+#endif
+
+/*
+ * Types and macros for handling bitmaps with one bit per multicast interface.
+ */
+typedef u_short mifi_t; /* type of a mif index */
+#define MAXMIFS 64
+
+#ifndef IF_SETSIZE
+#define IF_SETSIZE 256
+#endif
+
+typedef long if_mask;
+#define NIFBITS (sizeof(if_mask) * NBBY) /* bits per mask */
+
+#ifndef howmany
+#define howmany(x, y) (((x) + ((y) - 1)) / (y))
+#endif
+
+typedef struct if_set {
+ fd_mask ifs_bits[howmany(IF_SETSIZE, NIFBITS)];
+} if_set;
+
+#define IF_SET(n, p) ((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
+#define IF_CLR(n, p) ((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
+#define IF_ISSET(n, p) ((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
+#define IF_COPY(f, t) bcopy(f, t, sizeof(*(f)))
+#define IF_ZERO(p) bzero(p, sizeof(*(p)))
+
+/*
+ * Argument structure for MRT6_ADD_IF.
+ */
+struct mif6ctl {
+ mifi_t mif6c_mifi; /* the index of the mif to be added */
+ u_char mif6c_flags; /* MIFF_ flags defined below */
+ u_short mif6c_pifi; /* the index of the physical IF */
+#ifdef notyet
+ u_int mif6c_rate_limit; /* max rate */
+#endif
+};
+
+#define MIFF_REGISTER 0x1 /* mif represents a register end-point */
+
+/*
+ * Argument structure for MRT6_ADD_MFC and MRT6_DEL_MFC
+ */
+struct mf6cctl {
+ struct sockaddr_in6 mf6cc_origin; /* IPv6 origin of mcasts */
+ struct sockaddr_in6 mf6cc_mcastgrp; /* multicast group associated */
+ mifi_t mf6cc_parent; /* incoming ifindex */
+ struct if_set mf6cc_ifset; /* set of forwarding ifs */
+};
+
+/*
+ * The kernel's multicast routing statistics.
+ */
+struct mrt6stat {
+ u_quad_t mrt6s_mfc_lookups; /* # forw. cache hash table hits */
+ u_quad_t mrt6s_mfc_misses; /* # forw. cache hash table misses */
+ u_quad_t mrt6s_upcalls; /* # calls to mrouted */
+ u_quad_t mrt6s_no_route; /* no route for packet's origin */
+ u_quad_t mrt6s_bad_tunnel; /* malformed tunnel options */
+ u_quad_t mrt6s_cant_tunnel; /* no room for tunnel options */
+ u_quad_t mrt6s_wrong_if; /* arrived on wrong interface */
+ u_quad_t mrt6s_upq_ovflw; /* upcall Q overflow */
+ u_quad_t mrt6s_cache_cleanups; /* # entries with no upcalls */
+ u_quad_t mrt6s_drop_sel; /* pkts dropped selectively */
+ u_quad_t mrt6s_q_overflow; /* pkts dropped - Q overflow */
+ u_quad_t mrt6s_pkt2large; /* pkts dropped - size > BKT SIZE */
+ u_quad_t mrt6s_upq_sockfull; /* upcalls dropped - socket full */
+};
+
+/*
+ * Struct used to communicate from kernel to multicast router
+ * note the convenient similarity to an IPv6 header.
+ */
+struct mrt6msg {
+ u_long unused1;
+ u_char im6_msgtype; /* what type of message */
+#define MRT6MSG_NOCACHE 1
+#define MRT6MSG_WRONGMIF 2
+#define MRT6MSG_WHOLEPKT 3 /* used for user level encap*/
+ u_char im6_mbz; /* must be zero */
+ u_char im6_mif; /* mif rec'd on */
+ u_char unused2;
+ struct in6_addr im6_src, im6_dst;
+};
+
+/*
+ * Argument structure used by multicast routing daemon to get src-grp
+ * packet counts
+ */
+struct sioc_sg_req6 {
+ struct sockaddr_in6 src;
+ struct sockaddr_in6 grp;
+ u_quad_t pktcnt;
+ u_quad_t bytecnt;
+ u_quad_t wrong_if;
+};
+
+/*
+ * Argument structure used by mrouted to get mif pkt counts
+ */
+struct sioc_mif_req6 {
+ mifi_t mifi; /* mif number */
+ u_quad_t icount; /* Input packet count on mif */
+ u_quad_t ocount; /* Output packet count on mif */
+ u_quad_t ibytes; /* Input byte count on mif */
+ u_quad_t obytes; /* Output byte count on mif */
+};
+
+#if defined(_KERNEL) || defined(KERNEL)
+/*
+ * The kernel's multicast-interface structure.
+ */
+struct mif6 {
+ u_char m6_flags; /* MIFF_ flags defined above */
+ u_int m6_rate_limit; /* max rate */
+#ifdef notyet
+ struct tbf *m6_tbf; /* token bucket structure at intf. */
+#endif
+ struct in6_addr m6_lcl_addr; /* local interface address */
+ struct ifnet *m6_ifp; /* pointer to interface */
+ u_quad_t m6_pkt_in; /* # pkts in on interface */
+ u_quad_t m6_pkt_out; /* # pkts out on interface */
+ u_quad_t m6_bytes_in; /* # bytes in on interface */
+ u_quad_t m6_bytes_out; /* # bytes out on interface */
+ struct route_in6 m6_route;/* cached route if this is a tunnel */
+#ifdef notyet
+ u_int m6_rsvp_on; /* RSVP listening on this vif */
+ struct socket *m6_rsvpd; /* RSVP daemon socket */
+#endif
+};
+
+/*
+ * The kernel's multicast forwarding cache entry structure
+ */
+struct mf6c {
+ struct sockaddr_in6 mf6c_origin; /* IPv6 origin of mcasts */
+ struct sockaddr_in6 mf6c_mcastgrp; /* multicast group associated*/
+ mifi_t mf6c_parent; /* incoming IF */
+ struct if_set mf6c_ifset; /* set of outgoing IFs */
+
+ u_quad_t mf6c_pkt_cnt; /* pkt count for src-grp */
+ u_quad_t mf6c_byte_cnt; /* byte count for src-grp */
+ u_quad_t mf6c_wrong_if; /* wrong if for src-grp */
+ int mf6c_expire; /* time to clean entry up */
+ struct timeval mf6c_last_assert; /* last time I sent an assert*/
+ struct rtdetq *mf6c_stall; /* pkts waiting for route */
+ struct mf6c *mf6c_next; /* hash table linkage */
+};
+
+#define MF6C_INCOMPLETE_PARENT ((mifi_t)-1)
+
+/*
+ * Argument structure used for pkt info. while upcall is made
+ */
+#ifndef _NETINET_IP_MROUTE_H_
+struct rtdetq { /* XXX: rtdetq is also defined in ip_mroute.h */
+ struct mbuf *m; /* A copy of the packet */
+ struct ifnet *ifp; /* Interface pkt came in on */
+#ifdef UPCALL_TIMING
+ struct timeval t; /* Timestamp */
+#endif /* UPCALL_TIMING */
+ struct rtdetq *next;
+};
+#endif /* _NETINET_IP_MROUTE_H_ */
+
+#define MF6CTBLSIZ 256
+#if (MF6CTBLSIZ & (MF6CTBLSIZ - 1)) == 0 /* from sys:route.h */
+#define MF6CHASHMOD(h) ((h) & (MF6CTBLSIZ - 1))
+#else
+#define MF6CHASHMOD(h) ((h) % MF6CTBLSIZ)
+#endif
+
+#define MAX_UPQ6 4 /* max. no of pkts in upcall Q */
+
+int ip6_mrouter_set __P((int, struct socket *, struct mbuf *));
+int ip6_mrouter_get __P((int, struct socket *, struct mbuf **));
+int ip6_mrouter_done __P((void));
+int mrt6_ioctl __P((int, caddr_t));
+#endif /* _KERNEL */
+
+#endif /* !_NETINET6_IP6_MROUTE_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ip6_var.h b/ecos/packages/net/tcpip/current/include/netinet6/ip6_var.h
new file mode 100644
index 0000000..4496c60
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ip6_var.h
@@ -0,0 +1,287 @@
+//==========================================================================
+//
+// include/netinet6_ip6_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: ip6_var.h,v 1.2 1999/12/10 10:04:28 angelos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_var.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET6_IP6_VAR_H_
+#define _NETINET6_IP6_VAR_H_
+
+/*
+ * IP6 reassembly queue structure. Each fragment
+ * being reassembled is attached to one of these structures.
+ */
+struct ip6q {
+ u_long ip6q_head;
+ u_short ip6q_len;
+ u_char ip6q_nxt;
+ u_char ip6q_hlim;
+ struct ip6asfrag *ip6q_down;
+ struct ip6asfrag *ip6q_up;
+ u_long ip6q_ident;
+ u_char ip6q_arrive;
+ u_char ip6q_ttl;
+ struct in6_addr ip6q_src, ip6q_dst;
+ struct ip6q *ip6q_next;
+ struct ip6q *ip6q_prev;
+ int ip6q_unfrglen;
+#ifdef notyet
+ u_char *ip6q_nxtp;
+#endif
+};
+
+struct ip6asfrag {
+ u_long ip6af_head;
+ u_short ip6af_len;
+ u_char ip6af_nxt;
+ u_char ip6af_hlim;
+ /* must not override the above members during reassembling */
+ struct ip6asfrag *ip6af_down;
+ struct ip6asfrag *ip6af_up;
+ u_short ip6af_mff;
+ u_short ip6af_off;
+ struct mbuf *ip6af_m;
+ u_long ip6af_offset; /* offset where next header starts */
+ u_short ip6af_frglen; /* fragmentable part length */
+ u_char ip6af_x1[10];
+};
+
+#define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m))
+
+struct ip6_moptions {
+ struct ifnet *im6o_multicast_ifp; /* ifp for outgoing multicasts */
+ u_char im6o_multicast_hlim; /* hoplimit for outgoing multicasts */
+ u_char im6o_multicast_loop; /* 1 >= hear sends if a member */
+ LIST_HEAD(, in6_multi_mship) im6o_memberships;
+};
+
+/*
+ * Control options for outgoing packets
+ */
+
+/* Routing header related info */
+struct ip6po_rhinfo {
+ struct ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */
+ struct route_in6 ip6po_rhi_route; /* Route to the 1st hop */
+};
+#define ip6po_rthdr ip6po_rhinfo.ip6po_rhi_rthdr
+#define ip6po_route ip6po_rhinfo.ip6po_rhi_route
+
+struct ip6_pktopts {
+ struct mbuf *ip6po_m; /* Pointer to mbuf storing the data */
+ int ip6po_hlim; /* Hoplimit for outgoing packets */
+ struct in6_pktinfo *ip6po_pktinfo; /* Outgoing IF/address information */
+ struct sockaddr *ip6po_nexthop; /* Next-hop address */
+ struct ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
+ struct ip6_dest *ip6po_dest1; /* Destination options header(1st part) */
+ struct ip6po_rhinfo ip6po_rhinfo; /* Routing header related info. */
+ struct ip6_dest *ip6po_dest2; /* Destination options header(2nd part) */
+};
+
+struct ip6stat {
+ u_quad_t ip6s_total; /* total packets received */
+ u_quad_t ip6s_tooshort; /* packet too short */
+ u_quad_t ip6s_toosmall; /* not enough data */
+ u_quad_t ip6s_fragments; /* fragments received */
+ u_quad_t ip6s_fragdropped; /* frags dropped(dups, out of space) */
+ u_quad_t ip6s_fragtimeout; /* fragments timed out */
+ u_quad_t ip6s_fragoverflow; /* fragments that exceeded limit */
+ u_quad_t ip6s_forward; /* packets forwarded */
+ u_quad_t ip6s_cantforward; /* packets rcvd for unreachable dest */
+ u_quad_t ip6s_redirectsent; /* packets forwarded on same net */
+ u_quad_t ip6s_delivered; /* datagrams delivered to upper level*/
+ u_quad_t ip6s_localout; /* total ip packets generated here */
+ u_quad_t ip6s_odropped; /* lost packets due to nobufs, etc. */
+ u_quad_t ip6s_reassembled; /* total packets reassembled ok */
+ u_quad_t ip6s_fragmented; /* datagrams sucessfully fragmented */
+ u_quad_t ip6s_ofragments; /* output fragments created */
+ u_quad_t ip6s_cantfrag; /* don't fragment flag was set, etc. */
+ u_quad_t ip6s_badoptions; /* error in option processing */
+ u_quad_t ip6s_noroute; /* packets discarded due to no route */
+ u_quad_t ip6s_badvers; /* ip6 version != 6 */
+ u_quad_t ip6s_rawout; /* total raw ip packets generated */
+ u_quad_t ip6s_badscope; /* scope error */
+ u_quad_t ip6s_notmember; /* don't join this multicast group */
+ u_quad_t ip6s_nxthist[256]; /* next header history */
+ u_quad_t ip6s_m1; /* one mbuf */
+ u_quad_t ip6s_m2m[32]; /* two or more mbuf */
+ u_quad_t ip6s_mext1; /* one ext mbuf */
+ u_quad_t ip6s_mext2m; /* two or more ext mbuf */
+ u_quad_t ip6s_exthdrtoolong; /* ext hdr are not continuous */
+ u_quad_t ip6s_nogif; /* no match gif found */
+ u_quad_t ip6s_toomanyhdr; /* discarded due to too many headers */
+ /* XXX the following two items are not really AF_INET6 thing */
+ u_quad_t ip6s_pulldown; /* # of calls to m_pulldown */
+ u_quad_t ip6s_pulldown_copy; /* # of mbuf copies in m_pulldown */
+ u_quad_t ip6s_pulldown_alloc; /* # of mbuf allocs in m_pulldown */
+};
+
+#ifdef _KERNEL
+/* flags passed to ip6_output as last parameter */
+#define IPV6_DADOUTPUT 0x01 /* DAD */
+#define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */
+
+extern struct ip6stat ip6stat; /* statistics */
+extern u_int32_t ip6_id; /* fragment identifier */
+extern int ip6_defhlim; /* default hop limit */
+extern int ip6_defmcasthlim; /* default multicast hop limit */
+extern int ip6_forwarding; /* act as router? */
+extern int ip6_forward_srcrt; /* forward src-routed? */
+extern int ip6_gif_hlim; /* Hop limit for gif encap packet */
+extern int ip6_use_deprecated; /* allow deprecated addr as source */
+extern int ip6_rr_prune; /* router renumbering prefix
+ * walk list every 5 sec. */
+#ifdef MAPPED_ADDR_ENABLED
+extern int ip6_mapped_addr_on;
+#endif /* MAPPED_ADDR_ENABLED */
+
+extern struct socket *ip6_mrouter; /* multicast routing daemon */
+extern int ip6_sendredirects; /* send IP redirects when forwarding? */
+extern int ip6_maxfragpackets; /* Maximum packets in reassembly queue */
+extern int ip6_sourcecheck; /* Verify source interface */
+extern int ip6_sourcecheck_interval; /* Interval between log messages */
+extern int ip6_accept_rtadv; /* Acts as a host not a router */
+extern int ip6_keepfaith; /* Firewall Aided Internet Translator */
+extern int ip6_log_interval;
+extern time_t ip6_log_time;
+extern int ip6_hdrnestlimit; /* upper limit of # of extension headers */
+extern int ip6_dad_count; /* DupAddrDetectionTransmits */
+
+extern u_int32_t ip6_flow_seq;
+extern int ip6_auto_flowlabel;
+
+struct in6pcb;
+struct inpcb;
+
+int icmp6_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+
+void ip6_init __P((void));
+void ip6intr __P((void));
+void ip6_input __P((struct mbuf *));
+void ip6_freemoptions __P((struct ip6_moptions *));
+int ip6_unknown_opt __P((u_int8_t *, struct mbuf *, int));
+char * ip6_get_prevhdr __P((struct mbuf *, int));
+int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *));
+int ip6_process_hopopts __P((struct mbuf *, u_int8_t *, int, u_int32_t *,
+ u_int32_t *));
+void ip6_savecontrol __P((struct inpcb *, struct mbuf **, struct ip6_hdr *,
+ struct mbuf *));
+int ip6_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
+
+void ip6_forward __P((struct mbuf *, int));
+
+void ip6_mloopback __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *));
+int ip6_output __P((struct mbuf *, struct ip6_pktopts *,
+ struct route_in6 *, int,
+ struct ip6_moptions *, struct ifnet **));
+int ip6_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+int ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *, int));
+int ip6_optlen __P((struct inpcb *));
+
+int route6_input __P((struct mbuf **, int *, int));
+
+void frag6_init __P((void));
+int frag6_input __P((struct mbuf **, int *, int));
+void frag6_slowtimo __P((void));
+void frag6_drain __P((void));
+
+void rip6_init __P((void));
+int rip6_input __P((struct mbuf **mp, int *offp, int proto));
+int rip6_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+int rip6_output __P((struct mbuf *, ...));
+int rip6_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *));
+
+int dest6_input __P((struct mbuf **, int *, int));
+int none_input __P((struct mbuf **, int *, int));
+#endif /* _KERNEL */
+
+#endif /* !_NETINET6_IP6_VAR_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ip6protosw.h b/ecos/packages/net/tcpip/current/include/netinet6/ip6protosw.h
new file mode 100644
index 0000000..17e9644
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ip6protosw.h
@@ -0,0 +1,158 @@
+//==========================================================================
+//
+// include/netinet6_ip6protosw.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: ip6protosw.h,v 1.2 1999/12/10 10:04:28 angelos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ *
+ */
+
+/* BSDI protosw.h,v 2.3 1996/10/11 16:02:40 pjd Exp */
+
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)protosw.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _NETINET6_IP6PROTOSW_H_
+#define _NETINET6_IP6PROTOSW_H_
+
+/*
+ * Protocol switch table for IPv6.
+ * All other definitions should refer to sys/protosw.h
+ */
+
+struct mbuf;
+struct sockaddr;
+struct socket;
+struct domain;
+struct proc;
+struct ip6_hdr;
+
+/*
+ * argument type for the last arg of pr_ctlinput().
+ * should be consulted only with AF_INET6 family.
+ */
+struct ip6ctlparam {
+ struct mbuf *ip6c_m; /* start of mbuf chain */
+ struct ip6_hdr *ip6c_ip6; /* ip6 header of target packet */
+ int ip6c_off; /* offset of the target proto header */
+};
+
+struct ip6protosw {
+ short pr_type; /* socket type used for */
+ struct domain *pr_domain; /* domain protocol a member of */
+ short pr_protocol; /* protocol number */
+ short pr_flags; /* see below */
+
+/* protocol-protocol hooks */
+ int (*pr_input) /* input to protocol (from below) */
+ __P((struct mbuf **, int *, int));
+ int (*pr_output) /* output to protocol (from above) */
+ __P((struct mbuf *, ...));
+ void (*pr_ctlinput) /* control input (from below) */
+ __P((int, struct sockaddr *, void *));
+ int (*pr_ctloutput) /* control output (from above) */
+ __P((int, struct socket *, int, int, struct mbuf **));
+
+/* user-protocol hook */
+ int (*pr_usrreq) /* user request: see list below */
+ __P((struct socket *, int, struct mbuf *,
+ struct mbuf *, struct mbuf *, struct proc *));
+
+/* utility hooks */
+ void (*pr_init) /* initialization hook */
+ __P((void));
+
+ void (*pr_fasttimo) /* fast timeout (200ms) */
+ __P((void));
+ void (*pr_slowtimo) /* slow timeout (500ms) */
+ __P((void));
+ void (*pr_drain) /* flush any excess space possible */
+ __P((void));
+ int (*pr_sysctl) /* sysctl for protocol */
+ __P((int *, u_int, void *, size_t *, void *, size_t));
+};
+
+#endif /* !_NETINET6_IP6PROTOSW_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ipv6.h b/ecos/packages/net/tcpip/current/include/netinet6/ipv6.h
new file mode 100644
index 0000000..4926182
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ipv6.h
@@ -0,0 +1,153 @@
+//==========================================================================
+//
+// include/netinet6_ipv6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_IPV6_H
+#define _NETINET6_IPV6_H 1
+
+#define IPV6VERSION 6
+
+/*
+ * Header structures.
+ */
+
+struct ipv6
+{
+ uint32_t ipv6_versfl; /* Version and flow label word. */
+
+ uint16_t ipv6_length; /* Datagram length (not including the length
+ of this header). */
+ uint8_t ipv6_nexthdr; /* Next header type. */
+ uint8_t ipv6_hoplimit; /* Hop limit. */
+
+ struct in6_addr ipv6_src; /* Source address. */
+ struct in6_addr ipv6_dst; /* Destination address. */
+};
+
+#if __linux__
+#include <endian.h>
+#else /* __linux__ */
+#include <machine/endian.h>
+#endif /* __linux__ */
+
+struct ipv6hdr {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t ipv6_priority:4; /* going away? */
+ uint8_t ipv6_version:4;
+ uint32_t ipv6_flowid:24;
+#elif BYTE_ORDER == BIG_ENDIAN
+ uint32_t ipv6_flowid:24;
+ uint8_t ipv6_priority:4; /* going away? */
+ uint8_t ipv6_version:4;
+#else
+#error "Don't know what endian to use."
+#endif
+ uint16_t ipv6_len;
+ uint8_t ipv6_nextheader;
+ uint8_t ipv6_hoplimit;
+ struct in6_addr ipv6_src; /* source address */
+ struct in6_addr ipv6_dst; /* destination address */
+};
+
+/*
+ * Macros and defines for header fields, and values thereof.
+ * Assume things are in host order for these three macros.
+ */
+
+#define IPV6_VERSION(h) ((h)->ipv6_versfl >> 28)
+#define IPV6_PRIORITY(h) (((h)->ipv6_versfl & 0x0f000000) >> 24)
+#define IPV6_FLOWID(h) ((h)->ipv6_versfl & 0x00ffffff)
+
+#define MAXHOPLIMIT 64
+#define IPV6_MINMTU 576
+
+/*
+ * Other IPv6 header definitions.
+ */
+
+/* Fragmentation header & macros for it. NOTE: Host order assumption. */
+
+struct ipv6_fraghdr
+{
+ uint8_t frag_nexthdr; /* Next header type. */
+ uint8_t frag_reserved;
+ uint16_t frag_bitsoffset; /* More bit and fragment offset. */
+ uint32_t frag_id; /* Fragment identifier. */
+};
+
+#define FRAG_MOREMASK 0x1
+#define FRAG_OFFMASK 0xFFF8
+#define FRAG_MORE_BIT(fh) ((fh)->frag_bitsoffset & FRAG_MOREMASK)
+#define FRAG_OFFSET(fh) ((fh)->frag_bitsoffset & FRAG_OFFMASK)
+
+/* Source routing header. Host order assumption for macros. */
+
+struct ipv6_srcroute0
+{
+ uint8_t i6sr_nexthdr; /* Next header type. */
+ uint8_t i6sr_len; /* RH len in 8-byte addrs, !incl this structure */
+ uint8_t i6sr_type; /* Routing type, should be 0 */
+ uint8_t i6sr_left; /* Segments left */
+ uint32_t i6sr_reserved; /* 8 bits of reserved padding. */
+};
+
+#define I6SR_BITMASK(i6sr) ((i6sr)->i6sr_reserved & 0xffffff)
+
+/* Options header. For "ignoreable" options. */
+
+struct ipv6_opthdr
+{
+ uint8_t oh_nexthdr; /* Next header type. */
+ uint8_t oh_extlen; /* Header extension length. */
+ uint8_t oh_data[6]; /* Option data, may be reserved for
+ alignment purposes. */
+};
+
+#define OPT_PAD1 0
+#define OPT_PADN 1
+#define OPT_JUMBO 194
+
+struct ipv6_option
+{
+ uint8_t opt_type; /* Option type. */
+ uint8_t opt_datalen; /* Option data length. */
+ uint8_t opt_data[1]; /* Option data. */
+};
+#endif /* _NETINET6_IPV6_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ipv6_addrconf.h b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_addrconf.h
new file mode 100644
index 0000000..7764eb4
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_addrconf.h
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// include/netinet6_ipv6_addrconf.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_IPV6_ADDRCONF_H
+#define _NETINET6_IPV6_ADDRCONF_H 1
+
+/*
+ * Function definitions.
+ */
+void addrconf_init __P((void));
+void addrconf_timer __P((void *));
+void addrconf_dad __P((struct in6_ifaddr *));
+
+#endif /* _NETINET6_IPV6_ADDRCONF_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ipv6_icmp.h b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_icmp.h
new file mode 100644
index 0000000..856f65b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_icmp.h
@@ -0,0 +1,287 @@
+//==========================================================================
+//
+// include/netinet6_ipv6_icmp.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_IPV6_ICMP_H
+#define _NETINET6_IPV6_ICMP_H 1
+
+/*
+ * ICMPv6 header.
+ */
+
+struct ipv6_icmp
+{
+ uint8_t icmp_type;
+ uint8_t icmp_code;
+ uint16_t icmp_cksum;
+ union
+ {
+ uint32_t ih_reserved;
+ struct
+ {
+ uint16_t ihs_id;
+ uint16_t ihs_seq;
+ } ih_idseq;
+ struct
+ {
+ uint8_t ihr_hoplimit;
+ uint8_t ihr_bits;
+ uint16_t ihr_lifetime;
+ } ih_radv;
+ } icmp_hun;
+#define icmp_unused icmp_hun.ih_reserved
+#define icmp_nexthopmtu icmp_hun.ih_reserved
+#define icmp_paramptr icmp_hun.ih_reserved
+#define icmp_echoid icmp_hun.ih_idseq.ihs_id
+#define icmp_echoseq icmp_hun.ih_idseq.ihs_seq
+#define icmp_grpdelay icmp_hun.ih_idseq.ihs_id
+#define icmp_grpunused icmp_hun.ih_idseq.ihs_seq
+#define icmp_nadvbits icmp_hun.ih_reserved
+#define icmp_radvhop icmp_hun.ih_radv.ihr_hoplimit
+#define icmp_radvbits icmp_hun.ih_radv.ihr_bits
+#define icmp_radvlifetime icmp_hun.ih_radv.ihr_lifetime
+ union
+ {
+ struct
+ {
+ struct ipv6 ido_ipv6;
+ uint8_t ido_remaining[1];
+ } id_offending;
+ uint8_t id_data[1];
+ struct
+ {
+ struct in6_addr idn_addr;
+ uint8_t idn_ext[1];
+ } id_neighbor;
+ struct
+ {
+ struct in6_addr idr_addr1;
+ struct in6_addr idr_addr2;
+ uint8_t idr_ext[1];
+ } id_redirect;
+ struct
+ {
+ uint32_t ida_reachable;
+ uint32_t ida_retrans;
+ uint8_t ida_opt[1];
+ } id_radv;
+ } icmp_dun;
+#define icmp_offending icmp_dun.id_offending
+#define icmp_ipv6 icmp_dun.id_offending.ido_ipv6
+
+#define icmp_echodata icmp_dun.id_data
+
+#define icmp_grpaddr icmp_dun.id_neighbor.idn_addr
+
+#define icmp_radvreach icmp_dun.id_radv.ida_reachable
+#define icmp_radvretrans icmp_dun.id_radv.ida_retrans
+#define icmp_radvext icmp_dun.id_radv.ida_opt
+
+#define icmp_nsoltarg icmp_dun.id_neighbor.idn_addr
+#define icmp_nsolext icmp_dun.id_neighbor.idn_ext
+#define icmp_nadvaddr icmp_dun.id_neighbor.idn_addr
+#define icmp_nadvext icmp_dun.id_neighbor.idn_ext
+
+#define icmp_redirtarg icmp_dun.id_redirect.idr_addr1
+#define icmp_redirdest icmp_dun.id_redirect.idr_addr2
+#define icmp_redirext icmp_dun.id_redirect.idr_ext
+};
+
+/*
+ * ICMPv6 extension constants.
+ */
+
+#define EXT_SOURCELINK 1
+#define EXT_TARGETLINK 2
+#define EXT_PREFIX 3
+#define EXT_REDIR 4
+#define EXT_MTU 5
+
+/*
+ * Extension structures for IPv6 discovery messages.
+ */
+
+struct icmp_exthdr /* Generic extension */
+{
+ uint8_t ext_id;
+ uint8_t ext_length; /* Length is 8 * this field, 0 is invalid. */
+ uint8_t ext_data[6]; /* Padded to 8 bytes. */
+};
+
+struct ext_prefinfo /* Prefix information */
+{
+ uint8_t pre_extid;
+ uint8_t pre_length;
+
+ uint8_t pre_prefixsize;
+ uint8_t pre_bits;
+
+ uint32_t pre_valid;
+ uint32_t pre_preferred;
+ uint32_t pre_reserved;
+
+ struct in6_addr pre_prefix;
+};
+
+/*
+ * Values for pre_bits
+ */
+#define ICMPV6_PREFIX_ONLINK 0x80
+#define ICMPV6_PREFIX_AUTO 0x40
+
+struct ext_redir /* Redirected header */
+{
+ uint8_t rd_extid;
+ uint8_t rd_length;
+ uint8_t rd_reserved[6];
+ struct ipv6 rd_header;
+};
+
+struct ext_mtu /* Recommended link MTU. */
+{
+ uint8_t mtu_extid;
+ uint8_t mtu_length;
+ uint16_t mtu_reserved;
+ uint32_t mtu_mtu;
+};
+
+/*
+ * Constants
+ */
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enought to contain the returned ip header.
+ * Only then can we do the check to see if enough bits of packet
+ * data have been returned, since we need to check the returned
+ * ipv6 header length.
+ */
+#define ICMPV6_MINLEN 8 /* abs minimum */
+#define ICMPV6_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
+#define ICMPV6_NADVMINLEN 24 /* min neighbor advertisement */
+#define ICMPV6_NSOLMINLEN 24 /* min neighbor solicit */
+#define ICMPV6_RADVMINLEN 16 /* min router advertisement */
+#define ICMPV6_RSOLMINLEN 8 /* min router solicit */
+#define ICMPV6_REDIRMINLEN 40 /* min redirect */
+#define ICMPV6_HLPMINLEN (8 + sizeof(struct ipv6) + 8) /* HLP demux len. */
+#define ICMPV6_MAXLEN 576 /* This should be whatever IPV6_MINMTU
+ will be. I take this to be the WHOLE
+ packet, including IPv6 header, and any
+ IPv6 options before the ICMP message. */
+
+/*
+ * Definition of type and code field values.
+ * ICMPv6 fixes things so that info messages are >= 128.
+ */
+
+/* Error messages and codes. */
+
+#define ICMPV6_UNREACH 1 /* dest unreachable, codes: */
+#define ICMPV6_UNREACH_NOROUTE 0 /* No route to dest. */
+#define ICMPV6_UNREACH_ADMIN 1 /* Admin. prohibited */
+#define ICMPV6_UNREACH_NOTNEIGHBOR 2 /* For strict source
+ routing. */
+#define ICMPV6_UNREACH_ADDRESS 3 /* Address unreach. */
+#define ICMPV6_UNREACH_PORT 4 /* Port unreachable */
+#define ICMPV6_TOOBIG 2 /* Packet too big. */
+#define ICMPV6_TIMXCEED 3 /* time exceeded, code: */
+#define ICMPV6_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMPV6_TIMXCEED_REASS 1 /* Reassembly t.o. */
+#define ICMPV6_PARAMPROB 4 /* ip header bad */
+#define ICMPV6_PARAMPROB_PROB 0 /* Actual incorrect
+ parameter. */
+#define ICMPV6_PARAMPROB_NEXTHDR 1 /* Bad next hdr. */
+#define ICMPV6_PARAMPROB_BADOPT 2 /* Unrec. option */
+
+/* Info messages. */
+
+#define ICMPV6_ECHO 128 /* echo service */
+#define ICMPV6_ECHOREPLY 129 /* echo reply */
+#define ICMPV6_GRPQUERY 130 /* Query group membership. */
+#define ICMPV6_GRPREPORT 131 /* Join mcast group. */
+#define ICMPV6_GRPTERM 132 /* Leave mcast group. */
+
+#define ICMPV6_ROUTERSOL 133 /* Router solicit. */
+#define ICMPV6_ROUTERADV 134 /* Router advertisement. */
+#define ICMPV6_NEIGHBORSOL 135 /* Neighbor solicit. */
+#define ICMPV6_NEIGHBORADV 136 /* Neighbor advertisement. */
+
+#define ICMPV6_REDIRECT 137 /* ICMPv6 redirect. */
+
+/* Defined this way to save some HTONL cycles on little-endian boxes. */
+#if BYTE_ORDER == BIG_ENDIAN
+#define ICMPV6_NEIGHBORADV_RTR 0x80000000 /* Router flag. */
+#define ICMPV6_NEIGHBORADV_SOL 0x40000000 /* Solicited flag. */
+#define ICMPV6_NEIGHBORADV_OVERRIDE 0x20000000 /* Override flag. */
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+#define ICMPV6_NEIGHBORADV_RTR 0x80 /* Router flag. */
+#define ICMPV6_NEIGHBORADV_SOL 0x40 /* Solicited flag. */
+#define ICMPV6_NEIGHBORADV_OVERRIDE 0x20 /* Override flag. */
+#endif
+
+#define ICMPV6_MAXTYPE 137
+
+#define ICMPV6_INFOTYPE(type) ((type) >= 128)
+
+#if defined(_KERNEL) || defined(KERNEL)
+#include <netinet6/ipv6_var.h>
+
+/* Function prototypes */
+void ipv6_icmp_error(struct mbuf *, int, int, uint32_t);
+void ipv6_icmp_input(struct mbuf *, int);
+void ipv6_gsolicit(struct ifnet *, struct mbuf *, struct rtentry *);
+void ipv6_rtrequest(int, struct rtentry *, struct sockaddr *);
+int ipv6_icmp_output(struct mbuf *,struct socket *, struct in6_addr *);
+int ipv6_icmp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+#if __NetBSD__ || __FreeBSD__
+int ipv6_icmp_usrreq(struct socket *,int, struct mbuf *,struct mbuf *, struct mbuf *, struct proc *);
+#else /* __NetBSD__ || __FreeBSD__ */
+int ipv6_icmp_usrreq(struct socket *,int, struct mbuf *,struct mbuf *, struct mbuf *);
+#endif /* __NetBSD__ || __FreeBSD__ */
+
+void ipv6_routersol_input(struct mbuf *, int);
+void ipv6_routeradv_input(struct mbuf *, int);
+void ipv6_neighborsol_input(struct mbuf *, int);
+void ipv6_neighboradv_input(struct mbuf *, int);
+void ipv6_redirect_input(struct mbuf *, int);
+#endif /* defined(_KERNEL) || defined(KERNEL) */
+
+#endif /* _NETINET6_IPV6_ICMP_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ipv6_trans.h b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_trans.h
new file mode 100644
index 0000000..69fd520
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_trans.h
@@ -0,0 +1,56 @@
+//==========================================================================
+//
+// include/netinet6_ipv6_trans.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_IPV6_TRANS_H
+#define _NETINET6_IPV6_TRANS_H 1
+
+/* I don't include any #includes, as I'm using this for our (NRL)
+ * modified netinet/ip_output() function; thus, this #include should be
+ * used/stuck-in after all the other necessary includes.
+ *
+ * And yes, I only put one declaration here. There's no real need
+ * to stick the other prototypes in here and have ip_output() fluffed
+ * during preprocessing time.
+ */
+
+int ipv4_tunnel_output __P((struct mbuf *, struct sockaddr_in *, struct rtentry *));
+
+#endif /* _NETINET6_IPV6_TRANS_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/ipv6_var.h b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_var.h
new file mode 100644
index 0000000..ba48ed8
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/ipv6_var.h
@@ -0,0 +1,385 @@
+//==========================================================================
+//
+// include/netinet6_ipv6_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+#ifndef _NETINET6_IPV6_VAR_H
+#define _NETINET6_IPV6_VAR_H 1
+
+#include <netinet6/in6.h>
+
+/*
+ * IPv6 multicast "options". Session state for multicast, including
+ * weird per-session multicast things.
+ */
+
+struct ipv6_moptions
+{
+ struct ifnet *i6mo_multicast_ifp; /* ifp for outgoing multicasts */
+ u_char i6mo_multicast_ttl; /* TTL for outgoing multicasts.
+ Does this matter in IPv6? */
+ u_char i6mo_multicast_loop; /* 1 => hear sends if a member */
+ u_short i6mo_num_memberships; /* no. memberships this socket */
+ struct in6_multi *i6mo_membership[IN6_MAX_MEMBERSHIPS];
+};
+
+/*
+ * IPv6 stats.
+ */
+
+#if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802
+#define _IPV6STAT_TYPE u_quad_t
+#else /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802 */
+#define _IPV6STAT_TYPE u_long
+#endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802 */
+
+struct ipv6stat {
+ _IPV6STAT_TYPE ips_total; /* total packets received */
+ _IPV6STAT_TYPE ips_tooshort; /* packet too short */
+ _IPV6STAT_TYPE ips_toosmall; /* not enough data */
+ _IPV6STAT_TYPE ips_fragments; /* fragments received */
+ _IPV6STAT_TYPE ips_fragdropped; /* frags dropped (dups, out of space) */
+ _IPV6STAT_TYPE ips_fragtimeout; /* fragments timed out */
+ _IPV6STAT_TYPE ips_forward; /* packets forwarded */
+ _IPV6STAT_TYPE ips_cantforward; /* packets rcvd for unreachable dest */
+ _IPV6STAT_TYPE ips_redirectsent; /* packets forwarded on same net */
+ _IPV6STAT_TYPE ips_noproto; /* unknown or unsupported protocol */
+ _IPV6STAT_TYPE ips_delivered; /* datagrams delivered to upper level*/
+ _IPV6STAT_TYPE ips_localout; /* total ip packets generated here */
+ _IPV6STAT_TYPE ips_odropped; /* lost packets due to nobufs, etc. */
+ _IPV6STAT_TYPE ips_reassembled; /* total packets reassembled ok */
+ _IPV6STAT_TYPE ips_fragmented; /* datagrams sucessfully fragmented */
+ _IPV6STAT_TYPE ips_ofragments; /* output fragments created */
+ _IPV6STAT_TYPE ips_cantfrag; /* don't fragment flag was set, etc. */
+ _IPV6STAT_TYPE ips_badoptions; /* error in option processing */
+ _IPV6STAT_TYPE ips_noroute; /* packets discarded due to no route */
+ _IPV6STAT_TYPE ips_badvers; /* IPv6 version != 6 */
+ _IPV6STAT_TYPE ips_rawout; /* total raw ip packets generated */
+};
+
+#if defined(_KERNEL) || defined(KERNEL)
+/*
+ * The IPv6 fragment queue entry structure.
+ * Notes:
+ * Nodes are stored in ttl order.
+ * prefix comes from whichever packet gets here first.
+ * data contains a chain of chains of mbufs (m_next down a chain, m_nextpkt
+ * chaining chains together) where the chains are ordered by assembly
+ * position. When two chains are contiguous for reassembly, they are
+ * combined and the frag header disappears.
+ * The structure is deliberately sized so MALLOC will round up on the order
+ * of much less than the total size instead of doubling the size.
+ */
+
+struct ipv6_fragment
+{
+ struct ipv6_fragment *next; /* Next fragment chain */
+ struct mbuf *prefix; /* Headers before frag header(s) */
+ struct mbuf *data; /* Frag headers + whatever data */
+ u_char ttl; /* Fragment chain TTL. */
+ u_char flags; /* Bit 0 indicates got end of chain */
+};
+
+/*
+ * Structures and definitions for discovery mechanisms in IPv6.
+ */
+
+/*
+ * Neighbor cache:
+ *
+ * Number of unanswered probes is in discq.
+ * "Time of next event" will be in rt->rt_rmx.rmx_expire
+ * (rmx_expire will actually be quite overloaded, actually.)
+ * Status REACHABLE will be dq_unanswered < 0
+ * Status PROBE will be dq_unanswered >= 0
+ * Status INCOMPLETE will be link addr length of 0 if held,
+ * or deleted if not held.
+ *
+ * If held, but INCOMPLETE fails set RTF_REJECT and make sure
+ * IPv6 and HLP's know how to deal with RTF_REJECT being set.
+ */
+
+struct discq /* Similar to v4's llinfo_arp, discovery's "neighbor entry". */
+{
+ struct discq *dq_next,*dq_prev; /* For {ins,rem}que(). */
+ struct rtentry *dq_rt; /* Back pointer to routing entry for
+ an address that may be dead. */
+ struct mbuf *dq_queue; /* Queue of outgoing messages. */
+ int dq_unanswered; /* Number of unanswered probes. */
+};
+
+#if !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802)
+/* Routing flag redefinitions */
+#define RTF_ISAROUTER RTF_PROTO2 /* Neighbor is a router. */
+#define RTF_DEFAULT RTF_PROTO1 /* Default route. */
+#endif /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */
+
+/*
+ * These should be configurable parameters, see ipv6_discovery.c.
+ * All units are in comments besides constants.
+ */
+
+#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16 /* seconds */
+#define MAX_INITIAL_RTR_ADVERTISEMENTS 3 /* transmissions */
+#define MAX_RTR_RESPONSE_DELAY 2 /* seconds */
+
+#define MAX_RTR_SOLICITATION_DELAY 1 /* second */
+#define RTR_SOLICITATION_INTERVAL 3 /* seconds */
+#define MAX_RTR_SOLICITATIONS 3 /* transmissions */
+
+#define MAX_MULTICAST_SOLICIT 3 /* transmissions */
+#define MAX_UNICAST_SOLICIT 3 /* transmissions */
+#define MAX_ANYCAST_DELAY_TIME 1 /* seconds */
+#define MAX_NEIGHBOR_ADVERTISEMENTS 3 /* transmissions */
+#define MIN_NEIGHBOR_ADVERT_INTERVAL 16 /* seconds */
+#define REACHABLE_TIME 30 /* seconds */
+#define RETRANS_TIMER 3 /* seconds */
+#define DELAY_FIRST_PROBE_TIME 3 /* seconds */
+/* Need to somehow define random factors. */
+
+#define NEXTHOP_CLEAN_INTERVAL 600 /* seconds */
+#define REJECT_TIMER 20 /* seconds */
+
+/*
+ * Child of a router or tunnel. Is a "meta-entry" for garbage collection.
+ */
+
+struct v6child
+{
+ struct v6child *v6c_next,*v6c_prev; /* For {ins,rem}que() */
+ struct v6router *v6c_parent; /* Parent router. I'm null if
+ I'm the router, or a tunnel
+ child. */
+ struct rtentry *v6c_route; /* Next-hop cache entry. I won't
+ be holding it, but I'm attached
+ to it, like discq is to neighbor
+ cache entries. */
+};
+
+/*
+ * Default router list entry. Should be inserted
+ * in priority order. Will also have entries for non-
+ * default routers, because I may be a router myself.
+ */
+
+struct v6router
+{
+ struct v6router *v6r_next,*v6r_prev; /* For {ins,rem}que() */
+ struct rtentry *v6r_rt; /* Route for this. Could be neighbor,
+ could be tunnel. */
+ struct v6child v6r_children; /* Children of this router. */
+
+ /* Metric information? */
+ uint32_t v6r_expire; /* Expiration time. */
+};
+#define V6R_SIN6(v6r) ((struct sockaddr_in6 *)rt_key((v6r)->v6r_rt))
+
+/*
+ * Flags for "flags" argument in ipv6_output().
+ */
+
+#define IPV6_FORWARDING 0x1 /* Most of IPv6 header exists? */
+#define IPV6_RAWOUTPUT 0x2 /* Raw IPv6 packet! */
+#define IPV6_ROUTETOIF SO_DONTROUTE /* Include sys/socket.h... */
+
+void ipv6_init __P((void));
+void ipv6_drain __P((void));
+void ipv6_slowtimo __P((void));
+int ipv6_sysctl __P((int *, uint, void *, size_t *, void *, size_t));
+struct route6;
+
+#if __FreeBSD__
+int ipv6_ctloutput __P((struct socket *, struct sockopt *));
+int ripv6_ctloutput __P((struct socket *, struct sockopt *));
+#else /* __FreeBSD__ */
+int ipv6_ctloutput __P((int, struct socket *,int,int, struct mbuf **));
+int ripv6_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+#endif /* __FreeBSD__ */
+void ripv6_init __P((void));
+#if __OpenBSD__
+void ripv6_input __P((struct mbuf *, ...));
+int ripv6_output __P((struct mbuf *, ...));
+#else /* __OpenBSD__ */
+void ripv6_input __P((struct mbuf *, int));
+int ripv6_output __P((struct mbuf *, struct socket *, struct in6_addr *, struct mbuf *));
+#endif /* __OpenBSD__ */
+
+#if __NetBSD__ || __FreeBSD__
+int ripv6_usrreq_send(struct socket *, int, struct mbuf *, struct sockaddr *,
+ struct mbuf *, struct proc *);
+#else /* __NetBSD__ || __FreeBSD__ */
+int ripv6_usrreq_send(struct socket *, int, struct mbuf *, struct sockaddr *,
+ struct mbuf *);
+#endif /* __NetBSD__ || __FreeBSD__ */
+
+#if __FreeBSD__
+int ripv6_usrreq_abort(struct socket *);
+int ripv6_usrreq_attach(struct socket *, int , struct proc *);
+int ripv6_usrreq_bind(struct socket *, struct sockaddr *, struct proc *);
+int ripv6_usrreq_connect(struct socket *, struct sockaddr *, struct proc *);
+int ripv6_usrreq_control(struct socket *, u_long, caddr_t, struct ifnet *,
+ struct proc *);
+int ripv6_usrreq_detach(struct socket *);
+int ripv6_usrreq_peeraddr(struct socket *, struct sockaddr **);
+int ripv6_usrreq_sense(struct socket *, struct stat *);
+int ripv6_usrreq_shutdown(struct socket *);
+int ripv6_usrreq_sockaddr(struct socket *, struct sockaddr **);
+#else /* __FreeBSD__ */
+#if __NetBSD__
+int ripv6_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *, struct proc *));
+#else /* __NetBSD__ */
+int ripv6_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *));
+#endif /* __NetBSD__ */
+#endif /* __FreeBSD__ */
+
+#if __OpenBSD__
+void ipv6_input __P((struct mbuf *, ...));
+int ipv6_output __P((struct mbuf *, ...));
+#else /* __OpenBSD__ */
+void ipv6_input __P((struct mbuf *, int));
+int ipv6_output __P((struct mbuf *, struct route6 *, int, struct ipv6_moptions *, struct ifnet *, struct socket *));
+#endif /* __OpenBSD__ */
+void ipv6_reasm __P((struct mbuf *, int));
+void ipv6_hop __P((struct mbuf *, int));
+
+#if __FreeBSD__
+int in6_control __P((struct socket *,int, caddr_t, struct ifnet *,int, struct proc *));
+#else /* __FreeBSD__ */
+#if __NetBSD__
+int in6_control __P((struct socket *,u_long, caddr_t, struct ifnet *,int, struct proc *));
+#else /* __NetBSD__ */
+int in6_control __P((struct socket *,int, caddr_t, struct ifnet *,int));
+#endif /* __NetBSD__ */
+#endif /* __FreeBSD__ */
+void ipv6_stripoptions __P((struct mbuf *, int));
+struct in6_multi *in6_addmulti __P((struct in6_addr *,struct ifnet *));
+void in6_delmulti __P((struct in6_multi *));
+
+#if __FreeBSD__
+/* ripv6_usrreq and ipv6_icmp_usrreq functions */
+extern struct pr_usrreqs ripv6_usrreqs;
+extern struct pr_usrreqs ipv6_icmp_usrreqs;
+
+extern int ripv6_usr_attach(struct socket *, int , struct proc *);
+extern int ripv6_usr_disconnect(struct socket *);
+extern int ripv6_usr_abort(struct socket *);
+extern int ripv6_usr_detach(struct socket *);
+extern int ripv6_usr_bind(struct socket *, struct sockaddr *, struct proc *);
+extern int ripv6_usr_connect(struct socket *, struct sockaddr *, struct proc *);
+extern int ripv6_usr_shutdown(struct socket *);
+extern int ripv6_usr_send(struct socket *, int, struct mbuf *,
+ struct sockaddr *, struct mbuf *, struct proc *);
+extern int ripv6_usr_control(struct socket *, int, caddr_t,
+ struct ifnet *, struct proc *);
+extern int ripv6_usr_sense(struct socket *, struct stat *);
+extern int ripv6_usr_sockaddr(struct socket *, struct sockaddr **);
+extern int ripv6_usr_peeraddr(struct socket *, struct sockaddr **);
+#endif /* __FreeBSD__ */
+
+extern int ipv6_icmp_send(struct socket *, int, struct mbuf *,
+ struct sockaddr *, struct mbuf *, struct proc *);
+
+#if __OpenBSD__
+#ifdef NRL_IPSEC
+void *ipv6_trans_ctlinput __P((int, struct sockaddr *, void *, struct mbuf *));
+#else /* NRL_IPSEC */
+void *ipv6_trans_ctlinput __P((int, struct sockaddr *, void *));
+#endif /* NRL_IPSEC */
+#else /* __OpenBSD__ */
+struct ip;
+#ifdef NRL_IPSEC
+void ipv6_trans_ctlinput __P((int, struct sockaddr *, struct ip *, struct mbuf *));
+#else /* NRL_IPSEC */
+void ipv6_trans_ctlinput __P((int, struct sockaddr *, struct ip *));
+#endif /* NRL_IPSEC */
+#endif /* __OpenBSD__ */
+
+/* These might belong in in_pcb.h */
+struct inpcb;
+#if __FreeBSD__
+/*
+ * FreeBSD, having done away with the *_usrreq() functions no longer needs to
+ * pass mbufs to these functions. Thus they pass in sockaddrs instead.
+ */
+int in6_pcbbind(struct inpcb *, struct sockaddr *);
+int in6_pcbconnect(struct inpcb *, struct sockaddr *);
+int in6_setsockaddr(struct inpcb *, struct sockaddr **);
+int in6_setpeeraddr(struct inpcb *, struct sockaddr **);
+#else /* __FreeBSD__ */
+int in6_pcbbind(struct inpcb *, struct mbuf *);
+int in6_pcbconnect(struct inpcb *, struct mbuf *);
+int in6_setsockaddr(struct inpcb *, struct mbuf *);
+int in6_setpeeraddr(struct inpcb *, struct mbuf *);
+#endif /* __FreeBSD__ */
+void ipv6_onlink_query(struct sockaddr_in6 *);
+int ipv6_verify_onlink(struct sockaddr_in6 *);
+
+#if __FreeBSD__
+struct inpcbhead; /* XXX? Forward declaration needed. */
+#define __IN6_PCBNOTIFY_FIRSTARG struct inpcbhead *
+#endif /* __FreeBSD__ */
+#if __NetBSD__ || __OpenBSD__
+struct inpcbtable;
+#define __IN6_PCBNOTIFY_FIRSTARG struct inpcbtable *
+#endif /* __NetBSD__ || __OpenBSD__ */
+#if __bsdi__
+struct inpcb;
+#define __IN6_PCBNOTIFY_FIRSTARG struct inpcb *
+#endif /* __bsdi__ */
+
+#if (!__OpenBSD__ && defined(IPSEC)) || (__OpenBSD__ && defined(NRL_IPSEC))
+int in6_pcbnotify __P((__IN6_PCBNOTIFY_FIRSTARG, struct sockaddr *, uint,
+ struct in6_addr *, uint, int, void (*)(struct inpcb *,
+ int), struct mbuf *, int));
+#else /* (!__OpenBSD__ && defined(IPSEC)) || (__OpenBSD__ && defined(NRL_IPSEC)) */
+int in6_pcbnotify __P((__IN6_PCBNOTIFY_FIRSTARG, struct sockaddr *, uint,
+ struct in6_addr *, uint, int, void (*)(struct inpcb *,
+ int)));
+#endif /* (!__OpenBSD__ && defined(IPSEC)) || (__OpenBSD__ && defined(NRL_IPSEC)) */
+
+#undef __IN6_PCBNOTIFY_FIRSTARG
+
+void ipv6_freemoptions __P((struct ipv6_moptions *));
+
+int ipv6_controltoheader(struct mbuf **m, struct mbuf *control, struct ifnet **forceifp, int *);
+struct mbuf *ipv6_headertocontrol(struct mbuf *m, int extra, int inp_flags);
+#endif /* defined(_KERNEL) || defined(KERNEL) */
+
+#endif /* _NETINET6_IPV6_VAR_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/mld6_var.h b/ecos/packages/net/tcpip/current/include/netinet6/mld6_var.h
new file mode 100644
index 0000000..655e104
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/mld6_var.h
@@ -0,0 +1,80 @@
+//==========================================================================
+//
+// include/netinet6_mld6_var.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: mld6_var.h,v 1.1 1999/12/08 06:50:23 itojun Exp $ */
+
+/*
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET6_MLD6_VAR_H_
+#define _NETINET6_MLD6_VAR_H_
+
+#ifdef _KERNEL
+
+#define MLD6_RANDOM_DELAY(X) (random() % (X) + 1)
+
+/*
+ * States for MLD stop-listening processing
+ */
+#define MLD6_OTHERLISTENER 0
+#define MLD6_IREPORTEDLAST 1
+
+void mld6_init __P((void));
+void mld6_input __P((struct mbuf *, int));
+void mld6_start_listening __P((struct in6_multi *));
+void mld6_stop_listening __P((struct in6_multi *));
+void mld6_fasttimeo __P((void));
+#endif /* _KERNEL */
+
+#endif /* _NETINET6_MLD6_VAR_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/nd6.h b/ecos/packages/net/tcpip/current/include/netinet6/nd6.h
new file mode 100644
index 0000000..5e5e70c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/nd6.h
@@ -0,0 +1,335 @@
+//==========================================================================
+//
+// include/netinet6.nd6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: nd6.h,v 1.1 1999/12/08 06:50:23 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET6_ND6_H_
+#define _NETINET6_ND6_H_
+
+#include <sys/queue.h>
+
+struct llinfo_nd6 {
+ struct llinfo_nd6 *ln_next;
+ struct llinfo_nd6 *ln_prev;
+ struct rtentry *ln_rt;
+ struct mbuf *ln_hold; /* last packet until resolved/timeout */
+ long ln_asked; /* number of queries already sent for this addr */
+ u_long ln_expire; /* lifetime for NDP state transition */
+ short ln_state; /* reachability state */
+ short ln_router; /* 2^0: ND6 router bit */
+};
+
+#define ND6_LLINFO_NOSTATE -2
+#define ND6_LLINFO_WAITDELETE -1
+#define ND6_LLINFO_INCOMPLETE 0
+#define ND6_LLINFO_REACHABLE 1
+#define ND6_LLINFO_STALE 2
+#define ND6_LLINFO_DELAY 3
+#define ND6_LLINFO_PROBE 4
+
+struct nd_ifinfo {
+ u_int32_t linkmtu; /* LinkMTU */
+ u_int32_t maxmtu; /* Upper bound of LinkMTU */
+ u_int32_t basereachable; /* BaseReachableTime */
+ u_int32_t reachable; /* Reachable Time */
+ u_int32_t retrans; /* Retrans Timer */
+ int recalctm; /* BaseReacable re-calculation timer */
+ u_int8_t chlim; /* CurHopLimit */
+ u_int8_t receivedra;
+};
+
+struct in6_nbrinfo {
+ char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct in6_addr addr; /* IPv6 address of the neighbor */
+ long asked; /* number of queries already sent for this addr */
+ int isrouter; /* if it acts as a router */
+ int state; /* reachability state */
+ int expire; /* lifetime for NDP state transition */
+};
+
+#define DRLSTSIZ 10
+#define PRLSTSIZ 10
+struct in6_drlist {
+ char ifname[IFNAMSIZ];
+ struct {
+ struct in6_addr rtaddr;
+ u_char flags;
+ u_short rtlifetime;
+ u_long expire;
+ u_short if_index;
+ } defrouter[DRLSTSIZ];
+};
+
+struct in6_prlist {
+ char ifname[IFNAMSIZ];
+ struct {
+ struct in6_addr prefix;
+ struct prf_ra raflags;
+ u_char prefixlen;
+ u_long vltime;
+ u_long pltime;
+ u_long expire;
+ u_short if_index;
+ u_short advrtrs; /* number of advertisement routers */
+ struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
+ } prefix[PRLSTSIZ];
+};
+
+struct in6_ndireq {
+ char ifname[IFNAMSIZ];
+ struct nd_ifinfo ndi;
+};
+
+/* protocol constants */
+#define MAX_RTR_SOLICITATION_DELAY 1 /*1sec*/
+#define RTR_SOLICITATION_INTERVAL 4 /*4sec*/
+#define MAX_RTR_SOLICITATIONS 3
+
+#define ND6_INFINITE_LIFETIME 0xffffffff
+
+#ifdef _KERNEL
+/* node constants */
+#define MAX_REACHABLE_TIME 3600000 /* msec */
+#define REACHABLE_TIME 30000 /* msec */
+#define RETRANS_TIMER 1000 /* msec */
+#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */
+#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */
+#define ND_COMPUTE_RTIME(x) \
+ (((MIN_RANDOM_FACTOR * (x >> 10)) + (random() & \
+ ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
+
+struct nd_defrouter {
+ LIST_ENTRY(nd_defrouter) dr_entry;
+#define dr_next dr_entry.le_next
+ struct in6_addr rtaddr;
+ u_char flags;
+ u_short rtlifetime;
+ u_long expire;
+ struct ifnet *ifp;
+};
+
+struct nd_prefix {
+ struct ifnet *ndpr_ifp;
+ LIST_ENTRY(nd_prefix) ndpr_entry;
+ struct sockaddr_in6 ndpr_prefix; /* prefix */
+ struct in6_addr ndpr_mask; /* netmask derived from the prefix */
+ struct in6_addr ndpr_addr; /* address that is derived from the prefix */
+ u_int32_t ndpr_vltime; /* advertised valid lifetime */
+ u_int32_t ndpr_pltime; /* advertised preferred lifetime */
+ time_t ndpr_expire; /* expiration time of the prefix */
+ time_t ndpr_preferred; /* preferred time of the prefix */
+ struct prf_ra ndpr_flags;
+ /* list of routers that advertise the prefix: */
+ LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
+ u_char ndpr_plen;
+ struct ndpr_stateflags {
+ /* if this prefix can be regarded as on-link */
+ u_char onlink : 1;
+ } ndpr_stateflags;
+};
+
+#define ndpr_next ndpr_entry.le_next
+
+#define ndpr_raf ndpr_flags
+#define ndpr_raf_onlink ndpr_flags.onlink
+#define ndpr_raf_auto ndpr_flags.autonomous
+
+#define ndpr_statef_onlink ndpr_stateflags.onlink
+#define ndpr_statef_addmark ndpr_stateflags.addmark
+
+/*
+ * We keep expired prefix for certain amount of time, for validation purposes.
+ * 1800s = MaxRtrAdvInterval
+ */
+#define NDPR_KEEP_EXPIRED (1800 * 2)
+
+/*
+ * Message format for use in obtaining information about prefixes
+ * from inet6 sysctl function
+ */
+struct inet6_ndpr_msghdr {
+ u_short inpm_msglen; /* to skip over non-understood messages */
+ u_char inpm_version; /* future binary compatability */
+ u_char inpm_type; /* message type */
+ struct in6_addr inpm_prefix;
+ u_long prm_vltim;
+ u_long prm_pltime;
+ u_long prm_expire;
+ u_long prm_preferred;
+ struct in6_prflags prm_flags;
+ u_short prm_index; /* index for associated ifp */
+ u_char prm_plen; /* length of prefix in bits */
+};
+
+#define prm_raf_onlink prm_flags.prf_ra.onlink
+#define prm_raf_auto prm_flags.prf_ra.autonomous
+
+#define prm_statef_onlink prm_flags.prf_state.onlink
+
+#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid
+#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd
+
+#define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr))
+#define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr))
+
+struct nd_pfxrouter {
+ LIST_ENTRY(nd_pfxrouter) pfr_entry;
+#define pfr_next pfr_entry.le_next
+ struct nd_defrouter *router;
+};
+
+LIST_HEAD(nd_drhead, nd_defrouter);
+LIST_HEAD(nd_prhead, nd_prefix);
+
+/* nd6.c */
+extern int nd6_prune;
+extern int nd6_delay;
+extern int nd6_umaxtries;
+extern int nd6_mmaxtries;
+extern int nd6_useloopback;
+extern int nd6_proxyall;
+extern struct llinfo_nd6 llinfo_nd6;
+extern struct nd_ifinfo *nd_ifinfo;
+extern struct nd_drhead nd_defrouter;
+extern struct nd_prhead nd_prefix;
+
+union nd_opts {
+ struct nd_opt_hdr *nd_opt_array[9];
+ struct {
+ struct nd_opt_hdr *zero;
+ struct nd_opt_hdr *src_lladdr;
+ struct nd_opt_hdr *tgt_lladdr;
+ struct nd_opt_prefix_info *pi_beg;/* multiple opts, start */
+ struct nd_opt_rd_hdr *rh;
+ struct nd_opt_mtu *mtu;
+ struct nd_opt_hdr *search; /* multiple opts */
+ struct nd_opt_hdr *last; /* multiple opts */
+ int done;
+ struct nd_opt_prefix_info *pi_end;/* multiple opts, end */
+ } nd_opt_each;
+};
+#define nd_opts_src_lladdr nd_opt_each.src_lladdr
+#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
+#define nd_opts_pi nd_opt_each.pi_beg
+#define nd_opts_pi_end nd_opt_each.pi_end
+#define nd_opts_rh nd_opt_each.rh
+#define nd_opts_mtu nd_opt_each.mtu
+#define nd_opts_search nd_opt_each.search
+#define nd_opts_last nd_opt_each.last
+#define nd_opts_done nd_opt_each.done
+
+/* XXX: need nd6_var.h?? */
+/* nd6.c */
+void nd6_init __P((void));
+void nd6_ifattach __P((struct ifnet *));
+int nd6_is_addr_neighbor __P((struct in6_addr *, struct ifnet *));
+void nd6_option_init __P((void *, int, union nd_opts *));
+struct nd_opt_hdr *nd6_option __P((union nd_opts *));
+int nd6_options __P((union nd_opts *));
+struct rtentry *nd6_lookup __P((struct in6_addr *, int, struct ifnet *));
+void nd6_setmtu __P((struct ifnet *));
+void nd6_timer __P((void *));
+void nd6_free __P((struct rtentry *));
+void nd6_nud_hint __P((struct rtentry *, struct in6_addr *));
+int nd6_resolve __P((struct ifnet *, struct rtentry *,
+ struct mbuf *, struct sockaddr *, u_char *));
+#if defined(__bsdi__) && _BSDI_VERSION >= 199802
+void nd6_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *));
+void nd6_p2p_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *));
+#else
+void nd6_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+void nd6_p2p_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+#endif
+int nd6_ioctl __P((u_long, caddr_t, struct ifnet *));
+struct rtentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *,
+ char *, int, int, int));
+/* for test */
+int nd6_output __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *,
+ struct rtentry *));
+int nd6_storelladdr __P((struct ifnet *, struct rtentry *, struct mbuf *,
+ struct sockaddr *, u_char *));
+
+/* nd6_nbr.c */
+void nd6_na_input __P((struct mbuf *, int, int));
+void nd6_na_output __P((struct ifnet *, struct in6_addr *,
+ struct in6_addr *, u_long, int));
+void nd6_ns_input __P((struct mbuf *, int, int));
+void nd6_ns_output __P((struct ifnet *, struct in6_addr *,
+ struct in6_addr *, struct llinfo_nd6 *, int));
+caddr_t nd6_ifptomac __P((struct ifnet *));
+void nd6_dad_start __P((struct ifaddr *, int *));
+void nd6_dad_duplicated __P((struct ifaddr *));
+
+/* nd6_rtr.c */
+void nd6_rs_input __P((struct mbuf *, int, int));
+void nd6_ra_input __P((struct mbuf *, int, int));
+void prelist_del __P((struct nd_prefix *));
+void defrouter_addreq __P((struct nd_defrouter *));
+void defrouter_delreq __P((struct nd_defrouter *, int));
+void defrtrlist_del __P((struct nd_defrouter *));
+void prelist_remove __P((struct nd_prefix *));
+int prelist_update __P((struct nd_prefix *, struct nd_defrouter *,
+ struct mbuf *));
+struct nd_defrouter *defrouter_lookup __P((struct in6_addr *,
+ struct ifnet *));
+int in6_ifdel __P((struct ifnet *, struct in6_addr *));
+int in6_init_prefix_ltimes __P((struct nd_prefix *ndpr));
+void rt6_flush __P((struct in6_addr *, struct ifnet *));
+
+#endif /* _KERNEL */
+
+#endif /* _NETINET6_ND6_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/nd6_protocol.h b/ecos/packages/net/tcpip/current/include/netinet6/nd6_protocol.h
new file mode 100644
index 0000000..be22293
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/nd6_protocol.h
@@ -0,0 +1,129 @@
+//==========================================================================
+//
+// include/netinet6_nd6_protocol.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/*
+%%% portions-copyright-nrl-97
+Portions of this software are Copyright 1997-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_ND6_PROTOCOL_H
+#define _NETINET6_ND6_PROTOCOL_H 1
+
+#include <netinet6/icmpv6.h>
+
+#define ND6_ROUTER_SOLICITATION 133
+#define ND6_ROUTER_ADVERTISEMENT 134
+#define ND6_NEIGHBOR_SOLICITATION 135
+#define ND6_NEIGHBOR_ADVERTISEMENT 136
+#define ND6_REDIRECT 137
+
+enum nd6_option {
+ ND6_OPT_SOURCE_LINKADDR=1,
+ ND6_OPT_TARGET_LINKADDR=2,
+ ND6_OPT_PREFIX_INFORMATION=3,
+ ND6_OPT_REDIRECTED_HEADER=4,
+ ND6_OPT_MTU=5,
+ ND6_OPT_ENDOFLIST=256
+};
+
+struct nd_router_solicit { /* router solicitation */
+ struct icmpv6hdr rsol_hdr;
+};
+
+#define rsol_type rsol_hdr.icmpv6_type
+#define rsol_code rsol_hdr.icmpv6_code
+#define rsol_cksum rsol_hdr.icmpv6_cksum
+#define rsol_reserved rsol_hdr.icmpv6_data32[0]
+
+struct nd_router_advert { /* router advertisement */
+ struct icmpv6hdr radv_hdr;
+ uint32_t radv_reachable; /* reachable time */
+ uint32_t radv_retransmit; /* reachable retransmit time */
+};
+
+#define radv_type radv_hdr.icmpv6_type
+#define radv_code radv_hdr.icmpv6_code
+#define radv_cksum radv_hdr.icmpv6_cksum
+#define radv_maxhoplimit radv_hdr.icmpv6_data8[0]
+#define radv_m_o_res radv_hdr.icmpv6_data8[1]
+#define ND6_RADV_M_BIT 0x80
+#define ND6_RADV_O_BIT 0x40
+#define radv_router_lifetime radv_hdr.icmpv6_data16[1]
+
+struct nd6_nsolicitation { /* neighbor solicitation */
+ struct icmpv6hdr nsol6_hdr;
+ struct in6_addr nsol6_target;
+};
+
+struct nd6_nadvertisement { /* neighbor advertisement */
+ struct icmpv6hdr nadv6_hdr;
+ struct in6_addr nadv6_target;
+};
+
+#define nadv6_flags nadv6_hdr.icmpv6_data32[0]
+#define ND6_NADVERFLAG_ISROUTER 0x80
+#define ND6_NADVERFLAG_SOLICITED 0x40
+#define ND6_NADVERFLAG_OVERRIDE 0x20
+
+struct nd6_redirect { /* redirect */
+ struct icmpv6hdr redirect_hdr;
+ struct in6_addr redirect_target;
+ struct in6_addr redirect_destination;
+};
+
+struct nd6_opt_prefix_info { /* prefix information */
+ uint8_t opt_type;
+ uint8_t opt_length;
+ uint8_t opt_prefix_length;
+ uint8_t opt_l_a_res;
+ uint32_t opt_valid_life;
+ uint32_t opt_preferred_life;
+ uint32_t opt_reserved2;
+ struct in6_addr opt_prefix;
+};
+
+#define ND6_OPT_PI_L_BIT 0x80
+#define ND6_OPT_PI_A_BIT 0x40
+
+struct nd6_opt_mtu { /* MTU option */
+ uint8_t opt_type;
+ uint8_t opt_length;
+ uint16_t opt_reserved;
+ uint32_t opt_mtu;
+};
+
+#endif /* _NETINET6_ND6_PROTOCOL_H */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/osdep.h b/ecos/packages/net/tcpip/current/include/netinet6/osdep.h
new file mode 100644
index 0000000..b61a997
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/osdep.h
@@ -0,0 +1,147 @@
+//==========================================================================
+//
+// include/netinet6_osdep.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: osdep.h,v 1.3 1999/12/10 08:53:18 angelos Exp $ */
+/*
+%%% copyright-nrl-97
+This software is Copyright 1997-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+%%% copyright-cmetz-97
+This software is Copyright 1997-1998 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+*/
+#ifndef _NETINET6_OSDEP_H_
+#define _NETINET6_OSDEP_H_
+
+#define OSDEP_BSD 1
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#ifdef KERNEL
+#ifndef ATSH_ADD
+#include <sys/systm.h>
+#endif /* ATSH_ADD */
+#ifndef MLEN
+#include <sys/mbuf.h>
+#endif /* MLEN */
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#ifndef SB_MAX
+#include <sys/socketvar.h>
+#endif /* SB_MAX */
+#include <sys/proc.h>
+#ifndef RTM_RTTUNIT
+#include <net/route.h>
+#endif /* RTM_RTTUNIT */
+#endif /* KERNEL */
+struct ifnet;
+struct mbuf;
+#include <netinet/in.h>
+struct route6;
+
+#ifdef KERNEL
+/* XXX */
+#define OSDEP_CRITICALDCL int __s;
+#define OSDEP_CRITICALSTART __s = splnet()
+#define OSDEP_CRITICALEND splx(__s)
+#define OSDEP_TIMESECONDS (time.tv_sec)
+#define OSDEP_PROCESS struct proc
+#define OSDEP_PROCESSCURRENT (curproc)
+#define OSDEP_PROCESSPARENT(x) ((x)->p_pptr)
+#define OSDEP_PROCESSPID(x) ((x)->p_pid)
+
+#ifdef SS_PRIV
+#define OSDEP_SOCKETPRIVELEGED(socket) (socket->so_state & SS_PRIV)
+#else /* SS_PRIV */
+/* XXX? */
+#define OSDEP_SOCKETPRIVELEGED(socket) (!curproc || !curproc->p_ucred || !curproc->p_ucred->cr_uid)
+#endif /* SS_PRIV */
+#define OSDEP_PCAST(x) ((unsigned int)(x) & 0xffffffff)
+#define OSDEP_SOCKET struct socket
+#define OSDEP_PACKET struct mbuf
+struct mbuf;
+
+#define OSDEP_REAL_MALLOC(n) malloc((unsigned long)(n), M_TEMP, M_DONTWAIT)
+#define OSDEP_REAL_FREE(p) free((void *)p, M_TEMP)
+#define OSDEP_FAMILY(socket) (socket->so_proto->pr_domain->dom_family)
+#define OSDEP_PSEUDORANDOM (uint32_t)random()
+
+struct ifnet;
+struct mbuf *m_devget(char *, int, int, struct ifnet *, void (*)(const void *, void *, size_t));
+
+static __inline__ int __osdep_datatopacket(void *data, int len, OSDEP_PACKET **packet)
+{
+ if (!(*packet = m_devget(data, len, 0, NULL, NULL)))
+ return -ENOMEM;
+
+ return 0;
+};
+
+#define OSDEP_DATATOPACKET(data, len, packet) __osdep_datatopacket(data, len, packet)
+
+#define OSDEP_ZEROPACKET(packet) m_zero(packet)
+#define OSDEP_FREEPACKET(packet) m_freem(packet)
+
+#define memcpy(dst, src, len) bcopy(src, dst, len)
+#define memmove(dst, src, len) bcopy(src, dst, len)
+#define memset(p, zero, len) bzero(p, len) /* XXX */
+#define memcmp(p1, p2, len) bcmp(p1, p2, len)
+
+#define OSDEP_COPYFROMUSER(dst, src, len) copyin(src, dst, len)
+#define OSDEP_COPYTOUSER(dst, src, len) copyout(src, dst, len)
+
+#endif /* KERNEL */
+#define OSDEP_SALEN 1
+#define OSDEP_ERROR(x) (x)
+
+#define ENETSECURITYPOLICY -ECOMM
+
+#ifdef DEBUG_MALLOC
+#undef OSDEP_MALLOC
+#undef OSDEP_FREE
+#define OSDEP_MALLOC(n) debug_malloc_malloc(n, DEBUG_STATUS)
+#define OSDEP_FREE(p) debug_malloc_free(p)
+#else /* DEBUG_MALLOC */
+#undef OSDEP_MALLOC
+#define OSDEP_MALLOC(n) OSDEP_REAL_MALLOC(n)
+#undef OSDEP_FREE
+#define OSDEP_FREE(p) OSDEP_REAL_FREE(p)
+#endif /* DEBUG_MALLOC */
+
+#endif // _NETINET6_OSDEP_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/pim6.h b/ecos/packages/net/tcpip/current/include/netinet6/pim6.h
new file mode 100644
index 0000000..21e5932
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/pim6.h
@@ -0,0 +1,102 @@
+//==========================================================================
+//
+// include/netinet/pim6.h
+//
+// IPv6 protocol independent multicast
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: pim6.h,v 1.1 1999/12/08 06:50:23 itojun Exp $ */
+
+/*
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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 _NETINET_PIM6_H_
+#define _NETINET_PIM6_H_
+
+/*
+ * Protocol Independent Multicast (PIM) definitions
+ *
+ * Written by Ahmed Helmy, SGI, July 1996
+ *
+ * MULTICAST
+ */
+
+/*
+ * PIM packet header
+ */
+#define PIM_VERSION 2
+struct pim {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
+ u_char pim_type:4, /* the PIM message type, currently they are:
+ * Hello, Register, Register-Stop, Join/Prune,
+ * Bootstrap, Assert, Graft (PIM-DM only),
+ * Graft-Ack (PIM-DM only), C-RP-Adv
+ */
+ pim_ver:4; /* PIM version number; 2 for PIMv2 */
+#else
+ u_char pim_ver:4, /* PIM version */
+ pim_type:4; /* PIM type */
+#endif
+ u_char pim_rsv; /* Reserved */
+ u_short pim_cksum; /* IP style check sum */
+};
+
+#define PIM_MINLEN 8 /* The header min. length is 8 */
+#define PIM6_REG_MINLEN (PIM_MINLEN+40) /* Register message + inner IP6 header */
+
+/*
+ * Message types
+ */
+#define PIM_REGISTER 1 /* PIM Register type is 1 */
+
+/* second bit in reg_head is the null bit */
+#define PIM_NULL_REGISTER 0x40000000
+
+#endif // _NETINET_PIM6_H_
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/pim6_var.h b/ecos/packages/net/tcpip/current/include/netinet6/pim6_var.h
new file mode 100644
index 0000000..fdc705a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/pim6_var.h
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// include/netinet/pim6_var.h
+//
+// IPv6 protocol independent multicast
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/* $OpenBSD: pim6_var.h,v 1.1 1999/12/08 06:50:23 itojun Exp $ */
+
+/*
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+/* KAME Id: pim6_var.h,v 1.2 1999/08/01 15:58:13 itojun Exp */
+
+#ifndef _NETINET6_PIM6_VAR_H_
+#define _NETINET6_PIM6_VAR_H_
+
+/*
+ * Protocol Independent Multicast (PIM),
+ * implementation-specific definitions.
+ *
+ * Written by George Edmond Eddy (Rusty), ISI, February 1998
+ * Modified by Pavlin Ivanov Radoslavov, USC/ISI, May 1998
+ */
+
+struct pim6stat {
+ u_quad_t pim6s_rcv_total; /* total PIM messages received */
+ u_quad_t pim6s_rcv_tooshort; /* received with too few bytes */
+ u_quad_t pim6s_rcv_badsum; /* received with bad checksum */
+ u_quad_t pim6s_rcv_badversion; /* received bad PIM version */
+ u_quad_t pim6s_rcv_registers; /* received registers */
+ u_quad_t pim6s_rcv_badregisters; /* received invalid registers */
+ u_quad_t pim6s_snd_registers; /* sent registers */
+};
+
+#if (defined(KERNEL)) || (defined(_KERNEL))
+extern struct pim6stat pim6stat;
+
+int pim6_input __P((struct mbuf **, int*, int));
+#endif /* KERNEL */
+
+/*
+ * Names for PIM sysctl objects
+ */
+#define PIMCTL_STATS 1 /* statistics (read-only) */
+#define PIMCTL_MAXID 2
+
+#define PIMCTL_NAMES { \
+ { 0, 0 }, \
+ { 0, 0 }, \
+}
+
+#endif /* _NETINET6_PIM6_VAR_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/netinet6/tcpipv6.h b/ecos/packages/net/tcpip/current/include/netinet6/tcpipv6.h
new file mode 100644
index 0000000..4446032
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/netinet6/tcpipv6.h
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// include/netinet6_tcpipv6.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcpipv6.h,v 1.4 1999/12/10 08:53:18 angelos Exp $ */
+
+/*
+%%% copyright-nrl-95
+This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
+Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
+rights under this copyright have been assigned to the US Naval Research
+Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
+1.1 (January 17, 1995) applies to this software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+
+*/
+
+#ifndef _NETINET6_TCPIPV6_H
+#define _NETINET6_TCPIPV6_H 1
+
+#include <netinet6/ip6.h>
+#include <netinet/tcp.h>
+
+struct tcpipv6hdr {
+ struct ip6_hdr ti6_i;
+ struct tcphdr ti6_t;
+};
+
+#define ti6_src ti6_i.ipv6_src
+#define ti6_dst ti6_i.ipv6_dst
+#define ti6_sport ti6_t.th_sport
+#define ti6_dport ti6_t.th_dport
+#define ti6_seq ti6_t.th_seq
+#define ti6_ack ti6_t.th_ack
+#define ti6_x2 ti6_t.th_x2
+#define ti6_off ti6_t.th_off
+#define ti6_flags ti6_t.th_flags
+#define ti6_win ti6_t.th_win
+#define ti6_sum ti6_t.th_sum
+#define ti6_urp ti6_t.th_urp
+
+#endif /* _NETINET6_TCPIPV6_H */
diff --git a/ecos/packages/net/tcpip/current/include/sys/bsdselect.h b/ecos/packages/net/tcpip/current/include/sys/bsdselect.h
new file mode 100644
index 0000000..127f07c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/bsdselect.h
@@ -0,0 +1,55 @@
+//==========================================================================
+//
+// include/sys/select.h
+//
+// Support for 'select()' system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _SYS_SELECT_H_
+#define _SYS_SELECT_H_
+
+#include <pkgconf/system.h>
+
+#ifdef CYGPKG_IO_FILEIO
+
+#include <cyg/io/file.h>
+
+void selwakeup __P((struct selinfo *));
+
+#else
+
+/*
+ * Used to maintain information about processes that wish to be
+ * notified when I/O becomes possible.
+ */
+struct selinfo {
+ void *unused;
+};
+
+void selrecord __P((void *selector, struct selinfo *));
+void selwakeup __P((struct selinfo *));
+
+#endif
+
+#endif /* !_SYS_SELECT_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/bsdtypes.h b/ecos/packages/net/tcpip/current/include/sys/bsdtypes.h
new file mode 100644
index 0000000..2a5d597
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/bsdtypes.h
@@ -0,0 +1,194 @@
+//==========================================================================
+//
+// include/sys/types.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: types.h,v 1.15 1999/02/15 18:53:57 millert Exp $ */
+/* $NetBSD: types.h,v 1.29 1996/11/15 22:48:25 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)types.h 8.4 (Berkeley) 1/21/94
+ */
+
+#ifndef _SYS_TYPES_H_
+#define _SYS_TYPES_H_
+
+/* Machine type dependent parameters. */
+#include <machine/types.h>
+
+#include <machine/ansi.h>
+#include <machine/endian.h>
+
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+typedef unsigned char unchar; /* Sys V compatibility */
+typedef unsigned short ushort; /* Sys V compatibility */
+typedef unsigned int uint; /* Sys V compatibility */
+typedef unsigned long ulong; /* Sys V compatibility */
+#endif
+
+typedef u_int64_t u_quad_t; /* quads */
+typedef int64_t quad_t;
+typedef quad_t * qaddr_t;
+
+typedef char * caddr_t; /* core address */
+typedef int32_t daddr_t; /* disk address */
+typedef u_int32_t fixpt_t; /* fixed point number */
+typedef long key_t; /* IPC key (for Sys V IPC) */
+typedef quad_t rlim_t; /* resource limit */
+typedef int32_t segsz_t; /* segment size */
+typedef int32_t swblk_t; /* swap offset */
+typedef u_int32_t useconds_t; /* microseconds */
+typedef int32_t suseconds_t; /* microseconds (signed) */
+
+/*
+ * XPG4.2 states that inclusion of <netinet/in.h> must pull these
+ * in and that inclusion of <sys/socket.h> must pull in sa_family_t.
+ * We put there here because there are other headers that require
+ * these types and <sys/socket.h> and <netinet/in.h> will indirectly
+ * include <sys/types.h>. Thus we are compliant without too many hoops.
+ */
+typedef u_int32_t in_addr_t; /* base type for internet address */
+typedef u_int16_t in_port_t; /* IP port type */
+typedef u_int8_t sa_family_t; /* sockaddr address family type */
+typedef u_int32_t socklen_t; /* length type for network syscalls */
+
+/*
+ * These belong in unistd.h, but are placed here too to ensure that
+ * long arguments will be promoted to off_t if the program fails to
+ * include that header or explicitly cast them to off_t.
+ */
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+#ifndef _KERNEL
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+off_t lseek __P((int, off_t, int));
+int ftruncate __P((int, off_t));
+int truncate __P((const char *, off_t));
+__END_DECLS
+#endif /* !_KERNEL */
+#endif /* !defined(_POSIX_SOURCE) ... */
+
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+/* Major, minor numbers, dev_t's. */
+#define major(x) ((int32_t)(((u_int32_t)(x) >> 8) & 0xff))
+#define minor(x) ((int32_t)((x) & 0xff))
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
+#endif
+
+#if 0 //def _BSD_CLOCK_T_
+typedef _BSD_CLOCK_T_ clock_t;
+#undef _BSD_CLOCK_T_
+#endif
+
+#ifndef __ECOS
+#if 0 //def _BSD_SIZE_T_
+typedef _BSD_SIZE_T_ size_t;
+#undef _BSD_SIZE_T_
+#endif
+#endif
+
+#if 0 //def _BSD_SSIZE_T_
+typedef _BSD_SSIZE_T_ ssize_t;
+#undef _BSD_SSIZE_T_
+#endif
+
+#if 0 //def _BSD_TIME_T_
+typedef _BSD_TIME_T_ time_t;
+#undef _BSD_TIME_T_
+#endif
+
+#if 0 //def _BSD_CLOCKID_T_
+typedef _BSD_CLOCKID_T_ clockid_t;
+#undef _BSD_CLOCKID_T_
+#endif
+
+#if 0 //def _BSD_TIMER_T_
+typedef _BSD_TIMER_T_ timer_t;
+#undef _BSD_TIMER_T_
+#endif
+
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+
+#if defined(__STDC__) && defined(_KERNEL)
+/*
+ * Forward structure declarations for function prototypes. We include the
+ * common structures that cross subsystem boundaries here; others are mostly
+ * used in the same place that the structure is defined.
+ */
+struct proc;
+struct pgrp;
+struct ucred;
+struct rusage;
+struct file;
+struct buf;
+struct tty;
+struct uio;
+#endif
+
+#endif /* !defined(_POSIX_SOURCE) ... */
+#endif /* !_SYS_TYPES_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/cdefs.h b/ecos/packages/net/tcpip/current/include/sys/cdefs.h
new file mode 100644
index 0000000..c26bb31
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/cdefs.h
@@ -0,0 +1,170 @@
+//==========================================================================
+//
+// include/sys/cdefs.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: cdefs.h,v 1.5 1996/09/27 17:34:44 maja Exp $ */
+/* $NetBSD: cdefs.h,v 1.16 1996/04/03 20:46:39 christos Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)cdefs.h 8.7 (Berkeley) 1/21/94
+ */
+
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+
+/*
+ * Gratuitous NetBSD gcc extensions we can do without.
+ */
+
+#ifdef __KPRINTF_ATTRIBUTE__
+#undef __KPRINTF_ATTRIBUTE__
+#endif
+
+#include <machine/cdefs.h>
+
+#if defined(__cplusplus)
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS };
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments. __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define __P(protos) protos /* full-blown ANSI C */
+#define __CONCAT(x,y) x ## y
+#define __STRING(x) #x
+
+#define __const const /* define reserved names to standard */
+#define __signed signed
+#define __volatile volatile
+#if defined(__cplusplus)
+#define __inline inline /* convert to C++ keyword */
+#else
+#if !defined(__GNUC__) && !defined(lint)
+#define __inline /* delete GCC keyword */
+#endif /* !__GNUC__ && !lint */
+#endif /* !__cplusplus */
+
+#else /* !(__STDC__ || __cplusplus) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+
+#if !defined(__GNUC__) && !defined(lint)
+#define __const /* delete pseudo-ANSI C keywords */
+#define __inline
+#define __signed
+#define __volatile
+#endif /* !__GNUC__ && !lint */
+
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * Programs using the ANSI C keywords const, inline etc. as normal
+ * identifiers should define -DNO_ANSI_KEYWORDS.
+ */
+#ifndef NO_ANSI_KEYWORDS
+#define const __const /* convert ANSI C keywords */
+#define inline __inline
+#define signed __signed
+#define volatile __volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif /* !(__STDC__ || __cplusplus) */
+
+/*
+ * GCC1 and some versions of GCC2 declare dead (non-returning) and
+ * pure (no side effects) functions using "volatile" and "const";
+ * unfortunately, these then cause warnings under "-ansi -pedantic".
+ * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
+ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+ * in the distribution version of 2.5.5).
+ */
+#if !defined(__GNUC__) || __GNUC__ < 2 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define __dead __volatile
+#define __pure __const
+#endif
+#endif
+
+#ifdef __KPRINTF_ATTRIBUTE__
+#define __kprintf_attribute__(a) __attribute__(a)
+#else
+#define __kprintf_attribute__(a)
+#endif
+
+/* Delete pseudo-keywords wherever they are not available or needed. */
+#ifndef __dead
+#define __dead
+#define __pure
+#endif
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/domain.h b/ecos/packages/net/tcpip/current/include/sys/domain.h
new file mode 100644
index 0000000..e4062a4
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/domain.h
@@ -0,0 +1,102 @@
+//==========================================================================
+//
+// include/sys/domain.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: domain.h,v 1.2 1996/03/03 12:11:38 niklas Exp $ */
+/* $NetBSD: domain.h,v 1.10 1996/02/09 18:25:07 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)domain.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _SYS_DOMAIN_H_
+#define _SYS_DOMAIN_H_
+
+/*
+ * Structure per communications domain.
+ */
+
+/*
+ * Forward structure declarations for function prototypes [sic].
+ */
+struct mbuf;
+
+struct domain {
+ int dom_family; /* AF_xxx */
+ char *dom_name;
+ void (*dom_init) /* initialize domain data structures */
+ __P((void));
+ int (*dom_externalize) /* externalize access rights */
+ __P((struct mbuf *));
+ void (*dom_dispose) /* dispose of internalized rights */
+ __P((struct mbuf *));
+ struct protosw *dom_protosw, *dom_protoswNPROTOSW;
+ struct domain *dom_next;
+ int (*dom_rtattach) /* initialize routing table */
+ __P((void **, int));
+ int dom_rtoffset; /* an arg to rtattach, in bits */
+ int dom_maxrtkey; /* for routing layer */
+};
+
+#ifdef _KERNEL
+struct domain *domains;
+void domaininit __P((void));
+#endif
+
+#endif // _SYS_DOMAIN_H_
diff --git a/ecos/packages/net/tcpip/current/include/sys/endian.h b/ecos/packages/net/tcpip/current/include/sys/endian.h
new file mode 100644
index 0000000..f11fd32
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/endian.h
@@ -0,0 +1,222 @@
+//==========================================================================
+//
+// include/sys/endian.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: endian.h,v 1.4 1999/07/21 05:58:25 csapuntz Exp $ */
+
+/*-
+ * Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Niklas Hallqvist.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * Generic definitions for little- and big-endian systems. Other endianesses
+ * has to be dealt with in the specific machine/endian.h file for that port.
+ *
+ * This file is meant to be included from a little- or big-endian port's
+ * machine/endian.h after setting BYTE_ORDER to either 1234 for little endian
+ * or 4321 for big..
+ */
+
+#ifndef _SYS_ENDIAN_H_
+#define _SYS_ENDIAN_H_
+
+#ifndef _POSIX_SOURCE
+
+#include <sys/cdefs.h>
+
+#define LITTLE_ENDIAN 1234
+
+
+#define BIG_ENDIAN 4321
+#define PDP_ENDIAN 3412
+
+#ifdef __GNUC__
+
+#define __swap16gen(x) ({ \
+ u_int16_t __swap16gen_x = (x); \
+ \
+ (u_int16_t)((__swap16gen_x & 0xff) << 8 | \
+ (__swap16gen_x & 0xff00) >> 8); \
+})
+
+#define __swap32gen(x) ({ \
+ u_int32_t __swap32gen_x = (x); \
+ \
+ (u_int32_t)((__swap32gen_x & 0xff) << 24 | \
+ (__swap32gen_x & 0xff00) << 8 | \
+ (__swap32gen_x & 0xff0000) >> 8 | \
+ (__swap32gen_x & 0xff000000) >> 24); \
+})
+
+#else /* __GNUC__ */
+
+/* Note that these macros evaluate their arguments several times. */
+#define __swap16gen(x) \
+ (u_int16_t)(((u_int16_t)(x) & 0xff) << 8 | ((u_int16_t)(x) & 0xff00) >> 8)
+
+#define __swap32gen(x) \
+ (u_int32_t)(((u_int32_t)(x) & 0xff) << 24 | \
+ ((u_int32_t)(x) & 0xff00) << 8 | ((u_int32_t)(x) & 0xff0000) >> 8 | \
+ ((u_int32_t)(x) & 0xff000000) >> 24)
+
+#endif /* __GNUC__ */
+
+/*
+ * Define MD_SWAP if you provide swap{16,32}md functions/macros that are
+ * optimized for your architecture, These will be used for swap{16,32}
+ * unless the argument is a constant and we are using GCC, where we can
+ * take advantage of the CSE phase much better by using the generic version.
+ */
+#ifdef MD_SWAP
+#if __GNUC__
+
+#define swap16(x) ({ \
+ u_int16_t __swap16_x = (x); \
+ \
+ __builtin_constant_p(x) ? __swap16gen(__swap16_x) : \
+ __swap16md(__swap16_x); \
+})
+
+#define swap32(x) ({ \
+ u_int32_t __swap32_x = (x); \
+ \
+ __builtin_constant_p(x) ? __swap32gen(__swap32_x) : \
+ __swap32md(__swap32_x); \
+})
+
+#endif /* __GNUC__ */
+
+#else /* MD_SWAP */
+#define swap16 __swap16gen
+#define swap32 __swap32gen
+#endif /* MD_SWAP */
+
+#define swap16_multi(v, n) do { \
+ size_t __swap16_multi_n = (n); \
+ u_int16_t *__swap16_multi_v = (v); \
+ \
+ while (__swap16_multi_n) { \
+ *__swap16_multi_v = swap16(*__swap16_multi_v); \
+ __swap16_multi_v++; \
+ __swap16_multi_n--; \
+ } \
+} while (0)
+
+__BEGIN_DECLS
+u_int32_t htobe32 __P((u_int32_t));
+u_int16_t htobe16 __P((u_int16_t));
+u_int32_t betoh32 __P((u_int32_t));
+u_int16_t betoh16 __P((u_int16_t));
+
+u_int32_t htole32 __P((u_int32_t));
+u_int16_t htole16 __P((u_int16_t));
+u_int32_t letoh32 __P((u_int32_t));
+u_int16_t letoh16 __P((u_int16_t));
+__END_DECLS
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+/* Can be overridden by machine/endian.h before inclusion of this file. */
+#ifndef _QUAD_HIGHWORD
+#define _QUAD_HIGHWORD 1
+#endif
+#ifndef _QUAD_LOWWORD
+#define _QUAD_LOWWORD 0
+#endif
+
+#define htobe16 swap16
+#define htobe32 swap32
+#define betoh16 swap16
+#define betoh32 swap32
+
+#define htole16(x) (x)
+#define htole32(x) (x)
+#define letoh16(x) (x)
+#define letoh32(x) (x)
+
+#endif /* BYTE_ORDER */
+
+#if BYTE_ORDER == BIG_ENDIAN
+
+/* Can be overridden by machine/endian.h before inclusion of this file. */
+#ifndef _QUAD_HIGHWORD
+#define _QUAD_HIGHWORD 0
+#endif
+#ifndef _QUAD_LOWWORD
+#define _QUAD_LOWWORD 1
+#endif
+
+#define htole16 swap16
+#define htole32 swap32
+#define letoh16 swap16
+#define letoh32 swap32
+
+#define htobe16(x) (x)
+#define htobe32(x) (x)
+#define betoh16(x) (x)
+#define betoh32(x) (x)
+
+#endif /* BYTE_ORDER */
+
+#define htons htobe16
+#define htonl htobe32
+#define ntohs betoh16
+#define ntohl betoh32
+
+#define NTOHL(x) (x) = ntohl((u_int32_t)(x))
+#define NTOHS(x) (x) = ntohs((u_int16_t)(x))
+#define HTONL(x) (x) = htonl((u_int32_t)(x))
+#define HTONS(x) (x) = htons((u_int16_t)(x))
+
+#endif /* _POSIX_SOURCE */
+#endif /* _SYS_ENDIAN_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/errno.h b/ecos/packages/net/tcpip/current/include/sys/errno.h
new file mode 100644
index 0000000..3c15f86
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/errno.h
@@ -0,0 +1,30 @@
+//==========================================================================
+//
+// include/sys/errno.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Just another name for the standard file
+#include <errno.h>
diff --git a/ecos/packages/net/tcpip/current/include/sys/ioccom.h b/ecos/packages/net/tcpip/current/include/sys/ioccom.h
new file mode 100644
index 0000000..76f8eb6
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/ioccom.h
@@ -0,0 +1,103 @@
+//==========================================================================
+//
+// include/sys/ioccom.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ioccom.h,v 1.2 1996/03/03 12:11:49 niklas Exp $ */
+/* $NetBSD: ioccom.h,v 1.4 1994/10/30 21:49:56 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ioccom.h 8.2 (Berkeley) 3/28/94
+ */
+
+#ifndef _SYS_IOCCOM_H_
+#define _SYS_IOCCOM_H_
+
+/*
+ * Ioctl's have the command encoded in the lower word, and the size of
+ * any in or out parameters in the upper word. The high 3 bits of the
+ * upper word are used to encode the in/out status of the parameter.
+ */
+#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
+#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
+#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
+#define IOCGROUP(x) (((x) >> 8) & 0xff)
+
+#ifndef __ECOS
+#define IOCPARM_MAX NBPG /* max size of ioctl args, mult. of NBPG */
+#endif
+ /* no parameters */
+#define IOC_VOID (unsigned long)0x20000000
+ /* copy parameters out */
+#define IOC_OUT (unsigned long)0x40000000
+ /* copy parameters in */
+#define IOC_IN (unsigned long)0x80000000
+ /* copy paramters in and out */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+ /* mask for IN/OUT/VOID */
+#define IOC_DIRMASK (unsigned long)0xe0000000
+
+#define _IOC(inout,group,num,len) \
+ (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
+#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
+#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
+#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
+/* this should be _IORW, but stdio got there first */
+#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
+
+#endif /* !_SYS_IOCCOM_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/ioctl.h b/ecos/packages/net/tcpip/current/include/sys/ioctl.h
new file mode 100644
index 0000000..15ee2f8
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/ioctl.h
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// include/sys/ioctl.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ioctl.h,v 1.3 1996/03/03 12:11:50 niklas Exp $ */
+/* $NetBSD: ioctl.h,v 1.20 1996/01/30 18:21:47 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ioctl.h 8.6 (Berkeley) 3/28/94
+ */
+
+#ifndef _SYS_IOCTL_H_
+#define _SYS_IOCTL_H_
+
+#ifndef __ECOS
+#include <sys/ttycom.h>
+
+/*
+ * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ
+ * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented
+ * nonwithstanding).
+ */
+struct ttysize {
+ unsigned short ts_lines;
+ unsigned short ts_cols;
+ unsigned short ts_xxx;
+ unsigned short ts_yyy;
+};
+#define TIOCGSIZE TIOCGWINSZ
+#define TIOCSSIZE TIOCSWINSZ
+#endif
+
+#include <sys/ioccom.h>
+
+#ifndef __ECOS
+#include <sys/dkio.h>
+#include <sys/filio.h>
+#endif
+#include <sys/sockio.h>
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int ioctl __P((int, unsigned long, ...));
+__END_DECLS
+#endif /* !_KERNEL */
+#endif /* !_SYS_IOCTL_H_ */
+
+/*
+ * Keep outside _SYS_IOCTL_H_
+ * Compatability with old terminal driver
+ *
+ * Source level -> #define USE_OLD_TTY
+ * Kernel level -> options COMPAT_43 or COMPAT_SUNOS or ...
+ */
+#if defined(USE_OLD_TTY) || defined(COMPAT_43) || defined(COMPAT_SUNOS) || \
+ defined(COMPAT_SVR4) || defined(COMPAT_FREEBSD)
+#include <sys/ioctl_compat.h>
+#endif
diff --git a/ecos/packages/net/tcpip/current/include/sys/kernel.h b/ecos/packages/net/tcpip/current/include/sys/kernel.h
new file mode 100644
index 0000000..ef28665
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/kernel.h
@@ -0,0 +1,101 @@
+//==========================================================================
+//
+// include/sys/kernel.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: kernel.h,v 1.5 1996/08/11 20:39:07 niklas Exp $ */
+/* $NetBSD: kernel.h,v 1.11 1995/03/03 01:24:16 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)kernel.h 8.3 (Berkeley) 1/21/94
+ */
+
+/* Global variables for the kernel. */
+
+/* 1.1 */
+extern long hostid;
+extern char hostname[MAXHOSTNAMELEN];
+extern int hostnamelen;
+extern char domainname[MAXHOSTNAMELEN];
+extern int domainnamelen;
+
+/* 1.2 */
+extern volatile struct timeval mono_time;
+extern struct timeval boottime;
+extern struct timeval runtime;
+extern volatile struct timeval ktime;
+#define time ktime
+extern struct timezone tz; /* XXX */
+
+extern int tick; /* usec per tick (1000000 / hz) */
+extern int tickfix; /* periodic tick adj. tick not integral */
+extern int tickfixinterval; /* interval at which to apply adjustment */
+extern int tickadj; /* "standard" clock skew, us./tick */
+extern int hz; /* system clock's frequency */
+extern int stathz; /* statistics clock's frequency */
+extern int profhz; /* profiling clock's frequency */
+extern int lbolt; /* once a second sleep address */
+extern int tickdelta;
+extern long timedelta;
+
+
diff --git a/ecos/packages/net/tcpip/current/include/sys/malloc.h b/ecos/packages/net/tcpip/current/include/sys/malloc.h
new file mode 100644
index 0000000..98054bd
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/malloc.h
@@ -0,0 +1,469 @@
+//==========================================================================
+//
+// include/sys/malloc.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: malloc.h,v 1.27 1999/12/08 06:50:24 itojun Exp $ */
+/* $NetBSD: malloc.h,v 1.39 1998/07/12 19:52:01 augustss Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)malloc.h 8.5 (Berkeley) 5/3/95
+ */
+
+#ifndef _SYS_MALLOC_H_
+#define _SYS_MALLOC_H_
+
+/*
+ * flags to malloc
+ */
+#define M_WAITOK 0x0000
+#define M_NOWAIT 0x0001
+
+/*
+ * Types of memory to be allocated
+ */
+#define M_FREE 0 /* should be on free list */
+#define M_MBUF 1 /* mbuf */
+#define M_DEVBUF 2 /* device driver memory */
+#define M_SOCKET 3 /* socket structure */
+#define M_PCB 4 /* protocol control block */
+#define M_RTABLE 5 /* routing tables */
+#define M_HTABLE 6 /* IMP host tables */
+#define M_FTABLE 7 /* fragment reassembly header */
+#define M_ZOMBIE 8 /* zombie proc status */
+#define M_IFADDR 9 /* interface address */
+#define M_SOOPTS 10 /* socket options */
+#define M_SONAME 11 /* socket name */
+#define M_NAMEI 12 /* namei path name buffer */
+#define M_GPROF 13 /* kernel profiling buffer */
+#define M_IOCTLOPS 14 /* ioctl data buffer */
+#define M_MAPMEM 15 /* mapped memory descriptors */
+#define M_CRED 16 /* credentials */
+#define M_PGRP 17 /* process group header */
+#define M_SESSION 18 /* session header */
+#define M_IOV 19 /* large iov's */
+#define M_MOUNT 20 /* vfs mount struct */
+#define M_FHANDLE 21 /* network file handle */
+#define M_NFSREQ 22 /* NFS request header */
+#define M_NFSMNT 23 /* NFS mount structure */
+#define M_NFSNODE 24 /* NFS vnode private part */
+#define M_VNODE 25 /* Dynamically allocated vnodes */
+#define M_CACHE 26 /* Dynamically allocated cache entries */
+#define M_DQUOT 27 /* UFS quota entries */
+#define M_UFSMNT 28 /* UFS mount structure */
+#define M_SHM 29 /* SVID compatible shared memory segments */
+#define M_VMMAP 30 /* VM map structures */
+#define M_VMMAPENT 31 /* VM map entry structures */
+#define M_VMOBJ 32 /* VM object structure */
+#define M_VMOBJHASH 33 /* VM object hash structure */
+#define M_VMPMAP 34 /* VM pmap */
+#define M_VMPVENT 35 /* VM phys-virt mapping entry */
+#define M_VMPAGER 36 /* XXX: VM pager struct */
+#define M_VMPGDATA 37 /* XXX: VM pager private data */
+#define M_FILE 38 /* Open file structure */
+#define M_FILEDESC 39 /* Open file descriptor table */
+#define M_LOCKF 40 /* Byte-range locking structures */
+#define M_PROC 41 /* Proc structures */
+#define M_SUBPROC 42 /* Proc sub-structures */
+#define M_SEGMENT 43 /* Segment for LFS */
+#define M_LFSNODE 44 /* LFS vnode private part */
+#define M_FFSNODE 45 /* FFS vnode private part */
+#define M_MFSNODE 46 /* MFS vnode private part */
+#define M_NQLEASE 47 /* Nqnfs lease */
+#define M_NQMHOST 48 /* Nqnfs host address table */
+#define M_NETADDR 49 /* Export host address structure */
+#define M_NFSSVC 50 /* Nfs server structure */
+#define M_NFSUID 51 /* Nfs uid mapping structure */
+#define M_NFSD 52 /* Nfs server daemon structure */
+#define M_IPMOPTS 53 /* internet multicast options */
+#define M_IPMADDR 54 /* internet multicast address */
+#define M_IFMADDR 55 /* link-level multicast address */
+#define M_MRTABLE 56 /* multicast routing tables */
+#define M_ISOFSMNT 57 /* ISOFS mount structure */
+#define M_ISOFSNODE 58 /* ISOFS vnode private part */
+#define M_MSDOSFSMNT 59 /* MSDOS FS mount structure */
+#define M_MSDOSFSFAT 60 /* MSDOS FS fat table */
+#define M_MSDOSFSNODE 61 /* MSDOS FS vnode private part */
+#define M_TTYS 62 /* allocated tty structures */
+#define M_EXEC 63 /* argument lists & other mem used by exec */
+#define M_MISCFSMNT 64 /* miscfs mount structures */
+#define M_MISCFSNODE 65 /* miscfs vnode private part */
+#define M_ADOSFSMNT 66 /* adosfs mount structures */
+#define M_ADOSFSNODE 67 /* adosfs vnode private part */
+#define M_ANODE 68 /* adosfs anode structures and tables. */
+#define M_IPQ 69 /* IP packet queue entry */
+#define M_AFS 70 /* Andrew File System */
+#define M_ADOSFSBITMAP 71 /* adosfs bitmap */
+#define M_EXT2FSNODE 72 /* EXT2FS vnode private part */
+#define M_PFIL 73 /* packer filter */
+#define M_PFKEY 74 /* pfkey data */
+#define M_TDB 75 /* Transforms database */
+#define M_XDATA 76 /* IPsec data */
+#define M_VFS 77 /* VFS file systems */
+
+#define M_PAGEDEP 78 /* File page dependencies */
+#define M_INODEDEP 79 /* Inode dependencies */
+#define M_NEWBLK 80 /* New block allocation */
+#define M_BMSAFEMAP 81 /* Block or frag allocated from cyl group map */
+#define M_ALLOCDIRECT 82 /* Block or frag dependency for an inode */
+#define M_INDIRDEP 83 /* Indirect block dependencies */
+#define M_ALLOCINDIR 84 /* Block dependency for an indirect block */
+#define M_FREEFRAG 85 /* Previously used frag for an inode */
+#define M_FREEBLKS 86 /* Blocks freed from an inode */
+#define M_FREEFILE 87 /* Inode deallocated */
+#define M_DIRADD 88 /* New directory entry */
+#define M_MKDIR 89 /* New directory */
+#define M_DIRREM 90 /* Directory entry deleted */
+#define M_VMPBUCKET 91 /* VM page buckets */
+#define M_VMSWAP 92 /* VM swap structures */
+
+#define M_DISCQ 93 /* IPv6 discq */
+#define M_FRAGQ 94 /* IPv6 fragq */
+#define M_SECA 95 /* Sec Assoc */
+#if 0 /* NRL IPv6 */
+#define M_I6IFP 96 /* IPv6 if info */
+#endif
+
+#define M_RAIDFRAME 97 /* Raidframe data */
+
+#define M_UVMAMAP 98 /* UVM amap and realted */
+#define M_UVMAOBJ 99 /* UVM aobj and realted */
+#define M_POOL 100 /* Pool memory */
+
+#define M_USB 101 /* USB general */
+#define M_USBDEV 102 /* USB device driver */
+#define M_USBHC 103 /* USB host controller */
+
+
+/* KAME IPv6 */
+#define M_IP6OPT 123 /* IPv6 options */
+#define M_IP6NDP 124 /* IPv6 Neighbour Discovery */
+#define M_IP6RR 125 /* IPv6 Router Renumbering Prefix */
+#define M_RR_ADDR 126 /* IPv6 Router Renumbering Ifid */
+
+#define M_PIPE 104 /* Pipe structures */
+
+#define M_MEMDESC 105 /* Memory range */
+
+#define M_TEMP 127 /* misc temporary data buffers */
+#define M_LAST 128 /* Must be last type + 1 */
+
+
+#define INITKMEMNAMES { \
+ "free", /* 0 M_FREE */ \
+ "mbuf", /* 1 M_MBUF */ \
+ "devbuf", /* 2 M_DEVBUF */ \
+ "socket", /* 3 M_SOCKET */ \
+ "pcb", /* 4 M_PCB */ \
+ "routetbl", /* 5 M_RTABLE */ \
+ "hosttbl", /* 6 M_HTABLE */ \
+ "fragtbl", /* 7 M_FTABLE */ \
+ "zombie", /* 8 M_ZOMBIE */ \
+ "ifaddr", /* 9 M_IFADDR */ \
+ "soopts", /* 10 M_SOOPTS */ \
+ "soname", /* 11 M_SONAME */ \
+ "namei", /* 12 M_NAMEI */ \
+ "gprof", /* 13 M_GPROF */ \
+ "ioctlops", /* 14 M_IOCTLOPS */ \
+ "mapmem", /* 15 M_MAPMEM */ \
+ "cred", /* 16 M_CRED */ \
+ "pgrp", /* 17 M_PGRP */ \
+ "session", /* 18 M_SESSION */ \
+ "iov", /* 19 M_IOV */ \
+ "mount", /* 20 M_MOUNT */ \
+ "fhandle", /* 21 M_FHANDLE */ \
+ "NFS req", /* 22 M_NFSREQ */ \
+ "NFS mount", /* 23 M_NFSMNT */ \
+ "NFS node", /* 24 M_NFSNODE */ \
+ "vnodes", /* 25 M_VNODE */ \
+ "namecache", /* 26 M_CACHE */ \
+ "UFS quota", /* 27 M_DQUOT */ \
+ "UFS mount", /* 28 M_UFSMNT */ \
+ "shm", /* 29 M_SHM */ \
+ "VM map", /* 30 M_VMMAP */ \
+ "VM mapent", /* 31 M_VMMAPENT */ \
+ "VM object", /* 32 M_VMOBJ */ \
+ "VM objhash", /* 33 M_VMOBJHASH */ \
+ "VM pmap", /* 34 M_VMPMAP */ \
+ "VM pvmap", /* 35 M_VMPVENT */ \
+ "VM pager", /* 36 M_VMPAGER */ \
+ "VM pgdata", /* 37 M_VMPGDATA */ \
+ "file", /* 38 M_FILE */ \
+ "file desc", /* 39 M_FILEDESC */ \
+ "lockf", /* 40 M_LOCKF */ \
+ "proc", /* 41 M_PROC */ \
+ "subproc", /* 42 M_SUBPROC */ \
+ "LFS segment", /* 43 M_SEGMENT */ \
+ "LFS node", /* 44 M_LFSNODE */ \
+ "FFS node", /* 45 M_FFSNODE */ \
+ "MFS node", /* 46 M_MFSNODE */ \
+ "NQNFS Lease", /* 47 M_NQLEASE */ \
+ "NQNFS Host", /* 48 M_NQMHOST */ \
+ "Export Host", /* 49 M_NETADDR */ \
+ "NFS srvsock", /* 50 M_NFSSVC */ \
+ "NFS uid", /* 51 M_NFSUID */ \
+ "NFS daemon", /* 52 M_NFSD */ \
+ "ip_moptions", /* 53 M_IPMOPTS */ \
+ "in_multi", /* 54 M_IPMADDR */ \
+ "ether_multi", /* 55 M_IFMADDR */ \
+ "mrt", /* 56 M_MRTABLE */ \
+ "ISOFS mount", /* 57 M_ISOFSMNT */ \
+ "ISOFS node", /* 58 M_ISOFSNODE */ \
+ "MSDOSFS mount", /* 59 M_MSDOSFSMNT */ \
+ "MSDOSFS fat", /* 60 M_MSDOSFSFAT */ \
+ "MSDOSFS node", /* 61 M_MSDOSFSNODE */ \
+ "ttys", /* 62 M_TTYS */ \
+ "exec", /* 63 M_EXEC */ \
+ "miscfs mount", /* 64 M_MISCFSMNT */ \
+ "miscfs node", /* 65 M_MISCFSNODE */ \
+ "adosfs mount", /* 66 M_ADOSFSMNT */ \
+ "adosfs node", /* 67 M_ADOSFSNODE */ \
+ "adosfs anode", /* 68 M_ANODE */ \
+ "IP queue ent", /* 69 M_IPQ */ \
+ "afs", /* 70 M_AFS */ \
+ "adosfs bitmap", /* 71 M_ADOSFSBITMAP */ \
+ "EXT2FS node", /* 72 M_EXT2FSNODE */ \
+ "pfil", /* 73 M_PFIL */ \
+ "pfkey data", /* 74 M_PFKEY */ \
+ "tdb", /* 75 M_TDB */ \
+ "xform_data", /* 76 M_XDATA */ \
+ "vfs", /* 77 M_VFS */ \
+ "pagedep", /* 78 M_PAGEDEP */ \
+ "inodedep", /* 79 M_INODEDEP */ \
+ "newblk", /* 80 M_NEWBLK */ \
+ "bmsafemap", /* 81 M_BMSAFEMAP */ \
+ "allocdirect", /* 82 M_ALLOCDIRECT */ \
+ "indirdep", /* 83 M_INDIRDEP */ \
+ "allocindir", /* 84 M_ALLOCINDIR */ \
+ "freefrag", /* 85 M_FREEFRAG */ \
+ "freeblks", /* 86 M_FREEBLKS */ \
+ "freefile", /* 87 M_FREEFILE */ \
+ "diradd", /* 88 M_DIRADD */ \
+ "mkdir", /* 89 M_MKDIR */ \
+ "dirrem", /* 90 M_DIRREM */ \
+ "VM page bucket", /* 91 M_VMPBUCKET */ \
+ "VM swap", /* 92 M_VMSWAP */ \
+ "IPv6 discq", /* 93 M_DISCQ */ \
+ "IPv6 fragq", /* 94 M_FRAGQ */ \
+ "Sec Assoc", /* 95 M_SECA */ \
+ "IPv6 if info", /* 96 M_I6IFP */ \
+ "RaidFrame data", /* 97 M_RAIDFRAME */ \
+ "UVM amap", /* 98 M_UVMAMAP */ \
+ "UVM aobj", /* 99 M_UVMAOBJ */ \
+ "pool", /* 100 M_POOL */ \
+ "USB", /* 101 M_USB */ \
+ "USB device", /* 102 M_USBDEV */ \
+ "USB HC", /* 103 M_USBHC */ \
+ "pipe", /* 104 M_PIPE */ \
+ "memdesc", /* 105 M_MEMDESC */ \
+ NULL, \
+ NULL, NULL, NULL, NULL, NULL, \
+ NULL, NULL, NULL, NULL, NULL, \
+ NULL, NULL, NULL, NULL, NULL, \
+ NULL, \
+ "ip6_options", /* 123 M_IP6OPT */ \
+ "NDP", /* 124 M_IP6NDP */ \
+ "ip6rr", /* 125 M_IP6RR */ \
+ "rp_addr", /* 126 M_RR_ADDR */ \
+ "temp", /* 127 M_TEMP */ \
+}
+
+#ifndef __ECOS
+struct kmemstats {
+ long ks_inuse; /* # of packets of this type currently in use */
+ long ks_calls; /* total packets of this type ever allocated */
+ long ks_memuse; /* total memory held in bytes */
+ u_short ks_limblocks; /* number of times blocked for hitting limit */
+ u_short ks_mapblocks; /* number of times blocked for kernel map */
+ long ks_maxused; /* maximum number ever used */
+ long ks_limit; /* most that are allowed to exist */
+ long ks_size; /* sizes of this thing that are allocated */
+ long ks_spare;
+};
+
+/*
+ * Array of descriptors that describe the contents of each page
+ */
+struct kmemusage {
+ short ku_indx; /* bucket index */
+ union {
+ u_short freecnt;/* for small allocations, free pieces in page */
+ u_short pagecnt;/* for large allocations, pages alloced */
+ } ku_un;
+};
+#define ku_freecnt ku_un.freecnt
+#define ku_pagecnt ku_un.pagecnt
+
+/*
+ * Set of buckets for each size of memory block that is retained
+ */
+struct kmembuckets {
+ caddr_t kb_next; /* list of free blocks */
+ caddr_t kb_last; /* last free block */
+ long kb_calls; /* total calls to allocate this size */
+ long kb_total; /* total number of blocks allocated */
+ long kb_totalfree; /* # of free elements in this bucket */
+ long kb_elmpercl; /* # of elements in this sized allocation */
+ long kb_highwat; /* high water mark */
+ long kb_couldfree; /* over high water mark and could free */
+};
+
+#ifdef _KERNEL
+#define MINALLOCSIZE (1 << MINBUCKET)
+#define BUCKETINDX(size) \
+ ((size) <= (MINALLOCSIZE * 128) \
+ ? (size) <= (MINALLOCSIZE * 8) \
+ ? (size) <= (MINALLOCSIZE * 2) \
+ ? (size) <= (MINALLOCSIZE * 1) \
+ ? (MINBUCKET + 0) \
+ : (MINBUCKET + 1) \
+ : (size) <= (MINALLOCSIZE * 4) \
+ ? (MINBUCKET + 2) \
+ : (MINBUCKET + 3) \
+ : (size) <= (MINALLOCSIZE* 32) \
+ ? (size) <= (MINALLOCSIZE * 16) \
+ ? (MINBUCKET + 4) \
+ : (MINBUCKET + 5) \
+ : (size) <= (MINALLOCSIZE * 64) \
+ ? (MINBUCKET + 6) \
+ : (MINBUCKET + 7) \
+ : (size) <= (MINALLOCSIZE * 2048) \
+ ? (size) <= (MINALLOCSIZE * 512) \
+ ? (size) <= (MINALLOCSIZE * 256) \
+ ? (MINBUCKET + 8) \
+ : (MINBUCKET + 9) \
+ : (size) <= (MINALLOCSIZE * 1024) \
+ ? (MINBUCKET + 10) \
+ : (MINBUCKET + 11) \
+ : (size) <= (MINALLOCSIZE * 8192) \
+ ? (size) <= (MINALLOCSIZE * 4096) \
+ ? (MINBUCKET + 12) \
+ : (MINBUCKET + 13) \
+ : (size) <= (MINALLOCSIZE * 16384) \
+ ? (MINBUCKET + 14) \
+ : (MINBUCKET + 15))
+
+/*
+ * Turn virtual addresses into kmem map indicies
+ */
+#define kmemxtob(alloc) (kmembase + (alloc) * NBPG)
+#define btokmemx(addr) (((caddr_t)(addr) - kmembase) / NBPG)
+#define btokup(addr) (&kmemusage[((caddr_t)(addr) - kmembase) >> CLSHIFT])
+
+/*
+ * Macro versions for the usual cases of malloc/free
+ */
+#if defined(KMEMSTATS) || defined(DIAGNOSTIC) || defined(_LKM)
+#define MALLOC(space, cast, size, type, flags) \
+ (space) = (cast)malloc((u_long)(size), type, flags)
+#define FREE(addr, type) free((caddr_t)(addr), type)
+
+#else /* do not collect statistics */
+#define MALLOC(space, cast, size, type, flags) do { \
+ register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \
+ long s = splimp(); \
+ if (kbp->kb_next == NULL) { \
+ (space) = (cast)malloc((u_long)(size), type, flags); \
+ } else { \
+ (space) = (cast)kbp->kb_next; \
+ kbp->kb_next = *(caddr_t *)(space); \
+ } \
+ splx(s); \
+} while (0)
+
+#define FREE(addr, type) do { \
+ register struct kmembuckets *kbp; \
+ register struct kmemusage *kup = btokup(addr); \
+ long s = splimp(); \
+ if (1 << kup->ku_indx > MAXALLOCSAVE) { \
+ free((caddr_t)(addr), type); \
+ } else { \
+ kbp = &bucket[kup->ku_indx]; \
+ if (kbp->kb_next == NULL) \
+ kbp->kb_next = (caddr_t)(addr); \
+ else \
+ *(caddr_t *)(kbp->kb_last) = (caddr_t)(addr); \
+ *(caddr_t *)(addr) = NULL; \
+ kbp->kb_last = (caddr_t)(addr); \
+ } \
+ splx(s); \
+} while(0)
+#endif /* do not collect statistics */
+
+extern struct kmemstats kmemstats[];
+extern struct kmemusage *kmemusage;
+extern char *kmembase;
+extern struct kmembuckets bucket[];
+
+extern void *malloc __P((unsigned long size, int type, int flags));
+extern void free __P((void *addr, int type));
+
+#endif /* _KERNEL */
+#endif // __ECOS
+
+#if defined(__ECOS) && defined(_KERNEL)
+extern void *cyg_net_malloc(u_long size, int type, int flags);
+extern void cyg_net_free(caddr_t addr, int type);
+#define MALLOC(space, cast, size, type, flags) \
+ (space) = (cast)cyg_net_malloc((u_long)(size), type, flags)
+#define malloc(size, type, flags) cyg_net_malloc((u_long)size, type, flags)
+#define FREE(addr, type) cyg_net_free((caddr_t)(addr), type)
+#define free(addr, type) FREE(addr, type)
+#endif
+
+#endif /* !_SYS_MALLOC_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/mbuf.h b/ecos/packages/net/tcpip/current/include/sys/mbuf.h
new file mode 100644
index 0000000..2ca6bee
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/mbuf.h
@@ -0,0 +1,473 @@
+//==========================================================================
+//
+// include/sys/mbuf.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: mbuf.h,v 1.14 1999/12/08 06:50:24 itojun Exp $ */
+/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)mbuf.h 8.5 (Berkeley) 2/19/95
+ */
+
+#ifndef _SYS_MBUF_H_
+#define _SYS_MBUF_H_
+
+#ifndef M_WAITOK
+#include <sys/malloc.h>
+#endif
+
+/*
+ * Mbufs are of a single size, MSIZE (machine/param.h), which
+ * includes overhead. An mbuf may add a single "mbuf cluster" of size
+ * MCLBYTES (also in machine/param.h), which has no additional overhead
+ * and is used instead of the internal data area; this is done when
+ * at least MINCLSIZE of data must be stored.
+ */
+
+#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
+#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
+
+#define MINCLSIZE (MHLEN + 1) /* smallest amount to put in cluster */
+#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
+
+/*
+ * Macros for type conversion
+ * mtod(m,t) - convert mbuf pointer to data pointer of correct type
+ * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX)
+ * mtocl(x) - convert pointer within cluster to cluster index #
+ * cltom(x) - convert cluster # to ptr to beginning of cluster
+ */
+#define mtod(m,t) ((t)((m)->m_data))
+#define dtom(x) ((struct mbuf *)((long)(x) & ~(MSIZE-1)))
+#ifdef __ECOS
+extern int cyg_mtocl(u_long);
+extern struct mbuf *cyg_cltom(u_long);
+#define mtocl(x) cyg_mtocl((u_long)x)
+#define cltom(x) cyg_cltom((u_long)x)
+#else
+#define mtocl(x) (((u_long)(x) - (u_long)mbutl) >> MCLSHIFT)
+#define cltom(x) ((caddr_t)((u_long)mbutl + ((u_long)(x) << MCLSHIFT)))
+#endif
+
+/* header at beginning of each mbuf: */
+struct m_hdr {
+ struct mbuf *mh_next; /* next buffer in chain */
+ struct mbuf *mh_nextpkt; /* next chain in queue/record */
+ caddr_t mh_data; /* location of data */
+ u_int mh_len; /* amount of data in this mbuf */
+ short mh_type; /* type of data in this mbuf */
+ short mh_flags; /* flags; see below */
+};
+
+/* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
+struct pkthdr {
+ struct ifnet *rcvif; /* rcv interface */
+ int len; /* total packet length */
+ void *tdbi; /* pointer to struct tdb_ident */
+ /* XXX - pull in ip_ipsp.h */
+};
+
+/* description of external storage mapped into mbuf, valid if M_EXT set */
+struct m_ext {
+ caddr_t ext_buf; /* start of buffer */
+ void (*ext_free) /* free routine if not the usual */
+ __P((struct mbuf *));
+ u_int ext_size; /* size of buffer, for ext_free */
+ void (*ext_ref) /* add a reference to the ext object */
+ __P((struct mbuf *));
+ void *ext_handle; /* handle for storage manager */
+};
+
+struct mbuf {
+ struct m_hdr m_hdr;
+ union {
+ struct {
+ struct pkthdr MH_pkthdr; /* M_PKTHDR set */
+ union {
+ struct m_ext MH_ext; /* M_EXT set */
+ char MH_databuf[MHLEN];
+ } MH_dat;
+ } MH;
+ char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
+ } M_dat;
+};
+#define m_next m_hdr.mh_next
+#define m_len m_hdr.mh_len
+#define m_data m_hdr.mh_data
+#define m_type m_hdr.mh_type
+#define m_flags m_hdr.mh_flags
+#define m_nextpkt m_hdr.mh_nextpkt
+#define m_act m_nextpkt
+#define m_pkthdr M_dat.MH.MH_pkthdr
+#define m_ext M_dat.MH.MH_dat.MH_ext
+#define m_pktdat M_dat.MH.MH_dat.MH_databuf
+#define m_dat M_dat.M_databuf
+
+/* mbuf flags */
+#define M_EXT 0x0001 /* has associated external storage */
+#define M_PKTHDR 0x0002 /* start of record */
+#define M_EOR 0x0004 /* end of record */
+
+/* mbuf pkthdr flags, also in m_flags */
+#define M_BCAST 0x0100 /* send/received as link-level broadcast */
+#define M_MCAST 0x0200 /* send/received as link-level multicast */
+#define M_CONF 0x0400 /* packet was encrypted (ESP-transport) */
+#define M_AUTH 0x0800 /* packet was authenticated (AH) */
+#if 0 /* NRL IPv6 */
+#define M_TUNNEL 0x1000 /* packet was tunneled */
+#define M_DAD 0x2000 /* Used on outbound packets to indicate that
+ * this is for duplicate address detection */
+#endif
+
+/* KAME IPv6 */
+#define M_ANYCAST6 0x4000 /* received as IPv6 anycast */
+#if 0 /*KAME IPSEC*/
+#define M_AUTHIPHDR 0x0010 /* data origin authentication for IP header */
+#define M_DECRYPTED 0x0020 /* confidentiality */
+#endif
+#define M_LOOP 0x0040 /* for Mbuf statistics */
+#if 0 /*KAME IPSEC*/
+#define M_AUTHIPDGM 0x0080 /* data origin authentication */
+#endif
+
+/* flags copied when copying m_pkthdr */
+#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CONF|M_AUTH|M_ANYCAST6|M_LOOP)
+
+/* mbuf types */
+#define MT_FREE 0 /* should be on free list */
+#define MT_DATA 1 /* dynamic (data) allocation */
+#define MT_HEADER 2 /* packet header */
+#define MT_SOCKET 3 /* socket structure */
+#define MT_PCB 4 /* protocol control block */
+#define MT_RTABLE 5 /* routing tables */
+#define MT_HTABLE 6 /* IMP host tables */
+#define MT_ATABLE 7 /* address resolution tables */
+#define MT_SONAME 8 /* socket name */
+#define MT_SOOPTS 10 /* socket options */
+#define MT_FTABLE 11 /* fragment reassembly header */
+#define MT_RIGHTS 12 /* access rights */
+#define MT_IFADDR 13 /* interface address */
+#define MT_CONTROL 14 /* extra-data protocol message */
+#define MT_OOBDATA 15 /* expedited data */
+
+/* flags to m_get/MGET */
+#define M_DONTWAIT M_NOWAIT
+#define M_WAIT M_WAITOK
+
+#ifdef __ECOS
+extern void *cyg_net_mbuf_alloc(int type, int flags);
+extern void cyg_net_mbuf_free(caddr_t addr, int type);
+#define MBUF_ALLOC(space, cast, size, type, flags) \
+ (space) = (cast)cyg_net_mbuf_alloc(type, flags)
+#define MBUF_FREE(addr, type) cyg_net_mbuf_free((caddr_t)(addr), type)
+#else
+#define MBUF_ALLOC(space, cast, size, type, flags) \
+ MALLOC(space, cast, size, type, flags)
+#define MBUF_FREE(addr, type) \
+ MFREE(addr, type)
+#endif
+
+/*
+ * mbuf utility macros:
+ *
+ * MBUFLOCK(code)
+ * prevents a section of code from from being interrupted by network
+ * drivers.
+ */
+#define MBUFLOCK(code) \
+ { int ms = splimp(); \
+ { code } \
+ splx(ms); \
+ }
+
+/*
+ * mbuf allocation/deallocation macros:
+ *
+ * MGET(struct mbuf *m, int how, int type)
+ * allocates an mbuf and initializes it to contain internal data.
+ *
+ * MGETHDR(struct mbuf *m, int how, int type)
+ * allocates an mbuf and initializes it to contain a packet header
+ * and internal data.
+ */
+#define MGET(m, how, type) { \
+ MBUF_ALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \
+ if (m) { \
+ (m)->m_type = (type); \
+ MBUFLOCK(mbstat.m_mtypes[type]++;) \
+ (m)->m_next = (struct mbuf *)NULL; \
+ (m)->m_nextpkt = (struct mbuf *)NULL; \
+ (m)->m_data = (m)->m_dat; \
+ (m)->m_flags = 0; \
+ } else \
+ (m) = m_retry((how), (type)); \
+}
+
+#define MGETHDR(m, how, type) { \
+ MBUF_ALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \
+ if (m) { \
+ (m)->m_type = (type); \
+ MBUFLOCK(mbstat.m_mtypes[type]++;) \
+ (m)->m_next = (struct mbuf *)NULL; \
+ (m)->m_nextpkt = (struct mbuf *)NULL; \
+ (m)->m_data = (m)->m_pktdat; \
+ (m)->m_flags = M_PKTHDR; \
+ } else \
+ (m) = m_retryhdr((how), (type)); \
+}
+
+/*
+ * Mbuf cluster macros.
+ * MCLALLOC(caddr_t p, int how) allocates an mbuf cluster.
+ * MCLGET adds such clusters to a normal mbuf;
+ * the flag M_EXT is set upon success.
+ * MCLFREE releases a reference to a cluster allocated by MCLALLOC,
+ * freeing the cluster if the reference count has reached 0.
+ *
+ * Normal mbuf clusters are normally treated as character arrays
+ * after allocation, but use the first word of the buffer as a free list
+ * pointer while on the free list.
+ */
+union mcluster {
+ union mcluster *mcl_next;
+ char mcl_buf[MCLBYTES];
+};
+
+#define MCLALLOC(p, how) \
+ MBUFLOCK( \
+ if (mclfree == 0) \
+ (void)m_clalloc(1, (how)); \
+ if (((p) = (caddr_t)mclfree) != 0) { \
+ ++mclrefcnt[mtocl(p)]; \
+ mbstat.m_clfree--; \
+ mclfree = ((union mcluster *)(p))->mcl_next; \
+ } \
+ )
+
+#define MCLGET(m, how) \
+ { MCLALLOC((m)->m_ext.ext_buf, (how)); \
+ if ((m)->m_ext.ext_buf != NULL) { \
+ (m)->m_data = (m)->m_ext.ext_buf; \
+ (m)->m_flags |= M_EXT; \
+ (m)->m_ext.ext_size = MCLBYTES; \
+ (m)->m_ext.ext_free = NULL; \
+ (m)->m_ext.ext_ref = NULL; \
+ (m)->m_ext.ext_handle = NULL; \
+ } \
+ }
+
+#define MCLFREE(p) \
+ MBUFLOCK ( \
+ if (--mclrefcnt[mtocl(p)] == 0) { \
+ ((union mcluster *)(p))->mcl_next = mclfree; \
+ mclfree = (union mcluster *)(p); \
+ mbstat.m_clfree++; \
+ } \
+ )
+
+/*
+ * For cluster mbufs (regardless of header or not).
+ */
+#define MCL_ALIGN(m, len) \
+ { (m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) -1); }
+
+/*
+ * MFREE(struct mbuf *m, struct mbuf *n)
+ * Free a single mbuf and associated external storage.
+ * Place the successor, if any, in n.
+ */
+#define MFREE(m, n) \
+ { MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--;) \
+ if ((m)->m_flags & M_EXT) { \
+ if ((m)->m_ext.ext_free) \
+ (*((m)->m_ext.ext_free))(m); \
+ else \
+ MCLFREE((m)->m_ext.ext_buf); \
+ } \
+ (n) = (m)->m_next; \
+ MBUF_FREE((m), mbtypes[(m)->m_type]); \
+ }
+
+/*
+ * Copy mbuf pkthdr from from to to.
+ * from must have M_PKTHDR set, and to must be empty.
+ */
+#define M_COPY_PKTHDR(to, from) { \
+ (to)->m_pkthdr = (from)->m_pkthdr; \
+ (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
+ (to)->m_data = (to)->m_pktdat; \
+}
+
+/*
+ * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
+ * an object of the specified size at the end of the mbuf, longword aligned.
+ */
+#define M_ALIGN(m, len) \
+ { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); }
+/*
+ * As above, for mbufs allocated with m_gethdr/MGETHDR
+ * or initialized by M_COPY_PKTHDR.
+ */
+#define MH_ALIGN(m, len) \
+ { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); }
+
+/*
+ * Compute the amount of space available
+ * before the current start of data in an mbuf.
+ */
+#define M_LEADINGSPACE(m) \
+ ((m)->m_flags & M_EXT ? /* (m)->m_data - (m)->m_ext.ext_buf */ 0 : \
+ (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
+ (m)->m_data - (m)->m_dat)
+
+/*
+ * Compute the amount of space available
+ * after the end of data in an mbuf.
+ */
+#define M_TRAILINGSPACE(m) \
+ ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
+ ((m)->m_data + (m)->m_len) : \
+ &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
+
+/*
+ * Arrange to prepend space of size plen to mbuf m.
+ * If a new mbuf must be allocated, how specifies whether to wait.
+ * If how is M_DONTWAIT and allocation fails, the original mbuf chain
+ * is freed and m is set to NULL.
+ */
+#define M_PREPEND(m, plen, how) { \
+ if (M_LEADINGSPACE(m) >= (plen)) { \
+ (m)->m_data -= (plen); \
+ (m)->m_len += (plen); \
+ } else \
+ (m) = m_prepend((m), (plen), (how)); \
+ if ((m) && (m)->m_flags & M_PKTHDR) \
+ (m)->m_pkthdr.len += (plen); \
+}
+
+/* change mbuf to new type */
+#define MCHTYPE(m, t) { \
+ MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;) \
+ (m)->m_type = t;\
+}
+
+/* length to m_copy to copy all */
+#define M_COPYALL 1000000000
+
+/* compatiblity with 4.3 */
+#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
+
+/*
+ * Mbuf statistics.
+ */
+struct mbstat {
+ u_long m_mbufs; /* mbufs obtained from page pool */
+ u_long m_clusters; /* clusters obtained from page pool */
+ u_long m_spare; /* spare field */
+ u_long m_clfree; /* free clusters */
+ u_long m_drops; /* times failed to find space */
+ u_long m_wait; /* times waited for space */
+ u_long m_drain; /* times drained protocols for space */
+ u_short m_mtypes[256]; /* type specific mbuf allocations */
+};
+
+#ifdef _KERNEL
+extern struct mbuf *mbutl; /* virtual address of mclusters */
+extern char *mclrefcnt; /* cluster reference counts */
+extern struct mbstat mbstat;
+extern int nmbclusters;
+union mcluster *mclfree;
+extern int max_linkhdr; /* largest link-level header */
+extern int max_protohdr; /* largest protocol header */
+extern int max_hdr; /* largest link+protocol header */
+extern int max_datalen; /* MHLEN - max_hdr */
+extern int mbtypes[]; /* XXX */
+extern int needqueuedrain; /* True if allocation failed at */
+ /* interrupt level */
+
+void mbinit __P((void));
+struct mbuf *m_copym2 __P((struct mbuf *, int, int, int));
+struct mbuf *m_copym __P((struct mbuf *, int, int, int));
+struct mbuf *m_free __P((struct mbuf *));
+struct mbuf *m_get __P((int, int));
+struct mbuf *m_getclr __P((int, int));
+struct mbuf *m_gethdr __P((int, int));
+struct mbuf *m_prepend __P((struct mbuf *, int, int));
+struct mbuf *m_pullup __P((struct mbuf *, int));
+struct mbuf *m_pullup2 __P((struct mbuf *, int));
+struct mbuf *m_retry __P((int, int));
+struct mbuf *m_retryhdr __P((int, int));
+struct mbuf *m_split __P((struct mbuf *, int, int));
+struct mbuf *m_inject __P((struct mbuf *, int, int, int));
+void m_adj __P((struct mbuf *, int));
+int m_clalloc __P((int, int));
+void m_copyback __P((struct mbuf *, int, int, caddr_t));
+void m_freem __P((struct mbuf *));
+void m_reclaim __P((void));
+void m_copydata __P((struct mbuf *, int, int, caddr_t));
+void m_cat __P((struct mbuf *, struct mbuf *));
+struct mbuf *m_devget __P((char *, int, int, struct ifnet *,
+ void (*) __P((const void *, void *, size_t))));
+void m_zero __P((struct mbuf *));
+int m_apply __P((struct mbuf *, int, int,
+ int (*)(caddr_t, caddr_t, unsigned int), caddr_t));
+
+#endif
+
+#endif // _SYS_MBUF_H_
diff --git a/ecos/packages/net/tcpip/current/include/sys/param.h b/ecos/packages/net/tcpip/current/include/sys/param.h
new file mode 100644
index 0000000..89952cf
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/param.h
@@ -0,0 +1,344 @@
+//==========================================================================
+//
+// include/sys/param.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: param.h,v 1.25 1999/09/23 08:25:01 deraadt Exp $ */
+/* $NetBSD: param.h,v 1.23 1996/03/17 01:02:29 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)param.h 8.2 (Berkeley) 1/21/94
+ */
+
+#ifndef _SYS_PARAM_H_
+#define _SYS_PARAM_H_
+
+#define BSD 199306 /* System version (year & month). */
+#define BSD4_3 1
+#define BSD4_4 1
+
+#define OpenBSD 199912 /* OpenBSD version (year & month). */
+#define OpenBSD2_6 1 /* OpenBSD 2.6 */
+
+#ifndef NULL
+#ifdef __GNUG__
+#define NULL __null
+#else
+#define NULL 0
+#endif
+#endif
+
+#ifndef _LOCORE
+#include <sys/types.h>
+#ifndef __ECOS
+#include <sys/simplelock.h>
+#endif
+#endif
+
+#ifndef __ECOS
+/*
+ * Machine-independent constants (some used in following include files).
+ * Redefined constants are from POSIX 1003.1 limits file.
+ *
+ * MAXCOMLEN should be >= sizeof(ac_comm) (see <acct.h>)
+ * MAXLOGNAME should be >= UT_NAMESIZE (see <utmp.h>)
+ */
+#include <sys/syslimits.h>
+
+#define MAXCOMLEN 16 /* max command name remembered */
+#define MAXINTERP 64 /* max interpreter file name length */
+#define MAXLOGNAME 12 /* max login name length */
+#define MAXUPRC CHILD_MAX /* max simultaneous processes */
+#define NCARGS ARG_MAX /* max bytes for an exec function */
+#define NGROUPS NGROUPS_MAX /* max number groups */
+#define NOFILE OPEN_MAX /* max open files per process (soft) */
+#define NOFILE_MAX 1024 /* max open files per process (hard) */
+#define NOGROUP 65535 /* marker for empty group set member */
+#endif
+#define MAXHOSTNAMELEN 256 /* max hostname size */
+
+/* More types and definitions used throughout the kernel. */
+#ifdef _KERNEL
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#ifdef __ECOS
+#include <cyg/io/file.h>
+#else
+#include <sys/resource.h>
+#include <sys/ucred.h>
+#include <sys/uio.h>
+#endif
+#endif
+
+#ifndef __ECOS
+/* Signals. */
+#include <sys/signal.h>
+#endif
+
+#ifndef __ECOS
+/*
+ * Priorities. Note that with 32 run queues, differences less than 4 are
+ * insignificant.
+ */
+#define PSWP 0
+#define PVM 4
+#define PINOD 8
+#define PRIBIO 16
+#define PVFS 20
+#define PZERO 22 /* No longer magic, shouldn't be here. XXX */
+#define PSOCK 24
+#define PWAIT 32
+#define PLOCK 36
+#define PPAUSE 40
+#define PUSER 50
+#define MAXPRI 127 /* Priorities range from 0 through MAXPRI. */
+
+#define PRIMASK 0x0ff
+#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */
+#endif
+
+#define NBPW sizeof(int) /* number of bytes per word (integer) */
+
+#ifndef __ECOS
+#define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */
+#define NODEV (dev_t)(-1) /* non-existent device */
+
+/*
+ * Clustering of hardware pages on machines with ridiculously small
+ * page sizes is done here. The paging subsystem deals with units of
+ * CLSIZE pte's describing NBPG (from machine/machparam.h) pages each.
+ */
+#define CLBYTES (CLSIZE*NBPG)
+#define CLOFSET (CLSIZE*NBPG-1) /* for clusters, like PGOFSET */
+#define claligned(x) ((((int)(x))&CLOFSET)==0)
+#define CLOFF CLOFSET
+#define CLSHIFT (PGSHIFT+CLSIZELOG2)
+
+#if CLSIZE==1
+#define clbase(i) (i)
+#define clrnd(i) (i)
+#else
+/* Give the base virtual address (first of CLSIZE). */
+#define clbase(i) ((i) &~ (CLSIZE-1))
+/* Round a number of clicks up to a whole cluster. */
+#define clrnd(i) (((i) + (CLSIZE-1)) &~ (CLSIZE-1))
+#endif
+
+#define CBLOCK 64 /* Clist block size, must be a power of 2. */
+#define CBQSIZE (CBLOCK/NBBY) /* Quote bytes/cblock - can do better. */
+ /* Data chars/clist. */
+#define CBSIZE (CBLOCK - sizeof(struct cblock *) - CBQSIZE)
+#define CROUND (CBLOCK - 1) /* Clist rounding. */
+
+/*
+ * File system parameters and macros.
+ *
+ * The file system is made out of blocks of at most MAXBSIZE units, with
+ * smaller units (fragments) only in the last direct block. MAXBSIZE
+ * primarily determines the size of buffers in the buffer pool. It may be
+ * made larger without any effect on existing file systems; however making
+ * it smaller makes some file systems unmountable.
+ */
+#ifndef MAXBSIZE /* XXX temp until sun3 DMA chaining */
+#define MAXBSIZE MAXPHYS
+#endif
+#define MAXFRAG 8
+
+/*
+ * MAXPATHLEN defines the longest permissable path length after expanding
+ * symbolic links. It is used to allocate a temporary buffer from the buffer
+ * pool in which to do the name expansion, hence should be a power of two,
+ * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the
+ * maximum number of symbolic links that may be expanded in a path name.
+ * It should be set high enough to allow all legitimate uses, but halt
+ * infinite loops reasonably quickly.
+ */
+#define MAXPATHLEN PATH_MAX
+#define MAXSYMLINKS 32
+
+#endif // __ECOS
+
+/* Bit map related macros. */
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding. */
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#define powerof2(x) ((((x)-1)&(x))==0)
+
+/* Macros for min/max. */
+#ifndef _KERNEL
+# ifndef MIN
+# define MIN(a,b) (((a)<(b))?(a):(b))
+# endif
+# ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+# endif
+#endif
+
+#ifndef __ECOS
+/*
+ * Constants for setting the parameters of the kernel memory allocator.
+ *
+ * 2 ** MINBUCKET is the smallest unit of memory that will be
+ * allocated. It must be at least large enough to hold a pointer.
+ *
+ * Units of memory less or equal to MAXALLOCSAVE will permanently
+ * allocate physical memory; requests for these size pieces of
+ * memory are quite fast. Allocations greater than MAXALLOCSAVE must
+ * always allocate and free physical memory; requests for these
+ * size allocations should be done infrequently as they will be slow.
+ *
+ * Constraints: CLBYTES <= MAXALLOCSAVE <= 2 ** (MINBUCKET + 14), and
+ * MAXALLOCSIZE must be a power of two.
+ */
+#define MINBUCKET 4 /* 4 => min allocation of 16 bytes */
+#define MAXALLOCSAVE (2 * CLBYTES)
+
+/*
+ * Scale factor for scaled integers used to count %cpu time and load avgs.
+ *
+ * The number of CPU `tick's that map to a unique `%age' can be expressed
+ * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that
+ * can be calculated (assuming 32 bits) can be closely approximated using
+ * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15).
+ *
+ * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age',
+ * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024.
+ */
+#define FSHIFT 11 /* bits to right of fixed binary point */
+#define FSCALE (1<<FSHIFT)
+
+/*
+ * rfork() options.
+ *
+ * XXX currently, operations without RFPROC set are not supported.
+ */
+#define RFNAMEG (1<<0) /* UNIMPL new plan9 `name space' */
+#define RFENVG (1<<1) /* UNIMPL copy plan9 `env space' */
+#define RFFDG (1<<2) /* copy fd table */
+#define RFNOTEG (1<<3) /* UNIMPL create new plan9 `note group' */
+#define RFPROC (1<<4) /* change child (else changes curproc) */
+#define RFMEM (1<<5) /* share `address space' */
+#define RFNOWAIT (1<<6) /* parent need not wait() on child */
+#define RFCNAMEG (1<<10) /* UNIMPL zero plan9 `name space' */
+#define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */
+#define RFCFDG (1<<12) /* zero fd table */
+#endif // __ECOS
+
+#ifdef __ECOS
+// Function mappings
+
+extern int cyg_tsleep(void *, int, char *, int);
+extern void cyg_wakeup(void *);
+#define tsleep(e,p,w,t) cyg_tsleep(e,0,w,t)
+#define wakeup(e) cyg_wakeup(e)
+
+#ifdef CYGIMPL_TRACE_SPLX
+extern cyg_uint32 cyg_splimp(const char *file, const int line);
+extern cyg_uint32 cyg_splnet(const char *file, const int line);
+extern cyg_uint32 cyg_splclock(const char *file, const int line);
+extern cyg_uint32 cyg_splsoftnet(const char *file, const int line);
+extern void cyg_splx(cyg_uint32, const char *file, const int line);
+#define splimp() cyg_splimp(__FUNCTION__, __LINE__)
+#define splnet() cyg_splnet(__FUNCTION__, __LINE__)
+#define splclock() cyg_splclock(__FUNCTION__, __LINE__)
+#define splsoftnet() cyg_splsoftnet(__FUNCTION__, __LINE__)
+#define splx(x) cyg_splx(x, __FUNCTION__, __LINE__)
+#define cyg_scheduler_lock() _cyg_scheduler_lock(__FUNCTION__, __LINE__)
+#define cyg_scheduler_safe_lock() _cyg_scheduler_safe_lock(__FUNCTION__, __LINE__)
+#define cyg_scheduler_unlock() _cyg_scheduler_unlock(__FUNCTION__, __LINE__)
+#else
+extern cyg_uint32 cyg_splimp(void);
+extern cyg_uint32 cyg_splnet(void);
+extern cyg_uint32 cyg_splclock(void);
+extern cyg_uint32 cyg_splsoftnet(void);
+extern cyg_uint32 cyg_splhigh(void);
+extern void cyg_splx(cyg_uint32);
+#define splimp cyg_splimp
+#define splnet cyg_splnet
+#define splclock cyg_splclock
+#define splsoftnet cyg_splsoftnet
+#define splhigh cyg_splhigh
+#define splx cyg_splx
+#endif
+
+extern void cyg_panic(const char *msg, ...);
+#define panic cyg_panic
+
+// Namespace changes
+#define route_reinit cyg_route_reinit
+#define arc4random cyg_arc4random
+#endif
+
+/* Machine type dependent parameters. */
+#include <machine/param.h>
+#include <machine/limits.h>
+
+#endif // __SYS_PARAM_H_
diff --git a/ecos/packages/net/tcpip/current/include/sys/protosw.h b/ecos/packages/net/tcpip/current/include/sys/protosw.h
new file mode 100644
index 0000000..9afe2b4
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/protosw.h
@@ -0,0 +1,271 @@
+//==========================================================================
+//
+// include/sys/protosw.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: protosw.h,v 1.3 1996/04/21 22:31:54 deraadt Exp $ */
+/* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)protosw.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _SYS_PROTOSW_H_
+#define _SYS_PROTOSW_H_
+
+/*
+ * Protocol switch table.
+ *
+ * Each protocol has a handle initializing one of these structures,
+ * which is used for protocol-protocol and system-protocol communication.
+ *
+ * A protocol is called through the pr_init entry before any other.
+ * Thereafter it is called every 200ms through the pr_fasttimo entry and
+ * every 500ms through the pr_slowtimo for timer based actions.
+ * The system will call the pr_drain entry if it is low on space and
+ * this should throw away any non-critical data.
+ *
+ * Protocols pass data between themselves as chains of mbufs using
+ * the pr_input and pr_output hooks. Pr_input passes data up (towards
+ * UNIX) and pr_output passes it down (towards the imps); control
+ * information passes up and down on pr_ctlinput and pr_ctloutput.
+ * The protocol is responsible for the space occupied by any the
+ * arguments to these entries and must dispose it.
+ *
+ * The userreq routine interfaces protocols to the system and is
+ * described below.
+ */
+
+struct mbuf;
+struct sockaddr;
+struct socket;
+struct domain;
+
+struct protosw {
+ short pr_type; /* socket type used for */
+ struct domain *pr_domain; /* domain protocol a member of */
+ short pr_protocol; /* protocol number */
+ short pr_flags; /* see below */
+
+/* protocol-protocol hooks */
+ void (*pr_input) /* input to protocol (from below) */
+ __P((struct mbuf *, ...));
+ int (*pr_output) /* output to protocol (from above) */
+ __P((struct mbuf *, ...));
+ void *(*pr_ctlinput) /* control input (from below) */
+ __P((int, struct sockaddr *, void *));
+ int (*pr_ctloutput) /* control output (from above) */
+ __P((int, struct socket *, int, int, struct mbuf **));
+
+/* user-protocol hook */
+ int (*pr_usrreq) /* user request: see list below */
+ __P((struct socket *, int, struct mbuf *,
+ struct mbuf *, struct mbuf *));
+
+/* utility hooks */
+ void (*pr_init) /* initialization hook */
+ __P((void));
+
+ void (*pr_fasttimo) /* fast timeout (200ms) */
+ __P((void));
+ void (*pr_slowtimo) /* slow timeout (500ms) */
+ __P((void));
+ void (*pr_drain) /* flush any excess space possible */
+ __P((void));
+ int (*pr_sysctl) /* sysctl for protocol */
+ __P((int *, u_int, void *, size_t *, void *, size_t));
+};
+
+#define PR_SLOWHZ 2 /* 2 slow timeouts per second */
+#define PR_FASTHZ 5 /* 5 fast timeouts per second */
+
+/*
+ * Values for pr_flags.
+ * PR_ADDR requires PR_ATOMIC;
+ * PR_ADDR and PR_CONNREQUIRED are mutually exclusive.
+ */
+#define PR_ATOMIC 0x01 /* exchange atomic messages only */
+#define PR_ADDR 0x02 /* addresses given with messages */
+#define PR_CONNREQUIRED 0x04 /* connection required by protocol */
+#define PR_WANTRCVD 0x08 /* want PRU_RCVD calls */
+#define PR_RIGHTS 0x10 /* passes capabilities */
+
+/*
+ * The arguments to usrreq are:
+ * (*protosw[].pr_usrreq)(up, req, m, nam, opt);
+ * where up is a (struct socket *), req is one of these requests,
+ * m is a optional mbuf chain containing a message,
+ * nam is an optional mbuf chain containing an address,
+ * and opt is a pointer to a socketopt structure or nil.
+ * The protocol is responsible for disposal of the mbuf chain m,
+ * the caller is responsible for any space held by nam and opt.
+ * A non-zero return from usrreq gives an
+ * UNIX error number which should be passed to higher level software.
+ */
+#define PRU_ATTACH 0 /* attach protocol to up */
+#define PRU_DETACH 1 /* detach protocol from up */
+#define PRU_BIND 2 /* bind socket to address */
+#define PRU_LISTEN 3 /* listen for connection */
+#define PRU_CONNECT 4 /* establish connection to peer */
+#define PRU_ACCEPT 5 /* accept connection from peer */
+#define PRU_DISCONNECT 6 /* disconnect from peer */
+#define PRU_SHUTDOWN 7 /* won't send any more data */
+#define PRU_RCVD 8 /* have taken data; more room now */
+#define PRU_SEND 9 /* send this data */
+#define PRU_ABORT 10 /* abort (fast DISCONNECT, DETATCH) */
+#define PRU_CONTROL 11 /* control operations on protocol */
+#define PRU_SENSE 12 /* return status into m */
+#define PRU_RCVOOB 13 /* retrieve out of band data */
+#define PRU_SENDOOB 14 /* send out of band data */
+#define PRU_SOCKADDR 15 /* fetch socket's address */
+#define PRU_PEERADDR 16 /* fetch peer's address */
+#define PRU_CONNECT2 17 /* connect two sockets */
+/* begin for protocols internal use */
+#define PRU_FASTTIMO 18 /* 200ms timeout */
+#define PRU_SLOWTIMO 19 /* 500ms timeout */
+#define PRU_PROTORCV 20 /* receive from below */
+#define PRU_PROTOSEND 21 /* send to below */
+
+#define PRU_NREQ 21
+
+#ifdef PRUREQUESTS
+char *prurequests[] = {
+ "ATTACH", "DETACH", "BIND", "LISTEN",
+ "CONNECT", "ACCEPT", "DISCONNECT", "SHUTDOWN",
+ "RCVD", "SEND", "ABORT", "CONTROL",
+ "SENSE", "RCVOOB", "SENDOOB", "SOCKADDR",
+ "PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO",
+ "PROTORCV", "PROTOSEND",
+};
+#endif
+
+/*
+ * The arguments to the ctlinput routine are
+ * (*protosw[].pr_ctlinput)(cmd, sa, arg);
+ * where cmd is one of the commands below, sa is a pointer to a sockaddr,
+ * and arg is an optional caddr_t argument used within a protocol family.
+ */
+#define PRC_IFDOWN 0 /* interface transition */
+#define PRC_ROUTEDEAD 1 /* select new route if possible ??? */
+#define PRC_QUENCH2 3 /* DEC congestion bit says slow down */
+#define PRC_QUENCH 4 /* some one said to slow down */
+#define PRC_MSGSIZE 5 /* message size forced drop */
+#define PRC_HOSTDEAD 6 /* host appears to be down */
+#define PRC_HOSTUNREACH 7 /* deprecated (use PRC_UNREACH_HOST) */
+#define PRC_UNREACH_NET 8 /* no route to network */
+#define PRC_UNREACH_HOST 9 /* no route to host */
+#define PRC_UNREACH_PROTOCOL 10 /* dst says bad protocol */
+#define PRC_UNREACH_PORT 11 /* bad port # */
+/* was PRC_UNREACH_NEEDFRAG 12 (use PRC_MSGSIZE) */
+#define PRC_UNREACH_SRCFAIL 13 /* source route failed */
+#define PRC_REDIRECT_NET 14 /* net routing redirect */
+#define PRC_REDIRECT_HOST 15 /* host routing redirect */
+#define PRC_REDIRECT_TOSNET 16 /* redirect for type of service & net */
+#define PRC_REDIRECT_TOSHOST 17 /* redirect for tos & host */
+#define PRC_TIMXCEED_INTRANS 18 /* packet lifetime expired in transit */
+#define PRC_TIMXCEED_REASS 19 /* lifetime expired on reass q */
+#define PRC_PARAMPROB 20 /* header incorrect */
+
+#define PRC_NCMDS 21
+
+#define PRC_IS_REDIRECT(cmd) \
+ ((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
+
+#ifdef PRCREQUESTS
+char *prcrequests[] = {
+ "IFDOWN", "ROUTEDEAD", "#2", "DEC-BIT-QUENCH2",
+ "QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
+ "NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
+ "#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
+ "TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
+ "PARAMPROB"
+};
+#endif
+
+/*
+ * The arguments to ctloutput are:
+ * (*protosw[].pr_ctloutput)(req, so, level, optname, optval);
+ * req is one of the actions listed below, so is a (struct socket *),
+ * level is an indication of which protocol layer the option is intended.
+ * optname is a protocol dependent socket option request,
+ * optval is a pointer to a mbuf-chain pointer, for value-return results.
+ * The protocol is responsible for disposal of the mbuf chain *optval
+ * if supplied,
+ * the caller is responsible for any space held by *optval, when returned.
+ * A non-zero return from usrreq gives an
+ * UNIX error number which should be passed to higher level software.
+ */
+#define PRCO_GETOPT 0
+#define PRCO_SETOPT 1
+
+#define PRCO_NCMDS 2
+
+#ifdef PRCOREQUESTS
+char *prcorequests[] = {
+ "GETOPT", "SETOPT",
+};
+#endif
+
+#ifdef _KERNEL
+struct sockaddr;
+struct protosw *pffindproto __P((int, int, int));
+struct protosw *pffindtype __P((int, int));
+void pfctlinput __P((int, struct sockaddr *));
+#endif
+
+#endif // _SYS_PROTOSW_H_
diff --git a/ecos/packages/net/tcpip/current/include/sys/queue.h b/ecos/packages/net/tcpip/current/include/sys/queue.h
new file mode 100644
index 0000000..2358b86
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/queue.h
@@ -0,0 +1,514 @@
+//==========================================================================
+//
+// include/sys/queue.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: queue.h,v 1.14 1999/09/08 08:20:04 espie Exp $ */
+/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_END(head) NULL
+#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = SLIST_FIRST(head); \
+ (var) != SLIST_END(head); \
+ (var) = SLIST_NEXT(var, field))
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) { \
+ SLIST_FIRST(head) = SLIST_END(head); \
+}
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (0)
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List access methods
+ */
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_END(head) NULL
+#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_FOREACH(var, head, field) \
+ for((var) = LIST_FIRST(head); \
+ (var)!= LIST_END(head); \
+ (var) = LIST_NEXT(var, field))
+
+/*
+ * List functions.
+ */
+#define LIST_INIT(head) do { \
+ LIST_FIRST(head) = LIST_END(head); \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (0)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (0)
+
+#define LIST_REPLACE(elm, elm2, field) do { \
+ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
+ (elm2)->field.le_next->field.le_prev = \
+ &(elm2)->field.le_next; \
+ (elm2)->field.le_prev = (elm)->field.le_prev; \
+ *(elm2)->field.le_prev = (elm2); \
+} while (0)
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define SIMPLEQ_END(head) NULL
+#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
+#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+#define SIMPLEQ_FOREACH(var, head, field) \
+ for((var) = SIMPLEQ_FIRST(head); \
+ (var) != SIMPLEQ_END(head); \
+ (var) = SIMPLEQ_NEXT(var, field))
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
+ if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (0)
+
+/*
+ * Tail queue definitions.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+}
+
+/*
+ * tail queue access methods
+ */
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_END(head) NULL
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+/* XXX */
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define TAILQ_EMPTY(head) \
+ (TAILQ_FIRST(head) == TAILQ_END(head))
+
+#define TAILQ_FOREACH(var, head, field) \
+ for((var) = TAILQ_FIRST(head); \
+ (var) != TAILQ_END(head); \
+ (var) = TAILQ_NEXT(var, field))
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
+ (elm2)->field.tqe_next->field.tqe_prev = \
+ &(elm2)->field.le_next; \
+ else \
+ (head).tqh_last = &(elm2)->field.tqe_next; \
+ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
+ *(elm2)->field.tqe_prev = (elm2); \
+} while (0)
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue access methods
+ */
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define CIRCLEQ_END(head) ((void *)(head))
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+#define CIRCLEQ_EMPTY(head) \
+ (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for((var) = CIRCLEQ_FIRST(head); \
+ (var) != CIRCLEQ_END(head); \
+ (var) = CIRCLEQ_NEXT(var, field))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for((var) = CIRCLEQ_LAST(head); \
+ (var) != CIRCLEQ_END(head); \
+ (var) = CIRCLEQ_PREV(var, field))
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = CIRCLEQ_END(head); \
+ (head)->cqh_last = CIRCLEQ_END(head); \
+} while (0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = CIRCLEQ_END(head); \
+ if ((head)->cqh_last == CIRCLEQ_END(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = CIRCLEQ_END(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == CIRCLEQ_END(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (0)
+
+#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
+ CIRCLEQ_END(head)) \
+ (head).cqh_last = (elm2); \
+ else \
+ (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
+ if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
+ CIRCLEQ_END(head)) \
+ (head).cqh_first = (elm2); \
+ else \
+ (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
+} while (0)
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/socket.h b/ecos/packages/net/tcpip/current/include/sys/socket.h
new file mode 100644
index 0000000..fe9fb38
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/socket.h
@@ -0,0 +1,454 @@
+//==========================================================================
+//
+// include/sys/socket.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: socket.h,v 1.30 1999/12/08 06:50:24 itojun Exp $ */
+/* $NetBSD: socket.h,v 1.14 1996/02/09 18:25:36 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)socket.h 8.4 (Berkeley) 2/21/94
+ */
+
+#ifndef _SYS_SOCKET_H_
+#define _SYS_SOCKET_H_
+
+/*
+ * Definitions related to sockets: types, address families, options.
+ */
+
+/*
+ * Types
+ */
+#define SOCK_STREAM 1 /* stream socket */
+#define SOCK_DGRAM 2 /* datagram socket */
+#define SOCK_RAW 3 /* raw-protocol interface */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequenced packet stream */
+
+/*
+ * Option flags per-socket.
+ */
+#define SO_DEBUG 0x0001 /* turn on debugging info recording */
+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
+#define SO_REUSEADDR 0x0004 /* allow local address reuse */
+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
+#define SO_DONTROUTE 0x0010 /* just use interface addresses */
+#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
+#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
+#define SO_LINGER 0x0080 /* linger on close if data present */
+#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
+#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_SNDBUF 0x1001 /* send buffer size */
+#define SO_RCVBUF 0x1002 /* receive buffer size */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_TYPE 0x1008 /* get socket type */
+#define SO_NETPROC 0x1020 /* multiplex; network processing */
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define SOL_SOCKET 0xffff /* options for socket level */
+
+/*
+ * Address families.
+ */
+#define AF_UNSPEC 0 /* unspecified */
+#define AF_LOCAL 1 /* local to host (pipes, portals) */
+#define AF_UNIX AF_LOCAL /* backward compatibility */
+#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+#define AF_IMPLINK 3 /* arpanet imp addresses */
+#define AF_PUP 4 /* pup protocols: e.g. BSP */
+#define AF_CHAOS 5 /* mit CHAOS protocols */
+#define AF_NS 6 /* XEROX NS protocols */
+#define AF_ISO 7 /* ISO protocols */
+#define AF_OSI AF_ISO
+#define AF_ECMA 8 /* european computer manufacturers */
+#define AF_DATAKIT 9 /* datakit protocols */
+#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+#define AF_SNA 11 /* IBM SNA */
+#define AF_DECnet 12 /* DECnet */
+#define AF_DLI 13 /* DEC Direct data link interface */
+#define AF_LAT 14 /* LAT */
+#define AF_HYLINK 15 /* NSC Hyperchannel */
+#define AF_APPLETALK 16 /* Apple Talk */
+#define AF_ROUTE 17 /* Internal Routing Protocol */
+#define AF_LINK 18 /* Link layer interface */
+#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
+#define AF_COIP 20 /* connection-oriented IP, aka ST II */
+#define AF_CNT 21 /* Computer Network Technology */
+#define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */
+#define AF_IPX 23 /* Novell Internet Protocol */
+#define AF_INET6 24 /* IPv6 */
+#define pseudo_AF_PIP 25 /* Help Identify PIP packets */
+#define AF_ISDN 26 /* Integrated Services Digital Network*/
+#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */
+#define AF_NATM 27 /* native ATM access */
+#define AF_ENCAP 28
+#define AF_SIP 29 /* Simple Internet Protocol */
+#define AF_KEY 30
+#define AF_MAX 31
+
+/*
+ * Structure used by kernel to store most
+ * addresses.
+ */
+struct sockaddr {
+ u_int8_t sa_len; /* total length */
+ sa_family_t sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+
+/*
+ * Sockaddr type which can hold any sockaddr type available
+ * in the system.
+ *
+ * Note: __ss_{len,family} is defined in RFC2553. During RFC2553 discussion
+ * the field name went back and forth between ss_len and __ss_len,
+ * and RFC2553 specifies it to be __ss_len. openbsd picked ss_len.
+ * For maximum portability, userland programmer would need to
+ * (1) make the code never touch ss_len portion (cast it into sockaddr and
+ * touch sa_len), or (2) add "-Dss_len=__ss_len" into CFLAGS to unify all
+ * occurences (including header file) to __ss_len.
+ */
+struct sockaddr_storage {
+ u_int8_t ss_len; /* total length */
+ sa_family_t ss_family; /* address family */
+ u_char __ss_pad1[6]; /* align to quad */
+ u_int64_t __ss_pad2; /* force alignment for stupid compilers */
+ u_char __ss_pad3[240]; /* pad to a total of 256 bytes */
+};
+
+/*
+ * Structure used by kernel to pass protocol
+ * information in raw sockets.
+ */
+struct sockproto {
+ u_short sp_family; /* address family */
+ u_short sp_protocol; /* protocol */
+};
+
+/*
+ * Protocol families, same as address families for now.
+ */
+#define PF_UNSPEC AF_UNSPEC
+#define PF_LOCAL AF_LOCAL
+#define PF_UNIX PF_LOCAL /* backward compatibility */
+#define PF_INET AF_INET
+#define PF_INET6 AF_INET6
+#define PF_IMPLINK AF_IMPLINK
+#define PF_PUP AF_PUP
+#define PF_CHAOS AF_CHAOS
+#define PF_NS AF_NS
+#define PF_ISO AF_ISO
+#define PF_OSI AF_ISO
+#define PF_ECMA AF_ECMA
+#define PF_DATAKIT AF_DATAKIT
+#define PF_CCITT AF_CCITT
+#define PF_SNA AF_SNA
+#define PF_DECnet AF_DECnet
+#define PF_DLI AF_DLI
+#define PF_LAT AF_LAT
+#define PF_HYLINK AF_HYLINK
+#define PF_APPLETALK AF_APPLETALK
+#define PF_ROUTE AF_ROUTE
+#define PF_LINK AF_LINK
+#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
+#define PF_COIP AF_COIP
+#define PF_CNT AF_CNT
+#define PF_IPX AF_IPX /* same format as AF_NS */
+#define PF_INET6 AF_INET6
+#define PF_RTIP pseudo_AF_FTIP /* same format as AF_INET */
+#define PF_PIP pseudo_AF_PIP
+#define PF_ISDN AF_ISDN
+#define PF_NATM AF_NATM
+#define PF_ENCAP AF_ENCAP
+#define PF_SIP AF_SIP
+#define PF_KEY AF_KEY
+#define PF_MAX AF_MAX
+
+/*
+ * These are the valid values for the "how" field used by shutdown(2).
+ */
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+
+/*
+ * Socket credentials.
+ */
+struct sockcred {
+ uid_t sc_uid; /* real user id */
+ uid_t sc_euid; /* effective user id */
+ gid_t sc_gid; /* real group id */
+ gid_t sc_egid; /* effective group id */
+ int sc_ngroups; /* number of supplemental groups */
+ gid_t sc_groups[1]; /* variable length */
+};
+
+/*
+ * Compute size of a sockcred structure with groups.
+ */
+#define SOCKCREDSIZE(ngrps) \
+ (sizeof(struct sockcred) + (sizeof(gid_t) * ((ngrps) - 1)))
+
+/*
+ * Definitions for network related sysctl, CTL_NET.
+ *
+ * Second level is protocol family.
+ * Third level is protocol number.
+ *
+ * Further levels are defined by the individual families below.
+ */
+#define NET_MAXID AF_MAX
+
+#define CTL_NET_NAMES { \
+ { 0, 0 }, \
+ { "unix", CTLTYPE_NODE }, \
+ { "inet", CTLTYPE_NODE }, \
+ { "implink", CTLTYPE_NODE }, \
+ { "pup", CTLTYPE_NODE }, \
+ { "chaos", CTLTYPE_NODE }, \
+ { "xerox_ns", CTLTYPE_NODE }, \
+ { "iso", CTLTYPE_NODE }, \
+ { "emca", CTLTYPE_NODE }, \
+ { "datakit", CTLTYPE_NODE }, \
+ { "ccitt", CTLTYPE_NODE }, \
+ { "ibm_sna", CTLTYPE_NODE }, \
+ { "decnet", CTLTYPE_NODE }, \
+ { "dec_dli", CTLTYPE_NODE }, \
+ { "lat", CTLTYPE_NODE }, \
+ { "hylink", CTLTYPE_NODE }, \
+ { "appletalk", CTLTYPE_NODE }, \
+ { "route", CTLTYPE_NODE }, \
+ { "link_layer", CTLTYPE_NODE }, \
+ { "xtp", CTLTYPE_NODE }, \
+ { "coip", CTLTYPE_NODE }, \
+ { "cnt", CTLTYPE_NODE }, \
+ { "rtip", CTLTYPE_NODE }, \
+ { "ipx", CTLTYPE_NODE }, \
+ { "inet6", CTLTYPE_NODE }, \
+ { "pip", CTLTYPE_NODE }, \
+ { "isdn", CTLTYPE_NODE }, \
+ { "natm", CTLTYPE_NODE }, \
+ { "encap", CTLTYPE_NODE }, \
+ { "sip", CTLTYPE_NODE }, \
+ { "key", CTLTYPE_NODE }, \
+}
+
+/*
+ * PF_ROUTE - Routing table
+ *
+ * Three additional levels are defined:
+ * Fourth: address family, 0 is wildcard
+ * Fifth: type of info, defined below
+ * Sixth: flag(s) to mask with for NET_RT_FLAGS
+ */
+#define NET_RT_DUMP 1 /* dump; may limit to a.f. */
+#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */
+#define NET_RT_IFLIST 3 /* survey interface list */
+#define NET_RT_MAXID 4
+
+#define CTL_NET_RT_NAMES { \
+ { 0, 0 }, \
+ { "dump", CTLTYPE_STRUCT }, \
+ { "flags", CTLTYPE_STRUCT }, \
+ { "iflist", CTLTYPE_STRUCT }, \
+}
+
+/*
+ * Maximum queue length specifiable by listen(2).
+ */
+#define SOMAXCONN 128
+
+/*
+ * Message header for recvmsg and sendmsg calls.
+ * Used value-result for recvmsg, value only for sendmsg.
+ */
+struct msghdr {
+ caddr_t msg_name; /* optional address */
+ socklen_t msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ u_int msg_iovlen; /* # elements in msg_iov */
+ caddr_t msg_control; /* ancillary data, see below */
+ socklen_t msg_controllen; /* ancillary data buffer len */
+ int msg_flags; /* flags on received message */
+};
+
+#define MSG_OOB 0x1 /* process out-of-band data */
+#define MSG_PEEK 0x2 /* peek at incoming message */
+#define MSG_DONTROUTE 0x4 /* send without using routing tables */
+#define MSG_EOR 0x8 /* data completes record */
+#define MSG_TRUNC 0x10 /* data discarded before delivery */
+#define MSG_CTRUNC 0x20 /* control data lost before delivery */
+#define MSG_WAITALL 0x40 /* wait for full request or error */
+#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
+#define MSG_BCAST 0x100 /* this message rec'd as broadcast */
+#define MSG_MCAST 0x200 /* this message rec'd as multicast */
+
+/*
+ * Header for ancillary data objects in msg_control buffer.
+ * Used for additional information with/about a datagram
+ * not expressible by flags. The format is a sequence
+ * of message elements headed by cmsghdr structures.
+ */
+struct cmsghdr {
+ socklen_t cmsg_len; /* data byte count, including hdr */
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+/* followed by u_char cmsg_data[]; */
+};
+
+/* given pointer to struct cmsghdr, return pointer to data */
+#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
+
+/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
+#define CMSG_NXTHDR(mhdr, cmsg) \
+ (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
+ (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
+ (struct cmsghdr *)NULL : \
+ (struct cmsghdr *)((caddr_t)(cmsg) + CMSG_ALIGN((cmsg)->cmsg_len)))
+
+#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
+
+/* Round len up to next alignment boundary */
+#define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
+
+/* Length of the contents of a control message of length len */
+#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
+
+/* Length of the space taken up by a padded control message of length len */
+#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
+
+/* "Socket"-level control message types: */
+#define SCM_RIGHTS 0x01 /* access rights (array of int) */
+#define SCM_CREDS 0x02 /* credientials (struct sockcred) */
+
+/*
+ * 4.3 compat sockaddr, move to compat file later
+ */
+struct osockaddr {
+ u_short sa_family; /* address family */
+ char sa_data[14]; /* up to 14 bytes of direct address */
+};
+
+/*
+ * 4.3-compat message header (move to compat file later).
+ */
+struct omsghdr {
+ caddr_t msg_name; /* optional address */
+ int msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ caddr_t msg_accrights; /* access rights sent/received */
+ int msg_accrightslen;
+};
+
+#define SA_LEN(x) ((x)->sa_len)
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int accept __P((int, struct sockaddr *, socklen_t *));
+int bind __P((int, const struct sockaddr *, socklen_t));
+int connect __P((int, const struct sockaddr *, socklen_t));
+int getpeername __P((int, struct sockaddr *, socklen_t *));
+int getsockname __P((int, struct sockaddr *, socklen_t *));
+int getsockopt __P((int, int, int, void *, socklen_t *));
+int listen __P((int, int));
+ssize_t recv __P((int, void *, size_t, int));
+ssize_t recvfrom __P((int, void *, size_t, int, struct sockaddr *, socklen_t *));
+ssize_t recvmsg __P((int, struct msghdr *, int));
+ssize_t send __P((int, const void *, size_t, int));
+ssize_t sendto __P((int, const void *,
+ size_t, int, const struct sockaddr *, socklen_t));
+ssize_t sendmsg __P((int, const struct msghdr *, int));
+int setsockopt __P((int, int, int, const void *, socklen_t));
+int shutdown __P((int, int));
+int socket __P((int, int, int));
+int socketpair __P((int, int, int, int *));
+__END_DECLS
+#else
+# if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_LINUX) || \
+ defined(COMPAT_HPUX) || defined(COMPAT_FREEBSD)
+# define COMPAT_OLDSOCK
+# define MSG_COMPAT 0x8000
+# endif
+
+void pfctlinput __P((int, struct sockaddr *));
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_SOCKET_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/socketvar.h b/ecos/packages/net/tcpip/current/include/sys/socketvar.h
new file mode 100644
index 0000000..4f63689
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/socketvar.h
@@ -0,0 +1,338 @@
+//==========================================================================
+//
+// include/sys/socketvar.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: socketvar.h,v 1.17 1999/12/08 06:50:24 itojun Exp $ */
+/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)socketvar.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _SYS_SOCKETVAR_H_
+#define _SYS_SOCKETVAR_H_
+
+#include <sys/bsdselect.h> /* for struct selinfo */
+
+/*
+ * Kernel structure per socket.
+ * Contains send and receive buffer queues,
+ * handle on protocol and pointer to protocol
+ * private data and error information.
+ */
+struct socket {
+ short so_type; /* generic type, see socket.h */
+ short so_options; /* from socket call, see socket.h */
+ short so_linger; /* time to linger while closing */
+ short so_state; /* internal state flags SS_*, below */
+ void *so_pcb; /* protocol control block */
+ struct protosw *so_proto; /* protocol handle */
+/*
+ * Variables for connection queueing.
+ * Socket where accepts occur is so_head in all subsidiary sockets.
+ * If so_head is 0, socket is not related to an accept.
+ * For head socket so_q0 queues partially completed connections,
+ * while so_q is a queue of connections ready to be accepted.
+ * If a connection is aborted and it has so_head set, then
+ * it has to be pulled out of either so_q0 or so_q.
+ * We allow connections to queue up based on current queue lengths
+ * and limit on number of queued connections for this socket.
+ */
+ struct socket *so_head; /* back pointer to accept socket */
+ struct socket *so_q0; /* queue of partial connections */
+ struct socket *so_q; /* queue of incoming connections */
+ short so_q0len; /* partials on so_q0 */
+ short so_qlen; /* number of connections on so_q */
+ short so_qlimit; /* max number queued connections */
+ short so_timeo; /* connection timeout */
+ u_short so_error; /* error affecting connection */
+ pid_t so_pgid; /* pgid for signals */
+ uid_t so_siguid; /* uid of process who set so_pgid */
+ uid_t so_sigeuid; /* euid of process who set so_pgid */
+ u_long so_oobmark; /* chars to oob mark */
+/*
+ * Variables for socket buffering.
+ */
+ struct sockbuf {
+ u_long sb_cc; /* actual chars in buffer */
+ u_long sb_hiwat; /* max actual char count */
+ u_long sb_mbcnt; /* chars of mbufs used */
+ u_long sb_mbmax; /* max chars of mbufs to use */
+ long sb_lowat; /* low water mark */
+ struct mbuf *sb_mb; /* the mbuf chain */
+ struct selinfo sb_sel; /* process selecting read/write */
+ short sb_flags; /* flags, see below */
+ short sb_timeo; /* timeout for read/write */
+ } so_rcv, so_snd;
+#define SB_MAX (256*1024) /* default for max chars in sockbuf */
+#define SB_LOCK 0x01 /* lock on data queue */
+#define SB_WANT 0x02 /* someone is waiting to lock */
+#define SB_WAIT 0x04 /* someone is waiting for data/space */
+#define SB_SEL 0x08 /* someone is selecting */
+#define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
+#define SB_NOINTR 0x40 /* operations not interruptible */
+
+ void *so_internal; /* Space for svr4 stream data */
+ void (*so_upcall) __P((struct socket *so, caddr_t arg, int waitf));
+ caddr_t so_upcallarg; /* Arg for above */
+ uid_t so_euid; /* who opened the socket */
+ uid_t so_ruid; /* who opened the socket */
+};
+
+/*
+ * Socket state bits.
+ */
+#define SS_NOFDREF 0x001 /* no file table ref any more */
+#define SS_ISCONNECTED 0x002 /* socket connected to a peer */
+#define SS_ISCONNECTING 0x004 /* in process of connecting to peer */
+#define SS_ISDISCONNECTING 0x008 /* in process of disconnecting */
+#define SS_CANTSENDMORE 0x010 /* can't send more data to peer */
+#define SS_CANTRCVMORE 0x020 /* can't receive more data from peer */
+#define SS_RCVATMARK 0x040 /* at mark on input */
+#define SS_ISDISCONNECTED 0x800 /* socket disconnected from peer */
+
+#define SS_PRIV 0x080 /* privileged for broadcast, raw... */
+#define SS_NBIO 0x100 /* non-blocking ops */
+#define SS_ASYNC 0x200 /* async i/o notify */
+#define SS_ISCONFIRMING 0x400 /* deciding to accept connection req */
+#define SS_CONNECTOUT 0x1000 /* connect, not accept, at this end */
+
+/*
+ * Macros for sockets and socket buffering.
+ */
+
+/*
+ * Do we need to notify the other side when I/O is possible?
+ */
+#define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT|SB_SEL|SB_ASYNC)) != 0)
+
+/*
+ * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
+ * This is problematical if the fields are unsigned, as the space might
+ * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
+ * overflow and return 0. Should use "lmin" but it doesn't exist now.
+ */
+#define sbspace(sb) \
+ ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
+ (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
+
+/* do we have to send all at once on a socket? */
+#define sosendallatonce(so) \
+ ((so)->so_proto->pr_flags & PR_ATOMIC)
+
+/* can we read something from so? */
+#define soreadable(so) \
+ ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
+ ((so)->so_state & SS_CANTRCVMORE) || \
+ (so)->so_qlen || (so)->so_error)
+
+/* can we write something to so? */
+#define sowriteable(so) \
+ ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
+ (((so)->so_state&SS_ISCONNECTED) || \
+ ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
+ ((so)->so_state & SS_CANTSENDMORE) || \
+ (so)->so_error)
+
+/* adjust counters in sb reflecting allocation of m */
+#define sballoc(sb, m) { \
+ (sb)->sb_cc += (m)->m_len; \
+ (sb)->sb_mbcnt += MSIZE; \
+ if ((m)->m_flags & M_EXT) \
+ (sb)->sb_mbcnt += (m)->m_ext.ext_size; \
+}
+
+/* adjust counters in sb reflecting freeing of m */
+#define sbfree(sb, m) { \
+ (sb)->sb_cc -= (m)->m_len; \
+ (sb)->sb_mbcnt -= MSIZE; \
+ if ((m)->m_flags & M_EXT) \
+ (sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
+}
+
+/*
+ * Set lock on sockbuf sb; sleep if lock is already held.
+ * Unless SB_NOINTR is set on sockbuf, sleep is interruptible.
+ * Returns error without lock if sleep is interrupted.
+ */
+#ifdef __ECOS
+extern int sblock(struct sockbuf *sb, int wf);
+extern void sbunlock(struct sockbuf *sb);
+#else
+#define sblock(sb, wf) ((sb)->sb_flags & SB_LOCK ? \
+ (((wf) == M_WAITOK) ? sb_lock(sb) : EWOULDBLOCK) : \
+ ((sb)->sb_flags |= SB_LOCK), 0)
+
+/* release lock on sockbuf sb */
+#define sbunlock(sb) { \
+ (sb)->sb_flags &= ~SB_LOCK; \
+ if ((sb)->sb_flags & SB_WANT) { \
+ (sb)->sb_flags &= ~SB_WANT; \
+ wakeup((caddr_t)&(sb)->sb_flags); \
+ } \
+}
+#endif
+
+#define sorwakeup(so) { sowakeup((so), &(so)->so_rcv); \
+ if ((so)->so_upcall) \
+ (*((so)->so_upcall))((so), (so)->so_upcallarg, M_DONTWAIT); \
+ }
+
+#define sowwakeup(so) sowakeup((so), &(so)->so_snd)
+
+#ifdef _KERNEL
+u_long sb_max;
+/* to catch callers missing new second argument to sonewconn: */
+#define sonewconn(head, connstatus) sonewconn1((head), (connstatus))
+struct socket *sonewconn1 __P((struct socket *head, int connstatus));
+
+/* strings for sleep message: */
+extern char netio[], netcon[], netcls[];
+
+struct mbuf;
+struct sockaddr;
+struct proc;
+struct msghdr;
+struct stat;
+
+/*
+ * File operations on sockets.
+ */
+#ifdef __ECOS
+int soo_read __P((struct file *fp, struct uio *uio));
+int soo_write __P((struct file *fp, struct uio *uio));
+int soo_ioctl __P((struct file *fp, CYG_ADDRWORD cmd, CYG_ADDRWORD data));
+int soo_select __P((struct file *fp, int which));
+int soo_close __P((struct file *fp));
+#else
+int soo_read __P((struct file *fp, struct uio *uio, struct ucred *cred));
+int soo_write __P((struct file *fp, struct uio *uio, struct ucred *cred));
+int soo_ioctl __P((struct file *fp, u_long cmd, caddr_t data,
+ struct proc *p));
+int soo_select __P((struct file *fp, int which, struct proc *p));
+int soo_close __P((struct file *fp, struct proc *p));
+#endif
+
+int soo_stat __P((struct socket *, struct stat *));
+int uipc_usrreq __P((struct socket *, int , struct mbuf *,
+ struct mbuf *, struct mbuf *));
+void sbappend __P((struct sockbuf *sb, struct mbuf *m));
+int sbappendaddr __P((struct sockbuf *sb, struct sockaddr *asa,
+ struct mbuf *m0, struct mbuf *control));
+int sbappendcontrol __P((struct sockbuf *sb, struct mbuf *m0,
+ struct mbuf *control));
+void sbappendrecord __P((struct sockbuf *sb, struct mbuf *m0));
+void sbcheck __P((struct sockbuf *sb));
+void sbcompress __P((struct sockbuf *sb, struct mbuf *m, struct mbuf *n));
+struct mbuf *
+ sbcreatecontrol __P((caddr_t p, int size, int type, int level));
+void sbdrop __P((struct sockbuf *sb, int len));
+void sbdroprecord __P((struct sockbuf *sb));
+void sbflush __P((struct sockbuf *sb));
+void sbinsertoob __P((struct sockbuf *sb, struct mbuf *m0));
+void sbrelease __P((struct sockbuf *sb));
+int sbreserve __P((struct sockbuf *sb, u_long cc));
+int sbwait __P((struct sockbuf *sb));
+int sb_lock __P((struct sockbuf *sb));
+int soabort __P((struct socket *so));
+int soaccept __P((struct socket *so, struct mbuf *nam));
+int sobind __P((struct socket *so, struct mbuf *nam));
+void socantrcvmore __P((struct socket *so));
+void socantsendmore __P((struct socket *so));
+int soclose __P((struct socket *so));
+int soconnect __P((struct socket *so, struct mbuf *nam));
+int soconnect2 __P((struct socket *so1, struct socket *so2));
+int socreate __P((int dom, struct socket **aso, int type, int proto));
+int sodisconnect __P((struct socket *so));
+void sofree __P((struct socket *so));
+int sogetopt __P((struct socket *so, int level, int optname,
+ struct mbuf **mp));
+void sohasoutofband __P((struct socket *so));
+void soisconnected __P((struct socket *so));
+void soisconnecting __P((struct socket *so));
+void soisdisconnected __P((struct socket *so));
+void soisdisconnecting __P((struct socket *so));
+int solisten __P((struct socket *so, int backlog));
+struct socket *
+ sonewconn1 __P((struct socket *head, int connstatus));
+void soqinsque __P((struct socket *head, struct socket *so, int q));
+int soqremque __P((struct socket *so, int q));
+int soreceive __P((struct socket *so, struct mbuf **paddr, struct uio *uio,
+ struct mbuf **mp0, struct mbuf **controlp, int *flagsp));
+int soreserve __P((struct socket *so, u_long sndcc, u_long rcvcc));
+void sorflush __P((struct socket *so));
+int sosend __P((struct socket *so, struct mbuf *addr, struct uio *uio,
+ struct mbuf *top, struct mbuf *control, int flags));
+int sosetopt __P((struct socket *so, int level, int optname,
+ struct mbuf *m0));
+int soshutdown __P((struct socket *so, int how));
+void sowakeup __P((struct socket *so, struct sockbuf *sb));
+int sockargs __P((struct mbuf **, caddr_t, socklen_t, int));
+
+#ifdef __ECOS
+int sendit __P((int, struct msghdr *, int, register_t *));
+int recvit __P((int, struct msghdr *, caddr_t, register_t *));
+#else
+int sendit __P((struct proc *, int, struct msghdr *, int, register_t *));
+int recvit __P((struct proc *, int, struct msghdr *, caddr_t,
+ register_t *));
+#endif
+#endif /* _KERNEL */
+
+#endif // _SYS_SOCKETVAR_H_
diff --git a/ecos/packages/net/tcpip/current/include/sys/sockio.h b/ecos/packages/net/tcpip/current/include/sys/sockio.h
new file mode 100644
index 0000000..211e501
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/sockio.h
@@ -0,0 +1,179 @@
+//==========================================================================
+//
+// include/sys/sockio.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: sockio.h,v 1.10 1999/12/08 06:50:24 itojun Exp $ */
+/* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)sockio.h 8.1 (Berkeley) 3/28/94
+ */
+
+#ifndef _SYS_SOCKIO_H_
+#define _SYS_SOCKIO_H_
+
+#include <sys/ioccom.h>
+
+/* Socket ioctl's. */
+#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
+#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
+#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
+#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
+#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
+#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
+#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
+
+#ifdef __ECOS
+#define SIOCADDRT _IOW('r', 10, struct ecos_rtentry) /* add route */
+#define SIOCDELRT _IOW('r', 11, struct ecos_rtentry) /* delete route */
+#else
+#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
+#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
+#endif
+
+#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
+#define OSIOCGIFADDR _IOWR('i', 13, struct ifreq) /* get ifnet address */
+#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */
+#define SIOCGIFHWADDR _IOWR('i', 15, struct ifreq) /* get MAC address */
+#ifdef __ECOS
+#define SIOCSIFHWADDR _IOW('i',101, struct ifreq) /* set MAC address */
+/* NB these two take a struct ifreq followed by the useful data */
+#define SIOCGIFSTATSUD _IOWR('i',102, struct ifreq) /* get uptodate if stats */
+#define SIOCGIFSTATS _IOWR('i',103, struct ifreq) /* get interface stats */
+#endif
+#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
+#define OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) /* get p-p address */
+#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */
+#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */
+#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */
+#define OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq) /* get broadcast addr */
+#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */
+#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */
+#define OSIOCGIFCONF _IOWR('i', 20, struct ifconf) /* get ifnet list */
+#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */
+#define OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq) /* get net addr mask */
+#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */
+#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */
+#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */
+#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */
+#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */
+#define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */
+#define SIOCGIFDATA _IOWR('i', 27, struct ifreq) /* get if_data */
+
+/* KAME IPv6 */
+/* SIOCAIFALIAS? */
+#define SIOCALIFADDR _IOW('i', 28, struct if_laddrreq) /* add IF addr */
+#define SIOCGLIFADDR _IOWR('i', 29, struct if_laddrreq) /* get IF addr */
+#define SIOCDLIFADDR _IOW('i', 30, struct if_laddrreq) /* delete IF addr */
+
+#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
+#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */
+#define SIOCGETVIFCNT _IOWR('u', 51, struct sioc_vif_req)/* vif pkt cnt */
+#define SIOCGETSGCNT _IOWR('u', 52, struct sioc_sg_req) /* sg pkt cnt */
+
+#define SIOCSIFMEDIA _IOWR('i', 53, struct ifreq) /* set net media */
+#define SIOCGIFMEDIA _IOWR('i', 54, struct ifmediareq) /* get net media */
+
+#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */
+#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */
+#define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) /* get gif pdst addr */
+
+#define SIOCBRDGADD _IOWR('i', 60, struct ifbreq) /* add bridge ifs */
+#define SIOCBRDGDEL _IOWR('i', 61, struct ifbreq) /* del bridge ifs */
+#define SIOCBRDGGIFFLGS _IOWR('i', 62, struct ifbreq) /* get brdg if flags */
+#define SIOCBRDGSIFFLGS _IOWR('i', 63, struct ifbreq) /* set brdg if flags */
+#define SIOCBRDGSCACHE _IOWR('i', 64, struct ifbcachereq) /* set cache size */
+#define SIOCBRDGGCACHE _IOWR('i', 65, struct ifbcachereq) /* get cache size */
+#define SIOCBRDGADDS _IOW('i', 65, struct ifbreq) /* add span port */
+#define SIOCBRDGIFS _IOWR('i', 66, struct ifbreq) /* get member ifs */
+#define SIOCBRDGDELS _IOW('i', 66, struct ifbreq) /* del span port */
+#define SIOCBRDGRTS _IOWR('i', 67, struct ifbaconf) /* get addresses */
+#define SIOCBRDGSADDR _IOWR('i', 68, struct ifbareq) /* set addr flags */
+#define SIOCBRDGSTO _IOWR('i', 69, struct ifbcachetoreq) /* cache timeout */
+#define SIOCBRDGGTO _IOWR('i', 70, struct ifbcachetoreq) /* cache timeout */
+#define SIOCBRDGDADDR _IOWR('i', 71, struct ifbareq) /* delete addr */
+#define SIOCBRDGFLUSH _IOWR('i', 72, struct ifbreq) /* flush addr cache */
+
+#define SIOCBRDGARL _IOWR('i', 77, struct ifbrlreq) /* add bridge rule */
+#define SIOCBRDGFRL _IOWR('i', 78, struct ifbrlreq) /* flush brdg rules */
+#define SIOCBRDGGRL _IOWR('i', 79, struct ifbrlconf)/* get bridge rules */
+
+#define SIOCBRDGGPRI _IOWR('i', 80, struct ifbrparam) /* get priority */
+#define SIOCBRDGSPRI _IOW('i', 80, struct ifbrparam) /* set priority */
+#define SIOCBRDGGHT _IOWR('i', 81, struct ifbrparam) /* get hello time */
+#define SIOCBRDGSHT _IOW('i', 81, struct ifbrparam) /* set hello time */
+#define SIOCBRDGGFD _IOWR('i', 82, struct ifbrparam) /* get forward delay */
+#define SIOCBRDGSFD _IOW('i', 82, struct ifbrparam) /* set forward delay */
+#define SIOCBRDGGMA _IOWR('i', 83, struct ifbrparam) /* get max age */
+#define SIOCBRDGSMA _IOW('i', 83, struct ifbrparam) /* set max age */
+#define SIOCBRDGSIFPRIO _IOWR('i', 84, struct ifbreq) /* set if priority */
+#define SIOCBRDGSIFCOST _IOWR('i', 85, struct ifbreq) /* set if cost */
+
+#define SIOCSIFMTU _IOW('i', 127, struct ifreq) /* set ifnet mtu */
+#define SIOCGIFMTU _IOWR('i', 126, struct ifreq) /* get ifnet mtu */
+#define SIOCSIFASYNCMAP _IOW('i', 125, struct ifreq) /* set ppp asyncmap */
+#define SIOCGIFASYNCMAP _IOWR('i', 124, struct ifreq) /* get ppp asyncmap */
+
+#ifdef __ECOS
+#define FIONBIO _IOW('s', 80, int) /* set non-blocking I/O */
+#define FIOASYNC _IOW('s', 81, int) /* set async I/O */
+#define FIONREAD _IOR('s', 82, int) /* get number of avail chars */
+#endif
+
+#endif /* !_SYS_SOCKIO_H_ */
diff --git a/ecos/packages/net/tcpip/current/include/sys/syscallargs.h b/ecos/packages/net/tcpip/current/include/sys/syscallargs.h
new file mode 100644
index 0000000..b1a3872
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/syscallargs.h
@@ -0,0 +1,1411 @@
+//==========================================================================
+//
+// include/sys/syscallargs.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: syscallargs.h,v 1.41 1999/08/08 00:32:22 niklas Exp $ */
+
+/*
+ * System call argument lists.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * created from; OpenBSD: syscalls.master,v 1.37 1999/06/07 07:17:42 deraadt Exp
+ */
+
+#ifndef _SYS_SYSCALLARGS_H_
+#define _SYS_SYSCALLARGS_H_
+
+#define syscallarg(x) union { x datum; register_t pad; }
+
+#ifdef __ECOS
+#define SYSCALLARG(a,t) a.t.datum
+#endif
+
+#ifndef __ECOS
+struct sys_exit_args {
+ syscallarg(int) rval;
+};
+#endif
+
+struct sys_read_args {
+ syscallarg(int) fd;
+ syscallarg(void *) buf;
+ syscallarg(size_t) nbyte;
+};
+extern int sys_read(struct sys_read_args *, register_t *);
+
+struct sys_write_args {
+ syscallarg(int) fd;
+ syscallarg(const void *) buf;
+ syscallarg(size_t) nbyte;
+};
+extern int sys_write(struct sys_write_args *, register_t *);
+
+struct sys_open_args {
+ syscallarg(const char *) path;
+ syscallarg(int) flags;
+ syscallarg(int) mode;
+};
+
+struct sys_close_args {
+ syscallarg(int) fd;
+};
+
+#ifndef __ECOS
+struct sys_wait4_args {
+ syscallarg(int) pid;
+ syscallarg(int *) status;
+ syscallarg(int) options;
+ syscallarg(struct rusage *) rusage;
+};
+
+struct compat_43_sys_creat_args {
+ syscallarg(const char *) path;
+ syscallarg(int) mode;
+};
+
+struct sys_link_args {
+ syscallarg(const char *) path;
+ syscallarg(const char *) link;
+};
+
+struct sys_unlink_args {
+ syscallarg(const char *) path;
+};
+
+struct sys_chdir_args {
+ syscallarg(const char *) path;
+};
+
+struct sys_fchdir_args {
+ syscallarg(int) fd;
+};
+
+struct sys_mknod_args {
+ syscallarg(const char *) path;
+ syscallarg(int) mode;
+ syscallarg(dev_t) dev;
+};
+
+struct sys_chmod_args {
+ syscallarg(const char *) path;
+ syscallarg(int) mode;
+};
+
+struct sys_chown_args {
+ syscallarg(const char *) path;
+ syscallarg(uid_t) uid;
+ syscallarg(gid_t) gid;
+};
+
+struct sys_obreak_args {
+ syscallarg(char *) nsize;
+};
+
+struct sys_ogetfsstat_args {
+ syscallarg(struct statfs *) buf;
+ syscallarg(long) bufsize;
+ syscallarg(int) flags;
+};
+
+struct compat_43_sys_lseek_args {
+ syscallarg(int) fd;
+ syscallarg(long) offset;
+ syscallarg(int) whence;
+};
+
+struct sys_mount_args {
+ syscallarg(const char *) type;
+ syscallarg(const char *) path;
+ syscallarg(int) flags;
+ syscallarg(void *) data;
+};
+
+struct sys_unmount_args {
+ syscallarg(const char *) path;
+ syscallarg(int) flags;
+};
+
+struct sys_setuid_args {
+ syscallarg(uid_t) uid;
+};
+
+struct sys_ptrace_args {
+ syscallarg(int) req;
+ syscallarg(pid_t) pid;
+ syscallarg(caddr_t) addr;
+ syscallarg(int) data;
+};
+
+struct sys_recvmsg_args {
+ syscallarg(int) s;
+ syscallarg(struct msghdr *) msg;
+ syscallarg(int) flags;
+};
+
+struct sys_sendmsg_args {
+ syscallarg(int) s;
+ syscallarg(const struct msghdr *) msg;
+ syscallarg(int) flags;
+};
+#endif
+
+struct sys_recvfrom_args {
+ syscallarg(int) s;
+ syscallarg(void *) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(struct sockaddr *) from;
+ syscallarg(socklen_t *) fromlenaddr;
+};
+extern int sys_recvfrom(struct sys_recvfrom_args *, register_t *);
+
+struct sys_accept_args {
+ syscallarg(int) s;
+ syscallarg(struct sockaddr *) name;
+ syscallarg(socklen_t *) anamelen;
+};
+extern int sys_accept(struct sys_accept_args *, register_t *);
+
+struct sys_getpeername_args {
+ syscallarg(int) fdes;
+ syscallarg(struct sockaddr *) asa;
+ syscallarg(int *) alen;
+};
+extern int sys_getpeername(struct sys_getpeername_args *, register_t *);
+
+struct sys_getsockname_args {
+ syscallarg(int) fdes;
+ syscallarg(struct sockaddr *) asa;
+ syscallarg(socklen_t *) alen;
+};
+extern int sys_getsockname(struct sys_getsockname_args *, register_t *);
+
+struct sys_access_args {
+ syscallarg(const char *) path;
+ syscallarg(int) flags;
+};
+
+#ifndef __ECOS
+struct sys_chflags_args {
+ syscallarg(const char *) path;
+ syscallarg(u_int) flags;
+};
+
+struct sys_fchflags_args {
+ syscallarg(int) fd;
+ syscallarg(u_int) flags;
+};
+
+struct sys_kill_args {
+ syscallarg(int) pid;
+ syscallarg(int) signum;
+};
+
+struct compat_43_sys_stat_args {
+ syscallarg(const char *) path;
+ syscallarg(struct ostat *) ub;
+};
+
+struct compat_43_sys_lstat_args {
+ syscallarg(char *) path;
+ syscallarg(struct ostat *) ub;
+};
+
+struct sys_dup_args {
+ syscallarg(int) fd;
+};
+
+struct sys_profil_args {
+ syscallarg(caddr_t) samples;
+ syscallarg(size_t) size;
+ syscallarg(u_long) offset;
+ syscallarg(u_int) scale;
+};
+
+struct sys_ktrace_args {
+ syscallarg(const char *) fname;
+ syscallarg(int) ops;
+ syscallarg(int) facs;
+ syscallarg(pid_t) pid;
+};
+
+struct sys_sigaction_args {
+ syscallarg(int) signum;
+ syscallarg(const struct sigaction *) nsa;
+ syscallarg(struct sigaction *) osa;
+};
+
+struct sys_sigprocmask_args {
+ syscallarg(int) how;
+ syscallarg(sigset_t) mask;
+};
+
+struct sys_getlogin_args {
+ syscallarg(char *) namebuf;
+ syscallarg(u_int) namelen;
+};
+
+struct sys_setlogin_args {
+ syscallarg(const char *) namebuf;
+};
+
+struct sys_acct_args {
+ syscallarg(const char *) path;
+};
+
+struct sys_sigaltstack_args {
+ syscallarg(const struct sigaltstack *) nss;
+ syscallarg(struct sigaltstack *) oss;
+};
+#endif
+
+struct sys_ioctl_args {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(void *) data;
+};
+extern int sys_ioctl(struct sys_ioctl_args *, register_t *);
+
+#ifndef __ECOS
+struct sys_reboot_args {
+ syscallarg(int) opt;
+};
+
+struct sys_revoke_args {
+ syscallarg(const char *) path;
+};
+
+struct sys_symlink_args {
+ syscallarg(const char *) path;
+ syscallarg(const char *) link;
+};
+
+struct sys_readlink_args {
+ syscallarg(const char *) path;
+ syscallarg(char *) buf;
+ syscallarg(size_t) count;
+};
+
+struct sys_execve_args {
+ syscallarg(const char *) path;
+ syscallarg(char *const *) argp;
+ syscallarg(char *const *) envp;
+};
+
+struct sys_umask_args {
+ syscallarg(int) newmask;
+};
+
+struct sys_chroot_args {
+ syscallarg(const char *) path;
+};
+
+struct compat_43_sys_fstat_args {
+ syscallarg(int) fd;
+ syscallarg(struct ostat *) sb;
+};
+
+struct compat_43_sys_getkerninfo_args {
+ syscallarg(int) op;
+ syscallarg(char *) where;
+ syscallarg(int *) size;
+ syscallarg(int) arg;
+};
+
+struct sys_omsync_args {
+ syscallarg(caddr_t) addr;
+ syscallarg(size_t) len;
+};
+
+struct sys_sbrk_args {
+ syscallarg(int) incr;
+};
+
+struct sys_sstk_args {
+ syscallarg(int) incr;
+};
+
+struct compat_43_sys_mmap_args {
+ syscallarg(caddr_t) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) prot;
+ syscallarg(int) flags;
+ syscallarg(int) fd;
+ syscallarg(long) pos;
+};
+
+struct sys_ovadvise_args {
+ syscallarg(int) anom;
+};
+
+struct sys_munmap_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+};
+
+struct sys_mprotect_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) prot;
+};
+
+struct sys_madvise_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) behav;
+};
+
+struct sys_mincore_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ syscallarg(char *) vec;
+};
+
+struct sys_getgroups_args {
+ syscallarg(int) gidsetsize;
+ syscallarg(gid_t *) gidset;
+};
+
+struct sys_setgroups_args {
+ syscallarg(int) gidsetsize;
+ syscallarg(const gid_t *) gidset;
+};
+
+struct sys_setpgid_args {
+ syscallarg(pid_t) pid;
+ syscallarg(int) pgid;
+};
+
+struct sys_setitimer_args {
+ syscallarg(int) which;
+ syscallarg(const struct itimerval *) itv;
+ syscallarg(struct itimerval *) oitv;
+};
+
+struct sys_swapon_args {
+ syscallarg(const char *) name;
+};
+
+struct sys_getitimer_args {
+ syscallarg(int) which;
+ syscallarg(struct itimerval *) itv;
+};
+
+struct compat_43_sys_gethostname_args {
+ syscallarg(char *) hostname;
+ syscallarg(u_int) len;
+};
+
+struct compat_43_sys_sethostname_args {
+ syscallarg(char *) hostname;
+ syscallarg(u_int) len;
+};
+
+struct sys_dup2_args {
+ syscallarg(int) from;
+ syscallarg(int) to;
+};
+
+struct sys_fcntl_args {
+ syscallarg(int) fd;
+ syscallarg(int) cmd;
+ syscallarg(void *) arg;
+};
+#endif
+
+struct sys_select_args {
+ syscallarg(int) nd;
+ syscallarg(fd_set *) in;
+ syscallarg(fd_set *) ou;
+ syscallarg(fd_set *) ex;
+ syscallarg(struct timeval *) tv;
+};
+extern int sys_select(struct sys_select_args *, register_t *);
+
+#ifndef __ECOS
+struct sys_fsync_args {
+ syscallarg(int) fd;
+};
+
+struct sys_setpriority_args {
+ syscallarg(int) which;
+ syscallarg(int) who;
+ syscallarg(int) prio;
+};
+#endif
+
+struct sys_socket_args {
+ syscallarg(int) domain;
+ syscallarg(int) type;
+ syscallarg(int) protocol;
+};
+extern int sys_socket(struct sys_socket_args *, register_t *);
+
+struct sys_connect_args {
+ syscallarg(int) s;
+ syscallarg(const struct sockaddr *) name;
+ syscallarg(socklen_t) namelen;
+};
+extern int sys_connect(struct sys_connect_args *, register_t *);
+
+#ifndef __ECOS
+struct compat_43_sys_accept_args {
+ syscallarg(int) s;
+ syscallarg(caddr_t) name;
+ syscallarg(int *) anamelen;
+};
+
+struct sys_getpriority_args {
+ syscallarg(int) which;
+ syscallarg(int) who;
+};
+
+struct compat_43_sys_send_args {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(int) len;
+ syscallarg(int) flags;
+};
+
+struct compat_43_sys_recv_args {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(int) len;
+ syscallarg(int) flags;
+};
+
+struct sys_sigreturn_args {
+ syscallarg(struct sigcontext *) sigcntxp;
+};
+#endif
+
+struct sys_bind_args {
+ syscallarg(int) s;
+ syscallarg(const struct sockaddr *) name;
+ syscallarg(socklen_t) namelen;
+};
+extern int sys_bind(struct sys_bind_args *, register_t *);
+
+struct sys_setsockopt_args {
+ syscallarg(int) s;
+ syscallarg(int) level;
+ syscallarg(int) name;
+ syscallarg(const void *) val;
+ syscallarg(socklen_t) valsize;
+};
+extern int sys_setsockopt(struct sys_setsockopt_args *, register_t *);
+
+struct sys_listen_args {
+ syscallarg(int) s;
+ syscallarg(int) backlog;
+};
+extern int sys_listen(struct sys_listen_args *, register_t *);
+
+#ifndef __ECOS
+struct compat_43_sys_sigvec_args {
+ syscallarg(int) signum;
+ syscallarg(struct sigvec *) nsv;
+ syscallarg(struct sigvec *) osv;
+};
+
+struct compat_43_sys_sigblock_args {
+ syscallarg(int) mask;
+};
+
+struct compat_43_sys_sigsetmask_args {
+ syscallarg(int) mask;
+};
+
+struct sys_sigsuspend_args {
+ syscallarg(int) mask;
+};
+
+struct compat_43_sys_sigstack_args {
+ syscallarg(struct sigstack *) nss;
+ syscallarg(struct sigstack *) oss;
+};
+
+struct compat_43_sys_recvmsg_args {
+ syscallarg(int) s;
+ syscallarg(struct omsghdr *) msg;
+ syscallarg(int) flags;
+};
+
+struct compat_43_sys_sendmsg_args {
+ syscallarg(int) s;
+ syscallarg(caddr_t) msg;
+ syscallarg(int) flags;
+};
+
+struct sys_vtrace_args {
+ syscallarg(int) request;
+ syscallarg(int) value;
+};
+
+struct sys_gettimeofday_args {
+ syscallarg(struct timeval *) tp;
+ syscallarg(struct timezone *) tzp;
+};
+
+struct sys_getrusage_args {
+ syscallarg(int) who;
+ syscallarg(struct rusage *) rusage;
+};
+#endif
+
+struct sys_getsockopt_args {
+ syscallarg(int) s;
+ syscallarg(int) level;
+ syscallarg(int) name;
+ syscallarg(void *) val;
+ syscallarg(socklen_t *) avalsize;
+};
+extern int sys_getsockopt(struct sys_getsockopt_args *, register_t *);
+
+struct sys_readv_args {
+ syscallarg(int) fd;
+ syscallarg(const struct iovec *) iovp;
+ syscallarg(int) iovcnt;
+};
+
+struct sys_writev_args {
+ syscallarg(int) fd;
+ syscallarg(const struct iovec *) iovp;
+ syscallarg(int) iovcnt;
+};
+
+#ifndef __ECOS
+struct sys_settimeofday_args {
+ syscallarg(const struct timeval *) tv;
+ syscallarg(const struct timezone *) tzp;
+};
+
+struct sys_fchown_args {
+ syscallarg(int) fd;
+ syscallarg(uid_t) uid;
+ syscallarg(gid_t) gid;
+};
+
+struct sys_fchmod_args {
+ syscallarg(int) fd;
+ syscallarg(int) mode;
+};
+
+struct compat_43_sys_recvfrom_args {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(caddr_t) from;
+ syscallarg(int *) fromlenaddr;
+};
+
+struct compat_43_sys_setreuid_args {
+ syscallarg(int) ruid;
+ syscallarg(int) euid;
+};
+
+struct compat_43_sys_setregid_args {
+ syscallarg(int) rgid;
+ syscallarg(int) egid;
+};
+
+struct sys_rename_args {
+ syscallarg(const char *) from;
+ syscallarg(const char *) to;
+};
+
+struct compat_43_sys_truncate_args {
+ syscallarg(const char *) path;
+ syscallarg(long) length;
+};
+
+struct compat_43_sys_ftruncate_args {
+ syscallarg(int) fd;
+ syscallarg(long) length;
+};
+
+struct sys_flock_args {
+ syscallarg(int) fd;
+ syscallarg(int) how;
+};
+
+struct sys_mkfifo_args {
+ syscallarg(const char *) path;
+ syscallarg(int) mode;
+};
+#endif
+
+struct sys_sendto_args {
+ syscallarg(int) s;
+ syscallarg(const void *) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(const struct sockaddr *) to;
+ syscallarg(socklen_t) tolen;
+};
+extern int sys_sendto(struct sys_sendto_args *, register_t *);
+
+struct sys_shutdown_args {
+ syscallarg(int) s;
+ syscallarg(int) how;
+};
+extern int sys_shutdown(struct sys_shutdown_args *, register_t *);
+
+struct sys_socketpair_args {
+ syscallarg(int) domain;
+ syscallarg(int) type;
+ syscallarg(int) protocol;
+ syscallarg(int *) rsv;
+};
+
+#ifndef __ECOS
+struct sys_mkdir_args {
+ syscallarg(const char *) path;
+ syscallarg(int) mode;
+};
+
+struct sys_rmdir_args {
+ syscallarg(const char *) path;
+};
+
+struct sys_utimes_args {
+ syscallarg(const char *) path;
+ syscallarg(const struct timeval *) tptr;
+};
+
+struct sys_adjtime_args {
+ syscallarg(const struct timeval *) delta;
+ syscallarg(struct timeval *) olddelta;
+};
+
+struct compat_43_sys_getpeername_args {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(socklen_t *) alen;
+};
+
+struct compat_43_sys_sethostid_args {
+ syscallarg(int32_t) hostid;
+};
+
+struct compat_43_sys_getrlimit_args {
+ syscallarg(int) which;
+ syscallarg(struct ogetrlimit *) rlp;
+};
+
+struct compat_43_sys_setrlimit_args {
+ syscallarg(int) which;
+ syscallarg(struct ogetrlimit *) rlp;
+};
+
+struct compat_43_sys_killpg_args {
+ syscallarg(int) pgid;
+ syscallarg(int) signum;
+};
+
+struct sys_quotactl_args {
+ syscallarg(const char *) path;
+ syscallarg(int) cmd;
+ syscallarg(int) uid;
+ syscallarg(char *) arg;
+};
+
+struct compat_43_sys_getsockname_args {
+ syscallarg(int) fdec;
+ syscallarg(caddr_t) asa;
+ syscallarg(int *) alen;
+};
+
+struct sys_nfssvc_args {
+ syscallarg(int) flag;
+ syscallarg(void *) argp;
+};
+
+struct compat_43_sys_getdirentries_args {
+ syscallarg(int) fd;
+ syscallarg(char *) buf;
+ syscallarg(int) count;
+ syscallarg(long *) basep;
+};
+
+struct sys_ostatfs_args {
+ syscallarg(const char *) path;
+ syscallarg(struct ostatfs *) buf;
+};
+
+struct sys_ofstatfs_args {
+ syscallarg(int) fd;
+ syscallarg(struct ostatfs *) buf;
+};
+
+struct sys_getfh_args {
+ syscallarg(const char *) fname;
+ syscallarg(fhandle_t *) fhp;
+};
+
+struct compat_09_sys_getdomainname_args {
+ syscallarg(char *) domainname;
+ syscallarg(int) len;
+};
+
+struct compat_09_sys_setdomainname_args {
+ syscallarg(char *) domainname;
+ syscallarg(int) len;
+};
+
+struct compat_09_sys_uname_args {
+ syscallarg(struct outsname *) name;
+};
+
+struct sys_sysarch_args {
+ syscallarg(int) op;
+ syscallarg(char *) parms;
+};
+
+struct compat_10_sys_semsys_args {
+ syscallarg(int) which;
+ syscallarg(int) a2;
+ syscallarg(int) a3;
+ syscallarg(int) a4;
+ syscallarg(int) a5;
+};
+
+struct compat_10_sys_msgsys_args {
+ syscallarg(int) which;
+ syscallarg(int) a2;
+ syscallarg(int) a3;
+ syscallarg(int) a4;
+ syscallarg(int) a5;
+ syscallarg(int) a6;
+};
+
+struct compat_10_sys_shmsys_args {
+ syscallarg(int) which;
+ syscallarg(int) a2;
+ syscallarg(int) a3;
+ syscallarg(int) a4;
+};
+
+struct sys_ntp_gettime_args {
+ syscallarg(struct ntptimeval *) ntvp;
+};
+
+struct sys_ntp_adjtime_args {
+ syscallarg(struct timex *) tp;
+};
+
+struct sys_setgid_args {
+ syscallarg(gid_t) gid;
+};
+
+struct sys_setegid_args {
+ syscallarg(gid_t) egid;
+};
+
+struct sys_seteuid_args {
+ syscallarg(uid_t) euid;
+};
+
+struct lfs_bmapv_args {
+ syscallarg(fsid_t *) fsidp;
+ syscallarg(struct block_info *) blkiov;
+ syscallarg(int) blkcnt;
+};
+
+struct lfs_markv_args {
+ syscallarg(fsid_t *) fsidp;
+ syscallarg(struct block_info *) blkiov;
+ syscallarg(int) blkcnt;
+};
+
+struct lfs_segclean_args {
+ syscallarg(fsid_t *) fsidp;
+ syscallarg(u_long) segment;
+};
+
+struct lfs_segwait_args {
+ syscallarg(fsid_t *) fsidp;
+ syscallarg(struct timeval *) tv;
+};
+
+struct sys_stat_args {
+ syscallarg(const char *) path;
+ syscallarg(struct stat *) ub;
+};
+
+struct sys_fstat_args {
+ syscallarg(int) fd;
+ syscallarg(struct stat *) sb;
+};
+
+struct sys_lstat_args {
+ syscallarg(const char *) path;
+ syscallarg(struct stat *) ub;
+};
+
+struct sys_pathconf_args {
+ syscallarg(const char *) path;
+ syscallarg(int) name;
+};
+
+struct sys_fpathconf_args {
+ syscallarg(int) fd;
+ syscallarg(int) name;
+};
+
+struct sys_swapctl_args {
+ syscallarg(int) cmd;
+ syscallarg(const void *) arg;
+ syscallarg(int) misc;
+};
+
+struct sys_getrlimit_args {
+ syscallarg(int) which;
+ syscallarg(struct rlimit *) rlp;
+};
+
+struct sys_setrlimit_args {
+ syscallarg(int) which;
+ syscallarg(const struct rlimit *) rlp;
+};
+
+struct sys_getdirentries_args {
+ syscallarg(int) fd;
+ syscallarg(char *) buf;
+ syscallarg(int) count;
+ syscallarg(long *) basep;
+};
+
+struct sys_mmap_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) prot;
+ syscallarg(int) flags;
+ syscallarg(int) fd;
+ syscallarg(long) pad;
+ syscallarg(off_t) pos;
+};
+
+struct sys_lseek_args {
+ syscallarg(int) fd;
+ syscallarg(int) pad;
+ syscallarg(off_t) offset;
+ syscallarg(int) whence;
+};
+
+struct sys_truncate_args {
+ syscallarg(const char *) path;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+};
+
+struct sys_ftruncate_args {
+ syscallarg(int) fd;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+};
+
+struct sys___sysctl_args {
+ syscallarg(int *) name;
+ syscallarg(u_int) namelen;
+ syscallarg(void *) old;
+ syscallarg(size_t *) oldlenp;
+ syscallarg(void *) new;
+ syscallarg(size_t) newlen;
+};
+
+struct sys_mlock_args {
+ syscallarg(const void *) addr;
+ syscallarg(size_t) len;
+};
+
+struct sys_munlock_args {
+ syscallarg(const void *) addr;
+ syscallarg(size_t) len;
+};
+
+struct sys_undelete_args {
+ syscallarg(const char *) path;
+};
+
+struct sys_futimes_args {
+ syscallarg(int) fd;
+ syscallarg(const struct timeval *) tptr;
+};
+
+struct sys_getpgid_args {
+ syscallarg(pid_t) pid;
+};
+
+struct sys_xfspioctl_args {
+ syscallarg(int) operation;
+ syscallarg(char *) a_pathP;
+ syscallarg(int) a_opcode;
+ syscallarg(struct ViceIoctl *) a_paramsP;
+ syscallarg(int) a_followSymlinks;
+};
+
+struct sys___osemctl_args {
+ syscallarg(int) semid;
+ syscallarg(int) semnum;
+ syscallarg(int) cmd;
+ syscallarg(union semun *) arg;
+};
+
+struct sys_semget_args {
+ syscallarg(key_t) key;
+ syscallarg(int) nsems;
+ syscallarg(int) semflg;
+};
+
+struct sys_semop_args {
+ syscallarg(int) semid;
+ syscallarg(struct sembuf *) sops;
+ syscallarg(u_int) nsops;
+};
+
+struct sys_semconfig_args {
+ syscallarg(int) flag;
+};
+
+struct sys_omsgctl_args {
+ syscallarg(int) msqid;
+ syscallarg(int) cmd;
+ syscallarg(struct omsqid_ds *) buf;
+};
+
+struct sys_msgget_args {
+ syscallarg(key_t) key;
+ syscallarg(int) msgflg;
+};
+
+struct sys_msgsnd_args {
+ syscallarg(int) msqid;
+ syscallarg(const void *) msgp;
+ syscallarg(size_t) msgsz;
+ syscallarg(int) msgflg;
+};
+
+struct sys_msgrcv_args {
+ syscallarg(int) msqid;
+ syscallarg(void *) msgp;
+ syscallarg(size_t) msgsz;
+ syscallarg(long) msgtyp;
+ syscallarg(int) msgflg;
+};
+
+struct sys_shmat_args {
+ syscallarg(int) shmid;
+ syscallarg(const void *) shmaddr;
+ syscallarg(int) shmflg;
+};
+
+struct sys_oshmctl_args {
+ syscallarg(int) shmid;
+ syscallarg(int) cmd;
+ syscallarg(struct oshmid_ds *) buf;
+};
+
+struct sys_shmdt_args {
+ syscallarg(const void *) shmaddr;
+};
+
+struct sys_shmget_args {
+ syscallarg(key_t) key;
+ syscallarg(int) size;
+ syscallarg(int) shmflg;
+};
+
+struct sys_clock_gettime_args {
+ syscallarg(clockid_t) clock_id;
+ syscallarg(struct timespec *) tp;
+};
+
+struct sys_clock_settime_args {
+ syscallarg(clockid_t) clock_id;
+ syscallarg(const struct timespec *) tp;
+};
+
+struct sys_clock_getres_args {
+ syscallarg(clockid_t) clock_id;
+ syscallarg(struct timespec *) tp;
+};
+
+struct sys_nanosleep_args {
+ syscallarg(const struct timespec *) rqtp;
+ syscallarg(struct timespec *) rmtp;
+};
+
+struct sys_minherit_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) inherit;
+};
+
+struct sys_rfork_args {
+ syscallarg(int) flags;
+};
+
+struct sys_poll_args {
+ syscallarg(struct pollfd *) fds;
+ syscallarg(unsigned long) nfds;
+ syscallarg(int) timeout;
+};
+
+struct sys_lchown_args {
+ syscallarg(const char *) path;
+ syscallarg(uid_t) uid;
+ syscallarg(gid_t) gid;
+};
+
+struct sys_getsid_args {
+ syscallarg(pid_t) pid;
+};
+
+struct sys_msync_args {
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+};
+
+struct sys___semctl_args {
+ syscallarg(int) semid;
+ syscallarg(int) semnum;
+ syscallarg(int) cmd;
+ syscallarg(union semun *) arg;
+};
+
+struct sys_shmctl_args {
+ syscallarg(int) shmid;
+ syscallarg(int) cmd;
+ syscallarg(struct shmid_ds *) buf;
+};
+
+struct sys_msgctl_args {
+ syscallarg(int) msqid;
+ syscallarg(int) cmd;
+ syscallarg(struct msqid_ds *) buf;
+};
+
+struct sys_getfsstat_args {
+ syscallarg(struct statfs *) buf;
+ syscallarg(size_t) bufsize;
+ syscallarg(int) flags;
+};
+
+struct sys_statfs_args {
+ syscallarg(const char *) path;
+ syscallarg(struct statfs *) buf;
+};
+
+struct sys_fstatfs_args {
+ syscallarg(int) fd;
+ syscallarg(struct statfs *) buf;
+};
+
+struct sys_pipe_args {
+ syscallarg(int *) fdp;
+};
+
+/*
+ * System call prototypes.
+ */
+
+int sys_exit __P((struct proc *, void *, register_t *));
+int sys_fork __P((struct proc *, void *, register_t *));
+int sys_read __P((struct proc *, void *, register_t *));
+int sys_write __P((struct proc *, void *, register_t *));
+int sys_open __P((struct proc *, void *, register_t *));
+int sys_close __P((struct proc *, void *, register_t *));
+int sys_wait4 __P((struct proc *, void *, register_t *));
+int compat_43_sys_creat __P((struct proc *, void *, register_t *));
+int sys_link __P((struct proc *, void *, register_t *));
+int sys_unlink __P((struct proc *, void *, register_t *));
+int sys_chdir __P((struct proc *, void *, register_t *));
+int sys_fchdir __P((struct proc *, void *, register_t *));
+int sys_mknod __P((struct proc *, void *, register_t *));
+int sys_chmod __P((struct proc *, void *, register_t *));
+int sys_chown __P((struct proc *, void *, register_t *));
+int sys_obreak __P((struct proc *, void *, register_t *));
+int sys_ogetfsstat __P((struct proc *, void *, register_t *));
+int compat_43_sys_lseek __P((struct proc *, void *, register_t *));
+int sys_getpid __P((struct proc *, void *, register_t *));
+int sys_mount __P((struct proc *, void *, register_t *));
+int sys_unmount __P((struct proc *, void *, register_t *));
+int sys_setuid __P((struct proc *, void *, register_t *));
+int sys_getuid __P((struct proc *, void *, register_t *));
+int sys_geteuid __P((struct proc *, void *, register_t *));
+int sys_ptrace __P((struct proc *, void *, register_t *));
+int sys_recvmsg __P((struct proc *, void *, register_t *));
+int sys_sendmsg __P((struct proc *, void *, register_t *));
+int sys_recvfrom __P((struct proc *, void *, register_t *));
+int sys_accept __P((struct proc *, void *, register_t *));
+int sys_getpeername __P((struct proc *, void *, register_t *));
+int sys_getsockname __P((struct proc *, void *, register_t *));
+int sys_access __P((struct proc *, void *, register_t *));
+int sys_chflags __P((struct proc *, void *, register_t *));
+int sys_fchflags __P((struct proc *, void *, register_t *));
+int sys_sync __P((struct proc *, void *, register_t *));
+int sys_kill __P((struct proc *, void *, register_t *));
+int compat_43_sys_stat __P((struct proc *, void *, register_t *));
+int sys_getppid __P((struct proc *, void *, register_t *));
+int compat_43_sys_lstat __P((struct proc *, void *, register_t *));
+int sys_dup __P((struct proc *, void *, register_t *));
+int sys_opipe __P((struct proc *, void *, register_t *));
+int sys_getegid __P((struct proc *, void *, register_t *));
+int sys_profil __P((struct proc *, void *, register_t *));
+#ifdef KTRACE
+int sys_ktrace __P((struct proc *, void *, register_t *));
+#else
+#endif
+int sys_sigaction __P((struct proc *, void *, register_t *));
+int sys_getgid __P((struct proc *, void *, register_t *));
+int sys_sigprocmask __P((struct proc *, void *, register_t *));
+int sys_getlogin __P((struct proc *, void *, register_t *));
+int sys_setlogin __P((struct proc *, void *, register_t *));
+int sys_acct __P((struct proc *, void *, register_t *));
+int sys_sigpending __P((struct proc *, void *, register_t *));
+int sys_sigaltstack __P((struct proc *, void *, register_t *));
+int sys_ioctl __P((struct proc *, void *, register_t *));
+int sys_reboot __P((struct proc *, void *, register_t *));
+int sys_revoke __P((struct proc *, void *, register_t *));
+int sys_symlink __P((struct proc *, void *, register_t *));
+int sys_readlink __P((struct proc *, void *, register_t *));
+int sys_execve __P((struct proc *, void *, register_t *));
+int sys_umask __P((struct proc *, void *, register_t *));
+int sys_chroot __P((struct proc *, void *, register_t *));
+int compat_43_sys_fstat __P((struct proc *, void *, register_t *));
+int compat_43_sys_getkerninfo __P((struct proc *, void *, register_t *));
+int compat_43_sys_getpagesize __P((struct proc *, void *, register_t *));
+int sys_omsync __P((struct proc *, void *, register_t *));
+int sys_vfork __P((struct proc *, void *, register_t *));
+int sys_sbrk __P((struct proc *, void *, register_t *));
+int sys_sstk __P((struct proc *, void *, register_t *));
+int compat_43_sys_mmap __P((struct proc *, void *, register_t *));
+int sys_ovadvise __P((struct proc *, void *, register_t *));
+int sys_munmap __P((struct proc *, void *, register_t *));
+int sys_mprotect __P((struct proc *, void *, register_t *));
+int sys_madvise __P((struct proc *, void *, register_t *));
+int sys_mincore __P((struct proc *, void *, register_t *));
+int sys_getgroups __P((struct proc *, void *, register_t *));
+int sys_setgroups __P((struct proc *, void *, register_t *));
+int sys_getpgrp __P((struct proc *, void *, register_t *));
+int sys_setpgid __P((struct proc *, void *, register_t *));
+int sys_setitimer __P((struct proc *, void *, register_t *));
+int compat_43_sys_wait __P((struct proc *, void *, register_t *));
+int sys_swapon __P((struct proc *, void *, register_t *));
+int sys_getitimer __P((struct proc *, void *, register_t *));
+int compat_43_sys_gethostname __P((struct proc *, void *, register_t *));
+int compat_43_sys_sethostname __P((struct proc *, void *, register_t *));
+int compat_43_sys_getdtablesize __P((struct proc *, void *, register_t *));
+int sys_dup2 __P((struct proc *, void *, register_t *));
+int sys_fcntl __P((struct proc *, void *, register_t *));
+int sys_select __P((struct proc *, void *, register_t *));
+int sys_fsync __P((struct proc *, void *, register_t *));
+int sys_setpriority __P((struct proc *, void *, register_t *));
+int sys_socket __P((struct proc *, void *, register_t *));
+int sys_connect __P((struct proc *, void *, register_t *));
+int compat_43_sys_accept __P((struct proc *, void *, register_t *));
+int sys_getpriority __P((struct proc *, void *, register_t *));
+int compat_43_sys_send __P((struct proc *, void *, register_t *));
+int compat_43_sys_recv __P((struct proc *, void *, register_t *));
+int sys_sigreturn __P((struct proc *, void *, register_t *));
+int sys_bind __P((struct proc *, void *, register_t *));
+int sys_setsockopt __P((struct proc *, void *, register_t *));
+int sys_listen __P((struct proc *, void *, register_t *));
+int compat_43_sys_sigvec __P((struct proc *, void *, register_t *));
+int compat_43_sys_sigblock __P((struct proc *, void *, register_t *));
+int compat_43_sys_sigsetmask __P((struct proc *, void *, register_t *));
+int sys_sigsuspend __P((struct proc *, void *, register_t *));
+int compat_43_sys_sigstack __P((struct proc *, void *, register_t *));
+int compat_43_sys_recvmsg __P((struct proc *, void *, register_t *));
+int compat_43_sys_sendmsg __P((struct proc *, void *, register_t *));
+#ifdef TRACE
+int sys_vtrace __P((struct proc *, void *, register_t *));
+#else
+#endif
+int sys_gettimeofday __P((struct proc *, void *, register_t *));
+int sys_getrusage __P((struct proc *, void *, register_t *));
+int sys_getsockopt __P((struct proc *, void *, register_t *));
+int sys_readv __P((struct proc *, void *, register_t *));
+int sys_writev __P((struct proc *, void *, register_t *));
+int sys_settimeofday __P((struct proc *, void *, register_t *));
+int sys_fchown __P((struct proc *, void *, register_t *));
+int sys_fchmod __P((struct proc *, void *, register_t *));
+int compat_43_sys_recvfrom __P((struct proc *, void *, register_t *));
+int compat_43_sys_setreuid __P((struct proc *, void *, register_t *));
+int compat_43_sys_setregid __P((struct proc *, void *, register_t *));
+int sys_rename __P((struct proc *, void *, register_t *));
+int compat_43_sys_truncate __P((struct proc *, void *, register_t *));
+int compat_43_sys_ftruncate __P((struct proc *, void *, register_t *));
+int sys_flock __P((struct proc *, void *, register_t *));
+int sys_mkfifo __P((struct proc *, void *, register_t *));
+int sys_sendto __P((struct proc *, void *, register_t *));
+int sys_shutdown __P((struct proc *, void *, register_t *));
+int sys_socketpair __P((struct proc *, void *, register_t *));
+int sys_mkdir __P((struct proc *, void *, register_t *));
+int sys_rmdir __P((struct proc *, void *, register_t *));
+int sys_utimes __P((struct proc *, void *, register_t *));
+int sys_adjtime __P((struct proc *, void *, register_t *));
+int compat_43_sys_getpeername __P((struct proc *, void *, register_t *));
+int compat_43_sys_gethostid __P((struct proc *, void *, register_t *));
+int compat_43_sys_sethostid __P((struct proc *, void *, register_t *));
+int compat_43_sys_getrlimit __P((struct proc *, void *, register_t *));
+int compat_43_sys_setrlimit __P((struct proc *, void *, register_t *));
+int compat_43_sys_killpg __P((struct proc *, void *, register_t *));
+int sys_setsid __P((struct proc *, void *, register_t *));
+int sys_quotactl __P((struct proc *, void *, register_t *));
+int compat_43_sys_quota __P((struct proc *, void *, register_t *));
+int compat_43_sys_getsockname __P((struct proc *, void *, register_t *));
+#if defined(NFSCLIENT) || defined(NFSSERVER)
+int sys_nfssvc __P((struct proc *, void *, register_t *));
+#else
+#endif
+int compat_43_sys_getdirentries __P((struct proc *, void *, register_t *));
+int sys_ostatfs __P((struct proc *, void *, register_t *));
+int sys_ofstatfs __P((struct proc *, void *, register_t *));
+#if defined(NFSCLIENT) || defined(NFSSERVER)
+int sys_getfh __P((struct proc *, void *, register_t *));
+#else
+#endif
+int compat_09_sys_getdomainname __P((struct proc *, void *, register_t *));
+int compat_09_sys_setdomainname __P((struct proc *, void *, register_t *));
+int compat_09_sys_uname __P((struct proc *, void *, register_t *));
+int sys_sysarch __P((struct proc *, void *, register_t *));
+#if defined(SYSVSEM) && !defined(alpha)
+int compat_10_sys_semsys __P((struct proc *, void *, register_t *));
+#else
+#endif
+#if defined(SYSVMSG) && !defined(alpha)
+int compat_10_sys_msgsys __P((struct proc *, void *, register_t *));
+#else
+#endif
+#if defined(SYSVSHM) && !defined(alpha)
+int compat_10_sys_shmsys __P((struct proc *, void *, register_t *));
+#else
+#endif
+#ifdef NTP
+int sys_ntp_gettime __P((struct proc *, void *, register_t *));
+int sys_ntp_adjtime __P((struct proc *, void *, register_t *));
+#else
+#endif
+int sys_setgid __P((struct proc *, void *, register_t *));
+int sys_setegid __P((struct proc *, void *, register_t *));
+int sys_seteuid __P((struct proc *, void *, register_t *));
+#ifdef LFS
+int lfs_bmapv __P((struct proc *, void *, register_t *));
+int lfs_markv __P((struct proc *, void *, register_t *));
+int lfs_segclean __P((struct proc *, void *, register_t *));
+int lfs_segwait __P((struct proc *, void *, register_t *));
+#else
+#endif
+int sys_stat __P((struct proc *, void *, register_t *));
+int sys_fstat __P((struct proc *, void *, register_t *));
+int sys_lstat __P((struct proc *, void *, register_t *));
+int sys_pathconf __P((struct proc *, void *, register_t *));
+int sys_fpathconf __P((struct proc *, void *, register_t *));
+int sys_swapctl __P((struct proc *, void *, register_t *));
+int sys_getrlimit __P((struct proc *, void *, register_t *));
+int sys_setrlimit __P((struct proc *, void *, register_t *));
+int sys_getdirentries __P((struct proc *, void *, register_t *));
+int sys_mmap __P((struct proc *, void *, register_t *));
+int sys_lseek __P((struct proc *, void *, register_t *));
+int sys_truncate __P((struct proc *, void *, register_t *));
+int sys_ftruncate __P((struct proc *, void *, register_t *));
+int sys___sysctl __P((struct proc *, void *, register_t *));
+int sys_mlock __P((struct proc *, void *, register_t *));
+int sys_munlock __P((struct proc *, void *, register_t *));
+int sys_undelete __P((struct proc *, void *, register_t *));
+int sys_futimes __P((struct proc *, void *, register_t *));
+int sys_getpgid __P((struct proc *, void *, register_t *));
+int sys_xfspioctl __P((struct proc *, void *, register_t *));
+#ifdef LKM
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+int sys_lkmnosys __P((struct proc *, void *, register_t *));
+#else /* !LKM */
+#endif /* !LKM */
+#ifdef SYSVSEM
+int sys___osemctl __P((struct proc *, void *, register_t *));
+int sys_semget __P((struct proc *, void *, register_t *));
+int sys_semop __P((struct proc *, void *, register_t *));
+int sys_semconfig __P((struct proc *, void *, register_t *));
+#else
+#endif
+#ifdef SYSVMSG
+int sys_omsgctl __P((struct proc *, void *, register_t *));
+int sys_msgget __P((struct proc *, void *, register_t *));
+int sys_msgsnd __P((struct proc *, void *, register_t *));
+int sys_msgrcv __P((struct proc *, void *, register_t *));
+#else
+#endif
+#ifdef SYSVSHM
+int sys_shmat __P((struct proc *, void *, register_t *));
+int sys_oshmctl __P((struct proc *, void *, register_t *));
+int sys_shmdt __P((struct proc *, void *, register_t *));
+int sys_shmget __P((struct proc *, void *, register_t *));
+#else
+#endif
+int sys_clock_gettime __P((struct proc *, void *, register_t *));
+int sys_clock_settime __P((struct proc *, void *, register_t *));
+int sys_clock_getres __P((struct proc *, void *, register_t *));
+int sys_nanosleep __P((struct proc *, void *, register_t *));
+int sys_minherit __P((struct proc *, void *, register_t *));
+int sys_rfork __P((struct proc *, void *, register_t *));
+int sys_poll __P((struct proc *, void *, register_t *));
+int sys_issetugid __P((struct proc *, void *, register_t *));
+int sys_lchown __P((struct proc *, void *, register_t *));
+int sys_getsid __P((struct proc *, void *, register_t *));
+int sys_msync __P((struct proc *, void *, register_t *));
+#ifdef SYSVSEM
+int sys___semctl __P((struct proc *, void *, register_t *));
+#else
+#endif
+#ifdef SYSVSHM
+int sys_shmctl __P((struct proc *, void *, register_t *));
+#else
+#endif
+#ifdef SYSVMSG
+int sys_msgctl __P((struct proc *, void *, register_t *));
+#else
+#endif
+int sys_getfsstat __P((struct proc *, void *, register_t *));
+int sys_statfs __P((struct proc *, void *, register_t *));
+int sys_fstatfs __P((struct proc *, void *, register_t *));
+int sys_pipe __P((struct proc *, void *, register_t *));
+#endif
+
+#endif // _SYS_SYSCALLARGS_H_
diff --git a/ecos/packages/net/tcpip/current/include/sys/time.h b/ecos/packages/net/tcpip/current/include/sys/time.h
new file mode 100644
index 0000000..775817a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/include/sys/time.h
@@ -0,0 +1,239 @@
+//==========================================================================
+//
+// include/sys/time.h
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: time.h,v 1.9 1999/12/06 19:36:42 aaron Exp $ */
+/* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)time.h 8.2 (Berkeley) 7/10/94
+ */
+
+#ifndef _SYS_TIME_H_
+#define _SYS_TIME_H_
+
+#include <sys/types.h>
+#include <time.h>
+
+#if 0 //ndef __time_t_defined
+typedef int time_t;
+# define __time_t_defined
+#endif
+
+#if 0
+
+/*
+ * Structure returned by gettimeofday(2) system call,
+ * and used in other calls.
+ */
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+
+#endif
+
+#if 0
+/*
+ * Structure defined by POSIX.1b to be like a timeval.
+ */
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
+};
+#endif
+
+#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+}
+#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+}
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+
+/* Operations on timevals. */
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp, uvp, cmp) \
+ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
+ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec))
+#define timeradd(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
+ if ((vvp)->tv_usec >= 1000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+
+/* Operations on timespecs. */
+#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0
+#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
+#define timespeccmp(tsp, usp, cmp) \
+ (((tsp)->tv_sec == (usp)->tv_sec) ? \
+ ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
+ ((tsp)->tv_sec cmp (usp)->tv_sec))
+#define timespecadd(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec >= 1000000000L) { \
+ (vsp)->tv_sec++; \
+ (vsp)->tv_nsec -= 1000000000L; \
+ } \
+ } while (0)
+#define timespecsub(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec < 0) { \
+ (vsp)->tv_sec--; \
+ (vsp)->tv_nsec += 1000000000L; \
+ } \
+ } while (0)
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+/*
+ * Getkerninfo clock information structure
+ */
+struct clockinfo {
+ int hz; /* clock frequency */
+ int tick; /* micro-seconds per hz tick */
+ int tickadj; /* clock skew rate for adjtime() */
+ int stathz; /* statistics clock frequency */
+ int profhz; /* profiling clock frequency */
+};
+
+#define CLOCK_REALTIME 0
+#define CLOCK_VIRTUAL 1
+#define CLOCK_PROF 2
+
+#define TIMER_RELTIME 0x0 /* relative timer */
+#ifndef TIMER_ABSTIME
+#define TIMER_ABSTIME 0x1 /* absolute timer */
+#endif
+
+#if defined(_KERNEL) || defined(_STANDALONE)
+int itimerfix __P((struct timeval *tv));
+int itimerdecr __P((struct itimerval *itp, int usec));
+void microtime __P((struct timeval *tv));
+void settime __P((struct timeval *tv));
+#else /* !_KERNEL */
+
+#ifndef __ECOS
+#include <time.h>
+#endif
+
+#if 0 //ndef _POSIX_SOURCE
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int adjtime __P((const struct timeval *, struct timeval *));
+int clock_getres __P((clockid_t, struct timespec *));
+int clock_gettime __P((clockid_t, struct timespec *));
+int clock_settime __P((clockid_t, const struct timespec *));
+int futimes __P((int, const struct timeval *));
+int getitimer __P((int, struct itimerval *));
+int gettimeofday __P((struct timeval *, struct timezone *));
+int nanosleep __P((const struct timespec *, struct timespec *));
+int setitimer __P((int, const struct itimerval *, struct itimerval *));
+int settimeofday __P((const struct timeval *, const struct timezone *));
+int utimes __P((const char *, const struct timeval *));
+__END_DECLS
+#endif /* !POSIX */
+
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_TIME_H_ */
diff --git a/ecos/packages/net/tcpip/current/src/ecos/init.cxx b/ecos/packages/net/tcpip/current/src/ecos/init.cxx
new file mode 100644
index 0000000..0c2c5f0
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/ecos/init.cxx
@@ -0,0 +1,59 @@
+//==========================================================================
+//
+// ecos/init.cxx
+//
+// Networking package initializer class
+//
+//==========================================================================
+// ####ECOSPDCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// Permission is granted to use, copy, modify and redistribute this
+// file.
+//
+// -------------------------------------------
+// ####ECOSPDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// Network initialization
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#define NET_INIT CYGBLD_ATTRIB_INIT_AFTER(CYG_INIT_LIBC)
+
+// This is a dummy class just so we can execute the network package
+// initialization at it's proper priority
+
+externC void cyg_net_init(void);
+
+class net_init_class {
+public:
+ net_init_class(void) {
+ cyg_net_init();
+ }
+};
+
+// And here's an instance of the class just to make the code run
+static net_init_class _net_init NET_INIT;
+
+externC void
+cyg_do_net_init(void)
+{
+}
diff --git a/ecos/packages/net/tcpip/current/src/ecos/support.c b/ecos/packages/net/tcpip/current/src/ecos/support.c
new file mode 100644
index 0000000..4bce185
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/ecos/support.c
@@ -0,0 +1,728 @@
+//==========================================================================
+//
+// ecos/support.c
+//
+// eCos wrapper and support functions
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas, hmt
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// Support routines, etc., used by network code
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netisr.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <arpa/inet.h>
+
+#include <machine/cpu.h>
+
+#include <pkgconf/net.h>
+
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/cyg_ass.h>
+
+#if !CYGPKG_NET_DRIVER_FRAMEWORK // Interface
+#error At least one network driver framework must be defined!
+#else
+#include <cyg/io/eth/netdev.h>
+
+// Define table boundaries
+CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
+CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
+
+// Used for system-wide "ticks per second"
+int hz = 100;
+int tick = 10000; // usec per "tick"
+
+volatile struct timeval mono_time;
+volatile struct timeval ktime;
+
+// Low-level network debugging
+int net_debug = 0;
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char netint_stack[STACK_SIZE];
+static cyg_thread netint_thread_data;
+static cyg_handle_t netint_thread_handle;
+
+cyg_flag_t netint_flags;
+#define NETISR_ANY 0xFFFFFFFF // Any possible bit...
+
+extern void cyg_test_exit(void); // TEMP
+void
+cyg_panic(const char *msg, ...)
+{
+ cyg_uint32 old_ints;
+ CYG_FAIL( msg );
+ HAL_DISABLE_INTERRUPTS(old_ints);
+ diag_printf("PANIC: %s\n", msg);
+ cyg_test_exit(); // FIXME
+}
+
+
+// Round a number 'n' up to a multiple of 'm'
+#define round(n,m) ((((n)+((m)-1))/(m))*(m))
+
+#define NET_MEMPOOL_SIZE round(CYGPKG_NET_MEM_USAGE/4,MSIZE)
+#define NET_MBUFS_SIZE round(CYGPKG_NET_MEM_USAGE/4,MSIZE)
+#define NET_CLUSTERS_SIZE round(CYGPKG_NET_MEM_USAGE/2,MCLBYTES)
+
+static unsigned char net_mempool_area[NET_MEMPOOL_SIZE];
+static cyg_mempool_var net_mem_pool;
+static cyg_handle_t net_mem;
+static unsigned char net_mbufs_area[NET_MBUFS_SIZE];
+static cyg_mempool_fix net_mbufs_pool;
+static cyg_handle_t net_mbufs;
+static unsigned char net_clusters_area[NET_CLUSTERS_SIZE];
+static cyg_mempool_fix net_clusters_pool;
+static cyg_handle_t net_clusters;
+static char net_clusters_refcnt[(NET_CLUSTERS_SIZE/MCLBYTES)+1];
+
+#ifdef CYGDBG_NET_TIMING_STATS
+static struct net_stats stats_malloc, stats_free,
+ stats_memcpy, stats_memset,
+ stats_mbuf_alloc, stats_mbuf_free, stats_cluster_alloc;
+extern struct net_stats stats_in_cksum;
+
+// Display a number of ticks as microseconds
+// Note: for improved calculation significance, values are kept in ticks*1000
+static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
+static long ns_per_system_clock;
+
+static void
+show_ticks_in_us(cyg_uint32 ticks)
+{
+ long long ns;
+ ns_per_system_clock = 1000000/rtc_resolution[1];
+ ns = (ns_per_system_clock * ((long long)ticks * 1000)) /
+ CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+ ns += 5; // for rounding to .01us
+ diag_printf("%7d.%02d", (int)(ns/1000), (int)((ns%1000)/10));
+}
+
+void
+show_net_stats(struct net_stats *stats, const char *title)
+{
+ int ave;
+ ave = stats->total_time / stats->count;
+ diag_printf("%s:\n", title);
+ diag_printf(" count: %6d", stats->count);
+ diag_printf(", min: ");
+ show_ticks_in_us(stats->min_time);
+ diag_printf(", max: ");
+ show_ticks_in_us(stats->max_time);
+ diag_printf(", total: ");
+ show_ticks_in_us(stats->total_time);
+ diag_printf(", ave: ");
+ show_ticks_in_us(ave);
+ diag_printf("\n");
+ // Reset stats
+ memset(stats, 0, sizeof(*stats));
+}
+
+void
+show_net_times(void)
+{
+ show_net_stats(&stats_malloc, "Net malloc");
+ show_net_stats(&stats_free, "Net free");
+ show_net_stats(&stats_mbuf_alloc, "Mbuf alloc");
+ show_net_stats(&stats_mbuf_free, "Mbuf free");
+ show_net_stats(&stats_cluster_alloc, "Cluster alloc");
+ show_net_stats(&stats_in_cksum, "Checksum");
+ show_net_stats(&stats_memcpy, "Net memcpy");
+ show_net_stats(&stats_memset, "Net memset");
+}
+#endif /* CYGDBG_NET_TIMING_STATS */
+
+void *
+cyg_net_malloc(u_long size, int type, int flags)
+{
+ void *res;
+ START_STATS();
+ if (flags & M_NOWAIT) {
+ res = cyg_mempool_var_try_alloc(net_mem, size);
+ } else {
+ res = cyg_mempool_var_alloc(net_mem, size);
+ }
+ FINISH_STATS(stats_malloc);
+ return (res);
+}
+
+void
+cyg_net_free(caddr_t addr, int type)
+{
+ START_STATS();
+ cyg_mempool_var_free(net_mem, addr);
+ FINISH_STATS(stats_free);
+}
+
+void *
+cyg_net_mbuf_alloc(int type, int flags)
+{
+ void *res;
+ START_STATS();
+ mbstat.m_mbufs++;
+ if (flags & M_NOWAIT) {
+ res = cyg_mempool_fix_try_alloc(net_mbufs);
+ } else {
+ res = cyg_mempool_fix_alloc(net_mbufs);
+ }
+ FINISH_STATS(stats_mbuf_alloc);
+ // Check that this nastiness works OK
+ CYG_ASSERT( dtom(res) == res, "dtom failed, base of mbuf" );
+ CYG_ASSERT( dtom((char *)res + MSIZE/2) == res, "dtom failed, mid mbuf" );
+ return (res);
+}
+
+void
+cyg_net_mbuf_free(caddr_t addr, int type)
+{
+ START_STATS();
+ mbstat.m_mbufs--;
+ cyg_mempool_fix_free(net_mbufs, addr);
+ FINISH_STATS(stats_mbuf_free);
+}
+
+void *
+cyg_net_cluster_alloc(void)
+{
+ void *res;
+ START_STATS();
+ res = cyg_mempool_fix_try_alloc(net_clusters);
+ FINISH_STATS(stats_cluster_alloc);
+ return res;
+}
+
+static void
+cyg_kmem_init(void)
+{
+ unsigned char *p;
+#ifdef CYGPKG_NET_DEBUG
+ diag_printf("Network stack using %d bytes for misc space\n", NET_MEMPOOL_SIZE);
+ diag_printf(" %d bytes for mbufs\n", NET_MBUFS_SIZE);
+ diag_printf(" %d bytes for mbuf clusters\n", NET_CLUSTERS_SIZE);
+#endif
+ cyg_mempool_var_create(&net_mempool_area,
+ NET_MEMPOOL_SIZE,
+ &net_mem,
+ &net_mem_pool);
+ // Align the mbufs on MSIZE boudaries so that dtom() can work.
+ p = (unsigned char *)(((long)(&net_mbufs_area) + MSIZE - 1) & ~(MSIZE-1));
+ cyg_mempool_fix_create(p,
+ ((&(net_mbufs_area[NET_MBUFS_SIZE])) - p) & ~(MSIZE-1),
+ MSIZE,
+ &net_mbufs,
+ &net_mbufs_pool);
+ cyg_mempool_fix_create(&net_clusters_area,
+ NET_CLUSTERS_SIZE,
+ MCLBYTES,
+ &net_clusters,
+ &net_clusters_pool);
+ mbutl = (struct mbuf *)&net_clusters_area;
+ mclrefcnt = net_clusters_refcnt;
+}
+
+void cyg_kmem_print_stats( void )
+{
+ cyg_mempool_info info;
+
+ diag_printf( "Network stack mbuf stats:\n" );
+ diag_printf( " mbufs %d, clusters %d, free clusters %d\n",
+ mbstat.m_mbufs, /* mbufs obtained from page pool */
+ mbstat.m_clusters, /* clusters obtained from page pool */
+ /* mbstat.m_spare, */ /* spare field */
+ mbstat.m_clfree /* free clusters */
+ );
+ diag_printf( " Failed to get %d times\n"
+ " Waited to get %d times\n"
+ " Drained queues to get %d times\n",
+ mbstat.m_drops, /* times failed to find space */
+ mbstat.m_wait, /* times waited for space */
+ mbstat.m_drain /* times drained protocols for space */
+ /* mbstat.m_mtypes[256]; type specific mbuf allocations */
+ );
+
+ cyg_mempool_var_get_info( net_mem, &info );
+ diag_printf( "Misc mpool: total %7d, free %7d, max free block %d\n",
+ info.totalmem,
+ info.freemem,
+ info.maxfree
+ );
+
+ cyg_mempool_fix_get_info( net_mbufs, &info );
+ diag_printf( "Mbufs pool: total %7d, free %7d, blocksize %4d\n",
+ info.totalmem,
+ info.freemem,
+ info.blocksize
+ );
+
+
+ cyg_mempool_fix_get_info( net_clusters, &info );
+ diag_printf( "Clust pool: total %7d, free %7d, blocksize %4d\n",
+ info.totalmem,
+ info.freemem,
+ info.blocksize
+ );
+}
+
+// This API is for our own automated network tests. It's not in any header
+// files because it's not at all supported.
+int cyg_net_get_mem_stats( int which, cyg_mempool_info *p )
+{
+ CYG_CHECK_DATA_PTR( p, "Bad pointer to mempool_info" );
+ CYG_ASSERT( 0 <= which, "Mempool selector underflow" );
+ CYG_ASSERT( 2 >=which, "Mempool selector overflow" );
+
+ if ( p )
+ switch ( which ) {
+ case 0:
+ cyg_mempool_var_get_info( net_mem, p );
+ break;
+ case 1:
+ cyg_mempool_fix_get_info( net_mbufs, p );
+ break;
+ case 2:
+ cyg_mempool_fix_get_info( net_clusters, p );
+ break;
+ default:
+ return 0;
+ }
+ return (int)p;
+}
+
+int
+cyg_mtocl(u_long x)
+{
+ int res;
+ res = (((u_long)(x) - (u_long)mbutl) >> MCLSHIFT);
+ return res;
+}
+
+struct mbuf *
+cyg_cltom(u_long x)
+{
+ struct mbuf *res;
+ res = (struct mbuf *)((caddr_t)((u_long)mbutl + ((u_long)(x) << MCLSHIFT)));
+ return res;
+}
+
+externC void
+net_memcpy(void *d, void *s, int n)
+{
+ START_STATS();
+ memcpy(d, s, n);
+ FINISH_STATS(stats_memcpy);
+}
+
+externC void
+net_memset(void *s, int v, int n)
+{
+ START_STATS();
+ memset(s, v, n);
+ FINISH_STATS(stats_memset);
+}
+
+// Rather than bring in the whole BSD 'random' code...
+int
+arc4random(void)
+{
+ cyg_uint32 res;
+ static unsigned long seed = 0xDEADB00B;
+ HAL_CLOCK_READ(&res); // Not so bad... (but often 0..N where N is small)
+ seed = ((seed & 0x007F00FF) << 7) ^
+ ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
+ (res << 13) ^ (res >> 9); // using the clock too!
+ return (int)seed;
+}
+
+void
+get_random_bytes(void *buf, size_t len)
+{
+ unsigned long ranbuf, *lp;
+ lp = (unsigned long *)buf;
+ while (len > 0) {
+ ranbuf = arc4random();
+ *lp++ = ranbuf;
+ len -= sizeof(ranbuf);
+ }
+}
+
+void
+microtime(struct timeval *tp)
+{
+ panic("microtime");
+}
+
+void
+get_mono_time(void)
+{
+ panic("get_mono_time");
+}
+
+void
+csignal(pid_t pgid, int signum, uid_t uid, uid_t euid)
+{
+ panic("csignal");
+}
+
+int
+bcmp(const void *_p1, const void *_p2, size_t len)
+{
+ int res = 0;
+ unsigned char *p1 = (unsigned char *)_p1;
+ unsigned char *p2 = (unsigned char *)_p2;
+ while (len-- > 0) {
+ res = *p1++ - *p2++;
+ if (res) break;
+ }
+ return res;
+}
+
+int
+copyout(const void *s, void *d, size_t len)
+{
+ memcpy(d, s, len);
+ return 0;
+}
+
+int
+copyin(const void *s, void *d, size_t len)
+{
+ memcpy(d, s, len);
+ return 0;
+}
+
+void
+ovbcopy(const void *s, void *d, size_t len)
+{
+ memcpy(d, s, len);
+}
+
+// ------------------------------------------------------------------------
+// THE NETWORK THREAD ITSELF
+//
+// Network software interrupt handler
+// This function is run as a separate thread to allow
+// processing of network events (mostly incoming packets)
+// at "user level" instead of at interrupt time.
+//
+static void
+cyg_netint(cyg_addrword_t param)
+{
+ cyg_flag_value_t curisr;
+ int spl;
+ while (true) {
+ curisr = cyg_flag_wait(&netint_flags, NETISR_ANY,
+ CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR);
+ spl = splsoftnet(); // Prevent any overlapping "stack" processing
+#ifdef INET
+ if (curisr & (1 << NETISR_ARP)) {
+ // Pending ARP requests
+ arpintr();
+ }
+ if (curisr & (1 << NETISR_IP)) {
+ // Pending IPv4 input
+ ipintr();
+ }
+#endif
+#ifdef INET6
+ if (curisr & (1 << NETISR_IPV6)) {
+ // Pending IPv6 input
+ ip6intr();
+ }
+#endif
+#if NBRIDGE > 0
+ if (curisr & (1 << NETISR_BRIDGE)) {
+ // Pending bridge input
+ bridgeintr();
+ }
+#endif
+ splx(spl);
+ }
+}
+
+
+// This just sets one of the pseudo-ISR bits used above.
+void
+setsoftnet(void)
+{
+ // This is called if we are out of MBUFs - it doesn't do anything, and
+ // that situation is handled OK, so don't bother with the diagnostic:
+
+ // diag_printf("setsoftnet\n");
+
+ // No need to do this because it is ignored anyway:
+ // schednetisr(NETISR_SOFTNET);
+}
+
+
+/* Update the kernel globel ktime. */
+static void
+cyg_ktime_func(cyg_handle_t alarm,cyg_addrword_t data)
+{
+ cyg_tick_count_t now = cyg_current_time();
+
+ ktime.tv_usec = (now % hz) * tick;
+ ktime.tv_sec = 1 + now / hz;
+}
+
+static void
+cyg_ktime_init(void)
+{
+ cyg_handle_t ktime_alarm_handle;
+ static cyg_alarm ktime_alarm;
+ cyg_handle_t counter;
+
+ // Do not start at 0 - net stack thinks 0 an invalid time;
+ // Have a valid time available from right now:
+ ktime.tv_usec = 0;
+ ktime.tv_sec = 1;
+
+ cyg_clock_to_counter(cyg_real_time_clock(),&counter);
+ cyg_alarm_create(counter,
+ cyg_ktime_func,
+ 0,
+ &ktime_alarm_handle,
+ &ktime_alarm);
+
+ /* We want one alarm every 10ms. */
+ cyg_alarm_initialize(ktime_alarm_handle,cyg_current_time()+1,1);
+ cyg_alarm_enable(ktime_alarm_handle);
+}
+
+//
+// Network initialization
+// This function is called during system initialization to setup the whole
+// networking environment.
+
+// Linker magic to execute this function as 'init'
+extern void cyg_do_net_init(void);
+
+extern void ifinit(void);
+extern void loopattach(int);
+extern void bridgeattach(int);
+
+// Internal init functions:
+extern void cyg_alarm_timeout_init(void);
+extern void cyg_tsleep_init(void);
+
+void
+cyg_net_init(void)
+{
+ static int _init = false;
+ cyg_netdevtab_entry_t *t;
+
+ if (_init) return;
+
+ cyg_do_net_init(); // Just forces linking in the initializer/constructor
+ // Initialize interrupt "flags"
+ cyg_flag_init(&netint_flags);
+ // Initialize timeouts and net service thread (pseudo-DSRs)
+ cyg_alarm_timeout_init();
+ // Initialize tsleep/wakeup support
+ cyg_tsleep_init();
+ // Initialize network memory system
+ cyg_kmem_init();
+ mbinit();
+ cyg_ktime_init();
+
+ // Create network background thread
+ cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY, // Priority
+ cyg_netint, // entry
+ 0, // entry parameter
+ "Network support", // Name
+ &netint_stack[0], // Stack
+ STACK_SIZE, // Size
+ &netint_thread_handle, // Handle
+ &netint_thread_data // Thread data structure
+ );
+ cyg_thread_resume(netint_thread_handle); // Start it
+
+ // Initialize all network devices
+ for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
+// diag_printf("Init device '%s'\n", t->name);
+ if (t->init(t)) {
+ t->status = CYG_NETDEVTAB_STATUS_AVAIL;
+ } else {
+ // What to do if device init fails?
+ t->status = 0; // Device not [currently] available
+ }
+ }
+ // And attach the loopback interface
+#ifdef CYGPKG_NET_NLOOP
+#if 0 < CYGPKG_NET_NLOOP
+ loopattach(0);
+#endif
+#endif
+#if NBRIDGE > 0
+ bridgeattach(0);
+#endif
+ // Start up the network processing
+ ifinit();
+ domaininit();
+
+ // Done
+ _init = true;
+}
+
+// Copyright (C) 2002 Gary Thomas
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netdb.h>
+externC void if_indextoname(int indx, char *buf, int len);
+
+typedef void pr_fun(char *fmt, ...);
+
+static void
+_mask(struct sockaddr *sa, char *buf, int _len)
+{
+ char *cp = ((char *)sa) + 4;
+ int len = sa->sa_len - 4;
+ int tot = 0;
+
+ while (len-- > 0) {
+ if (tot) *buf++ = '.';
+ buf += diag_sprintf(buf, "%d", *cp++);
+ tot++;
+ }
+
+ while (tot < 4) {
+ if (tot) *buf++ = '.';
+ buf += diag_sprintf(buf, "%d", 0);
+ tot++;
+ }
+}
+
+static void
+_show_ifp(struct ifnet *ifp, pr_fun *pr)
+{
+ struct ifaddr *ifa;
+ char addr[64], netmask[64], broadcast[64];
+
+ (*pr)("%-8s", ifp->if_xname);
+ TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+ if (ifa->ifa_addr->sa_family != AF_LINK) {
+ getnameinfo (ifa->ifa_addr, ifa->ifa_addr->sa_len, addr, sizeof(addr), 0, 0, 0);
+ getnameinfo (ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, broadcast, sizeof(broadcast), 0, 0, 0);
+ _mask(ifa->ifa_netmask, netmask, 64);
+ (*pr)("IP: %s, Broadcast: %s, Netmask: %s\n", addr, broadcast, netmask);
+ (*pr)(" ");
+ if ((ifp->if_flags & IFF_UP)) (*pr)("UP ");
+ if ((ifp->if_flags & IFF_BROADCAST)) (*pr)("BROADCAST ");
+ if ((ifp->if_flags & IFF_LOOPBACK)) (*pr)("LOOPBACK ");
+ if ((ifp->if_flags & IFF_RUNNING)) (*pr)("RUNNING ");
+ if ((ifp->if_flags & IFF_PROMISC)) (*pr)("PROMISC ");
+ if ((ifp->if_flags & IFF_MULTICAST)) (*pr)("MULTICAST ");
+ if ((ifp->if_flags & IFF_ALLMULTI)) (*pr)("ALLMULTI ");
+ (*pr)("MTU: %d, Metric: %d\n", ifp->if_mtu, ifp->if_metric);
+ (*pr)(" Rx - Packets: %d, Bytes: %d", ifp->if_data.ifi_ipackets, ifp->if_data.ifi_ibytes);
+ (*pr)(", Tx - Packets: %d, Bytes: %d\n", ifp->if_data.ifi_opackets, ifp->if_data.ifi_obytes);
+ }
+ }
+}
+
+static int
+_dumpentry(struct radix_node *rn, void *vw)
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+ struct sockaddr *dst, *gate, *netmask, *genmask;
+ char addr[32], *cp;
+ pr_fun *pr = (pr_fun *)vw;
+
+ dst = rt_key(rt);
+ gate = rt->rt_gateway;
+ netmask = rt_mask(rt);
+ genmask = rt->rt_genmask;
+ if ((rt->rt_flags & (RTF_UP | RTF_LLINFO)) == RTF_UP) {
+ if (netmask == NULL) {
+ return 0;
+ }
+ _inet_ntop(dst, addr, sizeof(addr));
+ (*pr)("%-15s ", addr);
+ if (gate != NULL) {
+ _inet_ntop(gate, addr, sizeof(addr));
+ (*pr)("%-15s ", addr);
+ } else {
+ (*pr)("%-15s ", " ");
+ }
+ if (netmask != NULL) {
+ _mask(netmask, addr, sizeof(addr));
+ (*pr)("%-15s ", addr);
+ } else {
+ (*pr)("%-15s ", " ");
+ }
+ cp = addr;
+ if ((rt->rt_flags & RTF_UP)) *cp++ = 'U';
+ if ((rt->rt_flags & RTF_GATEWAY)) *cp++ = 'G';
+ if ((rt->rt_flags & RTF_STATIC)) *cp++ = 'S';
+ if ((rt->rt_flags & RTF_DYNAMIC)) *cp++ = 'D';
+ *cp = '\0';
+ (*pr)("%-8s ", addr); // Flags
+ if_indextoname(rt->rt_ifp->if_index, addr, 64);
+ (*pr)("%-8s ", addr);
+ (*pr)("\n");
+ }
+ return 0;
+}
+
+void
+show_network_tables(pr_fun *pr)
+{
+ int i, error;
+ struct radix_node_head *rnh;
+ struct ifnet *ifp;
+
+ cyg_scheduler_lock();
+ (*pr)("Routing tables\n");
+ (*pr)("Destination Gateway Mask Flags Interface\n");
+ for (i = 1; i <= AF_MAX; i++) {
+ if ((rnh = rt_tables[i]) != NULL) {
+ error = rnh->rnh_walktree(rnh, _dumpentry, pr);
+ }
+ }
+
+ (*pr)("Interface statistics\n");
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
+ _show_ifp(ifp, pr);
+ }
+ cyg_scheduler_unlock();
+}
+
+#endif // CYGPKG_NET_DRIVER_FRAMEWORK
+
+// EOF support.c
diff --git a/ecos/packages/net/tcpip/current/src/ecos/synch.c b/ecos/packages/net/tcpip/current/src/ecos/synch.c
new file mode 100644
index 0000000..972c832
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/ecos/synch.c
@@ -0,0 +1,416 @@
+//==========================================================================
+//
+// ecos/synch.c
+//
+// eCos wrapper and synch functions
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas, hmt
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// Synch routines, etc., used by network code
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netisr.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <arpa/inet.h>
+
+#include <machine/cpu.h>
+
+#include <pkgconf/net.h>
+
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/io/eth/netdev.h>
+
+//---------------------------- splx() emulation ------------------------------
+// This contains both the SPLX stuff and tsleep/wakeup - because those must
+// be SPLX aware. They release the SPLX lock when sleeping, and reclaim it
+// (if needs be) at wakeup.
+//
+// The variable spl_state (and the associated bit patterns) is used to keep
+// track of the "splx()" level. This is an artifact of the original stack,
+// based on the BSD interrupt world (interrupts and processing could be
+// masked based on a level value, supported by hardware). This is not very
+// real-time, so the emulation uses proper eCos tools and techniques to
+// accomplish the same result. The key here is in the analysis of the
+// various "levels", why they are used, etc.
+//
+// SPL_IMP is called in order to protect internal data structures
+// short-term, primarily so that interrupt processing does not interfere
+// with them.
+//
+// SPL_CLOCK is called in order to ensure that a timestamp is valid i.e. no
+// time passes while the stamp is being taken (since it is a potentially
+// non-idempotent data structure).
+//
+// SPL_SOFTNET is used to prevent all other stack processing, including
+// interrupts (DSRs), etc.
+//
+// SPL_INTERNAL is used when running the pseudo-DSR in timeout.c - this
+// runs what should really be the network interface device's DSR, and any
+// timeout routines that are scheduled. (They are broken out into a thread
+// to isolate the network locking from the rest of the system)
+//
+// NB a thread in thi state can tsleep(); see below. Tsleep releases and
+// reclaims the locks and so on. This necessary because of the possible
+// conflict where
+// I splsoft
+// I tsleep
+// He runs, he is lower priority
+// He splsofts
+// He or something else awakens me
+// I want to run, but he has splsoft, so I wait
+// He runs and releases splsoft
+// I awaken and go.
+
+static volatile cyg_uint32 spl_state = 0;
+#define SPL_IMP 0x01
+#define SPL_NET 0x02
+#define SPL_CLOCK 0x04
+#define SPL_SOFTNET 0x08
+#define SPL_INTERNAL 0x10
+
+static cyg_mutex_t splx_mutex;
+static volatile cyg_handle_t splx_thread;
+
+
+#ifdef CYGIMPL_TRACE_SPLX
+#define SPLXARGS const char *file, const int line
+#define SPLXMOREARGS , const char *file, const int line
+#define SPLXTRACE do_sched_event(__FUNCTION__, file, line, spl_state)
+#else
+#define SPLXARGS void
+#define SPLXMOREARGS
+#define SPLXTRACE
+#endif
+
+
+static inline cyg_uint32
+spl_any( cyg_uint32 which )
+{
+ cyg_uint32 old_spl = spl_state;
+ if ( cyg_thread_self() != splx_thread ) {
+ cyg_mutex_lock( &splx_mutex );
+ old_spl = 0; // Free when we unlock this context
+ CYG_ASSERT( 0 == splx_thread, "Thread still owned" );
+ CYG_ASSERT( 0 == spl_state, "spl still set" );
+ splx_thread = cyg_thread_self();
+ }
+ CYG_ASSERT( splx_mutex.locked, "spl_any: mutex not locked" );
+ CYG_ASSERT( (cyg_handle_t)splx_mutex.owner == cyg_thread_self(),
+ "spl_any: mutex not mine" );
+ spl_state |= which;
+ return old_spl;
+}
+
+
+cyg_uint32
+cyg_splimp(SPLXARGS)
+{
+ SPLXTRACE;
+ return spl_any( SPL_IMP );
+}
+
+cyg_uint32
+cyg_splclock(SPLXARGS)
+{
+ SPLXTRACE;
+ return spl_any( SPL_CLOCK );
+}
+
+cyg_uint32
+cyg_splnet(SPLXARGS)
+{
+ SPLXTRACE;
+ return spl_any( SPL_NET );
+}
+
+cyg_uint32
+cyg_splhigh(SPLXARGS)
+{
+ SPLXTRACE;
+ // splhigh did SPLSOFTNET in the contrib, so this is the same
+ return spl_any( SPL_SOFTNET );
+}
+
+cyg_uint32
+cyg_splsoftnet(SPLXARGS)
+{
+ SPLXTRACE;
+ return spl_any( SPL_SOFTNET );
+}
+
+cyg_uint32
+cyg_splinternal(SPLXARGS)
+{
+ SPLXTRACE;
+ return spl_any( SPL_INTERNAL );
+}
+
+
+//
+// Return to a previous interrupt state/level.
+//
+void
+cyg_splx(cyg_uint32 old_state SPLXMOREARGS)
+{
+ SPLXTRACE;
+
+ CYG_ASSERT( 0 != spl_state, "No state set" );
+ CYG_ASSERT( splx_mutex.locked, "splx: mutex not locked" );
+ CYG_ASSERT( (cyg_handle_t)splx_mutex.owner == cyg_thread_self(),
+ "splx: mutex not mine" );
+
+ spl_state &= old_state;
+
+ if ( 0 == spl_state ) {
+ splx_thread = 0;
+ cyg_mutex_unlock( &splx_mutex );
+ }
+}
+
+//------------------ tsleep() and wakeup() emulation ---------------------------
+//
+// Structure used to keep track of 'tsleep' style events
+//
+struct wakeup_event {
+ void *chan;
+ cyg_sem_t sem;
+};
+static struct wakeup_event wakeup_list[CYGPKG_NET_NUM_WAKEUP_EVENTS];
+
+
+// Called to initialize structures used by timeout functions
+void
+cyg_tsleep_init(void)
+{
+ int i;
+ struct wakeup_event *ev;
+ // Create list of "wakeup event" semaphores
+ for (i = 0, ev = wakeup_list; i < CYGPKG_NET_NUM_WAKEUP_EVENTS; i++, ev++) {
+ ev->chan = 0;
+ cyg_semaphore_init(&ev->sem, 0);
+ }
+ // Initialize the mutex and thread id:
+ cyg_mutex_init( &splx_mutex );
+ splx_thread = 0;
+}
+
+
+//
+// Signal an event
+void
+cyg_wakeup(void *chan)
+{
+ int i;
+ struct wakeup_event *ev;
+ cyg_scheduler_lock(); // Ensure scan is safe
+ // NB this is broadcast semantics because a sleeper/wakee holds the
+ // slot until they exit. This avoids a race condition whereby the
+ // semaphore can get an extra post - and then the slot is freed, so the
+ // sem wait returns immediately, AOK, so the slot wasn't freed.
+ for (i = 0, ev = wakeup_list; i < CYGPKG_NET_NUM_WAKEUP_EVENTS; i++, ev++)
+ if (ev->chan == chan)
+ cyg_semaphore_post(&ev->sem);
+
+ cyg_scheduler_unlock();
+}
+
+// ------------------------------------------------------------------------
+// Wait for an event with timeout
+// tsleep(event, priority, state, timeout)
+// event - the thing to wait for
+// priority - unused
+// state - a descriptive message
+// timeout - max time (in ticks) to wait
+// returns:
+// 0 - event was "signalled"
+// ETIMEDOUT - timeout occurred
+// EINTR - thread broken out of sleep
+//
+int
+cyg_tsleep(void *chan, int pri, char *wmesg, int timo)
+{
+ int i, res = 0;
+ struct wakeup_event *ev;
+ cyg_tick_count_t sleep_time;
+ cyg_handle_t self = cyg_thread_self();
+ int old_splflags = 0; // no flags held
+
+ cyg_scheduler_lock();
+
+ // Safely find a free slot:
+ for (i = 0, ev = wakeup_list; i < CYGPKG_NET_NUM_WAKEUP_EVENTS; i++, ev++) {
+ if (ev->chan == 0) {
+ ev->chan = chan;
+ break;
+ }
+ }
+ CYG_ASSERT( i < CYGPKG_NET_NUM_WAKEUP_EVENTS, "no sleep slots" );
+ CYG_ASSERT( 1 == cyg_scheduler_read_lock(),
+ "Tsleep - called with scheduler locked" );
+ // Defensive:
+ if ( i >= CYGPKG_NET_NUM_WAKEUP_EVENTS ) {
+ cyg_scheduler_unlock();
+ return ETIMEDOUT;
+ }
+
+ // If we are the owner, then we must release the mutex when
+ // we wait.
+ if ( self == splx_thread ) {
+ old_splflags = spl_state; // Keep them for restoration
+ CYG_ASSERT( spl_state, "spl_state not set" );
+ // Also want to assert that the mutex is locked...
+ CYG_ASSERT( splx_mutex.locked, "Splx mutex not locked" );
+ CYG_ASSERT( (cyg_handle_t)splx_mutex.owner == self, "Splx mutex not mine" );
+ splx_thread = 0;
+ spl_state = 0;
+ cyg_mutex_unlock( &splx_mutex );
+ }
+
+ // Re-initialize the semaphore - it might have counted up arbitrarily
+ // in the time between a prior sleeper being signalled and them
+ // actually running.
+ cyg_semaphore_init(&ev->sem, 0);
+
+ // This part actually does the wait:
+ // As of the new kernel, we can do this without unlocking the scheduler
+ if (timo) {
+ sleep_time = cyg_current_time() + timo;
+ if (!cyg_semaphore_timed_wait(&ev->sem, sleep_time)) {
+ if( cyg_current_time() >= sleep_time )
+ res = ETIMEDOUT;
+ else
+ res = EINTR;
+ }
+ } else {
+ if (!cyg_semaphore_wait(&ev->sem) ) {
+ res = EINTR;
+ }
+ }
+
+ ev->chan = 0; // Free the slot - the wakeup call cannot do this.
+
+ if ( old_splflags ) { // restore to previous state
+ // As of the new kernel, we can do this with the scheduler locked
+ cyg_mutex_lock( &splx_mutex ); // this might wait
+ CYG_ASSERT( 0 == splx_thread, "Splx thread set in tsleep" );
+ CYG_ASSERT( 0 == spl_state, "spl_state set in tsleep" );
+ splx_thread = self; // got it now...
+ spl_state = old_splflags;
+ }
+
+ cyg_scheduler_unlock();
+ return res;
+}
+
+
+
+// ------------------------------------------------------------------------
+// DEBUGGING ROUTINES
+#ifdef CYGIMPL_TRACE_SPLX
+#undef cyg_scheduler_lock
+#undef cyg_scheduler_safe_lock
+#undef cyg_scheduler_unlock
+
+#define MAX_SCHED_EVENTS 256
+static struct _sched_event {
+ char *fun, *file;
+ int line, lock;
+} sched_event[MAX_SCHED_EVENTS];
+static int next_sched_event = 0;
+static int total_sched_events = 0;
+
+static void
+do_sched_event(char *fun, char *file, int line, int lock)
+{
+ struct _sched_event *se = &sched_event[next_sched_event];
+ if (++next_sched_event == MAX_SCHED_EVENTS) {
+ next_sched_event = 0;
+ }
+ se->fun = fun;
+ se->file = file;
+ se->line = line;
+ se->lock = lock;
+ total_sched_events++;
+}
+
+static void
+show_sched_events(void)
+{
+ int i;
+ struct _sched_event *se;
+ if (total_sched_events < MAX_SCHED_EVENTS) {
+ i = 0;
+ } else {
+ i = next_sched_event + 1;
+ if (i == MAX_SCHED_EVENTS) i = 0;
+ }
+ diag_printf("%d total scheduler events\n", total_sched_events);
+ while (i != next_sched_event) {
+ se = &sched_event[i];
+ diag_printf("%s - lock: %d, called from %s.%d\n", se->fun, se->lock, se->file, se->line);
+ if (++i == MAX_SCHED_EVENTS) i = 0;
+ }
+}
+
+#define SPLX_TRACE_DATA() cyg_scheduler_read_lock()
+
+void
+_cyg_scheduler_lock(char *file, int line)
+{
+ cyg_scheduler_lock();
+ do_sched_event(__FUNCTION__, file, line, SPLX_TRACE_DATA());
+}
+
+void
+_cyg_scheduler_safe_lock(char *file, int line)
+{
+ cyg_scheduler_safe_lock();
+ do_sched_event(__FUNCTION__, file, line, SPLX_TRACE_DATA());
+}
+
+void
+_cyg_scheduler_unlock(char *file, int line)
+{
+ cyg_scheduler_unlock();
+ do_sched_event(__FUNCTION__, file, line, SPLX_TRACE_DATA());
+}
+#endif // CYGIMPL_TRACE_SPLX
+
+// EOF synch.c
diff --git a/ecos/packages/net/tcpip/current/src/ecos/timeout.c b/ecos/packages/net/tcpip/current/src/ecos/timeout.c
new file mode 100644
index 0000000..7091b3e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/ecos/timeout.c
@@ -0,0 +1,314 @@
+//==========================================================================
+//
+// lib/timeout.c
+//
+// timeout support
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas, hmt
+// Date: 1999-02-05
+// Description: Simple timeout functions
+//####DESCRIPTIONEND####
+
+#include <sys/param.h>
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <cyg/infra/cyg_ass.h>
+
+// Timeout support
+
+void alarm_timeout_init(void);
+
+#ifndef NTIMEOUTS
+#define NTIMEOUTS 8
+#endif
+typedef struct {
+ cyg_int32 delta; // Number of "ticks" in the future for this timeout
+ timeout_fun *fun; // Function to execute when it expires
+ void *arg; // Argument to pass when it does
+} timeout_entry;
+static timeout_entry timeouts[NTIMEOUTS];
+static cyg_handle_t timeout_alarm_handle;
+static cyg_alarm timeout_alarm;
+static cyg_int32 last_delta;
+static cyg_tick_count_t last_set_time;
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char alarm_stack[STACK_SIZE];
+static cyg_thread alarm_thread_data;
+static cyg_handle_t alarm_thread_handle;
+
+static cyg_flag_t alarm_flag;
+
+// ------------------------------------------------------------------------
+// This routine exists so that this module can synchronize:
+extern cyg_uint32 cyg_splinternal(void);
+
+// ------------------------------------------------------------------------
+// CALLBACK FUNCTION
+// Called from the thread, this runs the alarm callbacks.
+// Locking is already in place when this is called.
+static void
+do_timeout(void)
+{
+ int i;
+ cyg_int32 min_delta;
+ timeout_entry *e;
+
+ CYG_ASSERT( 0 < last_delta, "last_delta underflow" );
+
+ min_delta = last_delta; // local copy
+ last_delta = -1; // flag recursive call underway
+
+ for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) {
+ if (e->delta) {
+ CYG_ASSERT( e->delta >= min_delta, "e->delta underflow" );
+ e->delta -= min_delta;
+ if (e->delta <= 0) { // Defensive
+ // Time for this item to 'fire'
+ timeout_fun *fun = e->fun;
+ void *arg = e->arg;
+ // Call it *after* cleansing the record
+ e->fun = 0;
+ e->delta = 0;
+ (*fun)(arg);
+ }
+ }
+ }
+
+ // Now scan for a new timeout *after* running all the callbacks
+ // (because they can add timeouts themselves)
+ min_delta = 0x7FFFFFFF; // Maxint
+ for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++)
+ if (e->delta)
+ if (e->delta < min_delta)
+ min_delta = e->delta;
+
+ CYG_ASSERT( 0 < min_delta, "min_delta underflow" );
+
+ if (min_delta != 0x7FFFFFFF) {
+ // Still something to do, schedule it
+ last_set_time = cyg_current_time();
+ cyg_alarm_initialize(timeout_alarm_handle, last_set_time+min_delta, 0);
+ last_delta = min_delta;
+ } else {
+ last_delta = 0; // flag no activity
+ }
+}
+
+// ------------------------------------------------------------------------
+// ALARM EVENT FUNCTION
+// This is the DSR for the alarm firing:
+static void
+do_alarm(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ cyg_flag_setbits( &alarm_flag, 1 );
+}
+
+void ecos_synch_eth_drv_dsr(void)
+{
+ cyg_flag_setbits( &alarm_flag, 2 );
+}
+
+// ------------------------------------------------------------------------
+// HANDLER THREAD ENTRY ROUTINE
+// This waits on the DSR to tell it to run:
+static void
+alarm_thread(cyg_addrword_t param)
+{
+ // This is from the logical ethernet dev; it calls those delivery
+ // functions who need attention.
+ extern void eth_drv_run_deliveries( void );
+
+ // This is from the logical ethernet dev; it tickles somehow
+ // all ethernet devices in case one is wedged.
+ extern void eth_drv_tickle_devices( void );
+
+ while ( 1 ) {
+ int spl;
+ int x;
+#ifdef CYGPKG_NET_FAST_THREAD_TICKLE_DEVS
+ cyg_tick_count_t later = cyg_current_time();
+ later += CYGNUM_NET_FAST_THREAD_TICKLE_DEVS_DELAY;
+ x = cyg_flag_timed_wait(
+ &alarm_flag,
+ -1,
+ CYG_FLAG_WAITMODE_OR | CYG_FLAG_WAITMODE_CLR,
+ later );
+#else
+ x = cyg_flag_wait(
+ &alarm_flag,
+ -1,
+ CYG_FLAG_WAITMODE_OR | CYG_FLAG_WAITMODE_CLR );
+
+ CYG_ASSERT( 3 & x, "Lost my bits" );
+#endif // CYGPKG_NET_FAST_THREAD_TICKLE_DEVS
+ CYG_ASSERT( !((~3) & x), "Extra bits" );
+
+ spl = cyg_splinternal();
+
+ CYG_ASSERT( 0 == spl, "spl nonzero" );
+
+ if ( 2 & x )
+ eth_drv_run_deliveries();
+#ifdef CYGPKG_NET_FAST_THREAD_TICKLE_DEVS
+ // This is in the else clause for "do we deliver" because the
+ // network stack might have continuous timing events anyway - so
+ // the timeout would not occur, x would be 1 every time.
+ else // Tickle the devices...
+ eth_drv_tickle_devices();
+#endif // CYGPKG_NET_FAST_THREAD_TICKLE_DEVS
+
+ if ( 1 & x )
+ do_timeout();
+
+ cyg_splx(spl);
+ }
+}
+
+// ------------------------------------------------------------------------
+// INITIALIZATION FUNCTION
+void
+cyg_alarm_timeout_init( void )
+{
+ // Init the alarm object, attached to the real time clock
+ cyg_handle_t h;
+ cyg_clock_to_counter(cyg_real_time_clock(), &h);
+ cyg_alarm_create(h, do_alarm, 0, &timeout_alarm_handle, &timeout_alarm);
+ // Init the flag of waking up
+ cyg_flag_init( &alarm_flag );
+ // Create alarm background thread to run the callbacks
+ cyg_thread_create(
+ CYGPKG_NET_FAST_THREAD_PRIORITY, // Priority
+ alarm_thread, // entry
+ 0, // entry parameter
+ "Network alarm support", // Name
+ &alarm_stack[0], // Stack
+ STACK_SIZE, // Size
+ &alarm_thread_handle, // Handle
+ &alarm_thread_data // Thread data structure
+ );
+ cyg_thread_resume(alarm_thread_handle); // Start it
+}
+
+// ------------------------------------------------------------------------
+// EXPORTED API: SET A TIMEOUT
+// This can be called from anywhere, including recursively from the timeout
+// functions themselves.
+cyg_uint32
+timeout(timeout_fun *fun, void *arg, cyg_int32 delta)
+{
+ int i;
+ timeout_entry *e;
+ cyg_uint32 stamp;
+
+ // this needs to be atomic - recursive calls from the alarm
+ // handler thread itself are allowed:
+ int spl = cyg_splinternal();
+
+ CYG_ASSERT( 0 < delta, "delta is right now, or even sooner!" );
+
+ // Renormalize delta wrt the existing set alarm, if there is one
+ if ( last_delta > 0 )
+ delta += (cyg_int32)(cyg_current_time() - last_set_time);
+ // So recorded_delta is set to either:
+ // alarm is active: delta + NOW - THEN
+ // alarm is inactive: delta
+
+ stamp = 0; // Assume no slots available
+ for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) {
+ if ((e->delta == 0) && (e->fun == 0)) {
+ // Free entry
+ e->delta = delta;
+ e->fun = fun;
+ e->arg = arg;
+ stamp = (cyg_uint32)e;
+ break;
+ }
+ }
+
+ if ( stamp && // we did add a record AND
+ (0 == last_delta || // alarm was inactive OR
+ delta < last_delta) ) { // alarm was active but later than we need
+
+ // (if last_delta is -1, this call is recursive from the handler so
+ // also do nothing in that case)
+
+ // Here, we know the new item added is sooner than that which was
+ // most recently set, if any, so we can just go and set it up.
+ if ( 0 == last_delta )
+ last_set_time = cyg_current_time();
+
+ // So we use, to set the alarm either:
+ // alarm is active: (delta + NOW - THEN) + THEN
+ // alarm is inactive: delta + NOW
+ // and in either case it is true that
+ // (recorded_delta + last_set_time) == (delta + NOW)
+ cyg_alarm_initialize(timeout_alarm_handle, last_set_time+delta, 0);
+ last_delta = delta;
+ }
+ // Otherwise, the alarm is active, AND it is set to fire sooner than we
+ // require, so when it does, that will sort out calling the item we
+ // just added. Or we didn't actually add a record, so nothing has
+ // changed.
+
+#ifdef CYGPKG_INFRA_DEBUG
+ // Do some more checking akin to that in the alarm handler:
+ if ( last_delta != -1 ) { // not a recursive call
+ cyg_tick_count_t now = cyg_current_time();
+ CYG_ASSERT( last_delta >= 0, "Bad last delta" );
+ delta = 0x7fffffff;
+ for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) {
+ if (e->delta) {
+ CYG_ASSERT( e->delta >= last_delta, "e->delta underflow" );
+ CYG_ASSERT( last_set_time + e->delta + 1000 > now,
+ "Recorded alarm not in the future!" );
+ if ( e->delta < delta )
+ delta = e->delta;
+ } else {
+ CYG_ASSERT( 0 == e->fun, "Function recorded for 0 delta" );
+ }
+ }
+ CYG_ASSERT( delta == last_delta, "We didn't pick the smallest delta!" );
+ }
+#endif
+
+ cyg_splx(spl);
+ return stamp;
+}
+
+// ------------------------------------------------------------------------
+// EXPORTED API: CANCEL A TIMEOUT
+// This can be called from anywhere, including recursively from the timeout
+// functions themselves.
+void
+untimeout(timeout_fun *fun, void * arg)
+{
+ int i;
+ timeout_entry *e;
+ int spl = cyg_splinternal();
+
+ for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) {
+ if (e->delta && (e->fun == fun) && (e->arg == arg)) {
+ e->delta = 0;
+ e->fun = 0;
+ break;
+ }
+ }
+ cyg_splx(spl);
+}
+
+// ------------------------------------------------------------------------
+
+// EOF timeout.c
diff --git a/ecos/packages/net/tcpip/current/src/lib/accept.c b/ecos/packages/net/tcpip/current/src/lib/accept.c
new file mode 100644
index 0000000..c2844e1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/accept.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/accept.c
+//
+// accept() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+accept(int s, const struct sockaddr *name, socklen_t *anamelen)
+{
+ struct sys_accept_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,name) = (struct sockaddr *)name;
+ SYSCALLARG(args,anamelen) = anamelen;
+ error = sys_accept(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return res;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/bind.c b/ecos/packages/net/tcpip/current/src/lib/bind.c
new file mode 100644
index 0000000..994bc6c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/bind.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/bind.c
+//
+// bind() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+bind(int s, const struct sockaddr *name, socklen_t namelen)
+{
+ struct sys_bind_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,name) = name;
+ SYSCALLARG(args,namelen) = namelen;
+ error = sys_bind(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/close.c b/ecos/packages/net/tcpip/current/src/lib/close.c
new file mode 100644
index 0000000..7cf8f4e
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/close.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/close.c
+//
+// close() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+close(int fd)
+{
+ int error;
+ struct file *fp;
+ if (getfp(fd, &fp))
+ return (EBADF);
+ error = (*fp->f_ops->fo_close)(fp);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ ffree(fp);
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/connect.c b/ecos/packages/net/tcpip/current/src/lib/connect.c
new file mode 100644
index 0000000..10ec5c7
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/connect.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/connect.c
+//
+// connect() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+connect(int s, const struct sockaddr *name, socklen_t namelen)
+{
+ struct sys_connect_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,name) = name;
+ SYSCALLARG(args,namelen) = namelen;
+ error = sys_connect(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/getpeername.c b/ecos/packages/net/tcpip/current/src/lib/getpeername.c
new file mode 100644
index 0000000..45eefc2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/getpeername.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/getpeername.c
+//
+// getpeername() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+getpeername(int s, const struct sockaddr *name, socklen_t *namelen)
+{
+ struct sys_getpeername_args args;
+ int res, error;
+ SYSCALLARG(args,fdes) = s;
+ SYSCALLARG(args,asa) = (struct sockaddr *)name;
+ SYSCALLARG(args,alen) = namelen;
+ error = sys_getpeername(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/getsockname.c b/ecos/packages/net/tcpip/current/src/lib/getsockname.c
new file mode 100644
index 0000000..32044f9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/getsockname.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/getsockname.c
+//
+// getsockname() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+getsockname(int s, const struct sockaddr *name, socklen_t *namelen)
+{
+ struct sys_getsockname_args args;
+ int res, error;
+ SYSCALLARG(args,fdes) = s;
+ SYSCALLARG(args,asa) = (struct sockaddr *)name;
+ SYSCALLARG(args,alen) = namelen;
+ error = sys_getsockname(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/getsockopt.c b/ecos/packages/net/tcpip/current/src/lib/getsockopt.c
new file mode 100644
index 0000000..22e2b70
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/getsockopt.c
@@ -0,0 +1,54 @@
+//==========================================================================
+//
+// lib/getsockopt.c
+//
+// getsockopt() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+getsockopt(int s, int level, int name, void *val, socklen_t *avalsize)
+{
+ struct sys_getsockopt_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,level) = level;
+ SYSCALLARG(args,name) = name;
+ SYSCALLARG(args,val) = val;
+ SYSCALLARG(args,avalsize) = avalsize;
+ error = sys_getsockopt(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/ioctl.c b/ecos/packages/net/tcpip/current/src/lib/ioctl.c
new file mode 100644
index 0000000..7af846c
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/ioctl.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/ioctl.c
+//
+// ioctl() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+ioctl(int fd, u_long cmd, void *data)
+{
+ struct sys_ioctl_args args;
+ int res, error;
+ SYSCALLARG(args,fd) = fd;
+ SYSCALLARG(args,com) = cmd;
+ SYSCALLARG(args,data) = data;
+ error = sys_ioctl(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/listen.c b/ecos/packages/net/tcpip/current/src/lib/listen.c
new file mode 100644
index 0000000..fc489da
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/listen.c
@@ -0,0 +1,51 @@
+//==========================================================================
+//
+// lib/listen.c
+//
+// listen() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+listen(int s, int backlog)
+{
+ struct sys_listen_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,backlog) = backlog;
+ error = sys_listen(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/read.c b/ecos/packages/net/tcpip/current/src/lib/read.c
new file mode 100644
index 0000000..a9d59ab
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/read.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/read.c
+//
+// read() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+read(int fd, void *buf, size_t len)
+{
+ struct sys_read_args args;
+ int res, error;
+ SYSCALLARG(args,fd) = fd;
+ SYSCALLARG(args,buf) = buf;
+ SYSCALLARG(args,nbyte) = len;
+ error = sys_read(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return res;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/recv.c b/ecos/packages/net/tcpip/current/src/lib/recv.c
new file mode 100644
index 0000000..39866c1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/recv.c
@@ -0,0 +1,42 @@
+//==========================================================================
+//
+// lib/recv.c
+//
+// recv() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas,andrew.lunn@ascom.ch
+// Contributors: gthomas
+// Date: 2001-11-01
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+extern ssize_t recvfrom (int, void *, size_t, int, struct sockaddr *, socklen_t *);
+
+ssize_t
+recv(int s, void *buf, size_t buflen, int flags)
+{
+
+ return(recvfrom(s,buf,buflen,flags,NULL,0));
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/recvfrom.c b/ecos/packages/net/tcpip/current/src/lib/recvfrom.c
new file mode 100644
index 0000000..63c1b27
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/recvfrom.c
@@ -0,0 +1,56 @@
+//==========================================================================
+//
+// lib/recvfrom.c
+//
+// recvfrom() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+ssize_t
+recvfrom(int s, const void *buf, size_t buflen,
+ int flags, const struct sockaddr *from, socklen_t *fromlen)
+{
+ struct sys_recvfrom_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,buf) = (void *)buf;
+ SYSCALLARG(args,len) = buflen;
+ SYSCALLARG(args,flags) = flags;
+ SYSCALLARG(args,from) = (struct sockaddr *)from;
+ SYSCALLARG(args,fromlenaddr) = fromlen;
+ error = sys_recvfrom(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return res;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/select.c b/ecos/packages/net/tcpip/current/src/lib/select.c
new file mode 100644
index 0000000..9316913
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/select.c
@@ -0,0 +1,209 @@
+//==========================================================================
+//
+// lib/select.c
+//
+// 'select()' system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description: eCos implementation of 'select()' system call
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <cyg/kernel/kapi.h>
+#include <sys/select.h>
+#include <sys/bsdselect.h>
+
+static cyg_flag_t select_flag;
+static cyg_bool select_flag_init = false;
+#define SELECT_WAKE 0x01
+#define SELECT_ABORT 0x02
+
+//
+// Private function which does all the work for 'select()'
+//
+static int
+_cyg_select(int nfd, fd_set *in, fd_set *out, fd_set *ex,
+ struct timeval *tv, cyg_bool_t abortable)
+{
+ int fd, mode, num, ticks;
+ struct file *fp;
+ fd_set in_res, out_res, ex_res; // Result sets
+ fd_set *selection[3], *result[3];
+ cyg_tick_count_t now, then;
+ int mode_type[] = {FREAD, FWRITE, 0};
+ cyg_flag_value_t flag, wait_flag;
+
+ // Note: since this is called by application programs, it needs no protection
+ if (!select_flag_init) {
+ select_flag_init = true;
+ cyg_flag_init(&select_flag);
+ }
+ wait_flag = SELECT_WAKE;
+ if (abortable) wait_flag |= SELECT_ABORT;
+ FD_ZERO(&in_res);
+ FD_ZERO(&out_res);
+ FD_ZERO(&ex_res);
+ // Set up sets
+ selection[0] = in; result[0] = &in_res;
+ selection[1] = out; result[1] = &out_res;
+ selection[2] = ex; result[2] = &ex_res;
+ // Compute end time
+ if (tv) {
+ now = cyg_current_time();
+ ticks = (tv->tv_sec * 100) + (tv->tv_usec / 10000);
+ then = now + ticks;
+ } else {
+ then = 0; // Compiler warnings :-(
+ ticks = 0;
+ }
+ // Scan sets for possible I/O until something found, timeout or error.
+ while (true) {
+ num = 0; // Total file descriptors "ready"
+
+ cyg_scheduler_lock(); // Scan the list atomically wrt electing to sleep
+
+ for (mode = 0; mode < 3; mode++) {
+ if (selection[mode]) {
+ for (fd = 0; fd < nfd; fd++) {
+ if (FD_ISSET(fd, selection[mode])) {
+ if (getfp(fd, &fp)) {
+ cyg_scheduler_unlock(); // return.
+ errno = EBADF;
+ return -1;
+ }
+ if ((*fp->f_ops->fo_select)(fp, mode_type[mode])) {
+ FD_SET(fd, result[mode]);
+ num++;
+ }
+ }
+ }
+ }
+ }
+ if (num) {
+
+ cyg_scheduler_unlock(); // Happy, about to return.
+
+ // Found something, update user's sets
+ if (in) {
+ memcpy(in, &in_res, sizeof(in_res));
+ }
+ if (out) {
+ memcpy(out, &out_res, sizeof(out_res));
+ }
+ if (ex) {
+ memcpy(ex, &ex_res, sizeof(ex_res));
+ }
+ return num;
+ }
+ // Nothing found, see if we want to wait
+ if (tv) {
+ if (ticks == 0) {
+ // Special case of "poll"
+ cyg_scheduler_unlock(); // About to return.
+ return 0;
+ }
+ flag = cyg_flag_timed_wait(&select_flag, wait_flag,
+ CYG_FLAG_WAITMODE_OR,
+ then);
+ } else {
+ // Wait forever (until something happens)
+ flag = cyg_flag_wait(&select_flag, wait_flag,
+ CYG_FLAG_WAITMODE_OR);
+ }
+
+ cyg_scheduler_unlock(); // waited atomically
+
+ if (flag & SELECT_ABORT) {
+ errno = EINTR;
+ return -1;
+ }
+ if (!flag) {
+ return 0; // meaning no activity, ergo timeout occurred
+ }
+ }
+ errno = ENOSYS;
+ return -1;
+}
+
+//
+// This function is called by the lower layers to record the
+// fact that a particular 'select' event is being requested.
+//
+void
+selrecord(void *selector, struct selinfo *info)
+{
+ // Unused by this implementation
+}
+
+//
+// This function is called to indicate that a 'select' event
+// may have occurred.
+//
+void
+selwakeup(struct selinfo *info)
+{
+ // Need these ops to be atomic to make sure the clear occurs -
+ // otherwise a higher prio thread could hog the CPU when its fds are
+ // not ready, but the flag is (already) set, or set for someone else.
+ cyg_scheduler_lock();
+ cyg_flag_setbits(&select_flag, SELECT_WAKE);
+ cyg_flag_maskbits(&select_flag, 0 ); // clear all
+ cyg_scheduler_unlock();
+}
+
+//
+// The public function used by 'normal' programs. This interface does not allow
+// the 'select()' to be externally interrupted.
+//
+int
+select(int nfd, fd_set *in, fd_set *out, fd_set *ex,
+ struct timeval *tv)
+{
+ return _cyg_select(nfd, in, out, ex, tv, false);
+}
+
+//
+// The public function used by programs which wish to allow interruption,
+// using the 'cyg_select_abort()' function below.
+//
+int
+cyg_select_with_abort(int nfd, fd_set *in, fd_set *out, fd_set *ex,
+ struct timeval *tv)
+{
+ return _cyg_select(nfd, in, out, ex, tv, true);
+}
+
+//
+// This function can be called by the user to forceably abort any
+// current selects.
+//
+void
+cyg_select_abort(void)
+{
+ // See comments in selwakeup()...
+ cyg_scheduler_lock();
+ cyg_flag_setbits(&select_flag, SELECT_ABORT);
+ cyg_flag_maskbits(&select_flag, 0 );
+ cyg_scheduler_unlock();
+}
+
+
diff --git a/ecos/packages/net/tcpip/current/src/lib/sendto.c b/ecos/packages/net/tcpip/current/src/lib/sendto.c
new file mode 100644
index 0000000..d319150
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/sendto.c
@@ -0,0 +1,56 @@
+//==========================================================================
+//
+// lib/sendto.c
+//
+// sendto() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+ssize_t
+sendto(int s, const void *buf, size_t buflen,
+ int flags, const struct sockaddr *to, socklen_t tolen)
+{
+ struct sys_sendto_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,buf) = buf;
+ SYSCALLARG(args,len) = buflen;
+ SYSCALLARG(args,flags) = flags;
+ SYSCALLARG(args,to) = to;
+ SYSCALLARG(args,tolen) = tolen;
+ error = sys_sendto(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return res;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/setsockopt.c b/ecos/packages/net/tcpip/current/src/lib/setsockopt.c
new file mode 100644
index 0000000..88902f0
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/setsockopt.c
@@ -0,0 +1,54 @@
+//==========================================================================
+//
+// lib/setsockopt.c
+//
+// setsockopt() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+setsockopt(int s, int level, int name, const void *val, socklen_t valsize)
+{
+ struct sys_setsockopt_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,level) = level;
+ SYSCALLARG(args,name) = name;
+ SYSCALLARG(args,val) = val;
+ SYSCALLARG(args,valsize) = valsize;
+ error = sys_setsockopt(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/shutdown.c b/ecos/packages/net/tcpip/current/src/lib/shutdown.c
new file mode 100644
index 0000000..a8956eb
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/shutdown.c
@@ -0,0 +1,51 @@
+//==========================================================================
+//
+// lib/shutdown.c
+//
+// shutdown() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+shutdown(int s, int how)
+{
+ struct sys_shutdown_args args;
+ int res, error;
+ SYSCALLARG(args,s) = s;
+ SYSCALLARG(args,how) = how;
+ error = sys_shutdown(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/socket.c b/ecos/packages/net/tcpip/current/src/lib/socket.c
new file mode 100644
index 0000000..f92c225
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/socket.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/socket.c
+//
+// socket() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+socket(int domain, int type, int protocol)
+{
+ struct sys_socket_args args;
+ int res, error;
+ SYSCALLARG(args,domain) = domain;
+ SYSCALLARG(args,type) = type;
+ SYSCALLARG(args,protocol) = protocol;
+ error = sys_socket(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return res;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/lib/write.c b/ecos/packages/net/tcpip/current/src/lib/write.c
new file mode 100644
index 0000000..0667631
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/lib/write.c
@@ -0,0 +1,52 @@
+//==========================================================================
+//
+// lib/write.c
+//
+// write() system call
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <sys/syscallargs.h>
+
+int
+write(int fd, const void *buf, size_t len)
+{
+ struct sys_write_args args;
+ int res, error;
+ SYSCALLARG(args,fd) = fd;
+ SYSCALLARG(args,buf) = buf;
+ SYSCALLARG(args,nbyte) = len;
+ error = sys_write(&args, &res);
+ if (error) {
+ errno = error;
+ return -1;
+ } else {
+ return res;
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/kern_subr.c b/ecos/packages/net/tcpip/current/src/sys/kern/kern_subr.c
new file mode 100644
index 0000000..63cf342
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/kern_subr.c
@@ -0,0 +1,357 @@
+//==========================================================================
+//
+// sys/kern/kern_subr.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: kern_subr.c,v 1.10 1999/11/07 17:39:14 provos Exp $ */
+/* $NetBSD: kern_subr.c,v 1.15 1996/04/09 17:21:56 ragge Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/proc.h>
+#endif // __ECOS
+#include <sys/malloc.h>
+#include <sys/queue.h>
+
+int
+uiomove(cp, n, uio)
+ register caddr_t cp;
+ register int n;
+ register struct uio *uio;
+{
+ register struct iovec *iov;
+ u_int cnt;
+ int error = 0;
+
+#ifdef DIAGNOSTIC
+ if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
+ panic("uiomove: mode");
+ if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
+ panic("uiomove proc");
+#endif
+ while (n > 0 && uio->uio_resid) {
+ iov = uio->uio_iov;
+ cnt = iov->iov_len;
+ if (cnt == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ continue;
+ }
+ if (cnt > n)
+ cnt = n;
+ switch (uio->uio_segflg) {
+
+ case UIO_USERSPACE:
+ if (uio->uio_rw == UIO_READ)
+ error = copyout(cp, iov->iov_base, cnt);
+ else
+ error = copyin(iov->iov_base, cp, cnt);
+ if (error)
+ return (error);
+ break;
+
+ case UIO_SYSSPACE:
+#if defined(UVM)
+ if (uio->uio_rw == UIO_READ)
+ error = kcopy(cp, iov->iov_base, cnt);
+ else
+ error = kcopy(iov->iov_base, cp, cnt);
+ if (error)
+ return(error);
+#else
+ if (uio->uio_rw == UIO_READ)
+ bcopy((caddr_t)cp, iov->iov_base, cnt);
+ else
+ bcopy(iov->iov_base, (caddr_t)cp, cnt);
+ break;
+#endif
+ }
+ iov->iov_base = (char *)iov->iov_base + cnt;
+ iov->iov_len -= cnt;
+ uio->uio_resid -= cnt;
+ uio->uio_offset += cnt;
+ cp += cnt;
+ n -= cnt;
+ }
+ return (error);
+}
+
+#ifndef __ECOS
+/*
+ * Give next character to user as result of read.
+ */
+int
+ureadc(c, uio)
+ register int c;
+ register struct uio *uio;
+{
+ register struct iovec *iov;
+
+ if (uio->uio_resid == 0)
+#ifdef DIAGNOSTIC
+ panic("ureadc: zero resid");
+#else
+ return (EINVAL);
+#endif
+again:
+ if (uio->uio_iovcnt <= 0)
+#ifdef DIAGNOSTIC
+ panic("ureadc: non-positive iovcnt");
+#else
+ return (EINVAL);
+#endif
+ iov = uio->uio_iov;
+ if (iov->iov_len <= 0) {
+ uio->uio_iovcnt--;
+ uio->uio_iov++;
+ goto again;
+ }
+ switch (uio->uio_segflg) {
+
+ case UIO_USERSPACE:
+ if (subyte(iov->iov_base, c) < 0)
+ return (EFAULT);
+ break;
+
+ case UIO_SYSSPACE:
+ *(char *)iov->iov_base = c;
+ break;
+ }
+ iov->iov_base++;
+ iov->iov_len--;
+ uio->uio_resid--;
+ uio->uio_offset++;
+ return (0);
+}
+#endif // __ECOS
+
+/*
+ * General routine to allocate a hash table.
+ */
+#ifdef __ECOS
+void *
+hashinit(int elements, int type, int flags, u_long *hashmask)
+#else
+void *
+hashinit(elements, type, flags, hashmask)
+ int elements, type, flags;
+ u_long *hashmask;
+#endif
+{
+ long hashsize;
+ LIST_HEAD(generic, generic) *hashtbl;
+ int i;
+
+ if (elements <= 0)
+ panic("hashinit: bad cnt");
+ for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
+ continue;
+ hashsize >>= 1;
+ hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, flags);
+ for (i = 0; i < hashsize; i++)
+ LIST_INIT(&hashtbl[i]);
+ *hashmask = hashsize - 1;
+ return (hashtbl);
+}
+
+#ifndef __ECOS
+/*
+ * "Shutdown hook" types, functions, and variables.
+ */
+
+struct shutdownhook_desc {
+ LIST_ENTRY(shutdownhook_desc) sfd_list;
+ void (*sfd_fn) __P((void *));
+ void *sfd_arg;
+};
+
+LIST_HEAD(, shutdownhook_desc) shutdownhook_list;
+
+int shutdownhooks_done;
+
+void *
+shutdownhook_establish(fn, arg)
+ void (*fn) __P((void *));
+ void *arg;
+{
+ struct shutdownhook_desc *ndp;
+
+ ndp = (struct shutdownhook_desc *)
+ malloc(sizeof (*ndp), M_DEVBUF, M_NOWAIT);
+ if (ndp == NULL)
+ return NULL;
+
+ ndp->sfd_fn = fn;
+ ndp->sfd_arg = arg;
+ LIST_INSERT_HEAD(&shutdownhook_list, ndp, sfd_list);
+
+ return (ndp);
+}
+
+void
+shutdownhook_disestablish(vhook)
+ void *vhook;
+{
+#ifdef DIAGNOSTIC
+ struct shutdownhook_desc *dp;
+
+ for (dp = shutdownhook_list.lh_first; dp != NULL;
+ dp = dp->sfd_list.le_next)
+ if (dp == vhook)
+ break;
+ if (dp == NULL)
+ panic("shutdownhook_disestablish: hook not established");
+#endif
+
+ LIST_REMOVE((struct shutdownhook_desc *)vhook, sfd_list);
+}
+
+/*
+ * Run shutdown hooks. Should be invoked immediately before the
+ * system is halted or rebooted, i.e. after file systems unmounted,
+ * after crash dump done, etc.
+ */
+void
+doshutdownhooks()
+{
+ struct shutdownhook_desc *dp;
+
+ if (shutdownhooks_done)
+ return;
+
+ for (dp = shutdownhook_list.lh_first; dp != NULL; dp =
+ dp->sfd_list.le_next)
+ (*dp->sfd_fn)(dp->sfd_arg);
+}
+
+/*
+ * "Power hook" types, functions, and variables.
+ */
+
+struct powerhook_desc {
+ LIST_ENTRY(powerhook_desc) sfd_list;
+ void (*sfd_fn) __P((int, void *));
+ void *sfd_arg;
+};
+
+LIST_HEAD(, powerhook_desc) powerhook_list;
+
+void *
+powerhook_establish(fn, arg)
+ void (*fn) __P((int, void *));
+ void *arg;
+{
+ struct powerhook_desc *ndp;
+
+ ndp = (struct powerhook_desc *)
+ malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT);
+ if (ndp == NULL)
+ return NULL;
+
+ ndp->sfd_fn = fn;
+ ndp->sfd_arg = arg;
+ LIST_INSERT_HEAD(&powerhook_list, ndp, sfd_list);
+
+ return (ndp);
+}
+
+void
+powerhook_disestablish(vhook)
+ void *vhook;
+{
+#ifdef DIAGNOSTIC
+ struct powerhook_desc *dp;
+
+ for (dp = powerhook_list.lh_first; dp != NULL;
+ dp = dp->sfd_list.le_next)
+ if (dp == vhook)
+ break;
+ if (dp == NULL)
+ panic("powerhook_disestablish: hook not established");
+#endif
+
+ LIST_REMOVE((struct powerhook_desc *)vhook, sfd_list);
+ free(vhook, M_DEVBUF);
+}
+
+/*
+ * Run power hooks.
+ */
+void
+dopowerhooks(why)
+ int why;
+{
+ struct powerhook_desc *dp;
+
+ for (dp = LIST_FIRST(&powerhook_list);
+ dp != NULL;
+ dp = LIST_NEXT(dp, sfd_list)) {
+ (*dp->sfd_fn)(why, dp->sfd_arg);
+ }
+}
+#endif // __ECOS
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/sockio.c b/ecos/packages/net/tcpip/current/src/sys/kern/sockio.c
new file mode 100644
index 0000000..5cead64
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/sockio.c
@@ -0,0 +1,950 @@
+//==========================================================================
+//
+// sys/kern/sockio.c
+//
+// Socket interface to Fileio subsystem
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-06-06
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 <pkgconf/net.h>
+#include <pkgconf/io_fileio.h>
+
+#include <sys/types.h>
+
+#include <cyg/io/file.h>
+
+#include <cyg/fileio/fileio.h>
+#include <cyg/fileio/sockio.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+//==========================================================================
+// Forward definitions
+
+static int bsd_init( cyg_nstab_entry *nste );
+static int bsd_socket( cyg_nstab_entry *nste, int domain, int type,
+ int protocol, cyg_file *file );
+
+static int bsd_bind ( cyg_file *fp, const sockaddr *sa, socklen_t len );
+static int bsd_connect ( cyg_file *fp, const sockaddr *sa, socklen_t len );
+static int bsd_accept ( cyg_file *fp, cyg_file *new_fp,
+ struct sockaddr *name, socklen_t *anamelen );
+static int bsd_listen ( cyg_file *fp, int len );
+static int bsd_getname ( cyg_file *fp, sockaddr *sa, socklen_t *len, int peer );
+static int bsd_shutdown ( cyg_file *fp, int flags );
+static int bsd_getsockopt( cyg_file *fp, int level, int optname,
+ void *optval, socklen_t *optlen);
+static int bsd_setsockopt( cyg_file *fp, int level, int optname,
+ const void *optval, socklen_t optlen);
+static int bsd_sendmsg ( cyg_file *fp, const struct msghdr *m,
+ int flags, ssize_t *retsize );
+static int bsd_recvmsg ( cyg_file *fp, struct msghdr *m,
+ socklen_t *namelen, ssize_t *retsize );
+
+
+// File operations
+static int bsd_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+static int bsd_write (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+static int bsd_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence );
+static int bsd_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
+ CYG_ADDRWORD data);
+static int bsd_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info);
+static int bsd_fsync (struct CYG_FILE_TAG *fp, int mode );
+static int bsd_close (struct CYG_FILE_TAG *fp);
+static int bsd_fstat (struct CYG_FILE_TAG *fp, struct stat *buf );
+static int bsd_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );
+static int bsd_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );
+
+static int
+bsd_recvit(cyg_file *fp, struct msghdr *mp, socklen_t *namelenp, ssize_t *retsize);
+static int
+bsd_sendit(cyg_file *fp, const struct msghdr *mp, int flags, ssize_t *retsize);
+
+
+//==========================================================================
+// Table entrys
+
+NSTAB_ENTRY( bsd_nste, 0,
+ "bsd_tcpip",
+ "",
+ 0,
+ bsd_init,
+ bsd_socket);
+
+struct cyg_sock_ops bsd_sockops =
+{
+ bsd_bind,
+ bsd_connect,
+ bsd_accept,
+ bsd_listen,
+ bsd_getname,
+ bsd_shutdown,
+ bsd_getsockopt,
+ bsd_setsockopt,
+ bsd_sendmsg,
+ bsd_recvmsg
+};
+
+cyg_fileops bsd_sock_fileops =
+{
+ bsd_read,
+ bsd_write,
+ bsd_lseek,
+ bsd_ioctl,
+ bsd_select,
+ bsd_fsync,
+ bsd_close,
+ bsd_fstat,
+ bsd_getinfo,
+ bsd_setinfo
+};
+
+//==========================================================================
+// NStab functions
+
+
+
+// -------------------------------------------------------------------------
+
+static int bsd_init( cyg_nstab_entry *nste )
+{
+ // Initialization already handled via constructor
+
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_socket( cyg_nstab_entry *nste, int domain, int type,
+ int protocol, cyg_file *file )
+{
+ int error = 0;
+ struct socket *so;
+
+ error = socreate( domain, &so, type, protocol );
+
+ if( error == ENOERR )
+ {
+
+ cyg_selinit(&so->so_rcv.sb_sel);
+ cyg_selinit(&so->so_snd.sb_sel);
+
+ file->f_flag |= CYG_FREAD|CYG_FWRITE;
+ file->f_type = CYG_FILE_TYPE_SOCKET;
+ file->f_ops = &bsd_sock_fileops;
+ file->f_offset = 0;
+ file->f_data = (CYG_ADDRWORD)so;
+ file->f_xops = (CYG_ADDRWORD)&bsd_sockops;
+ }
+
+ return error;
+}
+
+
+//==========================================================================
+// Sockops functions
+
+// -------------------------------------------------------------------------
+
+static int bsd_bind ( cyg_file *fp, const sockaddr *sa, socklen_t len )
+{
+ struct mbuf *nam;
+ int error;
+
+ error = sockargs(&nam, (caddr_t)sa, len, MT_SONAME);
+
+ if (error)
+ return (error);
+
+ error = sobind((struct socket *)fp->f_data, nam);
+
+ m_freem(nam);
+
+ return error;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_connect ( cyg_file *fp, const sockaddr *sa, socklen_t len )
+{
+ register struct socket *so;
+ struct mbuf *nam;
+ int error, s;
+
+ so = (struct socket *)fp->f_data;
+
+ if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
+ return (EALREADY);
+
+ error = sockargs(&nam, (caddr_t)sa, len, MT_SONAME);
+
+ if (error)
+ return (error);
+
+ error = soconnect(so, nam);
+ if (error)
+ goto bad;
+
+ if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+ m_freem(nam);
+ return (EINPROGRESS);
+ }
+
+ s = splsoftnet();
+ while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
+ error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
+ netcon, 0);
+ if (error)
+ break;
+ }
+
+ if (error == 0) {
+ error = so->so_error;
+ so->so_error = 0;
+ }
+
+ splx(s);
+
+bad:
+ so->so_state &= ~SS_ISCONNECTING;
+ m_freem(nam);
+
+ return error;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_accept ( cyg_file *fp, cyg_file *new_fp,
+ struct sockaddr *name, socklen_t *anamelen )
+{
+ struct mbuf *nam;
+ socklen_t namelen = 0;
+ int error = 0, s;
+ register struct socket *so;
+
+ if( anamelen != NULL )
+ namelen = *anamelen;
+
+ s = splsoftnet();
+ so = (struct socket *)fp->f_data;
+
+ if ((so->so_options & SO_ACCEPTCONN) == 0) {
+ splx(s);
+ return (EINVAL);
+ }
+
+ if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
+ splx(s);
+ return (EWOULDBLOCK);
+ }
+
+ while (so->so_qlen == 0 && so->so_error == 0) {
+ if (so->so_state & SS_CANTRCVMORE) {
+ so->so_error = ECONNABORTED;
+ break;
+ }
+ error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
+ netcon, 0);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ }
+
+ if (so->so_error) {
+ error = so->so_error;
+ so->so_error = 0;
+ splx(s);
+ return (error);
+ }
+
+ {
+ struct socket *aso = so->so_q;
+ if (soqremque(aso, 1) == 0)
+ panic("accept");
+ so = aso;
+ }
+
+ cyg_selinit(&so->so_rcv.sb_sel);
+ cyg_selinit(&so->so_snd.sb_sel);
+
+ new_fp->f_type = DTYPE_SOCKET;
+ new_fp->f_flag |= FREAD|FWRITE;
+ new_fp->f_offset = 0;
+ new_fp->f_ops = &bsd_sock_fileops;
+ new_fp->f_data = (CYG_ADDRWORD)so;
+ new_fp->f_xops = (CYG_ADDRWORD)&bsd_sockops;
+
+ nam = m_get(M_WAIT, MT_SONAME);
+ (void) soaccept(so, nam);
+ if (name) {
+ if (namelen > nam->m_len)
+ namelen = nam->m_len;
+ /* SHOULD COPY OUT A CHAIN HERE */
+ if ((error = copyout(mtod(nam, caddr_t),
+ (caddr_t)name, namelen)) == 0)
+ *anamelen = namelen;
+ }
+ m_freem(nam);
+ splx(s);
+
+ return (error);
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_listen ( cyg_file *fp, int backlog )
+{
+ return (solisten((struct socket *)fp->f_data, backlog));
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_getname ( cyg_file *fp, sockaddr *asa, socklen_t *alen, int peer )
+{
+ register struct socket *so;
+ struct mbuf *m;
+ socklen_t len = 0;
+ int error;
+ int type = peer ? PRU_PEERADDR : PRU_SOCKADDR;
+
+ if( alen != NULL )
+ len = *alen;
+
+ so = (struct socket *)fp->f_data;
+
+ if ( peer && (so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
+ return (ENOTCONN);
+
+ m = m_getclr(M_WAIT, MT_SONAME);
+ if (m == NULL)
+ return (ENOBUFS);
+
+ error = (*so->so_proto->pr_usrreq)(so, type, 0, m, 0);
+ if (error)
+ goto bad;
+
+ if (len > m->m_len)
+ len = m->m_len;
+
+ error = copyout(mtod(m, caddr_t), (caddr_t)asa, len);
+
+ if (error == 0)
+ *alen = len;
+
+bad:
+ m_freem(m);
+
+ return (error);
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_shutdown ( cyg_file *fp, int how )
+{
+ return (soshutdown((struct socket *)fp->f_data, how));
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_getsockopt( cyg_file *fp, int level, int optname,
+ void *optval, socklen_t *optlen)
+{
+ struct mbuf *m = NULL;
+ socklen_t valsize = 0;
+ int error;
+
+ if( optval != NULL && optlen != NULL )
+ valsize = *optlen;
+
+ error = sogetopt((struct socket *)fp->f_data, level, optname, &m);
+
+ if( error == ENOERR && valsize != 0 && m != NULL)
+ {
+ if (valsize > m->m_len)
+ valsize = m->m_len;
+
+ error = copyout(mtod(m, caddr_t), optval, valsize);
+
+ if( error == ENOERR )
+ *optlen = valsize;
+
+ }
+
+ if (m != NULL)
+ (void) m_free(m);
+ return (error);
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_setsockopt( cyg_file *fp, int level, int optname,
+ const void *optval, socklen_t optlen)
+{
+ int error;
+ struct mbuf *m = NULL;
+
+ if( optlen > MCLBYTES )
+ return EINVAL;
+
+ if (optval != NULL) {
+ m = m_get(M_WAIT, MT_SOOPTS);
+ if (optlen > MLEN) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+ }
+ if (m == NULL)
+ return (ENOBUFS);
+ error = copyin(optval, mtod(m, caddr_t), optlen);
+ if (error) {
+ (void) m_free(m);
+ return (error);
+ }
+ m->m_len = optlen;
+ }
+
+ return (sosetopt((struct socket *)fp->f_data, level, optname, m));
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_sendmsg ( cyg_file *fp, const struct msghdr *m, int flags, ssize_t *retsize )
+{
+ return bsd_sendit( fp, m, flags, retsize);
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_recvmsg ( cyg_file *fp, struct msghdr *m, socklen_t *namelen, ssize_t *retsize )
+{
+ return bsd_recvit( fp, m, namelen, retsize);
+}
+
+//==========================================================================
+// File system call functions
+
+// -------------------------------------------------------------------------
+
+static int bsd_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+ return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
+ uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_write (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+ return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
+ uio, (struct mbuf *)0, (struct mbuf *)0, 0));
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence )
+{
+ return ESPIPE;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD cmd,
+ CYG_ADDRWORD data)
+{
+ register struct socket *so = (struct socket *)fp->f_data;
+ void *p = 0;
+
+ switch (cmd) {
+
+ case FIONBIO:
+ if (*(int *)data)
+ so->so_state |= SS_NBIO;
+ else
+ so->so_state &= ~SS_NBIO;
+ return (0);
+
+ case FIOASYNC:
+ if (*(int *)data) {
+ so->so_state |= SS_ASYNC;
+ so->so_rcv.sb_flags |= SB_ASYNC;
+ so->so_snd.sb_flags |= SB_ASYNC;
+ } else {
+ so->so_state &= ~SS_ASYNC;
+ so->so_rcv.sb_flags &= ~SB_ASYNC;
+ so->so_snd.sb_flags &= ~SB_ASYNC;
+ }
+ return (0);
+
+ case FIONREAD:
+ *(int *)data = so->so_rcv.sb_cc;
+ return (0);
+
+ case SIOCATMARK:
+ *(int *)data = (so->so_state&SS_RCVATMARK) != 0;
+ return (0);
+ }
+ /*
+ * Interface/routing/protocol specific ioctls:
+ * interface and routing ioctls should have a
+ * different entry since a socket's unnecessary
+ */
+ if (IOCGROUP(cmd) == 'i')
+ return (ifioctl(so, (u_long)cmd, (caddr_t)data, p));
+ if (IOCGROUP(cmd) == 'r')
+ return (rtioctl((u_long)cmd, (caddr_t)data, p));
+ return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
+ (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
+
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info)
+{
+ register struct socket *so = (struct socket *)fp->f_data;
+ register int s = splsoftnet();
+
+ switch (which) {
+
+ case FREAD:
+ if (soreadable(so)) {
+ splx(s);
+ return (1);
+ }
+ cyg_selrecord(info, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
+ break;
+
+ case FWRITE:
+ if (sowriteable(so)) {
+ splx(s);
+ return (1);
+ }
+ cyg_selrecord(info, &so->so_snd.sb_sel);
+ so->so_snd.sb_flags |= SB_SEL;
+ break;
+
+ case 0:
+ if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
+ splx(s);
+ return (1);
+ }
+ cyg_selrecord(info, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
+ break;
+ }
+ splx(s);
+
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_fsync (struct CYG_FILE_TAG *fp, int mode )
+{
+ // FIXME: call some sort of flush IOCTL?
+ return 0;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_close (struct CYG_FILE_TAG *fp)
+{
+ int error = 0;
+
+ if (fp->f_data)
+ error = soclose((struct socket *)fp->f_data);
+ fp->f_data = 0;
+ return (error);
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_fstat (struct CYG_FILE_TAG *fp, struct stat *buf )
+{
+ register struct socket *so = (struct socket *)fp->f_data;
+
+ bzero((caddr_t)buf, sizeof (*buf));
+
+ // Mark socket as a fifo for now. We need to add socket types to
+ // sys/stat.h.
+ buf->st_mode = __stat_mode_FIFO;
+
+ return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
+ (struct mbuf *)buf,
+ (struct mbuf *)0,
+ (struct mbuf *)0));
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len )
+{
+ return ENOSYS;
+}
+
+// -------------------------------------------------------------------------
+
+static int bsd_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len )
+{
+ return ENOSYS;
+}
+
+
+
+//==========================================================================
+// Select support
+
+// -------------------------------------------------------------------------
+// This function is called by the lower layers to record the
+// fact that a particular 'select' event is being requested.
+//
+
+void
+selrecord(void *selector, struct selinfo *info)
+{
+ // Unused by this implementation
+}
+
+// -------------------------------------------------------------------------
+// This function is called to indicate that a 'select' event
+// may have occurred.
+//
+
+void
+selwakeup(struct selinfo *info)
+{
+ cyg_selwakeup( info );
+}
+
+//==========================================================================
+// Misc support functions
+
+int
+sockargs(mp, buf, buflen, type)
+ struct mbuf **mp;
+ caddr_t buf;
+ socklen_t buflen;
+ int type;
+{
+ register struct sockaddr *sa;
+ register struct mbuf *m;
+ int error;
+
+ if (buflen > MLEN) {
+#ifdef COMPAT_OLDSOCK
+ if (type == MT_SONAME && buflen <= 112)
+ buflen = MLEN; /* unix domain compat. hack */
+ else
+#endif
+ return (EINVAL);
+ }
+ m = m_get(M_WAIT, type);
+ if (m == NULL)
+ return (ENOBUFS);
+ m->m_len = buflen;
+ error = copyin(buf, mtod(m, caddr_t), buflen);
+ if (error) {
+ (void) m_free(m);
+ return (error);
+ }
+ *mp = m;
+ if (type == MT_SONAME) {
+ sa = mtod(m, struct sockaddr *);
+
+#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
+ if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
+ sa->sa_family = sa->sa_len;
+#endif
+ sa->sa_len = buflen;
+ }
+ return (0);
+}
+
+
+// -------------------------------------------------------------------------
+// bsd_recvit()
+// Support for message reception. This is a lightly edited version of the
+// recvit() function is uipc_syscalls.c.
+
+static int
+bsd_recvit(cyg_file *fp, struct msghdr *mp, socklen_t *namelenp, ssize_t *retsize)
+{
+ struct uio auio;
+ register struct iovec *iov;
+ register int i;
+ size_t len;
+ int error;
+ struct mbuf *from = 0, *control = 0;
+
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_rw = UIO_READ;
+ auio.uio_offset = 0; /* XXX */
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX)
+ return (EINVAL);
+ }
+
+ len = auio.uio_resid;
+ error = soreceive((struct socket *)fp->f_data, &from, &auio,
+ NULL, mp->msg_control ? &control : NULL,
+ &mp->msg_flags);
+ if (error) {
+ if (auio.uio_resid != len &&
+ (error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ }
+ if (error)
+ goto out;
+ *retsize = len - auio.uio_resid;
+ if (mp->msg_name) {
+ len = mp->msg_namelen;
+ if (len <= 0 || from == 0)
+ len = 0;
+ else {
+ /* save sa_len before it is destroyed by MSG_COMPAT */
+ if (len > from->m_len)
+ len = from->m_len;
+ /* else if len < from->m_len ??? */
+#ifdef COMPAT_OLDSOCK
+ if (mp->msg_flags & MSG_COMPAT)
+ mtod(from, struct osockaddr *)->sa_family =
+ mtod(from, struct sockaddr *)->sa_family;
+#endif
+ error = copyout(mtod(from, caddr_t),
+ (caddr_t)mp->msg_name, (unsigned)len);
+ if (error)
+ goto out;
+ }
+ mp->msg_namelen = len;
+ if (namelenp ) {
+ *namelenp = len;
+#ifdef COMPAT_OLDSOCK
+ if (mp->msg_flags & MSG_COMPAT)
+ error = 0; /* old recvfrom didn't check */
+ else
+#endif
+ goto out;
+ }
+ }
+ if (mp->msg_control) {
+#ifdef COMPAT_OLDSOCK
+ /*
+ * We assume that old recvmsg calls won't receive access
+ * rights and other control info, esp. as control info
+ * is always optional and those options didn't exist in 4.3.
+ * If we receive rights, trim the cmsghdr; anything else
+ * is tossed.
+ */
+ if (control && mp->msg_flags & MSG_COMPAT) {
+ if (mtod(control, struct cmsghdr *)->cmsg_level !=
+ SOL_SOCKET ||
+ mtod(control, struct cmsghdr *)->cmsg_type !=
+ SCM_RIGHTS) {
+ mp->msg_controllen = 0;
+ goto out;
+ }
+ control->m_len -= sizeof (struct cmsghdr);
+ control->m_data += sizeof (struct cmsghdr);
+ }
+#endif
+ len = mp->msg_controllen;
+ if (len <= 0 || control == 0)
+ len = 0;
+ else {
+ struct mbuf *m = control;
+ caddr_t p = (caddr_t)mp->msg_control;
+
+ do {
+ i = m->m_len;
+ if (len < i) {
+ mp->msg_flags |= MSG_CTRUNC;
+ i = len;
+ }
+ error = copyout(mtod(m, caddr_t), p,
+ (unsigned)i);
+ if (m->m_next)
+ i = ALIGN(i);
+ p += i;
+ len -= i;
+ if (error != 0 || len <= 0)
+ break;
+ } while ((m = m->m_next) != NULL);
+ len = p - (caddr_t)mp->msg_control;
+ }
+ mp->msg_controllen = len;
+ }
+out:
+ if (from)
+ m_freem(from);
+ if (control)
+ m_freem(control);
+ return (error);
+}
+
+// -------------------------------------------------------------------------
+// sendit()
+// Support for message transmission. This is a lightly edited version of the
+// synonymous function is uipc_syscalls.c.
+
+static int
+bsd_sendit(cyg_file *fp, const struct msghdr *mp, int flags, ssize_t *retsize)
+{
+ struct uio auio;
+ register struct iovec *iov;
+ register int i;
+ struct mbuf *to, *control;
+ int len, error;
+
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_offset = 0; /* XXX */
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX)
+ return (EINVAL);
+ }
+ if (mp->msg_name) {
+ error = sockargs(&to, mp->msg_name, mp->msg_namelen,
+ MT_SONAME);
+ if (error)
+ return (error);
+ } else
+ to = 0;
+ if (mp->msg_control) {
+ if (mp->msg_controllen < sizeof(struct cmsghdr)
+#ifdef COMPAT_OLDSOCK
+ && mp->msg_flags != MSG_COMPAT
+#endif
+ ) {
+ error = EINVAL;
+ goto bad;
+ }
+ error = sockargs(&control, mp->msg_control,
+ mp->msg_controllen, MT_CONTROL);
+ if (error)
+ goto bad;
+#ifdef COMPAT_OLDSOCK
+ if (mp->msg_flags == MSG_COMPAT) {
+ register struct cmsghdr *cm;
+
+ M_PREPEND(control, sizeof(*cm), M_WAIT);
+ if (control == 0) {
+ error = ENOBUFS;
+ goto bad;
+ } else {
+ cm = mtod(control, struct cmsghdr *);
+ cm->cmsg_len = control->m_len;
+ cm->cmsg_level = SOL_SOCKET;
+ cm->cmsg_type = SCM_RIGHTS;
+ }
+ }
+#endif
+ } else
+ control = 0;
+
+ len = auio.uio_resid;
+ error = sosend((struct socket *)fp->f_data, to, &auio,
+ NULL, control, flags);
+ if (error) {
+ if (auio.uio_resid != len &&
+ (error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+#ifndef __ECOS
+ if (error == EPIPE)
+ psignal(p, SIGPIPE);
+#endif
+ }
+ if (error == 0)
+ *retsize = len - auio.uio_resid;
+bad:
+ if (to)
+ m_freem(to);
+ return (error);
+}
+
+
+//==========================================================================
+// End of sockio.c
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/sys_generic.c b/ecos/packages/net/tcpip/current/src/sys/kern/sys_generic.c
new file mode 100644
index 0000000..bf0e9ed
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/sys_generic.c
@@ -0,0 +1,1022 @@
+//==========================================================================
+//
+// sys/kern/sys_generic.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: sys_generic.c,v 1.22 1999/11/29 22:02:14 deraadt Exp $ */
+/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Theo de Raadt
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/filedesc.h>
+#endif // __ECOS
+#include <sys/ioctl.h>
+#ifdef __ECOS
+#include <cyg/io/file.h>
+#else // __ECOS
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+#endif // __ECOS
+#include <sys/socketvar.h>
+#ifndef __ECOS
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#endif // __ECOS
+#include <sys/malloc.h>
+#ifndef __ECOS
+#include <sys/poll.h>
+#endif // __ECOS
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+
+#ifndef __ECOS
+#include <sys/mount.h>
+#endif // __ECOS
+#include <sys/syscallargs.h>
+
+#ifndef __ECOS
+int selscan __P((struct proc *, fd_set *, fd_set *, int, register_t *));
+int seltrue __P((dev_t, int, struct proc *));
+void pollscan __P((struct proc *, struct pollfd *, int, register_t *));
+#endif // __ECOS
+
+/*
+ * Read system call.
+ */
+#ifdef __ECOS
+int
+sys_read(struct sys_read_args *uap, register_t *retval)
+#else
+/* ARGSUSED */
+int
+sys_read(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+#endif
+{
+#ifndef __ECOS
+ register struct sys_read_args /* {
+ syscallarg(int) fd;
+ syscallarg(void *) buf;
+ syscallarg(size_t) nbyte;
+ } */ *uap = v;
+ register struct filedesc *fdp = p->p_fd;
+#endif
+ struct file *fp;
+ struct uio auio;
+ struct iovec aiov;
+ long cnt, error = 0;
+#ifdef KTRACE
+ struct iovec ktriov;
+#endif
+
+#ifdef __ECOS
+ if (getfp((u_int)SCARG(uap, fd), &fp) ||
+#else
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
+#endif
+ (fp->f_flag & FREAD) == 0)
+ return (EBADF);
+ /* Don't allow nbyte to be larger than max return val */
+ if (SCARG(uap, nbyte) > SSIZE_MAX)
+ return(EINVAL);
+ aiov.iov_base = (caddr_t)SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, nbyte);
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_resid = SCARG(uap, nbyte);
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+#ifndef __ECOS
+ auio.uio_procp = p;
+#endif
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO))
+ ktriov = aiov;
+#endif
+ cnt = SCARG(uap, nbyte);
+#ifdef __ECOS
+ error = (*fp->f_ops->fo_read)(fp, &auio);
+#else
+ error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+#endif
+ if (error)
+#ifdef __ECOS
+ if (auio.uio_resid != cnt && (
+#else
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+#endif
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_GENIO) && error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, &ktriov,
+ cnt, error);
+#endif
+ *retval = cnt;
+ return (error);
+}
+
+
+#ifndef __ECOS
+/*
+ * Scatter read system call.
+ */
+int
+sys_readv(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_readv_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(int) iovcnt;
+ } */ *uap = v;
+ register struct file *fp;
+ register struct filedesc *fdp = p->p_fd;
+ struct uio auio;
+ register struct iovec *iov;
+ struct iovec *needfree;
+ struct iovec aiov[UIO_SMALLIOV];
+ long i, cnt, error = 0;
+ u_int iovlen;
+#ifdef KTRACE
+ struct iovec *ktriov = NULL;
+#endif
+
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
+ (fp->f_flag & FREAD) == 0)
+ return (EBADF);
+ if (SCARG(uap, iovcnt) <= 0)
+ return (EINVAL);
+ /* note: can't use iovlen until iovcnt is validated */
+ iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
+ if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
+ if (SCARG(uap, iovcnt) > IOV_MAX)
+ return (EINVAL);
+ MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
+ needfree = iov;
+ } else {
+ iov = aiov;
+ needfree = NULL;
+ }
+ auio.uio_iov = iov;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_procp = p;
+ error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
+ if (error)
+ goto done;
+ auio.uio_resid = 0;
+ for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
+ error = EINVAL;
+ goto done;
+ }
+ }
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO)) {
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ cnt = auio.uio_resid;
+ error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
+ if (error)
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
+ cnt, error);
+ FREE(ktriov, M_TEMP);
+ }
+#endif
+ *retval = cnt;
+done:
+ if (needfree)
+ FREE(needfree, M_IOV);
+ return (error);
+}
+#endif
+
+/*
+ * Write system call
+ */
+#ifdef __ECOS
+int
+sys_write(struct sys_write_args *uap, register_t *retval)
+#else
+int
+sys_write(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+#endif
+{
+#ifndef __ECOS
+ register struct sys_write_args /* {
+ syscallarg(int) fd;
+ syscallarg(void *) buf;
+ syscallarg(size_t) nbyte;
+ } */ *uap = v;
+ register struct filedesc *fdp = p->p_fd;
+#endif
+ struct file *fp;
+ struct uio auio;
+ struct iovec aiov;
+ long cnt, error = 0;
+#ifdef KTRACE
+ struct iovec ktriov;
+#endif
+
+#ifdef __ECOS
+ if (getfp((u_int)SCARG(uap, fd), &fp) ||
+#else
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
+#endif
+ (fp->f_flag & FWRITE) == 0)
+ return (EBADF);
+ /* Don't allow nbyte to be larger than max return val */
+ if (SCARG(uap, nbyte) > SSIZE_MAX)
+ return(EINVAL);
+ aiov.iov_base = (caddr_t)SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, nbyte);
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_resid = SCARG(uap, nbyte);
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_USERSPACE;
+#ifndef __ECOS
+ auio.uio_procp = p;
+#endif
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO))
+ ktriov = aiov;
+#endif
+ cnt = SCARG(uap, nbyte);
+#ifdef __ECOS
+ error = (*fp->f_ops->fo_write)(fp, &auio);
+#else
+ error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+#endif
+ if (error) {
+#ifdef __ECOS
+ if (auio.uio_resid != cnt &&
+ (error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+#else
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ if (error == EPIPE)
+ psignal(p, SIGPIPE);
+#endif
+ }
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_GENIO) && error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
+ &ktriov, cnt, error);
+#endif
+ *retval = cnt;
+ return (error);
+}
+
+#ifndef __ECOS
+/*
+ * Gather write system call
+ */
+int
+sys_writev(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_writev_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(int) iovcnt;
+ } */ *uap = v;
+ register struct file *fp;
+ register struct filedesc *fdp = p->p_fd;
+ struct uio auio;
+ register struct iovec *iov;
+ struct iovec *needfree;
+ struct iovec aiov[UIO_SMALLIOV];
+ long i, cnt, error = 0;
+ u_int iovlen;
+#ifdef KTRACE
+ struct iovec *ktriov = NULL;
+#endif
+
+ if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
+ (fp->f_flag & FWRITE) == 0)
+ return (EBADF);
+ if (SCARG(uap, iovcnt) <= 0)
+ return (EINVAL);
+ /* note: can't use iovlen until iovcnt is validated */
+ iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
+ if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
+ if (SCARG(uap, iovcnt) > IOV_MAX)
+ return (EINVAL);
+ MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
+ needfree = iov;
+ } else {
+ iov = aiov;
+ needfree = NULL;
+ }
+ auio.uio_iov = iov;
+ auio.uio_iovcnt = SCARG(uap, iovcnt);
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_procp = p;
+ error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
+ if (error)
+ goto done;
+ auio.uio_resid = 0;
+ for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
+ error = EINVAL;
+ goto done;
+ }
+ }
+#ifdef KTRACE
+ /*
+ * if tracing, save a copy of iovec
+ */
+ if (KTRPOINT(p, KTR_GENIO)) {
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ cnt = auio.uio_resid;
+ error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
+ if (error) {
+ if (auio.uio_resid != cnt && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ if (error == EPIPE)
+ psignal(p, SIGPIPE);
+ }
+ cnt -= auio.uio_resid;
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
+ ktriov, cnt, error);
+ FREE(ktriov, M_TEMP);
+ }
+#endif
+ *retval = cnt;
+done:
+ if (needfree)
+ FREE(needfree, M_IOV);
+ return (error);
+}
+#endif
+
+/*
+ * Ioctl system call
+ */
+#ifdef __ECOS
+int
+sys_ioctl(struct sys_ioctl_args *uap, register_t *retval)
+#else
+/* ARGSUSED */
+int
+sys_ioctl(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+#endif
+{
+#ifndef __ECOS
+ register struct sys_ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap = v;
+ register struct filedesc *fdp;
+#endif
+ int tmp;
+ struct file *fp;
+ register u_long com;
+ register int error;
+ register u_int size;
+ caddr_t data, memp;
+#define STK_PARAMS 128
+ char stkbuf[STK_PARAMS];
+
+#ifdef __ECOS
+ if (getfp(SCARG(uap, fd), &fp))
+#else
+ fdp = p->p_fd;
+ if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
+#endif
+ return (EBADF);
+
+ if ((fp->f_flag & (FREAD | FWRITE)) == 0)
+ return (EBADF);
+
+#ifdef __ECOS
+ com = SCARG(uap, com);
+#else
+ switch (com = SCARG(uap, com)) {
+ case FIONCLEX:
+ fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
+ return (0);
+ case FIOCLEX:
+ fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
+ return (0);
+ }
+#endif
+
+ /*
+ * Interpret high order word to find amount of data to be
+ * copied to/from the user's address space.
+ */
+ size = IOCPARM_LEN(com);
+#ifndef __ECOS
+ if (size > IOCPARM_MAX)
+ return (ENOTTY);
+#endif
+ memp = NULL;
+ if (size > sizeof (stkbuf)) {
+ memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
+ data = memp;
+ } else
+ data = stkbuf;
+ if (com&IOC_IN) {
+ if (size) {
+ error = copyin(SCARG(uap, data), data, (u_int)size);
+ if (error) {
+ if (memp)
+ free(memp, M_IOCTLOPS);
+ return (error);
+ }
+ } else
+ *(caddr_t *)data = SCARG(uap, data);
+ } else if ((com&IOC_OUT) && size)
+ /*
+ * Zero the buffer so the user always
+ * gets back something deterministic.
+ */
+ bzero(data, size);
+ else if (com&IOC_VOID)
+ *(caddr_t *)data = SCARG(uap, data);
+
+ switch (com) {
+
+ case FIONBIO:
+ if ((tmp = *(int *)data) != 0)
+ fp->f_flag |= FNONBLOCK;
+ else
+ fp->f_flag &= ~FNONBLOCK;
+#ifdef __ECOS
+ error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (CYG_ADDRWORD)&tmp);
+#else
+ error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
+#endif
+ break;
+
+ case FIOASYNC:
+ if ((tmp = *(int *)data) != 0)
+ fp->f_flag |= FASYNC;
+ else
+ fp->f_flag &= ~FASYNC;
+#ifdef __ECOS
+ error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (CYG_ADDRWORD)&tmp);
+#else
+ error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
+#endif
+ break;
+
+#ifndef __ECOS
+ case FIOSETOWN:
+ tmp = *(int *)data;
+ if (fp->f_type == DTYPE_SOCKET) {
+ struct socket *so = (struct socket *)fp->f_data;
+
+ so->so_pgid = tmp;
+ so->so_siguid = p->p_cred->p_ruid;
+ so->so_sigeuid = p->p_ucred->cr_uid;
+ error = 0;
+ break;
+ }
+ if (tmp <= 0) {
+ tmp = -tmp;
+ } else {
+ struct proc *p1 = pfind(tmp);
+ if (p1 == 0) {
+ error = ESRCH;
+ break;
+ }
+ tmp = p1->p_pgrp->pg_id;
+ }
+ error = (*fp->f_ops->fo_ioctl)
+ (fp, TIOCSPGRP, (caddr_t)&tmp, p);
+ break;
+
+ case FIOGETOWN:
+ if (fp->f_type == DTYPE_SOCKET) {
+ error = 0;
+ *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
+ break;
+ }
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
+ *(int *)data = -*(int *)data;
+ break;
+#endif
+ default:
+#ifdef __ECOS
+ error = (*fp->f_ops->fo_ioctl)(fp, com, (CYG_ADDRWORD)data);
+#else
+ error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
+#endif
+ /*
+ * Copy any data to user, size was
+ * already set and checked above.
+ */
+ if (error == 0 && (com&IOC_OUT) && size)
+ error = copyout(data, SCARG(uap, data), (u_int)size);
+ break;
+ }
+ if (memp)
+ free(memp, M_IOCTLOPS);
+ return (error);
+}
+
+#ifndef __ECOS
+int selwait, nselcoll;
+
+/*
+ * Select system call.
+ */
+int
+sys_select(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_select_args /* {
+ syscallarg(int) nd;
+ syscallarg(fd_set *) in;
+ syscallarg(fd_set *) ou;
+ syscallarg(fd_set *) ex;
+ syscallarg(struct timeval *) tv;
+ } */ *uap = v;
+ fd_set bits[6], *pibits[3], *pobits[3];
+ struct timeval atv;
+ int s, ncoll, error = 0, timo;
+ u_int ni;
+
+ if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
+ /* forgiving; slightly wrong */
+ SCARG(uap, nd) = p->p_fd->fd_nfiles;
+ }
+ ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
+ if (SCARG(uap, nd) > FD_SETSIZE) {
+ caddr_t mbits;
+
+ if ((mbits = malloc(ni * 6, M_TEMP, M_WAITOK)) == NULL) {
+ error = EINVAL;
+ goto cleanup;
+ }
+ bzero(mbits, ni * 6);
+ pibits[0] = (fd_set *)&mbits[ni * 0];
+ pibits[1] = (fd_set *)&mbits[ni * 1];
+ pibits[2] = (fd_set *)&mbits[ni * 2];
+ pobits[0] = (fd_set *)&mbits[ni * 3];
+ pobits[1] = (fd_set *)&mbits[ni * 4];
+ pobits[2] = (fd_set *)&mbits[ni * 5];
+ } else {
+ bzero((caddr_t)bits, sizeof(bits));
+ pibits[0] = &bits[0];
+ pibits[1] = &bits[1];
+ pibits[2] = &bits[2];
+ pobits[0] = &bits[3];
+ pobits[1] = &bits[4];
+ pobits[2] = &bits[5];
+ }
+
+#define getbits(name, x) \
+ if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \
+ (caddr_t)pibits[x], ni))) \
+ goto done;
+ getbits(in, 0);
+ getbits(ou, 1);
+ getbits(ex, 2);
+#undef getbits
+
+ if (SCARG(uap, tv)) {
+ error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
+ sizeof (atv));
+ if (error)
+ goto done;
+ if (itimerfix(&atv)) {
+ error = EINVAL;
+ goto done;
+ }
+ s = splclock();
+ timeradd(&atv, &time, &atv);
+ timo = hzto(&atv);
+ /*
+ * Avoid inadvertently sleeping forever.
+ */
+ if (timo == 0)
+ timo = 1;
+ splx(s);
+ } else
+ timo = 0;
+retry:
+ ncoll = nselcoll;
+ p->p_flag |= P_SELECT;
+ error = selscan(p, pibits[0], pobits[0], SCARG(uap, nd), retval);
+ if (error || *retval)
+ goto done;
+ s = splhigh();
+ /* this should be timercmp(&time, &atv, >=) */
+ if (SCARG(uap, tv) && (time.tv_sec > atv.tv_sec ||
+ (time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec))) {
+ splx(s);
+ goto done;
+ }
+ if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
+ splx(s);
+ goto retry;
+ }
+ p->p_flag &= ~P_SELECT;
+ error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
+ splx(s);
+ if (error == 0)
+ goto retry;
+done:
+ p->p_flag &= ~P_SELECT;
+ /* select is not restarted after signals... */
+ if (error == ERESTART)
+ error = EINTR;
+ if (error == EWOULDBLOCK)
+ error = 0;
+#define putbits(name, x) \
+ if (SCARG(uap, name) && (error2 = copyout((caddr_t)pobits[x], \
+ (caddr_t)SCARG(uap, name), ni))) \
+ error = error2;
+ if (error == 0) {
+ int error2;
+
+ putbits(in, 0);
+ putbits(ou, 1);
+ putbits(ex, 2);
+#undef putbits
+ }
+
+cleanup:
+ if (pibits[0] != &bits[0])
+ free(pibits[0], M_TEMP);
+ return (error);
+}
+
+int
+selscan(p, ibits, obits, nfd, retval)
+ struct proc *p;
+ fd_set *ibits, *obits;
+ int nfd;
+ register_t *retval;
+{
+ caddr_t cibits = (caddr_t)ibits, cobits = (caddr_t)obits;
+ register struct filedesc *fdp = p->p_fd;
+ register int msk, i, j, fd;
+ register fd_mask bits;
+ struct file *fp;
+ int ni, n = 0;
+ static int flag[3] = { FREAD, FWRITE, 0 };
+
+ /*
+ * if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded
+ * up to the next byte) otherwise the fd_set's are normal sized.
+ */
+ ni = sizeof(fd_set);
+ if (nfd > FD_SETSIZE)
+ ni = howmany(nfd, NFDBITS) * sizeof(fd_mask);
+
+ for (msk = 0; msk < 3; msk++) {
+ fd_set *pibits = (fd_set *)&cibits[msk*ni];
+ fd_set *pobits = (fd_set *)&cobits[msk*ni];
+
+ for (i = 0; i < nfd; i += NFDBITS) {
+ bits = pibits->fds_bits[i/NFDBITS];
+ while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
+ bits &= ~(1 << j);
+ fp = fdp->fd_ofiles[fd];
+ if (fp == NULL)
+ return (EBADF);
+ if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
+ FD_SET(fd, pobits);
+ n++;
+ }
+ }
+ }
+ }
+ *retval = n;
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+seltrue(dev, flag, p)
+ dev_t dev;
+ int flag;
+ struct proc *p;
+{
+
+ return (1);
+}
+
+/*
+ * Record a select request.
+ */
+void
+selrecord(selector, sip)
+ struct proc *selector;
+ struct selinfo *sip;
+{
+ struct proc *p;
+ pid_t mypid;
+
+ mypid = selector->p_pid;
+ if (sip->si_selpid == mypid)
+ return;
+ if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
+ p->p_wchan == (caddr_t)&selwait)
+ sip->si_flags |= SI_COLL;
+ else
+ sip->si_selpid = mypid;
+}
+
+/*
+ * Do a wakeup when a selectable event occurs.
+ */
+void
+selwakeup(sip)
+ register struct selinfo *sip;
+{
+ register struct proc *p;
+ int s;
+
+ if (sip->si_selpid == 0)
+ return;
+ if (sip->si_flags & SI_COLL) {
+ nselcoll++;
+ sip->si_flags &= ~SI_COLL;
+ wakeup((caddr_t)&selwait);
+ }
+ p = pfind(sip->si_selpid);
+ sip->si_selpid = 0;
+ if (p != NULL) {
+ s = splhigh();
+ if (p->p_wchan == (caddr_t)&selwait) {
+ if (p->p_stat == SSLEEP)
+ setrunnable(p);
+ else
+ unsleep(p);
+ } else if (p->p_flag & P_SELECT)
+ p->p_flag &= ~P_SELECT;
+ splx(s);
+ }
+}
+
+void
+pollscan(p, pl, nfd, retval)
+ struct proc *p;
+ struct pollfd *pl;
+ int nfd;
+ register_t *retval;
+{
+ register struct filedesc *fdp = p->p_fd;
+ register int msk, i;
+ struct file *fp;
+ int x, n = 0;
+ static int flag[3] = { FREAD, FWRITE, 0 };
+ static int pflag[3] = { POLLIN|POLLRDNORM, POLLOUT, POLLERR };
+
+ /*
+ * XXX: We need to implement the rest of the flags.
+ */
+ for (i = 0; i < nfd; i++) {
+ /* Check the file descriptor. */
+ if (pl[i].fd < 0)
+ continue;
+ if (pl[i].fd >= fdp->fd_nfiles) {
+ pl[i].revents = POLLNVAL;
+ n++;
+ continue;
+ }
+
+ fp = fdp->fd_ofiles[pl[i].fd];
+ if (fp == NULL) {
+ pl[i].revents = POLLNVAL;
+ n++;
+ continue;
+ }
+ for (x = msk = 0; msk < 3; msk++) {
+ if (pl[i].events & pflag[msk]) {
+ if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
+ pl[i].revents |= pflag[msk] &
+ pl[i].events;
+ x++;
+ }
+ }
+ }
+ if (x)
+ n++;
+ }
+ *retval = n;
+}
+
+/*
+ * We are using the same mechanism as select only we encode/decode args
+ * differently.
+ */
+int
+sys_poll(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_poll_args *uap = v;
+ size_t sz;
+ struct pollfd pfds[4], *pl = pfds;
+ int msec = SCARG(uap, timeout);
+ struct timeval atv;
+ int timo, ncoll, i, s, error, error2;
+ extern int nselcoll, selwait;
+
+ /* Standards say no more than MAX_OPEN; this is possibly better. */
+ if (SCARG(uap, nfds) > min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur,
+ maxfiles))
+ return (EINVAL);
+
+ sz = sizeof(struct pollfd) * SCARG(uap, nfds);
+
+ /* optimize for the default case, of a small nfds value */
+ if (sz > sizeof(pfds))
+ pl = (struct pollfd *) malloc(sz, M_TEMP, M_WAITOK);
+
+ if ((error = copyin(SCARG(uap, fds), pl, sz)) != 0)
+ goto bad;
+
+ for (i = 0; i < SCARG(uap, nfds); i++)
+ pl[i].revents = 0;
+
+ if (msec != -1) {
+ atv.tv_sec = msec / 1000;
+ atv.tv_usec = (msec - (atv.tv_sec * 1000)) * 1000;
+
+ if (itimerfix(&atv)) {
+ error = EINVAL;
+ goto done;
+ }
+ s = splclock();
+ timeradd(&atv, &time, &atv);
+ timo = hzto(&atv);
+ /*
+ * Avoid inadvertently sleeping forever.
+ */
+ if (timo == 0)
+ timo = 1;
+ splx(s);
+ } else
+ timo = 0;
+
+retry:
+ ncoll = nselcoll;
+ p->p_flag |= P_SELECT;
+ pollscan(p, pl, SCARG(uap, nfds), retval);
+ if (*retval)
+ goto done;
+ s = splhigh();
+ if (timo && timercmp(&time, &atv, >=)) {
+ splx(s);
+ goto done;
+ }
+ if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
+ splx(s);
+ goto retry;
+ }
+ p->p_flag &= ~P_SELECT;
+ error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "poll", timo);
+ splx(s);
+ if (error == 0)
+ goto retry;
+
+done:
+ p->p_flag &= ~P_SELECT;
+ /* poll is not restarted after signals... */
+ if (error == ERESTART)
+ error = EINTR;
+ if (error == EWOULDBLOCK)
+ error = 0;
+ if ((error2 = copyout(pl, SCARG(uap, fds), sz)) != 0)
+ error = error2;
+bad:
+ if (pl != pfds)
+ free((char *) pl, M_TEMP);
+ return (error);
+}
+#endif
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/sys_socket.c b/ecos/packages/net/tcpip/current/src/sys/kern/sys_socket.c
new file mode 100644
index 0000000..6c36169
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/sys_socket.c
@@ -0,0 +1,279 @@
+//==========================================================================
+//
+// sys/kern/sys_socket.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: sys_socket.c,v 1.3 1997/08/31 20:42:23 deraadt Exp $ */
+/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#ifdef __ECOS
+#include <cyg/io/file.h>
+#else
+#include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/ioctl.h>
+#ifndef __ECOS
+#include <sys/stat.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+struct fileops socketops =
+ { soo_read, soo_write, soo_ioctl, soo_select, soo_close };
+
+#ifdef __ECOS
+/* ARGSUSED */
+int
+soo_read(struct file *fp, struct uio *uio)
+#else
+/* ARGSUSED */
+int
+soo_read(fp, uio, cred)
+ struct file *fp;
+ struct uio *uio;
+ struct ucred *cred;
+#endif
+{
+
+ return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
+ uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
+}
+
+#ifdef __ECOS
+int
+soo_write(struct file *fp, struct uio *uio)
+#else
+/* ARGSUSED */
+int
+soo_write(fp, uio, cred)
+ struct file *fp;
+ struct uio *uio;
+ struct ucred *cred;
+#endif
+{
+
+ return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
+ uio, (struct mbuf *)0, (struct mbuf *)0, 0));
+}
+
+#ifdef __ECOS
+int
+soo_ioctl(struct file *fp, CYG_ADDRWORD cmd, CYG_ADDRWORD data)
+#else
+int
+soo_ioctl(fp, cmd, data, p)
+ struct file *fp;
+ u_long cmd;
+ register caddr_t data;
+ struct proc *p;
+#endif
+{
+ register struct socket *so = (struct socket *)fp->f_data;
+#ifdef __ECOS
+ void *p = 0;
+#endif
+
+ switch (cmd) {
+
+ case FIONBIO:
+ if (*(int *)data)
+ so->so_state |= SS_NBIO;
+ else
+ so->so_state &= ~SS_NBIO;
+ return (0);
+
+ case FIOASYNC:
+ if (*(int *)data) {
+ so->so_state |= SS_ASYNC;
+ so->so_rcv.sb_flags |= SB_ASYNC;
+ so->so_snd.sb_flags |= SB_ASYNC;
+ } else {
+ so->so_state &= ~SS_ASYNC;
+ so->so_rcv.sb_flags &= ~SB_ASYNC;
+ so->so_snd.sb_flags &= ~SB_ASYNC;
+ }
+ return (0);
+
+ case FIONREAD:
+ *(int *)data = so->so_rcv.sb_cc;
+ return (0);
+
+#ifndef __ECOS
+ case SIOCSPGRP:
+ so->so_pgid = *(int *)data;
+ so->so_siguid = p->p_cred->p_ruid;
+ so->so_sigeuid = p->p_ucred->cr_uid;
+ return (0);
+
+ case SIOCGPGRP:
+ *(int *)data = so->so_pgid;
+ return (0);
+#endif
+
+ case SIOCATMARK:
+ *(int *)data = (so->so_state&SS_RCVATMARK) != 0;
+ return (0);
+ }
+ /*
+ * Interface/routing/protocol specific ioctls:
+ * interface and routing ioctls should have a
+ * different entry since a socket's unnecessary
+ */
+ if (IOCGROUP(cmd) == 'i')
+ return (ifioctl(so, (u_long)cmd, (caddr_t)data, p));
+ if (IOCGROUP(cmd) == 'r')
+ return (rtioctl((u_long)cmd, (caddr_t)data, p));
+ return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
+ (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
+}
+
+#ifdef __ECOS
+int
+soo_select(struct file *fp, int which)
+#else
+int
+soo_select(fp, which, p)
+ struct file *fp;
+ int which;
+ struct proc *p;
+#endif
+{
+ register struct socket *so = (struct socket *)fp->f_data;
+ register int s = splsoftnet();
+#ifdef __ECOS
+ void *p = 0;
+#endif
+
+ switch (which) {
+
+ case FREAD:
+ if (soreadable(so)) {
+ splx(s);
+ return (1);
+ }
+ selrecord(p, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
+ break;
+
+ case FWRITE:
+ if (sowriteable(so)) {
+ splx(s);
+ return (1);
+ }
+ selrecord(p, &so->so_snd.sb_sel);
+ so->so_snd.sb_flags |= SB_SEL;
+ break;
+
+ case 0:
+ if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
+ splx(s);
+ return (1);
+ }
+ selrecord(p, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
+ break;
+ }
+ splx(s);
+ return (0);
+}
+
+#ifndef __ECOS
+int
+soo_stat(so, ub)
+ register struct socket *so;
+ register struct stat *ub;
+{
+
+ bzero((caddr_t)ub, sizeof (*ub));
+ ub->st_mode = S_IFSOCK;
+ return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
+ (struct mbuf *)ub, (struct mbuf *)0,
+ (struct mbuf *)0));
+}
+#endif
+
+#ifdef __ECOS
+int
+soo_close(struct file *fp)
+#else
+/* ARGSUSED */
+int
+soo_close(fp, p)
+ struct file *fp;
+ struct proc *p;
+#endif
+{
+ int error = 0;
+
+ if (fp->f_data)
+ error = soclose((struct socket *)fp->f_data);
+ fp->f_data = 0;
+ return (error);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/uipc_domain.c b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_domain.c
new file mode 100644
index 0000000..be7c073
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_domain.c
@@ -0,0 +1,308 @@
+//==========================================================================
+//
+// sys/kern/uipc_domain.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: uipc_domain.c,v 1.9 1999/12/08 06:50:17 itojun Exp $ */
+/* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+#endif
+
+void pffasttimo __P((void *));
+void pfslowtimo __P((void *));
+#if defined (KEY) || defined (IPSEC)
+int pfkey_init __P((void));
+#endif /* KEY || IPSEC */
+
+#define ADDDOMAIN(x) { \
+ extern struct domain __CONCAT(x,domain); \
+ __CONCAT(x,domain.dom_next) = domains; \
+ domains = &__CONCAT(x,domain); \
+}
+
+void
+domaininit()
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+#undef unix
+ /*
+ * KAME NOTE: ADDDOMAIN(route) is moved to the last part so that
+ * it will be initialized as the *first* element. confusing!
+ */
+#ifndef lint
+#ifndef __ECOS
+ ADDDOMAIN(unix);
+#endif
+#ifdef INET
+ ADDDOMAIN(inet);
+#endif
+#ifdef INET6
+ ADDDOMAIN(inet6);
+#endif /* INET6 */
+#if defined (KEY) || defined (IPSEC)
+ pfkey_init();
+#endif /* KEY || IPSEC */
+#ifdef IPX
+ ADDDOMAIN(ipx);
+#endif
+#ifdef NETATALK
+ ADDDOMAIN(atalk);
+#endif
+#ifdef NS
+ ADDDOMAIN(ns);
+#endif
+#ifdef ISO
+ ADDDOMAIN(iso);
+#endif
+#ifdef CCITT
+ ADDDOMAIN(ccitt);
+#endif
+#ifdef notdef /* XXXX */
+#include "imp.h"
+#if NIMP > 0
+ ADDDOMAIN(imp);
+#endif
+#endif
+#ifdef IPSEC
+#ifdef __KAME__
+ ADDDOMAIN(key);
+#endif
+#endif
+ ADDDOMAIN(route);
+#endif
+
+ for (dp = domains; dp; dp = dp->dom_next) {
+ if (dp->dom_init)
+ (*dp->dom_init)();
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_init)
+ (*pr->pr_init)();
+ }
+
+if (max_linkhdr < 16) /* XXX */
+max_linkhdr = 16;
+ max_hdr = max_linkhdr + max_protohdr;
+ max_datalen = MHLEN - max_hdr;
+ timeout(pffasttimo, NULL, 1);
+ timeout(pfslowtimo, NULL, 1);
+}
+
+struct protosw *
+pffindtype(family, type)
+ int family, type;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ if (dp->dom_family == family)
+ goto found;
+ return (0);
+found:
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_type && pr->pr_type == type)
+ return (pr);
+ return (0);
+}
+
+struct protosw *
+pffindproto(family, protocol, type)
+ int family, protocol, type;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+ struct protosw *maybe = 0;
+
+ if (family == 0)
+ return (0);
+ for (dp = domains; dp; dp = dp->dom_next)
+ if (dp->dom_family == family)
+ goto found;
+ return (0);
+found:
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
+ if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
+ return (pr);
+
+ if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
+ pr->pr_protocol == 0 && maybe == (struct protosw *)0)
+ maybe = pr;
+ }
+ return (maybe);
+}
+
+#ifndef __ECOS
+int
+net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ struct proc *p;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+ int family, protocol;
+
+ /*
+ * All sysctl names at this level are nonterminal.
+ * PF_KEY: next component is protocol family, and then at least one
+ * additional component.
+ * usually: next two components are protocol family and protocol
+ * number, then at least one addition component.
+ */
+ if (namelen < 2)
+ return (EISDIR); /* overloaded */
+ family = name[0];
+
+ if (family == 0)
+ return (0);
+ for (dp = domains; dp; dp = dp->dom_next)
+ if (dp->dom_family == family)
+ goto found;
+ return (ENOPROTOOPT);
+found:
+ switch (family) {
+#ifdef IPSEC
+#ifdef __KAME__
+ case PF_KEY:
+ pr = dp->dom_protosw;
+ if (pr->pr_sysctl)
+ return ((*pr->pr_sysctl)(name + 1, namelen - 1,
+ oldp, oldlenp, newp, newlen));
+ return (ENOPROTOOPT);
+#endif
+#endif
+ default:
+ break;
+ }
+ if (namelen < 3)
+ return (EISDIR); /* overloaded */
+ protocol = name[1];
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_protocol == protocol && pr->pr_sysctl)
+ return ((*pr->pr_sysctl)(name + 2, namelen - 2,
+ oldp, oldlenp, newp, newlen));
+ return (ENOPROTOOPT);
+}
+#endif
+
+void
+pfctlinput(cmd, sa)
+ int cmd;
+ struct sockaddr *sa;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_ctlinput)
+ (*pr->pr_ctlinput)(cmd, sa, NULL);
+}
+
+void
+pfslowtimo(arg)
+ void *arg;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_slowtimo) {
+ (*pr->pr_slowtimo)();
+ }
+ timeout(pfslowtimo, NULL, hz/2);
+}
+
+void
+pffasttimo(arg)
+ void *arg;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_fasttimo) {
+ (*pr->pr_fasttimo)();
+ }
+ timeout(pffasttimo, NULL, hz/5);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/uipc_mbuf.c b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_mbuf.c
new file mode 100644
index 0000000..ddbc5bc
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_mbuf.c
@@ -0,0 +1,1093 @@
+//==========================================================================
+//
+// sys/kern/uipc_mbuf.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: uipc_mbuf.c,v 1.18 1999/12/05 07:30:31 angelos Exp $ */
+/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/proc.h>
+#endif
+#include <sys/malloc.h>
+#ifndef __ECOS
+#include <sys/map.h>
+#endif
+#define MBTYPES
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#ifndef __ECOS
+#include <sys/syslog.h>
+#endif
+#include <sys/domain.h>
+#include <sys/protosw.h>
+
+#include <machine/cpu.h>
+
+#ifndef __ECOS
+#include <vm/vm.h>
+#endif
+
+#if defined(UVM)
+#include <uvm/uvm_extern.h>
+#endif
+
+#ifndef __ECOS
+extern vm_map_t mb_map;
+#endif
+struct mbuf *mbutl;
+char *mclrefcnt;
+int needqueuedrain;
+
+#ifdef __ECOS
+extern void setsoftnet(void);
+extern void *cyg_net_cluster_alloc(void);
+#endif
+
+/* Declarations of variables move from mbuf.h to keep g++ happy */
+#ifdef __ECOS
+struct mbstat mbstat;
+union mcluster *mclfree;
+int max_linkhdr; /* largest link-level header */
+int max_protohdr; /* largest protocol header */
+int max_hdr; /* largest link+protocol header */
+int max_datalen; /* MHLEN - max_hdr */
+#ifdef MBTYPES
+int mbtypes[] = { /* XXX */
+ M_FREE, /* MT_FREE 0 should be on free list */
+ M_MBUF, /* MT_DATA 1 dynamic (data) allocation */
+ M_MBUF, /* MT_HEADER 2 packet header */
+ M_SOCKET, /* MT_SOCKET 3 socket structure */
+ M_PCB, /* MT_PCB 4 protocol control block */
+ M_RTABLE, /* MT_RTABLE 5 routing tables */
+ M_HTABLE, /* MT_HTABLE 6 IMP host tables */
+ 0, /* MT_ATABLE 7 address resolution tables */
+ M_MBUF, /* MT_SONAME 8 socket name */
+ 0, /* 9 */
+ M_SOOPTS, /* MT_SOOPTS 10 socket options */
+ M_FTABLE, /* MT_FTABLE 11 fragment reassembly header */
+ M_MBUF, /* MT_RIGHTS 12 access rights */
+ M_IFADDR, /* MT_IFADDR 13 interface address */
+ M_MBUF, /* MT_CONTROL 14 extra-data protocol message */
+ M_MBUF, /* MT_OOBDATA 15 expedited data */
+#ifdef DATAKIT
+ 25, 26, 27, 28, 29, 30, 31, 32 /* datakit ugliness */
+#endif
+};
+#endif
+#endif // __ECOS
+
+void
+mbinit()
+{
+ int s;
+
+ s = splimp();
+#ifdef __ECOS
+ if (m_clalloc(1, M_DONTWAIT) == 0)
+#else
+ if (m_clalloc(max(4096 / CLBYTES, 1), M_DONTWAIT) == 0)
+#endif
+ goto bad;
+ splx(s);
+ return;
+bad:
+ panic("mbinit");
+}
+
+/*
+ * Allocate some number of mbuf clusters
+ * and place on cluster free list.
+ * Must be called at splimp.
+ */
+/* ARGSUSED */
+int
+m_clalloc(ncl, nowait)
+ register int ncl;
+ int nowait;
+{
+#ifdef __ECOS
+ caddr_t p;
+ int i;
+
+ if (ncl != 1) {
+ panic("Allocate multiple clusters!");
+ }
+ p = (caddr_t)cyg_net_cluster_alloc();
+ if (p == NULL) {
+ m_reclaim();
+ return (mclfree != NULL);
+ }
+ for (i = 0; i < ncl; i++) {
+ ((union mcluster *)p)->mcl_next = mclfree;
+ mclfree = (union mcluster *)p;
+ p += MCLBYTES;
+ mbstat.m_clfree++;
+ }
+ mbstat.m_clusters += ncl;
+ return (1);
+#else // __ECOS
+ volatile static struct timeval lastlogged;
+ struct timeval curtime, logdiff;
+ register caddr_t p;
+ register int i;
+ int npg, s;
+
+ npg = ncl * CLSIZE;
+#if defined(UVM)
+ p = (caddr_t)uvm_km_kmemalloc(mb_map, uvmexp.mb_object, ctob(npg),
+ nowait ? 0 : UVM_KMF_NOWAIT);
+#else
+ p = (caddr_t)kmem_malloc(mb_map, ctob(npg), !nowait);
+#endif
+ if (p == NULL) {
+ s = splclock();
+ curtime = time;
+ splx(s);
+ timersub(&curtime, &lastlogged, &logdiff);
+ if (logdiff.tv_sec >= 60) {
+ lastlogged = curtime;
+ log(LOG_ERR, "mb_map full\n");
+ }
+ m_reclaim();
+ return (mclfree != NULL);
+ }
+ ncl = ncl * CLBYTES / MCLBYTES;
+ for (i = 0; i < ncl; i++) {
+ ((union mcluster *)p)->mcl_next = mclfree;
+ mclfree = (union mcluster *)p;
+ p += MCLBYTES;
+ mbstat.m_clfree++;
+ }
+ mbstat.m_clusters += ncl;
+ return (1);
+#endif // __ECOS
+}
+
+/*
+ * When MGET failes, ask protocols to free space when short of memory,
+ * then re-attempt to allocate an mbuf.
+ */
+struct mbuf *
+m_retry(i, t)
+ int i, t;
+{
+ register struct mbuf *m;
+
+ if (i & M_DONTWAIT) {
+ needqueuedrain = 1;
+ setsoftnet();
+ return (NULL);
+ }
+ m_reclaim();
+#define m_retry(i, t) NULL
+ MGET(m, i, t);
+#undef m_retry
+ return (m);
+}
+
+/*
+ * As above; retry an MGETHDR.
+ */
+struct mbuf *
+m_retryhdr(i, t)
+ int i, t;
+{
+ register struct mbuf *m;
+
+ if (i & M_DONTWAIT) {
+ needqueuedrain = 1;
+ setsoftnet();
+ return (NULL);
+ }
+ m_reclaim();
+#define m_retryhdr(i, t) NULL
+ MGETHDR(m, i, t);
+#undef m_retryhdr
+ return (m);
+}
+
+void
+m_reclaim()
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+ int s = splimp();
+
+ needqueuedrain = 0;
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_drain)
+ (*pr->pr_drain)();
+ splx(s);
+ mbstat.m_drain++;
+}
+
+/*
+ * Space allocation routines.
+ * These are also available as macros
+ * for critical paths.
+ */
+struct mbuf *
+m_get(nowait, type)
+ int nowait, type;
+{
+ register struct mbuf *m;
+
+ MGET(m, nowait, type);
+ return (m);
+}
+
+struct mbuf *
+m_gethdr(nowait, type)
+ int nowait, type;
+{
+ register struct mbuf *m;
+
+ MGETHDR(m, nowait, type);
+ return (m);
+}
+
+struct mbuf *
+m_getclr(nowait, type)
+ int nowait, type;
+{
+ register struct mbuf *m;
+
+ MGET(m, nowait, type);
+ if (m == NULL)
+ return (NULL);
+ bzero(mtod(m, caddr_t), MLEN);
+ return (m);
+}
+
+struct mbuf *
+m_free(m)
+ struct mbuf *m;
+{
+ register struct mbuf *n;
+
+ MFREE(m, n);
+ return (n);
+}
+
+void
+m_freem(m)
+ register struct mbuf *m;
+{
+ register struct mbuf *n;
+
+ if (m == NULL)
+ return;
+ do {
+ MFREE(m, n);
+ } while ((m = n) != NULL);
+}
+
+/*
+ * Mbuffer utility routines.
+ */
+
+/*
+ * Lesser-used path for M_PREPEND:
+ * allocate new mbuf to prepend to chain,
+ * copy junk along.
+ */
+struct mbuf *
+m_prepend(m, len, how)
+ register struct mbuf *m;
+ int len, how;
+{
+ struct mbuf *mn;
+
+ MGET(mn, how, m->m_type);
+ if (mn == NULL) {
+ m_freem(m);
+ return (NULL);
+ }
+ if (m->m_flags & M_PKTHDR) {
+ M_COPY_PKTHDR(mn, m);
+ m->m_flags &= ~M_PKTHDR;
+ }
+ mn->m_next = m;
+ m = mn;
+ if (len < MHLEN)
+ MH_ALIGN(m, len);
+ m->m_len = len;
+ return (m);
+}
+
+/*
+ * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
+ * continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf.
+ * The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
+ */
+int MCFail;
+
+struct mbuf *
+m_copym(m, off0, len, wait)
+ register struct mbuf *m;
+ int off0, wait;
+ register int len;
+{
+ register struct mbuf *n, **np;
+ register int off = off0;
+ struct mbuf *top;
+ int copyhdr = 0;
+
+ if (off < 0)
+ panic("m_copym: off %d < 0", off);
+ if (len < 0)
+ panic("m_copym: len %d < 0", len);
+ if (off == 0 && m->m_flags & M_PKTHDR)
+ copyhdr = 1;
+ while (off > 0) {
+ if (m == NULL)
+ panic("m_copym: null mbuf");
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ np = &top;
+ top = NULL;
+ while (len > 0) {
+ if (m == NULL) {
+ if (len != M_COPYALL)
+ panic("m_copym: %d not M_COPYALL", len);
+ break;
+ }
+ MGET(n, wait, m->m_type);
+ *np = n;
+ if (n == NULL)
+ goto nospace;
+ if (copyhdr) {
+ M_COPY_PKTHDR(n, m);
+ if (len == M_COPYALL)
+ n->m_pkthdr.len -= off0;
+ else
+ n->m_pkthdr.len = len;
+ copyhdr = 0;
+ }
+ n->m_len = min(len, m->m_len - off);
+ if (m->m_flags & M_EXT) {
+ n->m_data = m->m_data + off;
+ if (!m->m_ext.ext_ref)
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ else
+ (*(m->m_ext.ext_ref))(m);
+ n->m_ext = m->m_ext;
+ n->m_flags |= M_EXT;
+ } else
+ bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
+ (unsigned)n->m_len);
+ if (len != M_COPYALL)
+ len -= n->m_len;
+ off = 0;
+ m = m->m_next;
+ np = &n->m_next;
+ }
+ if (top == NULL)
+ MCFail++;
+ return (top);
+nospace:
+ m_freem(top);
+ MCFail++;
+ return (NULL);
+}
+
+/*
+ * m_copym2() is like m_copym(), except it COPIES cluster mbufs, instead
+ * of merely bumping the reference count.
+ */
+struct mbuf *
+m_copym2(m, off0, len, wait)
+ register struct mbuf *m;
+ int off0, wait;
+ register int len;
+{
+ register struct mbuf *n, **np;
+ register int off = off0;
+ struct mbuf *top;
+ int copyhdr = 0;
+
+ if (len < 0)
+ panic("m_copym2: len %d < 0", len);
+ if (off < 0)
+ panic("m_copym2: off %d < 0", off);
+ if (off == 0 && m->m_flags & M_PKTHDR)
+ copyhdr = 1;
+ while (off > 0) {
+ if (m == NULL)
+ panic("m_copym2: null mbuf");
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ np = &top;
+ top = NULL;
+ while (len > 0) {
+ if (m == NULL) {
+ if (len != M_COPYALL)
+ panic("m_copym2: %d != M_COPYALL", len);
+ break;
+ }
+ MGET(n, wait, m->m_type);
+ *np = n;
+ if (n == NULL)
+ goto nospace;
+ if (copyhdr) {
+ M_COPY_PKTHDR(n, m);
+ if (len == M_COPYALL)
+ n->m_pkthdr.len -= off0;
+ else
+ n->m_pkthdr.len = len;
+ copyhdr = 0;
+ }
+ n->m_len = min(len, m->m_len - off);
+ if ((m->m_flags & M_EXT) && (n->m_len > MHLEN)) {
+ /* This is a cheesy hack. */
+ MCLGET(n, wait);
+ if (n->m_flags & M_EXT)
+ bcopy(mtod(m, caddr_t) + off, mtod(n, caddr_t),
+ (unsigned)n->m_len);
+ else
+ goto nospace;
+ } else
+ bcopy(mtod(m, caddr_t) + off, mtod(n, caddr_t),
+ (unsigned)n->m_len);
+ if (len != M_COPYALL)
+ len -= n->m_len;
+ off = 0;
+ m = m->m_next;
+ np = &n->m_next;
+ }
+ if (top == NULL)
+ MCFail++;
+ return (top);
+nospace:
+ m_freem(top);
+ MCFail++;
+ return (NULL);
+}
+
+/*
+ * Copy data from an mbuf chain starting "off" bytes from the beginning,
+ * continuing for "len" bytes, into the indicated buffer.
+ */
+void
+m_copydata(m, off, len, cp)
+ register struct mbuf *m;
+ register int off;
+ register int len;
+ caddr_t cp;
+{
+ register unsigned count;
+
+ if (off < 0)
+ panic("m_copydata: off %d < 0", off);
+ if (len < 0)
+ panic("m_copydata: len %d < 0", len);
+ while (off > 0) {
+ if (m == NULL)
+ panic("m_copydata: null mbuf in skip");
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ while (len > 0) {
+ if (m == NULL)
+ panic("m_copydata: null mbuf");
+ count = min(m->m_len - off, len);
+ bcopy(mtod(m, caddr_t) + off, cp, count);
+ len -= count;
+ cp += count;
+ off = 0;
+ m = m->m_next;
+ }
+}
+
+/*
+ * Concatenate mbuf chain n to m.
+ * Both chains must be of the same type (e.g. MT_DATA).
+ * Any m_pkthdr is not updated.
+ */
+void
+m_cat(m, n)
+ register struct mbuf *m, *n;
+{
+ while (m->m_next)
+ m = m->m_next;
+ while (n) {
+ if (m->m_flags & M_EXT ||
+ m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
+ /* just join the two chains */
+ m->m_next = n;
+ return;
+ }
+ /* splat the data from one into the other */
+ bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
+ (u_int)n->m_len);
+ m->m_len += n->m_len;
+ n = m_free(n);
+ }
+}
+
+void
+m_adj(mp, req_len)
+ struct mbuf *mp;
+ int req_len;
+{
+ register int len = req_len;
+ register struct mbuf *m;
+ register int count;
+
+ if ((m = mp) == NULL)
+ return;
+ if (len >= 0) {
+ /*
+ * Trim from head.
+ */
+ while (m != NULL && len > 0) {
+ if (m->m_len <= len) {
+ len -= m->m_len;
+ m->m_len = 0;
+ m = m->m_next;
+ } else {
+ m->m_len -= len;
+ m->m_data += len;
+ len = 0;
+ }
+ }
+ m = mp;
+ if (mp->m_flags & M_PKTHDR)
+ m->m_pkthdr.len -= (req_len - len);
+ } else {
+ /*
+ * Trim from tail. Scan the mbuf chain,
+ * calculating its length and finding the last mbuf.
+ * If the adjustment only affects this mbuf, then just
+ * adjust and return. Otherwise, rescan and truncate
+ * after the remaining size.
+ */
+ len = -len;
+ count = 0;
+ for (;;) {
+ count += m->m_len;
+ if (m->m_next == NULL)
+ break;
+ m = m->m_next;
+ }
+ if (m->m_len >= len) {
+ m->m_len -= len;
+ if (mp->m_flags & M_PKTHDR)
+ mp->m_pkthdr.len -= len;
+ return;
+ }
+ count -= len;
+ if (count < 0)
+ count = 0;
+ /*
+ * Correct length for chain is "count".
+ * Find the mbuf with last data, adjust its length,
+ * and toss data from remaining mbufs on chain.
+ */
+ m = mp;
+ if (m->m_flags & M_PKTHDR)
+ m->m_pkthdr.len = count;
+ for (; m; m = m->m_next) {
+ if (m->m_len >= count) {
+ m->m_len = count;
+ break;
+ }
+ count -= m->m_len;
+ }
+ while ((m = m->m_next) != NULL)
+ m->m_len = 0;
+ }
+}
+
+/*
+ * Rearange an mbuf chain so that len bytes are contiguous
+ * and in the data area of an mbuf (so that mtod and dtom
+ * will work for a structure of size len). Returns the resulting
+ * mbuf chain on success, frees it and returns null on failure.
+ * If there is room, it will add up to max_protohdr-len extra bytes to the
+ * contiguous region in an attempt to avoid being called next time.
+ */
+int MPFail;
+
+struct mbuf *
+m_pullup(n, len)
+ register struct mbuf *n;
+ int len;
+{
+ register struct mbuf *m;
+ register int count;
+ int space;
+
+ /*
+ * If first mbuf has no cluster, and has room for len bytes
+ * without shifting current data, pullup into it,
+ * otherwise allocate a new mbuf to prepend to the chain.
+ */
+ if ((n->m_flags & M_EXT) == 0 &&
+ n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
+ if (n->m_len >= len)
+ return (n);
+ m = n;
+ n = n->m_next;
+ len -= m->m_len;
+ } else {
+ if (len > MHLEN)
+ goto bad;
+ MGET(m, M_DONTWAIT, n->m_type);
+ if (m == NULL)
+ goto bad;
+ m->m_len = 0;
+ if (n->m_flags & M_PKTHDR) {
+ M_COPY_PKTHDR(m, n);
+ n->m_flags &= ~M_PKTHDR;
+ }
+ }
+ space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
+ do {
+ count = min(min(max(len, max_protohdr), space), n->m_len);
+ bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
+ (unsigned)count);
+ len -= count;
+ m->m_len += count;
+ n->m_len -= count;
+ space -= count;
+ if (n->m_len)
+ n->m_data += count;
+ else
+ n = m_free(n);
+ } while (len > 0 && n);
+ if (len > 0) {
+ (void)m_free(m);
+ goto bad;
+ }
+ m->m_next = n;
+ return (m);
+bad:
+ m_freem(n);
+ MPFail++;
+ return (NULL);
+}
+
+/*
+ * m_pullup2() works like m_pullup, save that len can be <= MCLBYTES.
+ * m_pullup2() only works on values of len such that MHLEN < len <= MCLBYTES,
+ * it calls m_pullup() for values <= MHLEN. It also only coagulates the
+ * reqested number of bytes. (For those of us who expect unwieldly option
+ * headers.
+ *
+ * KEBE SAYS: Remember that dtom() calls with data in clusters does not work!
+ */
+struct mbuf *
+m_pullup2(n, len)
+ register struct mbuf *n;
+ int len;
+{
+ register struct mbuf *m;
+ register int count;
+ int space;
+ if (len <= MHLEN)
+ return m_pullup(n, len);
+
+ if ((n->m_flags & M_EXT) != 0 &&
+ n->m_data + len < &n->m_data[MCLBYTES] && n->m_next) {
+ if (n->m_len >= len)
+ return (n);
+ m = n;
+ n = n->m_next;
+ len -= m->m_len;
+ } else {
+ if (len > MCLBYTES)
+ goto bad;
+ MGET(m, M_DONTWAIT, n->m_type);
+ if (m == NULL)
+ goto bad;
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0)
+ goto bad;
+ m->m_len = 0;
+ if (n->m_flags & M_PKTHDR) {
+ /* M_COPY_PKTHDR(m, n);*//* Too many adverse side effects. */
+ m->m_pkthdr = n->m_pkthdr;
+ m->m_flags = (n->m_flags & M_COPYFLAGS) | M_EXT;
+ n->m_flags &= ~M_PKTHDR;
+ /* n->m_data is cool. */
+ }
+ }
+
+ do {
+ count = min(len, n->m_len);
+ bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
+ (unsigned)count);
+ len -= count;
+ m->m_len += count;
+ n->m_len -= count;
+ space -= count;
+ if (n->m_len)
+ n->m_data += count;
+ else
+ n = m_free(n);
+ } while (len > 0 && n);
+ if (len > 0) {
+ (void)m_free(m);
+ goto bad;
+ }
+ m->m_next = n;
+
+ return (m);
+bad:
+ m_freem(n);
+ MPFail++;
+ return (NULL);
+}
+
+/*
+ * Inject a new mbuf chain of length siz in mbuf chain m0 at
+ * position len0. Returns a pointer to the first injected mbuf, or
+ * NULL on failure (m0 is left undisturbed). Note that if there is
+ * enough space for an object of size siz in the appropriate position,
+ * no memory will be allocated. Also, there will be no data movement in
+ * the first len0 bytes (pointers to that will remain valid).
+ *
+ * XXX It is assumed that siz is less than the size of an mbuf at the moment.
+ */
+struct mbuf *
+m_inject(m0, len0, siz, wait)
+ register struct mbuf *m0;
+ int len0, siz, wait;
+{
+ register struct mbuf *m, *n, *n2 = NULL, *n3;
+ unsigned len = len0, remain;
+
+ if ((siz >= MHLEN) || (len0 <= 0))
+ return (NULL);
+ for (m = m0; m && len > m->m_len; m = m->m_next)
+ len -= m->m_len;
+ if (m == NULL)
+ return (NULL);
+ remain = m->m_len - len;
+ if (remain == 0) {
+ if ((m->m_next) && (M_LEADINGSPACE(m->m_next) >= siz)) {
+ m->m_next->m_len += siz;
+ m0->m_pkthdr.len += siz;
+ m->m_next->m_data -= siz;
+ return m->m_next;
+ }
+ } else {
+ n2 = m_copym2(m, len, remain, wait);
+ if (n2 == NULL)
+ return (NULL);
+ }
+
+ MGET(n, wait, MT_DATA);
+ if (n == NULL) {
+ if (n2)
+ m_freem(n2);
+ return (NULL);
+ }
+
+ n->m_len = siz;
+ m0->m_pkthdr.len += siz;
+ m->m_len -= remain; /* Trim */
+ if (n2) {
+ for (n3 = n; n3->m_next != NULL; n3 = n3->m_next)
+ ;
+ n3->m_next = n2;
+ } else
+ n3 = n;
+ for (; n3->m_next != NULL; n3 = n3->m_next)
+ ;
+ n3->m_next = m->m_next;
+ m->m_next = n;
+ return n;
+}
+
+/*
+ * Partition an mbuf chain in two pieces, returning the tail --
+ * all but the first len0 bytes. In case of failure, it returns NULL and
+ * attempts to restore the chain to its original state.
+ */
+struct mbuf *
+m_split(m0, len0, wait)
+ register struct mbuf *m0;
+ int len0, wait;
+{
+ register struct mbuf *m, *n;
+ unsigned len = len0, remain, olen;
+
+ for (m = m0; m && len > m->m_len; m = m->m_next)
+ len -= m->m_len;
+ if (m == NULL)
+ return (NULL);
+ remain = m->m_len - len;
+ if (m0->m_flags & M_PKTHDR) {
+ MGETHDR(n, wait, m0->m_type);
+ if (n == NULL)
+ return (NULL);
+ n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
+ n->m_pkthdr.len = m0->m_pkthdr.len - len0;
+ olen = m0->m_pkthdr.len;
+ m0->m_pkthdr.len = len0;
+ if (m->m_flags & M_EXT)
+ goto extpacket;
+ if (remain > MHLEN) {
+ /* m can't be the lead packet */
+ MH_ALIGN(n, 0);
+ n->m_next = m_split(m, len, wait);
+ if (n->m_next == NULL) {
+ (void) m_free(n);
+ m0->m_pkthdr.len = olen;
+ return (NULL);
+ } else
+ return (n);
+ } else
+ MH_ALIGN(n, remain);
+ } else if (remain == 0) {
+ n = m->m_next;
+ m->m_next = NULL;
+ return (n);
+ } else {
+ MGET(n, wait, m->m_type);
+ if (n == NULL)
+ return (NULL);
+ M_ALIGN(n, remain);
+ }
+extpacket:
+ if (m->m_flags & M_EXT) {
+ n->m_flags |= M_EXT;
+ n->m_ext = m->m_ext;
+ if(!m->m_ext.ext_ref)
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ else
+ (*(m->m_ext.ext_ref))(m);
+ m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */
+ n->m_data = m->m_data + len;
+ } else {
+ bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
+ }
+ n->m_len = remain;
+ m->m_len = len;
+ n->m_next = m->m_next;
+ m->m_next = NULL;
+ return (n);
+}
+/*
+ * Routine to copy from device local memory into mbufs.
+ */
+struct mbuf *
+m_devget(buf, totlen, off0, ifp, copy)
+ char *buf;
+ int totlen, off0;
+ struct ifnet *ifp;
+ void (*copy) __P((const void *, void *, size_t));
+{
+ register struct mbuf *m;
+ struct mbuf *top = NULL, **mp = &top;
+ register int off = off0, len;
+ register char *cp;
+ char *epkt;
+
+ cp = buf;
+ epkt = cp + totlen;
+ if (off) {
+ /*
+ * If 'off' is non-zero, packet is trailer-encapsulated,
+ * so we have to skip the type and length fields.
+ */
+ cp += off + 2 * sizeof(u_int16_t);
+ totlen -= 2 * sizeof(u_int16_t);
+ }
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return (NULL);
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = totlen;
+ m->m_len = MHLEN;
+
+ while (totlen > 0) {
+ if (top != NULL) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ m_freem(top);
+ return (NULL);
+ }
+ m->m_len = MLEN;
+ }
+ len = min(totlen, epkt - cp);
+ if (len >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ m->m_len = len = min(len, MCLBYTES);
+ else
+ len = m->m_len;
+ } else {
+ /*
+ * Place initial small packet/header at end of mbuf.
+ */
+ if (len < m->m_len) {
+ if (top == NULL &&
+ len + max_linkhdr <= m->m_len)
+ m->m_data += max_linkhdr;
+ m->m_len = len;
+ } else
+ len = m->m_len;
+ }
+ if (copy)
+ copy(cp, mtod(m, caddr_t), (size_t)len);
+ else
+ bcopy(cp, mtod(m, caddr_t), (size_t)len);
+ cp += len;
+ *mp = m;
+ mp = &m->m_next;
+ totlen -= len;
+ if (cp == epkt)
+ cp = buf;
+ }
+ return (top);
+}
+
+void
+m_zero(m)
+ struct mbuf *m;
+{
+ while (m) {
+ if (m->m_flags & M_PKTHDR)
+ bzero((unsigned char *)m + sizeof(struct m_hdr) +
+ sizeof(struct pkthdr), MHLEN);
+ else
+ bzero((unsigned char *)m + sizeof(struct m_hdr), MLEN);
+ if ((m->m_flags & M_EXT) &&
+ (m->m_ext.ext_free == NULL) &&
+ !mclrefcnt[mtocl((m)->m_ext.ext_buf)])
+ bzero(m->m_ext.ext_buf, m->m_ext.ext_size);
+ m = m->m_next;
+ }
+}
+
+/*
+ * Apply function f to the data in an mbuf chain starting "off" bytes from the
+ * beginning, continuing for "len" bytes.
+ */
+int
+m_apply(m, off, len, f, fstate)
+ struct mbuf *m;
+ int off;
+ int len;
+ /* fstate, data, len */
+ int (*f)(caddr_t, caddr_t, unsigned int);
+ caddr_t fstate;
+{
+ int rval;
+ unsigned int count;
+
+ if (len < 0)
+ panic("m_apply: len %d < 0", len);
+ if (off < 0)
+ panic("m_apply: off %d < 0", off);
+ while (off > 0) {
+ if (m == NULL)
+ panic("m_apply: null mbuf in skip");
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ while (len > 0) {
+ if (m == NULL)
+ panic("m_apply: null mbuf");
+ count = min(m->m_len - off, len);
+
+ rval = f(fstate, mtod(m, caddr_t) + off, count);
+ if (rval)
+ return (rval);
+
+ len -= count;
+ off = 0;
+ m = m->m_next;
+ }
+
+ return (0);
+}
+
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/uipc_proto.c b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_proto.c
new file mode 100644
index 0000000..7439f49
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_proto.c
@@ -0,0 +1,105 @@
+//==========================================================================
+//
+// sys/kern/uipc_proto.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: uipc_proto.c,v 1.3 1998/04/26 22:40:42 millert Exp $ */
+/* $NetBSD: uipc_proto.c,v 1.8 1996/02/13 21:10:47 christos Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)uipc_proto.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+#include <sys/un.h>
+#include <sys/socketvar.h>
+
+#include <net/if.h>
+#include <net/raw_cb.h>
+
+/*
+ * Definitions of protocols supported in the UNIX domain.
+ */
+
+extern struct domain unixdomain; /* or at least forward */
+
+struct protosw unixsw[] = {
+{ SOCK_STREAM, &unixdomain, PF_LOCAL, PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
+ 0, 0, 0, 0,
+ uipc_usrreq,
+ 0, 0, 0, 0,
+},
+{ SOCK_DGRAM, &unixdomain, PF_LOCAL, PR_ATOMIC|PR_ADDR|PR_RIGHTS,
+ 0, 0, 0, 0,
+ uipc_usrreq,
+ 0, 0, 0, 0,
+},
+{ 0, 0, 0, 0,
+ raw_input, 0, raw_ctlinput, 0,
+ raw_usrreq,
+ raw_init, 0, 0, 0,
+}
+};
+
+struct domain unixdomain =
+ { AF_LOCAL, "unix", 0, unp_externalize, unp_dispose,
+ unixsw, &unixsw[sizeof(unixsw)/sizeof(unixsw[0])] };
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket.c b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket.c
new file mode 100644
index 0000000..c840164
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket.c
@@ -0,0 +1,1144 @@
+//==========================================================================
+//
+// sys/kern/uipc_socket.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: uipc_socket.c,v 1.27 1999/10/14 08:18:49 cmetz Exp $ */
+/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
+ */
+
+#include <sys/param.h>
+#ifdef __ECOS
+#include <cyg/io/file.h>
+#else
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/kernel.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#ifndef __ECOS
+#include <sys/signalvar.h>
+#include <sys/resourcevar.h>
+#endif
+
+#ifndef SOMINCONN
+#define SOMINCONN 80
+#endif /* SOMINCONN */
+
+int somaxconn = SOMAXCONN;
+int sominconn = SOMINCONN;
+
+/*
+ * Socket operation routines.
+ * These routines are called by the routines in
+ * sys_socket.c or from a system process, and
+ * implement the semantics of socket operations by
+ * switching out to the protocol specific routines.
+ */
+/*ARGSUSED*/
+int
+socreate(dom, aso, type, proto)
+ int dom;
+ struct socket **aso;
+ register int type;
+ int proto;
+{
+#ifndef __ECOS
+ struct proc *p = curproc; /* XXX */
+#endif
+ register struct protosw *prp;
+ register struct socket *so;
+ register int error;
+
+ if (proto)
+ prp = pffindproto(dom, proto, type);
+ else
+ prp = pffindtype(dom, type);
+ if (prp == 0 || prp->pr_usrreq == 0)
+ return (EPROTONOSUPPORT);
+ if (prp->pr_type != type)
+ return (EPROTOTYPE);
+ MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
+ bzero((caddr_t)so, sizeof(*so));
+ so->so_type = type;
+#ifdef __ECOS
+ so->so_state = SS_PRIV;
+ so->so_ruid = 0; // FIXME
+ so->so_euid = 0; // FIXME
+#else
+ if (p->p_ucred->cr_uid == 0)
+ so->so_state = SS_PRIV;
+ so->so_ruid = p->p_cred->p_ruid;
+ so->so_euid = p->p_ucred->cr_uid;
+#endif
+ so->so_proto = prp;
+ error =
+ (*prp->pr_usrreq)(so, PRU_ATTACH, NULL, (struct mbuf *)(long)proto,
+ NULL);
+ if (error) {
+ so->so_state |= SS_NOFDREF;
+ sofree(so);
+ return (error);
+ }
+#ifdef COMPAT_SUNOS
+ {
+ extern struct emul emul_sunos;
+ if (p->p_emul == &emul_sunos && type == SOCK_DGRAM)
+ so->so_options |= SO_BROADCAST;
+ }
+#endif
+ *aso = so;
+ return (0);
+}
+
+int
+sobind(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ int s = splsoftnet();
+ int error;
+
+ error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL);
+ splx(s);
+ return (error);
+}
+
+int
+solisten(so, backlog)
+ register struct socket *so;
+ int backlog;
+{
+ int s = splsoftnet(), error;
+
+ error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ if (so->so_q == 0)
+ so->so_options |= SO_ACCEPTCONN;
+ if (backlog < 0 || backlog > somaxconn)
+ backlog = somaxconn;
+ if (backlog < sominconn)
+ backlog = sominconn;
+ so->so_qlimit = backlog;
+ splx(s);
+ return (0);
+}
+
+void
+sofree(so)
+ register struct socket *so;
+{
+
+ if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
+ return;
+ if (so->so_head) {
+ /*
+ * We must not decommission a socket that's on the accept(2)
+ * queue. If we do, then accept(2) may hang after select(2)
+ * indicated that the listening socket was ready.
+ */
+ if (!soqremque(so, 0))
+ return;
+ }
+ sbrelease(&so->so_snd);
+ sorflush(so);
+ FREE(so, M_SOCKET);
+}
+
+/*
+ * Close a socket on last file table reference removal.
+ * Initiate disconnect if connected.
+ * Free socket when disconnect complete.
+ */
+int
+soclose(so)
+ register struct socket *so;
+{
+ struct socket *so2;
+ int s = splsoftnet(); /* conservative */
+ int error = 0;
+
+ if (so->so_options & SO_ACCEPTCONN) {
+ while ((so2 = so->so_q0) != NULL) {
+ (void) soqremque(so2, 0);
+ (void) soabort(so2);
+ }
+ while ((so2 = so->so_q) != NULL) {
+ (void) soqremque(so2, 1);
+ (void) soabort(so2);
+ }
+ }
+ if (so->so_pcb == 0)
+ goto discard;
+ if (so->so_state & SS_ISCONNECTED) {
+ if ((so->so_state & SS_ISDISCONNECTING) == 0) {
+ error = sodisconnect(so);
+ if (error)
+ goto drop;
+ }
+ if (so->so_options & SO_LINGER) {
+ if ((so->so_state & SS_ISDISCONNECTING) &&
+ (so->so_state & SS_NBIO))
+ goto drop;
+ while (so->so_state & SS_ISCONNECTED) {
+ error = tsleep((caddr_t)&so->so_timeo,
+ PSOCK | PCATCH, netcls,
+ so->so_linger * hz);
+ if (error)
+ break;
+ }
+ }
+ }
+drop:
+ if (so->so_pcb) {
+ int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, NULL,
+ NULL, NULL);
+ if (error == 0)
+ error = error2;
+ }
+discard:
+ if (so->so_state & SS_NOFDREF)
+ panic("soclose: NOFDREF");
+ so->so_state |= SS_NOFDREF;
+ sofree(so);
+ splx(s);
+ return (error);
+}
+
+/*
+ * Must be called at splsoftnet...
+ */
+int
+soabort(so)
+ struct socket *so;
+{
+
+ return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, NULL, NULL, NULL);
+}
+
+int
+soaccept(so, nam)
+ register struct socket *so;
+ struct mbuf *nam;
+{
+ int s = splsoftnet();
+ int error = 0;
+
+ if ((so->so_state & SS_NOFDREF) == 0)
+ panic("soaccept: !NOFDREF");
+ so->so_state &= ~SS_NOFDREF;
+ if ((so->so_state & SS_ISDISCONNECTED) == 0)
+ error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL,
+ nam, NULL);
+ splx(s);
+ return (error);
+}
+
+int
+soconnect(so, nam)
+ register struct socket *so;
+ struct mbuf *nam;
+{
+ int s;
+ int error;
+
+ if (so->so_options & SO_ACCEPTCONN)
+ return (EOPNOTSUPP);
+ s = splsoftnet();
+ /*
+ * If protocol is connection-based, can only connect once.
+ * Otherwise, if connected, try to disconnect first.
+ * This allows user to disconnect by connecting to, e.g.,
+ * a null address.
+ */
+ if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
+ ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
+ (error = sodisconnect(so))))
+ error = EISCONN;
+ else
+ error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
+ NULL, nam, NULL);
+ splx(s);
+ return (error);
+}
+
+int
+soconnect2(so1, so2)
+ register struct socket *so1;
+ struct socket *so2;
+{
+ int s = splsoftnet();
+ int error;
+
+ error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, NULL,
+ (struct mbuf *)so2, NULL);
+ splx(s);
+ return (error);
+}
+
+int
+sodisconnect(so)
+ register struct socket *so;
+{
+ int s = splsoftnet();
+ int error;
+
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ error = ENOTCONN;
+ goto bad;
+ }
+ if (so->so_state & SS_ISDISCONNECTING) {
+ error = EALREADY;
+ goto bad;
+ }
+ error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, NULL, NULL,
+ NULL);
+bad:
+ splx(s);
+ return (error);
+}
+
+#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
+/*
+ * Send on a socket.
+ * If send must go all at once and message is larger than
+ * send buffering, then hard error.
+ * Lock against other senders.
+ * If must go all at once and not enough room now, then
+ * inform user that this would block and do nothing.
+ * Otherwise, if nonblocking, send as much as possible.
+ * The data to be sent is described by "uio" if nonzero,
+ * otherwise by the mbuf chain "top" (which must be null
+ * if uio is not). Data provided in mbuf chain must be small
+ * enough to send all at once.
+ *
+ * Returns nonzero on error, timeout or signal; callers
+ * must check for short counts if EINTR/ERESTART are returned.
+ * Data and control buffers are freed on return.
+ */
+int
+sosend(so, addr, uio, top, control, flags)
+ register struct socket *so;
+ struct mbuf *addr;
+ struct uio *uio;
+ struct mbuf *top;
+ struct mbuf *control;
+ int flags;
+{
+#ifndef __ECOS
+ struct proc *p = curproc; /* XXX */
+#endif
+ struct mbuf **mp;
+ register struct mbuf *m;
+ register long space, len;
+ register quad_t resid;
+ int clen = 0, error, s, dontroute, mlen;
+ int atomic = sosendallatonce(so) || top;
+
+ if (uio)
+ resid = uio->uio_resid;
+ else
+ resid = top->m_pkthdr.len;
+ /*
+ * In theory resid should be unsigned (since uio->uio_resid is).
+ * However, space must be signed, as it might be less than 0
+ * if we over-committed, and we must use a signed comparison
+ * of space and resid. On the other hand, a negative resid
+ * causes us to loop sending 0-length segments to the protocol.
+ * MSG_EOR on a SOCK_STREAM socket is also invalid.
+ */
+ if (resid < 0 ||
+ (so->so_type == SOCK_STREAM && (flags & MSG_EOR))) {
+ error = EINVAL;
+ goto out;
+ }
+ dontroute =
+ (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
+ (so->so_proto->pr_flags & PR_ATOMIC);
+#ifndef __ECOS
+ p->p_stats->p_ru.ru_msgsnd++;
+#endif
+ if (control)
+ clen = control->m_len;
+#define snderr(errno) { error = errno; splx(s); goto release; }
+
+restart:
+ if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
+ goto out;
+ do {
+ s = splsoftnet();
+ if (so->so_state & SS_CANTSENDMORE)
+ snderr(EPIPE);
+ if (so->so_error)
+ snderr(so->so_error);
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
+ if ((so->so_state & SS_ISCONFIRMING) == 0 &&
+ !(resid == 0 && clen != 0))
+ snderr(ENOTCONN);
+ } else if (addr == 0)
+ snderr(EDESTADDRREQ);
+ }
+ space = sbspace(&so->so_snd);
+ if (flags & MSG_OOB)
+ space += 1024;
+ if ((atomic && resid > so->so_snd.sb_hiwat) ||
+ clen > so->so_snd.sb_hiwat)
+ snderr(EMSGSIZE);
+ if (space < resid + clen && uio &&
+ (atomic || space < so->so_snd.sb_lowat || space < clen)) {
+ if (so->so_state & SS_NBIO)
+ snderr(EWOULDBLOCK);
+ sbunlock(&so->so_snd);
+ error = sbwait(&so->so_snd);
+ splx(s);
+ if (error)
+ goto out;
+ goto restart;
+ }
+ splx(s);
+ mp = &top;
+ space -= clen;
+ do {
+ if (uio == NULL) {
+ /*
+ * Data is prepackaged in "top".
+ */
+ resid = 0;
+ if (flags & MSG_EOR)
+ top->m_flags |= M_EOR;
+ } else do {
+ if (top == 0) {
+ MGETHDR(m, M_WAIT, MT_DATA);
+ mlen = MHLEN;
+ m->m_pkthdr.len = 0;
+ m->m_pkthdr.rcvif = (struct ifnet *)0;
+ } else {
+ MGET(m, M_WAIT, MT_DATA);
+ mlen = MLEN;
+ }
+ if (resid >= MINCLSIZE && space >= MCLBYTES) {
+ MCLGET(m, M_WAIT);
+ if ((m->m_flags & M_EXT) == 0)
+ goto nopages;
+ mlen = MCLBYTES;
+#ifdef MAPPED_MBUFS
+ len = min(MCLBYTES, resid);
+#else
+ if (atomic && top == 0) {
+ len = min(MCLBYTES - max_hdr, resid);
+ m->m_data += max_hdr;
+ } else
+ len = min(MCLBYTES, resid);
+#endif
+ space -= len;
+ } else {
+nopages:
+ len = min(min(mlen, resid), space);
+ space -= len;
+ /*
+ * For datagram protocols, leave room
+ * for protocol headers in first mbuf.
+ */
+ if (atomic && top == 0 && len < mlen)
+ MH_ALIGN(m, len);
+ }
+ error = uiomove(mtod(m, caddr_t), (int)len, uio);
+ resid = uio->uio_resid;
+ m->m_len = len;
+ *mp = m;
+ top->m_pkthdr.len += len;
+ if (error)
+ goto release;
+ mp = &m->m_next;
+ if (resid <= 0) {
+ if (flags & MSG_EOR)
+ top->m_flags |= M_EOR;
+ break;
+ }
+ } while (space > 0 && atomic);
+ if (dontroute)
+ so->so_options |= SO_DONTROUTE;
+ s = splsoftnet(); /* XXX */
+ error = (*so->so_proto->pr_usrreq)(so, (flags & MSG_OOB) ?
+ PRU_SENDOOB : PRU_SEND,
+ top, addr, control);
+ splx(s);
+ if (dontroute)
+ so->so_options &= ~SO_DONTROUTE;
+ clen = 0;
+ control = 0;
+ top = 0;
+ mp = &top;
+ if (error)
+ goto release;
+ } while (resid && space > 0);
+ } while (resid);
+
+release:
+ sbunlock(&so->so_snd);
+out:
+ if (top)
+ m_freem(top);
+ if (control)
+ m_freem(control);
+ return (error);
+}
+
+/*
+ * Implement receive operations on a socket.
+ * We depend on the way that records are added to the sockbuf
+ * by sbappend*. In particular, each record (mbufs linked through m_next)
+ * must begin with an address if the protocol so specifies,
+ * followed by an optional mbuf or mbufs containing ancillary data,
+ * and then zero or more mbufs of data.
+ * In order to avoid blocking network interrupts for the entire time here,
+ * we splx() while doing the actual copy to user space.
+ * Although the sockbuf is locked, new data may still be appended,
+ * and thus we must maintain consistency of the sockbuf during that time.
+ *
+ * The caller may receive the data as a single mbuf chain by supplying
+ * an mbuf **mp0 for use in returning the chain. The uio is then used
+ * only for the count in uio_resid.
+ */
+int
+soreceive(so, paddr, uio, mp0, controlp, flagsp)
+ register struct socket *so;
+ struct mbuf **paddr;
+ struct uio *uio;
+ struct mbuf **mp0;
+ struct mbuf **controlp;
+ int *flagsp;
+{
+ register struct mbuf *m, **mp;
+ register int flags, len, error, s, offset;
+ struct protosw *pr = so->so_proto;
+ struct mbuf *nextrecord;
+ int moff, type = 0;
+ size_t orig_resid = uio->uio_resid;
+ int uio_error = 0;
+ int resid;
+
+ mp = mp0;
+ if (paddr)
+ *paddr = 0;
+ if (controlp)
+ *controlp = 0;
+ if (flagsp)
+ flags = *flagsp &~ MSG_EOR;
+ else
+ flags = 0;
+ if (so->so_state & SS_NBIO)
+ flags |= MSG_DONTWAIT;
+ if (flags & MSG_OOB) {
+ m = m_get(M_WAIT, MT_DATA);
+ error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
+ (struct mbuf *)(long)(flags & MSG_PEEK), NULL);
+ if (error)
+ goto bad;
+ do {
+ error = uiomove(mtod(m, caddr_t),
+ (int) min(uio->uio_resid, m->m_len), uio);
+ m = m_free(m);
+ } while (uio->uio_resid && error == 0 && m);
+bad:
+ if (m)
+ m_freem(m);
+ return (error);
+ }
+ if (mp)
+ *mp = (struct mbuf *)0;
+ if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
+ (*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL);
+
+restart:
+ if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
+ return (error);
+ s = splsoftnet();
+
+ m = so->so_rcv.sb_mb;
+ /*
+ * If we have less data than requested, block awaiting more
+ * (subject to any timeout) if:
+ * 1. the current count is less than the low water mark,
+ * 2. MSG_WAITALL is set, and it is possible to do the entire
+ * receive operation at once if we block (resid <= hiwat), or
+ * 3. MSG_DONTWAIT is not set.
+ * If MSG_WAITALL is set but resid is larger than the receive buffer,
+ * we have to do the receive in sections, and thus risk returning
+ * a short count if a timeout or signal occurs after we start.
+ */
+ if (m == 0 || (((flags & MSG_DONTWAIT) == 0 &&
+ so->so_rcv.sb_cc < uio->uio_resid) &&
+ (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
+ ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
+ m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0)) {
+#ifdef DIAGNOSTIC
+ if (m == 0 && so->so_rcv.sb_cc)
+ panic("receive 1");
+#endif
+ if (so->so_error) {
+ if (m)
+ goto dontblock;
+ error = so->so_error;
+ if ((flags & MSG_PEEK) == 0)
+ so->so_error = 0;
+ goto release;
+ }
+ if (so->so_state & SS_CANTRCVMORE) {
+ if (m)
+ goto dontblock;
+ else
+ goto release;
+ }
+ for (; m; m = m->m_next)
+ if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) {
+ m = so->so_rcv.sb_mb;
+ goto dontblock;
+ }
+ if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
+ (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
+ error = ENOTCONN;
+ goto release;
+ }
+ if (uio->uio_resid == 0 && controlp == NULL)
+ goto release;
+ if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
+ error = EWOULDBLOCK;
+ goto release;
+ }
+ sbunlock(&so->so_rcv);
+ error = sbwait(&so->so_rcv);
+ splx(s);
+ if (error)
+ return (error);
+ goto restart;
+ }
+dontblock:
+#ifdef notyet /* XXXX */
+ if (uio->uio_procp)
+ uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
+#endif
+ nextrecord = m->m_nextpkt;
+ if (pr->pr_flags & PR_ADDR) {
+#ifdef DIAGNOSTIC
+ if (m->m_type != MT_SONAME)
+ panic("receive 1a");
+#endif
+ orig_resid = 0;
+ if (flags & MSG_PEEK) {
+ if (paddr)
+ *paddr = m_copy(m, 0, m->m_len);
+ m = m->m_next;
+ } else {
+ sbfree(&so->so_rcv, m);
+ if (paddr) {
+ *paddr = m;
+ so->so_rcv.sb_mb = m->m_next;
+ m->m_next = 0;
+ m = so->so_rcv.sb_mb;
+ } else {
+ MFREE(m, so->so_rcv.sb_mb);
+ m = so->so_rcv.sb_mb;
+ }
+ }
+ }
+ while (m && m->m_type == MT_CONTROL && error == 0) {
+ if (flags & MSG_PEEK) {
+ if (controlp)
+ *controlp = m_copy(m, 0, m->m_len);
+ m = m->m_next;
+ } else {
+ sbfree(&so->so_rcv, m);
+ if (controlp) {
+ if (pr->pr_domain->dom_externalize &&
+ mtod(m, struct cmsghdr *)->cmsg_type ==
+ SCM_RIGHTS)
+ error = (*pr->pr_domain->dom_externalize)(m);
+ *controlp = m;
+ so->so_rcv.sb_mb = m->m_next;
+ m->m_next = 0;
+ m = so->so_rcv.sb_mb;
+ } else {
+ MFREE(m, so->so_rcv.sb_mb);
+ m = so->so_rcv.sb_mb;
+ }
+ }
+ if (controlp) {
+ orig_resid = 0;
+ controlp = &(*controlp)->m_next;
+ }
+ }
+ if (m) {
+ if ((flags & MSG_PEEK) == 0)
+ m->m_nextpkt = nextrecord;
+ type = m->m_type;
+ if (type == MT_OOBDATA)
+ flags |= MSG_OOB;
+ if (m->m_flags & M_BCAST)
+ flags |= MSG_BCAST;
+ if (m->m_flags & M_MCAST)
+ flags |= MSG_MCAST;
+ }
+ moff = 0;
+ offset = 0;
+ while (m && uio->uio_resid > 0 && error == 0) {
+ if (m->m_type == MT_OOBDATA) {
+ if (type != MT_OOBDATA)
+ break;
+ } else if (type == MT_OOBDATA)
+ break;
+#ifdef DIAGNOSTIC
+ else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
+ panic("receive 3");
+#endif
+ so->so_state &= ~SS_RCVATMARK;
+ len = uio->uio_resid;
+ if (so->so_oobmark && len > so->so_oobmark - offset)
+ len = so->so_oobmark - offset;
+ if (len > m->m_len - moff)
+ len = m->m_len - moff;
+ /*
+ * If mp is set, just pass back the mbufs.
+ * Otherwise copy them out via the uio, then free.
+ * Sockbuf must be consistent here (points to current mbuf,
+ * it points to next record) when we drop priority;
+ * we must note any additions to the sockbuf when we
+ * block interrupts again.
+ */
+ if (mp == 0 && uio_error == 0) {
+ resid = uio->uio_resid;
+ splx(s);
+ uio_error =
+ uiomove(mtod(m, caddr_t) + moff, (int)len,
+ uio);
+ s = splsoftnet();
+ if (uio_error)
+ uio->uio_resid = resid - len;
+ } else
+ uio->uio_resid -= len;
+ if (len == m->m_len - moff) {
+ if (m->m_flags & M_EOR)
+ flags |= MSG_EOR;
+ if (flags & MSG_PEEK) {
+ m = m->m_next;
+ moff = 0;
+ } else {
+ nextrecord = m->m_nextpkt;
+ sbfree(&so->so_rcv, m);
+ if (mp) {
+ *mp = m;
+ mp = &m->m_next;
+ so->so_rcv.sb_mb = m = m->m_next;
+ *mp = (struct mbuf *)0;
+ } else {
+ MFREE(m, so->so_rcv.sb_mb);
+ m = so->so_rcv.sb_mb;
+ }
+ if (m)
+ m->m_nextpkt = nextrecord;
+ }
+ } else {
+ if (flags & MSG_PEEK)
+ moff += len;
+ else {
+ if (mp)
+ *mp = m_copym(m, 0, len, M_WAIT);
+ m->m_data += len;
+ m->m_len -= len;
+ so->so_rcv.sb_cc -= len;
+ }
+ }
+ if (so->so_oobmark) {
+ if ((flags & MSG_PEEK) == 0) {
+ so->so_oobmark -= len;
+ if (so->so_oobmark == 0) {
+ so->so_state |= SS_RCVATMARK;
+ break;
+ }
+ } else {
+ offset += len;
+ if (offset == so->so_oobmark)
+ break;
+ }
+ }
+ if (flags & MSG_EOR)
+ break;
+ /*
+ * If the MSG_WAITALL flag is set (for non-atomic socket),
+ * we must not quit until "uio->uio_resid == 0" or an error
+ * termination. If a signal/timeout occurs, return
+ * with a short count but without error.
+ * Keep sockbuf locked against other readers.
+ */
+ while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
+ !sosendallatonce(so) && !nextrecord) {
+ if (so->so_error || so->so_state & SS_CANTRCVMORE)
+ break;
+ error = sbwait(&so->so_rcv);
+ if (error) {
+ sbunlock(&so->so_rcv);
+ splx(s);
+ return (0);
+ }
+ if ((m = so->so_rcv.sb_mb) != NULL)
+ nextrecord = m->m_nextpkt;
+ }
+ }
+
+ if (m && pr->pr_flags & PR_ATOMIC) {
+ flags |= MSG_TRUNC;
+ if ((flags & MSG_PEEK) == 0)
+ (void) sbdroprecord(&so->so_rcv);
+ }
+ if ((flags & MSG_PEEK) == 0) {
+ if (m == 0)
+ so->so_rcv.sb_mb = nextrecord;
+ if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
+ (*pr->pr_usrreq)(so, PRU_RCVD, NULL,
+ (struct mbuf *)(long)flags, NULL);
+ }
+ if (orig_resid == uio->uio_resid && orig_resid &&
+ (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
+ sbunlock(&so->so_rcv);
+ splx(s);
+ goto restart;
+ }
+
+ if (uio_error)
+ error = uio_error;
+
+ if (flagsp)
+ *flagsp |= flags;
+release:
+ sbunlock(&so->so_rcv);
+ splx(s);
+ return (error);
+}
+
+int
+soshutdown(so, how)
+ register struct socket *so;
+ register int how;
+{
+ register struct protosw *pr = so->so_proto;
+
+ how++;
+ if (how & ~(FREAD|FWRITE))
+ return (EINVAL);
+ if (how & FREAD)
+ sorflush(so);
+ if (how & FWRITE)
+ return (*pr->pr_usrreq)(so, PRU_SHUTDOWN, NULL, NULL, NULL);
+ return (0);
+}
+
+void
+sorflush(so)
+ register struct socket *so;
+{
+ register struct sockbuf *sb = &so->so_rcv;
+ register struct protosw *pr = so->so_proto;
+ register int s;
+ struct sockbuf asb;
+
+ sb->sb_flags |= SB_NOINTR;
+ (void) sblock(sb, M_WAITOK);
+ s = splimp();
+ socantrcvmore(so);
+ sbunlock(sb);
+ asb = *sb;
+ bzero((caddr_t)sb, sizeof (*sb));
+ splx(s);
+ if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
+ (*pr->pr_domain->dom_dispose)(asb.sb_mb);
+ sbrelease(&asb);
+}
+
+int
+sosetopt(so, level, optname, m0)
+ register struct socket *so;
+ int level, optname;
+ struct mbuf *m0;
+{
+ int error = 0;
+ register struct mbuf *m = m0;
+
+ if (level != SOL_SOCKET) {
+ if (so->so_proto && so->so_proto->pr_ctloutput)
+ return ((*so->so_proto->pr_ctloutput)
+ (PRCO_SETOPT, so, level, optname, &m0));
+ error = ENOPROTOOPT;
+ } else {
+ switch (optname) {
+
+ case SO_LINGER:
+ if (m == NULL || m->m_len != sizeof (struct linger)) {
+ error = EINVAL;
+ goto bad;
+ }
+ so->so_linger = mtod(m, struct linger *)->l_linger;
+ /* fall thru... */
+
+ case SO_DEBUG:
+ case SO_KEEPALIVE:
+ case SO_DONTROUTE:
+ case SO_USELOOPBACK:
+ case SO_BROADCAST:
+ case SO_REUSEADDR:
+ case SO_REUSEPORT:
+ case SO_OOBINLINE:
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ goto bad;
+ }
+ if (*mtod(m, int *))
+ so->so_options |= optname;
+ else
+ so->so_options &= ~optname;
+ break;
+
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ case SO_SNDLOWAT:
+ case SO_RCVLOWAT:
+ {
+ u_long cnt;
+
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ goto bad;
+ }
+ cnt = *mtod(m, int *);
+ if ((long)cnt <= 0)
+ cnt = 1;
+ switch (optname) {
+
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ if (sbreserve(optname == SO_SNDBUF ?
+ &so->so_snd : &so->so_rcv,
+ cnt) == 0) {
+ error = ENOBUFS;
+ goto bad;
+ }
+ break;
+
+ case SO_SNDLOWAT:
+ so->so_snd.sb_lowat = (cnt > so->so_snd.sb_hiwat) ?
+ so->so_snd.sb_hiwat : cnt;
+ break;
+ case SO_RCVLOWAT:
+ so->so_rcv.sb_lowat = (cnt > so->so_rcv.sb_hiwat) ?
+ so->so_rcv.sb_hiwat : cnt;
+ break;
+ }
+ break;
+ }
+
+ case SO_SNDTIMEO:
+ case SO_RCVTIMEO:
+ {
+ struct timeval *tv;
+ short val;
+
+ if (m == NULL || m->m_len < sizeof (*tv)) {
+ error = EINVAL;
+ goto bad;
+ }
+ tv = mtod(m, struct timeval *);
+ if (tv->tv_sec * hz + tv->tv_usec / tick > SHRT_MAX) {
+ error = EDOM;
+ goto bad;
+ }
+ val = tv->tv_sec * hz + tv->tv_usec / tick;
+
+ switch (optname) {
+
+ case SO_SNDTIMEO:
+ so->so_snd.sb_timeo = val;
+ break;
+ case SO_RCVTIMEO:
+ so->so_rcv.sb_timeo = val;
+ break;
+ }
+ break;
+ }
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
+ (void) ((*so->so_proto->pr_ctloutput)
+ (PRCO_SETOPT, so, level, optname, &m0));
+ m = NULL; /* freed by protocol */
+ }
+ }
+bad:
+ if (m)
+ (void) m_free(m);
+ return (error);
+}
+
+int
+sogetopt(so, level, optname, mp)
+ register struct socket *so;
+ int level, optname;
+ struct mbuf **mp;
+{
+ register struct mbuf *m;
+
+ if (level != SOL_SOCKET) {
+ if (so->so_proto && so->so_proto->pr_ctloutput) {
+ return ((*so->so_proto->pr_ctloutput)
+ (PRCO_GETOPT, so, level, optname, mp));
+ } else
+ return (ENOPROTOOPT);
+ } else {
+ m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof (int);
+
+ switch (optname) {
+
+ case SO_LINGER:
+ m->m_len = sizeof (struct linger);
+ mtod(m, struct linger *)->l_onoff =
+ so->so_options & SO_LINGER;
+ mtod(m, struct linger *)->l_linger = so->so_linger;
+ break;
+
+ case SO_USELOOPBACK:
+ case SO_DONTROUTE:
+ case SO_DEBUG:
+ case SO_KEEPALIVE:
+ case SO_REUSEADDR:
+ case SO_REUSEPORT:
+ case SO_BROADCAST:
+ case SO_OOBINLINE:
+ *mtod(m, int *) = so->so_options & optname;
+ break;
+
+ case SO_TYPE:
+ *mtod(m, int *) = so->so_type;
+ break;
+
+ case SO_ERROR:
+ *mtod(m, int *) = so->so_error;
+ so->so_error = 0;
+ break;
+
+ case SO_SNDBUF:
+ *mtod(m, int *) = so->so_snd.sb_hiwat;
+ break;
+
+ case SO_RCVBUF:
+ *mtod(m, int *) = so->so_rcv.sb_hiwat;
+ break;
+
+ case SO_SNDLOWAT:
+ *mtod(m, int *) = so->so_snd.sb_lowat;
+ break;
+
+ case SO_RCVLOWAT:
+ *mtod(m, int *) = so->so_rcv.sb_lowat;
+ break;
+
+ case SO_SNDTIMEO:
+ case SO_RCVTIMEO:
+ {
+ int val = (optname == SO_SNDTIMEO ?
+ so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
+
+ m->m_len = sizeof(struct timeval);
+ mtod(m, struct timeval *)->tv_sec = val / hz;
+ mtod(m, struct timeval *)->tv_usec =
+ (val % hz) * tick;
+ break;
+ }
+
+ default:
+ (void)m_free(m);
+ return (ENOPROTOOPT);
+ }
+ *mp = m;
+ return (0);
+ }
+}
+
+void
+sohasoutofband(so)
+ register struct socket *so;
+{
+#ifndef __ECOS
+ csignal(so->so_pgid, SIGURG, so->so_siguid, so->so_sigeuid);
+#endif
+ selwakeup(&so->so_rcv.sb_sel);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket2.c b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket2.c
new file mode 100644
index 0000000..04a3674
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_socket2.c
@@ -0,0 +1,906 @@
+//==========================================================================
+//
+// sys/kern/uipc_socket2.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: uipc_socket2.c,v 1.11 1999/12/08 06:50:17 itojun Exp $ */
+/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/buf.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#ifndef __ECOS
+#include <sys/signalvar.h>
+#endif
+
+#ifdef __ECOS
+#include <cyg/infra/diag.h>
+#endif
+
+/*
+ * Primitive routines for operating on sockets and socket buffers
+ */
+
+/* strings for sleep message: */
+char netio[] = "netio";
+char netcon[] = "netcon";
+char netcls[] = "netcls";
+
+u_long sb_max = SB_MAX; /* patchable */
+
+/*
+ * Procedures to manipulate state flags of socket
+ * and do appropriate wakeups. Normal sequence from the
+ * active (originating) side is that soisconnecting() is
+ * called during processing of connect() call,
+ * resulting in an eventual call to soisconnected() if/when the
+ * connection is established. When the connection is torn down
+ * soisdisconnecting() is called during processing of disconnect() call,
+ * and soisdisconnected() is called when the connection to the peer
+ * is totally severed. The semantics of these routines are such that
+ * connectionless protocols can call soisconnected() and soisdisconnected()
+ * only, bypassing the in-progress calls when setting up a ``connection''
+ * takes no time.
+ *
+ * From the passive side, a socket is created with
+ * two queues of sockets: so_q0 for connections in progress
+ * and so_q for connections already made and awaiting user acceptance.
+ * As a protocol is preparing incoming connections, it creates a socket
+ * structure queued on so_q0 by calling sonewconn(). When the connection
+ * is established, soisconnected() is called, and transfers the
+ * socket structure to so_q, making it available to accept().
+ *
+ * If a socket is closed with sockets on either
+ * so_q0 or so_q, these sockets are dropped.
+ *
+ * If higher level protocols are implemented in
+ * the kernel, the wakeups done here will sometimes
+ * cause software-interrupt process scheduling.
+ */
+
+void
+soisconnecting(so)
+ register struct socket *so;
+{
+
+ so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
+ so->so_state |= SS_ISCONNECTING;
+}
+
+void
+soisconnected(so)
+ register struct socket *so;
+{
+ register struct socket *head = so->so_head;
+
+ so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
+ so->so_state |= SS_ISCONNECTED;
+ if (head && soqremque(so, 0)) {
+ soqinsque(head, so, 1);
+ sorwakeup(head);
+ wakeup((caddr_t)&head->so_timeo);
+ } else {
+ wakeup((caddr_t)&so->so_timeo);
+ sorwakeup(so);
+ sowwakeup(so);
+ }
+}
+
+void
+soisdisconnecting(so)
+ register struct socket *so;
+{
+
+ so->so_state &= ~SS_ISCONNECTING;
+ so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
+ wakeup((caddr_t)&so->so_timeo);
+ sowwakeup(so);
+ sorwakeup(so);
+}
+
+void
+soisdisconnected(so)
+ register struct socket *so;
+{
+
+ so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
+ so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
+ wakeup((caddr_t)&so->so_timeo);
+ sowwakeup(so);
+ sorwakeup(so);
+}
+
+/*
+ * When an attempt at a new connection is noted on a socket
+ * which accepts connections, sonewconn is called. If the
+ * connection is possible (subject to space constraints, etc.)
+ * then we allocate a new structure, propoerly linked into the
+ * data structure of the original socket, and return this.
+ * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED.
+ *
+ * Currently, sonewconn() is defined as sonewconn1() in socketvar.h
+ * to catch calls that are missing the (new) second parameter.
+ */
+struct socket *
+sonewconn1(head, connstatus)
+ register struct socket *head;
+ int connstatus;
+{
+ register struct socket *so;
+ int soqueue = connstatus ? 1 : 0;
+
+ if (head->so_qlen + head->so_q0len > head->so_qlimit * 3)
+ return ((struct socket *)0);
+ MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT);
+ if (so == NULL)
+ return ((struct socket *)0);
+ bzero((caddr_t)so, sizeof(*so));
+ so->so_type = head->so_type;
+ so->so_options = head->so_options &~ SO_ACCEPTCONN;
+ so->so_linger = head->so_linger;
+ so->so_state = head->so_state | SS_NOFDREF;
+ so->so_proto = head->so_proto;
+ so->so_timeo = head->so_timeo;
+ so->so_pgid = head->so_pgid;
+ so->so_euid = head->so_euid;
+ so->so_ruid = head->so_ruid;
+ (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
+ soqinsque(head, so, soqueue);
+ if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
+ (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
+ (void) soqremque(so, soqueue);
+ (void) free((caddr_t)so, M_SOCKET);
+ return ((struct socket *)0);
+ }
+ if (connstatus) {
+ sorwakeup(head);
+ wakeup((caddr_t)&head->so_timeo);
+ so->so_state |= connstatus;
+ }
+ return (so);
+}
+
+void
+soqinsque(head, so, q)
+ register struct socket *head, *so;
+ int q;
+{
+
+ register struct socket **prev;
+ so->so_head = head;
+ if (q == 0) {
+ head->so_q0len++;
+ so->so_q0 = 0;
+ for (prev = &(head->so_q0); *prev; )
+ prev = &((*prev)->so_q0);
+ } else {
+ head->so_qlen++;
+ so->so_q = 0;
+ for (prev = &(head->so_q); *prev; )
+ prev = &((*prev)->so_q);
+ }
+ *prev = so;
+}
+
+int
+soqremque(so, q)
+ register struct socket *so;
+ int q;
+{
+ register struct socket *head, *prev, *next;
+
+ head = so->so_head;
+ prev = head;
+ for (;;) {
+ next = q ? prev->so_q : prev->so_q0;
+ if (next == so)
+ break;
+ if (next == 0)
+ return (0);
+ prev = next;
+ }
+ if (q == 0) {
+ prev->so_q0 = next->so_q0;
+ head->so_q0len--;
+ } else {
+ prev->so_q = next->so_q;
+ head->so_qlen--;
+ }
+ next->so_q0 = next->so_q = 0;
+ next->so_head = 0;
+ return (1);
+}
+
+/*
+ * Socantsendmore indicates that no more data will be sent on the
+ * socket; it would normally be applied to a socket when the user
+ * informs the system that no more data is to be sent, by the protocol
+ * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data
+ * will be received, and will normally be applied to the socket by a
+ * protocol when it detects that the peer will send no more data.
+ * Data queued for reading in the socket may yet be read.
+ */
+
+void
+socantsendmore(so)
+ struct socket *so;
+{
+
+ so->so_state |= SS_CANTSENDMORE;
+ sowwakeup(so);
+}
+
+void
+socantrcvmore(so)
+ struct socket *so;
+{
+
+ so->so_state |= SS_CANTRCVMORE;
+ sorwakeup(so);
+}
+
+/*
+ * Wait for data to arrive at/drain from a socket buffer.
+ */
+int
+sbwait(sb)
+ struct sockbuf *sb;
+{
+
+ sb->sb_flags |= SB_WAIT;
+ return (tsleep((caddr_t)&sb->sb_cc,
+ (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, netio,
+ sb->sb_timeo));
+}
+
+/*
+ * Lock a sockbuf already known to be locked;
+ * return any error returned from sleep (EINTR).
+ */
+int
+sb_lock(sb)
+ register struct sockbuf *sb;
+{
+ int error;
+
+ while (sb->sb_flags & SB_LOCK) {
+ sb->sb_flags |= SB_WANT;
+ error = tsleep((caddr_t)&sb->sb_flags,
+ (sb->sb_flags & SB_NOINTR) ?
+ PSOCK : PSOCK|PCATCH, netio, 0);
+ if (error)
+ return (error);
+ }
+ sb->sb_flags |= SB_LOCK;
+ return (0);
+}
+
+#ifdef __ECOS
+/*
+ * Set lock on sockbuf sb; sleep if lock is already held.
+ * Unless SB_NOINTR is set on sockbuf, sleep is interruptible.
+ * Returns error without lock if sleep is interrupted.
+ */
+int
+sblock(struct sockbuf *sb, int wf)
+{
+ int res;
+ cyg_scheduler_safe_lock();
+ if (sb->sb_flags & SB_LOCK) {
+ // Already locked by another thread
+ if (wf == M_WAITOK) {
+ res = sb_lock(sb);
+ // Note: scheduler unlocked by 'sb_lock()'
+ } else {
+ res = EWOULDBLOCK;
+ cyg_scheduler_unlock();
+ }
+ } else {
+ sb->sb_flags |= SB_LOCK;
+ res = 0;
+ cyg_scheduler_unlock();
+ }
+ return res;
+}
+
+/* release lock on sockbuf sb */
+void
+sbunlock(struct sockbuf *sb)
+{
+ cyg_scheduler_lock();
+ sb->sb_flags &= ~SB_LOCK;
+ if (sb->sb_flags & SB_WANT) {
+ sb->sb_flags &= ~SB_WANT;
+ wakeup((caddr_t)&sb->sb_flags);
+ }
+ cyg_scheduler_unlock();
+}
+#endif
+
+/*
+ * Wakeup processes waiting on a socket buffer.
+ * Do asynchronous notification via SIGIO
+ * if the socket has the SS_ASYNC flag set.
+ */
+void
+sowakeup(so, sb)
+ register struct socket *so;
+ register struct sockbuf *sb;
+{
+ selwakeup(&sb->sb_sel);
+ sb->sb_flags &= ~SB_SEL;
+ if (sb->sb_flags & SB_WAIT) {
+ sb->sb_flags &= ~SB_WAIT;
+ wakeup((caddr_t)&sb->sb_cc);
+ }
+#ifndef __ECOS
+ if (so->so_state & SS_ASYNC)
+ csignal(so->so_pgid, SIGIO, so->so_siguid, so->so_sigeuid);
+#endif
+}
+
+/*
+ * Socket buffer (struct sockbuf) utility routines.
+ *
+ * Each socket contains two socket buffers: one for sending data and
+ * one for receiving data. Each buffer contains a queue of mbufs,
+ * information about the number of mbufs and amount of data in the
+ * queue, and other fields allowing select() statements and notification
+ * on data availability to be implemented.
+ *
+ * Data stored in a socket buffer is maintained as a list of records.
+ * Each record is a list of mbufs chained together with the m_next
+ * field. Records are chained together with the m_nextpkt field. The upper
+ * level routine soreceive() expects the following conventions to be
+ * observed when placing information in the receive buffer:
+ *
+ * 1. If the protocol requires each message be preceded by the sender's
+ * name, then a record containing that name must be present before
+ * any associated data (mbuf's must be of type MT_SONAME).
+ * 2. If the protocol supports the exchange of ``access rights'' (really
+ * just additional data associated with the message), and there are
+ * ``rights'' to be received, then a record containing this data
+ * should be present (mbuf's must be of type MT_CONTROL).
+ * 3. If a name or rights record exists, then it must be followed by
+ * a data record, perhaps of zero length.
+ *
+ * Before using a new socket structure it is first necessary to reserve
+ * buffer space to the socket, by calling sbreserve(). This should commit
+ * some of the available buffer space in the system buffer pool for the
+ * socket (currently, it does nothing but enforce limits). The space
+ * should be released by calling sbrelease() when the socket is destroyed.
+ */
+
+int
+soreserve(so, sndcc, rcvcc)
+ register struct socket *so;
+ u_long sndcc, rcvcc;
+{
+
+ if (sbreserve(&so->so_snd, sndcc) == 0)
+ goto bad;
+ if (sbreserve(&so->so_rcv, rcvcc) == 0)
+ goto bad2;
+ if (so->so_rcv.sb_lowat == 0)
+ so->so_rcv.sb_lowat = 1;
+ if (so->so_snd.sb_lowat == 0)
+ so->so_snd.sb_lowat = MCLBYTES;
+ if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
+ so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
+ return (0);
+bad2:
+ sbrelease(&so->so_snd);
+bad:
+ return (ENOBUFS);
+}
+
+/*
+ * Allot mbufs to a sockbuf.
+ * Attempt to scale mbmax so that mbcnt doesn't become limiting
+ * if buffering efficiency is near the normal case.
+ */
+int
+sbreserve(sb, cc)
+ struct sockbuf *sb;
+ u_long cc;
+{
+
+ if (cc == 0 || cc > sb_max * MCLBYTES / (MSIZE + MCLBYTES))
+ return (0);
+ sb->sb_hiwat = cc;
+ sb->sb_mbmax = min(cc * 2, sb_max);
+ if (sb->sb_lowat > sb->sb_hiwat)
+ sb->sb_lowat = sb->sb_hiwat;
+ return (1);
+}
+
+/*
+ * Free mbufs held by a socket, and reserved mbuf space.
+ */
+void
+sbrelease(sb)
+ struct sockbuf *sb;
+{
+
+ sbflush(sb);
+ sb->sb_hiwat = sb->sb_mbmax = 0;
+}
+
+/*
+ * Routines to add and remove
+ * data from an mbuf queue.
+ *
+ * The routines sbappend() or sbappendrecord() are normally called to
+ * append new mbufs to a socket buffer, after checking that adequate
+ * space is available, comparing the function sbspace() with the amount
+ * of data to be added. sbappendrecord() differs from sbappend() in
+ * that data supplied is treated as the beginning of a new record.
+ * To place a sender's address, optional access rights, and data in a
+ * socket receive buffer, sbappendaddr() should be used. To place
+ * access rights and data in a socket receive buffer, sbappendrights()
+ * should be used. In either case, the new data begins a new record.
+ * Note that unlike sbappend() and sbappendrecord(), these routines check
+ * for the caller that there will be enough space to store the data.
+ * Each fails if there is not enough space, or if it cannot find mbufs
+ * to store additional information in.
+ *
+ * Reliable protocols may use the socket send buffer to hold data
+ * awaiting acknowledgement. Data is normally copied from a socket
+ * send buffer in a protocol with m_copy for output to a peer,
+ * and then removing the data from the socket buffer with sbdrop()
+ * or sbdroprecord() when the data is acknowledged by the peer.
+ */
+
+/*
+ * Append mbuf chain m to the last record in the
+ * socket buffer sb. The additional space associated
+ * the mbuf chain is recorded in sb. Empty mbufs are
+ * discarded and mbufs are compacted where possible.
+ */
+void
+sbappend(sb, m)
+ struct sockbuf *sb;
+ struct mbuf *m;
+{
+ register struct mbuf *n;
+
+ if (m == 0)
+ return;
+ if ((n = sb->sb_mb) != NULL) {
+ while (n->m_nextpkt)
+ n = n->m_nextpkt;
+ do {
+ if (n->m_flags & M_EOR) {
+ sbappendrecord(sb, m); /* XXXXXX!!!! */
+ return;
+ }
+ } while (n->m_next && (n = n->m_next));
+ }
+ sbcompress(sb, m, n);
+}
+
+#ifdef SOCKBUF_DEBUG
+void
+sbcheck(sb)
+ register struct sockbuf *sb;
+{
+ register struct mbuf *m;
+ register int len = 0, mbcnt = 0;
+
+ for (m = sb->sb_mb; m; m = m->m_next) {
+ len += m->m_len;
+ mbcnt += MSIZE;
+ if (m->m_flags & M_EXT)
+ mbcnt += m->m_ext.ext_size;
+ if (m->m_nextpkt)
+ panic("sbcheck nextpkt");
+ }
+ if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
+ printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc,
+ mbcnt, sb->sb_mbcnt);
+ panic("sbcheck");
+ }
+}
+#endif
+
+/*
+ * As above, except the mbuf chain
+ * begins a new record.
+ */
+void
+sbappendrecord(sb, m0)
+ register struct sockbuf *sb;
+ register struct mbuf *m0;
+{
+ register struct mbuf *m;
+
+ if (m0 == 0)
+ return;
+ if ((m = sb->sb_mb) != NULL)
+ while (m->m_nextpkt)
+ m = m->m_nextpkt;
+ /*
+ * Put the first mbuf on the queue.
+ * Note this permits zero length records.
+ */
+ sballoc(sb, m0);
+ if (m)
+ m->m_nextpkt = m0;
+ else
+ sb->sb_mb = m0;
+ m = m0->m_next;
+ m0->m_next = 0;
+ if (m && (m0->m_flags & M_EOR)) {
+ m0->m_flags &= ~M_EOR;
+ m->m_flags |= M_EOR;
+ }
+ sbcompress(sb, m, m0);
+}
+
+/*
+ * As above except that OOB data
+ * is inserted at the beginning of the sockbuf,
+ * but after any other OOB data.
+ */
+void
+sbinsertoob(sb, m0)
+ register struct sockbuf *sb;
+ register struct mbuf *m0;
+{
+ register struct mbuf *m;
+ register struct mbuf **mp;
+
+ if (m0 == 0)
+ return;
+ for (mp = &sb->sb_mb; (m = *mp) != NULL; mp = &((*mp)->m_nextpkt)) {
+ again:
+ switch (m->m_type) {
+
+ case MT_OOBDATA:
+ continue; /* WANT next train */
+
+ case MT_CONTROL:
+ if ((m = m->m_next) != NULL)
+ goto again; /* inspect THIS train further */
+ }
+ break;
+ }
+ /*
+ * Put the first mbuf on the queue.
+ * Note this permits zero length records.
+ */
+ sballoc(sb, m0);
+ m0->m_nextpkt = *mp;
+ *mp = m0;
+ m = m0->m_next;
+ m0->m_next = 0;
+ if (m && (m0->m_flags & M_EOR)) {
+ m0->m_flags &= ~M_EOR;
+ m->m_flags |= M_EOR;
+ }
+ sbcompress(sb, m, m0);
+}
+
+/*
+ * Append address and data, and optionally, control (ancillary) data
+ * to the receive queue of a socket. If present,
+ * m0 must include a packet header with total length.
+ * Returns 0 if no space in sockbuf or insufficient mbufs.
+ */
+int
+sbappendaddr(sb, asa, m0, control)
+ register struct sockbuf *sb;
+ struct sockaddr *asa;
+ struct mbuf *m0, *control;
+{
+ register struct mbuf *m, *n;
+ int space = asa->sa_len;
+
+if (m0 && (m0->m_flags & M_PKTHDR) == 0)
+panic("sbappendaddr");
+ if (m0)
+ space += m0->m_pkthdr.len;
+ for (n = control; n; n = n->m_next) {
+ space += n->m_len;
+ if (n->m_next == 0) /* keep pointer to last control buf */
+ break;
+ }
+ if (space > sbspace(sb))
+ return (0);
+ if (asa->sa_len > MLEN)
+ return (0);
+ MGET(m, M_DONTWAIT, MT_SONAME);
+ if (m == 0)
+ return (0);
+ m->m_len = asa->sa_len;
+ bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len);
+ if (n)
+ n->m_next = m0; /* concatenate data to control */
+ else
+ control = m0;
+ m->m_next = control;
+ for (n = m; n; n = n->m_next)
+ sballoc(sb, n);
+ if ((n = sb->sb_mb) != NULL) {
+ while (n->m_nextpkt)
+ n = n->m_nextpkt;
+ n->m_nextpkt = m;
+ } else
+ sb->sb_mb = m;
+ return (1);
+}
+
+int
+sbappendcontrol(sb, m0, control)
+ struct sockbuf *sb;
+ struct mbuf *m0, *control;
+{
+ register struct mbuf *m, *n;
+ int space = 0;
+
+ if (control == 0)
+ panic("sbappendcontrol");
+ for (m = control; ; m = m->m_next) {
+ space += m->m_len;
+ if (m->m_next == 0)
+ break;
+ }
+ n = m; /* save pointer to last control buffer */
+ for (m = m0; m; m = m->m_next)
+ space += m->m_len;
+ if (space > sbspace(sb))
+ return (0);
+ n->m_next = m0; /* concatenate data to control */
+ for (m = control; m; m = m->m_next)
+ sballoc(sb, m);
+ if ((n = sb->sb_mb) != NULL) {
+ while (n->m_nextpkt)
+ n = n->m_nextpkt;
+ n->m_nextpkt = control;
+ } else
+ sb->sb_mb = control;
+ return (1);
+}
+
+/*
+ * Compress mbuf chain m into the socket
+ * buffer sb following mbuf n. If n
+ * is null, the buffer is presumed empty.
+ */
+void
+sbcompress(sb, m, n)
+ register struct sockbuf *sb;
+ register struct mbuf *m, *n;
+{
+ register int eor = 0;
+ register struct mbuf *o;
+
+ while (m) {
+ eor |= m->m_flags & M_EOR;
+ if (m->m_len == 0 &&
+ (eor == 0 ||
+ (((o = m->m_next) || (o = n)) &&
+ o->m_type == m->m_type))) {
+ m = m_free(m);
+ continue;
+ }
+ if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 &&
+ (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] &&
+ n->m_type == m->m_type) {
+ bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len,
+ (unsigned)m->m_len);
+ n->m_len += m->m_len;
+ sb->sb_cc += m->m_len;
+ m = m_free(m);
+ continue;
+ }
+ if (n)
+ n->m_next = m;
+ else
+ sb->sb_mb = m;
+ sballoc(sb, m);
+ n = m;
+ m->m_flags &= ~M_EOR;
+ m = m->m_next;
+ n->m_next = 0;
+ }
+ if (eor) {
+ if (n)
+ n->m_flags |= eor;
+ else
+#ifdef __ECOS
+ diag_printf("semi-panic: sbcompress\n");
+#else
+ printf("semi-panic: sbcompress\n");
+#endif
+ }
+}
+
+/*
+ * Free all mbufs in a sockbuf.
+ * Check that all resources are reclaimed.
+ */
+void
+sbflush(sb)
+ register struct sockbuf *sb;
+{
+
+ if (sb->sb_flags & SB_LOCK)
+ panic("sbflush");
+ while (sb->sb_mbcnt)
+ sbdrop(sb, (int)sb->sb_cc);
+ if (sb->sb_cc || sb->sb_mb)
+ panic("sbflush 2");
+}
+
+/*
+ * Drop data from (the front of) a sockbuf.
+ */
+void
+sbdrop(sb, len)
+ register struct sockbuf *sb;
+ register int len;
+{
+ register struct mbuf *m, *mn;
+ struct mbuf *next;
+
+ next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
+ while (len > 0) {
+ if (m == 0) {
+ if (next == 0)
+ panic("sbdrop");
+ m = next;
+ next = m->m_nextpkt;
+ continue;
+ }
+ if (m->m_len > len) {
+ m->m_len -= len;
+ m->m_data += len;
+ sb->sb_cc -= len;
+ break;
+ }
+ len -= m->m_len;
+ sbfree(sb, m);
+ MFREE(m, mn);
+ m = mn;
+ }
+ while (m && m->m_len == 0) {
+ sbfree(sb, m);
+ MFREE(m, mn);
+ m = mn;
+ }
+ if (m) {
+ sb->sb_mb = m;
+ m->m_nextpkt = next;
+ } else
+ sb->sb_mb = next;
+}
+
+/*
+ * Drop a record off the front of a sockbuf
+ * and move the next record to the front.
+ */
+void
+sbdroprecord(sb)
+ register struct sockbuf *sb;
+{
+ register struct mbuf *m, *mn;
+
+ m = sb->sb_mb;
+ if (m) {
+ sb->sb_mb = m->m_nextpkt;
+ do {
+ sbfree(sb, m);
+ MFREE(m, mn);
+ } while ((m = mn) != NULL);
+ }
+}
+
+/*
+ * Create a "control" mbuf containing the specified data
+ * with the specified type for presentation on a socket buffer.
+ */
+struct mbuf *
+sbcreatecontrol(p, size, type, level)
+ caddr_t p;
+ register int size;
+ int type, level;
+{
+ register struct cmsghdr *cp;
+ struct mbuf *m;
+
+ if (size + sizeof(*cp) > MCLBYTES) {
+#ifdef __ECOS
+ diag_printf("sbcreatecontrol: message too large %d\n", size);
+#else
+ printf("sbcreatecontrol: message too large %d\n", size);
+#endif
+ return NULL;
+ }
+
+ if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)
+ return ((struct mbuf *) NULL);
+ if (size + sizeof(*cp) > MLEN) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_free(m);
+ return NULL;
+ }
+ }
+ cp = mtod(m, struct cmsghdr *);
+ bcopy(p, CMSG_DATA(cp), size);
+ size += sizeof(*cp);
+ m->m_len = size;
+ cp->cmsg_len = size;
+ cp->cmsg_level = level;
+ cp->cmsg_type = type;
+ return (m);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/kern/uipc_syscalls.c b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_syscalls.c
new file mode 100644
index 0000000..d09b422
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/kern/uipc_syscalls.c
@@ -0,0 +1,1269 @@
+//==========================================================================
+//
+// sys/kern/uipc_syscalls.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: uipc_syscalls.c,v 1.29 1999/12/08 06:50:17 itojun Exp $ */
+/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
+ */
+
+#include <sys/param.h>
+#ifdef __ECOS
+#include <cyg/io/file.h>
+static int ecos_getsock(int fdes, struct file **fpp);
+#define getsock(fdp, fdes, fpp) ecos_getsock(fdes, fpp)
+#else
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/filedesc.h>
+#include <sys/file.h>
+#include <sys/buf.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#ifndef __ECOS
+#include <sys/signalvar.h>
+#include <sys/un.h>
+#endif
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+
+#ifndef __ECOS
+#include <sys/mount.h>
+#endif
+#include <sys/syscallargs.h>
+
+/*
+ * System call interface to the socket abstraction.
+ */
+extern struct fileops socketops;
+
+#ifdef __ECOS
+int
+sys_socket(struct sys_socket_args *uap, register_t *retval)
+{
+#else
+int
+sys_socket(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_socket_args /* {
+ syscallarg(int) domain;
+ syscallarg(int) type;
+ syscallarg(int) protocol;
+ } */ *uap = v;
+ struct filedesc *fdp = p->p_fd;
+#endif // __ECOS
+ struct socket *so;
+ struct file *fp;
+ int fd, error;
+
+#ifdef __ECOS
+ if ((error = falloc(&fp, &fd)) != 0)
+#else
+ if ((error = falloc(p, &fp, &fd)) != 0)
+#endif
+ return (error);
+ fp->f_flag = FREAD|FWRITE;
+ fp->f_type = DTYPE_SOCKET;
+ fp->f_ops = &socketops;
+ error = socreate(SCARG(uap, domain), &so, SCARG(uap, type),
+ SCARG(uap, protocol));
+ if (error) {
+#ifndef __ECOS
+ fdremove(fdp, fd);
+#endif
+ ffree(fp);
+ } else {
+#ifdef __ECOS
+ fp->f_data = (CYG_ADDRWORD)so;
+#else
+ fp->f_data = (caddr_t)so;
+#endif
+ *retval = fd;
+ }
+ return (error);
+}
+
+#ifdef __ECOS
+int
+sys_bind(struct sys_bind_args *uap, register_t *retval)
+ {
+#else
+/* ARGSUSED */
+int
+sys_bind(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_bind_args /* {
+ syscallarg(int) s;
+ syscallarg(struct sockaddr *) name;
+ syscallarg(socklen_t) namelen;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ struct mbuf *nam;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ error = sockargs(&nam, (caddr_t)SCARG(uap, name), SCARG(uap, namelen),
+ MT_SONAME);
+ if (error)
+ return (error);
+ error = sobind((struct socket *)fp->f_data, nam);
+ m_freem(nam);
+ return (error);
+}
+
+/* ARGSUSED */
+#ifdef __ECOS
+int
+sys_listen(struct sys_listen_args *uap, register_t *retval)
+{
+#else
+int
+sys_listen(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_listen_args /* {
+ syscallarg(int) s;
+ syscallarg(int) backlog;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ return (solisten((struct socket *)fp->f_data, SCARG(uap, backlog)));
+}
+
+#ifdef __ECOS
+int
+ sys_accept(struct sys_accept_args *uap, register_t *retval)
+{
+#else
+int
+sys_accept(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_accept_args /* {
+ syscallarg(int) s;
+ syscallarg(struct sockaddr *) name;
+ syscallarg(socklen_t *) anamelen;
+ } */ *uap = v;
+#endif
+ struct file *fp;
+ struct mbuf *nam;
+ socklen_t namelen;
+ int error, s, tmpfd;
+ register struct socket *so;
+
+ if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, anamelen),
+ (caddr_t)&namelen, sizeof (namelen))))
+ return (error);
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ s = splsoftnet();
+ so = (struct socket *)fp->f_data;
+ if ((so->so_options & SO_ACCEPTCONN) == 0) {
+ splx(s);
+ return (EINVAL);
+ }
+ if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
+ splx(s);
+ return (EWOULDBLOCK);
+ }
+ while (so->so_qlen == 0 && so->so_error == 0) {
+ if (so->so_state & SS_CANTRCVMORE) {
+ so->so_error = ECONNABORTED;
+ break;
+ }
+ error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
+ netcon, 0);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ }
+ if (so->so_error) {
+ error = so->so_error;
+ so->so_error = 0;
+ splx(s);
+ return (error);
+ }
+#ifdef __ECOS
+ if ((error = falloc(&fp, &tmpfd)) != 0) {
+#else
+ if ((error = falloc(p, &fp, &tmpfd)) != 0) {
+#endif
+ splx(s);
+ return (error);
+ }
+ *retval = tmpfd;
+ { struct socket *aso = so->so_q;
+ if (soqremque(aso, 1) == 0)
+ panic("accept");
+ so = aso;
+ }
+ fp->f_type = DTYPE_SOCKET;
+ fp->f_flag = FREAD|FWRITE;
+ fp->f_ops = &socketops;
+#ifdef __ECOS
+ fp->f_data = (CYG_ADDRWORD)so;
+#else
+ fp->f_data = (caddr_t)so;
+#endif
+ nam = m_get(M_WAIT, MT_SONAME);
+ (void) soaccept(so, nam);
+ if (SCARG(uap, name)) {
+ if (namelen > nam->m_len)
+ namelen = nam->m_len;
+ /* SHOULD COPY OUT A CHAIN HERE */
+ if ((error = copyout(mtod(nam, caddr_t),
+ (caddr_t)SCARG(uap, name), namelen)) == 0)
+ error = copyout((caddr_t)&namelen,
+ (caddr_t)SCARG(uap, anamelen),
+ sizeof (*SCARG(uap, anamelen)));
+ }
+ m_freem(nam);
+ splx(s);
+ return (error);
+}
+
+#ifdef __ECOS
+int
+sys_connect(struct sys_connect_args *uap, register_t *retval)
+{
+#else
+/* ARGSUSED */
+int
+sys_connect(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_connect_args /* {
+ syscallarg(int) s;
+ syscallarg(struct sockaddr *) name;
+ syscallarg(socklen_t) namelen;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ register struct socket *so;
+ struct mbuf *nam;
+ int error, s;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ so = (struct socket *)fp->f_data;
+ if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
+ return (EALREADY);
+ error = sockargs(&nam, (caddr_t)SCARG(uap, name), SCARG(uap, namelen),
+ MT_SONAME);
+ if (error)
+ return (error);
+ error = soconnect(so, nam);
+ if (error)
+ goto bad;
+ if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+ m_freem(nam);
+ return (EINPROGRESS);
+ }
+ s = splsoftnet();
+ while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
+ error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
+ netcon, 0);
+ if (error)
+ break;
+ }
+ if (error == 0) {
+ error = so->so_error;
+ so->so_error = 0;
+ }
+ splx(s);
+bad:
+ so->so_state &= ~SS_ISCONNECTING;
+ m_freem(nam);
+#ifndef __ECOS
+ if (error == ERESTART)
+ error = EINTR;
+#endif
+ return (error);
+}
+
+#ifndef __ECOS
+int
+sys_socketpair(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_socketpair_args /* {
+ syscallarg(int) domain;
+ syscallarg(int) type;
+ syscallarg(int) protocol;
+ syscallarg(int *) rsv;
+ } */ *uap = v;
+ register struct filedesc *fdp = p->p_fd;
+ struct file *fp1, *fp2;
+ struct socket *so1, *so2;
+ int fd, error, sv[2];
+
+ error = socreate(SCARG(uap, domain), &so1, SCARG(uap, type),
+ SCARG(uap, protocol));
+ if (error)
+ return (error);
+ error = socreate(SCARG(uap, domain), &so2, SCARG(uap, type),
+ SCARG(uap, protocol));
+ if (error)
+ goto free1;
+ if ((error = falloc(p, &fp1, &fd)) != 0)
+ goto free2;
+ sv[0] = fd;
+ fp1->f_flag = FREAD|FWRITE;
+ fp1->f_type = DTYPE_SOCKET;
+ fp1->f_ops = &socketops;
+ fp1->f_data = (caddr_t)so1;
+ if ((error = falloc(p, &fp2, &fd)) != 0)
+ goto free3;
+ fp2->f_flag = FREAD|FWRITE;
+ fp2->f_type = DTYPE_SOCKET;
+ fp2->f_ops = &socketops;
+ fp2->f_data = (caddr_t)so2;
+ sv[1] = fd;
+ if ((error = soconnect2(so1, so2)) != 0)
+ goto free4;
+ if (SCARG(uap, type) == SOCK_DGRAM) {
+ /*
+ * Datagram socket connection is asymmetric.
+ */
+ if ((error = soconnect2(so2, so1)) != 0)
+ goto free4;
+ }
+ error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, rsv),
+ 2 * sizeof (int));
+ if (error == 0)
+ return (error);
+free4:
+ ffree(fp2);
+ fdremove(fdp, sv[1]);
+free3:
+ ffree(fp1);
+ fdremove(fdp, sv[0]);
+free2:
+ (void)soclose(so2);
+free1:
+ (void)soclose(so1);
+ return (error);
+}
+#endif
+
+#ifdef __ECOS
+int
+sys_sendto(struct sys_sendto_args *uap, register_t *retval)
+{
+#else
+int
+sys_sendto(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_sendto_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(struct sockaddr *) to;
+ syscallarg(socklen_t) tolen;
+ } */ *uap = v;
+#endif // __ECOS
+ struct msghdr msg;
+ struct iovec aiov;
+
+ msg.msg_name = (caddr_t)SCARG(uap, to);
+ msg.msg_namelen = SCARG(uap, tolen);
+ msg.msg_iov = &aiov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = 0;
+#ifdef COMPAT_OLDSOCK
+ msg.msg_flags = 0;
+#endif
+ aiov.iov_base = (char *)SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, len);
+#ifdef __ECOS
+ return (sendit(SCARG(uap, s), &msg, SCARG(uap, flags), retval));
+#else
+ return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
+#endif
+}
+
+#ifndef __ECOS
+int
+sys_sendmsg(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_sendmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) msg;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ struct msghdr msg;
+ struct iovec aiov[UIO_SMALLIOV], *iov;
+ int error;
+
+ error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof (msg));
+ if (error)
+ return (error);
+ if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
+ return (EMSGSIZE);
+ if (msg.msg_iovlen > UIO_SMALLIOV)
+ MALLOC(iov, struct iovec *,
+ sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
+ else
+ iov = aiov;
+ if (msg.msg_iovlen &&
+ (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
+ (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
+ goto done;
+ msg.msg_iov = iov;
+#ifdef COMPAT_OLDSOCK
+ msg.msg_flags = 0;
+#endif
+ error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
+done:
+ if (iov != aiov)
+ FREE(iov, M_IOV);
+ return (error);
+}
+#endif
+
+#ifdef __ECOS
+int
+sendit(int s, struct msghdr *mp, int flags, register_t *retsize)
+{
+#else
+int
+sendit(p, s, mp, flags, retsize)
+ register struct proc *p;
+ int s;
+ register struct msghdr *mp;
+ int flags;
+ register_t *retsize;
+{
+#endif // __ECOS
+ struct file *fp;
+ struct uio auio;
+ register struct iovec *iov;
+ register int i;
+ struct mbuf *to, *control;
+ int len, error;
+#ifdef KTRACE
+ struct iovec *ktriov = NULL;
+#endif
+
+ if ((error = getsock(p->p_fd, s, &fp)) != 0)
+ return (error);
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_rw = UIO_WRITE;
+#ifndef __ECOS
+ auio.uio_procp = p;
+#endif
+ auio.uio_offset = 0; /* XXX */
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX)
+ return (EINVAL);
+ }
+ if (mp->msg_name) {
+ error = sockargs(&to, mp->msg_name, mp->msg_namelen,
+ MT_SONAME);
+ if (error)
+ return (error);
+ } else
+ to = 0;
+ if (mp->msg_control) {
+ if (mp->msg_controllen < sizeof(struct cmsghdr)
+#ifdef COMPAT_OLDSOCK
+ && mp->msg_flags != MSG_COMPAT
+#endif
+ ) {
+ error = EINVAL;
+ goto bad;
+ }
+ error = sockargs(&control, mp->msg_control,
+ mp->msg_controllen, MT_CONTROL);
+ if (error)
+ goto bad;
+#ifdef COMPAT_OLDSOCK
+ if (mp->msg_flags == MSG_COMPAT) {
+ register struct cmsghdr *cm;
+
+ M_PREPEND(control, sizeof(*cm), M_WAIT);
+ if (control == 0) {
+ error = ENOBUFS;
+ goto bad;
+ } else {
+ cm = mtod(control, struct cmsghdr *);
+ cm->cmsg_len = control->m_len;
+ cm->cmsg_level = SOL_SOCKET;
+ cm->cmsg_type = SCM_RIGHTS;
+ }
+ }
+#endif
+ } else
+ control = 0;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_GENIO)) {
+ int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
+
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ len = auio.uio_resid;
+ error = sosend((struct socket *)fp->f_data, to, &auio,
+ NULL, control, flags);
+ if (error) {
+#ifdef __ECOS
+ if (auio.uio_resid != len &&
+ (error == EINTR || error == EWOULDBLOCK))
+#else
+ if (auio.uio_resid != len && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+#endif
+ error = 0;
+#ifndef __ECOS
+ if (error == EPIPE)
+ psignal(p, SIGPIPE);
+#endif
+ }
+ if (error == 0)
+ *retsize = len - auio.uio_resid;
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, s, UIO_WRITE,
+ ktriov, *retsize, error);
+ FREE(ktriov, M_TEMP);
+ }
+#endif
+bad:
+ if (to)
+ m_freem(to);
+ return (error);
+}
+
+#ifdef __ECOS
+int
+sys_recvfrom(struct sys_recvfrom_args *uap, register_t *retval)
+{
+#else
+int
+sys_recvfrom(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_recvfrom_args /* {
+ syscallarg(int) s;
+ syscallarg(caddr_t) buf;
+ syscallarg(size_t) len;
+ syscallarg(int) flags;
+ syscallarg(struct sockaddr *) from;
+ syscallarg(socklen_t *) fromlenaddr;
+ } */ *uap = v;
+#endif // __ECOS
+ struct msghdr msg;
+ struct iovec aiov;
+ int error;
+
+ if (SCARG(uap, fromlenaddr)) {
+ error = copyin((caddr_t)SCARG(uap, fromlenaddr),
+ (caddr_t)&msg.msg_namelen,
+ sizeof (msg.msg_namelen));
+ if (error)
+ return (error);
+ } else
+ msg.msg_namelen = 0;
+ msg.msg_name = (caddr_t)SCARG(uap, from);
+ msg.msg_iov = &aiov;
+ msg.msg_iovlen = 1;
+ aiov.iov_base = SCARG(uap, buf);
+ aiov.iov_len = SCARG(uap, len);
+ msg.msg_control = 0;
+ msg.msg_flags = SCARG(uap, flags);
+#ifdef __ECOS
+ return (recvit(SCARG(uap, s), &msg,
+ (caddr_t)SCARG(uap, fromlenaddr), retval));
+#else
+ return (recvit(p, SCARG(uap, s), &msg,
+ (caddr_t)SCARG(uap, fromlenaddr), retval));
+#endif
+}
+
+#ifndef __ECOS
+int
+sys_recvmsg(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_recvmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(struct msghdr *) msg;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ struct msghdr msg;
+ struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
+ register int error;
+
+ error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
+ sizeof (msg));
+ if (error)
+ return (error);
+ if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
+ return (EMSGSIZE);
+ if (msg.msg_iovlen > UIO_SMALLIOV)
+ MALLOC(iov, struct iovec *,
+ sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
+ else
+ iov = aiov;
+#ifdef COMPAT_OLDSOCK
+ msg.msg_flags = SCARG(uap, flags) &~ MSG_COMPAT;
+#else
+ msg.msg_flags = SCARG(uap, flags);
+#endif
+ uiov = msg.msg_iov;
+ msg.msg_iov = iov;
+ error = copyin((caddr_t)uiov, (caddr_t)iov,
+ (unsigned)(msg.msg_iovlen * sizeof (struct iovec)));
+ if (error)
+ goto done;
+ if ((error = recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval)) == 0) {
+ msg.msg_iov = uiov;
+ error = copyout((caddr_t)&msg, (caddr_t)SCARG(uap, msg),
+ sizeof(msg));
+ }
+done:
+ if (iov != aiov)
+ FREE(iov, M_IOV);
+ return (error);
+}
+#endif
+
+#ifdef __ECOS
+int
+recvit(int s, struct msghdr *mp, caddr_t namelenp, register_t *retsize)
+{
+#else
+int
+recvit(p, s, mp, namelenp, retsize)
+ register struct proc *p;
+ int s;
+ register struct msghdr *mp;
+ caddr_t namelenp;
+ register_t *retsize;
+{
+#endif // __ECOS
+ struct file *fp;
+ struct uio auio;
+ register struct iovec *iov;
+ register int i;
+ size_t len;
+ int error;
+ struct mbuf *from = 0, *control = 0;
+#ifdef KTRACE
+ struct iovec *ktriov = NULL;
+#endif
+
+ if ((error = getsock(p->p_fd, s, &fp)) != 0)
+ return (error);
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_rw = UIO_READ;
+#ifndef __ECOS
+ auio.uio_procp = p;
+#endif
+ auio.uio_offset = 0; /* XXX */
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ /* Don't allow sum > SSIZE_MAX */
+ if (iov->iov_len > SSIZE_MAX ||
+ (auio.uio_resid += iov->iov_len) > SSIZE_MAX)
+ return (EINVAL);
+ }
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_GENIO)) {
+ int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
+
+ MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
+ }
+#endif
+ len = auio.uio_resid;
+ error = soreceive((struct socket *)fp->f_data, &from, &auio,
+ NULL, mp->msg_control ? &control : NULL,
+ &mp->msg_flags);
+ if (error) {
+#ifdef __ECOS
+ if (auio.uio_resid != len &&
+ (error == EINTR || error == EWOULDBLOCK))
+#else
+ if (auio.uio_resid != len && (error == ERESTART ||
+ error == EINTR || error == EWOULDBLOCK))
+#endif
+ error = 0;
+ }
+#ifdef KTRACE
+ if (ktriov != NULL) {
+ if (error == 0)
+ ktrgenio(p->p_tracep, s, UIO_READ,
+ ktriov, len - auio.uio_resid, error);
+ FREE(ktriov, M_TEMP);
+ }
+#endif
+ if (error)
+ goto out;
+ *retsize = len - auio.uio_resid;
+ if (mp->msg_name) {
+ len = mp->msg_namelen;
+ if (len <= 0 || from == 0)
+ len = 0;
+ else {
+ /* save sa_len before it is destroyed by MSG_COMPAT */
+ if (len > from->m_len)
+ len = from->m_len;
+ /* else if len < from->m_len ??? */
+#ifdef COMPAT_OLDSOCK
+ if (mp->msg_flags & MSG_COMPAT)
+ mtod(from, struct osockaddr *)->sa_family =
+ mtod(from, struct sockaddr *)->sa_family;
+#endif
+ error = copyout(mtod(from, caddr_t),
+ (caddr_t)mp->msg_name, (unsigned)len);
+ if (error)
+ goto out;
+ }
+ mp->msg_namelen = len;
+ if (namelenp &&
+ (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
+#ifdef COMPAT_OLDSOCK
+ if (mp->msg_flags & MSG_COMPAT)
+ error = 0; /* old recvfrom didn't check */
+ else
+#endif
+ goto out;
+ }
+ }
+ if (mp->msg_control) {
+#ifdef COMPAT_OLDSOCK
+ /*
+ * We assume that old recvmsg calls won't receive access
+ * rights and other control info, esp. as control info
+ * is always optional and those options didn't exist in 4.3.
+ * If we receive rights, trim the cmsghdr; anything else
+ * is tossed.
+ */
+ if (control && mp->msg_flags & MSG_COMPAT) {
+ if (mtod(control, struct cmsghdr *)->cmsg_level !=
+ SOL_SOCKET ||
+ mtod(control, struct cmsghdr *)->cmsg_type !=
+ SCM_RIGHTS) {
+ mp->msg_controllen = 0;
+ goto out;
+ }
+ control->m_len -= sizeof (struct cmsghdr);
+ control->m_data += sizeof (struct cmsghdr);
+ }
+#endif
+ len = mp->msg_controllen;
+ if (len <= 0 || control == 0)
+ len = 0;
+ else {
+ struct mbuf *m = control;
+ caddr_t p = (caddr_t)mp->msg_control;
+
+ do {
+ i = m->m_len;
+ if (len < i) {
+ mp->msg_flags |= MSG_CTRUNC;
+ i = len;
+ }
+ error = copyout(mtod(m, caddr_t), p,
+ (unsigned)i);
+ if (m->m_next)
+ i = ALIGN(i);
+ p += i;
+ len -= i;
+ if (error != 0 || len <= 0)
+ break;
+ } while ((m = m->m_next) != NULL);
+ len = p - (caddr_t)mp->msg_control;
+ }
+ mp->msg_controllen = len;
+ }
+out:
+ if (from)
+ m_freem(from);
+ if (control)
+ m_freem(control);
+ return (error);
+}
+
+/* ARGSUSED */
+#ifdef __ECOS
+int
+sys_shutdown(struct sys_shutdown_args *uap, register_t *retval)
+{
+#else
+int
+sys_shutdown(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_shutdown_args /* {
+ syscallarg(int) s;
+ syscallarg(int) how;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ return (soshutdown((struct socket *)fp->f_data, SCARG(uap, how)));
+}
+
+#ifdef __ECOS
+int
+sys_setsockopt(struct sys_setsockopt_args *uap, register_t *retval)
+{
+#else
+/* ARGSUSED */
+int
+sys_setsockopt(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_setsockopt_args /* {
+ syscallarg(int) s;
+ syscallarg(int) level;
+ syscallarg(int) name;
+ syscallarg(caddr_t) val;
+ syscallarg(socklen_t) valsize;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ struct mbuf *m = NULL;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ if (SCARG(uap, valsize) > MCLBYTES)
+ return (EINVAL);
+ if (SCARG(uap, val)) {
+ m = m_get(M_WAIT, MT_SOOPTS);
+ if (SCARG(uap, valsize) > MLEN) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+ }
+ if (m == NULL)
+ return (ENOBUFS);
+ error = copyin(SCARG(uap, val), mtod(m, caddr_t),
+ SCARG(uap, valsize));
+ if (error) {
+ (void) m_free(m);
+ return (error);
+ }
+ m->m_len = SCARG(uap, valsize);
+ }
+ return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
+ SCARG(uap, name), m));
+}
+
+#ifdef __ECOS
+int
+sys_getsockopt(struct sys_getsockopt_args *uap, register_t *retval)
+{
+#else
+/* ARGSUSED */
+int
+sys_getsockopt(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_getsockopt_args /* {
+ syscallarg(int) s;
+ syscallarg(int) level;
+ syscallarg(int) name;
+ syscallarg(caddr_t) val;
+ syscallarg(socklen_t *) avalsize;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ struct mbuf *m = NULL;
+ socklen_t valsize;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
+ return (error);
+ if (SCARG(uap, val)) {
+ error = copyin((caddr_t)SCARG(uap, avalsize),
+ (caddr_t)&valsize, sizeof (valsize));
+ if (error)
+ return (error);
+ } else
+ valsize = 0;
+ if ((error = sogetopt((struct socket *)fp->f_data, SCARG(uap, level),
+ SCARG(uap, name), &m)) == 0 && SCARG(uap, val) && valsize &&
+ m != NULL) {
+ if (valsize > m->m_len)
+ valsize = m->m_len;
+ error = copyout(mtod(m, caddr_t), SCARG(uap, val), valsize);
+ if (error == 0)
+ error = copyout((caddr_t)&valsize,
+ (caddr_t)SCARG(uap, avalsize), sizeof (valsize));
+ }
+ if (m != NULL)
+ (void) m_free(m);
+ return (error);
+}
+
+#ifndef __ECOS
+int
+sys_pipe(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_pipe_args /* {
+ syscallarg(int *) fdp;
+ } */ *uap = v;
+ int error, fds[2];
+ register_t rval[2];
+
+ if ((error = sys_opipe(p, v, rval)) == -1)
+ return (error);
+
+ fds[0] = rval[0];
+ fds[1] = rval[1];
+ error = copyout((caddr_t)fds, (caddr_t)SCARG(uap, fdp),
+ 2 * sizeof (int));
+ if (error) {
+ fdrelease(p, retval[0]);
+ fdrelease(p, retval[1]);
+ }
+ return (error);
+}
+
+#ifdef OLD_PIPE
+
+/* ARGSUSED */
+int
+sys_opipe(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct filedesc *fdp = p->p_fd;
+ struct file *rf, *wf;
+ struct socket *rso, *wso;
+ int fd, error;
+
+ if ((error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) != 0)
+ return (error);
+ if ((error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) != 0)
+ goto free1;
+ if ((error = falloc(p, &rf, &fd)) != 0)
+ goto free2;
+ retval[0] = fd;
+ rf->f_flag = FREAD;
+ rf->f_type = DTYPE_SOCKET;
+ rf->f_ops = &socketops;
+ rf->f_data = (caddr_t)rso;
+ if ((error = falloc(p, &wf, &fd)) != 0)
+ goto free3;
+ wf->f_flag = FWRITE;
+ wf->f_type = DTYPE_SOCKET;
+ wf->f_ops = &socketops;
+ wf->f_data = (caddr_t)wso;
+ retval[1] = fd;
+ if ((error = unp_connect2(wso, rso)) != 0)
+ goto free4;
+ return (0);
+free4:
+ ffree(wf);
+ fdremove(fdp, retval[1]);
+free3:
+ ffree(rf);
+ fdremove(fdp, retval[0]);
+free2:
+ (void)soclose(wso);
+free1:
+ (void)soclose(rso);
+ return (error);
+}
+#endif
+#endif // __ECOS
+
+/*
+ * Get socket name.
+ */
+#ifdef __ECOS
+int
+sys_getsockname(struct sys_getsockname_args *uap, register_t *retval)
+{
+#else
+/* ARGSUSED */
+int
+sys_getsockname(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_getsockname_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(socklen_t *) alen;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ register struct socket *so;
+ struct mbuf *m;
+ socklen_t len;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0)
+ return (error);
+ error = copyin((caddr_t)SCARG(uap, alen), (caddr_t)&len, sizeof (len));
+ if (error)
+ return (error);
+ so = (struct socket *)fp->f_data;
+ m = m_getclr(M_WAIT, MT_SONAME);
+ if (m == NULL)
+ return (ENOBUFS);
+ error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
+ if (error)
+ goto bad;
+ if (len > m->m_len)
+ len = m->m_len;
+ error = copyout(mtod(m, caddr_t), (caddr_t)SCARG(uap, asa), len);
+ if (error == 0)
+ error = copyout((caddr_t)&len, (caddr_t)SCARG(uap, alen),
+ sizeof (len));
+bad:
+ m_freem(m);
+ return (error);
+}
+
+/*
+ * Get name of peer for connected socket.
+ */
+/* ARGSUSED */
+#ifdef __ECOS
+int
+sys_getpeername(struct sys_getpeername_args *uap, register_t *retval)
+{
+#else
+int
+sys_getpeername(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct sys_getpeername_args /* {
+ syscallarg(int) fdes;
+ syscallarg(caddr_t) asa;
+ syscallarg(socklen_t *) alen;
+ } */ *uap = v;
+#endif // __ECOS
+ struct file *fp;
+ register struct socket *so;
+ struct mbuf *m;
+ socklen_t len;
+ int error;
+
+ if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0)
+ return (error);
+ so = (struct socket *)fp->f_data;
+ if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
+ return (ENOTCONN);
+ error = copyin((caddr_t)SCARG(uap, alen), (caddr_t)&len, sizeof (len));
+ if (error)
+ return (error);
+ m = m_getclr(M_WAIT, MT_SONAME);
+ if (m == NULL)
+ return (ENOBUFS);
+ error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0);
+ if (error)
+ goto bad;
+ if (len > m->m_len)
+ len = m->m_len;
+ error = copyout(mtod(m, caddr_t), (caddr_t)SCARG(uap, asa), len);
+ if (error == 0)
+ error = copyout((caddr_t)&len, (caddr_t)SCARG(uap, alen),
+ sizeof (len));
+bad:
+ m_freem(m);
+ return (error);
+}
+
+int
+sockargs(mp, buf, buflen, type)
+ struct mbuf **mp;
+ caddr_t buf;
+ socklen_t buflen;
+ int type;
+{
+ register struct sockaddr *sa;
+ register struct mbuf *m;
+ int error;
+
+ if (buflen > MLEN) {
+#ifdef COMPAT_OLDSOCK
+ if (type == MT_SONAME && buflen <= 112)
+ buflen = MLEN; /* unix domain compat. hack */
+ else
+#endif
+ return (EINVAL);
+ }
+ m = m_get(M_WAIT, type);
+ if (m == NULL)
+ return (ENOBUFS);
+ m->m_len = buflen;
+ error = copyin(buf, mtod(m, caddr_t), buflen);
+ if (error) {
+ (void) m_free(m);
+ return (error);
+ }
+ *mp = m;
+ if (type == MT_SONAME) {
+ sa = mtod(m, struct sockaddr *);
+
+#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
+ if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
+ sa->sa_family = sa->sa_len;
+#endif
+ sa->sa_len = buflen;
+ }
+ return (0);
+}
+
+#ifdef __ECOS
+static int
+ecos_getsock(int fdes, struct file **fpp)
+{
+ struct file *fp;
+ if (getfp(fdes, &fp))
+ return (EBADF);
+ if (fp->f_type != DTYPE_SOCKET)
+ return (ENOTSOCK);
+ *fpp = fp;
+ return (0);
+}
+#else
+int
+getsock(fdp, fdes, fpp)
+ struct filedesc *fdp;
+ int fdes;
+ struct file **fpp;
+{
+ register struct file *fp;
+
+ if ((unsigned)fdes >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fdes]) == NULL)
+ return (EBADF);
+ if (fp->f_type != DTYPE_SOCKET)
+ return (ENOTSOCK);
+ *fpp = fp;
+ return (0);
+}
+#endif
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/bridgestp.c b/ecos/packages/net/tcpip/current/src/sys/net/bridgestp.c
new file mode 100644
index 0000000..e2c4afb
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/bridgestp.c
@@ -0,0 +1,1511 @@
+//==========================================================================
+//
+// sys/net/bridgestp.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jason L. Wright (jason@thought.net)
+// Contributors: Manu Sharma (manu.sharma@ascom.com)
+// Date: 2000-07-18
+// Purpose: Implementation of the spanning tree protocol as defined in
+// ISO/IEC Final DIS 15802-3 (IEEE P802.1D/D17), May 25, 1998.
+// (In English: IEEE 802.1D, Draft 17, 1998)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+//
+/* $OpenBSD: bridgestp.c,v 1.15 2002/12/10 13:22:55 markus Exp $ */
+
+/*
+ * Copyright (c) 2000 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * Implementation of the spanning tree protocol as defined in
+ * ISO/IEC Final DIS 15802-3 (IEEE P802.1D/D17), May 25, 1998.
+ * (In English: IEEE 802.1D, Draft 17, 1998)
+ */
+
+#ifdef __ECOS
+#include <pkgconf/net.h>
+#include <stdio.h>
+#else
+#include "bridge.h"
+#endif
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+#if NBRIDGE
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#ifndef __ECOS
+#include <sys/device.h>
+#endif
+#include <sys/kernel.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_llc.h>
+#include <net/netisr.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <net/if_bridge.h>
+
+#define STP_DEBUG
+#define STP_DETAILED_DEBUG
+#ifdef STP_DEBUG
+#define STPLOG(x) diag_printf x
+#else
+#define STPLOG(x)
+#endif
+
+#ifdef STP_DETAILED_DEBUG
+#define STP_OPERATION_LOG(x) diag_printf x
+#else
+#define STP_OPERATION_LOG(x)
+#endif
+
+/* BPDU message types */
+#define BSTP_MSGTYPE_CFG 0x00 /* Configuration */
+#define BSTP_MSGTYPE_TCN 0x80 /* Topology chg notification */
+
+/* BPDU flags */
+#define BSTP_FLAG_TC 0x01 /* Topology change */
+#define BSTP_FLAG_TCA 0x80 /* Topology change ack */
+
+#define BSTP_MESSAGE_AGE_INCR (1 * 256) /* in 256ths of a second */
+#define BSTP_TICK_VAL (1 * 256) /* in 256ths of a second */
+
+/*
+ * Because BPDU's do not make nicely aligned structures, two different
+ * declarations are used: bstp_?bpdu (wire representation, packed) and
+ * bstp_*_unit (internal, nicely aligned version).
+ */
+
+/* configuration bridge protocol data unit */
+struct bstp_cbpdu {
+ u_int8_t cbu_dsap; /* LLC: destination sap */
+ u_int8_t cbu_ssap; /* LLC: source sap */
+ u_int8_t cbu_ctl; /* LLC: control */
+ u_int16_t cbu_protoid; /* protocol id */
+ u_int8_t cbu_protover; /* protocol version */
+ u_int8_t cbu_bpdutype; /* message type */
+ u_int8_t cbu_flags; /* flags (below) */
+
+ /* root id */
+ u_int16_t cbu_rootpri; /* root priority */
+ u_int8_t cbu_rootaddr[6]; /* root address */
+
+ u_int32_t cbu_rootpathcost; /* root path cost */
+
+ /* bridge id */
+ u_int16_t cbu_bridgepri; /* bridge priority */
+ u_int8_t cbu_bridgeaddr[6]; /* bridge address */
+
+ u_int16_t cbu_portid; /* port id */
+ u_int16_t cbu_messageage; /* current message age */
+ u_int16_t cbu_maxage; /* maximum age */
+ u_int16_t cbu_hellotime; /* hello time */
+ u_int16_t cbu_forwarddelay; /* forwarding delay */
+} __attribute__((__packed__));
+
+/* topology change notification bridge protocol data unit */
+struct bstp_tbpdu {
+ u_int8_t tbu_dsap; /* LLC: destination sap */
+ u_int8_t tbu_ssap; /* LLC: source sap */
+ u_int8_t tbu_ctl; /* LLC: control */
+ u_int16_t tbu_protoid; /* protocol id */
+ u_int8_t tbu_protover; /* protocol version */
+ u_int8_t tbu_bpdutype; /* message type */
+} __attribute__((__packed__));
+
+u_int8_t bstp_etheraddr[] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
+u_int8_t bstp_init_done;
+
+void bstp_initialization(struct bridge_softc *);
+void bstp_stop(struct bridge_softc *);
+void bstp_initialize_port(struct bridge_softc *, struct bridge_iflist *);
+void bstp_ifupdstatus(struct bridge_softc *, struct bridge_iflist *);
+void bstp_enable_port(struct bridge_softc *, struct bridge_iflist *);
+void bstp_disable_port(struct bridge_softc *, struct bridge_iflist *);
+void bstp_enable_change_detection(struct bridge_iflist *);
+void bstp_disable_change_detection(struct bridge_iflist *);
+int bstp_root_bridge(struct bridge_softc *sc);
+int bstp_supersedes_port_info(struct bridge_softc *, struct bridge_iflist *,
+ struct bstp_config_unit *);
+int bstp_designated_port(struct bridge_softc *, struct bridge_iflist *);
+int bstp_designated_for_some_port(struct bridge_softc *);
+void bstp_transmit_config(struct bridge_softc *, struct bridge_iflist *);
+void bstp_transmit_tcn(struct bridge_softc *);
+struct mbuf *bstp_input(struct bridge_softc *, struct ifnet *,
+ struct ether_header *, struct mbuf *);
+void bstp_received_config_bpdu(struct bridge_softc *, struct bridge_iflist *,
+ struct bstp_config_unit *);
+void bstp_received_tcn_bpdu(struct bridge_softc *, struct bridge_iflist *,
+ struct bstp_tcn_unit *);
+void bstp_record_config_information(struct bridge_softc *,
+ struct bridge_iflist *, struct bstp_config_unit *);
+void bstp_record_config_timeout_values(struct bridge_softc *,
+ struct bstp_config_unit *);
+void bstp_config_bpdu_generation(struct bridge_softc *);
+void bstp_send_config_bpdu(struct bridge_iflist *, struct bstp_config_unit *);
+void bstp_configuration_update(struct bridge_softc *);
+void bstp_root_selection(struct bridge_softc *);
+void bstp_designated_port_selection(struct bridge_softc *);
+void bstp_become_designated_port(struct bridge_softc *, struct bridge_iflist *);
+void bstp_port_state_selection(struct bridge_softc *);
+void bstp_make_forwarding(struct bridge_softc *, struct bridge_iflist *);
+void bstp_make_blocking(struct bridge_softc *, struct bridge_iflist *);
+void bstp_set_port_state(struct bridge_iflist *, u_int8_t);
+void bstp_set_bridge_priority(struct bridge_softc *, u_int64_t);
+void bstp_set_port_priority(struct bridge_softc *, struct bridge_iflist *,
+ u_int16_t);
+void bstp_set_path_cost(struct bridge_softc *, struct bridge_iflist *,
+ u_int32_t);
+void bstp_topology_change_detection(struct bridge_softc *);
+void bstp_topology_change_acknowledged(struct bridge_softc *);
+void bstp_acknowledge_topology_change(struct bridge_softc *,
+ struct bridge_iflist *);
+
+void bstp_tick(void *);
+void bstp_timer_start(struct bridge_timer *, u_int16_t);
+void bstp_timer_stop(struct bridge_timer *);
+int bstp_timer_expired(struct bridge_timer *, u_int16_t);
+
+void bstp_hold_timer_expiry(struct bridge_softc *, struct bridge_iflist *);
+void bstp_message_age_timer_expiry(struct bridge_softc *,
+ struct bridge_iflist *);
+void bstp_forward_delay_timer_expiry(struct bridge_softc *,
+ struct bridge_iflist *);
+void bstp_topology_change_timer_expiry(struct bridge_softc *);
+void bstp_tcn_timer_expiry(struct bridge_softc *);
+void bstp_hello_timer_expiry(struct bridge_softc *);
+
+char stp_buf [32];
+char *
+stp_port_state (unsigned int state) {
+ memset (stp_buf, 0x0, 32);
+ switch (state) {
+ case BSTP_IFSTATE_DISABLED : sprintf (stp_buf, " Disabled "); break;
+ case BSTP_IFSTATE_LISTENING : sprintf (stp_buf, " Listn'ng "); break;
+ case BSTP_IFSTATE_LEARNING : sprintf (stp_buf, " Lrn'ng "); break;
+ case BSTP_IFSTATE_FORWARDING : sprintf (stp_buf, " Fwd'ng "); break;
+ case BSTP_IFSTATE_BLOCKING : sprintf (stp_buf, " Blk'ng "); break;
+ default: sprintf (stp_buf, " UNKNOWN "); break;
+ }
+ return stp_buf;
+}
+
+void
+bstp_transmit_config(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ if (bif->bif_hold_timer.active) {
+ bif->bif_config_pending = 1;
+ return;
+ }
+
+ bif->bif_config_bpdu.cu_message_type = BSTP_MSGTYPE_CFG;
+ bif->bif_config_bpdu.cu_rootid = sc->sc_designated_root;
+ bif->bif_config_bpdu.cu_root_path_cost = sc->sc_root_path_cost;
+ bif->bif_config_bpdu.cu_bridge_id = sc->sc_bridge_id;
+ bif->bif_config_bpdu.cu_port_id = bif->bif_port_id;
+
+ if (bstp_root_bridge(sc))
+ bif->bif_config_bpdu.cu_message_age = 0;
+ else
+ bif->bif_config_bpdu.cu_message_age =
+ sc->sc_root_port->bif_message_age_timer.value +
+ BSTP_MESSAGE_AGE_INCR;
+
+ bif->bif_config_bpdu.cu_max_age = sc->sc_max_age;
+ bif->bif_config_bpdu.cu_hello_time = sc->sc_hello_time;
+ bif->bif_config_bpdu.cu_forward_delay = sc->sc_forward_delay;
+ bif->bif_config_bpdu.cu_topology_change_acknowledgment
+ = bif->bif_topology_change_acknowledge;
+ bif->bif_config_bpdu.cu_topology_change = sc->sc_topology_change;
+
+ if (bif->bif_config_bpdu.cu_message_age < sc->sc_max_age) {
+ bif->bif_topology_change_acknowledge = 0;
+ bif->bif_config_pending = 0;
+ bstp_send_config_bpdu(bif, &bif->bif_config_bpdu);
+ bstp_timer_start(&bif->bif_hold_timer, 0);
+ }
+}
+
+void
+bstp_send_config_bpdu(bif, cu)
+ struct bridge_iflist *bif;
+ struct bstp_config_unit *cu;
+{
+ struct arpcom *arp;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ struct ether_header eh;
+ struct bstp_cbpdu bpdu;
+ int s, error;
+
+ s = splimp();
+ ifp = bif->ifp;
+ arp = (struct arpcom *)ifp;
+
+ if ((ifp->if_flags & IFF_RUNNING) == 0) {
+ splx(s);
+ return;
+ }
+#ifdef ALTQ
+ if (!ALTQ_IS_ENABLED(&ifp->if_snd))
+#endif
+ if (IF_QFULL(&ifp->if_snd)) {
+ splx(s);
+ return;
+ }
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ splx(s);
+ return;
+ }
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = sizeof(eh) + sizeof(bpdu);
+ m->m_len = m->m_pkthdr.len;
+
+ bpdu.cbu_ssap = bpdu.cbu_dsap = LLC_8021D_LSAP;
+ bpdu.cbu_ctl = LLC_UI;
+ bpdu.cbu_protoid = htons(0);
+ bpdu.cbu_protover = 0;
+ bpdu.cbu_bpdutype = cu->cu_message_type;
+ bpdu.cbu_flags = (cu->cu_topology_change ? BSTP_FLAG_TC : 0) |
+ (cu->cu_topology_change_acknowledgment ? BSTP_FLAG_TCA : 0);
+
+ bpdu.cbu_rootpri = htons(cu->cu_rootid >> 48);
+ bpdu.cbu_rootaddr[0] = cu->cu_rootid >> 40;
+ bpdu.cbu_rootaddr[1] = cu->cu_rootid >> 32;
+ bpdu.cbu_rootaddr[2] = cu->cu_rootid >> 24;
+ bpdu.cbu_rootaddr[3] = cu->cu_rootid >> 16;
+ bpdu.cbu_rootaddr[4] = cu->cu_rootid >> 8;
+ bpdu.cbu_rootaddr[5] = cu->cu_rootid >> 0;
+
+ bpdu.cbu_rootpathcost = htonl(cu->cu_root_path_cost);
+
+ bpdu.cbu_bridgepri = htons(cu->cu_rootid >> 48);
+ bpdu.cbu_bridgeaddr[0] = cu->cu_rootid >> 40;
+ bpdu.cbu_bridgeaddr[1] = cu->cu_rootid >> 32;
+ bpdu.cbu_bridgeaddr[2] = cu->cu_rootid >> 24;
+ bpdu.cbu_bridgeaddr[3] = cu->cu_rootid >> 16;
+ bpdu.cbu_bridgeaddr[4] = cu->cu_rootid >> 8;
+ bpdu.cbu_bridgeaddr[5] = cu->cu_rootid >> 0;
+
+ bpdu.cbu_portid = htons(cu->cu_port_id);
+ bpdu.cbu_messageage = htons(cu->cu_message_age);
+ bpdu.cbu_maxage = htons(cu->cu_max_age);
+ bpdu.cbu_hellotime = htons(cu->cu_hello_time);
+ bpdu.cbu_forwarddelay = htons(cu->cu_forward_delay);
+
+ bcopy(arp->ac_enaddr, eh.ether_shost, ETHER_ADDR_LEN);
+ bcopy(bstp_etheraddr, eh.ether_dhost, ETHER_ADDR_LEN);
+ eh.ether_type = htons(sizeof(bpdu));
+
+ bcopy(&eh, m->m_data, sizeof(eh));
+ bcopy(&bpdu, m->m_data + sizeof(eh), sizeof(bpdu));
+
+ STPLOG ((" - <%s>: Tx with Port 0x%x; Age %d; Flags %d\n", bif->ifp->if_xname,
+ cu->cu_port_id, cu->cu_message_age, bpdu.cbu_flags));
+
+ IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
+ if (error == 0 && (ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ splx(s);
+}
+
+int
+bstp_root_bridge(sc)
+ struct bridge_softc *sc;
+{
+ return (sc->sc_designated_root == sc->sc_bridge_id);
+}
+
+int
+bstp_supersedes_port_info(sc, bif, cu)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+ struct bstp_config_unit *cu;
+{
+ if (cu->cu_rootid < bif->bif_designated_root) {
+ return (1);
+ }
+ if (cu->cu_rootid > bif->bif_designated_root) {
+ return (0);
+ }
+
+ if (cu->cu_root_path_cost < bif->bif_designated_cost) {
+ return (1);
+ }
+ if (cu->cu_root_path_cost > bif->bif_designated_cost) {
+ return (0);
+ }
+
+ if (cu->cu_bridge_id < bif->bif_designated_bridge) {
+ return (1);
+ }
+ if (cu->cu_bridge_id > bif->bif_designated_bridge) {
+ return (0);
+ }
+
+ if (sc->sc_bridge_id != cu->cu_bridge_id) {
+ return (1);
+ }
+ if (cu->cu_port_id <= bif->bif_designated_port) {
+ return (1);
+ }
+ return (0);
+}
+
+void
+bstp_record_config_information(sc, bif, cu)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+ struct bstp_config_unit *cu;
+{
+ bif->bif_designated_root = cu->cu_rootid;
+ bif->bif_designated_cost = cu->cu_root_path_cost;
+ bif->bif_designated_bridge = cu->cu_bridge_id;
+ bif->bif_designated_port = cu->cu_port_id;
+ bstp_timer_start(&bif->bif_message_age_timer, cu->cu_message_age);
+}
+
+void
+bstp_record_config_timeout_values(sc, config)
+ struct bridge_softc *sc;
+ struct bstp_config_unit *config;
+{
+ sc->sc_max_age = config->cu_max_age;
+ sc->sc_hello_time = config->cu_hello_time;
+ sc->sc_forward_delay = config->cu_forward_delay;
+ sc->sc_topology_change = config->cu_topology_change;
+}
+
+void
+bstp_config_bpdu_generation(sc)
+ struct bridge_softc *sc;
+{
+ struct bridge_iflist *bif;
+
+ STPLOG (("STP : Tx Hello BPDU ...\n"));
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bstp_designated_port(sc, bif) &&
+ (bif->bif_state != BSTP_IFSTATE_DISABLED)) {
+ bstp_transmit_config(sc, bif);
+ } else {
+ STPLOG ((" - <%s>: No Tx\n", bif->ifp->if_xname));
+ }
+ }
+}
+
+int
+bstp_designated_port(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ return ((bif->bif_designated_bridge == sc->sc_bridge_id)
+ && (bif->bif_designated_port == bif->bif_port_id));
+}
+
+void
+bstp_transmit_tcn(sc)
+ struct bridge_softc *sc;
+{
+ struct bstp_tbpdu bpdu;
+ struct bridge_iflist *bif = sc->sc_root_port;
+ struct ifnet *ifp = bif->ifp;
+ struct arpcom *arp = (struct arpcom *)ifp;
+ struct ether_header *eh;
+ struct mbuf *m;
+ int s, error;
+
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
+ return;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return;
+
+ STPLOG (("STP : Tx TCN BPDU on <%s> ...\n", ifp->if_xname));
+
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = sizeof(*eh) + sizeof(bpdu);
+ m->m_len = m->m_pkthdr.len;
+
+ eh = mtod(m, struct ether_header *);
+ bcopy(arp->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN);
+ bcopy(bstp_etheraddr, eh->ether_dhost, ETHER_ADDR_LEN);
+ eh->ether_type = htons(sizeof(bpdu));
+
+ bpdu.tbu_ssap = bpdu.tbu_dsap = LLC_8021D_LSAP;
+ bpdu.tbu_ctl = LLC_UI;
+ bpdu.tbu_protoid = 0;
+ bpdu.tbu_protover = 0;
+ bpdu.tbu_bpdutype = BSTP_MSGTYPE_TCN;
+ bcopy(&bpdu, m->m_data + sizeof(*eh), sizeof(bpdu));
+
+ s = splimp();
+ IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
+ if (error == 0 && (ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ m = NULL;
+
+ splx(s);
+ if (m != NULL)
+ m_freem(m);
+}
+
+void
+bstp_configuration_update(sc)
+ struct bridge_softc *sc;
+{
+ STP_OPERATION_LOG ((" %s \n", __FUNCTION__));
+ bstp_root_selection(sc);
+ bstp_designated_port_selection(sc);
+}
+
+void
+bstp_root_selection(sc)
+ struct bridge_softc *sc;
+{
+ struct bridge_iflist *root_port = NULL, *bif;
+
+ STP_OPERATION_LOG ((" => Root Port selection ...\n", __FUNCTION__));
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ STP_OPERATION_LOG ((" - <%s>", bif->ifp->if_xname));
+ if (!(bif->bif_flags & IFBIF_STP)) {
+ STP_OPERATION_LOG ((" STP not configured\n"));
+ continue;
+ }
+ if (bstp_designated_port(sc, bif)) {
+ STP_OPERATION_LOG ((" dsgntd port\n"));
+ continue;
+ }
+ if (bif->bif_state == BSTP_IFSTATE_DISABLED) {
+ STP_OPERATION_LOG ((" .. in state DISABLED \n"));
+ continue;
+ }
+ if (bif->bif_designated_root >= sc->sc_bridge_id) {
+ STP_OPERATION_LOG ((" root: ifp dsgntd >= sc\n"));
+ continue;
+ }
+ if (root_port == NULL) {
+ STP_OPERATION_LOG ((" Set as Root Port\n"));
+ goto set_port;
+ }
+
+ if (bif->bif_designated_root < root_port->bif_designated_root) {
+ STP_OPERATION_LOG ((" ifp dsgntd < root dsgntd; Set as Root Port \n"));
+ goto set_port;
+ }
+ if (bif->bif_designated_root > root_port->bif_designated_root) {
+ STP_OPERATION_LOG ((" root: ifp dsgntd > root dsgntd \n"));
+ continue;
+ }
+
+ if ((bif->bif_designated_cost + bif->bif_path_cost) <
+ (root_port->bif_designated_cost + root_port->bif_path_cost)) {
+ STP_OPERATION_LOG ((" (dsgntd_cost+path_cost): ifp < root; Set as Root Port \n"));
+ goto set_port;
+ }
+ if ((bif->bif_designated_cost + bif->bif_path_cost) >
+ (root_port->bif_designated_cost + root_port->bif_path_cost)) {
+ STP_OPERATION_LOG ((" (dsgntd_cost+path_cost): ifp > root \n"));
+ continue;
+ }
+
+ if (bif->bif_designated_bridge < root_port->bif_designated_bridge) {
+ STP_OPERATION_LOG ((" bridge: ifp dsgntd < root dsgntd; Set as Root Port \n"));
+ goto set_port;
+ }
+ if (bif->bif_designated_bridge > root_port->bif_designated_bridge) {
+ STP_OPERATION_LOG ((" bridge: ifp dsgntd > root dsgntd \n"));
+ continue;
+ }
+
+ if (bif->bif_designated_port < root_port->bif_designated_port) {
+ STP_OPERATION_LOG ((" port: ifp dsgntd (%d) < root dsgntd (%d); Set as Root Port\n",
+ bif->bif_designated_port, root_port->bif_designated_port));
+ goto set_port;
+ }
+ if (bif->bif_designated_port > root_port->bif_designated_port) {
+ STP_OPERATION_LOG ((" port: ifp dsgntd (%d) > root dsgntd (%d)\n",
+ bif->bif_designated_port, root_port->bif_designated_port));
+ continue;
+ }
+
+ if (bif->bif_port_id >= root_port->bif_port_id) {
+ STP_OPERATION_LOG ((" ifp port_id (%d) >= root port_id (%d) 8 \n",
+ bif->bif_port_id, root_port->bif_port_id));
+ continue;
+ }
+set_port:
+ root_port = bif;
+ }
+
+ sc->sc_root_port = root_port;
+ if (root_port == NULL) {
+ sc->sc_designated_root = sc->sc_bridge_id;
+ sc->sc_root_path_cost = 0;
+ STPLOG ((" Root Port : <SELF ROOT>, Path Cost : 0\n"));
+ } else {
+ sc->sc_designated_root = root_port->bif_designated_root;
+ sc->sc_root_path_cost = root_port->bif_designated_cost +
+ root_port->bif_path_cost;
+ STPLOG ((" Root Port : <%s>, Path Cost : 0\n",
+ root_port->ifp->if_xname, sc->sc_root_path_cost));
+ }
+}
+
+void
+bstp_designated_port_selection(sc)
+ struct bridge_softc *sc;
+{
+ struct bridge_iflist *bif;
+
+ STP_OPERATION_LOG ((" => Designated Port selection ...\n"));
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bstp_designated_port(sc, bif)) {
+ STPLOG ((" - <%s>: already designated \n", bif->ifp->if_xname));
+ goto designated;
+ }
+ if (bif->bif_designated_root != sc->sc_designated_root) {
+ STPLOG ((" - <%s>: becomes designated\n", bif->ifp->if_xname));
+ goto designated;
+ }
+
+ /*
+ * PLC network is special, we cannot go as per standards because of
+ * our network topology and behavior
+ *
+ if (sc->sc_root_path_cost < bif->bif_designated_cost) {
+ STPLOG ((" - <%s>: becomes designated path cost (1)\n", bif->ifp->if_xname));
+ goto designated;
+ }
+ if (sc->sc_root_path_cost > bif->bif_designated_cost) {
+ STPLOG ((" - <%s>: Cannot be designated; Root cost (%d) > Desig cost (%d) \n",
+ bif->ifp->if_xname, sc->sc_root_path_cost, bif->bif_designated_cost));
+ continue;
+ }
+ */
+
+ if (sc->sc_bridge_id < bif->bif_designated_bridge) {
+ STPLOG ((" - <%s>: becomes dsgntd (self-brdgid < dsgntd-brdgid); \n", bif->ifp->if_xname));
+ goto designated;
+ }
+ if (sc->sc_bridge_id > bif->bif_designated_bridge) {
+ STPLOG ((" - <%s>: Cannot be dsgntd (self-brdgid > dsgntd-brdgid); \n", bif->ifp->if_xname));
+ continue;
+ }
+
+ if (bif->bif_port_id > bif->bif_designated_port) {
+ STPLOG ((" - <%s>: Cannot be dsgntd (self-portid > bsgntd-portid); \n", bif->ifp->if_xname));
+ continue;
+ }
+
+ /*
+ * PLC network is special, we cannot go as per standards because of
+ * our network topology and behavior
+ */
+ if (sc->sc_root_path_cost < bif->bif_designated_cost) {
+ STPLOG ((" - <%s>: becomes dsgntd path cost (1)\n", bif->ifp->if_xname));
+ goto designated;
+ }
+ if (sc->sc_root_path_cost > bif->bif_designated_cost) {
+ STPLOG ((" - <%s>: Cannot be dsgntd; Root cost (%d) > Desig cost (%d) \n",
+ bif->ifp->if_xname, sc->sc_root_path_cost, bif->bif_designated_cost));
+ continue;
+ }
+designated:
+ bstp_become_designated_port(sc, bif);
+ }
+}
+
+void
+bstp_become_designated_port(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ bif->bif_designated_root = sc->sc_designated_root;
+ bif->bif_designated_cost = sc->sc_root_path_cost;
+ bif->bif_designated_bridge = sc->sc_bridge_id;
+ bif->bif_designated_port = bif->bif_port_id;
+
+ STP_OPERATION_LOG ((" => %s values (cost:%d, port:0x%x)\n",
+ __FUNCTION__, bif->ifp->if_xname, bif->bif_designated_cost, bif->bif_designated_port));
+ //STP_OPERATION_LOG (("(cost:%d, port:0x%x)\n", bif->bif_designated_cost, bif->bif_designated_port));
+}
+
+void
+bstp_port_state_selection(sc)
+ struct bridge_softc *sc;
+{
+ struct bridge_iflist *bif;
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bif == sc->sc_root_port) {
+ bif->bif_config_pending = 0;
+ bif->bif_topology_change_acknowledge = 0;
+ bstp_make_forwarding(sc, bif);
+ } else if (bstp_designated_port(sc, bif)) {
+ bstp_timer_stop(&bif->bif_message_age_timer);
+ bstp_make_forwarding(sc, bif);
+ } else {
+ bif->bif_config_pending = 0;
+ bif->bif_topology_change_acknowledge = 0;
+ bstp_make_blocking(sc, bif);
+ }
+ }
+}
+
+void
+bstp_make_forwarding(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ if (bif->bif_state == BSTP_IFSTATE_BLOCKING) {
+ bstp_set_port_state(bif, BSTP_IFSTATE_LISTENING);
+ bstp_timer_start(&bif->bif_forward_delay_timer, 0);
+ }
+}
+
+void
+bstp_make_blocking(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ if ((bif->bif_state != BSTP_IFSTATE_DISABLED) &&
+ (bif->bif_state != BSTP_IFSTATE_BLOCKING)) {
+ if ((bif->bif_state == BSTP_IFSTATE_FORWARDING) ||
+ (bif->bif_state == BSTP_IFSTATE_LEARNING)) {
+ if (bif->bif_change_detection_enabled) {
+ bstp_topology_change_detection(sc);
+ }
+ bridge_rtdelete(sc, bif->ifp, 1);
+ }
+ bstp_set_port_state(bif, BSTP_IFSTATE_BLOCKING);
+ bstp_timer_stop(&bif->bif_forward_delay_timer);
+ }
+}
+
+void
+bstp_set_port_state(bif, state)
+ struct bridge_iflist *bif;
+ u_int8_t state;
+{
+ bif->bif_state = state;
+}
+
+void
+bstp_topology_change_detection(sc)
+ struct bridge_softc *sc;
+{
+ if (bstp_root_bridge(sc)) {
+ STPLOG ((" -> %s : Root Bridge\n", __FUNCTION__));
+ sc->sc_topology_change = 1;
+ bstp_timer_start(&sc->sc_topology_change_timer, 0);
+ } else if (!sc->sc_topology_change_detected) {
+ STPLOG ((" -> %s : NOT Root Bridge, Tx TCN\n", __FUNCTION__));
+ bstp_transmit_tcn(sc);
+ bstp_timer_start(&sc->sc_tcn_timer, 0);
+ }
+ sc->sc_topology_change_detected = 1;
+}
+
+void
+bstp_topology_change_acknowledged(sc)
+ struct bridge_softc *sc;
+{
+ sc->sc_topology_change_detected = 0;
+ bstp_timer_stop(&sc->sc_tcn_timer);
+}
+
+void
+bstp_acknowledge_topology_change(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ bif->bif_topology_change_acknowledge = 1;
+ bstp_transmit_config(sc, bif);
+}
+
+struct mbuf *
+bstp_input(sc, ifp, eh, m)
+ struct bridge_softc *sc;
+ struct ifnet *ifp;
+ struct ether_header *eh;
+ struct mbuf *m;
+{
+ struct bridge_iflist *bif = NULL;
+ struct bstp_tbpdu tpdu;
+ struct bstp_cbpdu cpdu;
+ struct bstp_config_unit cu;
+ struct bstp_tcn_unit tu;
+ u_int16_t len;
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bif->ifp == ifp)
+ break;
+ }
+
+ if (bif == NULL)
+ goto out;
+
+ len = ntohs(eh->ether_type);
+ if (len < sizeof(tpdu)) {
+ goto out;
+ }
+ if (m->m_pkthdr.len > len)
+ m_adj(m, len - m->m_pkthdr.len);
+ if ((m = m_pullup(m, sizeof(tpdu))) == NULL) {
+ goto out;
+ }
+ bcopy(mtod(m, struct tpdu *), &tpdu, sizeof(tpdu));
+
+ if (tpdu.tbu_dsap != LLC_8021D_LSAP ||
+ tpdu.tbu_ssap != LLC_8021D_LSAP ||
+ tpdu.tbu_ctl != LLC_UI) {
+ goto out;
+ }
+ if (tpdu.tbu_protoid != 0 || tpdu.tbu_protover != 0) {
+ goto out;
+ }
+
+ switch (tpdu.tbu_bpdutype) {
+ case BSTP_MSGTYPE_TCN:
+
+ STPLOG (("STP : Rx TCN on <%s> from %02X:%02X:%02X:%02X:%02X:%02X \n", bif->ifp->if_xname,
+ eh->ether_shost[0], eh->ether_shost[1], eh->ether_shost[2],
+ eh->ether_shost[3], eh->ether_shost[4], eh->ether_shost[5]));
+
+ tu.tu_message_type = tpdu.tbu_bpdutype;
+ bstp_received_tcn_bpdu(sc, bif, &tu);
+ break;
+
+ case BSTP_MSGTYPE_CFG:
+
+ STPLOG (("STP : Rx CFG on <%s> from %02X:%02X:%02X:%02X:%02X:%02X \n", bif->ifp->if_xname,
+ eh->ether_shost[0], eh->ether_shost[1], eh->ether_shost[2],
+ eh->ether_shost[3], eh->ether_shost[4], eh->ether_shost[5]));
+
+ if ((m = m_pullup(m, sizeof(cpdu))) == NULL)
+ goto out;
+ bcopy(mtod(m, struct bstp_cpdu *), &cpdu, sizeof(cpdu));
+
+ cu.cu_rootid =
+ (((u_int64_t)ntohs(cpdu.cbu_rootpri)) << 48) |
+ (((u_int64_t)cpdu.cbu_rootaddr[0]) << 40) |
+ (((u_int64_t)cpdu.cbu_rootaddr[1]) << 32) |
+ (((u_int64_t)cpdu.cbu_rootaddr[2]) << 24) |
+ (((u_int64_t)cpdu.cbu_rootaddr[3]) << 16) |
+ (((u_int64_t)cpdu.cbu_rootaddr[4]) << 8) |
+ (((u_int64_t)cpdu.cbu_rootaddr[5]) << 0);
+
+ cu.cu_bridge_id =
+ (((u_int64_t)ntohs(cpdu.cbu_bridgepri)) << 48) |
+ (((u_int64_t)cpdu.cbu_bridgeaddr[0]) << 40) |
+ (((u_int64_t)cpdu.cbu_bridgeaddr[1]) << 32) |
+ (((u_int64_t)cpdu.cbu_bridgeaddr[2]) << 24) |
+ (((u_int64_t)cpdu.cbu_bridgeaddr[3]) << 16) |
+ (((u_int64_t)cpdu.cbu_bridgeaddr[4]) << 8) |
+ (((u_int64_t)cpdu.cbu_bridgeaddr[5]) << 0);
+
+ cu.cu_root_path_cost = ntohl(cpdu.cbu_rootpathcost);
+ cu.cu_message_age = ntohs(cpdu.cbu_messageage);
+ cu.cu_max_age = ntohs(cpdu.cbu_maxage);
+ cu.cu_hello_time = ntohs(cpdu.cbu_hellotime);
+ cu.cu_forward_delay = ntohs(cpdu.cbu_forwarddelay);
+ cu.cu_port_id = ntohs(cpdu.cbu_portid);
+ cu.cu_message_type = cpdu.cbu_bpdutype;
+ cu.cu_topology_change_acknowledgment =
+ (cpdu.cbu_flags & BSTP_FLAG_TCA) ? 1 : 0;
+ cu.cu_topology_change =
+ (cpdu.cbu_flags & BSTP_FLAG_TC) ? 1 : 0;
+ bstp_received_config_bpdu(sc, bif, &cu);
+ break;
+ default:
+ goto out;
+ }
+
+out:
+ if (m)
+ m_freem(m);
+ return (NULL);
+}
+
+void
+bstp_received_config_bpdu(sc, bif, cu)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+ struct bstp_config_unit *cu;
+{
+ int root;
+
+ root = bstp_root_bridge(sc);
+
+ if (bif->bif_state != BSTP_IFSTATE_DISABLED) {
+ if (bstp_supersedes_port_info(sc, bif, cu)) {
+ STPLOG ((" Rx CFG on <%s> superseds port info; RE-Evaluating...\n", bif->ifp->if_xname));
+ bstp_record_config_information(sc, bif, cu);
+ bstp_configuration_update(sc);
+ bstp_port_state_selection(sc);
+
+ if ((!bstp_root_bridge(sc)) && root) {
+ bstp_timer_stop(&sc->sc_hello_timer);
+
+ if (sc->sc_topology_change_detected) {
+ bstp_timer_stop(&sc->sc_topology_change_timer);
+ bstp_transmit_tcn(sc);
+ bstp_timer_start(&sc->sc_tcn_timer, 0);
+ }
+ }
+
+ if (bif == sc->sc_root_port) {
+ bstp_record_config_timeout_values(sc, cu);
+ bstp_config_bpdu_generation(sc);
+
+ if (cu->cu_topology_change_acknowledgment) {
+ bstp_topology_change_acknowledged(sc);
+ }
+ }
+ } else if (bstp_designated_port(sc, bif)) {
+ STPLOG ((" Port <%s> supersedes Rx CFG info\n", bif->ifp->if_xname));
+ bstp_transmit_config(sc, bif);
+ }
+ }
+}
+
+void
+bstp_received_tcn_bpdu(sc, bif, tcn)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+ struct bstp_tcn_unit *tcn;
+{
+ if (bif->bif_state != BSTP_IFSTATE_DISABLED &&
+ bstp_designated_port(sc, bif)) {
+ bstp_topology_change_detection(sc);
+ bstp_acknowledge_topology_change(sc, bif);
+ }
+}
+
+void
+bstp_hello_timer_expiry(sc)
+ struct bridge_softc *sc;
+{
+ bstp_config_bpdu_generation(sc);
+ bstp_timer_start(&sc->sc_hello_timer, 0);
+}
+
+void
+bstp_message_age_timer_expiry(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ int root;
+
+ root = bstp_root_bridge(sc);
+ bstp_become_designated_port(sc, bif);
+ bstp_configuration_update(sc);
+ bstp_port_state_selection(sc);
+
+ if ((bstp_root_bridge(sc)) && (!root)) {
+ sc->sc_max_age = sc->sc_bridge_max_age;
+ sc->sc_hello_time = sc->sc_bridge_hello_time;
+ sc->sc_forward_delay = sc->sc_bridge_forward_delay;
+ bstp_topology_change_detection(sc);
+ bstp_timer_stop(&sc->sc_tcn_timer);
+ bstp_config_bpdu_generation(sc);
+ bstp_timer_start(&sc->sc_hello_timer, 0);
+ }
+}
+
+void
+bstp_forward_delay_timer_expiry(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ if (bif->bif_state == BSTP_IFSTATE_LISTENING) {
+ bstp_set_port_state(bif, BSTP_IFSTATE_LEARNING);
+ bstp_timer_start(&bif->bif_forward_delay_timer, 0);
+ } else if (bif->bif_state == BSTP_IFSTATE_LEARNING) {
+ bstp_set_port_state(bif, BSTP_IFSTATE_FORWARDING);
+ if (bstp_designated_for_some_port(sc) &&
+ bif->bif_change_detection_enabled)
+ bstp_topology_change_detection(sc);
+ }
+}
+
+int
+bstp_designated_for_some_port(sc)
+ struct bridge_softc *sc;
+{
+
+ struct bridge_iflist *bif;
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bif->bif_designated_bridge == sc->sc_bridge_id)
+ return (1);
+ }
+ return (0);
+}
+
+void
+bstp_tcn_timer_expiry(sc)
+ struct bridge_softc *sc;
+{
+ STPLOG ((" STP: tcn timer expired \n"));
+ bstp_transmit_tcn(sc);
+ bstp_timer_start(&sc->sc_tcn_timer, 0);
+}
+
+void
+bstp_topology_change_timer_expiry(sc)
+ struct bridge_softc *sc;
+{
+ STPLOG ((" STP: topology change timer expired \n"));
+ sc->sc_topology_change_detected = 0;
+ sc->sc_topology_change = 0;
+}
+
+void
+bstp_hold_timer_expiry(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ if (bif->bif_config_pending)
+ bstp_transmit_config(sc, bif);
+}
+
+void
+bstp_initialization(sc)
+ struct bridge_softc *sc;
+{
+ struct bridge_iflist *bif, *mif;
+ struct arpcom *ac, *mac;
+
+ mif = NULL; mac = NULL;
+ /* Browse through the ethernet address of each interface and pick the
+ * one which has lowest value
+ */
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP)) {
+ continue;
+ }
+ if (bif->ifp->if_type != IFT_ETHER) {
+ continue;
+ }
+ bif->bif_port_id = (bif->bif_priority << 8) |
+ (bif->ifp->if_index & 0xff);
+
+ if (mif == NULL) {
+ mif = bif;
+ mac = (struct arpcom *)bif->ifp;
+ continue;
+ }
+ ac = (struct arpcom *)bif->ifp;
+ if (memcmp(ac->ac_enaddr, mac->ac_enaddr, ETHER_ADDR_LEN) < 0) {
+ mif = bif;
+ mac = (struct arpcom *)bif->ifp;
+ continue;
+ }
+ }
+
+ if (mif == NULL) {
+ bstp_stop(sc);
+ return;
+ }
+
+ /* Configure bridge-id as specified in standards
+ */
+ sc->sc_bridge_id =
+ (((u_int64_t)sc->sc_bridge_priority) << 48) |
+ (((u_int64_t)mac->ac_enaddr[0]) << 40) |
+ (((u_int64_t)mac->ac_enaddr[1]) << 32) |
+ (mac->ac_enaddr[2] << 24) | (mac->ac_enaddr[3] << 16) |
+ (mac->ac_enaddr[4] << 8) | (mac->ac_enaddr[5]);
+
+ /* Configure self as root bridge
+ */
+ sc->sc_designated_root = sc->sc_bridge_id;
+ sc->sc_root_path_cost = 0;
+ sc->sc_root_port = NULL;
+
+ sc->sc_max_age = sc->sc_bridge_max_age;
+ sc->sc_hello_time = sc->sc_bridge_hello_time;
+ sc->sc_forward_delay = sc->sc_bridge_forward_delay;
+ sc->sc_topology_change_detected = 0;
+ sc->sc_topology_change = 0;
+ bstp_timer_stop(&sc->sc_tcn_timer);
+ bstp_timer_stop(&sc->sc_topology_change_timer);
+
+ /* If there is a timeout already set on this, cancel it and restart.
+ * The intent is to avoid setting duplicate timeouts. If the timeout
+ * is already set, untimeout would cancel it.
+ */
+#ifdef __ECOS
+ if (!bstp_init_done) {
+ untimeout(bstp_tick, sc);
+ timeout(bstp_tick, sc, hz);
+ bstp_init_done = 1;
+ }
+#else
+ if (!timeout_initialized(&sc->sc_bstptimeout))
+ timeout_set(&sc->sc_bstptimeout, bstp_tick, sc);
+ if (!timeout_pending(&sc->sc_bstptimeout))
+ timeout_add(&sc->sc_bstptimeout, hz);
+#endif // __ECOS
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (bif->bif_flags & IFBIF_STP) {
+ STPLOG (("%s:%s ..(en). \n", __FUNCTION__, bif->ifp->if_xname));
+ bstp_enable_port(sc, bif);
+ }
+ else {
+ STPLOG (("%s:%s ..(dis). \n", __FUNCTION__, bif->ifp->if_xname));
+ bstp_disable_port(sc, bif);
+ }
+ }
+
+ bstp_port_state_selection(sc);
+ bstp_config_bpdu_generation(sc);
+ bstp_timer_start(&sc->sc_hello_timer, 0);
+}
+
+void
+bstp_stop(sc)
+ struct bridge_softc *sc;
+{
+
+ struct bridge_iflist *bif;
+
+ STPLOG ((" %s\n", __FUNCTION__));
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED);
+ bstp_timer_stop(&bif->bif_hold_timer);
+ bstp_timer_stop(&bif->bif_message_age_timer);
+ bstp_timer_stop(&bif->bif_forward_delay_timer);
+ }
+
+#ifdef __ECOS
+ if (bstp_init_done) {
+ STPLOG (("##### untimeout ##### loc 1\n"));
+ untimeout(bstp_tick, sc);
+ bstp_init_done = 0;
+ }
+#else
+ if (timeout_initialized(&sc->sc_bstptimeout) &&
+ timeout_pending(&sc->sc_bstptimeout))
+ timeout_del(&sc->sc_bstptimeout);
+#endif //__ECOS
+
+ bstp_timer_stop(&sc->sc_topology_change_timer);
+ bstp_timer_stop(&sc->sc_tcn_timer);
+ bstp_timer_stop(&sc->sc_hello_timer);
+
+}
+
+void
+bstp_initialize_port(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ bstp_become_designated_port(sc, bif);
+ bstp_set_port_state(bif, BSTP_IFSTATE_BLOCKING);
+ bif->bif_topology_change_acknowledge = 0;
+ bif->bif_config_pending = 0;
+ bstp_enable_change_detection(bif);
+ bstp_timer_stop(&bif->bif_message_age_timer);
+ bstp_timer_stop(&bif->bif_forward_delay_timer);
+ bstp_timer_stop(&bif->bif_hold_timer);
+}
+
+void
+bstp_enable_port(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ bstp_initialize_port(sc, bif);
+ bstp_port_state_selection(sc);
+}
+
+void
+bstp_disable_port(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ int root;
+
+ root = bstp_root_bridge(sc);
+ bstp_become_designated_port(sc, bif);
+ bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED);
+ bif->bif_topology_change_acknowledge = 0;
+ bif->bif_config_pending = 0;
+ bstp_timer_stop(&bif->bif_message_age_timer);
+ bstp_timer_stop(&bif->bif_forward_delay_timer);
+ bstp_configuration_update(sc);
+ bridge_rtdelete(sc, bif->ifp, 1);
+
+ if (bstp_root_bridge(sc) && (!root)) {
+ sc->sc_max_age = sc->sc_bridge_max_age;
+ sc->sc_hello_time = sc->sc_bridge_hello_time;
+ sc->sc_forward_delay = sc->sc_bridge_forward_delay;
+ bstp_topology_change_detection(sc);
+ bstp_timer_stop(&sc->sc_tcn_timer);
+ bstp_config_bpdu_generation(sc);
+ bstp_timer_start(&sc->sc_hello_timer, 0);
+ }
+}
+
+void
+bstp_set_bridge_priority(sc, new_bridge_id)
+ struct bridge_softc *sc;
+ u_int64_t new_bridge_id;
+{
+ int root;
+ struct bridge_iflist *bif;
+
+ root = bstp_root_bridge(sc);
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bstp_designated_port(sc, bif))
+ bif->bif_designated_bridge = new_bridge_id;
+ }
+
+ sc->sc_bridge_id = new_bridge_id;
+
+ bstp_configuration_update(sc);
+ bstp_port_state_selection(sc);
+
+ if (bstp_root_bridge(sc) && (!root)) {
+ sc->sc_max_age = sc->sc_bridge_max_age;
+ sc->sc_hello_time = sc->sc_bridge_hello_time;
+ sc->sc_forward_delay = sc->sc_bridge_forward_delay;
+ bstp_topology_change_detection(sc);
+ bstp_timer_stop(&sc->sc_tcn_timer);
+ bstp_config_bpdu_generation(sc);
+ bstp_timer_start(&sc->sc_hello_timer, 0);
+ }
+}
+
+void
+bstp_set_port_priority(sc, bif, new_port_id)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+ u_int16_t new_port_id;
+{
+ if (bstp_designated_port(sc, bif))
+ bif->bif_designated_port = new_port_id;
+
+ bif->bif_port_id = new_port_id;
+
+ if ((sc->sc_bridge_id == bif->bif_designated_bridge) &&
+ (bif->bif_port_id < bif->bif_designated_port)) {
+ bstp_become_designated_port(sc, bif);
+ bstp_port_state_selection(sc);
+ }
+}
+
+void
+bstp_set_path_cost(sc, bif, path_cost)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+ u_int32_t path_cost;
+{
+ bif->bif_path_cost = path_cost;
+ bstp_configuration_update(sc);
+ bstp_port_state_selection(sc);
+}
+
+void
+bstp_enable_change_detection(bif)
+ struct bridge_iflist *bif;
+{
+ bif->bif_change_detection_enabled = 1;
+}
+
+void
+bstp_disable_change_detection(bif)
+ struct bridge_iflist *bif;
+{
+ bif->bif_change_detection_enabled = 0;
+}
+
+void
+bstp_ifupdstatus(sc, bif)
+ struct bridge_softc *sc;
+ struct bridge_iflist *bif;
+{
+ struct ifnet *ifp = bif->ifp;
+#ifndef __ECOS
+ struct ifmediareq ifmr;
+#endif
+ int err = EOPNOTSUPP;
+
+ if (ifp->if_flags & IFF_UP) {
+#ifndef __ECOS
+ ifmr.ifm_count = 0;
+ err = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr);
+#endif
+ if (err) {
+ if (bif->bif_state == BSTP_IFSTATE_DISABLED)
+ bstp_enable_port(sc, bif);
+ STPLOG (("<%s:%s> ", bif->ifp->if_xname, stp_port_state(bif->bif_state)));
+ return;
+ }
+#ifndef __ECOS
+ if (!(ifmr.ifm_status & IFM_AVALID)) {
+ if (bif->bif_state == BSTP_IFSTATE_DISABLED)
+ bstp_enable_port(sc, bif);
+ return;
+ }
+
+ if (ifmr.ifm_status & IFM_ACTIVE) {
+ if (bif->bif_state == BSTP_IFSTATE_DISABLED)
+ bstp_enable_port(sc, bif);
+ return;
+ }
+#endif
+
+ if (bif->bif_state != BSTP_IFSTATE_DISABLED) {
+ bstp_disable_port(sc, bif);
+ }
+
+ return;
+ }
+
+ if (bif->bif_state != BSTP_IFSTATE_DISABLED)
+ bstp_disable_port(sc, bif);
+}
+
+void
+bstp_tick(vsc)
+ void *vsc;
+{
+ struct bridge_softc *sc = vsc;
+ struct bridge_iflist *bif;
+ int s;
+
+ s = splnet();
+
+ STPLOG (("Port Status: "));
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ bstp_ifupdstatus(sc, bif);
+ }
+ STPLOG (("\n"));
+
+ if (bstp_timer_expired(&sc->sc_hello_timer, sc->sc_hello_time))
+ bstp_hello_timer_expiry(sc);
+
+ if (bstp_timer_expired(&sc->sc_tcn_timer, sc->sc_bridge_hello_time))
+ bstp_tcn_timer_expiry(sc);
+
+ if (bstp_timer_expired(&sc->sc_topology_change_timer,
+ sc->sc_topology_change_time))
+ bstp_topology_change_timer_expiry(sc);
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bstp_timer_expired(&bif->bif_message_age_timer,
+ sc->sc_max_age))
+ bstp_message_age_timer_expiry(sc, bif);
+ }
+
+ LIST_FOREACH(bif, &sc->sc_iflist, next) {
+ if (!(bif->bif_flags & IFBIF_STP))
+ continue;
+ if (bstp_timer_expired(&bif->bif_forward_delay_timer,
+ sc->sc_forward_delay))
+ bstp_forward_delay_timer_expiry(sc, bif);
+
+ if (bstp_timer_expired(&bif->bif_hold_timer,
+ sc->sc_hold_time))
+ bstp_hold_timer_expiry(sc, bif);
+ }
+
+#ifdef __ECOS
+ if (sc->sc_if.if_flags & IFF_RUNNING) {
+ timeout (bstp_tick, sc, hz);
+ }
+#else
+ if (sc->sc_if.if_flags & IFF_RUNNING)
+ timeout_add(&sc->sc_bstptimeout, hz);
+#endif //__ECOS
+
+ splx(s);
+}
+
+void
+bstp_timer_start(t, v)
+ struct bridge_timer *t;
+ u_int16_t v;
+{
+ t->value = v;
+ t->active = 1;
+}
+
+void
+bstp_timer_stop(t)
+ struct bridge_timer *t;
+{
+ t->value = 0;
+ t->active = 0;
+}
+
+int
+bstp_timer_expired(t, v)
+ struct bridge_timer *t;
+ u_int16_t v;
+{
+ if (!t->active)
+ return (0);
+ t->value += BSTP_TICK_VAL;
+ if (t->value >= v) {
+ bstp_timer_stop(t);
+ return (1);
+ }
+ return (0);
+
+}
+
+int
+bstp_ioctl(ifp, cmd, data)
+ struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+ struct ifbrparam *bp = (struct ifbrparam *)data;
+ struct bridge_softc *sc = (struct bridge_softc *)ifp;
+ int r = 0, err = 0;
+
+ switch (cmd) {
+ case SIOCBRDGGPRI:
+ bp->ifbrp_prio = sc->sc_bridge_priority;
+ break;
+ case SIOCBRDGGMA:
+ bp->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
+ break;
+ case SIOCBRDGGHT:
+ bp->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
+ break;
+ case SIOCBRDGGFD:
+ bp->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
+ break;
+ case SIOCBRDGSPRI:
+ sc->sc_bridge_priority = bp->ifbrp_prio;
+ r = 1;
+ break;
+ case SIOCBRDGSMA:
+ if (bp->ifbrp_maxage == 0) {
+ err = EINVAL;
+ break;
+ }
+ sc->sc_bridge_max_age = bp->ifbrp_maxage << 8;
+ r = 1;
+ break;
+ case SIOCBRDGSHT:
+ if (bp->ifbrp_hellotime == 0) {
+ err = EINVAL;
+ break;
+ }
+ sc->sc_bridge_hello_time = bp->ifbrp_hellotime << 8;
+ r = 1;
+ break;
+ case SIOCBRDGSFD:
+ if (bp->ifbrp_fwddelay == 0) {
+ err = EINVAL;
+ break;
+ }
+ sc->sc_bridge_forward_delay = bp->ifbrp_fwddelay << 8;
+ r = 1;
+ break;
+ case SIOCBRDGSIFCOST:
+ case SIOCBRDGSIFPRIO:
+ case SIOCBRDGSIFFLGS:
+ case SIOCBRDGADD:
+ case SIOCBRDGDEL:
+ r = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (r)
+ bstp_initialization(sc);
+
+ return (err);
+}
+
+#endif /* NBRIDGE */
+#endif /* CYGPKG_NET_BRIDGE_STP_CODE */
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/if.c b/ecos/packages/net/tcpip/current/src/sys/net/if.c
new file mode 100644
index 0000000..3a07cb7
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/if.c
@@ -0,0 +1,959 @@
+//==========================================================================
+//
+// sys/net/if.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if.c,v 1.25 1999/12/08 06:50:17 itojun Exp $ */
+/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if.c 8.3 (Berkeley) 1/4/94
+ */
+
+#ifdef __ECOS
+#include <pkgconf/net.h>
+#else
+#include "bpfilter.h"
+#include "bridge.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/proc.h>
+#endif
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/kernel.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/radix.h>
+
+#include <net/route.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/igmp.h>
+#ifdef MROUTING
+#include <netinet/ip_mroute.h>
+#endif
+#endif
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#endif
+
+#ifdef IPFILTER
+#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_fil.h>
+#include <netinet/ip_nat.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#if NBRIDGE > 0
+#include <net/if_bridge.h>
+#endif
+
+void if_attachsetup __P((struct ifnet *));
+int if_detach_rtdelete __P((struct radix_node *, void *));
+
+int ifqmaxlen = IFQ_MAXLEN;
+void if_slowtimo __P((void *arg));
+
+#ifdef INET6
+/*
+ * XXX: declare here to avoid to include many inet6 related files..
+ * should be more generalized?
+ */
+extern void nd6_setmtu __P((struct ifnet *));
+#endif
+
+/*
+ * Network interface utility routines.
+ *
+ * Routines with ifa_ifwith* names take sockaddr *'s as
+ * parameters.
+ */
+void
+ifinit()
+{
+ register struct ifnet *ifp;
+
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ if (ifp->if_snd.ifq_maxlen == 0)
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ if_slowtimo(NULL);
+}
+
+int if_index = 0;
+struct ifaddr **ifnet_addrs = NULL;
+struct ifnet **ifindex2ifnet = NULL;
+
+/*
+ * Attach an interface to the
+ * list of "active" interfaces.
+ */
+void
+if_attachsetup(ifp)
+ struct ifnet *ifp;
+{
+ unsigned int socksize, ifasize;
+ int namelen, masklen;
+ register struct sockaddr_dl *sdl;
+ register struct ifaddr *ifa;
+ static int if_indexlim = 8;
+
+ ifp->if_index = ++if_index;
+
+ /*
+ * We have some arrays that should be indexed by if_index.
+ * since if_index will grow dynamically, they should grow too.
+ * struct ifadd **ifnet_addrs
+ * struct ifnet **ifindex2ifnet
+ */
+ if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if_index >= if_indexlim) {
+ size_t n;
+ caddr_t q;
+
+ while (if_index >= if_indexlim)
+ if_indexlim <<= 1;
+
+ /* grow ifnet_addrs */
+ n = if_indexlim * sizeof(ifa);
+ q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
+ bzero(q, n);
+ if (ifnet_addrs) {
+ bcopy((caddr_t)ifnet_addrs, q, n/2);
+ free((caddr_t)ifnet_addrs, M_IFADDR);
+ }
+ ifnet_addrs = (struct ifaddr **)q;
+
+ /* grow ifindex2ifnet */
+ n = if_indexlim * sizeof(struct ifnet *);
+ q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
+ bzero(q, n);
+ if (ifindex2ifnet) {
+ bcopy((caddr_t)ifindex2ifnet, q, n/2);
+ free((caddr_t)ifindex2ifnet, M_IFADDR);
+ }
+ ifindex2ifnet = (struct ifnet **)q;
+ }
+
+ ifindex2ifnet[if_index] = ifp;
+
+ /*
+ * create a Link Level name for this device
+ */
+ namelen = strlen(ifp->if_xname);
+#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
+ masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
+ socksize = masklen + ifp->if_addrlen;
+#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
+ if (socksize < sizeof(*sdl))
+ socksize = sizeof(*sdl);
+ socksize = ROUNDUP(socksize);
+ ifasize = sizeof(*ifa) + 2 * socksize;
+ ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
+ bzero((caddr_t)ifa, ifasize);
+ sdl = (struct sockaddr_dl *)(ifa + 1);
+ sdl->sdl_len = socksize;
+ sdl->sdl_family = AF_LINK;
+ bcopy(ifp->if_xname, sdl->sdl_data, namelen);
+ sdl->sdl_nlen = namelen;
+ sdl->sdl_index = ifp->if_index;
+ sdl->sdl_type = ifp->if_type;
+ ifnet_addrs[if_index] = ifa;
+ ifa->ifa_ifp = ifp;
+ ifa->ifa_rtrequest = link_rtrequest;
+ TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
+ ifa->ifa_addr = (struct sockaddr *)sdl;
+ sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
+ ifa->ifa_netmask = (struct sockaddr *)sdl;
+ sdl->sdl_len = masklen;
+ while (namelen != 0)
+ sdl->sdl_data[--namelen] = 0xff;
+}
+
+void
+if_attachhead(ifp)
+ struct ifnet *ifp;
+{
+ if (if_index == 0)
+ TAILQ_INIT(&ifnet);
+ TAILQ_INIT(&ifp->if_addrlist);
+ TAILQ_INSERT_HEAD(&ifnet, ifp, if_list);
+ if_attachsetup(ifp);
+}
+
+void
+if_attach(ifp)
+ struct ifnet *ifp;
+{
+// Initialize queue - moved here to support "late" attaches
+ if (ifp->if_snd.ifq_maxlen == 0)
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+//
+ if (if_index == 0)
+ TAILQ_INIT(&ifnet);
+ TAILQ_INIT(&ifp->if_addrlist);
+ TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
+ if_attachsetup(ifp);
+}
+
+/*
+ * Delete a route if it has a specific interface for output.
+ * This function complies to the rn_walktree callback API.
+ */
+int
+if_detach_rtdelete(rn, vifp)
+ struct radix_node *rn;
+ void *vifp;
+{
+ struct ifnet *ifp = vifp;
+ struct rtentry *rt = (struct rtentry *)rn;
+
+ if (rt->rt_ifp == ifp)
+ rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
+ 0, NULL);
+
+ /*
+ * XXX There should be no need to check for rt_ifa belonging to this
+ * interface, because then rt_ifp is set, right?
+ */
+
+ return (0);
+}
+
+/*
+ * Detach an interface from everything in the kernel. Also deallocate
+ * private resources.
+ * XXX So far only the INET protocol family has been looked over
+ * wrt resource usage that needs to be decoupled.
+ */
+void
+if_detach(ifp)
+ struct ifnet *ifp;
+{
+ struct ifaddr *ifa;
+ int i, s = splimp();
+ struct radix_node_head *rnh;
+
+#if NBRIDGE > 0
+ /* Remove the interface from any bridge it is part of. */
+ if (ifp->if_bridge)
+ bridge_ifdetach(ifp);
+#endif
+
+#if NBPFILTER > 0
+ /* If there is a bpf device attached, detach from it. */
+ if (ifp->if_bpf)
+ bpfdetach(ifp);
+#endif
+
+ /*
+ * Find and remove all routes which is using this interface.
+ * XXX Factor out into a route.c function?
+ */
+ for (i = 1; i <= AF_MAX; i++) {
+ rnh = rt_tables[i];
+ if (rnh)
+ (*rnh->rnh_walktree)(rnh, if_detach_rtdelete, ifp);
+ }
+
+#ifdef INET
+ rti_delete(ifp);
+ myip_ifp = NULL;
+#ifdef MROUTING
+ vif_delete(ifp);
+#endif
+#endif
+ /*
+ * XXX transient ifp refs? inpcb.ip_moptions.imo_multicast_ifp?
+ * Other network stacks than INET?
+ */
+
+ /* Remove the interface from the list of all interfaces. */
+ TAILQ_REMOVE(&ifnet, ifp, if_list);
+
+#ifdef IPFILTER
+ /* XXX More ipf & ipnat cleanup needed. */
+ nat_ifdetach(ifp);
+#endif
+
+ /* Deallocate private resources. */
+ for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa;
+ ifa = TAILQ_FIRST(&ifp->if_addrlist)) {
+ TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
+#ifdef INET
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ TAILQ_REMOVE(&in_ifaddr, (struct in_ifaddr *)ifa,
+ ia_list);
+#endif
+ free(ifa, M_IFADDR);
+ }
+ splx(s);
+}
+
+/*
+ * Locate an interface based on a complete address.
+ */
+/*ARGSUSED*/
+struct ifaddr *
+ifa_ifwithaddr(addr)
+ register struct sockaddr *addr;
+{
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+
+#define equal(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != addr->sa_family)
+ continue;
+ if (ifa->ifa_dstaddr == NULL)
+ continue;
+ if (equal(addr, ifa->ifa_addr))
+ return (ifa);
+ if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
+ /* IP6 doesn't have broadcast */
+ ifa->ifa_broadaddr->sa_len != 0 &&
+ equal(ifa->ifa_broadaddr, addr))
+ return (ifa);
+ }
+ return (NULL);
+}
+/*
+ * Locate the point to point interface with a given destination address.
+ */
+/*ARGSUSED*/
+struct ifaddr *
+ifa_ifwithdstaddr(addr)
+ register struct sockaddr *addr;
+{
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != addr->sa_family ||
+ ifa->ifa_dstaddr == NULL)
+ continue;
+ if (equal(addr, ifa->ifa_dstaddr))
+ return (ifa);
+ }
+ return (NULL);
+}
+
+/*
+ * Find an interface on a specific network. If many, choice
+ * is most specific found.
+ */
+struct ifaddr *
+ifa_ifwithnet(addr)
+ struct sockaddr *addr;
+{
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+ struct ifaddr *ifa_maybe = 0;
+ u_int af = addr->sa_family;
+ char *addr_data = addr->sa_data, *cplim;
+
+ if (af == AF_LINK) {
+ register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
+ if (sdl->sdl_index && sdl->sdl_index <= if_index)
+ return (ifnet_addrs[sdl->sdl_index]);
+ }
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
+ register char *cp, *cp2, *cp3;
+
+ if (ifa->ifa_addr->sa_family != af ||
+ ifa->ifa_netmask == 0)
+ next: continue;
+ cp = addr_data;
+ cp2 = ifa->ifa_addr->sa_data;
+ cp3 = ifa->ifa_netmask->sa_data;
+ cplim = (char *)ifa->ifa_netmask +
+ ifa->ifa_netmask->sa_len;
+ while (cp3 < cplim)
+ if ((*cp++ ^ *cp2++) & *cp3++)
+ /* want to continue for() loop */
+ goto next;
+ if (ifa_maybe == 0 ||
+ rn_refines((caddr_t)ifa->ifa_netmask,
+ (caddr_t)ifa_maybe->ifa_netmask))
+ ifa_maybe = ifa;
+ }
+ return (ifa_maybe);
+}
+
+/*
+ * Find an interface using a specific address family
+ */
+struct ifaddr *
+ifa_ifwithaf(af)
+ register int af;
+{
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next)
+ if (ifa->ifa_addr->sa_family == af)
+ return (ifa);
+ return (NULL);
+}
+
+/*
+ * Find an interface address specific to an interface best matching
+ * a given address.
+ */
+struct ifaddr *
+ifaof_ifpforaddr(addr, ifp)
+ struct sockaddr *addr;
+ register struct ifnet *ifp;
+{
+ register struct ifaddr *ifa;
+ register char *cp, *cp2, *cp3;
+ register char *cplim;
+ struct ifaddr *ifa_maybe = 0;
+ u_int af = addr->sa_family;
+
+ if (af >= AF_MAX)
+ return (NULL);
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != af)
+ continue;
+ ifa_maybe = ifa;
+ if (ifa->ifa_netmask == 0) {
+ if (equal(addr, ifa->ifa_addr) ||
+ (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
+ return (ifa);
+ continue;
+ }
+ cp = addr->sa_data;
+ cp2 = ifa->ifa_addr->sa_data;
+ cp3 = ifa->ifa_netmask->sa_data;
+ cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
+ for (; cp3 < cplim; cp3++)
+ if ((*cp++ ^ *cp2++) & *cp3)
+ break;
+ if (cp3 == cplim)
+ return (ifa);
+ }
+ return (ifa_maybe);
+}
+
+/*
+ * Default action when installing a route with a Link Level gateway.
+ * Lookup an appropriate real ifa to point to.
+ * This should be moved to /sys/net/link.c eventually.
+ */
+void
+link_rtrequest(cmd, rt, sa)
+ int cmd;
+ register struct rtentry *rt;
+ struct sockaddr *sa;
+{
+ register struct ifaddr *ifa;
+ struct sockaddr *dst;
+ struct ifnet *ifp;
+
+ if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
+ ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
+ return;
+ if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
+ IFAFREE(rt->rt_ifa);
+ rt->rt_ifa = ifa;
+ ifa->ifa_refcnt++;
+ if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
+ ifa->ifa_rtrequest(cmd, rt, sa);
+ }
+}
+
+/*
+ * Mark an interface down and notify protocols of
+ * the transition.
+ * NOTE: must be called at splsoftnet or equivalent.
+ */
+void
+if_down(ifp)
+ register struct ifnet *ifp;
+{
+ register struct ifaddr *ifa;
+
+ ifp->if_flags &= ~IFF_UP;
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next)
+ pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
+ if_qflush(&ifp->if_snd);
+ rt_ifmsg(ifp);
+}
+
+/*
+ * Mark an interface up and notify protocols of
+ * the transition.
+ * NOTE: must be called at splsoftnet or equivalent.
+ */
+void
+if_up(ifp)
+ register struct ifnet *ifp;
+{
+#ifdef notyet
+ register struct ifaddr *ifa;
+#endif
+
+ ifp->if_flags |= IFF_UP;
+#ifdef notyet
+ /* this has no effect on IP, and will kill all ISO connections XXX */
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
+ ifa = ifa->ifa_list.tqe_next)
+ pfctlinput(PRC_IFUP, ifa->ifa_addr);
+#endif
+ rt_ifmsg(ifp);
+#ifdef INET6
+ in6_if_up(ifp);
+#endif
+}
+
+/*
+ * Flush an interface queue.
+ */
+void
+if_qflush(ifq)
+ register struct ifqueue *ifq;
+{
+ register struct mbuf *m, *n;
+
+ n = ifq->ifq_head;
+ while ((m = n) != NULL) {
+ n = m->m_act;
+ m_freem(m);
+ }
+ ifq->ifq_head = 0;
+ ifq->ifq_tail = 0;
+ ifq->ifq_len = 0;
+}
+
+/*
+ * Handle interface watchdog timer routines. Called
+ * from softclock, we decrement timers (if set) and
+ * call the appropriate interface routine on expiration.
+ */
+void
+if_slowtimo(arg)
+ void *arg;
+{
+ register struct ifnet *ifp;
+ int s = splimp();
+
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
+ if (ifp->if_timer == 0 || --ifp->if_timer)
+ continue;
+ if (ifp->if_watchdog)
+ (*ifp->if_watchdog)(ifp);
+ }
+ splx(s);
+ timeout(if_slowtimo, NULL, hz / IFNET_SLOWHZ);
+}
+
+/*
+ * Map interface name to
+ * interface structure pointer.
+ */
+struct ifnet *
+ifunit(name)
+ register char *name;
+{
+ register struct ifnet *ifp;
+
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ if (strcmp(ifp->if_xname, name) == 0)
+ return (ifp);
+
+ return (NULL);
+}
+
+
+/*
+ * Map interface name in a sockaddr_dl to
+ * interface structure pointer.
+ */
+struct ifnet *
+if_withname(sa)
+ struct sockaddr *sa;
+{
+ char ifname[IFNAMSIZ+1];
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
+
+ if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
+ (sdl->sdl_nlen > IFNAMSIZ) )
+ return NULL;
+
+ /*
+ * ifunit wants a null-terminated name. It may not be null-terminated
+ * in the sockaddr. We don't want to change the caller's sockaddr,
+ * and there might not be room to put the trailing null anyway, so we
+ * make a local copy that we know we can null terminate safely.
+ */
+
+ bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
+ ifname[sdl->sdl_nlen] = '\0';
+ return ifunit(ifname);
+}
+
+
+/*
+ * Interface ioctls.
+ */
+int
+ifioctl(so, cmd, data, p)
+ struct socket *so;
+ u_long cmd;
+ caddr_t data;
+ struct proc *p;
+{
+ register struct ifnet *ifp;
+ register struct ifreq *ifr;
+ int error = 0;
+ short oif_flags;
+
+ switch (cmd) {
+
+ case SIOCGIFCONF:
+ case OSIOCGIFCONF:
+ return (ifconf(cmd, data));
+ }
+ ifr = (struct ifreq *)data;
+ ifp = ifunit(ifr->ifr_name);
+ if (ifp == 0)
+ return (ENXIO);
+ oif_flags = ifp->if_flags;
+ switch (cmd) {
+
+ case SIOCGIFFLAGS:
+ ifr->ifr_flags = ifp->if_flags;
+ break;
+
+ case SIOCGIFMETRIC:
+ ifr->ifr_metric = ifp->if_metric;
+ break;
+
+ case SIOCGIFDATA:
+ error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
+ sizeof(ifp->if_data));
+ break;
+
+ case SIOCSIFFLAGS:
+#ifndef __ECOS
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+ return (error);
+#endif
+ if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
+ int s = splimp();
+ if_down(ifp);
+ splx(s);
+ }
+ if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
+ int s = splimp();
+ if_up(ifp);
+ splx(s);
+ }
+ ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
+ (ifr->ifr_flags &~ IFF_CANTCHANGE);
+ if (ifp->if_ioctl)
+ (void) (*ifp->if_ioctl)(ifp, cmd, data);
+ break;
+
+ case SIOCSIFMETRIC:
+#ifndef __ECOS
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+ return (error);
+#endif
+ ifp->if_metric = ifr->ifr_metric;
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ case SIOCSIFMEDIA:
+#ifndef __ECOS
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+ return (error);
+#endif
+ /* FALLTHROUGH */
+#ifdef SIOCGIFSTATS
+ case SIOCGIFSTATS:
+#ifdef SIOCGIFSTATSUD
+ case SIOCGIFSTATSUD:
+#endif
+#endif // SIOCGIFSTATS
+ case SIOCGIFMEDIA:
+ if (ifp->if_ioctl == 0)
+ return (EOPNOTSUPP);
+ error = (*ifp->if_ioctl)(ifp, cmd, data);
+ break;
+
+ default:
+ if (so->so_proto == 0)
+ return (EOPNOTSUPP);
+#if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
+ error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
+ (struct mbuf *) cmd, (struct mbuf *) data,
+ (struct mbuf *) ifp));
+#else
+ {
+ u_long ocmd = cmd;
+
+ switch (cmd) {
+
+ case SIOCSIFADDR:
+ case SIOCSIFDSTADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCSIFNETMASK:
+#if BYTE_ORDER != BIG_ENDIAN
+ if (ifr->ifr_addr.sa_family == 0 &&
+ ifr->ifr_addr.sa_len < 16) {
+ ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
+ ifr->ifr_addr.sa_len = 16;
+ }
+#else
+ if (ifr->ifr_addr.sa_len == 0)
+ ifr->ifr_addr.sa_len = 16;
+#endif
+ break;
+
+ case OSIOCGIFADDR:
+ cmd = SIOCGIFADDR;
+ break;
+
+ case OSIOCGIFDSTADDR:
+ cmd = SIOCGIFDSTADDR;
+ break;
+
+ case OSIOCGIFBRDADDR:
+ cmd = SIOCGIFBRDADDR;
+ break;
+
+ case OSIOCGIFNETMASK:
+ cmd = SIOCGIFNETMASK;
+ }
+ error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
+ (struct mbuf *) cmd,
+ (struct mbuf *) data,
+ (struct mbuf *) ifp));
+ switch (ocmd) {
+
+ case OSIOCGIFADDR:
+ case OSIOCGIFDSTADDR:
+ case OSIOCGIFBRDADDR:
+ case OSIOCGIFNETMASK:
+ *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
+ }
+
+ }
+#endif
+ break;
+ }
+
+ if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
+#ifdef INET6
+ if ((ifp->if_flags & IFF_UP) != 0) {
+ int s = splimp();
+ in6_if_up(ifp);
+ splx(s);
+ }
+#endif
+ }
+ return (error);
+}
+
+/*
+ * Return interface configuration
+ * of system. List may be used
+ * in later ioctl's (above) to get
+ * other information.
+ */
+/*ARGSUSED*/
+int
+ifconf(cmd, data)
+ u_long cmd;
+ caddr_t data;
+{
+ register struct ifconf *ifc = (struct ifconf *)data;
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+ struct ifreq ifr, *ifrp;
+ int space = ifc->ifc_len, error = 0;
+
+ /* If ifc->ifc_len is 0, fill it in with the needed size and return. */
+ if (space == 0) {
+ for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) {
+ register struct sockaddr *sa;
+
+ if ((ifa = ifp->if_addrlist.tqh_first) == 0)
+ space += sizeof (ifr);
+ else
+ for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
+ sa = ifa->ifa_addr;
+#if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
+ if (cmd != OSIOCGIFCONF)
+#endif
+ if (sa->sa_len > sizeof(*sa))
+ space += sa->sa_len -
+ sizeof (*sa);
+ space += sizeof (ifr);
+ }
+ }
+ ifc->ifc_len = space;
+ return(0);
+ }
+
+ ifrp = ifc->ifc_req;
+ for (ifp = ifnet.tqh_first; space >= sizeof (ifr) && ifp != 0;
+ ifp = ifp->if_list.tqe_next) {
+ bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
+ if ((ifa = ifp->if_addrlist.tqh_first) == 0) {
+ bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof(ifr));
+ if (error)
+ break;
+ space -= sizeof (ifr), ifrp++;
+ } else
+ for (; space >= sizeof (ifr) && ifa != 0;
+ ifa = ifa->ifa_list.tqe_next) {
+ register struct sockaddr *sa = ifa->ifa_addr;
+#if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
+ if (cmd == OSIOCGIFCONF) {
+ struct osockaddr *osa =
+ (struct osockaddr *)&ifr.ifr_addr;
+ ifr.ifr_addr = *sa;
+ osa->sa_family = sa->sa_family;
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr));
+ ifrp++;
+ } else
+#endif
+ if (sa->sa_len <= sizeof(*sa)) {
+ ifr.ifr_addr = *sa;
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr));
+ ifrp++;
+ } else {
+ space -= sa->sa_len - sizeof(*sa);
+ if (space < sizeof (ifr))
+ break;
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr.ifr_name));
+ if (error == 0)
+ error = copyout((caddr_t)sa,
+ (caddr_t)&ifrp->ifr_addr,
+ sa->sa_len);
+ ifrp = (struct ifreq *)(sa->sa_len +
+ (caddr_t)&ifrp->ifr_addr);
+ }
+ if (error)
+ break;
+ space -= sizeof (ifr);
+ }
+ }
+ ifc->ifc_len -= space;
+ return (error);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/if_bridge.c b/ecos/packages/net/tcpip/current/src/sys/net/if_bridge.c
new file mode 100644
index 0000000..04093c6
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/if_bridge.c
@@ -0,0 +1,2349 @@
+//==========================================================================
+//
+// sys/net/if_bridge.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jason L. Wright (jason@thought.net)
+// Contributors: andrew.lunn@ascom.ch (Andrew Lunn), hmt, manu.sharma@ascom.com
+// Date: 2000-07-18
+// Purpose: Ethernet bridge
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+/* $OpenBSD: if_bridge.c,v 1.33 2000/06/20 05:50:16 jason Exp $ */
+
+/*
+ * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifdef __ECOS
+#include <pkgconf/net.h>
+#else
+#include "bridge.h"
+#include "bpfilter.h"
+#include "enc.h"
+#endif
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/proc.h>
+#include <sys/systm.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#ifndef __ECOS
+#include <sys/device.h>
+#endif
+#include <sys/kernel.h>
+#include <machine/cpu.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_llc.h>
+#include <net/route.h>
+#include <net/netisr.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_ipsp.h>
+
+#ifndef __ECOS
+#include <net/if_enc.h>
+#endif
+#ifdef IPFILTER
+#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_fil.h>
+#endif
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <net/if_bridge.h>
+
+#ifdef __ECOS
+#include <stdio.h> /* for sprintf */
+#endif
+
+#ifndef BRIDGE_RTABLE_SIZE
+#define BRIDGE_RTABLE_SIZE 1024
+#endif
+#define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1)
+
+/*
+ * Maximum number of addresses to cache
+ */
+#ifndef BRIDGE_RTABLE_MAX
+#define BRIDGE_RTABLE_MAX 100
+#endif
+
+/*
+ * Timeout (in seconds) for entries learned dynamically
+ */
+#ifndef BRIDGE_RTABLE_TIMEOUT
+#define BRIDGE_RTABLE_TIMEOUT 300
+#endif
+
+/* Spanning tree defaults */
+#define BSTP_DEFAULT_MAX_AGE (20 * 256)
+#define BSTP_DEFAULT_HELLO_TIME (2 * 256)
+#define BSTP_DEFAULT_FORWARD_DELAY (15 * 256)
+#define BSTP_DEFAULT_HOLD_TIME (1 * 256)
+#define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000
+#define BSTP_DEFAULT_PORT_PRIORITY 0x80
+#define BSTP_DEFAULT_PATH_COST 55
+
+extern int ifqmaxlen;
+
+/* SNAP LLC header */
+struct snap {
+ u_int8_t dsap;
+ u_int8_t ssap;
+ u_int8_t control;
+ u_int8_t org[3];
+ u_int16_t type;
+};
+
+struct bridge_softc bridgectl[CYGNUM_NET_BRIDGES];
+
+void bridgeattach __P((int));
+int bridge_ioctl __P((struct ifnet *, u_long, caddr_t));
+void bridge_start __P((struct ifnet *));
+void bridgeintr_frame __P((struct bridge_softc *, struct mbuf *));
+void bridge_broadcast __P((struct bridge_softc *, struct ifnet *,
+ struct ether_header *, struct mbuf *)) __attribute ((weak));
+void bridge_stop __P((struct bridge_softc *));
+void bridge_init __P((struct bridge_softc *));
+int bridge_bifconf __P((struct bridge_softc *, struct ifbifconf *));
+
+int bridge_rtfind __P((struct bridge_softc *, struct ifbaconf *));
+void bridge_rtage __P((void *));
+void bridge_rttrim __P((struct bridge_softc *));
+int bridge_rtdaddr __P((struct bridge_softc *, struct ether_addr *));
+int bridge_rtflush __P((struct bridge_softc *, int));
+struct ifnet * bridge_rtupdate __P((struct bridge_softc *,
+ struct ether_addr *, struct ifnet *ifp, int, u_int8_t));
+struct ifnet * bridge_rtlookup __P((struct bridge_softc *,
+ struct ether_addr *));
+u_int32_t bridge_hash __P((struct ether_addr *));
+int bridge_blocknonip __P((struct ether_header *, struct mbuf *));
+int bridge_addrule __P((struct bridge_iflist *,
+ struct ifbrlreq *, int out));
+int bridge_flushrule __P((struct bridge_iflist *));
+int bridge_brlconf __P((struct bridge_softc *, struct ifbrlconf *));
+u_int8_t bridge_filterrule __P((struct brl_node *, struct ether_header *));
+int bridge_ifenqueue __P((struct bridge_softc *, struct ifnet *, struct mbuf *));
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+void bridge_span (struct bridge_softc *, struct ether_header *, struct mbuf *);
+#endif
+
+#define ETHERADDR_IS_IP_MCAST(a) \
+ /* struct etheraddr *a; */ \
+ ((a)->ether_addr_octet[0] == 0x01 && \
+ (a)->ether_addr_octet[1] == 0x00 && \
+ (a)->ether_addr_octet[2] == 0x5e)
+
+
+#if defined(INET) && (defined(IPFILTER) || defined(IPFILTER_LKM))
+/*
+ * Filter hooks
+ */
+struct mbuf *bridge_filter __P((struct bridge_softc *, struct ifnet *,
+ struct ether_header *, struct mbuf *m));
+#endif
+
+void
+bridgeattach(unused)
+ int unused;
+{
+ int i;
+ struct ifnet *ifp;
+
+ for (i = 0; i < CYGNUM_NET_BRIDGES; i++) {
+ bridgectl[i].sc_brtmax = BRIDGE_RTABLE_MAX;
+ bridgectl[i].sc_brttimeout = (BRIDGE_RTABLE_TIMEOUT * hz) / 2;
+ bridgectl[i].sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
+ bridgectl[i].sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
+ bridgectl[i].sc_bridge_forward_delay= BSTP_DEFAULT_FORWARD_DELAY;
+ bridgectl[i].sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
+ bridgectl[i].sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
+ LIST_INIT(&bridgectl[i].sc_iflist);
+ LIST_INIT(&bridgectl[i].sc_spanlist);
+ ifp = &bridgectl[i].sc_if;
+ sprintf(ifp->if_xname, "bridge%d", i);
+ ifp->if_softc = &bridgectl[i];
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_ioctl = bridge_ioctl;
+ ifp->if_output = bridge_output;
+ ifp->if_start = bridge_start;
+ ifp->if_type = IFT_PROPVIRTUAL;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ ifp->if_hdrlen = sizeof(struct ether_header);
+ if_attach(ifp);
+#if NBPFILTER > 0
+ bpfattach(&bridgectl[i].sc_if.if_bpf, ifp,
+ DLT_EN10MB, sizeof(struct ether_header));
+#endif
+ }
+}
+
+int
+bridge_ioctl(ifp, cmd, data)
+ struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+#ifndef __ECOS
+ struct proc *prc = curproc; /* XXX */
+#endif
+ struct ifnet *ifs;
+ struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc;
+ struct ifbreq *req = (struct ifbreq *)data;
+ struct ifbaconf *baconf = (struct ifbaconf *)data;
+ struct ifbareq *bareq = (struct ifbareq *)data;
+ struct ifbcachereq *bcachereq = (struct ifbcachereq *)data;
+ struct ifbifconf *bifconf = (struct ifbifconf *)data;
+ struct ifbcachetoreq *bcacheto = (struct ifbcachetoreq *)data;
+ struct ifbrlreq *brlreq = (struct ifbrlreq *)data;
+ struct ifbrlconf *brlconf = (struct ifbrlconf *)data;
+ struct ifreq ifreq;
+ int error = 0, s;
+ struct bridge_iflist *p;
+
+ s = splimp();
+ switch (cmd) {
+ case SIOCBRDGADD:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) { /* no such interface */
+ error = ENOENT;
+ break;
+ }
+ if (ifs->if_bridge == (caddr_t)sc) {
+ error = EEXIST;
+ break;
+ }
+ if (ifs->if_bridge != NULL) {
+ error = EBUSY;
+ break;
+ }
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ /* If it's in the span list, it can't be a member. */
+ LIST_FOREACH(p, &sc->sc_spanlist, next) {
+ if (p->ifp == ifs)
+ break;
+ }
+ if (p != LIST_END(&sc->sc_spanlist)) {
+ error = EBUSY;
+ break;
+ }
+#endif
+
+
+ if (ifs->if_type == IFT_ETHER) {
+ if ((ifs->if_flags & IFF_UP) == 0) {
+ /*
+ * Bring interface up long enough to set
+ * promiscuous flag, then shut it down again.
+ */
+ strncpy(ifreq.ifr_name, req->ifbr_ifsname,
+ sizeof(ifreq.ifr_name) - 1);
+ ifreq.ifr_name[sizeof(ifreq.ifr_name) - 1] = '\0';
+ ifs->if_flags |= IFF_UP;
+ ifreq.ifr_flags = ifs->if_flags;
+ error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS,
+ (caddr_t)&ifreq);
+ if (error != 0)
+ break;
+
+ error = ifpromisc(ifs, 1);
+ if (error != 0)
+ break;
+
+ strncpy(ifreq.ifr_name, req->ifbr_ifsname,
+ sizeof(ifreq.ifr_name) - 1);
+ ifreq.ifr_name[sizeof(ifreq.ifr_name) - 1] = '\0';
+ ifs->if_flags &= ~IFF_UP;
+ ifreq.ifr_flags = ifs->if_flags;
+ error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS,
+ (caddr_t)&ifreq);
+ if (error != 0) {
+ ifpromisc(ifs, 0);
+ break;
+ }
+ } else {
+ error = ifpromisc(ifs, 1);
+ if (error != 0)
+ break;
+ }
+ }
+#ifndef __ECOS
+#if NENC > 0
+ else if (ifs->if_type == IFT_ENC) {
+ /* Can't bind enc0 to a bridge */
+ if (ifs->if_softc == &encif[0]) {
+ error = EINVAL;
+ break;
+ }
+ }
+#endif /* NENC */
+#endif
+ else {
+ error = EINVAL;
+ break;
+ }
+
+ p = (struct bridge_iflist *) malloc(
+ sizeof(struct bridge_iflist), M_DEVBUF, M_NOWAIT);
+ if (p == NULL && ifs->if_type == IFT_ETHER) {
+ error = ENOMEM;
+ ifpromisc(ifs, 0);
+ break;
+ }
+
+ p->ifp = ifs;
+ p->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
+ p->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
+ p->bif_path_cost = BSTP_DEFAULT_PATH_COST;
+ SIMPLEQ_INIT(&p->bif_brlin);
+ SIMPLEQ_INIT(&p->bif_brlout);
+ LIST_INSERT_HEAD(&sc->sc_iflist, p, next);
+ ifs->if_bridge = (caddr_t)sc;
+ break;
+ case SIOCBRDGDEL:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ p = LIST_FIRST(&sc->sc_iflist);
+ while (p != NULL) {
+ if (strncmp(p->ifp->if_xname, req->ifbr_ifsname,
+ sizeof(p->ifp->if_xname)) == 0) {
+ p->ifp->if_bridge = NULL;
+
+ error = ifpromisc(p->ifp, 0);
+
+ LIST_REMOVE(p, next);
+ bridge_rtdelete(sc, p->ifp, 0);
+ bridge_flushrule(p);
+ free(p, M_DEVBUF);
+ break;
+ }
+ p = LIST_NEXT(p, next);
+ }
+ if (p == NULL) {
+ error = ENOENT;
+ break;
+ }
+ break;
+ case SIOCBRDGIFS:
+ error = bridge_bifconf(sc, bifconf);
+ break;
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ case SIOCBRDGADDS:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) { /* no such interface */
+ error = ENOENT;
+ break;
+ }
+ if (ifs->if_bridge == (caddr_t)sc) {
+ error = EEXIST;
+ break;
+ }
+ if (ifs->if_bridge != NULL) {
+ error = EBUSY;
+ break;
+ }
+ LIST_FOREACH(p, &sc->sc_spanlist, next) {
+ if (p->ifp == ifs)
+ break;
+ }
+ if (p != LIST_END(&sc->sc_spanlist)) {
+ error = EBUSY;
+ break;
+ }
+ p = (struct bridge_iflist *)malloc(
+ sizeof(struct bridge_iflist), M_DEVBUF, M_NOWAIT);
+ if (p == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bzero(p, sizeof(struct bridge_iflist));
+ p->ifp = ifs;
+ SIMPLEQ_INIT(&p->bif_brlin);
+ SIMPLEQ_INIT(&p->bif_brlout);
+ LIST_INSERT_HEAD(&sc->sc_spanlist, p, next);
+ break;
+ case SIOCBRDGDELS:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+
+ LIST_FOREACH(p, &sc->sc_spanlist, next) {
+ if (strncmp(p->ifp->if_xname, req->ifbr_ifsname,
+ sizeof(p->ifp->if_xname)) == 0) {
+ LIST_REMOVE(p, next);
+ free(p, M_DEVBUF);
+ break;
+ }
+ }
+ if (p == LIST_END(&sc->sc_spanlist)) {
+ error = ENOENT;
+ break;
+ }
+ break;
+#endif
+
+ case SIOCBRDGGIFFLGS:
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ if ((caddr_t)sc != ifs->if_bridge) {
+ error = ESRCH;
+ break;
+ }
+ p = LIST_FIRST(&sc->sc_iflist);
+ while (p != NULL && p->ifp != ifs) {
+ p = LIST_NEXT(p, next);
+ }
+ if (p == NULL) {
+ error = ESRCH;
+ break;
+ }
+ req->ifbr_ifsflags = p->bif_flags;
+ req->ifbr_state = p->bif_state;
+ req->ifbr_priority = p->bif_priority;
+ req->ifbr_path_cost = p->bif_path_cost;
+ req->ifbr_portno = p->ifp->if_index & 0xff;
+ break;
+ case SIOCBRDGSIFFLGS:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ if ((caddr_t)sc != ifs->if_bridge) {
+ error = ESRCH;
+ break;
+ }
+ p = LIST_FIRST(&sc->sc_iflist);
+ while (p != NULL && p->ifp != ifs) {
+ p = LIST_NEXT(p, next);
+ }
+ if (p == NULL) {
+ error = ESRCH;
+ break;
+ }
+ p->bif_flags = req->ifbr_ifsflags;
+ break;
+ case SIOCBRDGSIFPRIO:
+ case SIOCBRDGSIFCOST:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ if ((caddr_t)sc != ifs->if_bridge) {
+ error = ESRCH;
+ break;
+ }
+ LIST_FOREACH(p, &sc->sc_iflist, next) {
+ if (p->ifp == ifs)
+ break;
+ }
+ if (p == LIST_END(&sc->sc_iflist)) {
+ error = ESRCH;
+ break;
+ }
+ if (cmd == SIOCBRDGSIFPRIO)
+ p->bif_priority = req->ifbr_priority;
+ else {
+ if (req->ifbr_path_cost < 1)
+ error = EINVAL;
+ else
+ p->bif_path_cost = req->ifbr_path_cost;
+ }
+ break;
+ case SIOCBRDGRTS:
+ error = bridge_rtfind(sc, baconf);
+ break;
+ case SIOCBRDGFLUSH:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ error = bridge_rtflush(sc, req->ifbr_ifsflags);
+ break;
+ case SIOCBRDGSADDR:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ ifs = ifunit(bareq->ifba_ifsname);
+ if (ifs == NULL) { /* no such interface */
+ error = ENOENT;
+ break;
+ }
+
+ if (ifs->if_bridge == NULL ||
+ ifs->if_bridge != (caddr_t)sc) {
+ error = ESRCH;
+ break;
+ }
+
+ ifs = bridge_rtupdate(sc, &bareq->ifba_dst, ifs, 1,
+ bareq->ifba_flags);
+ if (ifs == NULL)
+ error = ENOMEM;
+ break;
+ case SIOCBRDGDADDR:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ error = bridge_rtdaddr(sc, &bareq->ifba_dst);
+ break;
+ case SIOCBRDGGCACHE:
+ bcachereq->ifbc_size = sc->sc_brtmax;
+ break;
+ case SIOCBRDGSCACHE:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ sc->sc_brtmax = bcachereq->ifbc_size;
+ bridge_rttrim(sc);
+ break;
+ case SIOCBRDGSTO:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ sc->sc_brttimeout = (bcacheto->ifbct_time * hz) / 2;
+ untimeout(bridge_rtage, sc);
+ if (bcacheto->ifbct_time != 0)
+ timeout(bridge_rtage, sc, sc->sc_brttimeout);
+ break;
+ case SIOCBRDGGTO:
+ bcacheto->ifbct_time = (2 * sc->sc_brttimeout) / hz;
+ break;
+ case SIOCSIFFLAGS:
+ if ((ifp->if_flags & IFF_UP) == IFF_UP)
+ bridge_init(sc);
+
+ if ((ifp->if_flags & IFF_UP) == 0)
+ bridge_stop(sc);
+
+ break;
+ case SIOCBRDGARL:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ ifs = ifunit(brlreq->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ if (ifs->if_bridge == NULL ||
+ ifs->if_bridge != (caddr_t)sc) {
+ error = ESRCH;
+ break;
+ }
+ p = LIST_FIRST(&sc->sc_iflist);
+ while (p != NULL && p->ifp != ifs) {
+ p = LIST_NEXT(p, next);
+ }
+ if (p == NULL) {
+ error = ESRCH;
+ break;
+ }
+ if ((brlreq->ifbr_action != BRL_ACTION_BLOCK &&
+ brlreq->ifbr_action != BRL_ACTION_PASS) ||
+ (brlreq->ifbr_flags & (BRL_FLAG_IN|BRL_FLAG_OUT)) == 0) {
+ error = EINVAL;
+ break;
+ }
+ if (brlreq->ifbr_flags & BRL_FLAG_IN) {
+ error = bridge_addrule(p, brlreq, 0);
+ if (error)
+ break;
+ }
+ if (brlreq->ifbr_flags & BRL_FLAG_OUT) {
+ error = bridge_addrule(p, brlreq, 1);
+ if (error)
+ break;
+ }
+ break;
+ case SIOCBRDGFRL:
+#ifndef __ECOS
+ if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0)
+ break;
+#endif
+ ifs = ifunit(brlreq->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ if (ifs->if_bridge == NULL ||
+ ifs->if_bridge != (caddr_t)sc) {
+ error = ESRCH;
+ break;
+ }
+ p = LIST_FIRST(&sc->sc_iflist);
+ while (p != NULL && p->ifp != ifs) {
+ p = LIST_NEXT(p, next);
+ }
+ if (p == NULL) {
+ error = ESRCH;
+ break;
+ }
+ error = bridge_flushrule(p);
+ break;
+ case SIOCBRDGGRL:
+ error = bridge_brlconf(sc, brlconf);
+ break;
+ case SIOCBRDGGPRI:
+ case SIOCBRDGGMA:
+ case SIOCBRDGGHT:
+ case SIOCBRDGGFD:
+ break;
+ case SIOCBRDGSPRI:
+ case SIOCBRDGSFD:
+ case SIOCBRDGSMA:
+ case SIOCBRDGSHT:
+#ifndef __ECOS
+ error = suser(prc->p_ucred, &prc->p_acflag);
+#endif
+ break;
+ default:
+ error = EINVAL;
+ }
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ if (!error)
+ error = bstp_ioctl(ifp, cmd, data);
+#endif
+ splx(s);
+ return (error);
+}
+
+/* Detach an interface from a bridge. */
+void
+bridge_ifdetach(ifp)
+ struct ifnet *ifp;
+{
+ struct bridge_softc *bsc = (struct bridge_softc *)ifp->if_bridge;
+ struct bridge_iflist *bif;
+
+ for (bif = LIST_FIRST(&bsc->sc_iflist); bif;
+ bif = LIST_NEXT(bif, next))
+ if (bif->ifp == ifp) {
+ LIST_REMOVE(bif, next);
+ bridge_rtdelete(bsc, ifp, 0);
+ bridge_flushrule(bif);
+ free(bif, M_DEVBUF);
+ ifp->if_bridge = NULL;
+ break;
+ }
+}
+
+int
+bridge_bifconf(sc, bifc)
+ struct bridge_softc *sc;
+ struct ifbifconf *bifc;
+{
+ struct bridge_iflist *p;
+ u_int32_t total = 0, i;
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ u_int32_t j;
+#endif
+ int error = 0;
+ struct ifbreq breq;
+
+ p = LIST_FIRST(&sc->sc_iflist);
+ while (p != NULL) {
+ total++;
+ p = LIST_NEXT(p, next);
+ }
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ p = LIST_FIRST(&sc->sc_spanlist);
+ while (p != NULL) {
+ total++;
+ p = LIST_NEXT(p, next);
+ }
+#endif
+
+ if (bifc->ifbic_len == 0) {
+ i = total;
+ goto done;
+ }
+
+ p = LIST_FIRST(&sc->sc_iflist);
+ i = 0;
+ while (p != NULL && bifc->ifbic_len > i * sizeof(breq)) {
+ strncpy(breq.ifbr_name, sc->sc_if.if_xname,
+ sizeof(breq.ifbr_name)-1);
+ breq.ifbr_name[sizeof(breq.ifbr_name) - 1] = '\0';
+ strncpy(breq.ifbr_ifsname, p->ifp->if_xname,
+ sizeof(breq.ifbr_ifsname)-1);
+ breq.ifbr_ifsname[sizeof(breq.ifbr_ifsname) - 1] = '\0';
+ breq.ifbr_ifsflags = p->bif_flags;
+ breq.ifbr_state = p->bif_state;
+ breq.ifbr_priority = p->bif_priority;
+ breq.ifbr_path_cost = p->bif_path_cost;
+ breq.ifbr_portno = p->ifp->if_index & 0xff;
+ error = copyout((caddr_t)&breq,
+ (caddr_t)(bifc->ifbic_req + i), sizeof(breq));
+ if (error)
+ goto done;
+ p = LIST_NEXT(p, next);
+ i++;
+ bifc->ifbic_len -= sizeof(breq);
+ }
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ p = LIST_FIRST(&sc->sc_spanlist);
+ j = 0;
+ while (p != NULL && bifc->ifbic_len > j * sizeof(breq)) {
+ strncpy(breq.ifbr_name, sc->sc_if.if_xname,
+ sizeof(breq.ifbr_name)-1);
+ breq.ifbr_name[sizeof(breq.ifbr_name) - 1] = '\0';
+ strncpy(breq.ifbr_ifsname, p->ifp->if_xname,
+ sizeof(breq.ifbr_ifsname)-1);
+ breq.ifbr_ifsname[sizeof(breq.ifbr_ifsname) - 1] = '\0';
+ breq.ifbr_ifsflags = p->bif_flags | IFBIF_SPAN;
+ breq.ifbr_state = p->bif_state;
+ breq.ifbr_priority = p->bif_priority;
+ breq.ifbr_path_cost = p->bif_path_cost;
+ breq.ifbr_portno = p->ifp->if_index & 0xff;
+ error = copyout((caddr_t)&breq,
+ (caddr_t)(bifc->ifbic_req + j), sizeof(breq));
+ if (error)
+ goto done;
+ p = LIST_NEXT(p, next);
+ j++;
+ bifc->ifbic_len -= sizeof(breq);
+ }
+#endif
+done:
+ bifc->ifbic_len = i * sizeof(breq);
+ return (error);
+}
+
+int
+bridge_brlconf(sc, bc)
+ struct bridge_softc *sc;
+ struct ifbrlconf *bc;
+{
+ struct ifnet *ifp;
+ struct bridge_iflist *ifl;
+ struct brl_node *n;
+ struct ifbrlreq req;
+ int error = 0;
+ u_int32_t i, total=0;
+
+ ifp = ifunit(bc->ifbrl_ifsname);
+ if (ifp == NULL)
+ return (ENOENT);
+ if (ifp->if_bridge == NULL || ifp->if_bridge != (caddr_t)sc)
+ return (ESRCH);
+ ifl = LIST_FIRST(&sc->sc_iflist);
+ while (ifl != NULL && ifl->ifp != ifp)
+ ifl = LIST_NEXT(ifl, next);
+ if (ifl == NULL)
+ return (ESRCH);
+
+ n = SIMPLEQ_FIRST(&ifl->bif_brlin);
+ while (n != NULL) {
+ total++;
+ n = SIMPLEQ_NEXT(n, brl_next);
+ }
+ n = SIMPLEQ_FIRST(&ifl->bif_brlout);
+ while (n != NULL) {
+ total++;
+ n = SIMPLEQ_NEXT(n, brl_next);
+ }
+
+ if (bc->ifbrl_len == 0) {
+ i = total;
+ goto done;
+ }
+
+ i = 0;
+ n = SIMPLEQ_FIRST(&ifl->bif_brlin);
+ while (n != NULL && bc->ifbrl_len > i * sizeof(req)) {
+ strncpy(req.ifbr_name, sc->sc_if.if_xname,
+ sizeof(req.ifbr_name) - 1);
+ req.ifbr_name[sizeof(req.ifbr_name) - 1] = '\0';
+ strncpy(req.ifbr_ifsname, ifl->ifp->if_xname,
+ sizeof(req.ifbr_ifsname) - 1);
+ req.ifbr_ifsname[sizeof(req.ifbr_ifsname) - 1] = '\0';
+ req.ifbr_action = n->brl_action;
+ req.ifbr_flags = n->brl_flags;
+ req.ifbr_src = n->brl_src;
+ req.ifbr_dst = n->brl_dst;
+ error = copyout((caddr_t)&req,
+ (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req));
+ if (error)
+ goto done;
+ n = SIMPLEQ_NEXT(n, brl_next);
+ i++;
+ bc->ifbrl_len -= sizeof(req);
+ }
+
+ n = SIMPLEQ_FIRST(&ifl->bif_brlout);
+ while (n != NULL && bc->ifbrl_len > i * sizeof(req)) {
+ strncpy(req.ifbr_name, sc->sc_if.if_xname,
+ sizeof(req.ifbr_name) - 1);
+ req.ifbr_name[sizeof(req.ifbr_name) - 1] = '\0';
+ strncpy(req.ifbr_ifsname, ifl->ifp->if_xname,
+ sizeof(req.ifbr_ifsname) - 1);
+ req.ifbr_ifsname[sizeof(req.ifbr_ifsname) - 1] = '\0';
+ req.ifbr_action = n->brl_action;
+ req.ifbr_flags = n->brl_flags;
+ req.ifbr_src = n->brl_src;
+ req.ifbr_dst = n->brl_dst;
+ error = copyout((caddr_t)&req,
+ (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req));
+ if (error)
+ goto done;
+ n = SIMPLEQ_NEXT(n, brl_next);
+ i++;
+ bc->ifbrl_len -= sizeof(req);
+ }
+
+done:
+ bc->ifbrl_len = i * sizeof(req);
+ return (error);
+}
+
+void
+bridge_init(sc)
+ struct bridge_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_if;
+ int i, s;
+
+ if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING)
+ return;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL) {
+ sc->sc_rts = (struct bridge_rthead *)malloc(
+ BRIDGE_RTABLE_SIZE * (sizeof(struct bridge_rthead)),
+ M_DEVBUF, M_NOWAIT);
+ if (sc->sc_rts == NULL) {
+ splx(s);
+ return;
+ }
+ for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
+ LIST_INIT(&sc->sc_rts[i]);
+ }
+ }
+ ifp->if_flags |= IFF_RUNNING;
+ splx(s);
+
+ if (sc->sc_brttimeout != 0)
+ timeout(bridge_rtage, sc, sc->sc_brttimeout);
+}
+
+/*
+ * Stop the bridge and deallocate the routing table.
+ */
+void
+bridge_stop(sc)
+ struct bridge_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_if;
+
+ /*
+ * If we're not running, there's nothing to do.
+ */
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
+ return;
+
+ untimeout(bridge_rtage, sc);
+
+ bridge_rtflush(sc, IFBF_FLUSHDYN);
+
+ ifp->if_flags &= ~IFF_RUNNING;
+}
+
+/*
+ * Send output from the bridge. The mbuf has the ethernet header
+ * already attached. We must enqueue or free the mbuf before exiting.
+ */
+int
+bridge_output(ifp, m, sa, rt)
+ struct ifnet *ifp;
+ struct mbuf *m;
+ struct sockaddr *sa;
+ struct rtentry *rt;
+{
+ struct ether_header *eh;
+ struct ifnet *dst_if;
+ struct ether_addr *src, *dst;
+ struct bridge_softc *sc;
+ int s;
+
+ if (m->m_len < sizeof(*eh)) {
+ m = m_pullup(m, sizeof(*eh));
+ if (m == NULL)
+ return (0);
+ }
+ eh = mtod(m, struct ether_header *);
+ dst = (struct ether_addr *)&eh->ether_dhost[0];
+ src = (struct ether_addr *)&eh->ether_shost[0];
+ sc = (struct bridge_softc *)ifp->if_bridge;
+
+ s = splimp();
+
+ /*
+ * If bridge is down, but original output interface is up,
+ * go ahead and send out that interface. Otherwise the packet
+ * is dropped below.
+ */
+ if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
+ dst_if = ifp;
+ goto sendunicast;
+ }
+
+ /*
+ * If the packet is a broadcast or we don't know a better way to
+ * get there, send to all interfaces.
+ */
+ dst_if = bridge_rtlookup(sc, dst);
+ if (dst_if == NULL || eh->ether_dhost[0] & 1) {
+ struct bridge_iflist *p;
+ struct mbuf *mc;
+ int used = 0;
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ bridge_span(sc, NULL, m);
+#endif
+
+ for (p = LIST_FIRST(&sc->sc_iflist); p != NULL;
+ p = LIST_NEXT(p, next)) {
+ if ((p->ifp->if_flags & IFF_RUNNING) == 0)
+ continue;
+ if (IF_QFULL(&p->ifp->if_snd)) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+
+ if (LIST_NEXT(p, next) == NULL) {
+ used = 1;
+ mc = m;
+ } else {
+ mc = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+ if (mc == NULL) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+ }
+
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += m->m_pkthdr.len;
+ // Also count the bytes in the outgoing interface; normally
+ // done in if_ethersubr.c but here we bypass that route.
+ p->ifp->if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&p->ifp->if_snd, mc);
+ if ((p->ifp->if_flags & IFF_OACTIVE) == 0)
+ (*p->ifp->if_start)(p->ifp);
+ }
+ if (!used)
+ m_freem(m);
+ splx(s);
+ return (0);
+ }
+
+sendunicast:
+ if ((dst_if->if_flags & IFF_RUNNING) == 0) {
+ m_freem(m);
+ splx(s);
+ return (0);
+ }
+ if (IF_QFULL(&dst_if->if_snd)) {
+ sc->sc_if.if_oerrors++;
+ m_freem(m);
+ splx(s);
+ return (0);
+ }
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += m->m_pkthdr.len;
+ // Also count the bytes in the outgoing interface; normally
+ // done in if_ethersubr.c but here we bypass that route.
+ dst_if->if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&dst_if->if_snd, m);
+ if ((dst_if->if_flags & IFF_OACTIVE) == 0)
+ (*dst_if->if_start)(dst_if);
+ splx(s);
+ return (0);
+}
+
+/*
+ * Start output on the bridge. This function should never be called.
+ */
+void
+bridge_start(ifp)
+ struct ifnet *ifp;
+{
+}
+
+void
+bridgeintr(void)
+{
+ struct bridge_softc *sc;
+ struct mbuf *m;
+ int i, s;
+
+ for (i = 0; i < CYGNUM_NET_BRIDGES; i++) {
+ sc = &bridgectl[i];
+ for (;;) {
+ s = splimp();
+ IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ splx(s);
+ if (m == NULL)
+ break;
+ bridgeintr_frame(sc, m);
+ }
+ }
+}
+
+/*
+ * Loop through each bridge interface and process their input queues.
+ */
+void
+bridgeintr_frame(sc, m)
+ struct bridge_softc *sc;
+ struct mbuf *m;
+{
+ int s;
+ struct ifnet *src_if, *dst_if;
+ struct bridge_iflist *ifl;
+ struct ether_addr *dst, *src;
+ struct ether_header eh;
+
+ if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
+ m_freem(m);
+ return;
+ }
+
+ src_if = m->m_pkthdr.rcvif;
+
+ /*
+ * Pick out 802.1D packets.
+ * */
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+#ifdef __ECOS
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ if (bcmp (mtod(m,struct ether_header *), bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
+ m_copydata(m, 0, sizeof(struct ether_header), (caddr_t)&eh);
+ m_adj (m, sizeof(struct ether_header));
+ m = bstp_input(sc, src_if, &eh, m);
+ if (m == NULL)
+ return;
+ }
+ }
+#endif // __ECOS
+#endif
+
+#if NBPFILTER > 0
+ if (sc->sc_if.if_bpf)
+ bpf_mtap(sc->sc_if.if_bpf, m);
+#endif
+
+ sc->sc_if.if_lastchange = time;
+ sc->sc_if.if_ipackets++;
+ sc->sc_if.if_ibytes += m->m_pkthdr.len;
+
+ ifl = LIST_FIRST(&sc->sc_iflist);
+ while (ifl != NULL && ifl->ifp != src_if) {
+ ifl = LIST_NEXT(ifl, next);
+ }
+ if (ifl == NULL) {
+ m_freem(m);
+ return;
+ }
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ if ((ifl->bif_flags & IFBIF_STP) &&
+ (ifl->bif_state == BSTP_IFSTATE_BLOCKING ||
+ ifl->bif_state == BSTP_IFSTATE_LISTENING ||
+ ifl->bif_state == BSTP_IFSTATE_DISABLED)) {
+ m_freem(m);
+ return;
+ }
+#endif
+
+ if (m->m_pkthdr.len < sizeof(eh)) {
+ m_freem(m);
+ return;
+ }
+ m_copydata(m, 0, sizeof(struct ether_header), (caddr_t)&eh);
+ dst = (struct ether_addr *)&eh.ether_dhost[0];
+ src = (struct ether_addr *)&eh.ether_shost[0];
+
+ /*
+ * If interface is learning, and if source address
+ * is not broadcast or multicast, record it's address.
+ */
+ if ((ifl->bif_flags & IFBIF_LEARNING) &&
+ (eh.ether_shost[0] & 1) == 0 &&
+ !(eh.ether_shost[0] == 0 &&
+ eh.ether_shost[1] == 0 &&
+ eh.ether_shost[2] == 0 &&
+ eh.ether_shost[3] == 0 &&
+ eh.ether_shost[4] == 0 &&
+ eh.ether_shost[5] == 0))
+ bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC);
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ if ((ifl->bif_flags & IFBIF_STP) &&
+ (ifl->bif_state == BSTP_IFSTATE_LEARNING)) {
+ m_freem(m);
+ return;
+ }
+#endif
+ /*
+ * At this point, the port either does not participate in stp or
+ * it is in forwarding state.
+ */
+
+ /*
+ * If packet is unicast, destined for someone on "this"
+ * side of the bridge, drop it.
+ */
+ if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) {
+ dst_if = bridge_rtlookup(sc, dst);
+ if (dst_if == src_if) {
+ m_freem(m);
+ return;
+ }
+ } else
+ dst_if = NULL;
+
+ /*
+ * Multicast packets get handled a little differently:
+ * If interface is:
+ * -link0,-link1 (default) Forward all multicast
+ * as broadcast.
+ * -link0,link1 Drop non-IP multicast, forward
+ * as broadcast IP multicast.
+ * link0,-link1 Drop IP multicast, forward as
+ * broadcast non-IP multicast.
+ * link0,link1 Drop all multicast.
+ */
+ if (m->m_flags & M_MCAST) {
+ if ((sc->sc_if.if_flags &
+ (IFF_LINK0 | IFF_LINK1)) ==
+ (IFF_LINK0 | IFF_LINK1)) {
+ m_freem(m);
+ return;
+ }
+ if (sc->sc_if.if_flags & IFF_LINK0 &&
+ ETHERADDR_IS_IP_MCAST(dst)) {
+ m_freem(m);
+ return;
+ }
+ if (sc->sc_if.if_flags & IFF_LINK1 &&
+ !ETHERADDR_IS_IP_MCAST(dst)) {
+ m_freem(m);
+ return;
+ }
+ }
+
+ if (ifl->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) {
+ m_freem(m);
+ return;
+ }
+
+ if (SIMPLEQ_FIRST(&ifl->bif_brlin) &&
+ bridge_filterrule(SIMPLEQ_FIRST(&ifl->bif_brlin), &eh) ==
+ BRL_ACTION_BLOCK) {
+ m_freem(m);
+ return;
+ }
+
+#if defined(INET) && (defined(IPFILTER) || defined(IPFILTER_LKM))
+ m = bridge_filter(sc, src_if, &eh, m);
+ if (m == NULL)
+ return;
+#endif
+
+ /*
+ * If the packet is a multicast or broadcast OR if we don't
+ * know any better, forward it to all interfaces.
+ */
+ if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_if == NULL) {
+ sc->sc_if.if_imcasts++;
+ s = splimp();
+ bridge_broadcast(sc, src_if, &eh, m);
+ splx(s);
+ return;
+ }
+
+ /*
+ * At this point, we're dealing with a unicast frame going to a
+ * different interface
+ */
+ if ((dst_if->if_flags & IFF_RUNNING) == 0) {
+ m_freem(m);
+ return;
+ }
+ ifl = LIST_FIRST(&sc->sc_iflist);
+ while (ifl != NULL && ifl->ifp != dst_if)
+ ifl = LIST_NEXT(ifl, next);
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ if ((ifl->bif_flags & IFBIF_STP) &&
+ (ifl->bif_state == BSTP_IFSTATE_DISABLED ||
+ ifl->bif_state == BSTP_IFSTATE_BLOCKING)) {
+ m_freem(m);
+ return;
+ }
+#endif
+
+ if (SIMPLEQ_FIRST(&ifl->bif_brlout) &&
+ bridge_filterrule(SIMPLEQ_FIRST(&ifl->bif_brlout), &eh) ==
+ BRL_ACTION_BLOCK) {
+ m_freem(m);
+ return;
+ }
+ s = splimp();
+ if (IF_QFULL(&dst_if->if_snd)) {
+ sc->sc_if.if_oerrors++;
+ m_freem(m);
+ splx(s);
+ return;
+ }
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += m->m_pkthdr.len;
+ // Also count the bytes in the outgoing interface; normally
+ // done in if_ethersubr.c but here we bypass that route.
+ dst_if->if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&dst_if->if_snd, m);
+ if ((dst_if->if_flags & IFF_OACTIVE) == 0)
+ (*dst_if->if_start)(dst_if);
+ splx(s);
+}
+
+/*
+ * Receive input from an interface. Queue the packet for bridging if its
+ * not for us, and schedule an interrupt.
+ */
+struct mbuf *
+bridge_input(ifp, eh, m)
+ struct ifnet *ifp;
+ struct ether_header *eh;
+ struct mbuf *m;
+{
+ struct bridge_softc *sc;
+ int s;
+ struct bridge_iflist *ifl;
+ struct arpcom *ac;
+ struct mbuf *mc;
+
+ /*
+ * Make sure this interface is a bridge member.
+ */
+ if (ifp == NULL || ifp->if_bridge == NULL || m == NULL)
+ return (m);
+
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("bridge_input(): no HDR");
+
+ sc = (struct bridge_softc *)ifp->if_bridge;
+ if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
+ return (m);
+
+ LIST_FOREACH (ifl, &sc->sc_iflist, next) {
+ if (ifl->ifp == ifp)
+ break;
+ }
+ if (ifl == LIST_END (&sc->sc_iflist))
+ return (m);
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ bridge_span(sc, eh, m);
+ /*
+ * Tap off 802.1D packets, they do not get forwarded
+ */
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ if (bcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
+#ifdef __ECOS
+ M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
+ if (m == NULL)
+ return (NULL);
+ bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header));
+
+ s = splimp ();
+ if (IF_QFULL(&sc->sc_if.if_snd)) {
+ m_freem (m);
+ splx (s);
+ return (NULL);
+ }
+ IF_ENQUEUE(&sc->sc_if.if_snd, m);
+ splx (s);
+ schednetisr (NETISR_BRIDGE);
+ return (NULL);
+#else
+ m = bstp_input(sc, ifp, eh, m);
+ if (m == NULL)
+ return (NULL);
+#endif
+ }
+ }
+#endif
+
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ /*
+ * make a copy of 'm' with 'eh' tacked on to the
+ * beginning. Return 'm' for local processing
+ * and enqueue the copy. Schedule netisr.
+ */
+ mc = m_copym2(m, 0, M_COPYALL, M_NOWAIT);
+ if (mc == NULL)
+ return (m);
+ M_PREPEND(mc, sizeof(struct ether_header), M_DONTWAIT);
+ if (mc == NULL)
+ return (m);
+ bcopy(eh, mtod(mc, caddr_t), sizeof(struct ether_header));
+ s = splimp();
+ if (IF_QFULL(&sc->sc_if.if_snd)) {
+ m_freem(mc);
+ splx(s);
+ return (m);
+ }
+ IF_ENQUEUE(&sc->sc_if.if_snd, mc);
+ splx(s);
+ schednetisr(NETISR_BRIDGE);
+ return (m);
+ }
+
+ /*
+ * No need to queue frames for ifs in blocking, disabled or listening state
+ */
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ if ((ifl->bif_flags & IFBIF_STP) &&
+ ((ifl->bif_state == BSTP_IFSTATE_BLOCKING) ||
+ (ifl->bif_state == BSTP_IFSTATE_LISTENING) ||
+ (ifl->bif_state == BSTP_IFSTATE_DISABLED)))
+ return (m);
+#endif
+
+ /*
+ * Unicast, make sure it's not for us.
+ */
+ for (ifl = LIST_FIRST(&sc->sc_iflist);ifl; ifl = LIST_NEXT(ifl,next)) {
+ if (ifl->ifp->if_type != IFT_ETHER)
+ continue;
+ ac = (struct arpcom *)ifl->ifp;
+ if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0) {
+ if (ifl->bif_flags & IFBIF_LEARNING)
+ bridge_rtupdate(sc,
+ (struct ether_addr *)&eh->ether_shost,
+ ifp, 0, IFBAF_DYNAMIC);
+ m->m_pkthdr.rcvif = ifl->ifp;
+ return (m);
+ }
+ if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0) {
+ m_freem(m);
+ return (NULL);
+ }
+ }
+ M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
+ if (m == NULL)
+ return (NULL);
+ bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header));
+ s = splimp();
+ if (IF_QFULL(&sc->sc_if.if_snd)) {
+ m_freem(m);
+ splx(s);
+ return (NULL);
+ }
+ IF_ENQUEUE(&sc->sc_if.if_snd, m);
+ splx(s);
+ schednetisr(NETISR_BRIDGE);
+ return (NULL);
+}
+
+/*
+ * Send a frame to all interfaces that are members of the bridge
+ * (except the one it came in on). This code assumes that it is
+ * running at splnet or higher.
+ */
+void
+bridge_broadcast(sc, ifp, eh, m)
+ struct bridge_softc *sc;
+ struct ifnet *ifp;
+ struct ether_header *eh;
+ struct mbuf *m;
+{
+ struct bridge_iflist *p;
+ struct mbuf *mc;
+ int used = 0;
+
+ for (p = LIST_FIRST(&sc->sc_iflist); p; p = LIST_NEXT(p, next)) {
+ /*
+ * Don't retransmit out of the same interface where
+ * the packet was received from.
+ */
+ if (p->ifp->if_index == ifp->if_index)
+ continue;
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+ if ((p->bif_flags & IFBIF_STP) &&
+ (p->bif_state != BSTP_IFSTATE_FORWARDING))
+ continue;
+#endif
+
+ if ((p->bif_flags & IFBIF_DISCOVER) == 0 &&
+ (m->m_flags & (M_BCAST | M_MCAST)) == 0)
+ continue;
+
+ if ((p->ifp->if_flags & IFF_RUNNING) == 0)
+ continue;
+
+ if (IF_QFULL(&p->ifp->if_snd)) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+
+ if (SIMPLEQ_FIRST(&p->bif_brlout) &&
+ bridge_filterrule(SIMPLEQ_FIRST(&p->bif_brlout), eh) ==
+ BRL_ACTION_BLOCK)
+ continue;
+
+ /* If last one, reuse the passed-in mbuf */
+ if (LIST_NEXT(p, next) == NULL) {
+ mc = m;
+ used = 1;
+ } else {
+ mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
+ if (mc == NULL) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+ }
+
+ if (p->bif_flags & IFBIF_BLOCKNONIP &&
+ bridge_blocknonip(eh, mc)) {
+ m_freem(mc);
+ continue;
+ }
+
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += mc->m_pkthdr.len;
+ if (ifp && ((eh->ether_shost[0] & 1) == 0) )
+ ifp->if_omcasts++;
+ // Also count the bytes in the outgoing interface; normally
+ // done in if_ethersubr.c but here we bypass that route.
+ p->ifp->if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&p->ifp->if_snd, mc);
+ if ((p->ifp->if_flags & IFF_OACTIVE) == 0)
+ (*p->ifp->if_start)(p->ifp);
+ }
+
+ if (!used)
+ m_freem(m);
+}
+
+#ifdef CYGPKG_NET_BRIDGE_STP_CODE
+void
+bridge_span(sc, eh, morig)
+ struct bridge_softc *sc;
+ struct ether_header *eh;
+ struct mbuf *morig;
+{
+ struct bridge_iflist *p;
+ struct ifnet *ifp;
+ struct mbuf *mc, *m;
+ int error;
+
+ if (LIST_EMPTY(&sc->sc_spanlist))
+ return;
+
+ m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT);
+ if (m == NULL)
+ return;
+ if (eh != NULL) {
+ M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
+ if (m == NULL)
+ return;
+ bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header));
+ }
+
+ LIST_FOREACH(p, &sc->sc_spanlist, next) {
+ ifp = p->ifp;
+
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
+ continue;
+
+#ifdef ALTQ
+ if (ALTQ_IS_ENABLED(&ifp->if_snd) == 0)
+#endif
+ if (IF_QFULL(&ifp->if_snd)) {
+ IF_DROP(&ifp->if_snd);
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+
+ mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
+ if (mc == NULL) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+
+ error = bridge_ifenqueue(sc, ifp, m);
+ if (error)
+ continue;
+ }
+ m_freem(m);
+}
+#endif
+
+struct ifnet *
+bridge_rtupdate(sc, ea, ifp, setflags, flags)
+ struct bridge_softc *sc;
+ struct ether_addr *ea;
+ struct ifnet *ifp;
+ int setflags;
+ u_int8_t flags;
+{
+ struct bridge_rtnode *p, *q;
+ u_int32_t h;
+ int s, dir;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL) {
+ if (setflags && flags == IFBAF_STATIC) {
+ sc->sc_rts = (struct bridge_rthead *)malloc(
+ BRIDGE_RTABLE_SIZE *
+ (sizeof(struct bridge_rthead)),M_DEVBUF,M_NOWAIT);
+
+ if (sc->sc_rts == NULL)
+ goto done;
+
+ for (h = 0; h < BRIDGE_RTABLE_SIZE; h++)
+ LIST_INIT(&sc->sc_rts[h]);
+ } else
+ goto done;
+ }
+
+ h = bridge_hash(ea);
+ p = LIST_FIRST(&sc->sc_rts[h]);
+ if (p == NULL) {
+ if (sc->sc_brtcnt >= sc->sc_brtmax)
+ goto done;
+ p = (struct bridge_rtnode *)malloc(
+ sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT);
+ if (p == NULL)
+ goto done;
+
+ bcopy(ea, &p->brt_addr, sizeof(p->brt_addr));
+ p->brt_if = ifp;
+ p->brt_age = 1;
+
+ if (setflags)
+ p->brt_flags = flags;
+ else
+ p->brt_flags = IFBAF_DYNAMIC;
+
+ LIST_INSERT_HEAD(&sc->sc_rts[h], p, brt_next);
+ sc->sc_brtcnt++;
+ goto want;
+ }
+
+ do {
+ q = p;
+ p = LIST_NEXT(p, brt_next);
+
+ dir = memcmp(ea, &q->brt_addr, sizeof(q->brt_addr));
+ if (dir == 0) {
+ if (setflags) {
+ q->brt_if = ifp;
+ q->brt_flags = flags;
+ }
+
+ if (q->brt_if == ifp)
+ q->brt_age = 1;
+ ifp = q->brt_if;
+ goto want;
+ }
+
+ if (dir > 0) {
+ if (sc->sc_brtcnt >= sc->sc_brtmax)
+ goto done;
+ p = (struct bridge_rtnode *)malloc(
+ sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT);
+ if (p == NULL)
+ goto done;
+
+ bcopy(ea, &p->brt_addr, sizeof(p->brt_addr));
+ p->brt_if = ifp;
+ p->brt_age = 1;
+
+ if (setflags)
+ p->brt_flags = flags;
+ else
+ p->brt_flags = IFBAF_DYNAMIC;
+
+ LIST_INSERT_BEFORE(q, p, brt_next);
+ sc->sc_brtcnt++;
+ goto want;
+ }
+
+ if (p == NULL) {
+ if (sc->sc_brtcnt >= sc->sc_brtmax)
+ goto done;
+ p = (struct bridge_rtnode *)malloc(
+ sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT);
+ if (p == NULL)
+ goto done;
+
+ bcopy(ea, &p->brt_addr, sizeof(p->brt_addr));
+ p->brt_if = ifp;
+ p->brt_age = 1;
+
+ if (setflags)
+ p->brt_flags = flags;
+ else
+ p->brt_flags = IFBAF_DYNAMIC;
+ LIST_INSERT_AFTER(q, p, brt_next);
+ sc->sc_brtcnt++;
+ goto want;
+ }
+ } while (p != NULL);
+
+done:
+ ifp = NULL;
+want:
+ splx(s);
+ return (ifp);
+}
+
+struct ifnet *
+bridge_rtlookup(sc, ea)
+ struct bridge_softc *sc;
+ struct ether_addr *ea;
+{
+ struct bridge_rtnode *p;
+ u_int32_t h;
+ int s, dir;
+
+ /*
+ * Lock out everything else
+ */
+ s = splhigh();
+
+ if (sc->sc_rts == NULL)
+ goto fail;
+
+ h = bridge_hash(ea);
+ p = LIST_FIRST(&sc->sc_rts[h]);
+ while (p != NULL) {
+ dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr));
+ if (dir == 0) {
+ splx(s);
+ return (p->brt_if);
+ }
+ if (dir > 0)
+ goto fail;
+ p = LIST_NEXT(p, brt_next);
+ }
+fail:
+ splx(s);
+ return (NULL);
+}
+
+/*
+ * The following hash function is adapted from 'Hash Functions' by Bob Jenkins
+ * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
+ * "You may use this code any way you wish, private, educational, or
+ * commercial. It's free."
+ */
+#define mix(a,b,c) \
+ do { \
+ a -= b; a -= c; a ^= (c >> 13); \
+ b -= c; b -= a; b ^= (a << 8); \
+ c -= a; c -= b; c ^= (b >> 13); \
+ a -= b; a -= c; a ^= (c >> 12); \
+ b -= c; b -= a; b ^= (a << 16); \
+ c -= a; c -= b; c ^= (b >> 5); \
+ a -= b; a -= c; a ^= (c >> 3); \
+ b -= c; b -= a; b ^= (a << 10); \
+ c -= a; c -= b; c ^= (b >> 15); \
+ } while(0)
+
+u_int32_t
+bridge_hash(addr)
+ struct ether_addr *addr;
+{
+ u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = 0xdeadbeef;
+
+ b += addr->ether_addr_octet[5] << 8;
+ b += addr->ether_addr_octet[4];
+ a += addr->ether_addr_octet[3] << 24;
+ a += addr->ether_addr_octet[2] << 16;
+ a += addr->ether_addr_octet[1] << 8;
+ a += addr->ether_addr_octet[0];
+
+ mix(a, b, c);
+ return (c & BRIDGE_RTABLE_MASK);
+}
+
+/*
+ * Trim the routing table so that we've got a number of routes
+ * less than or equal to the maximum.
+ */
+void
+bridge_rttrim(sc)
+ struct bridge_softc *sc;
+{
+ struct bridge_rtnode *n, *p;
+ int s, i;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL)
+ goto done;
+
+ /*
+ * Make sure we have to trim the address table
+ */
+ if (sc->sc_brtcnt <= sc->sc_brtmax)
+ goto done;
+
+ /*
+ * Force an aging cycle, this might trim enough addresses.
+ */
+ splx(s);
+ bridge_rtage(sc);
+ s = splhigh();
+
+ if (sc->sc_brtcnt <= sc->sc_brtmax)
+ goto done;
+
+ for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
+ n = LIST_FIRST(&sc->sc_rts[i]);
+ while (n != NULL) {
+ p = LIST_NEXT(n, brt_next);
+ if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
+ LIST_REMOVE(n, brt_next);
+ sc->sc_brtcnt--;
+ free(n, M_DEVBUF);
+ n = p;
+ if (sc->sc_brtcnt <= sc->sc_brtmax)
+ goto done;
+ }
+ }
+ }
+
+done:
+ if (sc->sc_rts != NULL && sc->sc_brtcnt == 0 &&
+ (sc->sc_if.if_flags & IFF_UP) == 0) {
+ free(sc->sc_rts, M_DEVBUF);
+ sc->sc_rts = NULL;
+ }
+
+ splx(s);
+}
+
+/*
+ * Perform an aging cycle
+ */
+void
+bridge_rtage(vsc)
+ void *vsc;
+{
+ struct bridge_softc *sc = (struct bridge_softc *)vsc;
+ struct bridge_rtnode *n, *p;
+ int s, i;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL) {
+ splx(s);
+ return;
+ }
+
+ for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
+ n = LIST_FIRST(&sc->sc_rts[i]);
+ while (n != NULL) {
+ if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_STATIC) {
+ n->brt_age = !n->brt_age;
+ if (n->brt_age)
+ n->brt_age = 0;
+ n = LIST_NEXT(n, brt_next);
+ } else if (n->brt_age) {
+ n->brt_age = 0;
+ n = LIST_NEXT(n, brt_next);
+ } else {
+ p = LIST_NEXT(n, brt_next);
+ LIST_REMOVE(n, brt_next);
+ sc->sc_brtcnt--;
+ free(n, M_DEVBUF);
+ n = p;
+ }
+ }
+ }
+ splx(s);
+
+ if (sc->sc_brttimeout != 0)
+ timeout(bridge_rtage, sc, sc->sc_brttimeout);
+}
+
+/*
+ * Remove all dynamic addresses from the cache
+ */
+int
+bridge_rtflush(sc, full)
+ struct bridge_softc *sc;
+ int full;
+{
+ int s, i;
+ struct bridge_rtnode *p, *n;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL)
+ goto done;
+
+ for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
+ n = LIST_FIRST(&sc->sc_rts[i]);
+ while (n != NULL) {
+ if (full ||
+ (n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
+ p = LIST_NEXT(n, brt_next);
+ LIST_REMOVE(n, brt_next);
+ sc->sc_brtcnt--;
+ free(n, M_DEVBUF);
+ n = p;
+ } else
+ n = LIST_NEXT(n, brt_next);
+ }
+ }
+
+ if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) {
+ free(sc->sc_rts, M_DEVBUF);
+ sc->sc_rts = NULL;
+ }
+
+done:
+ splx(s);
+ return (0);
+}
+
+/*
+ * Remove an address from the cache
+ */
+int
+bridge_rtdaddr(sc, ea)
+ struct bridge_softc *sc;
+ struct ether_addr *ea;
+{
+ int h, s;
+ struct bridge_rtnode *p;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL)
+ goto done;
+
+ h = bridge_hash(ea);
+ p = LIST_FIRST(&sc->sc_rts[h]);
+ while (p != NULL) {
+ if (bcmp(ea, &p->brt_addr, sizeof(p->brt_addr)) == 0) {
+ LIST_REMOVE(p, brt_next);
+ sc->sc_brtcnt--;
+ free(p, M_DEVBUF);
+ if (sc->sc_brtcnt == 0 &&
+ (sc->sc_if.if_flags & IFF_UP) == 0) {
+ free(sc->sc_rts, M_DEVBUF);
+ sc->sc_rts = NULL;
+ }
+ splx(s);
+ return (0);
+ }
+ p = LIST_NEXT(p, brt_next);
+ }
+
+done:
+ splx(s);
+ return (ENOENT);
+}
+/*
+ * Delete routes to a specific interface member.
+ */
+void
+bridge_rtdelete(sc, ifp, dynonly)
+ struct bridge_softc *sc;
+ struct ifnet *ifp;
+{
+ int i, s;
+ struct bridge_rtnode *n, *p;
+
+ s = splhigh();
+ if (sc->sc_rts == NULL)
+ goto done;
+
+ /*
+ * Loop through all of the hash buckets and traverse each
+ * chain looking for routes to this interface.
+ */
+ for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
+ n = LIST_FIRST(&sc->sc_rts[i]);
+ while (n != NULL) {
+ if (n->brt_if == ifp) { /* found one */
+ p = LIST_NEXT(n, brt_next);
+ LIST_REMOVE(n, brt_next);
+ sc->sc_brtcnt--;
+ free(n, M_DEVBUF);
+ n = p;
+ } else
+ n = LIST_NEXT(n, brt_next);
+ }
+ }
+ if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) {
+ free(sc->sc_rts, M_DEVBUF);
+ sc->sc_rts = NULL;
+ }
+
+done:
+ splx(s);
+}
+
+/*
+ * Gather all of the routes for this interface.
+ */
+int
+bridge_rtfind(sc, baconf)
+ struct bridge_softc *sc;
+ struct ifbaconf *baconf;
+{
+ int i, s, error = 0;
+ u_int32_t cnt = 0;
+ struct bridge_rtnode *n;
+ struct ifbareq bareq;
+
+ s = splhigh();
+
+ if (sc->sc_rts == NULL || baconf->ifbac_len == 0)
+ goto done;
+
+ for (i = 0, cnt = 0; i < BRIDGE_RTABLE_SIZE; i++) {
+ n = LIST_FIRST(&sc->sc_rts[i]);
+ while (n != NULL) {
+ if (baconf->ifbac_len <
+ (cnt + 1) * sizeof(struct ifbareq))
+ goto done;
+ bcopy(sc->sc_if.if_xname, bareq.ifba_name,
+ sizeof(bareq.ifba_name));
+ bcopy(n->brt_if->if_xname, bareq.ifba_ifsname,
+ sizeof(bareq.ifba_ifsname));
+ bcopy(&n->brt_addr, &bareq.ifba_dst,
+ sizeof(bareq.ifba_dst));
+ bareq.ifba_age = n->brt_age;
+ bareq.ifba_flags = n->brt_flags;
+ error = copyout((caddr_t)&bareq,
+ (caddr_t)(baconf->ifbac_req + cnt), sizeof(bareq));
+ if (error)
+ goto done;
+ n = LIST_NEXT(n, brt_next);
+ cnt++;
+ }
+ }
+done:
+ baconf->ifbac_len = cnt * sizeof(struct ifbareq);
+ splx(s);
+ return (error);
+}
+
+/*
+ * Block non-ip frames:
+ * Returns 0 if frame is ip, and 1 if it should be dropped.
+ */
+int
+bridge_blocknonip(eh, m)
+ struct ether_header *eh;
+ struct mbuf *m;
+{
+ struct snap snap;
+ u_int16_t etype;
+
+ if (m->m_pkthdr.len < sizeof(struct ether_header))
+ return (1);
+
+ etype = ntohs(eh->ether_type);
+ switch (etype) {
+ case ETHERTYPE_ARP:
+ case ETHERTYPE_REVARP:
+ case ETHERTYPE_IP:
+ case ETHERTYPE_IPV6:
+ return (0);
+ }
+
+ if (etype > ETHERMTU)
+ return (1);
+
+ if (m->m_pkthdr.len <
+ (sizeof(struct ether_header) + sizeof(struct snap)))
+ return (1);
+
+ m_copydata(m, sizeof(struct ether_header), sizeof(struct snap),
+ (caddr_t)&snap);
+
+ etype = ntohs(snap.type);
+ if (snap.dsap == LLC_SNAP_LSAP && snap.ssap == LLC_SNAP_LSAP &&
+ snap.control == LLC_UI &&
+ snap.org[0] == 0 && snap.org[1] == 0 && snap.org[2] == 0 &&
+ (etype == ETHERTYPE_ARP ||
+ etype == ETHERTYPE_REVARP ||
+ etype == ETHERTYPE_IP ||
+ etype == ETHERTYPE_IPV6)) {
+ return (0);
+ }
+
+ return (1);
+}
+
+u_int8_t
+bridge_filterrule(n, eh)
+ struct brl_node *n;
+ struct ether_header *eh;
+{
+ u_int8_t flags;
+
+ for (; n != NULL; n = SIMPLEQ_NEXT(n, brl_next)) {
+ flags = n->brl_flags & (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID);
+ if (flags == 0)
+ return (n->brl_action);
+ if (flags == (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID)) {
+ if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN))
+ continue;
+ if (bcmp(eh->ether_dhost, &n->brl_src, ETHER_ADDR_LEN))
+ continue;
+ return (n->brl_action);
+ }
+ if (flags == BRL_FLAG_SRCVALID) {
+ if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN))
+ continue;
+ return (n->brl_action);
+ }
+ if (flags == BRL_FLAG_DSTVALID) {
+ if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN))
+ continue;
+ return (n->brl_action);
+ }
+ }
+ return (BRL_ACTION_PASS);
+}
+
+int
+bridge_addrule(bif, req, out)
+ struct bridge_iflist *bif;
+ struct ifbrlreq *req;
+ int out;
+{
+ struct brl_node *n;
+
+ n = (struct brl_node *)malloc(sizeof(struct brl_node), M_DEVBUF, M_NOWAIT);
+ if (n == NULL)
+ return (ENOMEM);
+ bcopy(&req->ifbr_src, &n->brl_src, sizeof(struct ether_addr));
+ bcopy(&req->ifbr_dst, &n->brl_dst, sizeof(struct ether_addr));
+ n->brl_action = req->ifbr_action;
+ n->brl_flags = req->ifbr_flags;
+ if (out) {
+ n->brl_flags &= ~BRL_FLAG_IN;
+ n->brl_flags |= BRL_FLAG_OUT;
+ SIMPLEQ_INSERT_TAIL(&bif->bif_brlout, n, brl_next);
+ } else {
+ n->brl_flags &= ~BRL_FLAG_OUT;
+ n->brl_flags |= BRL_FLAG_IN;
+ SIMPLEQ_INSERT_TAIL(&bif->bif_brlin, n, brl_next);
+ }
+ return (0);
+}
+
+int
+bridge_flushrule(bif)
+ struct bridge_iflist *bif;
+{
+ struct brl_node *p, *q;
+
+ p = SIMPLEQ_FIRST(&bif->bif_brlin);
+ while (p != NULL) {
+ q = SIMPLEQ_NEXT(p, brl_next);
+ SIMPLEQ_REMOVE_HEAD(&bif->bif_brlin, p, brl_next);
+ free(p, M_DEVBUF);
+ p = q;
+ }
+ p = SIMPLEQ_FIRST(&bif->bif_brlout);
+ while (p != NULL) {
+ q = SIMPLEQ_NEXT(p, brl_next);
+ SIMPLEQ_REMOVE_HEAD(&bif->bif_brlout, p, brl_next);
+ free(p, M_DEVBUF);
+ p = q;
+ }
+ return (0);
+}
+
+#if defined(INET) && (defined(IPFILTER) || defined(IPFILTER_LKM))
+
+/*
+ * Maximum sized IP header
+ */
+union maxip {
+ struct ip ip;
+ u_int32_t _padding[16];
+};
+
+/*
+ * Filter IP packets by peeking into the ethernet frame. This violates
+ * the ISO model, but allows us to act as a IP filter at the data link
+ * layer. As a result, most of this code will look familiar to those
+ * who've read net/if_ethersubr.c and netinet/ip_input.c
+ */
+struct mbuf *
+bridge_filter(sc, ifp, eh, m)
+ struct bridge_softc *sc;
+ struct ifnet *ifp;
+ struct ether_header *eh;
+ struct mbuf *m;
+{
+ struct snap snap;
+ int hassnap = 0;
+ struct ip *ip;
+ int hlen;
+
+ if (fr_checkp == NULL)
+ return (m);
+
+ if (eh->ether_type != htons(ETHERTYPE_IP)) {
+ if (eh->ether_type > ETHERMTU ||
+ m->m_pkthdr.len < (sizeof(struct snap) +
+ sizeof(struct ether_header)))
+ return (m);
+
+ m_copydata(m, sizeof(struct ether_header),
+ sizeof(struct snap), (caddr_t)&snap);
+
+ if (snap.dsap != LLC_SNAP_LSAP || snap.ssap != LLC_SNAP_LSAP ||
+ snap.control != LLC_UI ||
+ snap.org[0] != 0 || snap.org[1] != 0 || snap.org[2] ||
+ snap.type != htons(ETHERTYPE_IP))
+ return (m);
+ hassnap = 1;
+ }
+
+ m_adj(m, sizeof(struct ether_header));
+ if (hassnap)
+ m_adj(m, sizeof(struct snap));
+
+ if (m->m_pkthdr.len < sizeof(struct ip))
+ goto dropit;
+
+ /* Copy minimal header, and drop invalids */
+ if (m->m_len < sizeof(struct ip) &&
+ (m = m_pullup(m, sizeof(struct ip))) == NULL)
+ return (NULL);
+ ip = mtod(m, struct ip *);
+
+ if (ip->ip_v != IPVERSION)
+ goto dropit;
+
+ hlen = ip->ip_hl << 2; /* get whole header length */
+ if (hlen < sizeof(struct ip))
+ goto dropit;
+ if (hlen > m->m_len) {
+ if ((m = m_pullup(m, sizeof(struct ip))) == NULL)
+ return (NULL);
+ ip = mtod(m, struct ip *);
+ }
+
+ if ((ip->ip_sum = in_cksum(m, hlen)) != 0)
+ goto dropit;
+
+ NTOHS(ip->ip_len);
+ if (ip->ip_len < hlen)
+ goto dropit;
+ NTOHS(ip->ip_id);
+ NTOHS(ip->ip_off);
+
+ if (m->m_pkthdr.len < ip->ip_len)
+ goto dropit;
+ if (m->m_pkthdr.len > ip->ip_len) {
+ if (m->m_len == m->m_pkthdr.len) {
+ m->m_len = ip->ip_len;
+ m->m_pkthdr.len = ip->ip_len;
+ } else
+ m_adj(m, ip->ip_len - m->m_pkthdr.len);
+ }
+
+ /* Finally, we get to filter the packet! */
+ if (fr_checkp && (*fr_checkp)(ip, hlen, ifp, 0, &m))
+ return (NULL);
+
+ /* Rebuild the IP header */
+ if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
+ return (NULL);
+ if (m->m_len < sizeof(struct ip))
+ goto dropit;
+ ip = mtod(m, struct ip *);
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_id);
+ HTONS(ip->ip_off);
+ ip->ip_sum = in_cksum(m, hlen);
+
+ /* Reattach SNAP header */
+ if (hassnap) {
+ M_PREPEND(m, sizeof(snap), M_DONTWAIT);
+ if (m == NULL)
+ goto dropit;
+ bcopy(&snap, mtod(m, caddr_t), sizeof(snap));
+ }
+
+ /* Reattach ethernet header */
+ M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
+ if (m == NULL)
+ goto dropit;
+ bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
+
+ return (m);
+
+dropit:
+ if (m != NULL)
+ m_freem(m);
+ return (NULL);
+}
+#endif
+
+int
+ifpromisc(ifp, pswitch)
+ struct ifnet *ifp;
+ int pswitch;
+{
+ struct ifreq ifr;
+
+ if (pswitch) {
+ /*
+ * If the device is not configured up, we cannot put it in
+ * promiscuous mode.
+ */
+ if ((ifp->if_flags & IFF_UP) == 0)
+ return (ENETDOWN);
+ if (ifp->if_pcount++ != 0)
+ return (0);
+ ifp->if_flags |= IFF_PROMISC;
+ } else {
+ if (--ifp->if_pcount > 0)
+ return (0);
+ ifp->if_flags &= ~IFF_PROMISC;
+ /*
+ * If the device is not configured up, we should not need to
+ * turn off promiscuous mode (device should have turned it
+ * off when interface went down; and will look at IFF_PROMISC
+ * again next time interface comes up).
+ */
+ if ((ifp->if_flags & IFF_UP) == 0)
+ return (0);
+ }
+ ifr.ifr_flags = ifp->if_flags;
+ return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
+}
+
+int
+bridge_ifenqueue(sc, ifp, m)
+ struct bridge_softc *sc;
+ struct ifnet *ifp;
+ struct mbuf *m;
+{
+ int error, len;
+ short mflags;
+
+ len = m->m_pkthdr.len;
+ mflags = m->m_flags;
+ IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
+ if (error) {
+ sc->sc_if.if_oerrors++;
+ return (error);
+ }
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += len;
+ ifp->if_obytes += len;
+ if (mflags & M_MCAST)
+ ifp->if_omcasts++;
+ if ((ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ return (0);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/if_ethersubr.c b/ecos/packages/net/tcpip/current/src/sys/net/if_ethersubr.c
new file mode 100644
index 0000000..d1be3bd
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/if_ethersubr.c
@@ -0,0 +1,1179 @@
+//==========================================================================
+//
+// sys/net/if_ethersubr.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_ethersubr.c,v 1.32 1999/12/08 06:50:17 itojun Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#ifndef __ECOS
+#include <sys/syslog.h>
+#endif
+
+#include <machine/cpu.h>
+
+#include <net/if.h>
+#include <net/netisr.h>
+#include <net/route.h>
+#include <net/if_llc.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+
+#include <netinet/in.h>
+#ifdef INET
+#include <netinet/in_var.h>
+#endif
+#include <netinet/if_ether.h>
+
+#ifndef __ECOS
+#include "bridge.h"
+#endif
+#if NBRIDGE > 0
+#include <net/if_bridge.h>
+#endif
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+#endif
+
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+#endif
+
+#ifdef ISO
+#include <netiso/argo_debug.h>
+#include <netiso/iso.h>
+#include <netiso/iso_var.h>
+#include <netiso/iso_snpac.h>
+#endif
+
+#ifdef CCITT
+#include <netccitt/x25.h>
+#include <netccitt/pk.h>
+#include <netccitt/pk_extern.h>
+#include <netccitt/dll.h>
+#include <netccitt/llc_var.h>
+#endif
+
+#ifdef NETATALK
+#include <netatalk/at.h>
+#include <netatalk/at_var.h>
+#include <netatalk/at_extern.h>
+
+#define llc_snap_org_code llc_un.type_snap.org_code
+#define llc_snap_ether_type llc_un.type_snap.ether_type
+
+extern u_char at_org_code[ 3 ];
+extern u_char aarp_org_code[ 3 ];
+#endif /* NETATALK */
+
+#if defined(CCITT)
+#include <sys/socketvar.h>
+#endif
+
+#if 0 /*NRL INET6*/
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+#endif /* INET6 */
+
+u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+#define senderr(e) { error = (e); goto bad;}
+
+
+int
+ether_ioctl(ifp, arp, cmd, data)
+ register struct ifnet *ifp;
+ struct arpcom *arp;
+ u_long cmd;
+ caddr_t data;
+{
+ struct ifaddr *ifa = (struct ifaddr *)data;
+ int error = 0;
+
+ switch (cmd) {
+
+#if defined(CCITT)
+ case SIOCSIFCONF_X25:
+ ifp->if_flags |= IFF_UP;
+ ifa->ifa_rtrequest = cons_rtrequest;
+ error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);
+ break;
+#endif /* CCITT */
+ case SIOCSIFADDR:
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef IPX
+ case AF_IPX:
+ {
+ struct ipx_addr *ina = &IA_SIPX(ifa)->sipx_addr;
+
+ if (ipx_nullhost(*ina))
+ ina->ipx_host =
+ *(union ipx_host *)(arp->ac_enaddr);
+ else
+ bcopy(ina->ipx_host.c_host,
+ arp->ac_enaddr, sizeof(arp->ac_enaddr));
+ break;
+ }
+#endif /* IPX */
+#ifdef NETATALK
+ case AF_APPLETALK:
+ /* Nothing to do. */
+ break;
+#endif /* NETATALK */
+#ifdef NS
+ /* XXX - This code is probably wrong. */
+ case AF_NS:
+ {
+ struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
+
+ if (ns_nullhost(*ina))
+ ina->x_host =
+ *(union ns_host *)(arp->ac_enaddr);
+ else
+ bcopy(ina->x_host.c_host,
+ arp->ac_enaddr, sizeof(arp->ac_enaddr));
+ break;
+ }
+#endif /* NS */
+ }
+ break;
+ default:
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * Ethernet output routine.
+ * Encapsulate a packet of type family for the local net.
+ * Assumes that ifp is actually pointer to arpcom structure.
+ */
+int
+ether_output(ifp, m0, dst, rt0)
+ register struct ifnet *ifp;
+ struct mbuf *m0;
+ struct sockaddr *dst;
+ struct rtentry *rt0;
+{
+ u_int16_t etype;
+ int s, error = 0;
+ u_char edst[6];
+ register struct mbuf *m = m0;
+ register struct rtentry *rt;
+ struct mbuf *mcopy = (struct mbuf *)0;
+ register struct ether_header *eh;
+ struct arpcom *ac = (struct arpcom *)ifp;
+
+ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ senderr(ENETDOWN);
+ ifp->if_lastchange = time;
+ if ((rt = rt0) != NULL) {
+ if ((rt->rt_flags & RTF_UP) == 0) {
+ if ((rt0 = rt = rtalloc1(dst, 1)) != NULL)
+ rt->rt_refcnt--;
+ else
+ senderr(EHOSTUNREACH);
+ }
+ if (rt->rt_flags & RTF_GATEWAY) {
+ if (rt->rt_gwroute == 0)
+ goto lookup;
+ if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
+ rtfree(rt); rt = rt0;
+ lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
+ if ((rt = rt->rt_gwroute) == 0)
+ senderr(EHOSTUNREACH);
+ }
+ }
+ if (rt->rt_flags & RTF_REJECT)
+ if (rt->rt_rmx.rmx_expire == 0 ||
+ time.tv_sec < rt->rt_rmx.rmx_expire)
+ senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
+ }
+ switch (dst->sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ if (!arpresolve(ac, rt, m, dst, edst))
+ return (0); /* if not yet resolved */
+ /* If broadcasting on a simplex interface, loopback a copy */
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
+ etype = htons(ETHERTYPE_IP);
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+#ifndef OLDIP6OUTPUT
+ if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
+ return(0); /* it must be impossible, but... */
+#else
+ if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst))
+ return(0); /* if not yet resolves */
+#endif
+ etype = htons(ETHERTYPE_IPV6);
+ break;
+#endif
+#ifdef NS
+ case AF_NS:
+ etype = htons(ETHERTYPE_NS);
+ bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
+ (caddr_t)edst, sizeof (edst));
+ if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
+ return (looutput(ifp, m, dst, rt));
+ /* If broadcasting on a simplex interface, loopback a copy */
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
+ break;
+#endif
+#ifdef IPX
+ case AF_IPX:
+ etype = htons(ETHERTYPE_IPX);
+ bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host,
+ (caddr_t)edst, sizeof (edst));
+ if (!bcmp((caddr_t)edst, (caddr_t)&ipx_thishost, sizeof(edst)))
+ return (looutput(ifp, m, dst, rt));
+ /* If broadcasting on a simplex interface, loopback a copy */
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
+ break;
+#endif
+#if 0 /*NRL INET6*/
+ case AF_INET6:
+ /*
+ * The bottom line here is to either queue the outgoing packet
+ * in the discovery engine, or fill in edst with something
+ * that'll work.
+ */
+ if (m->m_flags & M_MCAST) {
+ /*
+ * If multicast dest., then use IPv6 -> Ethernet
+ * mcast mapping. Really simple.
+ */
+ ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr,
+ edst);
+ } else {
+ /* Do unicast neighbor discovery stuff. */
+ if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
+ return 0;
+ }
+ etype = htons(ETHERTYPE_IPV6);
+ break;
+#endif /* INET6 */
+#ifdef NETATALK
+ case AF_APPLETALK: {
+ struct at_ifaddr *aa;
+
+ if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
+#ifdef NETATALKDEBUG
+ extern char *prsockaddr(struct sockaddr *);
+ printf("aarpresolv: failed for %s\n", prsockaddr(dst));
+#endif /* NETATALKDEBUG */
+ return (0);
+ }
+
+ /*
+ * ifaddr is the first thing in at_ifaddr
+ */
+ aa = (struct at_ifaddr *)at_ifawithnet(
+ (struct sockaddr_at *)dst,
+ ifp->if_addrlist.tqh_first);
+ if (aa == 0)
+ goto bad;
+
+ /*
+ * In the phase 2 case, we need to prepend an mbuf for the llc
+ * header. Since we must preserve the value of m, which is
+ * passed to us by value, we m_copy() the first mbuf,
+ * and use it for our llc header.
+ */
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+ struct llc llc;
+
+ /* XXX Really this should use netisr too */
+ M_PREPEND(m, AT_LLC_SIZE, M_WAIT);
+ /*
+ * FreeBSD doesn't count the LLC len in
+ * ifp->obytes, so they increment a length
+ * field here. We don't do this.
+ */
+ llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
+ llc.llc_control = LLC_UI;
+ bcopy(at_org_code, llc.llc_snap_org_code,
+ sizeof(at_org_code));
+ llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
+ bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE);
+ etype = htons(m->m_pkthdr.len);
+ } else {
+ etype = htons(ETHERTYPE_AT);
+ }
+ } break;
+#endif /* NETATALK */
+#ifdef ISO
+ case AF_ISO: {
+ int snpalen;
+ struct llc *l;
+ register struct sockaddr_dl *sdl;
+
+ if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
+ sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
+ bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
+ } else {
+ error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
+ (char *)edst, &snpalen);
+ if (error)
+ goto bad; /* Not Resolved */
+ }
+ /* If broadcasting on a simplex interface, loopback a copy */
+ if (*edst & 1)
+ m->m_flags |= (M_BCAST|M_MCAST);
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
+ (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
+ M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
+ if (mcopy) {
+ eh = mtod(mcopy, struct ether_header *);
+ bcopy(edst, eh->ether_dhost, sizeof (edst));
+ bcopy(ac->ac_enaddr, eh->ether_shost,
+ sizeof (edst));
+ }
+ }
+ M_PREPEND(m, 3, M_DONTWAIT);
+ if (m == NULL)
+ return (0);
+ etype = htons(m->m_pkthdr.len);
+ l = mtod(m, struct llc *);
+ l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
+ l->llc_control = LLC_UI;
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ETHER]) {
+ int i;
+ printf("unoutput: sending pkt to: ");
+ for (i=0; i<6; i++)
+ printf("%x ", edst[i] & 0xff);
+ printf("\n");
+ }
+#endif
+ } break;
+#endif /* ISO */
+/* case AF_NSAP: */
+ case AF_CCITT: {
+ register struct sockaddr_dl *sdl =
+ (struct sockaddr_dl *) rt -> rt_gateway;
+
+ if (sdl && sdl->sdl_family == AF_LINK
+ && sdl->sdl_alen > 0) {
+ bcopy(LLADDR(sdl), (char *)edst,
+ sizeof(edst));
+ } else goto bad; /* Not a link interface ? Funny ... */
+ if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
+ (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
+ M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
+ if (mcopy) {
+ eh = mtod(mcopy, struct ether_header *);
+ bcopy(edst, eh->ether_dhost, sizeof (edst));
+ bcopy(ac->ac_enaddr, eh->ether_shost,
+ sizeof (edst));
+ }
+ }
+ etype = htons(m->m_pkthdr.len);
+#ifdef LLC_DEBUG
+ {
+ int i;
+ register struct llc *l = mtod(m, struct llc *);
+
+ printf("ether_output: sending LLC2 pkt to: ");
+ for (i=0; i<6; i++)
+ printf("%x ", edst[i] & 0xff);
+ printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
+ m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
+ l->llc_control & 0xff);
+
+ }
+#endif /* LLC_DEBUG */
+ } break;
+
+ case AF_UNSPEC:
+ eh = (struct ether_header *)dst->sa_data;
+ bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
+ /* AF_UNSPEC doesn't swap the byte order of the ether_type. */
+ etype = eh->ether_type;
+ break;
+
+ default:
+#ifdef __ECOS
+// diag_printf("%s: can't handle af%d\n", ifp->if_xname,
+// dst->sa_family);
+#else
+ printf("%s: can't handle af%d\n", ifp->if_xname,
+ dst->sa_family);
+#endif
+ senderr(EAFNOSUPPORT);
+ }
+
+ if (mcopy)
+ (void) looutput(ifp, mcopy, dst, rt);
+
+ /*
+ * Add local net header. If no space in first mbuf,
+ * allocate another.
+ */
+ M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
+ if (m == 0)
+ senderr(ENOBUFS);
+ eh = mtod(m, struct ether_header *);
+ bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
+ sizeof(eh->ether_type));
+ bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
+ sizeof(eh->ether_shost));
+
+#if NBRIDGE > 0
+ /*
+ * Interfaces that are bridge members need special handling
+ * for output.
+ */
+ if (ifp->if_bridge) {
+ bridge_output(ifp, m, NULL, NULL);
+ return (error);
+ }
+#endif
+
+ s = splimp();
+ /*
+ * Queue message on interface, and start output if interface
+ * not yet active.
+ */
+ if (IF_QFULL(&ifp->if_snd)) {
+ // Let the interface try a dequeue anyway, in case the
+ // interface has "got better" from whatever made the queue
+ // fill up - being unplugged for example.
+ if ((ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ IF_DROP(&ifp->if_snd);
+ splx(s);
+ senderr(ENOBUFS);
+ }
+ ifp->if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&ifp->if_snd, m);
+ if (m->m_flags & M_MCAST)
+ ifp->if_omcasts++;
+ if ((ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ splx(s);
+ return (error);
+
+bad:
+ if (m)
+ m_freem(m);
+ return (error);
+}
+
+/*
+ * Process a received Ethernet packet;
+ * the packet is in the mbuf chain m without
+ * the ether header, which is provided separately.
+ */
+void
+ether_input(ifp, eh, m)
+ struct ifnet *ifp;
+ register struct ether_header *eh;
+ struct mbuf *m;
+{
+ register struct ifqueue *inq;
+ u_int16_t etype;
+ int s, llcfound = 0;
+ register struct llc *l;
+ struct arpcom *ac = (struct arpcom *)ifp;
+#ifdef __ECOS
+ unsigned int sched_what;
+#endif
+
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ m_freem(m);
+ return;
+ }
+ ifp->if_lastchange = time;
+ ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
+ if (eh->ether_dhost[0] & 1) {
+ if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
+ sizeof(etherbroadcastaddr)) == 0)
+ m->m_flags |= M_BCAST;
+ else
+ m->m_flags |= M_MCAST;
+ }
+ if (m->m_flags & (M_BCAST|M_MCAST))
+ ifp->if_imcasts++;
+
+#if NBRIDGE > 0
+ /*
+ * Tap the packet off here for a bridge, if configured and
+ * active for this interface. bridge_input returns
+ * NULL if it has consumed the packet, otherwise, it
+ * gets processed as normal.
+ */
+ if (ifp->if_bridge) {
+ m = bridge_input(ifp, eh, m);
+ if (m == NULL)
+ return;
+ /* The bridge has determined it's for us. */
+ goto decapsulate;
+ }
+#endif
+ /*
+ * If packet is unicast and we're in promiscuous mode, make sure it
+ * is for us. Drop otherwise.
+ */
+ if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
+ (ifp->if_flags & IFF_PROMISC)) {
+ if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
+ ETHER_ADDR_LEN)) {
+ m_freem(m);
+ return;
+ }
+ }
+
+decapsulate:
+ etype = ntohs(eh->ether_type);
+ switch (etype) {
+#ifdef INET
+ case ETHERTYPE_IP:
+#ifdef __ECOS
+ sched_what = NETISR_IP;
+#else
+ schednetisr(NETISR_IP);
+#endif
+ inq = &ipintrq;
+ break;
+
+ case ETHERTYPE_ARP:
+ if (ifp->if_flags & IFF_NOARP)
+ goto dropanyway;
+#ifdef __ECOS
+ sched_what = NETISR_ARP;
+#else
+ schednetisr(NETISR_ARP);
+#endif
+ inq = &arpintrq;
+ break;
+
+ case ETHERTYPE_REVARP:
+ if (ifp->if_flags & IFF_NOARP)
+ goto dropanyway;
+ revarpinput(m); /* XXX queue? */
+ return;
+
+#endif
+#ifdef INET6
+ /*
+ * Schedule IPv6 software interrupt for incoming IPv6 packet.
+ */
+ case ETHERTYPE_IPV6:
+#ifdef __ECOS
+ sched_what = NETISR_IPV6;
+#else
+ schednetisr(NETISR_IPV6);
+#endif
+ inq = &ip6intrq;
+ break;
+#endif /* INET6 */
+#ifdef IPX
+ case ETHERTYPE_IPX:
+#ifdef __ECOS
+ sched_what = NETISR_IPX;
+#else
+ schednetisr(NETISR_IPX);
+#endif
+ inq = &ipxintrq;
+ break;
+#endif
+#ifdef NS
+ case ETHERTYPE_NS:
+#ifdef __ECOS
+ sched_what = NETISR_NS;
+#else
+ schednetisr(NETISR_NS);
+#endif
+ inq = &nsintrq;
+ break;
+#endif
+#ifdef NETATALK
+ case ETHERTYPE_AT:
+#ifdef __ECOS
+ sched_what = NETISR_ATALK;
+#else
+ schednetisr(NETISR_ATALK);
+#endif
+ inq = &atintrq1;
+ break;
+ case ETHERTYPE_AARP:
+ /* probably this should be done with a NETISR as well */
+ /* XXX queue this */
+ aarpinput((struct arpcom *)ifp, m);
+ return;
+#endif
+ default:
+ if (llcfound || etype > ETHERMTU)
+ goto dropanyway;
+ llcfound = 1;
+ l = mtod(m, struct llc *);
+ switch (l->llc_dsap) {
+ case LLC_SNAP_LSAP:
+#ifdef NETATALK
+ /*
+ * Some protocols (like Appletalk) need special
+ * handling depending on if they are type II
+ * or SNAP encapsulated. Everything else
+ * gets handled by stripping off the SNAP header
+ * and going back up to decapsulate.
+ */
+ if (l->llc_control == LLC_UI &&
+ l->llc_ssap == LLC_SNAP_LSAP &&
+ Bcmp(&(l->llc_snap_org_code)[0],
+ at_org_code, sizeof(at_org_code)) == 0 &&
+ ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
+ inq = &atintrq2;
+ m_adj(m, AT_LLC_SIZE);
+#ifdef __ECOS
+ sched_what = NETISR_ATALK;
+#else
+ schednetisr(NETISR_ATALK);
+#endif
+ break;
+ }
+
+ if (l->llc_control == LLC_UI &&
+ l->llc_ssap == LLC_SNAP_LSAP &&
+ Bcmp(&(l->llc_snap_org_code)[0],
+ aarp_org_code, sizeof(aarp_org_code)) == 0 &&
+ ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
+ m_adj(m, AT_LLC_SIZE);
+ /* XXX Really this should use netisr too */
+ aarpinput((struct arpcom *)ifp, m);
+ return;
+ }
+#endif /* NETATALK */
+ if (l->llc_control == LLC_UI &&
+ l->llc_dsap == LLC_SNAP_LSAP &&
+ l->llc_ssap == LLC_SNAP_LSAP) {
+ /* SNAP */
+ if (m->m_pkthdr.len > etype)
+ m_adj(m, etype - m->m_pkthdr.len);
+ m->m_data += 6; /* XXX */
+ m->m_len -= 6; /* XXX */
+ m->m_pkthdr.len -= 6; /* XXX */
+ M_PREPEND(m, sizeof *eh, M_DONTWAIT);
+ if (m == 0)
+ return;
+ *mtod(m, struct ether_header *) = *eh;
+ goto decapsulate;
+ }
+ goto dropanyway;
+#ifdef ISO
+ case LLC_ISO_LSAP:
+ switch (l->llc_control) {
+ case LLC_UI:
+ /* LLC_UI_P forbidden in class 1 service */
+ if ((l->llc_dsap == LLC_ISO_LSAP) &&
+ (l->llc_ssap == LLC_ISO_LSAP)) {
+ /* LSAP for ISO */
+ if (m->m_pkthdr.len > etype)
+ m_adj(m, etype - m->m_pkthdr.len);
+ m->m_data += 3; /* XXX */
+ m->m_len -= 3; /* XXX */
+ m->m_pkthdr.len -= 3; /* XXX */
+ M_PREPEND(m, sizeof *eh, M_DONTWAIT);
+ if (m == 0)
+ return;
+ *mtod(m, struct ether_header *) = *eh;
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ETHER])
+ printf("clnp packet");
+#endif
+#ifdef __ECOS
+ sched_what = NETISR_ISO;
+#else
+ schednetisr(NETISR_ISO);
+#endif
+ inq = &clnlintrq;
+ break;
+ }
+ goto dropanyway;
+
+ case LLC_XID:
+ case LLC_XID_P:
+ if(m->m_len < 6)
+ goto dropanyway;
+ l->llc_window = 0;
+ l->llc_fid = 9;
+ l->llc_class = 1;
+ l->llc_dsap = l->llc_ssap = 0;
+ /* Fall through to */
+ case LLC_TEST:
+ case LLC_TEST_P:
+ {
+ struct sockaddr sa;
+ register struct ether_header *eh2;
+ int i;
+ u_char c = l->llc_dsap;
+
+ l->llc_dsap = l->llc_ssap;
+ l->llc_ssap = c;
+ if (m->m_flags & (M_BCAST | M_MCAST))
+ bcopy(ac->ac_enaddr,
+ eh->ether_dhost, 6);
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ eh2 = (struct ether_header *)sa.sa_data;
+ for (i = 0; i < 6; i++) {
+ eh2->ether_shost[i] = c = eh->ether_dhost[i];
+ eh2->ether_dhost[i] =
+ eh->ether_dhost[i] = eh->ether_shost[i];
+ eh->ether_shost[i] = c;
+ }
+ ifp->if_output(ifp, m, &sa, NULL);
+ return;
+ }
+ break;
+ }
+#endif /* ISO */
+#ifdef CCITT
+ case LLC_X25_LSAP:
+ if (m->m_pkthdr.len > etype)
+ m_adj(m, etype - m->m_pkthdr.len);
+ M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
+ if (m == 0)
+ return;
+ if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
+ eh->ether_dhost, LLC_X25_LSAP, 6,
+ mtod(m, struct sdl_hdr *)))
+ panic("ETHER cons addr failure");
+ mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
+#ifdef LLC_DEBUG
+ printf("llc packet\n");
+#endif /* LLC_DEBUG */
+#ifdef __ECOS
+ sched_what = NETISR_CCITT;
+#else
+ schednetisr(NETISR_CCITT);
+#endif
+ inq = &llcintrq;
+ break;
+#endif /* CCITT */
+ dropanyway:
+ default:
+ m_freem(m);
+ return;
+ }
+ }
+
+ s = splimp();
+ if (IF_QFULL(inq)) {
+ IF_DROP(inq);
+ m_freem(m);
+ } else
+ IF_ENQUEUE(inq, m);
+ splx(s);
+#ifdef __ECOS
+ schednetisr(sched_what);
+#endif
+}
+
+/*
+ * Convert Ethernet address to printable (loggable) representation.
+ */
+static char digits[] = "0123456789abcdef";
+char *
+ether_sprintf(ap)
+ register u_char *ap;
+{
+ register int i;
+ static char etherbuf[18];
+ register char *cp = etherbuf;
+
+ for (i = 0; i < 6; i++) {
+ *cp++ = digits[*ap >> 4];
+ *cp++ = digits[*ap++ & 0xf];
+ *cp++ = ':';
+ }
+ *--cp = 0;
+ return (etherbuf);
+}
+
+/*
+ * Perform common duties while attaching to interface list
+ */
+void
+ether_ifattach(ifp)
+ register struct ifnet *ifp;
+{
+ register struct ifaddr *ifa;
+ register struct sockaddr_dl *sdl;
+
+ ifp->if_type = IFT_ETHER;
+ ifp->if_addrlen = 6;
+ ifp->if_hdrlen = 14;
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_output = ether_output;
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
+ ifa = ifa->ifa_list.tqe_next)
+ if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
+ sdl->sdl_family == AF_LINK) {
+ sdl->sdl_type = IFT_ETHER;
+ sdl->sdl_alen = ifp->if_addrlen;
+ bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
+ LLADDR(sdl), ifp->if_addrlen);
+ break;
+ }
+ LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
+}
+
+void
+ether_ifdetach(ifp)
+ struct ifnet *ifp;
+{
+ struct arpcom *ac = (struct arpcom *)ifp;
+ struct ether_multi *enm;
+
+ for (enm = LIST_FIRST(&ac->ac_multiaddrs); enm;
+ enm = LIST_FIRST(&ac->ac_multiaddrs)) {
+ LIST_REMOVE(enm, enm_list);
+ free(enm, M_IFMADDR);
+ }
+}
+
+u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
+u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
+
+#ifdef INET6
+u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
+u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
+#endif
+
+/*
+ * Add an Ethernet multicast address or range of addresses to the list for a
+ * given interface.
+ */
+int
+ether_addmulti(ifr, ac)
+ struct ifreq *ifr;
+ register struct arpcom *ac;
+{
+ register struct ether_multi *enm;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif /* INET6 */
+ u_char addrlo[6];
+ u_char addrhi[6];
+ int s = splimp();
+
+ switch (ifr->ifr_addr.sa_family) {
+
+ case AF_UNSPEC:
+ bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
+ bcopy(addrlo, addrhi, 6);
+ break;
+
+#ifdef INET
+ case AF_INET:
+ sin = (struct sockaddr_in *)&(ifr->ifr_addr);
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ /*
+ * An IP address of INADDR_ANY means listen to all
+ * of the Ethernet multicast addresses used for IP.
+ * (This is for the sake of IP multicast routers.)
+ */
+ bcopy(ether_ipmulticast_min, addrlo, 6);
+ bcopy(ether_ipmulticast_max, addrhi, 6);
+ }
+ else {
+ ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
+ bcopy(addrlo, addrhi, 6);
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)
+ &(((struct in6_ifreq *)ifr)->ifr_addr);
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * An unspecified IPv6 address means listen to all
+ * of the IPv6 multicast addresses on this Ethernet.
+ * (Multicast routers like this.)
+ */
+ bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
+ bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
+ } else {
+ ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ }
+ break;
+#endif /* INET6 */
+
+ default:
+ splx(s);
+ return (EAFNOSUPPORT);
+ }
+
+ /*
+ * Verify that we have valid Ethernet multicast addresses.
+ */
+ if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
+ splx(s);
+ return (EINVAL);
+ }
+ /*
+ * See if the address range is already in the list.
+ */
+ ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
+ if (enm != NULL) {
+ /*
+ * Found it; just increment the reference count.
+ */
+ ++enm->enm_refcount;
+ splx(s);
+ return (0);
+ }
+ /*
+ * New address or range; malloc a new multicast record
+ * and link it into the interface's multicast list.
+ */
+ enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
+ if (enm == NULL) {
+ splx(s);
+ return (ENOBUFS);
+ }
+ bcopy(addrlo, enm->enm_addrlo, 6);
+ bcopy(addrhi, enm->enm_addrhi, 6);
+ enm->enm_ac = ac;
+ enm->enm_refcount = 1;
+ LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
+ ac->ac_multicnt++;
+ splx(s);
+ /*
+ * Return ENETRESET to inform the driver that the list has changed
+ * and its reception filter should be adjusted accordingly.
+ */
+ return (ENETRESET);
+}
+
+/*
+ * Delete a multicast address record.
+ */
+int
+ether_delmulti(ifr, ac)
+ struct ifreq *ifr;
+ register struct arpcom *ac;
+{
+ register struct ether_multi *enm;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif /* INET6 */
+ u_char addrlo[6];
+ u_char addrhi[6];
+ int s = splimp();
+
+ switch (ifr->ifr_addr.sa_family) {
+
+ case AF_UNSPEC:
+ bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
+ bcopy(addrlo, addrhi, 6);
+ break;
+
+#ifdef INET
+ case AF_INET:
+ sin = (struct sockaddr_in *)&(ifr->ifr_addr);
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ /*
+ * An IP address of INADDR_ANY means stop listening
+ * to the range of Ethernet multicast addresses used
+ * for IP.
+ */
+ bcopy(ether_ipmulticast_min, addrlo, 6);
+ bcopy(ether_ipmulticast_max, addrhi, 6);
+ }
+ else {
+ ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
+ bcopy(addrlo, addrhi, 6);
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * An unspecified IPv6 address means stop listening to
+ * all IPv6 multicast addresses on this Ethernet.'
+ *
+ * (This might not be healthy, given IPv6's reliance on
+ * multicast for things like neighbor discovery.
+ * Perhaps initializing all-nodes, solicited nodes, and
+ * possibly all-routers for this interface afterwards
+ * is not a bad idea.)
+ */
+ bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
+ bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
+ } else {
+ ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ }
+ break;
+#endif /* INET6 */
+
+ default:
+ splx(s);
+ return (EAFNOSUPPORT);
+ }
+
+ /*
+ * Look up the address in our list.
+ */
+ ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
+ if (enm == NULL) {
+ splx(s);
+ return (ENXIO);
+ }
+ if (--enm->enm_refcount != 0) {
+ /*
+ * Still some claims to this record.
+ */
+ splx(s);
+ return (0);
+ }
+ /*
+ * No remaining claims to this record; unlink and free it.
+ */
+ LIST_REMOVE(enm, enm_list);
+ free(enm, M_IFMADDR);
+ ac->ac_multicnt--;
+ splx(s);
+ /*
+ * Return ENETRESET to inform the driver that the list has changed
+ * and its reception filter should be adjusted accordingly.
+ */
+ return (ENETRESET);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/if_loop.c b/ecos/packages/net/tcpip/current/src/sys/net/if_loop.c
new file mode 100644
index 0000000..7929f42
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/if_loop.c
@@ -0,0 +1,446 @@
+//==========================================================================
+//
+// sys/net/if_loop.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_loop.c,v 1.12 1999/12/08 06:50:18 itojun Exp $ */
+/* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_loop.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+/*
+ * Loopback interface driver for protocol testing and timing.
+ */
+
+#ifndef __ECOS
+#include "bpfilter.h"
+#include "loop.h"
+#endif
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <machine/cpu.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/netisr.h>
+#include <net/route.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <netinet6/in6_var.h>
+#include <netinet6/ip6.h>
+#endif
+
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+#endif
+
+#ifdef ISO
+#include <netiso/iso.h>
+#include <netiso/iso_var.h>
+#endif
+
+#ifdef NETATALK
+#include <netinet/if_ether.h>
+#include <netatalk/at.h>
+#include <netatalk/at_var.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#if defined(LARGE_LOMTU)
+#define LOMTU (131072 + MHLEN + MLEN)
+#else
+#define LOMTU (32768 + MHLEN + MLEN)
+#endif
+
+#ifndef __ECOS
+#include <stdio.h> // for 'sprintf()'
+#endif
+
+struct ifnet loif[NLOOP];
+
+void
+loopattach(n)
+ int n;
+{
+ register int i;
+ register struct ifnet *ifp;
+
+ for (i = NLOOP; i--; ) {
+ ifp = &loif[i];
+#if !defined(__ECOS) || (CYGPKG_NET_NLOOP > 1)
+ sprintf(ifp->if_xname, "lo%d", i);
+#else
+ strcpy(ifp->if_xname, "lo0");
+#endif
+ ifp->if_softc = NULL;
+ ifp->if_mtu = LOMTU;
+ ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
+ ifp->if_ioctl = loioctl;
+ ifp->if_output = looutput;
+ ifp->if_type = IFT_LOOP;
+ ifp->if_hdrlen = sizeof(u_int32_t);
+ ifp->if_addrlen = 0;
+ if_attachhead(ifp);
+#if NBPFILTER > 0
+ bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
+#endif
+ }
+}
+
+int
+looutput(ifp, m, dst, rt)
+ struct ifnet *ifp;
+ register struct mbuf *m;
+ struct sockaddr *dst;
+ register struct rtentry *rt;
+{
+ int s, isr;
+ register struct ifqueue *ifq = 0;
+
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("looutput: no header mbuf");
+ ifp->if_lastchange = time;
+#if NBPFILTER > 0
+ /*
+ * only send packets to bpf if they are real loopback packets;
+ * looutput() is also called for SIMPLEX interfaces to duplicate
+ * packets for local use. But don't dup them to bpf.
+ */
+ if (ifp->if_bpf && (ifp->if_flags&IFF_LOOPBACK)) {
+ /*
+ * We need to prepend the address family as
+ * a four byte field. Cons up a dummy header
+ * to pacify bpf. This is safe because bpf
+ * will only read from the mbuf (i.e., it won't
+ * try to free it or keep a pointer to it).
+ */
+ struct mbuf m0;
+ u_int32_t af = htonl(dst->sa_family);
+
+ m0.m_next = m;
+ m0.m_len = sizeof(af);
+ m0.m_data = (char *)&af;
+
+ bpf_mtap(ifp->if_bpf, &m0);
+ }
+#endif
+ m->m_pkthdr.rcvif = ifp;
+
+ if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ m_freem(m);
+ return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+ rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ }
+
+#ifndef PULLDOWN_TEST
+ /*
+ * KAME requires that the packet to be contiguous on the
+ * mbuf. We need to make that sure.
+ * this kind of code should be avoided.
+ * XXX other conditions to avoid running this part?
+ */
+ if (m && m->m_next != NULL) {
+ struct mbuf *n;
+
+ MGETHDR(n, M_DONTWAIT, MT_HEADER);
+ if (n) {
+ MCLGET(n, M_DONTWAIT);
+ if ((n->m_flags & M_EXT) == 0) {
+ m_free(n);
+ n = NULL;
+ }
+ }
+ if (!n) {
+#ifdef __ECOS
+ diag_printf("looutput: mbuf allocation failed\n");
+#else
+ printf("looutput: mbuf allocation failed\n");
+#endif
+ m_freem(m);
+ return ENOBUFS;
+ }
+
+ n->m_pkthdr.rcvif = m->m_pkthdr.rcvif;
+ n->m_pkthdr.len = m->m_pkthdr.len;
+ if (m->m_pkthdr.len <= MCLBYTES) {
+ m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
+ n->m_len = m->m_pkthdr.len;
+ m_freem(m);
+ } else {
+ m_copydata(m, 0, MCLBYTES, mtod(n, caddr_t));
+ m_adj(m, MCLBYTES);
+ n->m_len = MCLBYTES;
+ n->m_next = m;
+ m->m_flags &= ~M_PKTHDR;
+ }
+ m = n;
+ }
+#if 0
+ if (m && m->m_next != NULL) {
+ printf("loop: not contiguous...\n");
+ m_freem(m);
+ return ENOBUFS;
+ }
+#endif
+#endif
+
+ ifp->if_opackets++;
+ ifp->if_obytes += m->m_pkthdr.len;
+ switch (dst->sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ ifq = &ipintrq;
+ isr = NETISR_IP;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ ifq = &ip6intrq;
+ isr = NETISR_IPV6;
+ break;
+#endif /* INET6 */
+#ifdef NS
+ case AF_NS:
+ ifq = &nsintrq;
+ isr = NETISR_NS;
+ break;
+#endif
+#ifdef IPX
+ case AF_IPX:
+ ifq = &ipxintrq;
+ isr = NETISR_IPX;
+ break;
+#endif
+#ifdef ISO
+ case AF_ISO:
+ ifq = &clnlintrq;
+ isr = NETISR_ISO;
+ break;
+#endif
+#ifdef NETATALK
+ case AF_APPLETALK:
+ ifq = &atintrq2;
+ isr = NETISR_ATALK;
+ break;
+#endif
+ default:
+#ifdef __ECOS
+ diag_printf("%s: can't handle af%d\n", ifp->if_xname,
+ dst->sa_family);
+#else
+ printf("%s: can't handle af%d\n", ifp->if_xname,
+ dst->sa_family);
+#endif
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+ s = splimp();
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ m_freem(m);
+ splx(s);
+ return (ENOBUFS);
+ }
+ IF_ENQUEUE(ifq, m);
+ schednetisr(isr);
+ ifp->if_ipackets++;
+ ifp->if_ibytes += m->m_pkthdr.len;
+ splx(s);
+ return (0);
+}
+
+/* ARGSUSED */
+void
+lortrequest(cmd, rt, sa)
+ int cmd;
+ struct rtentry *rt;
+ struct sockaddr *sa;
+{
+
+ if (rt)
+ rt->rt_rmx.rmx_mtu = LOMTU;
+}
+
+/*
+ * Process an ioctl request.
+ */
+/* ARGSUSED */
+int
+loioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+ register struct ifaddr *ifa;
+ register struct ifreq *ifr;
+ register int error = 0;
+
+ switch (cmd) {
+
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+ ifa = (struct ifaddr *)data;
+ if (ifa != 0 /*&& ifa->ifa_addr->sa_family == AF_ISO*/)
+ ifa->ifa_rtrequest = lortrequest;
+ /*
+ * Everything else is done at a higher level.
+ */
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ ifr = (struct ifreq *)data;
+ if (ifr == 0) {
+ error = EAFNOSUPPORT; /* XXX */
+ break;
+ }
+ switch (ifr->ifr_addr.sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif /* INET6 */
+
+ default:
+ error = EAFNOSUPPORT;
+ break;
+ }
+ break;
+
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/radix.c b/ecos/packages/net/tcpip/current/src/sys/net/radix.c
new file mode 100644
index 0000000..04f20d5
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/radix.c
@@ -0,0 +1,965 @@
+//==========================================================================
+//
+// sys/net/radix.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: radix.c,v 1.4 1996/09/05 08:42:32 mickey Exp $ */
+/* $NetBSD: radix.c,v 1.11 1996/03/16 23:55:36 christos Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)radix.c 8.4 (Berkeley) 11/2/94
+ */
+
+/*
+ * Routines to build and maintain radix trees for routing lookups.
+ */
+#include <sys/param.h>
+#ifdef _KERNEL
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/syslog.h>
+#endif
+#include <sys/malloc.h>
+#define M_DONTWAIT M_NOWAIT
+#include <sys/domain.h>
+#else
+#include <stdlib.h>
+#endif
+#include <net/radix.h>
+
+int max_keylen;
+struct radix_mask *rn_mkfreelist;
+struct radix_node_head *mask_rnhead;
+static char *addmask_key;
+static char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, -1};
+static char *rn_zeros, *rn_ones;
+
+#define rn_masktop (mask_rnhead->rnh_treetop)
+#undef Bcmp
+#define Bcmp(a, b, l) (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l))
+
+
+static int rn_satsifies_leaf __P((char *, struct radix_node *, int));
+static int rn_lexobetter __P((void *, void *));
+static struct radix_mask *rn_new_radix_mask __P((struct radix_node *,
+ struct radix_mask *));
+/*
+ * The data structure for the keys is a radix tree with one way
+ * branching removed. The index rn_b at an internal node n represents a bit
+ * position to be tested. The tree is arranged so that all descendants
+ * of a node n have keys whose bits all agree up to position rn_b - 1.
+ * (We say the index of n is rn_b.)
+ *
+ * There is at least one descendant which has a one bit at position rn_b,
+ * and at least one with a zero there.
+ *
+ * A route is determined by a pair of key and mask. We require that the
+ * bit-wise logical and of the key and mask to be the key.
+ * We define the index of a route to associated with the mask to be
+ * the first bit number in the mask where 0 occurs (with bit number 0
+ * representing the highest order bit).
+ *
+ * We say a mask is normal if every bit is 0, past the index of the mask.
+ * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b,
+ * and m is a normal mask, then the route applies to every descendant of n.
+ * If the index(m) < rn_b, this implies the trailing last few bits of k
+ * before bit b are all 0, (and hence consequently true of every descendant
+ * of n), so the route applies to all descendants of the node as well.
+ *
+ * Similar logic shows that a non-normal mask m such that
+ * index(m) <= index(n) could potentially apply to many children of n.
+ * Thus, for each non-host route, we attach its mask to a list at an internal
+ * node as high in the tree as we can go.
+ *
+ * The present version of the code makes use of normal routes in short-
+ * circuiting an explict mask and compare operation when testing whether
+ * a key satisfies a normal route, and also in remembering the unique leaf
+ * that governs a subtree.
+ */
+
+struct radix_node *
+rn_search(v_arg, head)
+ void *v_arg;
+ struct radix_node *head;
+{
+ register struct radix_node *x;
+ register caddr_t v;
+
+ for (x = head, v = v_arg; x->rn_b >= 0;) {
+ if (x->rn_bmask & v[x->rn_off])
+ x = x->rn_r;
+ else
+ x = x->rn_l;
+ }
+ return (x);
+}
+
+struct radix_node *
+rn_search_m(v_arg, head, m_arg)
+ struct radix_node *head;
+ void *v_arg, *m_arg;
+{
+ register struct radix_node *x;
+ register caddr_t v = v_arg, m = m_arg;
+
+ for (x = head; x->rn_b >= 0;) {
+ if ((x->rn_bmask & m[x->rn_off]) &&
+ (x->rn_bmask & v[x->rn_off]))
+ x = x->rn_r;
+ else
+ x = x->rn_l;
+ }
+ return x;
+}
+
+int
+rn_refines(m_arg, n_arg)
+ void *m_arg, *n_arg;
+{
+ register caddr_t m = m_arg, n = n_arg;
+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
+ int masks_are_equal = 1;
+
+ if (longer > 0)
+ lim -= longer;
+ while (n < lim) {
+ if (*n & ~(*m))
+ return 0;
+ if (*n++ != *m++)
+ masks_are_equal = 0;
+ }
+ while (n < lim2)
+ if (*n++)
+ return 0;
+ if (masks_are_equal && (longer < 0))
+ for (lim2 = m - longer; m < lim2; )
+ if (*m++)
+ return 1;
+ return (!masks_are_equal);
+}
+
+struct radix_node *
+rn_lookup(v_arg, m_arg, head)
+ void *v_arg, *m_arg;
+ struct radix_node_head *head;
+{
+ register struct radix_node *x;
+ caddr_t netmask = 0;
+
+ if (m_arg) {
+ if ((x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_off)) == 0)
+ return (0);
+ netmask = x->rn_key;
+ }
+ x = rn_match(v_arg, head);
+ if (x && netmask) {
+ while (x && x->rn_mask != netmask)
+ x = x->rn_dupedkey;
+ }
+ return x;
+}
+
+static int
+rn_satsifies_leaf(trial, leaf, skip)
+ char *trial;
+ register struct radix_node *leaf;
+ int skip;
+{
+ register char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask;
+ char *cplim;
+ int length = min(*(u_char *)cp, *(u_char *)cp2);
+
+ if (cp3 == 0)
+ cp3 = rn_ones;
+ else
+ length = min(length, *(u_char *)cp3);
+ cplim = cp + length; cp3 += skip; cp2 += skip;
+ for (cp += skip; cp < cplim; cp++, cp2++, cp3++)
+ if ((*cp ^ *cp2) & *cp3)
+ return 0;
+ return 1;
+}
+
+struct radix_node *
+rn_match(v_arg, head)
+ void *v_arg;
+ struct radix_node_head *head;
+{
+ caddr_t v = v_arg;
+ register struct radix_node *t = head->rnh_treetop, *x;
+ register caddr_t cp = v, cp2;
+ caddr_t cplim;
+ struct radix_node *saved_t, *top = t;
+ int off = t->rn_off, vlen = *(u_char *)cp, matched_off;
+ register int test, b, rn_b;
+
+ /*
+ * Open code rn_search(v, top) to avoid overhead of extra
+ * subroutine call.
+ */
+ for (; t->rn_b >= 0; ) {
+ if (t->rn_bmask & cp[t->rn_off])
+ t = t->rn_r;
+ else
+ t = t->rn_l;
+ }
+ /*
+ * See if we match exactly as a host destination
+ * or at least learn how many bits match, for normal mask finesse.
+ *
+ * It doesn't hurt us to limit how many bytes to check
+ * to the length of the mask, since if it matches we had a genuine
+ * match and the leaf we have is the most specific one anyway;
+ * if it didn't match with a shorter length it would fail
+ * with a long one. This wins big for class B&C netmasks which
+ * are probably the most common case...
+ */
+ if (t->rn_mask)
+ vlen = *(u_char *)t->rn_mask;
+ cp += off; cp2 = t->rn_key + off; cplim = v + vlen;
+ for (; cp < cplim; cp++, cp2++)
+ if (*cp != *cp2)
+ goto on1;
+ /*
+ * This extra grot is in case we are explicitly asked
+ * to look up the default. Ugh!
+ */
+ if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey)
+ t = t->rn_dupedkey;
+ return t;
+on1:
+ test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */
+ for (b = 7; (test >>= 1) > 0;)
+ b--;
+ matched_off = cp - v;
+ b += matched_off << 3;
+ rn_b = -1 - b;
+ /*
+ * If there is a host route in a duped-key chain, it will be first.
+ */
+ if ((saved_t = t)->rn_mask == 0)
+ t = t->rn_dupedkey;
+ for (; t; t = t->rn_dupedkey)
+ /*
+ * Even if we don't match exactly as a host,
+ * we may match if the leaf we wound up at is
+ * a route to a net.
+ */
+ if (t->rn_flags & RNF_NORMAL) {
+ if (rn_b <= t->rn_b)
+ return t;
+ } else if (rn_satsifies_leaf(v, t, matched_off))
+ return t;
+ t = saved_t;
+ /* start searching up the tree */
+ do {
+ register struct radix_mask *m;
+ t = t->rn_p;
+ if ((m = t->rn_mklist) != NULL) {
+ /*
+ * If non-contiguous masks ever become important
+ * we can restore the masking and open coding of
+ * the search and satisfaction test and put the
+ * calculation of "off" back before the "do".
+ */
+ do {
+ if (m->rm_flags & RNF_NORMAL) {
+ if (rn_b <= m->rm_b)
+ return (m->rm_leaf);
+ } else {
+ off = min(t->rn_off, matched_off);
+ x = rn_search_m(v, t, m->rm_mask);
+ while (x && x->rn_mask != m->rm_mask)
+ x = x->rn_dupedkey;
+ if (x && rn_satsifies_leaf(v, x, off))
+ return x;
+ }
+ } while ((m = m->rm_mklist) != NULL);
+ }
+ } while (t != top);
+ return 0;
+}
+
+#ifdef RN_DEBUG
+int rn_nodenum;
+struct radix_node *rn_clist;
+int rn_saveinfo;
+int rn_debug = 1;
+#endif
+
+struct radix_node *
+rn_newpair(v, b, nodes)
+ void *v;
+ int b;
+ struct radix_node nodes[2];
+{
+ register struct radix_node *tt = nodes, *t = tt + 1;
+ t->rn_b = b; t->rn_bmask = 0x80 >> (b & 7);
+ t->rn_l = tt; t->rn_off = b >> 3;
+ tt->rn_b = -1; tt->rn_key = (caddr_t)v; tt->rn_p = t;
+ tt->rn_flags = t->rn_flags = RNF_ACTIVE;
+#ifdef RN_DEBUG
+ tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
+ tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
+#endif
+ return t;
+}
+
+struct radix_node *
+rn_insert(v_arg, head, dupentry, nodes)
+ void *v_arg;
+ struct radix_node_head *head;
+ int *dupentry;
+ struct radix_node nodes[2];
+{
+ caddr_t v = v_arg;
+ struct radix_node *top = head->rnh_treetop;
+ int head_off = top->rn_off, vlen = (int)*((u_char *)v);
+ register struct radix_node *t = rn_search(v_arg, top);
+ register caddr_t cp = v + head_off;
+ register int b;
+ struct radix_node *tt;
+ /*
+ * Find first bit at which v and t->rn_key differ
+ */
+ {
+ register caddr_t cp2 = t->rn_key + head_off;
+ register int cmp_res;
+ caddr_t cplim = v + vlen;
+
+ while (cp < cplim)
+ if (*cp2++ != *cp++)
+ goto on1;
+ *dupentry = 1;
+ return t;
+on1:
+ *dupentry = 0;
+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
+ for (b = (cp - v) << 3; cmp_res; b--)
+ cmp_res >>= 1;
+ }
+ {
+ register struct radix_node *p, *x = top;
+ cp = v;
+ do {
+ p = x;
+ if (cp[x->rn_off] & x->rn_bmask)
+ x = x->rn_r;
+ else x = x->rn_l;
+ } while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */
+#ifdef __ECOS
+#else
+#ifdef RN_DEBUG
+ if (rn_debug)
+ log(LOG_DEBUG, "rn_insert: Going In:\n"), traverse(p);
+#endif
+#endif
+ t = rn_newpair(v_arg, b, nodes); tt = t->rn_l;
+ if ((cp[p->rn_off] & p->rn_bmask) == 0)
+ p->rn_l = t;
+ else
+ p->rn_r = t;
+ x->rn_p = t; t->rn_p = p; /* frees x, p as temp vars below */
+ if ((cp[t->rn_off] & t->rn_bmask) == 0) {
+ t->rn_r = x;
+ } else {
+ t->rn_r = tt; t->rn_l = x;
+ }
+#ifdef __ECOS
+#else
+#ifdef RN_DEBUG
+ if (rn_debug)
+ log(LOG_DEBUG, "rn_insert: Coming Out:\n"), traverse(p);
+#endif
+#endif
+ }
+ return (tt);
+}
+
+struct radix_node *
+rn_addmask(n_arg, search, skip)
+ int search, skip;
+ void *n_arg;
+{
+ caddr_t netmask = (caddr_t)n_arg;
+ register struct radix_node *x;
+ register caddr_t cp, cplim;
+ register int b = 0, mlen, j;
+ int maskduplicated, m0, isnormal;
+ struct radix_node *saved_x;
+ static int last_zeroed = 0;
+
+ if ((mlen = *(u_char *)netmask) > max_keylen)
+ mlen = max_keylen;
+ if (skip == 0)
+ skip = 1;
+ if (mlen <= skip)
+ return (mask_rnhead->rnh_nodes);
+ if (skip > 1)
+ Bcopy(rn_ones + 1, addmask_key + 1, skip - 1);
+ if ((m0 = mlen) > skip)
+ Bcopy(netmask + skip, addmask_key + skip, mlen - skip);
+ /*
+ * Trim trailing zeroes.
+ */
+ for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;)
+ cp--;
+ mlen = cp - addmask_key;
+ if (mlen <= skip) {
+ if (m0 >= last_zeroed)
+ last_zeroed = mlen;
+ return (mask_rnhead->rnh_nodes);
+ }
+ if (m0 < last_zeroed)
+ Bzero(addmask_key + m0, last_zeroed - m0);
+ *addmask_key = last_zeroed = mlen;
+ x = rn_search(addmask_key, rn_masktop);
+ if (Bcmp(addmask_key, x->rn_key, mlen) != 0)
+ x = 0;
+ if (x || search)
+ return (x);
+ R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x));
+ if ((saved_x = x) == 0)
+ return (0);
+ Bzero(x, max_keylen + 2 * sizeof (*x));
+ netmask = cp = (caddr_t)(x + 2);
+ Bcopy(addmask_key, cp, mlen);
+ x = rn_insert(cp, mask_rnhead, &maskduplicated, x);
+ if (maskduplicated) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR, "rn_addmask: mask impossibly already in tree");
+#endif
+ Free(saved_x);
+ return (x);
+ }
+ /*
+ * Calculate index of mask, and check for normalcy.
+ */
+ cplim = netmask + mlen; isnormal = 1;
+ for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
+ cp++;
+ if (cp != cplim) {
+ for (j = 0x80; (j & *cp) != 0; j >>= 1)
+ b++;
+ if (*cp != normal_chars[b] || cp != (cplim - 1))
+ isnormal = 0;
+ }
+ b += (cp - netmask) << 3;
+ x->rn_b = -1 - b;
+ if (isnormal)
+ x->rn_flags |= RNF_NORMAL;
+ return (x);
+}
+
+static int /* XXX: arbitrary ordering for non-contiguous masks */
+rn_lexobetter(m_arg, n_arg)
+ void *m_arg, *n_arg;
+{
+ register u_char *mp = m_arg, *np = n_arg, *lim;
+
+ if (*mp > *np)
+ return 1; /* not really, but need to check longer one first */
+ if (*mp == *np)
+ for (lim = mp + *mp; mp < lim;)
+ if (*mp++ > *np++)
+ return 1;
+ return 0;
+}
+
+static struct radix_mask *
+rn_new_radix_mask(tt, next)
+ register struct radix_node *tt;
+ register struct radix_mask *next;
+{
+ register struct radix_mask *m;
+
+ MKGet(m);
+ if (m == 0) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR, "Mask for route not entered\n");
+#endif
+ return (0);
+ }
+ Bzero(m, sizeof *m);
+ m->rm_b = tt->rn_b;
+ m->rm_flags = tt->rn_flags;
+ if (tt->rn_flags & RNF_NORMAL)
+ m->rm_leaf = tt;
+ else
+ m->rm_mask = tt->rn_mask;
+ m->rm_mklist = next;
+ tt->rn_mklist = m;
+ return m;
+}
+
+struct radix_node *
+rn_addroute(v_arg, n_arg, head, treenodes)
+ void *v_arg, *n_arg;
+ struct radix_node_head *head;
+ struct radix_node treenodes[2];
+{
+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
+ register struct radix_node *t, *x = NULL, *tt;
+ struct radix_node *saved_tt, *top = head->rnh_treetop;
+ short b = 0, b_leaf = 0;
+ int keyduplicated;
+ caddr_t mmask;
+ struct radix_mask *m, **mp;
+
+ /*
+ * In dealing with non-contiguous masks, there may be
+ * many different routes which have the same mask.
+ * We will find it useful to have a unique pointer to
+ * the mask to speed avoiding duplicate references at
+ * nodes and possibly save time in calculating indices.
+ */
+ if (netmask) {
+ if ((x = rn_addmask(netmask, 0, top->rn_off)) == 0)
+ return (0);
+ b_leaf = x->rn_b;
+ b = -1 - x->rn_b;
+ netmask = x->rn_key;
+ }
+ /*
+ * Deal with duplicated keys: attach node to previous instance
+ */
+ saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes);
+ if (keyduplicated) {
+ for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) {
+ if (tt->rn_mask == netmask)
+ return (0);
+ if (netmask == 0 ||
+ (tt->rn_mask &&
+ ((b_leaf < tt->rn_b) || /* index(netmask) > node */
+ rn_refines(netmask, tt->rn_mask) ||
+ rn_lexobetter(netmask, tt->rn_mask))))
+ break;
+ }
+ /*
+ * If the mask is not duplicated, we wouldn't
+ * find it among possible duplicate key entries
+ * anyway, so the above test doesn't hurt.
+ *
+ * We sort the masks for a duplicated key the same way as
+ * in a masklist -- most specific to least specific.
+ * This may require the unfortunate nuisance of relocating
+ * the head of the list.
+ */
+ if (tt == saved_tt) {
+ struct radix_node *xx = x;
+ /* link in at head of list */
+ (tt = treenodes)->rn_dupedkey = t;
+ tt->rn_flags = t->rn_flags;
+ tt->rn_p = x = t->rn_p;
+ if (x->rn_l == t) x->rn_l = tt; else x->rn_r = tt;
+ saved_tt = tt; x = xx;
+ } else {
+ (tt = treenodes)->rn_dupedkey = t->rn_dupedkey;
+ t->rn_dupedkey = tt;
+ }
+#ifdef RN_DEBUG
+ t=tt+1; tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
+ tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
+#endif
+ tt->rn_key = (caddr_t) v;
+ tt->rn_b = -1;
+ tt->rn_flags = RNF_ACTIVE;
+ }
+ /*
+ * Put mask in tree.
+ */
+ if (netmask) {
+ tt->rn_mask = netmask;
+ tt->rn_b = x->rn_b;
+ tt->rn_flags |= x->rn_flags & RNF_NORMAL;
+ }
+ t = saved_tt->rn_p;
+ if (keyduplicated)
+ goto on2;
+ b_leaf = -1 - t->rn_b;
+ if (t->rn_r == saved_tt) x = t->rn_l; else x = t->rn_r;
+ /* Promote general routes from below */
+ if (x->rn_b < 0) {
+ for (mp = &t->rn_mklist; x; x = x->rn_dupedkey)
+ if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) {
+ *mp = m = rn_new_radix_mask(x, 0);
+ if (m)
+ mp = &m->rm_mklist;
+ }
+ } else if (x->rn_mklist) {
+ /*
+ * Skip over masks whose index is > that of new node
+ */
+ for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist)
+ if (m->rm_b >= b_leaf)
+ break;
+ t->rn_mklist = m; *mp = 0;
+ }
+on2:
+ /* Add new route to highest possible ancestor's list */
+ if ((netmask == 0) || (b > t->rn_b ))
+ return tt; /* can't lift at all */
+ b_leaf = tt->rn_b;
+ do {
+ x = t;
+ t = t->rn_p;
+ } while (b <= t->rn_b && x != top);
+ /*
+ * Search through routes associated with node to
+ * insert new route according to index.
+ * Need same criteria as when sorting dupedkeys to avoid
+ * double loop on deletion.
+ */
+ for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) {
+ if (m->rm_b < b_leaf)
+ continue;
+ if (m->rm_b > b_leaf)
+ break;
+ if (m->rm_flags & RNF_NORMAL) {
+ mmask = m->rm_leaf->rn_mask;
+ if (tt->rn_flags & RNF_NORMAL) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR,
+ "Non-unique normal route, mask not entered");
+#endif
+ return tt;
+ }
+ } else
+ mmask = m->rm_mask;
+ if (mmask == netmask) {
+ m->rm_refs++;
+ tt->rn_mklist = m;
+ return tt;
+ }
+ if (rn_refines(netmask, mmask) || rn_lexobetter(netmask, mmask))
+ break;
+ }
+ *mp = rn_new_radix_mask(tt, *mp);
+ return tt;
+}
+
+struct radix_node *
+rn_delete(v_arg, netmask_arg, head)
+ void *v_arg, *netmask_arg;
+ struct radix_node_head *head;
+{
+ register struct radix_node *t, *p, *x, *tt;
+ struct radix_mask *m, *saved_m, **mp;
+ struct radix_node *dupedkey, *saved_tt, *top;
+ caddr_t v, netmask;
+ int b, head_off, vlen;
+
+ v = v_arg;
+ netmask = netmask_arg;
+ x = head->rnh_treetop;
+ tt = rn_search(v, x);
+ head_off = x->rn_off;
+ vlen = *(u_char *)v;
+ saved_tt = tt;
+ top = x;
+ if (tt == 0 ||
+ Bcmp(v + head_off, tt->rn_key + head_off, vlen - head_off))
+ return (0);
+ /*
+ * Delete our route from mask lists.
+ */
+ if (netmask) {
+ if ((x = rn_addmask(netmask, 1, head_off)) == 0)
+ return (0);
+ netmask = x->rn_key;
+ while (tt->rn_mask != netmask)
+ if ((tt = tt->rn_dupedkey) == 0)
+ return (0);
+ }
+ if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0)
+ goto on1;
+ if (tt->rn_flags & RNF_NORMAL) {
+ if (m->rm_leaf != tt || m->rm_refs > 0) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR, "rn_delete: inconsistent annotation\n");
+#endif
+ return 0; /* dangling ref could cause disaster */
+ }
+ } else {
+ if (m->rm_mask != tt->rn_mask) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR, "rn_delete: inconsistent annotation\n");
+#endif
+ goto on1;
+ }
+ if (--m->rm_refs >= 0)
+ goto on1;
+ }
+ b = -1 - tt->rn_b;
+ t = saved_tt->rn_p;
+ if (b > t->rn_b)
+ goto on1; /* Wasn't lifted at all */
+ do {
+ x = t;
+ t = t->rn_p;
+ } while (b <= t->rn_b && x != top);
+ for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist)
+ if (m == saved_m) {
+ *mp = m->rm_mklist;
+ MKFree(m);
+ break;
+ }
+ if (m == 0) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR, "rn_delete: couldn't find our annotation\n");
+#endif
+ if (tt->rn_flags & RNF_NORMAL)
+ return (0); /* Dangling ref to us */
+ }
+on1:
+ /*
+ * Eliminate us from tree
+ */
+ if (tt->rn_flags & RNF_ROOT)
+ return (0);
+#ifdef RN_DEBUG
+ /* Get us out of the creation list */
+ for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) {}
+ if (t) t->rn_ybro = tt->rn_ybro;
+#endif
+ t = tt->rn_p;
+ if ((dupedkey = saved_tt->rn_dupedkey) != 0) {
+ if (tt == saved_tt) {
+ x = dupedkey; x->rn_p = t;
+ if (t->rn_l == tt) t->rn_l = x; else t->rn_r = x;
+ } else {
+ for (x = p = saved_tt; p && p->rn_dupedkey != tt;)
+ p = p->rn_dupedkey;
+ if (p) p->rn_dupedkey = tt->rn_dupedkey;
+#ifdef __ECOS
+#else
+ else log(LOG_ERR, "rn_delete: couldn't find us\n");
+#endif
+ }
+ t = tt + 1;
+ if (t->rn_flags & RNF_ACTIVE) {
+#ifndef RN_DEBUG
+ *++x = *t; p = t->rn_p;
+#else
+ b = t->rn_info; *++x = *t; t->rn_info = b; p = t->rn_p;
+#endif
+ if (p->rn_l == t) p->rn_l = x; else p->rn_r = x;
+ x->rn_l->rn_p = x; x->rn_r->rn_p = x;
+ }
+ goto out;
+ }
+ if (t->rn_l == tt) x = t->rn_r; else x = t->rn_l;
+ p = t->rn_p;
+ if (p->rn_r == t) p->rn_r = x; else p->rn_l = x;
+ x->rn_p = p;
+ /*
+ * Demote routes attached to us.
+ */
+ if (t->rn_mklist) {
+ if (x->rn_b >= 0) {
+ for (mp = &x->rn_mklist; (m = *mp) != NULL;)
+ mp = &m->rm_mklist;
+ *mp = t->rn_mklist;
+ } else {
+ /* If there are any key,mask pairs in a sibling
+ duped-key chain, some subset will appear sorted
+ in the same order attached to our mklist */
+ for (m = t->rn_mklist; m && x; x = x->rn_dupedkey)
+ if (m == x->rn_mklist) {
+ struct radix_mask *mm = m->rm_mklist;
+ x->rn_mklist = 0;
+ if (--(m->rm_refs) < 0)
+ MKFree(m);
+ m = mm;
+ }
+#ifdef __ECOS
+#else
+ if (m)
+ log(LOG_ERR, "%s %p at %p\n",
+ "rn_delete: Orphaned Mask", m, x);
+#endif
+ }
+ }
+ /*
+ * We may be holding an active internal node in the tree.
+ */
+ x = tt + 1;
+ if (t != x) {
+#ifndef RN_DEBUG
+ *t = *x;
+#else
+ b = t->rn_info; *t = *x; t->rn_info = b;
+#endif
+ t->rn_l->rn_p = t; t->rn_r->rn_p = t;
+ p = x->rn_p;
+ if (p->rn_l == x) p->rn_l = t; else p->rn_r = t;
+ }
+out:
+ tt->rn_flags &= ~RNF_ACTIVE;
+ tt[1].rn_flags &= ~RNF_ACTIVE;
+ return (tt);
+}
+
+int
+rn_walktree(h, f, w)
+ struct radix_node_head *h;
+ register int (*f) __P((struct radix_node *, void *));
+ void *w;
+{
+ int error;
+ struct radix_node *base, *next;
+ register struct radix_node *rn = h->rnh_treetop;
+ /*
+ * This gets complicated because we may delete the node
+ * while applying the function f to it, so we need to calculate
+ * the successor node in advance.
+ */
+ /* First time through node, go left */
+ while (rn->rn_b >= 0)
+ rn = rn->rn_l;
+ for (;;) {
+ base = rn;
+ /* If at right child go back up, otherwise, go right */
+ while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0)
+ rn = rn->rn_p;
+ /* Find the next *leaf* since next node might vanish, too */
+ for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;)
+ rn = rn->rn_l;
+ next = rn;
+ /* Process leaves */
+ while ((rn = base) != NULL) {
+ base = rn->rn_dupedkey;
+ if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w)))
+ return (error);
+ }
+ rn = next;
+ if (rn->rn_flags & RNF_ROOT)
+ return (0);
+ }
+ /* NOTREACHED */
+}
+
+int
+rn_inithead(head, off)
+ void **head;
+ int off;
+{
+ register struct radix_node_head *rnh;
+ register struct radix_node *t, *tt, *ttt;
+ if (*head)
+ return (1);
+ R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh));
+ if (rnh == 0)
+ return (0);
+ Bzero(rnh, sizeof (*rnh));
+ *head = rnh;
+ t = rn_newpair(rn_zeros, off, rnh->rnh_nodes);
+ ttt = rnh->rnh_nodes + 2;
+ t->rn_r = ttt;
+ t->rn_p = t;
+ tt = t->rn_l;
+ tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;
+ tt->rn_b = -1 - off;
+ *ttt = *tt;
+ ttt->rn_key = rn_ones;
+ rnh->rnh_addaddr = rn_addroute;
+ rnh->rnh_deladdr = rn_delete;
+ rnh->rnh_matchaddr = rn_match;
+ rnh->rnh_lookup = rn_lookup;
+ rnh->rnh_walktree = rn_walktree;
+ rnh->rnh_treetop = t;
+ return (1);
+}
+
+void
+rn_init()
+{
+ char *cp, *cplim;
+#ifdef _KERNEL
+ struct domain *dom;
+
+ for (dom = domains; dom; dom = dom->dom_next)
+ if (dom->dom_maxrtkey > max_keylen)
+ max_keylen = dom->dom_maxrtkey;
+#endif
+ if (max_keylen == 0) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR,
+ "rn_init: radix functions require max_keylen be set\n");
+#endif
+ return;
+ }
+ R_Malloc(rn_zeros, char *, 3 * max_keylen);
+ if (rn_zeros == NULL)
+ panic("rn_init");
+ Bzero(rn_zeros, 3 * max_keylen);
+ rn_ones = cp = rn_zeros + max_keylen;
+ addmask_key = cplim = rn_ones + max_keylen;
+ while (cp < cplim)
+ *cp++ = -1;
+ if (rn_inithead((void **)&mask_rnhead, 0) == 0)
+ panic("rn_init 2");
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/raw_cb.c b/ecos/packages/net/tcpip/current/src/sys/net/raw_cb.c
new file mode 100644
index 0000000..7dacc34
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/raw_cb.c
@@ -0,0 +1,178 @@
+//==========================================================================
+//
+// sys/net/raw_cb.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: raw_cb.c,v 1.2 1996/03/03 21:07:16 niklas Exp $ */
+/* $NetBSD: raw_cb.c,v 1.9 1996/02/13 22:00:39 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)raw_cb.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+#include <netinet/in.h>
+
+/*
+ * Routines to manage the raw protocol control blocks.
+ *
+ * TODO:
+ * hash lookups by protocol family/protocol + address family
+ * take care of unique address problems per AF?
+ * redo address binding to allow wildcards
+ */
+
+u_long raw_sendspace = RAWSNDQ;
+u_long raw_recvspace = RAWRCVQ;
+
+/*
+ * Allocate a control block and a nominal amount
+ * of buffer space for the socket.
+ */
+int
+raw_attach(so, proto)
+ register struct socket *so;
+ int proto;
+{
+ register struct rawcb *rp = sotorawcb(so);
+ int error;
+
+ /*
+ * It is assumed that raw_attach is called
+ * after space has been allocated for the
+ * rawcb.
+ */
+ if (rp == 0)
+ return (ENOBUFS);
+ if ((error = soreserve(so, raw_sendspace, raw_recvspace)) != 0)
+ return (error);
+ rp->rcb_socket = so;
+ rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
+ rp->rcb_proto.sp_protocol = proto;
+ LIST_INSERT_HEAD(&rawcb, rp, rcb_list);
+ return (0);
+}
+
+/*
+ * Detach the raw connection block and discard
+ * socket resources.
+ */
+void
+raw_detach(rp)
+ register struct rawcb *rp;
+{
+ struct socket *so = rp->rcb_socket;
+
+ so->so_pcb = 0;
+ sofree(so);
+ LIST_REMOVE(rp, rcb_list);
+#ifdef notdef
+ if (rp->rcb_laddr)
+ m_freem(dtom(rp->rcb_laddr));
+ rp->rcb_laddr = 0;
+#endif
+ free((caddr_t)(rp), M_PCB);
+}
+
+/*
+ * Disconnect and possibly release resources.
+ */
+void
+raw_disconnect(rp)
+ struct rawcb *rp;
+{
+
+#ifdef notdef
+ if (rp->rcb_faddr)
+ m_freem(dtom(rp->rcb_faddr));
+ rp->rcb_faddr = 0;
+#endif
+ if (rp->rcb_socket->so_state & SS_NOFDREF)
+ raw_detach(rp);
+}
+
+#ifdef notdef
+int
+raw_bind(so, nam)
+ register struct socket *so;
+ struct mbuf *nam;
+{
+ struct sockaddr *addr = mtod(nam, struct sockaddr *);
+ register struct rawcb *rp;
+
+ if (ifnet == 0)
+ return (EADDRNOTAVAIL);
+ rp = sotorawcb(so);
+ nam = m_copym(nam, 0, M_COPYALL, M_WAITOK);
+ rp->rcb_laddr = mtod(nam, struct sockaddr *);
+ return (0);
+}
+#endif
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/raw_usrreq.c b/ecos/packages/net/tcpip/current/src/sys/net/raw_usrreq.c
new file mode 100644
index 0000000..f0fde95
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/raw_usrreq.c
@@ -0,0 +1,360 @@
+//==========================================================================
+//
+// sys/net/raw_usrreq.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: raw_usrreq.c,v 1.3 1998/09/17 12:29:55 deraadt Exp $ */
+/* $NetBSD: raw_usrreq.c,v 1.11 1996/02/13 22:00:43 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netisr.h>
+#include <net/raw_cb.h>
+
+#include <machine/stdarg.h>
+/*
+ * Initialize raw connection block q.
+ */
+void
+raw_init()
+{
+
+ LIST_INIT(&rawcb);
+}
+
+
+/*
+ * Raw protocol input routine. Find the socket
+ * associated with the packet(s) and move them over. If
+ * nothing exists for this packet, drop it.
+ */
+/*
+ * Raw protocol interface.
+ */
+void
+#if __STDC__
+raw_input(struct mbuf *m0, ...)
+#else
+raw_input(m0, va_alist)
+ struct mbuf *m0;
+ va_dcl
+#endif
+{
+ register struct rawcb *rp;
+ register struct mbuf *m = m0;
+ register int sockets = 0;
+ struct socket *last;
+ va_list ap;
+ register struct sockproto *proto;
+ struct sockaddr *src, *dst;
+
+ va_start(ap, m0);
+ proto = va_arg(ap, struct sockproto *);
+ src = va_arg(ap, struct sockaddr *);
+ dst = va_arg(ap, struct sockaddr *);
+ va_end(ap);
+
+ last = 0;
+ for (rp = rawcb.lh_first; rp != 0; rp = rp->rcb_list.le_next) {
+ if (rp->rcb_proto.sp_family != proto->sp_family)
+ continue;
+ if (rp->rcb_proto.sp_protocol &&
+ rp->rcb_proto.sp_protocol != proto->sp_protocol)
+ continue;
+ /*
+ * We assume the lower level routines have
+ * placed the address in a canonical format
+ * suitable for a structure comparison.
+ *
+ * Note that if the lengths are not the same
+ * the comparison will fail at the first byte.
+ */
+#define equal(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
+ if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
+ continue;
+ if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
+ continue;
+ if (last) {
+ struct mbuf *n;
+ if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
+ if (sbappendaddr(&last->so_rcv, src,
+ n, (struct mbuf *)0) == 0)
+ /* should notify about lost packet */
+ m_freem(n);
+ else {
+ sorwakeup(last);
+ sockets++;
+ }
+ }
+ }
+ last = rp->rcb_socket;
+ }
+ if (last) {
+ if (sbappendaddr(&last->so_rcv, src,
+ m, (struct mbuf *)0) == 0)
+ m_freem(m);
+ else {
+ sorwakeup(last);
+ sockets++;
+ }
+ } else
+ m_freem(m);
+}
+
+/*ARGSUSED*/
+void *
+raw_ctlinput(cmd, arg, d)
+ int cmd;
+ struct sockaddr *arg;
+ void *d;
+{
+
+ if (cmd < 0 || cmd > PRC_NCMDS)
+ return NULL;
+ return NULL;
+ /* INCOMPLETE */
+}
+
+/*ARGSUSED*/
+int
+raw_usrreq(so, req, m, nam, control)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ register struct rawcb *rp = sotorawcb(so);
+ register int error = 0;
+ int len;
+
+ if (req == PRU_CONTROL)
+ return (EOPNOTSUPP);
+ if (control && control->m_len) {
+ error = EOPNOTSUPP;
+ goto release;
+ }
+ if (rp == 0) {
+ error = EINVAL;
+ goto release;
+ }
+ switch (req) {
+
+ /*
+ * Allocate a raw control block and fill in the
+ * necessary info to allow packets to be routed to
+ * the appropriate raw interface routine.
+ */
+ case PRU_ATTACH:
+#ifndef __ECOS
+ if ((so->so_state & SS_PRIV) == 0) {
+ error = EACCES;
+ break;
+ }
+#endif
+ error = raw_attach(so, (int)(long)nam);
+ break;
+
+ /*
+ * Destroy state just before socket deallocation.
+ * Flush data or not depending on the options.
+ */
+ case PRU_DETACH:
+ if (rp == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ raw_detach(rp);
+ break;
+
+#ifdef notdef
+ /*
+ * If a socket isn't bound to a single address,
+ * the raw input routine will hand it anything
+ * within that protocol family (assuming there's
+ * nothing else around it should go to).
+ */
+ case PRU_CONNECT:
+ if (rp->rcb_faddr) {
+ error = EISCONN;
+ break;
+ }
+ nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
+ rp->rcb_faddr = mtod(nam, struct sockaddr *);
+ soisconnected(so);
+ break;
+
+ case PRU_BIND:
+ if (rp->rcb_laddr) {
+ error = EINVAL; /* XXX */
+ break;
+ }
+ error = raw_bind(so, nam);
+ break;
+#else
+ case PRU_CONNECT:
+ case PRU_BIND:
+#endif
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ goto release;
+
+ case PRU_DISCONNECT:
+ if (rp->rcb_faddr == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ raw_disconnect(rp);
+ soisdisconnected(so);
+ break;
+
+ /*
+ * Mark the connection as being incapable of further input.
+ */
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ /*
+ * Ship a packet out. The appropriate raw output
+ * routine handles any massaging necessary.
+ */
+ case PRU_SEND:
+ if (nam) {
+ if (rp->rcb_faddr) {
+ error = EISCONN;
+ break;
+ }
+ rp->rcb_faddr = mtod(nam, struct sockaddr *);
+ } else if (rp->rcb_faddr == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ error = (*so->so_proto->pr_output)(m, so);
+ m = NULL;
+ if (nam)
+ rp->rcb_faddr = 0;
+ break;
+
+ case PRU_ABORT:
+ raw_disconnect(rp);
+ sofree(so);
+ soisdisconnected(so);
+ break;
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ return (0);
+
+ /*
+ * Not supported.
+ */
+ case PRU_RCVOOB:
+ case PRU_RCVD:
+ return(EOPNOTSUPP);
+
+ case PRU_LISTEN:
+ case PRU_ACCEPT:
+ case PRU_SENDOOB:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SOCKADDR:
+ if (rp->rcb_laddr == 0) {
+ error = EINVAL;
+ break;
+ }
+ len = rp->rcb_laddr->sa_len;
+ bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
+ nam->m_len = len;
+ break;
+
+ case PRU_PEERADDR:
+ if (rp->rcb_faddr == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ len = rp->rcb_faddr->sa_len;
+ bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
+ nam->m_len = len;
+ break;
+
+ default:
+ panic("raw_usrreq");
+ }
+release:
+ if (m != NULL)
+ m_freem(m);
+ return (error);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/route.c b/ecos/packages/net/tcpip/current/src/sys/net/route.c
new file mode 100644
index 0000000..67673d9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/route.c
@@ -0,0 +1,1074 @@
+//==========================================================================
+//
+// sys/net/route.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: route.c,v 1.16 1999/12/08 06:50:18 itojun Exp $ */
+/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1980, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)route.c 8.2 (Berkeley) 11/15/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifdef __ECOS
+struct proc {
+ int __unused;
+};
+#else
+#include <sys/systm.h>
+#include <sys/proc.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#ifdef NS
+#include <netns/ns.h>
+#endif
+
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+
+extern struct ifnet encif;
+#endif
+
+#define SA(p) ((struct sockaddr *)(p))
+
+int rttrash; /* routes not in table but not freed */
+struct sockaddr wildcard; /* zero valued cookie for wildcard searches */
+
+static int okaytoclone __P((u_int, int));
+
+#ifdef IPSEC
+
+static struct ifaddr *
+encap_findgwifa(struct sockaddr *gw)
+{
+ return encif.if_addrlist.tqh_first;
+}
+
+#endif
+
+void
+rtable_init(table)
+ void **table;
+{
+ struct domain *dom;
+ for (dom = domains; dom; dom = dom->dom_next)
+ if (dom->dom_rtattach)
+ dom->dom_rtattach(&table[dom->dom_family],
+ dom->dom_rtoffset);
+}
+
+void
+route_init()
+{
+ rn_init(); /* initialize all zeroes, all ones, mask table */
+ rtable_init((void **)rt_tables);
+}
+
+// FIXME: This function is only here because BOOTP fails on a second interface.
+// This failure is due to the fact that a route to 0.0.0.0 seems to be
+// incredibly sticky, i.e. can't be deleted. BOOTP uses this to
+// achieve a generic broadcast. Sadly it seems that BOOTP servers will
+// only work this way, thus the hack.
+//
+// This version enumerates all routes and deletes them - this leaks less
+// store than the previous version.
+
+static int
+rt_reinit_rtdelete( struct radix_node *rn, void *vifp )
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+ rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
+ 0, NULL);
+ return (0);
+}
+
+void
+cyg_route_reinit(void)
+{
+ int i;
+ for (i = 0; i < AF_MAX+1; i++) {
+ struct radix_node_head *rnh;
+ rnh = rt_tables[i];
+ if (rnh) {
+ (*rnh->rnh_walktree)(rnh, rt_reinit_rtdelete, NULL);
+ }
+ }
+}
+
+void
+rtalloc_noclone(ro, howstrict)
+ register struct route *ro;
+ int howstrict;
+{
+ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
+ return; /* XXX */
+ ro->ro_rt = rtalloc2(&ro->ro_dst, 1, howstrict);
+}
+
+static int
+okaytoclone(flags, howstrict)
+ u_int flags;
+ int howstrict;
+{
+ if (howstrict == ALL_CLONING)
+ return 1;
+ if (howstrict == ONNET_CLONING && !(flags & (RTF_GATEWAY|RTF_TUNNEL)))
+ return 1;
+ return 0;
+}
+
+struct rtentry *
+rtalloc2(dst, report,howstrict)
+ register struct sockaddr *dst;
+ int report,howstrict;
+{
+ register struct radix_node_head *rnh = rt_tables[dst->sa_family];
+ register struct rtentry *rt;
+ register struct radix_node *rn;
+ struct rtentry *newrt = 0;
+ struct rt_addrinfo info;
+ int s = splnet(), err = 0, msgtype = RTM_MISS;
+
+ if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
+ ((rn->rn_flags & RNF_ROOT) == 0)) {
+ newrt = rt = (struct rtentry *)rn;
+ if (report && (rt->rt_flags & RTF_CLONING) &&
+ okaytoclone(rt->rt_flags, howstrict)) {
+ err = rtrequest(RTM_RESOLVE, dst, SA(0), SA(0), 0,
+ &newrt);
+ if (err) {
+ newrt = rt;
+ rt->rt_refcnt++;
+ goto miss;
+ }
+ if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
+ msgtype = RTM_RESOLVE;
+ goto miss;
+ }
+ } else
+ rt->rt_refcnt++;
+ } else {
+ rtstat.rts_unreach++;
+miss: if (report) {
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ rt_missmsg(msgtype, &info, 0, err);
+ }
+ }
+ splx(s);
+ return (newrt);
+}
+
+/*
+ * Packet routing routines.
+ */
+void
+rtalloc(ro)
+ register struct route *ro;
+{
+ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
+ return; /* XXX */
+ ro->ro_rt = rtalloc1(&ro->ro_dst, 1);
+}
+
+struct rtentry *
+rtalloc1(dst, report)
+ register struct sockaddr *dst;
+ int report;
+{
+ register struct radix_node_head *rnh = rt_tables[dst->sa_family];
+ register struct rtentry *rt;
+ register struct radix_node *rn;
+ struct rtentry *newrt = 0;
+ struct rt_addrinfo info;
+ int s = splsoftnet(), err = 0, msgtype = RTM_MISS;
+
+ if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
+ ((rn->rn_flags & RNF_ROOT) == 0)) {
+ newrt = rt = (struct rtentry *)rn;
+ if (report && (rt->rt_flags & RTF_CLONING)) {
+ err = rtrequest(RTM_RESOLVE, dst, SA(NULL),
+ SA(NULL), 0, &newrt);
+ if (err) {
+ newrt = rt;
+ rt->rt_refcnt++;
+ goto miss;
+ }
+ if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
+ msgtype = RTM_RESOLVE;
+ goto miss;
+ }
+ } else
+ rt->rt_refcnt++;
+ } else {
+ if (dst->sa_family != PF_KEY)
+ rtstat.rts_unreach++;
+ /*
+ * IP encapsulation does lots of lookups where we don't need nor want
+ * the RTM_MISSes that would be generated. It causes RTM_MISS storms
+ * sent upward breaking user-level routing queries.
+ */
+ miss: if (report && dst->sa_family != PF_KEY) {
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ rt_missmsg(msgtype, &info, 0, err);
+ }
+ }
+ splx(s);
+ return (newrt);
+}
+
+void
+rtfree(rt)
+ register struct rtentry *rt;
+{
+ register struct ifaddr *ifa;
+
+ if (rt == NULL)
+ panic("rtfree");
+ rt->rt_refcnt--;
+ if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {
+ if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
+ panic ("rtfree 2");
+ rttrash--;
+ if (rt->rt_refcnt < 0) {
+#ifdef __ECOS
+ diag_printf("rtfree: %x not freed (neg refs)\n", rt);
+#else
+ printf("rtfree: %x not freed (neg refs)\n", rt);
+#endif
+ return;
+ }
+ rt_timer_remove_all(rt);
+ ifa = rt->rt_ifa;
+ if (ifa)
+ IFAFREE(ifa);
+ Free(rt_key(rt));
+ Free(rt);
+ }
+}
+
+void
+ifafree(ifa)
+ register struct ifaddr *ifa;
+{
+ if (ifa == NULL)
+ panic("ifafree");
+ if (ifa->ifa_refcnt == 0)
+ free(ifa, M_IFADDR);
+ else
+ ifa->ifa_refcnt--;
+}
+
+/*
+ * Force a routing table entry to the specified
+ * destination to go through the given gateway.
+ * Normally called as a result of a routing redirect
+ * message from the network layer.
+ *
+ * N.B.: must be called at splsoftnet
+ */
+void
+rtredirect(dst, gateway, netmask, flags, src, rtp)
+ struct sockaddr *dst, *gateway, *netmask, *src;
+ int flags;
+ struct rtentry **rtp;
+{
+ register struct rtentry *rt;
+ int error = 0;
+ u_int32_t *stat = NULL;
+ struct rt_addrinfo info;
+ struct ifaddr *ifa;
+
+ /* verify the gateway is directly reachable */
+ if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
+ error = ENETUNREACH;
+ goto out;
+ }
+ rt = rtalloc1(dst, 0);
+ /*
+ * If the redirect isn't from our current router for this dst,
+ * it's either old or wrong. If it redirects us to ourselves,
+ * we have a routing loop, perhaps as a result of an interface
+ * going down recently.
+ */
+#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
+ if (!(flags & RTF_DONE) && rt &&
+ (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
+ error = EINVAL;
+ else if (ifa_ifwithaddr(gateway) != NULL)
+ error = EHOSTUNREACH;
+ if (error)
+ goto done;
+ /*
+ * Create a new entry if we just got back a wildcard entry
+ * or the the lookup failed. This is necessary for hosts
+ * which use routing redirects generated by smart gateways
+ * to dynamically build the routing tables.
+ */
+ if ((rt == NULL) || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
+ goto create;
+ /*
+ * Don't listen to the redirect if it's
+ * for a route to an interface.
+ */
+ if (rt->rt_flags & RTF_GATEWAY) {
+ if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
+ /*
+ * Changing from route to net => route to host.
+ * Create new route, rather than smashing route to net.
+ */
+ create:
+ flags |= RTF_GATEWAY | RTF_DYNAMIC;
+ error = rtrequest((int)RTM_ADD, dst, gateway,
+ netmask, flags,
+ (struct rtentry **)0);
+ stat = &rtstat.rts_dynamic;
+ } else {
+ /*
+ * Smash the current notion of the gateway to
+ * this destination. Should check about netmask!!!
+ */
+ rt->rt_flags |= RTF_MODIFIED;
+ flags |= RTF_MODIFIED;
+ stat = &rtstat.rts_newgateway;
+ rt_setgate(rt, rt_key(rt), gateway);
+ }
+ } else
+ error = EHOSTUNREACH;
+done:
+ if (rt) {
+ if (rtp && !error)
+ *rtp = rt;
+ else
+ rtfree(rt);
+ }
+out:
+ if (error)
+ rtstat.rts_badredirect++;
+ else if (stat != NULL)
+ (*stat)++;
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ info.rti_info[RTAX_GATEWAY] = gateway;
+ info.rti_info[RTAX_NETMASK] = netmask;
+ info.rti_info[RTAX_AUTHOR] = src;
+ rt_missmsg(RTM_REDIRECT, &info, flags, error);
+}
+
+/*
+* Routing table ioctl interface.
+*/
+int
+rtioctl(req, data, p)
+ u_long req;
+ caddr_t data;
+ struct proc *p;
+{
+#ifdef __ECOS
+ struct ecos_rtentry *rt;
+ int res;
+
+ switch (req) {
+ case SIOCADDRT:
+ rt = (struct ecos_rtentry *)data;
+ res = rtrequest(RTM_ADD,
+ &rt->rt_dst,
+ &rt->rt_gateway,
+ &rt->rt_genmask,
+ rt->rt_flags,
+ NULL);
+ return (res);
+ case SIOCDELRT:
+ rt = (struct ecos_rtentry *)data;
+ res = rtrequest(RTM_DELETE,
+ &rt->rt_dst,
+ &rt->rt_gateway,
+ &rt->rt_genmask,
+ rt->rt_flags,
+ NULL);
+ return (res);
+ default:
+ return (EOPNOTSUPP);
+ }
+#else
+ return (EOPNOTSUPP);
+#endif
+}
+
+struct ifaddr *
+ifa_ifwithroute(flags, dst, gateway)
+ int flags;
+ struct sockaddr *dst, *gateway;
+{
+ register struct ifaddr *ifa;
+
+#ifdef IPSEC
+ /*
+ * If the destination is a PF_KEY address, we'll look
+ * for the existence of a encap interface number or address
+ * in the options list of the gateway. By default, we'll return
+ * enc0.
+ */
+ if (dst && (dst->sa_family == PF_KEY))
+ return encap_findgwifa(gateway);
+#endif
+
+ if ((flags & RTF_GATEWAY) == 0) {
+ /*
+ * If we are adding a route to an interface,
+ * and the interface is a pt to pt link
+ * we should search for the destination
+ * as our clue to the interface. Otherwise
+ * we can use the local address.
+ */
+ ifa = NULL;
+ if (flags & RTF_HOST)
+ ifa = ifa_ifwithdstaddr(dst);
+ if (ifa == NULL)
+ ifa = ifa_ifwithaddr(gateway);
+ } else {
+ /*
+ * If we are adding a route to a remote net
+ * or host, the gateway may still be on the
+ * other end of a pt to pt link.
+ */
+ ifa = ifa_ifwithdstaddr(gateway);
+ }
+ if (ifa == NULL)
+ ifa = ifa_ifwithnet(gateway);
+ if (ifa == NULL) {
+ struct rtentry *rt = rtalloc1(gateway, 0);
+ if (rt == NULL)
+ return (NULL);
+ rt->rt_refcnt--;
+ /* The gateway must be local if the same address family. */
+ if (!(flags & RTF_TUNNEL) && (rt->rt_flags & RTF_GATEWAY) &&
+ rt_key(rt)->sa_family == dst->sa_family)
+ return (0);
+ if ((ifa = rt->rt_ifa) == NULL)
+ return (NULL);
+ }
+ if (ifa->ifa_addr->sa_family != dst->sa_family) {
+ struct ifaddr *oifa = ifa;
+ ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
+ if (ifa == NULL)
+ ifa = oifa;
+ }
+ return (ifa);
+}
+
+#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
+const char *
+_rt_cmd(int req)
+{
+ switch (req)
+ {
+ case RTM_DELETE:
+ return "DELETE";
+ case RTM_RESOLVE:
+ return "RESOLVE";
+ case RTM_ADD:
+ return "ADD";
+ default:
+ return "???";
+ }
+}
+
+int
+rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
+ int req, flags;
+ struct sockaddr *dst, *gateway, *netmask;
+ struct rtentry **ret_nrt;
+{
+ int s = splsoftnet(); int error = 0;
+ register struct rtentry *rt;
+ register struct radix_node *rn;
+ register struct radix_node_head *rnh;
+ struct ifaddr *ifa;
+ struct sockaddr *ndst;
+#define senderr(x) { error = x ; goto bad; }
+
+ if ((rnh = rt_tables[dst->sa_family]) == 0)
+ senderr(EAFNOSUPPORT);
+ if (flags & RTF_HOST)
+ netmask = 0;
+ switch (req) {
+ case RTM_DELETE:
+ if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)
+ senderr(ESRCH);
+ if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
+ panic ("rtrequest delete");
+ rt = (struct rtentry *)rn;
+ rt->rt_flags &= ~RTF_UP;
+ if (rt->rt_gwroute) {
+ if (rt != rt->rt_gwroute)
+ RTFREE( rt->rt_gwroute ); // Free it up as normal
+ else
+ rt->rt_refcnt--; // Just dec the refcount - freeing
+ // it here would be premature
+ rt->rt_gwroute = NULL;
+ }
+ if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
+ ifa->ifa_rtrequest(RTM_DELETE, rt, SA(NULL));
+ rttrash++;
+ if (ret_nrt)
+ *ret_nrt = rt;
+ else if (rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++;
+ rtfree(rt);
+ }
+ break;
+
+ case RTM_RESOLVE:
+ if (ret_nrt == NULL || (rt = *ret_nrt) == NULL)
+ senderr(EINVAL);
+ ifa = rt->rt_ifa;
+ flags = rt->rt_flags & ~RTF_CLONING;
+ gateway = rt->rt_gateway;
+ if ((netmask = rt->rt_genmask) == NULL)
+ flags |= RTF_HOST;
+ goto makeroute;
+
+ case RTM_ADD:
+ if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == NULL)
+ senderr(ENETUNREACH);
+
+ /* The interface found in the previous statement may
+ * be overridden later by rt_setif. See the code
+ * for case RTM_ADD in rtsock.c:route_output.
+ */
+ makeroute:
+ R_Malloc(rt, struct rtentry *, sizeof(*rt));
+ if (rt == NULL)
+ senderr(ENOBUFS);
+ Bzero(rt, sizeof(*rt));
+ rt->rt_flags = RTF_UP | flags;
+ LIST_INIT(&rt->rt_timer);
+ if (rt_setgate(rt, dst, gateway)) {
+ Free(rt);
+ senderr(ENOBUFS);
+ }
+ ndst = rt_key(rt);
+ if (netmask) {
+ rt_maskedcopy(dst, ndst, netmask);
+ } else
+ Bcopy(dst, ndst, dst->sa_len);
+if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU)) { /* XXX */
+ rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu;
+}
+ rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,
+ rnh, rt->rt_nodes);
+ if (rn == NULL) {
+ if (rt->rt_gwroute)
+ rtfree(rt->rt_gwroute);
+ Free(rt_key(rt));
+ Free(rt);
+ senderr(EEXIST);
+ }
+ ifa->ifa_refcnt++;
+ rt->rt_ifa = ifa;
+ rt->rt_ifp = ifa->ifa_ifp;
+ if (req == RTM_RESOLVE) {
+ /*
+ * Copy both metrics and a back pointer to the cloned
+ * route's parent.
+ */
+ rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
+ rt->rt_parent = *ret_nrt; /* Back ptr. to parent. */
+ }
+ if (ifa->ifa_rtrequest)
+ ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : NULL));
+ if (ret_nrt) {
+ *ret_nrt = rt;
+ rt->rt_refcnt++;
+ }
+#ifdef INET6
+ /* If we have a v4_in_v4 or a v4_in_v6 tunnel route
+ * then do some tunnel state (e.g. security state)
+ * initialization.
+ *
+ * Since IPV6 packets flow down this path, we don't
+ * want it using ipv4_tunnelsetup(rt) (since they
+ * have their own ipv6_tunnel_parent/child()
+ * routines which are called ipv6_rtrequest().)
+ *
+ * Thus, we check to see if the packet is to a v4
+ * destination.
+ */
+ if (dst->sa_family == AF_INET && (rt->rt_flags & RTF_TUNNEL))
+ ipv4_tunnelsetup(rt);
+#endif /* INET6 */
+ break;
+ }
+bad:
+ splx(s);
+ return (error);
+}
+
+/*
+ * Set up any tunnel states (e.g. security) information
+ * for v4_in_v4 or v4_in_v6 tunnel routes.
+ */
+void
+ipv4_tunnelsetup(rt)
+ register struct rtentry *rt;
+{
+ /* XXX */
+}
+
+int
+rt_setgate(rt0, dst, gate)
+ struct rtentry *rt0;
+ struct sockaddr *dst, *gate;
+{
+ caddr_t new, old;
+ int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len);
+ register struct rtentry *rt = rt0;
+
+ if (rt->rt_gateway == NULL || glen > ROUNDUP(rt->rt_gateway->sa_len)) {
+ old = (caddr_t)rt_key(rt);
+ R_Malloc(new, caddr_t, dlen + glen);
+ if (new == NULL)
+ return 1;
+ rt->rt_nodes->rn_key = new;
+ } else {
+ new = rt->rt_nodes->rn_key;
+ old = NULL;
+ }
+ Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen);
+ if (old) {
+ Bcopy(dst, new, dlen);
+ Free(old);
+ }
+ if (rt->rt_gwroute != NULL) {
+ rt = rt->rt_gwroute;
+ RTFREE(rt);
+ rt = rt0;
+ rt->rt_gwroute = NULL;
+ }
+ if (rt->rt_flags & RTF_GATEWAY) {
+ rt->rt_gwroute = rtalloc1(gate, 1);
+ }
+ return 0;
+}
+
+void
+rt_maskedcopy(src, dst, netmask)
+ struct sockaddr *src, *dst, *netmask;
+{
+ register u_char *cp1 = (u_char *)src;
+ register u_char *cp2 = (u_char *)dst;
+ register u_char *cp3 = (u_char *)netmask;
+ u_char *cplim = cp2 + *cp3;
+ u_char *cplim2 = cp2 + *cp1;
+
+ *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
+ cp3 += 2;
+ if (cplim > cplim2)
+ cplim = cplim2;
+ while (cp2 < cplim)
+ *cp2++ = *cp1++ & *cp3++;
+ if (cp2 < cplim2)
+ bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
+}
+
+/*
+ * Set up a routing table entry, normally
+ * for an interface.
+ */
+int
+rtinit(ifa, cmd, flags)
+ register struct ifaddr *ifa;
+ int cmd, flags;
+{
+ register struct rtentry *rt;
+ register struct sockaddr *dst;
+ register struct sockaddr *deldst;
+ struct mbuf *m = NULL;
+ struct rtentry *nrt = NULL;
+ int error;
+
+ dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
+ if (cmd == RTM_DELETE) {
+ if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
+ m = m_get(M_DONTWAIT, MT_SONAME);
+ if (m == NULL)
+ return(ENOBUFS);
+ deldst = mtod(m, struct sockaddr *);
+ rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
+ dst = deldst;
+ }
+ if ((rt = rtalloc1(dst, 0)) != NULL) {
+ rt->rt_refcnt--;
+ if (rt->rt_ifa != ifa) {
+ if (m != NULL)
+ (void) m_free(m);
+ return (flags & RTF_HOST ? EHOSTUNREACH
+ : ENETUNREACH);
+ }
+ }
+ }
+ error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask,
+ flags | ifa->ifa_flags, &nrt);
+ if (m != NULL)
+ (void) m_free(m);
+ if (cmd == RTM_DELETE && error == 0 && (rt = nrt) != NULL) {
+ rt_newaddrmsg(cmd, ifa, error, nrt);
+ if (rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++;
+ rtfree(rt);
+ }
+ }
+ if (cmd == RTM_ADD && error == 0 && (rt = nrt) != NULL) {
+ rt->rt_refcnt--;
+#ifdef INET6
+ /* Initialize Path MTU for IPv6 interface route */
+ if (ifa->ifa_addr->sa_family == AF_INET6 &&
+ !rt->rt_rmx.rmx_mtu)
+ rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu;
+#endif /* INET6 */
+ if (rt->rt_ifa != ifa) {
+#ifdef __ECOS
+ diag_printf("rtinit: wrong ifa (%x) was (%x)\n",
+ ifa, rt->rt_ifa);
+#else
+ printf("rtinit: wrong ifa (%x) was (%x)\n",
+ ifa, rt->rt_ifa);
+#endif
+ if (rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt,
+ SA(NULL));
+ IFAFREE(rt->rt_ifa);
+ rt->rt_ifa = ifa;
+ rt->rt_ifp = ifa->ifa_ifp;
+ rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; /*XXX*/
+ ifa->ifa_refcnt++;
+ if (ifa->ifa_rtrequest)
+ ifa->ifa_rtrequest(RTM_ADD, rt, SA(NULL));
+ }
+ rt_newaddrmsg(cmd, ifa, error, nrt);
+ }
+ return (error);
+}
+
+/*
+ * Route timer routines. These routes allow functions to be called
+ * for various routes at any time. This is useful in supporting
+ * path MTU discovery and redirect route deletion.
+ *
+ * This is similar to some BSDI internal functions, but it provides
+ * for multiple queues for efficiency's sake...
+ */
+
+LIST_HEAD(, rttimer_queue) rttimer_queue_head;
+static int rt_init_done = 0;
+
+#define RTTIMER_CALLOUT(r) { \
+ if (r->rtt_func != NULL) { \
+ (*r->rtt_func)(r->rtt_rt, r); \
+ } else { \
+ rtrequest((int) RTM_DELETE, \
+ (struct sockaddr *)rt_key(r->rtt_rt), \
+ 0, 0, 0, 0); \
+ } \
+}
+
+/*
+ * Some subtle order problems with domain initialization mean that
+ * we cannot count on this being run from rt_init before various
+ * protocol initializations are done. Therefore, we make sure
+ * that this is run when the first queue is added...
+ */
+
+void
+rt_timer_init()
+{
+#ifndef __ECOS
+ assert(rt_init_done == 0);
+#endif
+
+#if 0
+ pool_init(&rttimer_pool, sizeof(struct rttimer), 0, 0, 0, "rttmrpl",
+ 0, NULL, NULL, M_RTABLE);
+#endif
+
+ LIST_INIT(&rttimer_queue_head);
+ timeout(rt_timer_timer, NULL, hz); /* every second */
+ rt_init_done = 1;
+}
+
+struct rttimer_queue *
+rt_timer_queue_create(timeout)
+ u_int timeout;
+{
+ struct rttimer_queue *rtq;
+
+ if (rt_init_done == 0)
+ rt_timer_init();
+
+ R_Malloc(rtq, struct rttimer_queue *, sizeof *rtq);
+ if (rtq == NULL)
+ return (NULL);
+
+ rtq->rtq_timeout = timeout;
+ TAILQ_INIT(&rtq->rtq_head);
+ LIST_INSERT_HEAD(&rttimer_queue_head, rtq, rtq_link);
+
+ return (rtq);
+}
+
+void
+rt_timer_queue_change(rtq, timeout)
+ struct rttimer_queue *rtq;
+ long timeout;
+{
+
+ rtq->rtq_timeout = timeout;
+}
+
+
+void
+rt_timer_queue_destroy(rtq, destroy)
+ struct rttimer_queue *rtq;
+ int destroy;
+{
+ struct rttimer *r;
+
+ while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL) {
+ LIST_REMOVE(r, rtt_link);
+ TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
+ if (destroy)
+ RTTIMER_CALLOUT(r);
+#if 0
+ pool_put(&rttimer_pool, r);
+#else
+ free(r, M_RTABLE);
+#endif
+ }
+
+ LIST_REMOVE(rtq, rtq_link);
+
+ /*
+ * Caller is responsible for freeing the rttimer_queue structure.
+ */
+}
+
+void
+rt_timer_remove_all(rt)
+ struct rtentry *rt;
+{
+ struct rttimer *r;
+
+ while ((r = LIST_FIRST(&rt->rt_timer)) != NULL) {
+ LIST_REMOVE(r, rtt_link);
+ TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
+#if 0
+ pool_put(&rttimer_pool, r);
+#else
+ free(r, M_RTABLE);
+#endif
+ }
+}
+
+int
+rt_timer_add(rt, func, queue)
+ struct rtentry *rt;
+ void(*func) __P((struct rtentry *, struct rttimer *));
+ struct rttimer_queue *queue;
+{
+ struct rttimer *r;
+ long current_time;
+ int s;
+
+ s = splclock();
+#ifdef __ECOS
+ get_mono_time();
+#endif
+ current_time = mono_time.tv_sec;
+ splx(s);
+
+ /*
+ * If there's already a timer with this action, destroy it before
+ * we add a new one.
+ */
+ for (r = LIST_FIRST(&rt->rt_timer); r != NULL;
+ r = LIST_NEXT(r, rtt_link)) {
+ if (r->rtt_func == func) {
+ LIST_REMOVE(r, rtt_link);
+ TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
+#if 0
+ pool_put(&rttimer_pool, r);
+#else
+ free(r, M_RTABLE);
+#endif
+ break; /* only one per list, so we can quit... */
+ }
+ }
+
+#if 0
+ r = pool_get(&rttimer_pool, PR_NOWAIT);
+#else
+ r = (struct rttimer *)malloc(sizeof(*r), M_RTABLE, M_NOWAIT);
+#endif
+ if (r == NULL)
+ return (ENOBUFS);
+
+ r->rtt_rt = rt;
+ r->rtt_time = current_time;
+ r->rtt_func = func;
+ r->rtt_queue = queue;
+ LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link);
+ TAILQ_INSERT_TAIL(&queue->rtq_head, r, rtt_next);
+
+ return (0);
+}
+
+/* ARGSUSED */
+void
+rt_timer_timer(arg)
+ void *arg;
+{
+ struct rttimer_queue *rtq;
+ struct rttimer *r;
+ long current_time;
+ int s;
+
+ s = splclock();
+#ifdef __ECOS
+ get_mono_time();
+#endif
+ current_time = mono_time.tv_sec;
+ splx(s);
+
+ s = splsoftnet();
+ for (rtq = LIST_FIRST(&rttimer_queue_head); rtq != NULL;
+ rtq = LIST_NEXT(rtq, rtq_link)) {
+ while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL &&
+ (r->rtt_time + rtq->rtq_timeout) < current_time) {
+ LIST_REMOVE(r, rtt_link);
+ TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
+ RTTIMER_CALLOUT(r);
+#if 0
+ pool_put(&rttimer_pool, r);
+#else
+ free(r, M_RTABLE);
+#endif
+ }
+ }
+ splx(s);
+
+ timeout(rt_timer_timer, NULL, hz); /* every second */
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/net/rtsock.c b/ecos/packages/net/tcpip/current/src/sys/net/rtsock.c
new file mode 100644
index 0000000..5e8317b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/net/rtsock.c
@@ -0,0 +1,1053 @@
+//==========================================================================
+//
+// sys/net/rtsock.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: rtsock.c,v 1.8 1999/12/08 06:50:18 itojun Exp $ */
+/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)rtsock.c 8.6 (Berkeley) 2/11/95
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#include <sys/proc.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+
+#ifndef __ECOS
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+
+#include <machine/stdarg.h>
+
+struct sockaddr route_dst = { 2, PF_ROUTE, };
+struct sockaddr route_src = { 2, PF_ROUTE, };
+struct sockproto route_proto = { PF_ROUTE, };
+
+struct walkarg {
+ int w_op, w_arg, w_given, w_needed, w_tmemsize;
+ caddr_t w_where, w_tmem;
+};
+
+static struct mbuf *
+ rt_msg1 __P((int, struct rt_addrinfo *));
+static int rt_msg2 __P((int,
+ struct rt_addrinfo *, caddr_t, struct walkarg *));
+static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
+static void rt_setif __P((struct rtentry *, struct sockaddr *,
+ struct sockaddr *, struct sockaddr *));
+
+/* Sleazy use of local variables throughout file, warning!!!! */
+#define dst info.rti_info[RTAX_DST]
+#define gate info.rti_info[RTAX_GATEWAY]
+#define netmask info.rti_info[RTAX_NETMASK]
+#define genmask info.rti_info[RTAX_GENMASK]
+#define ifpaddr info.rti_info[RTAX_IFP]
+#define ifaaddr info.rti_info[RTAX_IFA]
+#define brdaddr info.rti_info[RTAX_BRD]
+
+/*ARGSUSED*/
+int
+route_usrreq(so, req, m, nam, control)
+ register struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ register int error = 0;
+ register struct rawcb *rp = sotorawcb(so);
+ int s;
+
+ if (req == PRU_ATTACH) {
+ MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
+ if ((so->so_pcb = rp) != NULL)
+ bzero(so->so_pcb, sizeof(*rp));
+
+ }
+ if (req == PRU_DETACH && rp) {
+ int af = rp->rcb_proto.sp_protocol;
+ if (af == AF_INET)
+ route_cb.ip_count--;
+ else if (af == AF_INET6)
+ route_cb.ip6_count--;
+ else if (af == AF_NS)
+ route_cb.ns_count--;
+ else if (af == AF_ISO)
+ route_cb.iso_count--;
+ route_cb.any_count--;
+ }
+ s = splsoftnet();
+ /*
+ * Don't call raw_usrreq() in the attach case, because
+ * we want to allow non-privileged processes to listen on
+ * and send "safe" commands to the routing socket.
+ */
+ if (req == PRU_ATTACH) {
+#ifndef __ECOS
+ if (curproc == 0)
+ error = EACCES;
+ else
+#endif // FIXME?
+ error = raw_attach(so, (int)(long)nam);
+ } else
+ error = raw_usrreq(so, req, m, nam, control);
+
+ rp = sotorawcb(so);
+ if (req == PRU_ATTACH && rp) {
+ int af = rp->rcb_proto.sp_protocol;
+ if (error) {
+ free((caddr_t)rp, M_PCB);
+ splx(s);
+ return (error);
+ }
+ if (af == AF_INET)
+ route_cb.ip_count++;
+ else if (af == AF_INET6)
+ route_cb.ip6_count++;
+ else if (af == AF_NS)
+ route_cb.ns_count++;
+ else if (af == AF_ISO)
+ route_cb.iso_count++;
+ rp->rcb_faddr = &route_src;
+ route_cb.any_count++;
+ soisconnected(so);
+ so->so_options |= SO_USELOOPBACK;
+ }
+ splx(s);
+ return (error);
+}
+
+/*ARGSUSED*/
+int
+#if __STDC__
+route_output(struct mbuf *m, ...)
+#else
+route_output(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ register struct rt_msghdr *rtm = 0;
+ register struct rtentry *rt = 0;
+ struct rtentry *saved_nrt = 0;
+ struct radix_node_head *rnh;
+ struct rt_addrinfo info;
+ int len, error = 0;
+ struct ifnet *ifp = 0;
+ struct socket *so;
+ va_list ap;
+
+ va_start(ap, m);
+ so = va_arg(ap, struct socket *);
+ va_end(ap);
+
+ bzero(&info, sizeof(info));
+#define senderr(e) { error = e; goto flush;}
+ if (m == 0 || ((m->m_len < sizeof(int32_t)) &&
+ (m = m_pullup(m, sizeof(int32_t))) == 0))
+ return (ENOBUFS);
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("route_output");
+ len = m->m_pkthdr.len;
+ if (len < sizeof(*rtm) ||
+ len != mtod(m, struct rt_msghdr *)->rtm_msglen) {
+ dst = 0;
+ senderr(EINVAL);
+ }
+ R_Malloc(rtm, struct rt_msghdr *, len);
+ if (rtm == 0) {
+ dst = 0;
+ senderr(ENOBUFS);
+ }
+ m_copydata(m, 0, len, (caddr_t)rtm);
+ if (rtm->rtm_version != RTM_VERSION) {
+ dst = 0;
+ senderr(EPROTONOSUPPORT);
+ }
+#ifdef __ECOS
+ rtm->rtm_pid = 0; // FIXME
+#else
+ rtm->rtm_pid = curproc->p_pid;
+#endif
+ info.rti_addrs = rtm->rtm_addrs;
+ rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info);
+ if (dst == 0)
+ senderr(EINVAL);
+ if (genmask) {
+ struct radix_node *t;
+ t = rn_addmask((caddr_t)genmask, 0, 1);
+ if (t && Bcmp(genmask, t->rn_key, *(u_char *)genmask) == 0)
+ genmask = (struct sockaddr *)(t->rn_key);
+ else
+ senderr(ENOBUFS);
+ }
+
+ /*
+ * Verify that the caller has the appropriate privilege; RTM_GET
+ * is the only operation the non-superuser is allowed.
+ */
+#ifndef __ECOS
+ if (rtm->rtm_type != RTM_GET &&
+ suser(curproc->p_ucred, &curproc->p_acflag) != 0)
+ senderr(EACCES);
+#endif
+ switch (rtm->rtm_type) {
+
+ case RTM_ADD:
+ if (gate == 0)
+ senderr(EINVAL);
+ error = rtrequest(RTM_ADD, dst, gate, netmask,
+ rtm->rtm_flags, &saved_nrt);
+ if (error == 0 && saved_nrt) {
+ /*
+ * If the route request specified an interface with
+ * IFA and/or IFP, we set the requested interface on
+ * the route with rt_setif. It would be much better
+ * to do this inside rtrequest, but that would
+ * require passing the desired interface, in some
+ * form, to rtrequest. Since rtrequest is called in
+ * so many places (roughly 40 in our source), adding
+ * a parameter is to much for us to swallow; this is
+ * something for the FreeBSD developers to tackle.
+ * Instead, we let rtrequest compute whatever
+ * interface it wants, then come in behind it and
+ * stick in the interface that we really want. This
+ * works reasonably well except when rtrequest can't
+ * figure out what interface to use (with
+ * ifa_withroute) and returns ENETUNREACH. Ideally
+ * it shouldn't matter if rtrequest can't figure out
+ * the interface if we're going to explicitly set it
+ * ourselves anyway. But practically we can't
+ * recover here because rtrequest will not do any of
+ * the work necessary to add the route if it can't
+ * find an interface. As long as there is a default
+ * route that leads to some interface, rtrequest will
+ * find an interface, so this problem should be
+ * rarely encountered.
+ * dwiggins@bbn.com
+ */
+
+ rt_setif(saved_nrt, ifpaddr, ifaaddr, gate);
+ rt_setmetrics(rtm->rtm_inits,
+ &rtm->rtm_rmx, &saved_nrt->rt_rmx);
+ saved_nrt->rt_refcnt--;
+ saved_nrt->rt_genmask = genmask;
+ }
+ break;
+
+ case RTM_DELETE:
+ error = rtrequest(RTM_DELETE, dst, gate, netmask,
+ rtm->rtm_flags, &saved_nrt);
+ if (error == 0) {
+ (rt = saved_nrt)->rt_refcnt++;
+ goto report;
+ }
+ break;
+
+ case RTM_GET:
+ case RTM_CHANGE:
+ case RTM_LOCK:
+ if ((rnh = rt_tables[dst->sa_family]) == 0) {
+ senderr(EAFNOSUPPORT);
+ } else if ((rt = (struct rtentry *)
+ rnh->rnh_lookup(dst, netmask, rnh)) != NULL)
+ rt->rt_refcnt++;
+ else
+ senderr(ESRCH);
+ switch(rtm->rtm_type) {
+
+ case RTM_GET:
+ report:
+ dst = rt_key(rt);
+ gate = rt->rt_gateway;
+ netmask = rt_mask(rt);
+ genmask = rt->rt_genmask;
+ if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
+ if ((ifp = rt->rt_ifp) != NULL) {
+ ifpaddr = ifp->if_addrlist.tqh_first->ifa_addr;
+ ifaaddr = rt->rt_ifa->ifa_addr;
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ brdaddr = rt->rt_ifa->ifa_dstaddr;
+ else
+ brdaddr = 0;
+ rtm->rtm_index = ifp->if_index;
+ } else {
+ ifpaddr = 0;
+ ifaaddr = 0;
+ }
+ }
+ len = rt_msg2(rtm->rtm_type, &info, (caddr_t)0,
+ (struct walkarg *)0);
+ if (len > rtm->rtm_msglen) {
+ struct rt_msghdr *new_rtm;
+ R_Malloc(new_rtm, struct rt_msghdr *, len);
+ if (new_rtm == 0)
+ senderr(ENOBUFS);
+ Bcopy(rtm, new_rtm, rtm->rtm_msglen);
+ Free(rtm); rtm = new_rtm;
+ }
+ (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm,
+ (struct walkarg *)0);
+ rtm->rtm_flags = rt->rt_flags;
+ rtm->rtm_rmx = rt->rt_rmx;
+ rtm->rtm_addrs = info.rti_addrs;
+ break;
+
+ case RTM_CHANGE:
+ if (gate && rt_setgate(rt, rt_key(rt), gate))
+#ifdef __ECOS
+ senderr(EMFILE);
+#else
+ senderr(EDQUOT);
+#endif
+
+#if 1
+ rt_setif(rt, ifpaddr, ifaaddr, gate);
+#else
+ /* new gateway could require new ifaddr, ifp;
+ flags may also be different; ifp may be specified
+ by ll sockaddr when protocol address is ambiguous */
+ if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) &&
+ (ifp = ifa->ifa_ifp) && (ifaaddr || gate))
+ ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate,
+ ifp);
+ else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) ||
+ (gate && (ifa = ifa_ifwithroute(rt->rt_flags,
+ rt_key(rt), gate))))
+ ifp = ifa->ifa_ifp;
+ if (ifa) {
+ register struct ifaddr *oifa = rt->rt_ifa;
+ if (oifa != ifa) {
+ if (oifa && oifa->ifa_rtrequest)
+ oifa->ifa_rtrequest(RTM_DELETE,
+ rt, gate);
+ IFAFREE(rt->rt_ifa);
+ rt->rt_ifa = ifa;
+ ifa->ifa_refcnt++;
+ rt->rt_ifp = ifp;
+ }
+ }
+#endif
+ rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
+ &rt->rt_rmx);
+#if 0
+ if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate);
+#endif
+ if (genmask)
+ rt->rt_genmask = genmask;
+ /*
+ * Fall into
+ */
+ case RTM_LOCK:
+ rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
+ rt->rt_rmx.rmx_locks |=
+ (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
+ break;
+ }
+ break;
+
+ default:
+ senderr(EOPNOTSUPP);
+ }
+
+flush:
+ if (rtm) {
+ if (error)
+ rtm->rtm_errno = error;
+ else
+ rtm->rtm_flags |= RTF_DONE;
+ }
+ if (rt)
+ rtfree(rt);
+ {
+ register struct rawcb *rp = 0;
+ /*
+ * Check to see if we don't want our own messages.
+ */
+ if ((so->so_options & SO_USELOOPBACK) == 0) {
+ if (route_cb.any_count <= 1) {
+ if (rtm)
+ Free(rtm);
+ m_freem(m);
+ return (error);
+ }
+ /* There is another listener, so construct message */
+ rp = sotorawcb(so);
+ }
+ if (rtm) {
+ m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
+ Free(rtm);
+ }
+ if (rp)
+ rp->rcb_proto.sp_family = 0; /* Avoid us */
+ if (dst)
+ route_proto.sp_protocol = dst->sa_family;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+ if (rp)
+ rp->rcb_proto.sp_family = PF_ROUTE;
+ }
+ return (error);
+}
+
+void
+rt_setmetrics(which, in, out)
+ u_long which;
+ register struct rt_metrics *in, *out;
+{
+#define metric(f, e) if (which & (f)) out->e = in->e;
+ metric(RTV_RPIPE, rmx_recvpipe);
+ metric(RTV_SPIPE, rmx_sendpipe);
+ metric(RTV_SSTHRESH, rmx_ssthresh);
+ metric(RTV_RTT, rmx_rtt);
+ metric(RTV_RTTVAR, rmx_rttvar);
+ metric(RTV_HOPCOUNT, rmx_hopcount);
+ metric(RTV_MTU, rmx_mtu);
+ metric(RTV_EXPIRE, rmx_expire);
+#undef metric
+}
+
+/*
+ * Set route's interface given ifpaddr, ifaaddr, and gateway.
+ */
+static void
+rt_setif(rt, Ifpaddr, Ifaaddr, Gate)
+ struct rtentry *rt;
+ struct sockaddr *Ifpaddr, *Ifaaddr, *Gate;
+{
+ struct ifaddr *ifa = 0;
+ struct ifnet *ifp = 0;
+
+ /* new gateway could require new ifaddr, ifp;
+ flags may also be different; ifp may be specified
+ by ll sockaddr when protocol address is ambiguous */
+ if (Ifpaddr && (ifa = ifa_ifwithnet(Ifpaddr)) &&
+ (ifp = ifa->ifa_ifp) && (Ifaaddr || Gate))
+ ifa = ifaof_ifpforaddr(Ifaaddr ? Ifaaddr : Gate,
+ ifp);
+ else if (Ifpaddr && (ifp = if_withname(Ifpaddr)) ) {
+ ifa = Gate ? ifaof_ifpforaddr(Gate, ifp) :
+ TAILQ_FIRST(&ifp->if_addrlist);
+ }
+ else if ((Ifaaddr && (ifa = ifa_ifwithaddr(Ifaaddr))) ||
+ (Gate && (ifa = ifa_ifwithroute(rt->rt_flags,
+ rt_key(rt), Gate))))
+ ifp = ifa->ifa_ifp;
+ if (ifa) {
+ register struct ifaddr *oifa = rt->rt_ifa;
+ if (oifa != ifa) {
+ if (oifa && oifa->ifa_rtrequest)
+ oifa->ifa_rtrequest(RTM_DELETE,
+ rt, Gate);
+ IFAFREE(rt->rt_ifa);
+ rt->rt_ifa = ifa;
+ ifa->ifa_refcnt++;
+ rt->rt_ifp = ifp;
+ rt->rt_rmx.rmx_mtu = ifp->if_mtu;
+ if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, Gate);
+ } else
+ goto call_ifareq;
+ return;
+ }
+ call_ifareq:
+ /* XXX: to reset gateway to correct value, at RTM_CHANGE */
+ if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, Gate);
+}
+
+
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+static void
+rt_xaddrs(cp, cplim, rtinfo)
+ register caddr_t cp, cplim;
+ register struct rt_addrinfo *rtinfo;
+{
+ register struct sockaddr *sa;
+ register int i;
+
+ bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info));
+ for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
+ if ((rtinfo->rti_addrs & (1 << i)) == 0)
+ continue;
+ rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
+ ADVANCE(cp, sa);
+ }
+}
+
+/*
+ * Copy data from a buffer back into the indicated mbuf chain,
+ * starting "off" bytes from the beginning, extending the mbuf
+ * chain if necessary. The mbuf needs to be properly initalized
+ * including the setting of m_len.
+ */
+void
+m_copyback(m0, off, len, cp)
+ struct mbuf *m0;
+ register int off;
+ register int len;
+ caddr_t cp;
+{
+ register int mlen;
+ register struct mbuf *m = m0, *n;
+ int totlen = 0;
+
+ if (m0 == 0)
+ return;
+ while (off > (mlen = m->m_len)) {
+ off -= mlen;
+ totlen += mlen;
+ if (m->m_next == 0) {
+ n = m_getclr(M_DONTWAIT, m->m_type);
+ if (n == 0)
+ goto out;
+ n->m_len = min(MLEN, len + off);
+ m->m_next = n;
+ }
+ m = m->m_next;
+ }
+ while (len > 0) {
+ mlen = min (m->m_len - off, len);
+ bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
+ cp += mlen;
+ len -= mlen;
+ mlen += off;
+ off = 0;
+ totlen += mlen;
+ if (len == 0)
+ break;
+ if (m->m_next == 0) {
+ n = m_get(M_DONTWAIT, m->m_type);
+ if (n == 0)
+ break;
+ n->m_len = min(MLEN, len);
+ m->m_next = n;
+ }
+ m = m->m_next;
+ }
+out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
+ m->m_pkthdr.len = totlen;
+}
+
+static struct mbuf *
+rt_msg1(type, rtinfo)
+ int type;
+ register struct rt_addrinfo *rtinfo;
+{
+ register struct rt_msghdr *rtm;
+ register struct mbuf *m;
+ register int i;
+ register struct sockaddr *sa;
+ int len, dlen;
+
+ m = m_gethdr(M_DONTWAIT, MT_DATA);
+ if (m == 0)
+ return (m);
+ switch (type) {
+
+ case RTM_DELADDR:
+ case RTM_NEWADDR:
+ len = sizeof(struct ifa_msghdr);
+ break;
+
+ case RTM_IFINFO:
+ len = sizeof(struct if_msghdr);
+ break;
+
+ default:
+ len = sizeof(struct rt_msghdr);
+ }
+ if (len > MHLEN)
+ panic("rt_msg1");
+ m->m_pkthdr.len = m->m_len = len;
+ m->m_pkthdr.rcvif = 0;
+ rtm = mtod(m, struct rt_msghdr *);
+ bzero((caddr_t)rtm, len);
+ for (i = 0; i < RTAX_MAX; i++) {
+ if ((sa = rtinfo->rti_info[i]) == NULL)
+ continue;
+ rtinfo->rti_addrs |= (1 << i);
+ dlen = ROUNDUP(sa->sa_len);
+ m_copyback(m, len, dlen, (caddr_t)sa);
+ len += dlen;
+ }
+ if (m->m_pkthdr.len != len) {
+ m_freem(m);
+ return (NULL);
+ }
+ rtm->rtm_msglen = len;
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_type = type;
+ return (m);
+}
+
+static int
+rt_msg2(type, rtinfo, cp, w)
+ int type;
+ register struct rt_addrinfo *rtinfo;
+ caddr_t cp;
+ struct walkarg *w;
+{
+ register int i;
+ int len, dlen, second_time = 0;
+ caddr_t cp0;
+
+ rtinfo->rti_addrs = 0;
+again:
+ switch (type) {
+
+ case RTM_DELADDR:
+ case RTM_NEWADDR:
+ len = sizeof(struct ifa_msghdr);
+ break;
+
+ case RTM_IFINFO:
+ len = sizeof(struct if_msghdr);
+ break;
+
+ default:
+ len = sizeof(struct rt_msghdr);
+ }
+ if ((cp0 = cp) != NULL)
+ cp += len;
+ for (i = 0; i < RTAX_MAX; i++) {
+ register struct sockaddr *sa;
+
+ if ((sa = rtinfo->rti_info[i]) == 0)
+ continue;
+ rtinfo->rti_addrs |= (1 << i);
+ dlen = ROUNDUP(sa->sa_len);
+ if (cp) {
+ bcopy((caddr_t)sa, cp, (unsigned)dlen);
+ cp += dlen;
+ }
+ len += dlen;
+ }
+ if (cp == 0 && w != NULL && !second_time) {
+ register struct walkarg *rw = w;
+
+ rw->w_needed += len;
+ if (rw->w_needed <= 0 && rw->w_where) {
+ if (rw->w_tmemsize < len) {
+ if (rw->w_tmem)
+ free(rw->w_tmem, M_RTABLE);
+ rw->w_tmem = (caddr_t) malloc(len, M_RTABLE,
+ M_NOWAIT);
+ if (rw->w_tmem)
+ rw->w_tmemsize = len;
+ }
+ if (rw->w_tmem) {
+ cp = rw->w_tmem;
+ second_time = 1;
+ goto again;
+ } else
+ rw->w_where = 0;
+ }
+ }
+ if (cp) {
+ register struct rt_msghdr *rtm = (struct rt_msghdr *)cp0;
+
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_type = type;
+ rtm->rtm_msglen = len;
+ }
+ return (len);
+}
+
+/*
+ * This routine is called to generate a message from the routing
+ * socket indicating that a redirect has occured, a routing lookup
+ * has failed, or that a protocol has detected timeouts to a particular
+ * destination.
+ */
+void
+rt_missmsg(type, rtinfo, flags, error)
+ int type, flags, error;
+ register struct rt_addrinfo *rtinfo;
+{
+ register struct rt_msghdr *rtm;
+ register struct mbuf *m;
+ struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];
+
+ if (route_cb.any_count == 0)
+ return;
+ m = rt_msg1(type, rtinfo);
+ if (m == 0)
+ return;
+ rtm = mtod(m, struct rt_msghdr *);
+ rtm->rtm_flags = RTF_DONE | flags;
+ rtm->rtm_errno = error;
+ rtm->rtm_addrs = rtinfo->rti_addrs;
+ route_proto.sp_protocol = sa ? sa->sa_family : 0;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+}
+
+/*
+ * This routine is called to generate a message from the routing
+ * socket indicating that the status of a network interface has changed.
+ */
+void
+rt_ifmsg(ifp)
+ register struct ifnet *ifp;
+{
+ register struct if_msghdr *ifm;
+ struct mbuf *m;
+ struct rt_addrinfo info;
+
+ if (route_cb.any_count == 0)
+ return;
+ bzero((caddr_t)&info, sizeof(info));
+ m = rt_msg1(RTM_IFINFO, &info);
+ if (m == 0)
+ return;
+ ifm = mtod(m, struct if_msghdr *);
+ ifm->ifm_index = ifp->if_index;
+ ifm->ifm_flags = ifp->if_flags;
+ ifm->ifm_data = ifp->if_data;
+ ifm->ifm_addrs = 0;
+ route_proto.sp_protocol = 0;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+}
+
+/*
+ * This is called to generate messages from the routing socket
+ * indicating a network interface has had addresses associated with it.
+ * if we ever reverse the logic and replace messages TO the routing
+ * socket indicate a request to configure interfaces, then it will
+ * be unnecessary as the routing socket will automatically generate
+ * copies of it.
+ */
+void
+rt_newaddrmsg(cmd, ifa, error, rt)
+ int cmd, error;
+ register struct ifaddr *ifa;
+ register struct rtentry *rt;
+{
+ struct rt_addrinfo info;
+ struct sockaddr *sa = NULL;
+ int pass;
+ struct mbuf *m = NULL;
+ struct ifnet *ifp = ifa->ifa_ifp;
+
+ if (route_cb.any_count == 0)
+ return;
+ for (pass = 1; pass < 3; pass++) {
+ bzero((caddr_t)&info, sizeof(info));
+ if ((cmd == RTM_ADD && pass == 1) ||
+ (cmd == RTM_DELETE && pass == 2)) {
+ register struct ifa_msghdr *ifam;
+ int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
+
+ ifaaddr = sa = ifa->ifa_addr;
+ ifpaddr = ifp->if_addrlist.tqh_first->ifa_addr;
+ netmask = ifa->ifa_netmask;
+ brdaddr = ifa->ifa_dstaddr;
+ if ((m = rt_msg1(ncmd, &info)) == NULL)
+ continue;
+ ifam = mtod(m, struct ifa_msghdr *);
+ ifam->ifam_index = ifp->if_index;
+ ifam->ifam_metric = ifa->ifa_metric;
+ ifam->ifam_flags = ifa->ifa_flags;
+ ifam->ifam_addrs = info.rti_addrs;
+ }
+ if ((cmd == RTM_ADD && pass == 2) ||
+ (cmd == RTM_DELETE && pass == 1)) {
+ register struct rt_msghdr *rtm;
+
+ if (rt == 0)
+ continue;
+ netmask = rt_mask(rt);
+ dst = sa = rt_key(rt);
+ gate = rt->rt_gateway;
+ if ((m = rt_msg1(cmd, &info)) == NULL)
+ continue;
+ rtm = mtod(m, struct rt_msghdr *);
+ rtm->rtm_index = ifp->if_index;
+ rtm->rtm_flags |= rt->rt_flags;
+ rtm->rtm_errno = error;
+ rtm->rtm_addrs = info.rti_addrs;
+ }
+ route_proto.sp_protocol = sa ? sa->sa_family : 0;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+ }
+}
+
+#ifndef __ECOS
+/*
+ * This is used in dumping the kernel table via sysctl().
+ */
+int
+sysctl_dumpentry(rn, v)
+ struct radix_node *rn;
+ register void *v;
+{
+ register struct walkarg *w = v;
+ register struct rtentry *rt = (struct rtentry *)rn;
+ int error = 0, size;
+ struct rt_addrinfo info;
+
+ if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
+ return 0;
+ bzero((caddr_t)&info, sizeof(info));
+ dst = rt_key(rt);
+ gate = rt->rt_gateway;
+ netmask = rt_mask(rt);
+ genmask = rt->rt_genmask;
+ if (rt->rt_ifp) {
+ ifpaddr = rt->rt_ifp->if_addrlist.tqh_first->ifa_addr;
+ ifaaddr = rt->rt_ifa->ifa_addr;
+ if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
+ brdaddr = rt->rt_ifa->ifa_dstaddr;
+ }
+ size = rt_msg2(RTM_GET, &info, 0, w);
+ if (w->w_where && w->w_tmem) {
+ register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
+
+ rtm->rtm_flags = rt->rt_flags;
+ rtm->rtm_use = rt->rt_use;
+ rtm->rtm_rmx = rt->rt_rmx;
+ rtm->rtm_index = rt->rt_ifp->if_index;
+ rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0;
+ rtm->rtm_addrs = info.rti_addrs;
+ if ((error = copyout((caddr_t)rtm, w->w_where, size)) != 0)
+ w->w_where = NULL;
+ else
+ w->w_where += size;
+ }
+ return (error);
+}
+
+int
+sysctl_iflist(af, w)
+ int af;
+ register struct walkarg *w;
+{
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+ struct rt_addrinfo info;
+ int len, error = 0;
+
+ bzero((caddr_t)&info, sizeof(info));
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
+ if (w->w_arg && w->w_arg != ifp->if_index)
+ continue;
+ ifa = ifp->if_addrlist.tqh_first;
+ ifpaddr = ifa->ifa_addr;
+ len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w);
+ ifpaddr = 0;
+ if (w->w_where && w->w_tmem) {
+ register struct if_msghdr *ifm;
+
+ ifm = (struct if_msghdr *)w->w_tmem;
+ ifm->ifm_index = ifp->if_index;
+ ifm->ifm_flags = ifp->if_flags;
+ ifm->ifm_data = ifp->if_data;
+ ifm->ifm_addrs = info.rti_addrs;
+ error = copyout((caddr_t)ifm, w->w_where, len);
+ if (error)
+ return (error);
+ w->w_where += len;
+ }
+ while ((ifa = ifa->ifa_list.tqe_next) != NULL) {
+ if (af && af != ifa->ifa_addr->sa_family)
+ continue;
+ ifaaddr = ifa->ifa_addr;
+ netmask = ifa->ifa_netmask;
+ brdaddr = ifa->ifa_dstaddr;
+ len = rt_msg2(RTM_NEWADDR, &info, 0, w);
+ if (w->w_where && w->w_tmem) {
+ register struct ifa_msghdr *ifam;
+
+ ifam = (struct ifa_msghdr *)w->w_tmem;
+ ifam->ifam_index = ifa->ifa_ifp->if_index;
+ ifam->ifam_flags = ifa->ifa_flags;
+ ifam->ifam_metric = ifa->ifa_metric;
+ ifam->ifam_addrs = info.rti_addrs;
+ error = copyout(w->w_tmem, w->w_where, len);
+ if (error)
+ return (error);
+ w->w_where += len;
+ }
+ }
+ ifaaddr = netmask = brdaddr = 0;
+ }
+ return (0);
+}
+
+int
+sysctl_rtable(name, namelen, where, given, new, newlen)
+ int *name;
+ u_int namelen;
+ void *where;
+ size_t *given;
+ void *new;
+ size_t newlen;
+{
+ register struct radix_node_head *rnh;
+ int i, s, error = EINVAL;
+ u_char af;
+ struct walkarg w;
+
+ if (new)
+ return (EPERM);
+ if (namelen != 3)
+ return (EINVAL);
+ af = name[0];
+ Bzero(&w, sizeof(w));
+ w.w_where = where;
+ w.w_given = *given;
+ w.w_needed = 0 - w.w_given;
+ w.w_op = name[1];
+ w.w_arg = name[2];
+
+ s = splsoftnet();
+ switch (w.w_op) {
+
+ case NET_RT_DUMP:
+ case NET_RT_FLAGS:
+ for (i = 1; i <= AF_MAX; i++)
+ if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&
+ (error = (*rnh->rnh_walktree)(rnh,
+ sysctl_dumpentry,
+ &w)))
+ break;
+ break;
+
+ case NET_RT_IFLIST:
+ error = sysctl_iflist(af, &w);
+ }
+ splx(s);
+ if (w.w_tmem)
+ free(w.w_tmem, M_RTABLE);
+ w.w_needed += w.w_given;
+ if (where) {
+ *given = w.w_where - (caddr_t) where;
+ if (*given < w.w_needed)
+ return (ENOMEM);
+ } else {
+ *given = (11 * w.w_needed) / 10;
+ }
+ return (error);
+}
+#endif
+
+/*
+ * Definitions of protocols supported in the ROUTE domain.
+ */
+
+extern struct domain routedomain; /* or at least forward */
+
+struct protosw routesw[] = {
+{ SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR,
+ raw_input, route_output, raw_ctlinput, 0,
+ route_usrreq,
+ raw_init, 0, 0, 0,
+#ifdef __ECOS
+ 0,
+#else
+ sysctl_rtable,
+#endif
+}
+};
+
+struct domain routedomain =
+ { PF_ROUTE, "route", route_init, 0, 0,
+ routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] };
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/if_ether.c b/ecos/packages/net/tcpip/current/src/sys/netinet/if_ether.c
new file mode 100644
index 0000000..93b1fdf
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/if_ether.c
@@ -0,0 +1,996 @@
+//==========================================================================
+//
+// sys/netinet/if_ether.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: if_ether.c,v 1.19 1999/11/10 18:48:47 chris Exp $ */
+/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Ethernet address resolution protocol.
+ * TODO:
+ * add "inuse/lock" bit (or ref. count) along with valid bit
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#ifndef __ECOS
+#include <sys/syslog.h>
+#include <sys/proc.h>
+#endif
+
+#ifdef INET
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+
+#define SIN(s) ((struct sockaddr_in *)s)
+#define SDL(s) ((struct sockaddr_dl *)s)
+#define SRP(s) ((struct sockaddr_inarp *)s)
+
+/*
+ * ARP trailer negotiation. Trailer protocol is not IP specific,
+ * but ARP request/response use IP addresses.
+ */
+#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
+
+/* timer values */
+int arpt_prune = (5*60*1); /* walk list every 5 minutes */
+int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
+int arpt_down = 20; /* once declared down, don't send for 20 secs */
+#define rt_expire rt_rmx.rmx_expire
+
+static void arprequest
+ __P((struct arpcom *, u_int32_t *, u_int32_t *, u_int8_t *));
+static void arptfree __P((struct llinfo_arp *));
+static void arptimer __P((void *));
+static struct llinfo_arp *arplookup __P((u_int32_t, int, int));
+static void in_arpinput __P((struct mbuf *));
+
+extern struct ifnet loif;
+LIST_HEAD(, llinfo_arp) llinfo_arp;
+struct ifqueue arpintrq = {0, 0, 0, 50};
+int arp_inuse, arp_allocated, arp_intimer;
+int arp_maxtries = 5;
+int useloopback = 1; /* use loopback interface for local traffic */
+int arpinit_done = 0;
+
+/* revarp state */
+static struct in_addr myip, srv_ip;
+static int myip_initialized = 0;
+static int revarp_in_progress = 0;
+struct ifnet *myip_ifp = NULL;
+
+static void arptimer __P((void *));
+static void arprequest __P((struct arpcom *, u_int32_t *, u_int32_t *,
+ u_int8_t *));
+static void in_arpinput __P((struct mbuf *));
+static void arptfree __P((struct llinfo_arp *));
+static struct llinfo_arp *arplookup __P((u_int32_t, int, int ));
+#ifdef DDB
+#include <vm/vm.h>
+
+static void db_print_sa __P((struct sockaddr *));
+static void db_print_ifa __P((struct ifaddr *));
+static void db_print_llinfo __P((caddr_t));
+static int db_show_radix_node __P((struct radix_node *, void *));
+#endif
+
+/*
+ * Timeout routine. Age arp_tab entries periodically.
+ */
+/* ARGSUSED */
+static void
+arptimer(arg)
+ void *arg;
+{
+ int s;
+ register struct llinfo_arp *la, *nla;
+
+ s = splsoftnet();
+ timeout(arptimer, NULL, arpt_prune * hz);
+ for (la = llinfo_arp.lh_first; la != 0; la = nla) {
+ register struct rtentry *rt = la->la_rt;
+
+ nla = la->la_list.le_next;
+ if (rt->rt_expire && rt->rt_expire <= time.tv_sec)
+ arptfree(la); /* timer has expired; clear */
+ }
+ splx(s);
+}
+
+/*
+ * Parallel to llc_rtrequest.
+ */
+void
+arp_rtrequest(req, rt, sa)
+ int req;
+ register struct rtentry *rt;
+ struct sockaddr *sa;
+{
+ register struct sockaddr *gate = rt->rt_gateway;
+ register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
+ static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+
+ if (!arpinit_done) {
+ arpinit_done = 1;
+ /*
+ * We generate expiration times from time.tv_sec
+ * so avoid accidently creating permanent routes.
+ */
+ if (time.tv_sec == 0) {
+ time.tv_sec++;
+ }
+ timeout(arptimer, (caddr_t)0, hz);
+ }
+ if (rt->rt_flags & RTF_GATEWAY)
+ return;
+ switch (req) {
+
+ case RTM_ADD:
+ /*
+ * XXX: If this is a manually added route to interface
+ * such as older version of routed or gated might provide,
+ * restore cloning bit.
+ */
+ if ((rt->rt_flags & RTF_HOST) == 0 &&
+ SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
+ rt->rt_flags |= RTF_CLONING;
+ if (rt->rt_flags & RTF_CLONING) {
+ /*
+ * Case 1: This route should come from a route to iface.
+ */
+ rt_setgate(rt, rt_key(rt),
+ (struct sockaddr *)&null_sdl);
+ gate = rt->rt_gateway;
+ SDL(gate)->sdl_type = rt->rt_ifp->if_type;
+ SDL(gate)->sdl_index = rt->rt_ifp->if_index;
+ /*
+ * Give this route an expiration time, even though
+ * it's a "permanent" route, so that routes cloned
+ * from it do not need their expiration time set.
+ */
+ rt->rt_expire = time.tv_sec;
+ break;
+ }
+ /* Announce a new entry if requested. */
+ if (rt->rt_flags & RTF_ANNOUNCE)
+ arprequest((struct arpcom *)rt->rt_ifp,
+ &SIN(rt_key(rt))->sin_addr.s_addr,
+ &SIN(rt_key(rt))->sin_addr.s_addr,
+ (u_char *)LLADDR(SDL(gate)));
+ /*FALLTHROUGH*/
+ case RTM_RESOLVE:
+ if (gate->sa_family != AF_LINK ||
+ gate->sa_len < sizeof(null_sdl)) {
+#ifdef __ECOS
+#else
+ log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
+#endif
+ break;
+ }
+ SDL(gate)->sdl_type = rt->rt_ifp->if_type;
+ SDL(gate)->sdl_index = rt->rt_ifp->if_index;
+ if (la != 0)
+ break; /* This happens on a route change */
+ /*
+ * Case 2: This route may come from cloning, or a manual route
+ * add with a LL address.
+ */
+ R_Malloc(la, struct llinfo_arp *, sizeof(*la));
+ rt->rt_llinfo = (caddr_t)la;
+ if (la == 0) {
+#ifdef __ECOS
+#else
+ log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
+#endif
+ break;
+ }
+ arp_inuse++, arp_allocated++;
+ Bzero(la, sizeof(*la));
+ la->la_rt = rt;
+ rt->rt_flags |= RTF_LLINFO;
+ LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
+ if (SIN(rt_key(rt))->sin_addr.s_addr ==
+ (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
+ /*
+ * This test used to be
+ * if (loif.if_flags & IFF_UP)
+ * It allowed local traffic to be forced through
+ * the hardware by configuring the loopback down.
+ * However, it causes problems during network
+ * configuration for boards that can't receive
+ * packets they send. It is now necessary to clear
+ * "useloopback" and remove the route to force
+ * traffic out to the hardware.
+ */
+ rt->rt_expire = 0;
+ Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
+ LLADDR(SDL(gate)),
+ SDL(gate)->sdl_alen = ETHER_ADDR_LEN);
+ if (useloopback)
+ rt->rt_ifp = &loif;
+ }
+ break;
+
+ case RTM_DELETE:
+ if (la == 0)
+ break;
+ arp_inuse--;
+ LIST_REMOVE(la, la_list);
+ rt->rt_llinfo = 0;
+ rt->rt_flags &= ~RTF_LLINFO;
+ if (la->la_hold)
+ m_freem(la->la_hold);
+ Free((caddr_t)la);
+ }
+}
+
+/*
+ * Broadcast an ARP request. Caller specifies:
+ * - arp header source ip address
+ * - arp header target ip address
+ * - arp header source ethernet address
+ */
+static void
+arprequest(ac, sip, tip, enaddr)
+ register struct arpcom *ac;
+ register u_int32_t *sip, *tip;
+ register u_int8_t *enaddr;
+{
+ register struct mbuf *m;
+ register struct ether_header *eh;
+ register struct ether_arp *ea;
+ struct sockaddr sa;
+
+ if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
+ return;
+ m->m_len = sizeof(*ea);
+ m->m_pkthdr.len = sizeof(*ea);
+ MH_ALIGN(m, sizeof(*ea));
+ ea = mtod(m, struct ether_arp *);
+ eh = (struct ether_header *)sa.sa_data;
+ bzero((caddr_t)ea, sizeof (*ea));
+ bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
+ sizeof(eh->ether_dhost));
+ eh->ether_type = htons(ETHERTYPE_ARP); /* if_output will not swap */
+ ea->arp_hrd = htons(ARPHRD_ETHER);
+ ea->arp_pro = htons(ETHERTYPE_IP);
+ ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
+ ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
+ ea->arp_op = htons(ARPOP_REQUEST);
+ bcopy((caddr_t)enaddr, (caddr_t)eh->ether_shost,
+ sizeof(eh->ether_shost));
+ bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
+ bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
+ bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
+}
+
+/*
+ * Resolve an IP address into an ethernet address. If success,
+ * desten is filled in. If there is no entry in arptab,
+ * set one up and broadcast a request for the IP address.
+ * Hold onto this mbuf and resend it once the address
+ * is finally resolved. A return value of 1 indicates
+ * that desten has been filled in and the packet should be sent
+ * normally; a 0 return indicates that the packet has been
+ * taken over here, either now or for later transmission.
+ */
+int
+arpresolve(ac, rt, m, dst, desten)
+ register struct arpcom *ac;
+ register struct rtentry *rt;
+ struct mbuf *m;
+ register struct sockaddr *dst;
+ register u_char *desten;
+{
+ register struct llinfo_arp *la;
+ struct sockaddr_dl *sdl;
+
+ if (m->m_flags & M_BCAST) { /* broadcast */
+ bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
+ sizeof(etherbroadcastaddr));
+ return (1);
+ }
+ if (m->m_flags & M_MCAST) { /* multicast */
+ ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
+ return (1);
+ }
+ if (rt)
+ la = (struct llinfo_arp *)rt->rt_llinfo;
+ else {
+ if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)) != NULL)
+ rt = la->la_rt;
+ }
+ if (la == 0 || rt == 0) {
+#ifdef __ECOS
+#else
+ log(LOG_DEBUG, "arpresolve: can't allocate llinfo\n");
+#endif
+ m_freem(m);
+ return (0);
+ }
+ sdl = SDL(rt->rt_gateway);
+ /*
+ * Check the address family and length is valid, the address
+ * is resolved; otherwise, try to resolve.
+ */
+ if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) &&
+ sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
+ bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
+ return 1;
+ }
+ if (((struct ifnet *)ac)->if_flags & IFF_NOARP)
+ return 0;
+
+ /*
+ * There is an arptab entry, but no ethernet address
+ * response yet. Replace the held mbuf with this
+ * latest one.
+ */
+ if (la->la_hold)
+ m_freem(la->la_hold);
+ la->la_hold = m;
+ /*
+ * Re-send the ARP request when appropriate.
+ */
+#ifdef DIAGNOSTIC
+ if (rt->rt_expire == 0) {
+ /* This should never happen. (Should it? -gwr) */
+ printf("arpresolve: unresolved and rt_expire == 0\n");
+ /* Set expiration time to now (expired). */
+ rt->rt_expire = time.tv_sec;
+ }
+#endif
+ if (rt->rt_expire) {
+ rt->rt_flags &= ~RTF_REJECT;
+ if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) {
+ rt->rt_expire = time.tv_sec;
+ if (la->la_asked++ < arp_maxtries)
+ arprequest(ac,
+ &(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr),
+ &(SIN(dst)->sin_addr.s_addr),
+ ac->ac_enaddr);
+ else {
+ rt->rt_flags |= RTF_REJECT;
+ rt->rt_expire += arpt_down;
+ la->la_asked = 0;
+ }
+ }
+ }
+ return (0);
+}
+
+/*
+ * Common length and type checks are done here,
+ * then the protocol-specific routine is called.
+ */
+void
+arpintr()
+{
+ register struct mbuf *m;
+ register struct arphdr *ar;
+ int s;
+
+ while (arpintrq.ifq_head) {
+ s = splimp();
+ IF_DEQUEUE(&arpintrq, m);
+ splx(s);
+ if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
+ panic("arpintr");
+ if (m->m_len >= sizeof(struct arphdr) &&
+ (ar = mtod(m, struct arphdr *)) &&
+ ntohs(ar->ar_hrd) == ARPHRD_ETHER &&
+ m->m_len >=
+ sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
+ switch (ntohs(ar->ar_pro)) {
+
+ case ETHERTYPE_IP:
+ case ETHERTYPE_IPTRAILERS:
+ in_arpinput(m);
+ continue;
+ }
+ m_freem(m);
+ }
+}
+
+/*
+ * ARP for Internet protocols on Ethernet.
+ * Algorithm is that given in RFC 826.
+ * In addition, a sanity check is performed on the sender
+ * protocol address, to catch impersonators.
+ * We no longer handle negotiations for use of trailer protocol:
+ * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
+ * along with IP replies if we wanted trailers sent to us,
+ * and also sent them in response to IP replies.
+ * This allowed either end to announce the desire to receive
+ * trailer packets.
+ * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
+ * but formerly didn't normally send requests.
+ */
+static void
+in_arpinput(m)
+ struct mbuf *m;
+{
+ register struct ether_arp *ea;
+ register struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
+ struct ether_header *eh;
+ register struct llinfo_arp *la = 0;
+ register struct rtentry *rt;
+ struct in_ifaddr *ia, *maybe_ia = 0;
+ struct sockaddr_dl *sdl;
+ struct sockaddr sa;
+ struct in_addr isaddr, itaddr, myaddr;
+ int op;
+
+ ea = mtod(m, struct ether_arp *);
+ op = ntohs(ea->arp_op);
+ bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr));
+ bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr));
+ for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
+ if (ia->ia_ifp == &ac->ac_if ||
+ (ia->ia_ifp->if_bridge &&
+ ia->ia_ifp->if_bridge == ac->ac_if.if_bridge)) {
+ maybe_ia = ia;
+ if (itaddr.s_addr == ia->ia_addr.sin_addr.s_addr ||
+ isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
+ break;
+ }
+ if (maybe_ia == 0)
+ goto out;
+ myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;
+ if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
+ sizeof (ea->arp_sha)))
+ goto out; /* it's from me, ignore it. */
+ if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
+ sizeof (ea->arp_sha))) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR,
+ "arp: ether address is broadcast for IP address %s!\n",
+ inet_ntoa(isaddr));
+#endif
+ goto out;
+ }
+ if (isaddr.s_addr == myaddr.s_addr) {
+#ifdef __ECOS
+#else
+ log(LOG_ERR,
+ "duplicate IP address %s sent from ethernet address %s\n",
+ inet_ntoa(isaddr), ether_sprintf(ea->arp_sha));
+#endif
+ itaddr = myaddr;
+ goto reply;
+ }
+ la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
+ if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
+ if (sdl->sdl_alen &&
+ bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
+ if (rt->rt_flags & RTF_PERMANENT_ARP) {
+#ifdef __ECOS
+#else
+ log(LOG_WARNING,
+ "arp: attempt to overwrite permanent "
+ "entry for %s by %s on %s\n",
+ inet_ntoa(isaddr),
+ ether_sprintf(ea->arp_sha),
+ (&ac->ac_if)->if_xname);
+#endif
+ goto out;
+ } else if (rt->rt_ifp != &ac->ac_if) {
+#ifdef __ECOS
+#else
+ log(LOG_WARNING,
+ "arp: attempt to overwrite entry for %s "
+ "on %s by %s on %s\n",
+ inet_ntoa(isaddr), rt->rt_ifp->if_xname,
+ ether_sprintf(ea->arp_sha),
+ (&ac->ac_if)->if_xname);
+#endif
+ goto out;
+ } else {
+#ifdef __ECOS
+#else
+ log(LOG_INFO,
+ "arp info overwritten for %s by %s on %s\n",
+ inet_ntoa(isaddr),
+ ether_sprintf(ea->arp_sha),
+ (&ac->ac_if)->if_xname);
+#endif
+ rt->rt_expire = 1; /* no longer static */
+ }
+ }
+ bcopy((caddr_t)ea->arp_sha, LLADDR(sdl),
+ sdl->sdl_alen = sizeof(ea->arp_sha));
+ if (rt->rt_expire)
+ rt->rt_expire = time.tv_sec + arpt_keep;
+ rt->rt_flags &= ~RTF_REJECT;
+ la->la_asked = 0;
+ if (la->la_hold) {
+ (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
+ rt_key(rt), rt);
+ la->la_hold = 0;
+ }
+ }
+reply:
+ if (op != ARPOP_REQUEST) {
+ out:
+ m_freem(m);
+ return;
+ }
+ if (itaddr.s_addr == myaddr.s_addr) {
+ /* I am the target */
+ bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
+ sizeof(ea->arp_sha));
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
+ sizeof(ea->arp_sha));
+ } else {
+ la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
+ if (la == 0)
+ goto out;
+ rt = la->la_rt;
+ bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
+ sizeof(ea->arp_sha));
+ sdl = SDL(rt->rt_gateway);
+ bcopy(LLADDR(sdl), (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
+ }
+
+ bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, sizeof(ea->arp_spa));
+ bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
+ ea->arp_op = htons(ARPOP_REPLY);
+ ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
+ eh = (struct ether_header *)sa.sa_data;
+ bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,
+ sizeof(eh->ether_dhost));
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
+ sizeof(eh->ether_shost));
+ eh->ether_type = htons(ETHERTYPE_ARP);
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
+ return;
+}
+
+/*
+ * Free an arp entry.
+ */
+static void
+arptfree(la)
+ register struct llinfo_arp *la;
+{
+ register struct rtentry *rt = la->la_rt;
+ register struct sockaddr_dl *sdl;
+
+ if (rt == 0)
+ panic("arptfree");
+ if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
+ sdl->sdl_family == AF_LINK) {
+ sdl->sdl_alen = 0;
+ la->la_asked = 0;
+ rt->rt_flags &= ~RTF_REJECT;
+ return;
+ }
+ rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
+ 0, (struct rtentry **)0);
+}
+
+/*
+ * Lookup or enter a new address in arptab.
+ */
+static struct llinfo_arp *
+arplookup(addr, create, proxy)
+ u_int32_t addr;
+ int create, proxy;
+{
+ register struct rtentry *rt;
+ static struct sockaddr_inarp sin;
+
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = addr;
+ sin.sin_other = proxy ? SIN_PROXY : 0;
+ rt = rtalloc1(sintosa(&sin), create);
+ if (rt == 0)
+ return (0);
+ rt->rt_refcnt--;
+ if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
+ rt->rt_gateway->sa_family != AF_LINK) {
+ if (create)
+#ifdef __ECOS
+#else
+ log(LOG_DEBUG,
+ "arplookup: unable to enter address for %s\n",
+ inet_ntoa(sin.sin_addr));
+#endif
+ return (0);
+ }
+ return ((struct llinfo_arp *)rt->rt_llinfo);
+}
+
+int
+arpioctl(cmd, data)
+ u_long cmd;
+ caddr_t data;
+{
+
+ return (EOPNOTSUPP);
+}
+
+void
+arp_ifinit(ac, ifa)
+ struct arpcom *ac;
+ struct ifaddr *ifa;
+{
+
+ /* Warn the user if another station has this IP address. */
+ arprequest(ac,
+ &(IA_SIN(ifa)->sin_addr.s_addr),
+ &(IA_SIN(ifa)->sin_addr.s_addr),
+ ac->ac_enaddr);
+ ifa->ifa_rtrequest = arp_rtrequest;
+ ifa->ifa_flags |= RTF_CLONING;
+}
+
+/*
+ * Called from Ethernet interrupt handlers
+ * when ether packet type ETHERTYPE_REVARP
+ * is received. Common length and type checks are done here,
+ * then the protocol-specific routine is called.
+ */
+void
+revarpinput(m)
+ struct mbuf *m;
+{
+ struct arphdr *ar;
+
+ if (m->m_len < sizeof(struct arphdr))
+ goto out;
+ ar = mtod(m, struct arphdr *);
+ if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
+ goto out;
+ if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
+ goto out;
+ switch (ntohs(ar->ar_pro)) {
+
+ case ETHERTYPE_IP:
+ case ETHERTYPE_IPTRAILERS:
+ in_revarpinput(m);
+ return;
+
+ default:
+ break;
+ }
+out:
+ m_freem(m);
+}
+
+/*
+ * RARP for Internet protocols on Ethernet.
+ * Algorithm is that given in RFC 903.
+ * We are only using for bootstrap purposes to get an ip address for one of
+ * our interfaces. Thus we support no user-interface.
+ *
+ * Since the contents of the RARP reply are specific to the interface that
+ * sent the request, this code must ensure that they are properly associated.
+ *
+ * Note: also supports ARP via RARP packets, per the RFC.
+ */
+void
+in_revarpinput(m)
+ struct mbuf *m;
+{
+ struct ifnet *ifp;
+ struct ether_arp *ar;
+ int op;
+
+ ar = mtod(m, struct ether_arp *);
+ op = ntohs(ar->arp_op);
+ switch (op) {
+ case ARPOP_REQUEST:
+ case ARPOP_REPLY: /* per RFC */
+ in_arpinput(m);
+ return;
+ case ARPOP_REVREPLY:
+ break;
+ case ARPOP_REVREQUEST: /* handled by rarpd(8) */
+ default:
+ goto out;
+ }
+ if (!revarp_in_progress)
+ goto out;
+ ifp = m->m_pkthdr.rcvif;
+ if (ifp != myip_ifp) /* !same interface */
+ goto out;
+ if (myip_initialized)
+ goto wake;
+ if (bcmp(ar->arp_tha, ((struct arpcom *)ifp)->ac_enaddr,
+ sizeof(ar->arp_tha)))
+ goto out;
+ bcopy((caddr_t)ar->arp_spa, (caddr_t)&srv_ip, sizeof(srv_ip));
+ bcopy((caddr_t)ar->arp_tpa, (caddr_t)&myip, sizeof(myip));
+ myip_initialized = 1;
+wake: /* Do wakeup every time in case it was missed. */
+ wakeup((caddr_t)&myip);
+
+out:
+ m_freem(m);
+}
+
+/*
+ * Send a RARP request for the ip address of the specified interface.
+ * The request should be RFC 903-compliant.
+ */
+void
+revarprequest(ifp)
+ struct ifnet *ifp;
+{
+ struct sockaddr sa;
+ struct mbuf *m;
+ struct ether_header *eh;
+ struct ether_arp *ea;
+ struct arpcom *ac = (struct arpcom *)ifp;
+
+ if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
+ return;
+ m->m_len = sizeof(*ea);
+ m->m_pkthdr.len = sizeof(*ea);
+ MH_ALIGN(m, sizeof(*ea));
+ ea = mtod(m, struct ether_arp *);
+ eh = (struct ether_header *)sa.sa_data;
+ bzero((caddr_t)ea, sizeof(*ea));
+ bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
+ sizeof(eh->ether_dhost));
+ eh->ether_type = htons(ETHERTYPE_REVARP);
+ ea->arp_hrd = htons(ARPHRD_ETHER);
+ ea->arp_pro = htons(ETHERTYPE_IP);
+ ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
+ ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
+ ea->arp_op = htons(ARPOP_REVREQUEST);
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
+ sizeof(ea->arp_tha));
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
+ sizeof(ea->arp_sha));
+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha,
+ sizeof(ea->arp_tha));
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ ifp->if_output(ifp, m, &sa, (struct rtentry *)0);
+}
+
+/*
+ * RARP for the ip address of the specified interface, but also
+ * save the ip address of the server that sent the answer.
+ * Timeout if no response is received.
+ */
+int
+revarpwhoarewe(ifp, serv_in, clnt_in)
+ struct ifnet *ifp;
+ struct in_addr *serv_in;
+ struct in_addr *clnt_in;
+{
+ int result, count = 20;
+
+ if (myip_initialized)
+ return EIO;
+
+ myip_ifp = ifp;
+ revarp_in_progress = 1;
+ while (count--) {
+ revarprequest(ifp);
+ result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2);
+ if (result != EWOULDBLOCK)
+ break;
+ }
+ revarp_in_progress = 0;
+ if (!myip_initialized)
+ return ENETUNREACH;
+
+ bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in));
+ bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in));
+ return 0;
+}
+
+/* For compatibility: only saves interface address. */
+int
+revarpwhoami(in, ifp)
+ struct in_addr *in;
+ struct ifnet *ifp;
+{
+ struct in_addr server;
+ return (revarpwhoarewe(ifp, &server, in));
+}
+
+
+#ifdef DDB
+
+#include <machine/db_machdep.h>
+#include <ddb/db_interface.h>
+#include <ddb/db_output.h>
+
+static void
+db_print_sa(sa)
+ struct sockaddr *sa;
+{
+ int len;
+ u_char *p;
+
+ if (sa == 0) {
+ db_printf("[NULL]");
+ return;
+ }
+
+ p = (u_char*)sa;
+ len = sa->sa_len;
+ db_printf("[");
+ while (len > 0) {
+ db_printf("%d", *p);
+ p++;
+ len--;
+ if (len)
+ db_printf(",");
+ }
+ db_printf("]\n");
+}
+
+static void
+db_print_ifa(ifa)
+ struct ifaddr *ifa;
+{
+ if (ifa == 0)
+ return;
+ db_printf(" ifa_addr=");
+ db_print_sa(ifa->ifa_addr);
+ db_printf(" ifa_dsta=");
+ db_print_sa(ifa->ifa_dstaddr);
+ db_printf(" ifa_mask=");
+ db_print_sa(ifa->ifa_netmask);
+ db_printf(" flags=0x%x, refcnt=%d, metric=%d\n",
+ ifa->ifa_flags, ifa->ifa_refcnt, ifa->ifa_metric);
+}
+
+static void
+db_print_llinfo(li)
+ caddr_t li;
+{
+ struct llinfo_arp *la;
+
+ if (li == 0)
+ return;
+ la = (struct llinfo_arp *)li;
+ db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n",
+ la->la_rt, la->la_hold, la->la_asked);
+}
+
+/*
+ * Function to pass to rn_walktree().
+ * Return non-zero error to abort walk.
+ */
+static int
+db_show_radix_node(rn, w)
+ struct radix_node *rn;
+ void *w;
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+
+ db_printf("rtentry=%p", rt);
+
+ db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n",
+ rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire);
+
+ db_printf(" key="); db_print_sa(rt_key(rt));
+ db_printf(" mask="); db_print_sa(rt_mask(rt));
+ db_printf(" gw="); db_print_sa(rt->rt_gateway);
+
+ db_printf(" ifp=%p ", rt->rt_ifp);
+ if (rt->rt_ifp)
+ db_printf("(%s)", rt->rt_ifp->if_xname);
+ else
+ db_printf("(NULL)");
+
+ db_printf(" ifa=%p\n", rt->rt_ifa);
+ db_print_ifa(rt->rt_ifa);
+
+ db_printf(" genmask="); db_print_sa(rt->rt_genmask);
+
+ db_printf(" gwroute=%p llinfo=%p\n", rt->rt_gwroute, rt->rt_llinfo);
+ db_print_llinfo(rt->rt_llinfo);
+ return (0);
+}
+
+/*
+ * Function to print all the route trees.
+ * Use this from ddb: "call db_show_arptab"
+ */
+int
+db_show_arptab()
+{
+ struct radix_node_head *rnh;
+ rnh = rt_tables[AF_INET];
+ db_printf("Route tree for AF_INET\n");
+ if (rnh == NULL) {
+ db_printf(" (not initialized)\n");
+ return (0);
+ }
+ rn_walktree(rnh, db_show_radix_node, NULL);
+ return (0);
+}
+#endif
+#endif /* INET */
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/igmp.c b/ecos/packages/net/tcpip/current/src/sys/netinet/igmp.c
new file mode 100644
index 0000000..f84c84f
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/igmp.c
@@ -0,0 +1,614 @@
+//==========================================================================
+//
+// sys/netinet/igmp.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: igmp.c,v 1.6 1999/12/08 06:50:19 itojun Exp $ */
+/* $NetBSD: igmp.c,v 1.15 1996/02/13 23:41:25 christos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Internet Group Management Protocol (IGMP) routines.
+ *
+ * Written by Steve Deering, Stanford, May 1988.
+ * Modified by Rosen Sharma, Stanford, Aug 1994.
+ * Modified by Bill Fenner, Xerox PARC, Feb 1995.
+ *
+ * MULTICAST Revision: 1.3
+ */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/igmp.h>
+#include <netinet/igmp_var.h>
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+
+#include <machine/stdarg.h>
+
+#define IP_MULTICASTOPTS 0
+
+int igmp_timers_are_running;
+static struct router_info *rti_head;
+
+void igmp_sendpkt __P((struct in_multi *, int));
+static int rti_fill __P((struct in_multi *));
+static struct router_info * rti_find __P((struct ifnet *));
+
+void
+igmp_init()
+{
+
+ /*
+ * To avoid byte-swapping the same value over and over again.
+ */
+ igmp_timers_are_running = 0;
+ rti_head = 0;
+}
+
+static int
+rti_fill(inm)
+ struct in_multi *inm;
+{
+ register struct router_info *rti;
+
+ for (rti = rti_head; rti != 0; rti = rti->rti_next) {
+ if (rti->rti_ifp == inm->inm_ifp) {
+ inm->inm_rti = rti;
+ if (rti->rti_type == IGMP_v1_ROUTER)
+ return (IGMP_v1_HOST_MEMBERSHIP_REPORT);
+ else
+ return (IGMP_v2_HOST_MEMBERSHIP_REPORT);
+ }
+ }
+
+ rti = (struct router_info *)malloc(sizeof(struct router_info),
+ M_MRTABLE, M_NOWAIT);
+ rti->rti_ifp = inm->inm_ifp;
+ rti->rti_type = IGMP_v2_ROUTER;
+ rti->rti_next = rti_head;
+ rti_head = rti;
+ inm->inm_rti = rti;
+ return (IGMP_v2_HOST_MEMBERSHIP_REPORT);
+}
+
+static struct router_info *
+rti_find(ifp)
+ struct ifnet *ifp;
+{
+ register struct router_info *rti;
+
+ for (rti = rti_head; rti != 0; rti = rti->rti_next) {
+ if (rti->rti_ifp == ifp)
+ return (rti);
+ }
+
+ rti = (struct router_info *)malloc(sizeof(struct router_info),
+ M_MRTABLE, M_NOWAIT);
+ rti->rti_ifp = ifp;
+ rti->rti_type = IGMP_v2_ROUTER;
+ rti->rti_next = rti_head;
+ rti_head = rti;
+ return (rti);
+}
+
+void
+rti_delete(ifp)
+ struct ifnet *ifp;
+{
+ struct router_info *rti, **prti = &rti_head;
+
+ for (rti = rti_head; rti != 0; rti = rti->rti_next) {
+ if (rti->rti_ifp == ifp) {
+ *prti = rti->rti_next;
+ free(rti, M_MRTABLE);
+ break;
+ }
+ prti = &rti->rti_next;
+ }
+}
+
+void
+#if __STDC__
+igmp_input(struct mbuf *m, ...)
+#else
+igmp_input(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ int proto;
+ register int iphlen;
+ register struct ifnet *ifp = m->m_pkthdr.rcvif;
+ register struct ip *ip = mtod(m, struct ip *);
+ register struct igmp *igmp;
+ register int igmplen;
+ register int minlen;
+ struct in_multi *inm;
+ struct in_multistep step;
+ struct router_info *rti;
+ register struct in_ifaddr *ia;
+ int timer;
+ va_list ap;
+
+ va_start(ap, m);
+ iphlen = va_arg(ap, int);
+ proto = va_arg(ap, int);
+ va_end(ap);
+
+ ++igmpstat.igps_rcv_total;
+
+ igmplen = ip->ip_len;
+
+ /*
+ * Validate lengths
+ */
+ if (igmplen < IGMP_MINLEN) {
+ ++igmpstat.igps_rcv_tooshort;
+ m_freem(m);
+ return;
+ }
+ minlen = iphlen + IGMP_MINLEN;
+ if ((m->m_flags & M_EXT || m->m_len < minlen) &&
+ (m = m_pullup(m, minlen)) == 0) {
+ ++igmpstat.igps_rcv_tooshort;
+ return;
+ }
+
+ /*
+ * Validate checksum
+ */
+ m->m_data += iphlen;
+ m->m_len -= iphlen;
+ igmp = mtod(m, struct igmp *);
+ if (in_cksum(m, igmplen)) {
+ ++igmpstat.igps_rcv_badsum;
+ m_freem(m);
+ return;
+ }
+ m->m_data -= iphlen;
+ m->m_len += iphlen;
+ ip = mtod(m, struct ip *);
+
+ switch (igmp->igmp_type) {
+
+ case IGMP_HOST_MEMBERSHIP_QUERY:
+ ++igmpstat.igps_rcv_queries;
+
+ if (ifp->if_flags & IFF_LOOPBACK)
+ break;
+
+ if (igmp->igmp_code == 0) {
+ rti = rti_find(ifp);
+ rti->rti_type = IGMP_v1_ROUTER;
+ rti->rti_age = 0;
+
+ if (ip->ip_dst.s_addr != INADDR_ALLHOSTS_GROUP) {
+ ++igmpstat.igps_rcv_badqueries;
+ m_freem(m);
+ return;
+ }
+
+ /*
+ * Start the timers in all of our membership records
+ * for the interface on which the query arrived,
+ * except those that are already running and those
+ * that belong to a "local" group (224.0.0.X).
+ */
+ IN_FIRST_MULTI(step, inm);
+ while (inm != NULL) {
+ if (inm->inm_ifp == ifp &&
+ inm->inm_timer == 0 &&
+ !IN_LOCAL_GROUP(inm->inm_addr.s_addr)) {
+ inm->inm_state = IGMP_DELAYING_MEMBER;
+ inm->inm_timer = IGMP_RANDOM_DELAY(
+ IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ);
+ igmp_timers_are_running = 1;
+ }
+ IN_NEXT_MULTI(step, inm);
+ }
+ } else {
+ if (!IN_MULTICAST(ip->ip_dst.s_addr)) {
+ ++igmpstat.igps_rcv_badqueries;
+ m_freem(m);
+ return;
+ }
+
+ timer = igmp->igmp_code * PR_FASTHZ / IGMP_TIMER_SCALE;
+
+ /*
+ * Start the timers in all of our membership records
+ * for the interface on which the query arrived,
+ * except those that are already running and those
+ * that belong to a "local" group (224.0.0.X). For
+ * timers already running, check if they need to be
+ * reset.
+ */
+ IN_FIRST_MULTI(step, inm);
+ while (inm != NULL) {
+ if (inm->inm_ifp == ifp &&
+ !IN_LOCAL_GROUP(inm->inm_addr.s_addr) &&
+ (ip->ip_dst.s_addr == INADDR_ALLHOSTS_GROUP ||
+ ip->ip_dst.s_addr == inm->inm_addr.s_addr)) {
+ switch (inm->inm_state) {
+ case IGMP_DELAYING_MEMBER:
+ if (inm->inm_timer <= timer)
+ break;
+ /* FALLTHROUGH */
+ case IGMP_IDLE_MEMBER:
+ case IGMP_LAZY_MEMBER:
+ case IGMP_AWAKENING_MEMBER:
+ inm->inm_state =
+ IGMP_DELAYING_MEMBER;
+ inm->inm_timer =
+ IGMP_RANDOM_DELAY(timer);
+ igmp_timers_are_running = 1;
+ break;
+ case IGMP_SLEEPING_MEMBER:
+ inm->inm_state =
+ IGMP_AWAKENING_MEMBER;
+ break;
+ }
+ }
+ IN_NEXT_MULTI(step, inm);
+ }
+ }
+
+ break;
+
+ case IGMP_v1_HOST_MEMBERSHIP_REPORT:
+ ++igmpstat.igps_rcv_reports;
+
+ if (ifp->if_flags & IFF_LOOPBACK)
+ break;
+
+ if (!IN_MULTICAST(igmp->igmp_group.s_addr) ||
+ igmp->igmp_group.s_addr != ip->ip_dst.s_addr) {
+ ++igmpstat.igps_rcv_badreports;
+ m_freem(m);
+ return;
+ }
+
+ /*
+ * KLUDGE: if the IP source address of the report has an
+ * unspecified (i.e., zero) subnet number, as is allowed for
+ * a booting host, replace it with the correct subnet number
+ * so that a process-level multicast routing daemon can
+ * determine which subnet it arrived from. This is necessary
+ * to compensate for the lack of any way for a process to
+ * determine the arrival interface of an incoming packet.
+ */
+ if ((ip->ip_src.s_addr & IN_CLASSA_NET) == 0) {
+ IFP_TO_IA(ifp, ia);
+ if (ia)
+ ip->ip_src.s_addr = ia->ia_subnet;
+ }
+
+ /*
+ * If we belong to the group being reported, stop
+ * our timer for that group.
+ */
+ IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm);
+ if (inm != NULL) {
+ inm->inm_timer = 0;
+ ++igmpstat.igps_rcv_ourreports;
+
+ switch (inm->inm_state) {
+ case IGMP_IDLE_MEMBER:
+ case IGMP_LAZY_MEMBER:
+ case IGMP_AWAKENING_MEMBER:
+ case IGMP_SLEEPING_MEMBER:
+ inm->inm_state = IGMP_SLEEPING_MEMBER;
+ break;
+ case IGMP_DELAYING_MEMBER:
+ if (inm->inm_rti->rti_type == IGMP_v1_ROUTER)
+ inm->inm_state = IGMP_LAZY_MEMBER;
+ else
+ inm->inm_state = IGMP_SLEEPING_MEMBER;
+ break;
+ }
+ }
+
+ break;
+
+ case IGMP_v2_HOST_MEMBERSHIP_REPORT:
+#ifdef MROUTING
+ /*
+ * Make sure we don't hear our own membership report. Fast
+ * leave requires knowing that we are the only member of a
+ * group.
+ */
+ IFP_TO_IA(ifp, ia);
+ if (ia && ip->ip_src.s_addr == ia->ia_addr.sin_addr.s_addr)
+ break;
+#endif
+
+ ++igmpstat.igps_rcv_reports;
+
+ if (ifp->if_flags & IFF_LOOPBACK)
+ break;
+
+ if (!IN_MULTICAST(igmp->igmp_group.s_addr) ||
+ igmp->igmp_group.s_addr != ip->ip_dst.s_addr) {
+ ++igmpstat.igps_rcv_badreports;
+ m_freem(m);
+ return;
+ }
+
+ /*
+ * KLUDGE: if the IP source address of the report has an
+ * unspecified (i.e., zero) subnet number, as is allowed for
+ * a booting host, replace it with the correct subnet number
+ * so that a process-level multicast routing daemon can
+ * determine which subnet it arrived from. This is necessary
+ * to compensate for the lack of any way for a process to
+ * determine the arrival interface of an incoming packet.
+ */
+ if ((ip->ip_src.s_addr & IN_CLASSA_NET) == 0) {
+#ifndef MROUTING
+ IFP_TO_IA(ifp, ia);
+#endif
+ if (ia)
+ ip->ip_src.s_addr = ia->ia_subnet;
+ }
+
+ /*
+ * If we belong to the group being reported, stop
+ * our timer for that group.
+ */
+ IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm);
+ if (inm != NULL) {
+ inm->inm_timer = 0;
+ ++igmpstat.igps_rcv_ourreports;
+
+ switch (inm->inm_state) {
+ case IGMP_DELAYING_MEMBER:
+ case IGMP_IDLE_MEMBER:
+ case IGMP_AWAKENING_MEMBER:
+ inm->inm_state = IGMP_LAZY_MEMBER;
+ break;
+ case IGMP_LAZY_MEMBER:
+ case IGMP_SLEEPING_MEMBER:
+ break;
+ }
+ }
+
+ break;
+
+ }
+
+ /*
+ * Pass all valid IGMP packets up to any process(es) listening
+ * on a raw IGMP socket.
+ */
+ rip_input(m, iphlen, proto);
+ return;
+}
+
+void
+igmp_joingroup(inm)
+ struct in_multi *inm;
+{
+ int s = splsoftnet();
+
+ inm->inm_state = IGMP_IDLE_MEMBER;
+
+ if (!IN_LOCAL_GROUP(inm->inm_addr.s_addr) &&
+ (inm->inm_ifp->if_flags & IFF_LOOPBACK) == 0) {
+ igmp_sendpkt(inm, rti_fill(inm));
+ inm->inm_state = IGMP_DELAYING_MEMBER;
+ inm->inm_timer = IGMP_RANDOM_DELAY(
+ IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ);
+ igmp_timers_are_running = 1;
+ } else
+ inm->inm_timer = 0;
+ splx(s);
+}
+
+void
+igmp_leavegroup(inm)
+ struct in_multi *inm;
+{
+
+ switch (inm->inm_state) {
+ case IGMP_DELAYING_MEMBER:
+ case IGMP_IDLE_MEMBER:
+ if (!IN_LOCAL_GROUP(inm->inm_addr.s_addr) &&
+ (inm->inm_ifp->if_flags & IFF_LOOPBACK) == 0)
+ if (inm->inm_rti->rti_type != IGMP_v1_ROUTER)
+ igmp_sendpkt(inm, IGMP_HOST_LEAVE_MESSAGE);
+ break;
+ case IGMP_LAZY_MEMBER:
+ case IGMP_AWAKENING_MEMBER:
+ case IGMP_SLEEPING_MEMBER:
+ break;
+ }
+}
+
+void
+igmp_fasttimo()
+{
+ register struct in_multi *inm;
+ struct in_multistep step;
+ int s;
+
+ /*
+ * Quick check to see if any work needs to be done, in order
+ * to minimize the overhead of fasttimo processing.
+ */
+ if (!igmp_timers_are_running)
+ return;
+
+ s = splsoftnet();
+ igmp_timers_are_running = 0;
+ IN_FIRST_MULTI(step, inm);
+ while (inm != NULL) {
+ if (inm->inm_timer == 0) {
+ /* do nothing */
+ } else if (--inm->inm_timer == 0) {
+ if (inm->inm_state == IGMP_DELAYING_MEMBER) {
+ if (inm->inm_rti->rti_type == IGMP_v1_ROUTER)
+ igmp_sendpkt(inm,
+ IGMP_v1_HOST_MEMBERSHIP_REPORT);
+ else
+ igmp_sendpkt(inm,
+ IGMP_v2_HOST_MEMBERSHIP_REPORT);
+ inm->inm_state = IGMP_IDLE_MEMBER;
+ }
+ } else {
+ igmp_timers_are_running = 1;
+ }
+ IN_NEXT_MULTI(step, inm);
+ }
+ splx(s);
+}
+
+void
+igmp_slowtimo()
+{
+ register struct router_info *rti;
+ int s;
+
+ s = splsoftnet();
+ for (rti = rti_head; rti != 0; rti = rti->rti_next) {
+ if (rti->rti_type == IGMP_v1_ROUTER &&
+ ++rti->rti_age >= IGMP_AGE_THRESHOLD) {
+ rti->rti_type = IGMP_v2_ROUTER;
+ }
+ }
+ splx(s);
+}
+
+void
+igmp_sendpkt(inm, type)
+ struct in_multi *inm;
+ int type;
+{
+ struct mbuf *m;
+ struct igmp *igmp;
+ struct ip *ip;
+ struct ip_moptions imo;
+#ifdef MROUTING
+ extern struct socket *ip_mrouter;
+#endif /* MROUTING */
+
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return;
+ /*
+ * Assume max_linkhdr + sizeof(struct ip) + IGMP_MINLEN
+ * is smaller than mbuf size returned by MGETHDR.
+ */
+ m->m_data += max_linkhdr;
+ m->m_len = sizeof(struct ip) + IGMP_MINLEN;
+ m->m_pkthdr.len = sizeof(struct ip) + IGMP_MINLEN;
+
+ ip = mtod(m, struct ip *);
+ ip->ip_tos = 0;
+ ip->ip_len = sizeof(struct ip) + IGMP_MINLEN;
+ ip->ip_off = 0;
+ ip->ip_p = IPPROTO_IGMP;
+ ip->ip_src.s_addr = INADDR_ANY;
+ ip->ip_dst = inm->inm_addr;
+
+ m->m_data += sizeof(struct ip);
+ m->m_len -= sizeof(struct ip);
+ igmp = mtod(m, struct igmp *);
+ igmp->igmp_type = type;
+ igmp->igmp_code = 0;
+ igmp->igmp_group = inm->inm_addr;
+ igmp->igmp_cksum = 0;
+ igmp->igmp_cksum = in_cksum(m, IGMP_MINLEN);
+ m->m_data -= sizeof(struct ip);
+ m->m_len += sizeof(struct ip);
+
+ imo.imo_multicast_ifp = inm->inm_ifp;
+ imo.imo_multicast_ttl = 1;
+#ifdef RSVP_ISI
+ imo.imo_multicast_vif = -1;
+#endif
+ /*
+ * Request loopback of the report if we are acting as a multicast
+ * router, so that the process-level routing demon can hear it.
+ */
+#ifdef MROUTING
+ imo.imo_multicast_loop = (ip_mrouter != NULL);
+#else
+ imo.imo_multicast_loop = 0;
+#endif /* MROUTING */
+
+#if 0 /*KAME IPSEC*/
+ m->m_pkthdr.rcvif = NULL;
+#endif /*IPSEC*/
+ ip_output(m, (struct mbuf *)0, (struct route *)0, IP_MULTICASTOPTS,
+ &imo, NULL);
+
+ ++igmpstat.igps_snd_reports;
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/in.c b/ecos/packages/net/tcpip/current/src/sys/netinet/in.c
new file mode 100644
index 0000000..1fb2f09
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/in.c
@@ -0,0 +1,902 @@
+//==========================================================================
+//
+// sys/netinet/in.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in.c,v 1.14 1999/12/08 06:50:19 itojun Exp $ */
+/* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in.c 8.2 (Berkeley) 11/15/93
+ */
+
+#ifdef __ECOS
+#include <pkgconf/net.h>
+#else
+#include "ether.h"
+#include "gif.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#if NGIF > 0
+#include <net/if_gif.h>
+#endif
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/igmp_var.h>
+
+#ifdef MROUTING
+#include <netinet/ip_mroute.h>
+#endif
+
+#ifdef INET
+
+static int in_mask2len __P((struct in_addr *));
+static void in_len2mask __P((struct in_addr *, int));
+static int in_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
+ struct ifnet *));
+
+#ifndef SUBNETSARELOCAL
+#define SUBNETSARELOCAL 0
+#endif
+int subnetsarelocal = SUBNETSARELOCAL;
+/*
+ * Return 1 if an internet address is for a ``local'' host
+ * (one to which we have a connection). If subnetsarelocal
+ * is true, this includes other subnets of the local net.
+ * Otherwise, it includes only the directly-connected (sub)nets.
+ */
+int
+in_localaddr(in)
+ struct in_addr in;
+{
+ register struct in_ifaddr *ia;
+
+ if (subnetsarelocal) {
+ for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
+ if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
+ return (1);
+ } else {
+ for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
+ if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Determine whether an IP address is in a reserved set of addresses
+ * that may not be forwarded, or whether datagrams to that destination
+ * may be forwarded.
+ */
+int
+in_canforward(in)
+ struct in_addr in;
+{
+ register u_int32_t net;
+
+ if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr))
+ return (0);
+ if (IN_CLASSA(in.s_addr)) {
+ net = in.s_addr & IN_CLASSA_NET;
+ if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Trim a mask in a sockaddr
+ */
+void
+in_socktrim(ap)
+ struct sockaddr_in *ap;
+{
+ register char *cplim = (char *) &ap->sin_addr;
+ register char *cp = (char *) (&ap->sin_addr + 1);
+
+ ap->sin_len = 0;
+ while (--cp >= cplim)
+ if (*cp) {
+ (ap)->sin_len = cp - (char *) (ap) + 1;
+ break;
+ }
+}
+
+static int
+in_mask2len(mask)
+ struct in_addr *mask;
+{
+ int x, y;
+ u_char *p;
+
+ p = (u_char *)mask;
+ for (x = 0; x < sizeof(*mask); x++) {
+ if (p[x] != 0xff)
+ break;
+ }
+ y = 0;
+ if (x < sizeof(*mask)) {
+ for (y = 0; y < 8; y++) {
+ if ((p[x] & (0x80 >> y)) == 0)
+ break;
+ }
+ }
+ return x * 8 + y;
+}
+
+static void
+in_len2mask(mask, len)
+ struct in_addr *mask;
+ int len;
+{
+ int i;
+ u_char *p;
+
+ p = (u_char *)mask;
+ bzero(mask, sizeof(*mask));
+ for (i = 0; i < len / 8; i++)
+ p[i] = 0xff;
+ if (len % 8)
+ p[i] = (0xff00 >> (len % 8)) & 0xff;
+}
+
+int in_interfaces; /* number of external internet interfaces */
+
+/*
+ * Generic internet control operations (ioctl's).
+ * Ifp is 0 if not an interface-specific ioctl.
+ */
+/* ARGSUSED */
+int
+in_control(so, cmd, data, ifp)
+ struct socket *so;
+ u_long cmd;
+ caddr_t data;
+ register struct ifnet *ifp;
+{
+ register struct ifreq *ifr = (struct ifreq *)data;
+ register struct in_ifaddr *ia = 0;
+ struct in_aliasreq *ifra = (struct in_aliasreq *)data;
+ struct sockaddr_in oldaddr;
+ int error, hostIsNew, maskIsNew;
+
+#if NGIF > 0
+ if (ifp && ifp->if_type == IFT_GIF) {
+ switch (cmd) {
+ case SIOCSIFPHYADDR:
+ if ((so->so_state & SS_PRIV) == 0)
+ return(EPERM);
+ case SIOCGIFPSRCADDR:
+ case SIOCGIFPDSTADDR:
+ return gif_ioctl(ifp, cmd, data);
+ }
+ }
+#endif
+
+ switch (cmd) {
+ case SIOCALIFADDR:
+ case SIOCDLIFADDR:
+ if ((so->so_state & SS_PRIV) == 0)
+ return(EPERM);
+ /*fall through*/
+ case SIOCGLIFADDR:
+ if (!ifp)
+ return EINVAL;
+ return in_lifaddr_ioctl(so, cmd, data, ifp);
+ }
+
+ /*
+ * Find address for this interface, if it exists.
+ */
+ if (ifp)
+ for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next)
+ if (ia->ia_ifp == ifp)
+ break;
+
+ switch (cmd) {
+
+ case SIOCAIFADDR:
+ case SIOCDIFADDR:
+
+ case SIOCSIFADDR: // Moved from after this search, otherwise repeated
+ // identical SIOCSIFADDRs leaked the previously allocated record.
+
+ if (ifra->ifra_addr.sin_family == AF_INET)
+ for (; ia != 0; ia = ia->ia_list.tqe_next) {
+ if (ia->ia_ifp == ifp &&
+ ia->ia_addr.sin_addr.s_addr ==
+ ifra->ifra_addr.sin_addr.s_addr)
+ break;
+ }
+ if (cmd == SIOCDIFADDR && ia == 0)
+ return (EADDRNOTAVAIL);
+ /* FALLTHROUGH */
+ case SIOCSIFNETMASK:
+ case SIOCSIFDSTADDR:
+ if ((so->so_state & SS_PRIV) == 0)
+ return (EPERM);
+
+ if (ifp == 0)
+ panic("in_control");
+ if (ia == (struct in_ifaddr *)0) {
+ ia = (struct in_ifaddr *)
+ malloc(sizeof *ia, M_IFADDR, M_WAITOK); // This alloc was leaked
+ if (ia == (struct in_ifaddr *)0)
+ return (ENOBUFS);
+ bzero((caddr_t)ia, sizeof *ia);
+ TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list);
+ TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
+ ifa_list);
+ ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
+ ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
+ ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
+ ia->ia_sockmask.sin_len = 8;
+ if (ifp->if_flags & IFF_BROADCAST) {
+ ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
+ ia->ia_broadaddr.sin_family = AF_INET;
+ }
+ ia->ia_ifp = ifp;
+ LIST_INIT(&ia->ia_multiaddrs);
+ if ((ifp->if_flags & IFF_LOOPBACK) == 0)
+ in_interfaces++;
+ }
+ break;
+
+ case SIOCSIFBRDADDR:
+ if ((so->so_state & SS_PRIV) == 0)
+ return (EPERM);
+ /* FALLTHROUGH */
+
+ case SIOCGIFADDR:
+ case SIOCGIFNETMASK:
+ case SIOCGIFDSTADDR:
+ case SIOCGIFBRDADDR:
+ if (ia && satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
+ struct in_ifaddr *ia2;
+
+ for (ia2 = ia; ia2; ia2 = ia2->ia_list.tqe_next) {
+ if (ia2->ia_ifp == ifp &&
+ ia2->ia_addr.sin_addr.s_addr ==
+ satosin(&ifr->ifr_addr)->sin_addr.s_addr)
+ break;
+ }
+ if (ia2 && ia2->ia_ifp == ifp)
+ ia = ia2;
+ }
+ if (ia == (struct in_ifaddr *)0)
+ return (EADDRNOTAVAIL);
+ break;
+ }
+ switch (cmd) {
+
+ case SIOCGIFADDR:
+ *satosin(&ifr->ifr_addr) = ia->ia_addr;
+ break;
+
+ case SIOCGIFBRDADDR:
+ if ((ifp->if_flags & IFF_BROADCAST) == 0)
+ return (EINVAL);
+ *satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
+ break;
+
+ case SIOCGIFDSTADDR:
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+ return (EINVAL);
+ *satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
+ break;
+
+ case SIOCGIFNETMASK:
+ *satosin(&ifr->ifr_addr) = ia->ia_sockmask;
+ break;
+
+ case SIOCSIFDSTADDR:
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+ return (EINVAL);
+ oldaddr = ia->ia_dstaddr;
+ ia->ia_dstaddr = *satosin(&ifr->ifr_dstaddr);
+ if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
+ (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
+ ia->ia_dstaddr = oldaddr;
+ return (error);
+ }
+ if (ia->ia_flags & IFA_ROUTE) {
+ ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr);
+ rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
+ ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
+ rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
+ }
+ break;
+
+ case SIOCSIFBRDADDR:
+ if ((ifp->if_flags & IFF_BROADCAST) == 0)
+ return (EINVAL);
+ ia->ia_broadaddr = *satosin(&ifr->ifr_broadaddr);
+ break;
+
+ case SIOCSIFADDR:
+ return (in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1));
+
+ case SIOCSIFNETMASK:
+ ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr =
+ ifra->ifra_addr.sin_addr.s_addr;
+ break;
+
+ case SIOCAIFADDR:
+ maskIsNew = 0;
+ hostIsNew = 1;
+ error = 0;
+ if (ia->ia_addr.sin_family == AF_INET) {
+ if (ifra->ifra_addr.sin_len == 0) {
+ ifra->ifra_addr = ia->ia_addr;
+ hostIsNew = 0;
+ } else if (ifra->ifra_addr.sin_addr.s_addr ==
+ ia->ia_addr.sin_addr.s_addr)
+ hostIsNew = 0;
+ }
+ if (ifra->ifra_mask.sin_len) {
+ in_ifscrub(ifp, ia);
+ ia->ia_sockmask = ifra->ifra_mask;
+ ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
+ maskIsNew = 1;
+ }
+ if ((ifp->if_flags & IFF_POINTOPOINT) &&
+ (ifra->ifra_dstaddr.sin_family == AF_INET)) {
+ in_ifscrub(ifp, ia);
+ ia->ia_dstaddr = ifra->ifra_dstaddr;
+ maskIsNew = 1; /* We lie; but the effect's the same */
+ }
+ if (ifra->ifra_addr.sin_family == AF_INET &&
+ (hostIsNew || maskIsNew))
+ error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
+ if ((ifp->if_flags & IFF_BROADCAST) &&
+ (ifra->ifra_broadaddr.sin_family == AF_INET))
+ ia->ia_broadaddr = ifra->ifra_broadaddr;
+ return (error);
+
+ case SIOCDIFADDR:
+ in_ifscrub(ifp, ia);
+ TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
+ TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
+ IFAFREE((&ia->ia_ifa));
+ break;
+
+#ifdef MROUTING
+ case SIOCGETVIFCNT:
+ case SIOCGETSGCNT:
+ return (mrt_ioctl(cmd, data));
+#endif /* MROUTING */
+
+ default:
+ if (ifp == 0 || ifp->if_ioctl == 0)
+ return (EOPNOTSUPP);
+ return ((*ifp->if_ioctl)(ifp, cmd, data));
+ }
+ return (0);
+}
+
+/*
+ * SIOC[GAD]LIFADDR.
+ * SIOCGLIFADDR: get first address. ( ??? )
+ * SIOCGLIFADDR with IFLR_PREFIX:
+ * get first address that matches the specified prefix.
+ * SIOCALIFADDR: add the specified address.
+ * SIOCALIFADDR with IFLR_PREFIX:
+ * EINVAL since we can't deduce hostid part of the address.
+ * SIOCDLIFADDR: delete the specified address.
+ * SIOCDLIFADDR with IFLR_PREFIX:
+ * delete the first address that matches the specified prefix.
+ * return values:
+ * EINVAL on invalid parameters
+ * EADDRNOTAVAIL on prefix match failed/specified address not found
+ * other values may be returned from in_ioctl()
+ */
+static int
+in_lifaddr_ioctl(so, cmd, data, ifp)
+ struct socket *so;
+ u_long cmd;
+ caddr_t data;
+ struct ifnet *ifp;
+{
+ struct if_laddrreq *iflr = (struct if_laddrreq *)data;
+ struct ifaddr *ifa;
+ struct sockaddr *sa;
+
+ /* sanity checks */
+ if (!data || !ifp) {
+ panic("invalid argument to in_lifaddr_ioctl");
+ /*NOTRECHED*/
+ }
+
+ switch (cmd) {
+ case SIOCGLIFADDR:
+ /* address must be specified on GET with IFLR_PREFIX */
+ if ((iflr->flags & IFLR_PREFIX) == 0)
+ break;
+ /*FALLTHROUGH*/
+ case SIOCALIFADDR:
+ case SIOCDLIFADDR:
+ /* address must be specified on ADD and DELETE */
+ sa = (struct sockaddr *)&iflr->addr;
+ if (sa->sa_family != AF_INET)
+ return EINVAL;
+ if (sa->sa_len != sizeof(struct sockaddr_in))
+ return EINVAL;
+ /* XXX need improvement */
+ sa = (struct sockaddr *)&iflr->dstaddr;
+ if (sa->sa_family
+ && sa->sa_family != AF_INET)
+ return EINVAL;
+ if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in))
+ return EINVAL;
+ break;
+ default: /*shouldn't happen*/
+#if 0
+ panic("invalid cmd to in_lifaddr_ioctl");
+ /*NOTREACHED*/
+#else
+ return EOPNOTSUPP;
+#endif
+ }
+ if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
+ return EINVAL;
+
+ switch (cmd) {
+ case SIOCALIFADDR:
+ {
+ struct in_aliasreq ifra;
+
+ if (iflr->flags & IFLR_PREFIX)
+ return EINVAL;
+
+ /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
+ bzero(&ifra, sizeof(ifra));
+ bcopy(iflr->iflr_name, ifra.ifra_name,
+ sizeof(ifra.ifra_name));
+
+ bcopy(&iflr->addr, &ifra.ifra_addr,
+ ((struct sockaddr *)&iflr->addr)->sa_len);
+
+ if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
+ bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
+ ((struct sockaddr *)&iflr->dstaddr)->sa_len);
+ }
+
+ ifra.ifra_mask.sin_family = AF_INET;
+ ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
+ in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
+
+ return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp);
+ }
+ case SIOCGLIFADDR:
+ case SIOCDLIFADDR:
+ {
+ struct in_ifaddr *ia;
+ struct in_addr mask, candidate, match;
+ struct sockaddr_in *sin;
+ int cmp;
+
+ bzero(&mask, sizeof(mask));
+ if (iflr->flags & IFLR_PREFIX) {
+ /* lookup a prefix rather than address. */
+ in_len2mask(&mask, iflr->prefixlen);
+
+ sin = (struct sockaddr_in *)&iflr->addr;
+ match.s_addr = sin->sin_addr.s_addr;
+ match.s_addr &= mask.s_addr;
+
+ /* if you set extra bits, that's wrong */
+ if (match.s_addr != sin->sin_addr.s_addr)
+ return EINVAL;
+
+ cmp = 1;
+ } else {
+ if (cmd == SIOCGLIFADDR) {
+ /* on getting an address, take the 1st match */
+ cmp = 0; /*XXX*/
+ } else {
+ /* on deleting an address, do exact match */
+ in_len2mask(&mask, 32);
+ sin = (struct sockaddr_in *)&iflr->addr;
+ match.s_addr = sin->sin_addr.s_addr;
+
+ cmp = 1;
+ }
+ }
+
+ for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+ if (!cmp)
+ break;
+ candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
+ candidate.s_addr &= mask.s_addr;
+ if (candidate.s_addr == match.s_addr)
+ break;
+ }
+ if (!ifa)
+ return EADDRNOTAVAIL;
+ ia = (struct in_ifaddr *)ifa;
+
+ if (cmd == SIOCGLIFADDR) {
+ /* fill in the if_laddrreq structure */
+ bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
+
+ if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
+ bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
+ ia->ia_dstaddr.sin_len);
+ } else
+ bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
+
+ iflr->prefixlen =
+ in_mask2len(&ia->ia_sockmask.sin_addr);
+
+ iflr->flags = 0; /*XXX*/
+
+ return 0;
+ } else {
+ struct in_aliasreq ifra;
+
+ /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
+ bzero(&ifra, sizeof(ifra));
+ bcopy(iflr->iflr_name, ifra.ifra_name,
+ sizeof(ifra.ifra_name));
+
+ bcopy(&ia->ia_addr, &ifra.ifra_addr,
+ ia->ia_addr.sin_len);
+ if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
+ bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
+ ia->ia_dstaddr.sin_len);
+ }
+ bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
+ ia->ia_sockmask.sin_len);
+
+ return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, ifp);
+ }
+ }
+ }
+
+ return EOPNOTSUPP; /*just for safety*/
+}
+
+/*
+ * Delete any existing route for an interface.
+ */
+void
+in_ifscrub(ifp, ia)
+ register struct ifnet *ifp;
+ register struct in_ifaddr *ia;
+{
+
+ if ((ia->ia_flags & IFA_ROUTE) == 0)
+ return;
+ if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
+ rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
+ else
+ rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
+ ia->ia_flags &= ~IFA_ROUTE;
+}
+
+/*
+ * Initialize an interface's internet address
+ * and routing table entry.
+ */
+int
+in_ifinit(ifp, ia, sin, scrub)
+ register struct ifnet *ifp;
+ register struct in_ifaddr *ia;
+ struct sockaddr_in *sin;
+ int scrub;
+{
+ register u_int32_t i = sin->sin_addr.s_addr;
+ struct sockaddr_in oldaddr;
+ int s = splimp(), flags = RTF_UP, error;
+
+ oldaddr = ia->ia_addr;
+ ia->ia_addr = *sin;
+ /*
+ * Give the interface a chance to initialize
+ * if this is its first address,
+ * and to validate the address if necessary.
+ */
+ if (ifp->if_ioctl &&
+ (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
+ splx(s);
+ ia->ia_addr = oldaddr;
+ return (error);
+ }
+ splx(s);
+ if (scrub) {
+ ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
+ in_ifscrub(ifp, ia);
+ ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
+ }
+ if (IN_CLASSA(i))
+ ia->ia_netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(i))
+ ia->ia_netmask = IN_CLASSB_NET;
+ else
+ ia->ia_netmask = IN_CLASSC_NET;
+ /*
+ * The subnet mask usually includes at least the standard network part,
+ * but may may be smaller in the case of supernetting.
+ * If it is set, we believe it.
+ */
+ if (ia->ia_subnetmask == 0) {
+ ia->ia_subnetmask = ia->ia_netmask;
+ ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask;
+ } else
+ ia->ia_netmask &= ia->ia_subnetmask;
+ ia->ia_net = i & ia->ia_netmask;
+ ia->ia_subnet = i & ia->ia_subnetmask;
+ in_socktrim(&ia->ia_sockmask);
+ /*
+ * Add route for the network.
+ */
+ ia->ia_ifa.ifa_metric = ifp->if_metric;
+ if (ifp->if_flags & IFF_BROADCAST) {
+ ia->ia_broadaddr.sin_addr.s_addr =
+ ia->ia_subnet | ~ia->ia_subnetmask;
+ ia->ia_netbroadcast.s_addr =
+ ia->ia_net | ~ia->ia_netmask;
+ } else if (ifp->if_flags & IFF_LOOPBACK) {
+ ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
+ flags |= RTF_HOST;
+ } else if (ifp->if_flags & IFF_POINTOPOINT) {
+ if (ia->ia_dstaddr.sin_family != AF_INET)
+ return (0);
+ flags |= RTF_HOST;
+ }
+ if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
+ ia->ia_flags |= IFA_ROUTE;
+ /*
+ * If the interface supports multicast, join the "all hosts"
+ * multicast group on that interface.
+ */
+ if (ifp->if_flags & IFF_MULTICAST) {
+ struct in_addr addr;
+
+ addr.s_addr = INADDR_ALLHOSTS_GROUP;
+ in_addmulti(&addr, ifp);
+ }
+ return (error);
+}
+
+
+/*
+ * Return 1 if the address might be a local broadcast address.
+ */
+int
+in_broadcast(in, ifp)
+ struct in_addr in;
+ struct ifnet *ifp;
+{
+ struct ifnet *ifn, *if_first, *if_target;
+ register struct ifaddr *ifa;
+
+ if (in.s_addr == INADDR_BROADCAST ||
+ in.s_addr == INADDR_ANY)
+ return 1;
+ if (ifp && ((ifp->if_flags & IFF_BROADCAST) == 0))
+ return 0;
+
+ if (ifp == NULL)
+ {
+ if_first = ifnet.tqh_first;
+ if_target = 0;
+ }
+ else
+ {
+ if_first = ifp;
+ if_target = ifp->if_list.tqe_next;
+ }
+
+#define ia (ifatoia(ifa))
+ /*
+ * Look through the list of addresses for a match
+ * with a broadcast address.
+ * If ifp is NULL, check against all the interfaces.
+ */
+ for (ifn = if_first; ifn != if_target; ifn = ifn->if_list.tqe_next)
+ for (ifa = ifn->if_addrlist.tqh_first; ifa;
+ ifa = ifa->ifa_list.tqe_next)
+ if (!ifp)
+ {
+ if (ifa->ifa_addr->sa_family == AF_INET &&
+ ((ia->ia_subnetmask != 0xffffffff &&
+ (((ifn->if_flags & IFF_BROADCAST) &&
+ in.s_addr == ia->ia_broadaddr.sin_addr.s_addr) ||
+ in.s_addr == ia->ia_subnet)) ||
+ /*
+ * Check for old-style (host 0) broadcast.
+ */
+ (in.s_addr == ia->ia_netbroadcast.s_addr ||
+ in.s_addr == ia->ia_net)))
+ return 1;
+ }
+ else
+ if (ifa->ifa_addr->sa_family == AF_INET &&
+ (((ifn->if_flags & IFF_BROADCAST) &&
+ in.s_addr == ia->ia_broadaddr.sin_addr.s_addr) ||
+ in.s_addr == ia->ia_netbroadcast.s_addr ||
+ /*
+ * Check for old-style (host 0) broadcast.
+ */
+ in.s_addr == ia->ia_subnet ||
+ in.s_addr == ia->ia_net))
+ return 1;
+ return (0);
+#undef ia
+}
+
+/*
+ * Add an address to the list of IP multicast addresses for a given interface.
+ */
+struct in_multi *
+in_addmulti(ap, ifp)
+ register struct in_addr *ap;
+ register struct ifnet *ifp;
+{
+ register struct in_multi *inm;
+ struct ifreq ifr;
+ struct in_ifaddr *ia;
+ int s = splsoftnet();
+
+ /*
+ * See if address already in list.
+ */
+ IN_LOOKUP_MULTI(*ap, ifp, inm);
+ if (inm != NULL) {
+ /*
+ * Found it; just increment the reference count.
+ */
+ ++inm->inm_refcount;
+ } else {
+ /*
+ * New address; allocate a new multicast record
+ * and link it into the interface's multicast list.
+ */
+ inm = (struct in_multi *)malloc(sizeof(*inm),
+ M_IPMADDR, M_NOWAIT);
+ if (inm == NULL) {
+ splx(s);
+ return (NULL);
+ }
+ inm->inm_addr = *ap;
+ inm->inm_ifp = ifp;
+ inm->inm_refcount = 1;
+ IFP_TO_IA(ifp, ia);
+ if (ia == NULL) {
+ free(inm, M_IPMADDR);
+ splx(s);
+ return (NULL);
+ }
+ inm->inm_ia = ia;
+ LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_list);
+ /*
+ * Ask the network driver to update its multicast reception
+ * filter appropriately for the new address.
+ */
+ satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in);
+ satosin(&ifr.ifr_addr)->sin_family = AF_INET;
+ satosin(&ifr.ifr_addr)->sin_addr = *ap;
+ if ((ifp->if_ioctl == NULL) ||
+ (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
+ LIST_REMOVE(inm, inm_list);
+ free(inm, M_IPMADDR);
+ splx(s);
+ return (NULL);
+ }
+ /*
+ * Let IGMP know that we have joined a new IP multicast group.
+ */
+ igmp_joingroup(inm);
+ }
+ splx(s);
+ return (inm);
+}
+
+/*
+ * Delete a multicast address record.
+ */
+void
+in_delmulti(inm)
+ register struct in_multi *inm;
+{
+ struct ifreq ifr;
+ int s = splsoftnet();
+
+ if (--inm->inm_refcount == 0) {
+ /*
+ * No remaining claims to this record; let IGMP know that
+ * we are leaving the multicast group.
+ */
+ igmp_leavegroup(inm);
+ /*
+ * Unlink from list.
+ */
+ LIST_REMOVE(inm, inm_list);
+ /*
+ * Notify the network driver to update its multicast reception
+ * filter.
+ */
+ satosin(&ifr.ifr_addr)->sin_family = AF_INET;
+ satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
+ (*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
+ (caddr_t)&ifr);
+ free(inm, M_IPMADDR);
+ }
+ splx(s);
+}
+
+#endif
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/in_cksum.c b/ecos/packages/net/tcpip/current/src/sys/netinet/in_cksum.c
new file mode 100644
index 0000000..3a74df8
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/in_cksum.c
@@ -0,0 +1,196 @@
+//==========================================================================
+//
+// sys/netinet/in_cksum.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_cksum.c,v 1.3 1997/02/24 14:06:35 niklas Exp $ */
+/* $NetBSD: in_cksum.c,v 1.11 1996/04/08 19:55:37 jonathan Exp $ */
+
+/*
+ * Copyright (c) 1988, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <netinet/in.h>
+
+struct net_stats stats_in_cksum;
+
+/*
+ * Checksum routine for Internet Protocol family headers (Portable Version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ */
+
+#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
+#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
+
+int
+in_cksum(m, len)
+ register struct mbuf *m;
+ register int len;
+{
+ register u_int16_t *w;
+ register int sum = 0;
+ register int mlen = 0;
+ int byte_swapped = 0;
+
+ union {
+ u_int8_t c[2];
+ u_int16_t s;
+ } s_util;
+ union {
+ u_int16_t s[2];
+ u_int32_t l;
+ } l_util;
+
+ START_STATS();
+
+ for (;m && len; m = m->m_next) {
+ if (m->m_len == 0)
+ continue;
+ w = mtod(m, u_int16_t *);
+ if (mlen == -1) {
+ /*
+ * The first byte of this mbuf is the continuation
+ * of a word spanning between this mbuf and the
+ * last mbuf.
+ *
+ * s_util.c[0] is already saved when scanning previous
+ * mbuf.
+ */
+ s_util.c[1] = *(u_int8_t *)w;
+ sum += s_util.s;
+ w = (u_int16_t *)((u_int8_t *)w + 1);
+ mlen = m->m_len - 1;
+ len--;
+ } else
+ mlen = m->m_len;
+ if (len < mlen)
+ mlen = len;
+ len -= mlen;
+ /*
+ * Force to even boundary.
+ */
+ if ((1 & (long) w) && (mlen > 0)) {
+ REDUCE;
+ sum <<= 8;
+ s_util.c[0] = *(u_int8_t *)w;
+ w = (u_int16_t *)((int8_t *)w + 1);
+ mlen--;
+ byte_swapped = 1;
+ }
+ /*
+ * Unroll the loop to make overhead from
+ * branches &c small.
+ */
+ while ((mlen -= 32) >= 0) {
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+ sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
+ sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
+ sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
+ w += 16;
+ }
+ mlen += 32;
+ while ((mlen -= 8) >= 0) {
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+ w += 4;
+ }
+ mlen += 8;
+ if (mlen == 0 && byte_swapped == 0)
+ continue;
+ REDUCE;
+ while ((mlen -= 2) >= 0) {
+ sum += *w++;
+ }
+ if (byte_swapped) {
+ REDUCE;
+ sum <<= 8;
+ byte_swapped = 0;
+ if (mlen == -1) {
+ s_util.c[1] = *(u_int8_t *)w;
+ sum += s_util.s;
+ mlen = 0;
+ } else
+ mlen = -1;
+ } else if (mlen == -1)
+ s_util.c[0] = *(u_int8_t *)w;
+ }
+ if (len)
+#ifdef __ECOS
+ diag_printf("cksum: out of data\n");
+#else
+ printf("cksum: out of data\n");
+#endif
+ if (mlen == -1) {
+ /* The last mbuf has odd # of bytes. Follow the
+ standard (the odd byte may be shifted left by 8 bits
+ or not as determined by endian-ness of the machine) */
+ s_util.c[1] = 0;
+ sum += s_util.s;
+ }
+ REDUCE;
+
+ FINISH_STATS(stats_in_cksum);
+
+ return (~sum & 0xffff);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/in_pcb.c b/ecos/packages/net/tcpip/current/src/sys/netinet/in_pcb.c
new file mode 100644
index 0000000..4b295f4
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/in_pcb.c
@@ -0,0 +1,1089 @@
+//==========================================================================
+//
+// sys/netinet/in_pcb.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_pcb.c,v 1.36 1999/12/08 11:36:40 angelos Exp $ */
+/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#ifdef __ECOS
+#undef errno
+#endif
+#include <sys/time.h>
+#ifndef __ECOS
+#include <sys/proc.h>
+#endif
+#include <sys/domain.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+
+#ifdef INET6
+#include <netinet6/ip6_var.h>
+#endif /* INET6 */
+
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+
+extern int check_ipsec_policy __P((struct inpcb *, u_int32_t));
+#endif
+
+#if 0 /*KAME IPSEC*/
+#include <netinet6/ipsec.h>
+#include <netkey/key.h>
+#include <netkey/key_debug.h>
+#endif /* IPSEC */
+
+struct in_addr zeroin_addr;
+
+extern int ipsec_auth_default_level;
+extern int ipsec_esp_trans_default_level;
+extern int ipsec_esp_network_default_level;
+
+/*
+ * These configure the range of local port addresses assigned to
+ * "unspecified" outgoing connections/packets/whatever.
+ */
+int ipport_firstauto = IPPORT_RESERVED; /* 1024 */
+int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */
+int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 40000 */
+int ipport_hilastauto = IPPORT_HILASTAUTO; /* 44999 */
+
+#define INPCBHASH(table, faddr, fport, laddr, lport) \
+ &(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \
+ ntohs((fport)) + ntohs((lport))) & (table->inpt_hash)]
+
+#define IN6PCBHASH(table, faddr, fport, laddr, lport) \
+ &(table)->inpt_hashtbl[(ntohl((faddr)->s6_addr32[0] ^ \
+ (faddr)->s6_addr32[3]) + ntohs((fport)) + ntohs((lport))) & \
+ (table->inpt_hash)]
+
+void
+in_pcbinit(table, hashsize)
+ struct inpcbtable *table;
+ int hashsize;
+{
+
+ CIRCLEQ_INIT(&table->inpt_queue);
+ table->inpt_hashtbl = hashinit(hashsize, M_PCB, M_WAITOK, &table->inpt_hash);
+ table->inpt_lastport = 0;
+}
+
+struct baddynamicports baddynamicports;
+
+/*
+ * Check if the specified port is invalid for dynamic allocation.
+ */
+int
+in_baddynamic(port, proto)
+ u_int16_t port;
+ u_int16_t proto;
+{
+
+ if (port < IPPORT_RESERVED/2 || port >= IPPORT_RESERVED)
+ return(0);
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ return (DP_ISSET(baddynamicports.tcp, port));
+ case IPPROTO_UDP:
+ return (DP_ISSET(baddynamicports.udp, port));
+ default:
+ return (0);
+ }
+}
+
+int
+in_pcballoc(so, v)
+ struct socket *so;
+ void *v;
+{
+ struct inpcbtable *table = v;
+ register struct inpcb *inp;
+ int s;
+
+ MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_NOWAIT);
+ if (inp == NULL)
+ return (ENOBUFS);
+ bzero((caddr_t)inp, sizeof(*inp));
+ inp->inp_table = table;
+ inp->inp_socket = so;
+ inp->inp_seclevel[SL_AUTH] = ipsec_auth_default_level;
+ inp->inp_seclevel[SL_ESP_TRANS] = ipsec_esp_trans_default_level;
+ inp->inp_seclevel[SL_ESP_NETWORK] = ipsec_esp_network_default_level;
+ s = splnet();
+ CIRCLEQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue);
+ LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, inp->inp_fport,
+ &inp->inp_laddr, inp->inp_lport), inp, inp_hash);
+ splx(s);
+ so->so_pcb = inp;
+ inp->inp_hops = -1;
+
+#ifdef INET6
+ /*
+ * Small change in this function to set the INP_IPV6 flag so routines
+ * outside pcb-specific routines don't need to use sotopf(), and all
+ * of it's pointer chasing, later.
+ */
+ if (sotopf(so) == PF_INET6)
+ inp->inp_flags = INP_IPV6;
+ inp->inp_csumoffset = -1;
+#endif /* INET6 */
+ return (0);
+}
+
+int
+in_pcbbind(v, nam)
+ register void *v;
+ struct mbuf *nam;
+{
+ register struct inpcb *inp = v;
+ register struct socket *so = inp->inp_socket;
+ register struct inpcbtable *table = inp->inp_table;
+ u_int16_t *lastport = &inp->inp_table->inpt_lastport;
+ register struct sockaddr_in *sin;
+#ifndef __ECOS
+ struct proc *p = curproc; /* XXX */
+ int error;
+#endif
+ u_int16_t lport = 0;
+ int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
+
+#ifdef INET6
+ if (sotopf(so) == PF_INET6)
+ return in6_pcbbind(inp, nam);
+#endif /* INET6 */
+
+ if (in_ifaddr.tqh_first == 0)
+ return (EADDRNOTAVAIL);
+ if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY)
+ return (EINVAL);
+ if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
+ ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
+ (so->so_options & SO_ACCEPTCONN) == 0))
+ wild = INPLOOKUP_WILDCARD;
+ if (nam) {
+ sin = mtod(nam, struct sockaddr_in *);
+ if (nam->m_len != sizeof (*sin))
+ return (EINVAL);
+#ifdef notdef
+ /*
+ * We should check the family, but old programs
+ * incorrectly fail to initialize it.
+ */
+ if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+#endif
+ lport = sin->sin_port;
+ if (IN_MULTICAST(sin->sin_addr.s_addr)) {
+ /*
+ * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
+ * allow complete duplication of binding if
+ * SO_REUSEPORT is set, or if SO_REUSEADDR is set
+ * and a multicast address is bound on both
+ * new and duplicated sockets.
+ */
+ if (so->so_options & SO_REUSEADDR)
+ reuseport = SO_REUSEADDR|SO_REUSEPORT;
+ } else if (sin->sin_addr.s_addr != INADDR_ANY) {
+ sin->sin_port = 0; /* yech... */
+ if (in_iawithaddr(sin->sin_addr, NULL) == 0)
+ return (EADDRNOTAVAIL);
+ }
+ if (lport) {
+ struct inpcb *t;
+
+ /* GROSS */
+#ifndef __ECOS
+ if (ntohs(lport) < IPPORT_RESERVED &&
+ (error = suser(p->p_ucred, &p->p_acflag)))
+ return (EACCES);
+#endif
+ if (so->so_euid) {
+ t = in_pcblookup(table, &zeroin_addr, 0,
+ &sin->sin_addr, lport, INPLOOKUP_WILDCARD);
+ if (t && (so->so_euid != t->inp_socket->so_euid))
+ return (EADDRINUSE);
+ }
+ t = in_pcblookup(table, &zeroin_addr, 0,
+ &sin->sin_addr, lport, wild);
+ if (t && (reuseport & t->inp_socket->so_options) == 0)
+ return (EADDRINUSE);
+ }
+ inp->inp_laddr = sin->sin_addr;
+ }
+ if (lport == 0) {
+ u_int16_t first, last, old = 0;
+ int count;
+ int loopcount = 0;
+
+ if (inp->inp_flags & INP_HIGHPORT) {
+ first = ipport_hifirstauto; /* sysctl */
+ last = ipport_hilastauto;
+ } else if (inp->inp_flags & INP_LOWPORT) {
+#ifndef __ECOS
+ if ((error = suser(p->p_ucred, &p->p_acflag)))
+ return (EACCES);
+#endif
+ first = IPPORT_RESERVED-1; /* 1023 */
+ last = 600; /* not IPPORT_RESERVED/2 */
+ } else {
+ first = ipport_firstauto; /* sysctl */
+ last = ipport_lastauto;
+ }
+
+ /*
+ * Simple check to ensure all ports are not used up causing
+ * a deadlock here.
+ *
+ * We split the two cases (up and down) so that the direction
+ * is not being tested on each round of the loop.
+ */
+
+portloop:
+ if (first > last) {
+ /*
+ * counting down
+ */
+ if (loopcount == 0) { /* only do this once. */
+ old = first;
+ first -= (arc4random() % (first - last));
+ }
+ count = first - last;
+ *lastport = first; /* restart each time */
+
+ do {
+ if (count-- <= 0) { /* completely used? */
+ if (loopcount == 0) {
+ last = old;
+ loopcount++;
+ goto portloop;
+ }
+ return (EADDRNOTAVAIL);
+ }
+ --*lastport;
+ if (*lastport > first || *lastport < last)
+ *lastport = first;
+ lport = htons(*lastport);
+ } while (in_baddynamic(*lastport, so->so_proto->pr_protocol) ||
+ in_pcblookup(table, &zeroin_addr, 0,
+ &inp->inp_laddr, lport, wild));
+ } else {
+ /*
+ * counting up
+ */
+ if (loopcount == 0) { /* only do this once. */
+ old = first;
+ first += (arc4random() % (last - first));
+ }
+ count = last - first;
+ *lastport = first; /* restart each time */
+
+ do {
+ if (count-- <= 0) { /* completely used? */
+ if (loopcount == 0) {
+ first = old;
+ loopcount++;
+ goto portloop;
+ }
+ return (EADDRNOTAVAIL);
+ }
+ ++*lastport;
+ if (*lastport < first || *lastport > last)
+ *lastport = first;
+ lport = htons(*lastport);
+ } while (in_baddynamic(*lastport, so->so_proto->pr_protocol) ||
+ in_pcblookup(table, &zeroin_addr, 0,
+ &inp->inp_laddr, lport, wild));
+ }
+ }
+ inp->inp_lport = lport;
+ in_pcbrehash(inp);
+ return (0);
+}
+
+/*
+ * Connect from a socket to a specified address.
+ * Both address and port must be specified in argument sin.
+ * If don't have a local address for this socket yet,
+ * then pick one.
+ */
+int
+in_pcbconnect(v, nam)
+ register void *v;
+ struct mbuf *nam;
+{
+ register struct inpcb *inp = v;
+ struct sockaddr_in *ifaddr = NULL;
+ register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+
+#ifdef INET6
+ if (sotopf(inp->inp_socket) == PF_INET6)
+ return (in6_pcbconnect(inp, nam));
+#endif /* INET6 */
+
+ if (nam->m_len != sizeof (*sin))
+ return (EINVAL);
+ if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (sin->sin_port == 0)
+ return (EADDRNOTAVAIL);
+ if (in_ifaddr.tqh_first != 0) {
+ /*
+ * If the destination address is INADDR_ANY,
+ * use the primary local address.
+ * If the supplied address is INADDR_BROADCAST,
+ * and the primary interface supports broadcast,
+ * choose the broadcast address for that interface.
+ */
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ sin->sin_addr = in_ifaddr.tqh_first->ia_addr.sin_addr;
+ else if (sin->sin_addr.s_addr == INADDR_BROADCAST &&
+ (in_ifaddr.tqh_first->ia_ifp->if_flags & IFF_BROADCAST))
+ sin->sin_addr = in_ifaddr.tqh_first->ia_broadaddr.sin_addr;
+ }
+ if (inp->inp_laddr.s_addr == INADDR_ANY) {
+#if 0
+ register struct route *ro;
+ struct sockaddr_in *sin2;
+ struct in_ifaddr *ia;
+
+ ia = (struct in_ifaddr *)0;
+ /*
+ * If route is known or can be allocated now,
+ * our src addr is taken from the i/f, else punt.
+ */
+ ro = &inp->inp_route;
+ if (ro->ro_rt &&
+ (satosin(&ro->ro_dst)->sin_addr.s_addr !=
+ sin->sin_addr.s_addr ||
+ inp->inp_socket->so_options & SO_DONTROUTE)) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = (struct rtentry *)0;
+ }
+ if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
+ (ro->ro_rt == (struct rtentry *)0 ||
+ ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
+ /* No route yet, so try to acquire one */
+ ro->ro_dst.sa_family = AF_INET;
+ ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
+ satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
+ rtalloc(ro);
+
+ /*
+ * It is important to bzero out the rest of the
+ * struct sockaddr_in when mixing v6 & v4!
+ */
+ sin2 = (struct sockaddr_in *)&ro->ro_dst;
+ bzero(sin2->sin_zero, sizeof(sin2->sin_zero));
+ }
+ /*
+ * If we found a route, use the address
+ * corresponding to the outgoing interface
+ * unless it is the loopback (in case a route
+ * to our address on another net goes to loopback).
+ */
+ if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
+ ia = ifatoia(ro->ro_rt->rt_ifa);
+ if (ia == 0) {
+ u_int16_t fport = sin->sin_port;
+
+ sin->sin_port = 0;
+ ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin)));
+ if (ia == 0)
+ ia = ifatoia(ifa_ifwithnet(sintosa(sin)));
+ sin->sin_port = fport;
+ if (ia == 0)
+ ia = in_ifaddr.tqh_first;
+ if (ia == 0)
+ return (EADDRNOTAVAIL);
+ }
+ /*
+ * If the destination address is multicast and an outgoing
+ * interface has been set as a multicast option, use the
+ * address of that interface as our source address.
+ */
+ if (IN_MULTICAST(sin->sin_addr.s_addr) &&
+#ifdef INET6
+ inp->inp_moptions != NULL &&
+ !(inp->inp_flags & INP_IPV6_MCAST))
+#else
+ inp->inp_moptions != NULL)
+#endif
+ {
+ struct ip_moptions *imo;
+ struct ifnet *ifp;
+
+ imo = inp->inp_moptions;
+ if (imo->imo_multicast_ifp != NULL) {
+ ifp = imo->imo_multicast_ifp;
+ for (ia = in_ifaddr.tqh_first; ia != 0;
+ ia = ia->ia_list.tqe_next)
+ if (ia->ia_ifp == ifp)
+ break;
+ if (ia == 0)
+ return (EADDRNOTAVAIL);
+ }
+ }
+ ifaddr = satosin(&ia->ia_addr);
+#else
+ int error;
+ ifaddr = in_selectsrc(sin, &inp->inp_route,
+ inp->inp_socket->so_options, inp->inp_moptions, &error);
+ if (ifaddr == NULL) {
+ if (error == 0)
+ error = EADDRNOTAVAIL;
+ return error;
+ }
+#endif
+ }
+ if (in_pcbhashlookup(inp->inp_table, sin->sin_addr, sin->sin_port,
+ inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
+ inp->inp_lport) != 0)
+ return (EADDRINUSE);
+ if (inp->inp_laddr.s_addr == INADDR_ANY) {
+ if (inp->inp_lport == 0 &&
+ in_pcbbind(inp, (struct mbuf *)0) == EADDRNOTAVAIL)
+ return (EADDRNOTAVAIL);
+ inp->inp_laddr = ifaddr->sin_addr;
+ }
+ inp->inp_faddr = sin->sin_addr;
+ inp->inp_fport = sin->sin_port;
+ in_pcbrehash(inp);
+#ifdef IPSEC
+ return (check_ipsec_policy(inp, 0));
+#else
+ return (0);
+#endif
+}
+
+void
+in_pcbdisconnect(v)
+ void *v;
+{
+ struct inpcb *inp = v;
+
+#ifdef INET6
+ if (sotopf(inp->inp_socket) == PF_INET6) {
+ inp->inp_faddr6 = in6addr_any;
+ /* Disconnected AF_INET6 sockets cannot be "v4-mapped" */
+ inp->inp_flags &= ~INP_IPV6_MAPPED;
+ } else
+#endif
+ inp->inp_faddr.s_addr = INADDR_ANY;
+
+ inp->inp_fport = 0;
+ in_pcbrehash(inp);
+ if (inp->inp_socket->so_state & SS_NOFDREF)
+ in_pcbdetach(inp);
+}
+
+void
+in_pcbdetach(v)
+ void *v;
+{
+ struct inpcb *inp = v;
+ struct socket *so = inp->inp_socket;
+ int s;
+
+#if 0 /*KAME IPSEC*/
+ if (so->so_pcb) {
+ KEYDEBUG(KEYDEBUG_KEY_STAMP,
+ printf("DP call free SO=%p from in_pcbdetach\n", so));
+ key_freeso(so);
+ }
+ ipsec4_delete_pcbpolicy(inp);
+#endif /*IPSEC*/
+ so->so_pcb = 0;
+ sofree(so);
+ if (inp->inp_options)
+ (void)m_freem(inp->inp_options);
+ if (inp->inp_route.ro_rt)
+ rtfree(inp->inp_route.ro_rt);
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ ip6_freemoptions(inp->inp_moptions6);
+ else
+#endif
+ ip_freemoptions(inp->inp_moptions);
+#ifdef IPSEC
+ /* XXX IPsec cleanup here */
+ s = spltdb();
+ if (inp->inp_tdb)
+ TAILQ_REMOVE(&inp->inp_tdb->tdb_inp, inp, inp_tdb_next);
+ splx(s);
+#endif
+ s = splnet();
+ LIST_REMOVE(inp, inp_hash);
+ CIRCLEQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue);
+ splx(s);
+ FREE(inp, M_PCB);
+}
+
+void
+in_setsockaddr(inp, nam)
+ register struct inpcb *inp;
+ struct mbuf *nam;
+{
+ register struct sockaddr_in *sin;
+
+ nam->m_len = sizeof (*sin);
+ sin = mtod(nam, struct sockaddr_in *);
+ bzero((caddr_t)sin, sizeof (*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = inp->inp_lport;
+ sin->sin_addr = inp->inp_laddr;
+}
+
+void
+in_setpeeraddr(inp, nam)
+ struct inpcb *inp;
+ struct mbuf *nam;
+{
+ register struct sockaddr_in *sin;
+
+#ifdef INET6
+ if (sotopf(inp->inp_socket) == PF_INET6)
+ in6_setpeeraddr(inp, nam);
+#endif /* INET6 */
+
+ nam->m_len = sizeof (*sin);
+ sin = mtod(nam, struct sockaddr_in *);
+ bzero((caddr_t)sin, sizeof (*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = inp->inp_fport;
+ sin->sin_addr = inp->inp_faddr;
+}
+
+/*
+ * Pass some notification to all connections of a protocol
+ * associated with address dst. The local address and/or port numbers
+ * may be specified to limit the search. The "usual action" will be
+ * taken, depending on the ctlinput cmd. The caller must filter any
+ * cmds that are uninteresting (e.g., no error in the map).
+ * Call the protocol specific routine (if any) to report
+ * any errors for each matching socket.
+ *
+ * Must be called at splsoftnet.
+ */
+void
+in_pcbnotify(table, dst, fport_arg, laddr, lport_arg, errno, notify)
+ struct inpcbtable *table;
+ struct sockaddr *dst;
+ u_int fport_arg, lport_arg;
+ struct in_addr laddr;
+ int errno;
+ void (*notify) __P((struct inpcb *, int));
+{
+ register struct inpcb *inp, *oinp;
+ struct in_addr faddr;
+ u_int16_t fport = fport_arg, lport = lport_arg;
+
+#ifdef INET6
+ /*
+ * See in6_pcbnotify() for IPv6 codepath. By the time this
+ * gets called, the addresses passed are either definitely IPv4 or
+ * IPv6; *_pcbnotify() never gets called with v4-mapped v6 addresses.
+ */
+#endif /* INET6 */
+
+ if (dst->sa_family != AF_INET)
+ return;
+ faddr = satosin(dst)->sin_addr;
+ if (faddr.s_addr == INADDR_ANY)
+ return;
+
+ for (inp = table->inpt_queue.cqh_first;
+ inp != (struct inpcb *)&table->inpt_queue;) {
+ if (inp->inp_faddr.s_addr != faddr.s_addr ||
+ inp->inp_socket == 0 ||
+ inp->inp_fport != fport ||
+ inp->inp_lport != lport ||
+ inp->inp_laddr.s_addr != laddr.s_addr) {
+ inp = inp->inp_queue.cqe_next;
+ continue;
+ }
+ oinp = inp;
+ inp = inp->inp_queue.cqe_next;
+ if (notify)
+ (*notify)(oinp, errno);
+ }
+}
+
+void
+in_pcbnotifyall(table, dst, errno, notify)
+ struct inpcbtable *table;
+ struct sockaddr *dst;
+ int errno;
+ void (*notify) __P((struct inpcb *, int));
+{
+ register struct inpcb *inp, *oinp;
+ struct in_addr faddr;
+
+#ifdef INET6
+ /*
+ * See in6_pcbnotify() for IPv6 codepath. By the time this
+ * gets called, the addresses passed are either definitely IPv4 or
+ * IPv6; *_pcbnotify() never gets called with v4-mapped v6 addresses.
+ */
+#endif /* INET6 */
+
+ if (dst->sa_family != AF_INET)
+ return;
+ faddr = satosin(dst)->sin_addr;
+ if (faddr.s_addr == INADDR_ANY)
+ return;
+
+ for (inp = table->inpt_queue.cqh_first;
+ inp != (struct inpcb *)&table->inpt_queue;) {
+ if (inp->inp_faddr.s_addr != faddr.s_addr ||
+ inp->inp_socket == 0) {
+ inp = inp->inp_queue.cqe_next;
+ continue;
+ }
+ oinp = inp;
+ inp = inp->inp_queue.cqe_next;
+ if (notify)
+ (*notify)(oinp, errno);
+ }
+}
+
+/*
+ * Check for alternatives when higher level complains
+ * about service problems. For now, invalidate cached
+ * routing information. If the route was created dynamically
+ * (by a redirect), time to try a default gateway again.
+ */
+void
+in_losing(inp)
+ struct inpcb *inp;
+{
+ register struct rtentry *rt;
+ struct rt_addrinfo info;
+
+ if ((rt = inp->inp_route.ro_rt)) {
+ inp->inp_route.ro_rt = 0;
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst;
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
+ if (rt->rt_flags & RTF_DYNAMIC)
+ (void) rtrequest(RTM_DELETE, rt_key(rt),
+ rt->rt_gateway, rt_mask(rt), rt->rt_flags,
+ (struct rtentry **)0);
+ else
+ /*
+ * A new route can be allocated
+ * the next time output is attempted.
+ */
+ rtfree(rt);
+ }
+}
+
+/*
+ * After a routing change, flush old routing
+ * and allocate a (hopefully) better one.
+ */
+void
+in_rtchange(inp, errno)
+ register struct inpcb *inp;
+ int errno;
+{
+ if (inp->inp_route.ro_rt) {
+ rtfree(inp->inp_route.ro_rt);
+ inp->inp_route.ro_rt = 0;
+ /*
+ * A new route can be allocated the next time
+ * output is attempted.
+ */
+ }
+}
+
+struct inpcb *
+in_pcblookup(table, faddrp, fport_arg, laddrp, lport_arg, flags)
+ struct inpcbtable *table;
+ void *faddrp, *laddrp;
+ u_int fport_arg, lport_arg;
+ int flags;
+{
+ register struct inpcb *inp, *match = 0;
+ int matchwild = 3, wildcard;
+ u_int16_t fport = fport_arg, lport = lport_arg;
+ struct in_addr faddr = *(struct in_addr *)faddrp;
+ struct in_addr laddr = *(struct in_addr *)laddrp;
+
+ for (inp = table->inpt_queue.cqh_first;
+ inp != (struct inpcb *)&table->inpt_queue;
+ inp = inp->inp_queue.cqe_next) {
+ if (inp->inp_lport != lport)
+ continue;
+ wildcard = 0;
+#ifdef INET6
+ if (flags & INPLOOKUP_IPV6) {
+ struct in6_addr *laddr6 = (struct in6_addr *)laddrp;
+ struct in6_addr *faddr6 = (struct in6_addr *)faddrp;
+
+ /*
+ * Always skip AF_INET sockets when looking
+ * for AF_INET6 addresses. The only problem
+ * with this comes if the PF_INET6 addresses
+ * are v4-mapped addresses. From what I've
+ * been able to see, none of the callers cause
+ * such a situation to occur. If such a
+ * situation DID occur, then it is possible to
+ * miss a matching PCB.
+ */
+ if (!(inp->inp_flags & INP_IPV6))
+ continue;
+
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) {
+ if (IN6_IS_ADDR_UNSPECIFIED(laddr6))
+ wildcard++;
+ else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr6))
+ continue;
+ } else {
+ if (!IN6_IS_ADDR_UNSPECIFIED(laddr6))
+ wildcard++;
+ }
+
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
+ if (IN6_IS_ADDR_UNSPECIFIED(faddr6))
+ wildcard++;
+ else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6,
+ faddr6) || inp->inp_fport != fport)
+ continue;
+ } else {
+ if (!IN6_IS_ADDR_UNSPECIFIED(faddr6))
+ wildcard++;
+ }
+ } else
+#endif /* INET6 */
+ {
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ if (faddr.s_addr == INADDR_ANY)
+ wildcard++;
+ else if (inp->inp_faddr.s_addr != faddr.s_addr ||
+ inp->inp_fport != fport)
+ continue;
+ } else {
+ if (faddr.s_addr != INADDR_ANY)
+ wildcard++;
+ }
+ if (inp->inp_laddr.s_addr != INADDR_ANY) {
+ if (laddr.s_addr == INADDR_ANY)
+ wildcard++;
+ else if (inp->inp_laddr.s_addr != laddr.s_addr)
+ continue;
+ } else {
+ if (laddr.s_addr != INADDR_ANY)
+ wildcard++;
+ }
+ }
+ if ((!wildcard || (flags & INPLOOKUP_WILDCARD)) &&
+ wildcard < matchwild) {
+ match = inp;
+ if ((matchwild = wildcard) == 0)
+ break;
+ }
+ }
+ return (match);
+}
+
+struct sockaddr_in *
+in_selectsrc(sin, ro, soopts, mopts, errorp)
+ struct sockaddr_in *sin;
+ struct route *ro;
+ int soopts;
+ struct ip_moptions *mopts;
+ int *errorp;
+{
+ struct sockaddr_in *sin2;
+ struct in_ifaddr *ia;
+
+ ia = (struct in_ifaddr *)0;
+ /*
+ * If route is known or can be allocated now,
+ * our src addr is taken from the i/f, else punt.
+ */
+ if (ro->ro_rt &&
+ (satosin(&ro->ro_dst)->sin_addr.s_addr !=
+ sin->sin_addr.s_addr ||
+ soopts & SO_DONTROUTE)) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = (struct rtentry *)0;
+ }
+ if ((soopts & SO_DONTROUTE) == 0 && /*XXX*/
+ (ro->ro_rt == (struct rtentry *)0 ||
+ ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
+ /* No route yet, so try to acquire one */
+ ro->ro_dst.sa_family = AF_INET;
+ ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
+ satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
+ rtalloc(ro);
+
+ /*
+ * It is important to bzero out the rest of the
+ * struct sockaddr_in when mixing v6 & v4!
+ */
+ sin2 = (struct sockaddr_in *)&ro->ro_dst;
+ bzero(sin2->sin_zero, sizeof(sin2->sin_zero));
+ }
+ /*
+ * If we found a route, use the address
+ * corresponding to the outgoing interface
+ * unless it is the loopback (in case a route
+ * to our address on another net goes to loopback).
+ */
+ if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
+ ia = ifatoia(ro->ro_rt->rt_ifa);
+ if (ia == 0) {
+ u_int16_t fport = sin->sin_port;
+
+ sin->sin_port = 0;
+ ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin)));
+ if (ia == 0)
+ ia = ifatoia(ifa_ifwithnet(sintosa(sin)));
+ sin->sin_port = fport;
+ if (ia == 0)
+ ia = in_ifaddr.tqh_first;
+ if (ia == 0) {
+ *errorp = EADDRNOTAVAIL;
+ return NULL;
+ }
+ }
+ /*
+ * If the destination address is multicast and an outgoing
+ * interface has been set as a multicast option, use the
+ * address of that interface as our source address.
+ */
+ if (IN_MULTICAST(sin->sin_addr.s_addr) &&
+#if 0 /*def INET6*/
+ mopts != NULL &&
+ !(inp->inp_flags & INP_IPV6_MCAST))
+#else
+ mopts != NULL)
+#endif
+ {
+ struct ip_moptions *imo;
+ struct ifnet *ifp;
+
+ imo = mopts;
+ if (imo->imo_multicast_ifp != NULL) {
+ ifp = imo->imo_multicast_ifp;
+ for (ia = in_ifaddr.tqh_first; ia != 0;
+ ia = ia->ia_list.tqe_next)
+ if (ia->ia_ifp == ifp)
+ break;
+ if (ia == 0) {
+ *errorp = EADDRNOTAVAIL;
+ return NULL;
+ }
+ }
+ }
+ return satosin(&ia->ia_addr);
+}
+
+void
+in_pcbrehash(inp)
+ struct inpcb *inp;
+{
+ struct inpcbtable *table = inp->inp_table;
+ int s;
+
+ s = splnet();
+ LIST_REMOVE(inp, inp_hash);
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6) {
+ LIST_INSERT_HEAD(IN6PCBHASH(table, &inp->inp_faddr6,
+ inp->inp_fport, &inp->inp_laddr6, inp->inp_lport),
+ inp, inp_hash);
+ } else {
+#endif /* INET6 */
+ LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr,
+ inp->inp_fport, &inp->inp_laddr, inp->inp_lport),
+ inp, inp_hash);
+#ifdef INET6
+ }
+#endif /* INET6 */
+ splx(s);
+}
+
+#ifdef DIAGNOSTIC
+int in_pcbnotifymiss = 0;
+#endif
+
+struct inpcb *
+in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
+ struct inpcbtable *table;
+ struct in_addr faddr, laddr;
+ u_int fport_arg, lport_arg;
+{
+ struct inpcbhead *head;
+ register struct inpcb *inp;
+ u_int16_t fport = fport_arg, lport = lport_arg;
+
+ head = INPCBHASH(table, &faddr, fport, &laddr, lport);
+ for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {
+ if (inp->inp_faddr.s_addr == faddr.s_addr &&
+ inp->inp_fport == fport &&
+ inp->inp_lport == lport &&
+ inp->inp_laddr.s_addr == laddr.s_addr) {
+ /*
+ * Move this PCB to the head of hash chain so that
+ * repeated accesses are quicker. This is analogous to
+ * the historic single-entry PCB cache.
+ */
+ if (inp != head->lh_first) {
+ LIST_REMOVE(inp, inp_hash);
+ LIST_INSERT_HEAD(head, inp, inp_hash);
+ }
+ break;
+ }
+ }
+#ifdef DIAGNOSTIC
+ if (inp == NULL && in_pcbnotifymiss) {
+ printf("in_pcbhashlookup: faddr=%08x fport=%d laddr=%08x lport=%d\n",
+ ntohl(faddr.s_addr), ntohs(fport),
+ ntohl(laddr.s_addr), ntohs(lport));
+ }
+#endif
+ return (inp);
+}
+
+#ifdef INET6
+struct inpcb *
+in6_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
+ struct inpcbtable *table;
+ struct in6_addr *faddr, *laddr;
+ u_int fport_arg, lport_arg;
+{
+ struct inpcbhead *head;
+ register struct inpcb *inp;
+ u_int16_t fport = fport_arg, lport = lport_arg;
+
+ head = IN6PCBHASH(table, faddr, fport, laddr, lport);
+ for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {
+ if (!(inp->inp_flags & INP_IPV6))
+ continue;
+ if (IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, faddr) &&
+ inp->inp_fport == fport && inp->inp_lport == lport &&
+ IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr)) {
+ /*
+ * Move this PCB to the head of hash chain so that
+ * repeated accesses are quicker. This is analogous to
+ * the historic single-entry PCB cache.
+ */
+ if (inp != head->lh_first) {
+ LIST_REMOVE(inp, inp_hash);
+ LIST_INSERT_HEAD(head, inp, inp_hash);
+ }
+ break;
+ }
+ }
+#ifdef DIAGNOSTIC
+ if (inp == NULL && in_pcbnotifymiss) {
+ printf("in6_pcblookup_connect: faddr=");
+ printf(" fport=%d laddr=", ntohs(fport));
+ printf(" lport=%d\n", ntohs(lport));
+ }
+#endif
+ return (inp);
+}
+#endif /* INET6 */
+
+
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/in_proto.c b/ecos/packages/net/tcpip/current/src/sys/netinet/in_proto.c
new file mode 100644
index 0000000..36e64b2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/in_proto.c
@@ -0,0 +1,384 @@
+//==========================================================================
+//
+// sys/netinet/in_proto.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: in_proto.c,v 1.17 1999/12/09 03:46:59 angelos Exp $ */
+/* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * 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 project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)in_proto.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <net/radix.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/in_pcb.h>
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <netinet/ip6.h>
+#endif
+
+#include <netinet/igmp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_debug.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+/*
+ * TCP/IP protocol family: IP, ICMP, UDP, TCP.
+ */
+
+#if 0 /*KAME IPSEC*/
+#include <netinet6/ah.h>
+#ifdef IPSEC_ESP
+#include <netinet6/esp.h>
+#endif
+#include <netinet6/ipcomp.h>
+#endif /* IPSEC */
+
+#ifndef __ECOS
+#include "gif.h"
+#endif
+#if NGIF > 0
+#include <netinet/in_gif.h>
+#endif
+
+#ifdef NSIP
+#include <netns/ns_var.h>
+#include <netns/idp_var.h>
+#endif /* NSIP */
+
+#ifdef IPXIP
+#include <netipx/ipx.h>
+#include <netipx/ipx_ip.h>
+#endif /* NSIP */
+
+#ifdef TPIP
+#include <netiso/tp_param.h>
+#include <netiso/tp_var.h>
+#endif /* TPIP */
+
+#ifdef EON
+#include <netiso/eonvar.h>
+#endif /* EON */
+
+#ifdef MROUTING
+#include <netinet/ip_mroute.h>
+#endif /* MROUTING */
+
+#ifdef IPFILTER
+void iplinit __P((void));
+#define ip_init iplinit
+#endif
+
+#ifdef INET6
+#include <netinet6/ip6_var.h>
+#endif /* INET6 */
+
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+#include <netinet/ip_ah.h>
+#include <netinet/ip_esp.h>
+#include <netinet/ip_ip4.h>
+#include <netinet/ip_ether.h>
+#endif
+
+#ifndef CYGPKG_NET_SYSCTL
+#define ip_sysctl 0
+#define udp_sysctl 0
+#define tcp_sysctl 0
+#define icmp_sysctl 0
+#endif
+
+extern struct domain inetdomain;
+
+struct protosw inetsw[] = {
+{ 0, &inetdomain, 0, 0,
+ 0, ip_output, 0, 0,
+ 0,
+ ip_init, 0, ip_slowtimo, ip_drain, ip_sysctl
+},
+{ SOCK_DGRAM, &inetdomain, IPPROTO_UDP, PR_ATOMIC|PR_ADDR,
+ udp_input, 0, udp_ctlinput, ip_ctloutput,
+ udp_usrreq,
+ udp_init, 0, 0, 0, udp_sysctl
+},
+{ SOCK_STREAM, &inetdomain, IPPROTO_TCP, PR_CONNREQUIRED|PR_WANTRCVD,
+ tcp_input, 0, tcp_ctlinput, tcp_ctloutput,
+ tcp_usrreq,
+ tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain, tcp_sysctl
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_RAW, PR_ATOMIC|PR_ADDR,
+ rip_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_ICMP, PR_ATOMIC|PR_ADDR,
+ icmp_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0, icmp_sysctl
+},
+#if NGIF > 0 && !defined(IPSEC)
+{ SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR,
+ in_gif_input, 0, 0, 0,
+ 0,
+ 0, 0, 0, 0,
+},
+#ifdef INET6
+{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR,
+ in_gif_input, 0, 0, 0,
+ 0,
+ 0, 0, 0, 0,
+},
+#endif /* INET6 */
+#else /* NGIF */
+#if defined(IPSEC) || defined(MROUTING)
+{ SOCK_RAW, &inetdomain, IPPROTO_IPIP, PR_ATOMIC|PR_ADDR,
+ ip4_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq, /* XXX */
+ 0, 0, 0, 0, ip4_sysctl
+},
+#if NGIF > 0 && defined(INET6)
+{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR,
+ in_gif_input, 0, 0, 0,
+ 0,
+ 0, 0, 0, 0,
+},
+#endif /* NGIF && INET6 */
+#endif /* MROUTING || IPSEC */
+#endif /*NGIF*/
+{ SOCK_RAW, &inetdomain, IPPROTO_IGMP, PR_ATOMIC|PR_ADDR,
+ igmp_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ igmp_init, igmp_fasttimo, igmp_slowtimo, 0,
+},
+#ifdef TPIP
+{ SOCK_SEQPACKET,&inetdomain, IPPROTO_TP, PR_CONNREQUIRED|PR_WANTRCVD,
+ tpip_input, 0, tpip_ctlinput, tp_ctloutput,
+ tp_usrreq,
+ tp_init, 0, tp_slowtimo, tp_drain,
+},
+#endif /* TPIP */
+/* EON (ISO CLNL over IP) */
+#ifdef EON
+{ SOCK_RAW, &inetdomain, IPPROTO_EON, 0,
+ eoninput, 0, eonctlinput, 0,
+ 0,
+ eonprotoinit, 0, 0, 0,
+},
+#endif /* EON */
+#ifdef IPXIP
+{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
+ ipxip_input, rip_output, ipxip_ctlinput, 0,
+ rip_usrreq,
+ ipxipprotoinit,0, 0, 0,
+},
+#endif /* NSIP */
+#ifdef NSIP
+{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
+ idpip_input, rip_output, nsip_ctlinput, 0,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+#endif /* NSIP */
+#ifdef IPSEC
+{ SOCK_RAW, &inetdomain, IPPROTO_AH, PR_ATOMIC|PR_ADDR,
+ ah_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0, ah_sysctl
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_ESP, PR_ATOMIC|PR_ADDR,
+ esp_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0, esp_sysctl
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_ETHERIP, PR_ATOMIC|PR_ADDR,
+ etherip_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0, etherip_sysctl
+},
+#endif
+#if 0 /*NRL IPv6*/
+/* IPv6 in IPv4 tunneled packets... */
+{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR,
+ ip6_input, rip_output, ipv6_trans_ctlinput, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0
+},
+#if 0
+/* IPv4 in IPv4 tunneled packets... */
+{ SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR,
+ ipv4_input, 0, 0, 0,
+ 0,
+ 0, 0, 0, 0
+},
+#endif /* 0 */
+#endif /* defined(INET6) */
+/* raw wildcard */
+{ SOCK_RAW, &inetdomain, 0, PR_ATOMIC|PR_ADDR,
+ rip_input, rip_output, 0, rip_ctloutput,
+ rip_usrreq,
+ rip_init, 0, 0, 0,
+},
+};
+
+struct domain inetdomain =
+ { AF_INET, "internet", 0, 0, 0,
+ inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])], 0,
+ rn_inithead, 32, sizeof(struct sockaddr_in) };
+
+#ifdef notyet /* XXXX */
+#include "imp.h"
+#if NIMP > 0
+extern struct domain impdomain;
+int rimp_output(), hostslowtimo();
+
+struct protosw impsw[] = {
+{ SOCK_RAW, &impdomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, rimp_output, 0, 0,
+ rip_usrreq,
+ 0, 0, hostslowtimo, 0,
+},
+};
+
+struct domain impdomain =
+ { AF_IMPLINK, "imp", 0, 0, 0,
+ impsw, &impsw[sizeof (impsw)/sizeof(impsw[0])] };
+#endif
+
+#include "hy.h"
+#if NHY > 0
+/*
+ * HYPERchannel protocol family: raw interface.
+ */
+int rhy_output();
+extern struct domain hydomain;
+
+struct protosw hysw[] = {
+{ SOCK_RAW, &hydomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, rhy_output, 0, 0,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+};
+
+struct domain hydomain =
+ { AF_HYLINK, "hy", 0, 0, 0, hysw, &hysw[sizeof (hysw)/sizeof(hysw[0])] };
+#endif
+#endif
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/ip_icmp.c b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_icmp.c
new file mode 100644
index 0000000..ff123c2
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_icmp.c
@@ -0,0 +1,767 @@
+//==========================================================================
+//
+// sys/netinet/ip_icmp.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_icmp.c,v 1.19 1999/12/08 06:50:19 itojun Exp $ */
+/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#ifndef __ECOS
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <netinet/icmp_var.h>
+
+#if 0 /*KAME IPSEC*/
+#include <netinet6/ipsec.h>
+#include <netkey/key.h>
+#include <netkey/key_debug.h>
+#endif
+
+#include <machine/stdarg.h>
+
+/*
+ * ICMP routines: error generation, receive packet processing, and
+ * routines to turnaround packets back to the originator, and
+ * host table maintenance routines.
+ */
+
+int icmpmaskrepl = 0;
+int icmpbmcastecho = 0;
+#ifdef ICMPPRINTFS
+int icmpprintfs = 0;
+#endif
+
+#if 0
+static int ip_next_mtu __P((int, int));
+#else
+/*static*/ int ip_next_mtu __P((int, int));
+#endif
+
+extern struct protosw inetsw[];
+
+/*
+ * Generate an error packet of type error
+ * in response to bad packet ip.
+ *
+ * The ip packet inside has ip_off and ip_len in host byte order.
+ */
+void
+icmp_error(n, type, code, dest, destifp)
+ struct mbuf *n;
+ int type, code;
+ n_long dest;
+ struct ifnet *destifp;
+{
+ register struct ip *oip = mtod(n, struct ip *), *nip;
+ register unsigned oiplen = oip->ip_hl << 2;
+ register struct icmp *icp;
+ struct mbuf *m, m0;
+ unsigned icmplen;
+
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("icmp_error(%x, %d, %d)\n", oip, type, code);
+#endif
+ if (type != ICMP_REDIRECT)
+ icmpstat.icps_error++;
+ /*
+ * Don't send error if not the first fragment of message.
+ * Don't error if the old packet protocol was ICMP
+ * error message, only known informational types.
+ */
+ if (oip->ip_off &~ (IP_MF|IP_DF))
+ goto freeit;
+ if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
+ n->m_len >= oiplen + ICMP_MINLEN &&
+ !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) {
+ icmpstat.icps_oldicmp++;
+ goto freeit;
+ }
+ /* Don't send error in response to a multicast or broadcast packet */
+ if (n->m_flags & (M_BCAST|M_MCAST))
+ goto freeit;
+ /*
+ * First, formulate icmp message
+ */
+ m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ goto freeit;
+ icmplen = oiplen + min(8, oip->ip_len);
+ m->m_len = icmplen + ICMP_MINLEN;
+ MH_ALIGN(m, m->m_len);
+ icp = mtod(m, struct icmp *);
+ if ((u_int)type > ICMP_MAXTYPE)
+ panic("icmp_error");
+ icmpstat.icps_outhist[type]++;
+ icp->icmp_type = type;
+ if (type == ICMP_REDIRECT)
+ icp->icmp_gwaddr.s_addr = dest;
+ else {
+ icp->icmp_void = 0;
+ /*
+ * The following assignments assume an overlay with the
+ * zeroed icmp_void field.
+ */
+ if (type == ICMP_PARAMPROB) {
+ icp->icmp_pptr = code;
+ code = 0;
+ } else if (type == ICMP_UNREACH &&
+ code == ICMP_UNREACH_NEEDFRAG && destifp)
+ icp->icmp_nextmtu = htons(destifp->if_mtu);
+ }
+
+ icp->icmp_code = code;
+ bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen);
+ nip = &icp->icmp_ip;
+ nip->ip_off = htons(nip->ip_off);
+ nip->ip_len = htons(nip->ip_len);
+
+ m0.m_next = NULL; /* correct nip->ip_sum */
+ m0.m_data = (char *)nip;
+ m0.m_len = nip->ip_hl << 2;
+ nip->ip_sum = 0;
+ nip->ip_sum = in_cksum(&m0, nip->ip_hl << 2);
+
+ /*
+ * Now, copy old ip header (without options)
+ * in front of icmp message.
+ */
+ if (m->m_data - sizeof(struct ip) < m->m_pktdat)
+ panic("icmp len");
+ m->m_data -= sizeof(struct ip);
+ m->m_len += sizeof(struct ip);
+ m->m_pkthdr.len = m->m_len;
+ m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
+ nip = mtod(m, struct ip *);
+ bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip));
+ nip->ip_off = htons(nip->ip_off);
+ nip->ip_len = m->m_len;
+ nip->ip_hl = sizeof(struct ip) >> 2;
+ nip->ip_p = IPPROTO_ICMP;
+ nip->ip_tos = 0;
+ icmp_reflect(m);
+
+freeit:
+ m_freem(n);
+}
+
+static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
+static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
+static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
+struct sockaddr_in icmpmask = { 8, 0 };
+
+/*
+ * Process a received ICMP message.
+ */
+void
+#if __STDC__
+icmp_input(struct mbuf *m, ...)
+#else
+icmp_input(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ int proto;
+ register struct icmp *icp;
+ register struct ip *ip = mtod(m, struct ip *);
+ int icmplen = ip->ip_len;
+ register int i;
+ struct in_ifaddr *ia;
+ void *(*ctlfunc) __P((int, struct sockaddr *, void *));
+ int code;
+ extern u_char ip_protox[];
+ int hlen;
+ va_list ap;
+
+ va_start(ap, m);
+ hlen = va_arg(ap, int);
+ proto = va_arg(ap, int);
+ va_end(ap);
+
+ /*
+ * Locate icmp structure in mbuf, and check
+ * that not corrupted and of at least minimum length.
+ */
+#ifdef ICMPPRINTFS
+ if (icmpprintfs) {
+ char buf[4*sizeof "123"];
+
+ strcpy(buf, inet_ntoa(ip->ip_dst));
+ printf("icmp_input from %s to %s, len %d\n",
+ inet_ntoa(ip->ip_src), buf, icmplen);
+ }
+#endif
+ if (icmplen < ICMP_MINLEN) {
+ icmpstat.icps_tooshort++;
+ goto freeit;
+ }
+ i = hlen + min(icmplen, ICMP_ADVLENMIN);
+ if (m->m_len < i && (m = m_pullup(m, i)) == 0) {
+ icmpstat.icps_tooshort++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ m->m_len -= hlen;
+ m->m_data += hlen;
+ icp = mtod(m, struct icmp *);
+ if (in_cksum(m, icmplen)) {
+ icmpstat.icps_checksum++;
+ goto freeit;
+ }
+ m->m_len += hlen;
+ m->m_data -= hlen;
+
+#ifdef ICMPPRINTFS
+ /*
+ * Message type specific processing.
+ */
+ if (icmpprintfs)
+ printf("icmp_input, type %d code %d\n", icp->icmp_type,
+ icp->icmp_code);
+#endif
+#if 0 /*KAME IPSEC*/
+ /* drop it if it does not match the policy */
+ if (ipsec4_in_reject(m, NULL)) {
+ ipsecstat.in_polvio++;
+ goto freeit;
+ }
+#endif
+ if (icp->icmp_type > ICMP_MAXTYPE)
+ goto raw;
+ icmpstat.icps_inhist[icp->icmp_type]++;
+ code = icp->icmp_code;
+ switch (icp->icmp_type) {
+
+ case ICMP_UNREACH:
+ switch (code) {
+ case ICMP_UNREACH_NET:
+ case ICMP_UNREACH_HOST:
+ case ICMP_UNREACH_PROTOCOL:
+ case ICMP_UNREACH_PORT:
+ case ICMP_UNREACH_SRCFAIL:
+ code += PRC_UNREACH_NET;
+ break;
+
+ case ICMP_UNREACH_NEEDFRAG:
+#if 0 /*NRL INET6*/
+ if (icp->icmp_nextmtu) {
+ extern int ipv6_trans_mtu
+ __P((struct mbuf **, int, int));
+ struct mbuf *m0 = m;
+
+ /*
+ * Do cool v4-related path MTU, for now,
+ * only v6-in-v4 can handle it.
+ */
+ if (icmplen >= ICMP_V6ADVLENMIN &&
+ icmplen >= ICMP_V6ADVLEN(icp) &&
+ icp->icmp_ip.ip_p == IPPROTO_IPV6) {
+ /*
+ * ipv6_trans_mtu returns 1 if
+ * the mbuf is still intact.
+ */
+ if (ipv6_trans_mtu(&m0,icp->icmp_nextmtu,
+ hlen + ICMP_V6ADVLEN(icp))) {
+ m = m0;
+ goto raw;
+ } else
+ return;
+ }
+ }
+#endif /* INET6 */
+ code = PRC_MSGSIZE;
+ break;
+
+ case ICMP_UNREACH_NET_UNKNOWN:
+ case ICMP_UNREACH_NET_PROHIB:
+ case ICMP_UNREACH_TOSNET:
+ code = PRC_UNREACH_NET;
+ break;
+
+ case ICMP_UNREACH_HOST_UNKNOWN:
+ case ICMP_UNREACH_ISOLATED:
+ case ICMP_UNREACH_HOST_PROHIB:
+ case ICMP_UNREACH_TOSHOST:
+ case ICMP_UNREACH_FILTER_PROHIB:
+ case ICMP_UNREACH_HOST_PRECEDENCE:
+ case ICMP_UNREACH_PRECEDENCE_CUTOFF:
+ code = PRC_UNREACH_HOST;
+ break;
+
+ default:
+ goto badcode;
+ }
+ goto deliver;
+
+ case ICMP_TIMXCEED:
+ if (code > 1)
+ goto badcode;
+ code += PRC_TIMXCEED_INTRANS;
+ goto deliver;
+
+ case ICMP_PARAMPROB:
+ if (code > 1)
+ goto badcode;
+ code = PRC_PARAMPROB;
+ goto deliver;
+
+ case ICMP_SOURCEQUENCH:
+ if (code)
+ goto badcode;
+ code = PRC_QUENCH;
+ deliver:
+ /*
+ * Problem with datagram; advise higher level routines.
+ */
+ if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
+ icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
+ icmpstat.icps_badlen++;
+ goto freeit;
+ }
+ if (IN_MULTICAST(icp->icmp_ip.ip_dst.s_addr))
+ goto badcode;
+ NTOHS(icp->icmp_ip.ip_len);
+#ifdef INET6
+ /* Get more contiguous data for a v6 in v4 ICMP message. */
+ if (icp->icmp_ip.ip_p == IPPROTO_IPV6) {
+ if (icmplen < ICMP_V6ADVLENMIN ||
+ icmplen < ICMP_V6ADVLEN(icp)) {
+ icmpstat.icps_badlen++;
+ goto freeit;
+ } else {
+ if (!(m = m_pullup(m, (ip->ip_hl << 2) +
+ ICMP_V6ADVLEN(icp)))) {
+ icmpstat.icps_tooshort++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ icp = (struct icmp *)(m->m_data + (ip->ip_hl << 2));
+ }
+ }
+#endif /* INET6 */
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
+#endif
+ icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
+ /*
+ * XXX if the packet contains [IPv4 AH TCP], we can't make a
+ * notification to TCP layer.
+ */
+ ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
+ if (ctlfunc)
+ (*ctlfunc)(code, sintosa(&icmpsrc), &icp->icmp_ip);
+ break;
+
+ badcode:
+ icmpstat.icps_badcode++;
+ break;
+
+ case ICMP_ECHO:
+ if (!icmpbmcastecho &&
+ (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
+ icmpstat.icps_bmcastecho++;
+ break;
+ }
+ icp->icmp_type = ICMP_ECHOREPLY;
+ goto reflect;
+
+ case ICMP_TSTAMP:
+ if (!icmpbmcastecho &&
+ (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
+ icmpstat.icps_bmcastecho++;
+ break;
+ }
+ if (icmplen < ICMP_TSLEN) {
+ icmpstat.icps_badlen++;
+ break;
+ }
+ icp->icmp_type = ICMP_TSTAMPREPLY;
+ icp->icmp_rtime = iptime();
+ icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */
+ goto reflect;
+
+ case ICMP_MASKREQ:
+ if (icmpmaskrepl == 0)
+ break;
+ /*
+ * We are not able to respond with all ones broadcast
+ * unless we receive it over a point-to-point interface.
+ */
+ if (icmplen < ICMP_MASKLEN) {
+ icmpstat.icps_badlen++;
+ break;
+ }
+ if (ip->ip_dst.s_addr == INADDR_BROADCAST ||
+ ip->ip_dst.s_addr == INADDR_ANY)
+ icmpdst.sin_addr = ip->ip_src;
+ else
+ icmpdst.sin_addr = ip->ip_dst;
+ ia = ifatoia(ifaof_ifpforaddr(sintosa(&icmpdst),
+ m->m_pkthdr.rcvif));
+ if (ia == 0)
+ break;
+ icp->icmp_type = ICMP_MASKREPLY;
+ icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;
+ if (ip->ip_src.s_addr == 0) {
+ if (ia->ia_ifp->if_flags & IFF_BROADCAST)
+ ip->ip_src = ia->ia_broadaddr.sin_addr;
+ else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
+ ip->ip_src = ia->ia_dstaddr.sin_addr;
+ }
+reflect:
+ ip->ip_len += hlen; /* since ip_input deducts this */
+ icmpstat.icps_reflect++;
+ icmpstat.icps_outhist[icp->icmp_type]++;
+ icmp_reflect(m);
+ return;
+
+ case ICMP_REDIRECT:
+ if (code > 3)
+ goto badcode;
+ if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
+ icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
+ icmpstat.icps_badlen++;
+ break;
+ }
+ /*
+ * Short circuit routing redirects to force
+ * immediate change in the kernel's routing
+ * tables. The message is also handed to anyone
+ * listening on a raw socket (e.g. the routing
+ * daemon for use in updating its tables).
+ */
+ icmpgw.sin_addr = ip->ip_src;
+ icmpdst.sin_addr = icp->icmp_gwaddr;
+#ifdef ICMPPRINTFS
+ if (icmpprintfs) {
+ char buf[4 * sizeof "123"];
+ strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst));
+
+ printf("redirect dst %s to %s\n",
+ buf, inet_ntoa(icp->icmp_gwaddr));
+ }
+#endif
+ icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
+ rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst),
+ (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
+ sintosa(&icmpgw), (struct rtentry **)0);
+ pfctlinput(PRC_REDIRECT_HOST, sintosa(&icmpsrc));
+#if 0 /*KAME IPSEC*/
+ key_sa_routechange((struct sockaddr *)&icmpsrc);
+#endif
+ break;
+
+ /*
+ * No kernel processing for the following;
+ * just fall through to send to raw listener.
+ */
+ case ICMP_ECHOREPLY:
+ case ICMP_ROUTERADVERT:
+ case ICMP_ROUTERSOLICIT:
+ case ICMP_TSTAMPREPLY:
+ case ICMP_IREQREPLY:
+ case ICMP_MASKREPLY:
+ default:
+ break;
+ }
+
+raw:
+ rip_input(m, hlen, proto);
+ return;
+
+freeit:
+ m_freem(m);
+}
+
+/*
+ * Reflect the ip packet back to the source
+ */
+void
+icmp_reflect(m)
+ struct mbuf *m;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register struct in_ifaddr *ia;
+ struct in_addr t;
+ struct mbuf *opts = 0;
+ int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
+
+ if (!in_canforward(ip->ip_src) &&
+ ((ip->ip_src.s_addr & IN_CLASSA_NET) !=
+ htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
+ m_freem(m); /* Bad return address */
+ goto done; /* ip_output() will check for broadcast */
+ }
+ t = ip->ip_dst;
+ ip->ip_dst = ip->ip_src;
+ /*
+ * If the incoming packet was addressed directly to us,
+ * use dst as the src for the reply. Otherwise (broadcast
+ * or anonymous), use the address which corresponds
+ * to the incoming interface.
+ */
+ for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) {
+ if (t.s_addr == ia->ia_addr.sin_addr.s_addr)
+ break;
+ if ((ia->ia_ifp->if_flags & IFF_BROADCAST) &&
+ t.s_addr == ia->ia_broadaddr.sin_addr.s_addr)
+ break;
+ }
+ icmpdst.sin_addr = t;
+ if (ia == (struct in_ifaddr *)0)
+ ia = ifatoia(ifaof_ifpforaddr(sintosa(&icmpdst),
+ m->m_pkthdr.rcvif));
+ /*
+ * The following happens if the packet was not addressed to us,
+ * and was received on an interface with no IP address.
+ */
+ if (ia == (struct in_ifaddr *)0)
+ ia = in_ifaddr.tqh_first;
+ t = ia->ia_addr.sin_addr;
+ ip->ip_src = t;
+ ip->ip_ttl = MAXTTL;
+
+ if (optlen > 0) {
+ register u_char *cp;
+ int opt, cnt;
+ u_int len;
+
+ /*
+ * Retrieve any source routing from the incoming packet;
+ * add on any record-route or timestamp options.
+ */
+ cp = (u_char *) (ip + 1);
+ if ((opts = ip_srcroute()) == 0 &&
+ (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) {
+ opts->m_len = sizeof(struct in_addr);
+ mtod(opts, struct in_addr *)->s_addr = 0;
+ }
+ if (opts) {
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("icmp_reflect optlen %d rt %d => ",
+ optlen, opts->m_len);
+#endif
+ for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ len = 1;
+ else {
+ len = cp[IPOPT_OLEN];
+ if (len <= 0 || len > cnt)
+ break;
+ }
+ /*
+ * Should check for overflow, but it "can't happen"
+ */
+ if (opt == IPOPT_RR || opt == IPOPT_TS ||
+ opt == IPOPT_SECURITY) {
+ bcopy((caddr_t)cp,
+ mtod(opts, caddr_t) + opts->m_len, len);
+ opts->m_len += len;
+ }
+ }
+ /* Terminate & pad, if necessary */
+ if ((cnt = opts->m_len % 4) != 0) {
+ for (; cnt < 4; cnt++) {
+ *(mtod(opts, caddr_t) + opts->m_len) =
+ IPOPT_EOL;
+ opts->m_len++;
+ }
+ }
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("%d\n", opts->m_len);
+#endif
+ }
+ /*
+ * Now strip out original options by copying rest of first
+ * mbuf's data back, and adjust the IP length.
+ */
+ ip->ip_len -= optlen;
+ ip->ip_hl = sizeof(struct ip) >> 2;
+ m->m_len -= optlen;
+ if (m->m_flags & M_PKTHDR)
+ m->m_pkthdr.len -= optlen;
+ optlen += sizeof(struct ip);
+ bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1),
+ (unsigned)(m->m_len - sizeof(struct ip)));
+ }
+ m->m_flags &= ~(M_BCAST|M_MCAST);
+ icmp_send(m, opts);
+done:
+ if (opts)
+ (void)m_free(opts);
+}
+
+/*
+ * Send an icmp packet back to the ip level,
+ * after supplying a checksum.
+ */
+void
+icmp_send(m, opts)
+ register struct mbuf *m;
+ struct mbuf *opts;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register int hlen;
+ register struct icmp *icp;
+
+ hlen = ip->ip_hl << 2;
+ m->m_data += hlen;
+ m->m_len -= hlen;
+ icp = mtod(m, struct icmp *);
+ icp->icmp_cksum = 0;
+ icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
+ m->m_data -= hlen;
+ m->m_len += hlen;
+#ifdef ICMPPRINTFS
+ if (icmpprintfs) {
+ char buf[4 * sizeof "123"];
+
+ strcpy(buf, inet_ntoa(ip->ip_dst));
+ printf("icmp_send dst %s src %s\n",
+ buf, inet_ntoa(ip->ip_src));
+ }
+#endif
+#if 0 /*KAME IPSEC*/
+ m->m_pkthdr.rcvif = NULL;
+#endif /*IPSEC*/
+ (void) ip_output(m, opts, NULL, 0, NULL, NULL);
+}
+
+n_time
+iptime()
+{
+ struct timeval atv;
+ u_long t;
+
+ microtime(&atv);
+ t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000;
+ return (htonl(t));
+}
+
+#ifdef CYGPKG_NET_SYSCTL
+int
+icmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+{
+
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case ICMPCTL_MASKREPL:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl));
+ case ICMPCTL_BMCASTECHO:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpbmcastecho));
+ default:
+ return (ENOPROTOOPT);
+ }
+ /* NOTREACHED */
+}
+#endif // CYGPKG_NET_SYSCTL
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/ip_id.c b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_id.c
new file mode 100644
index 0000000..177bb58
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_id.c
@@ -0,0 +1,232 @@
+//==========================================================================
+//
+// sys/netinet/ip_id.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_id.c,v 1.2 1999/08/26 13:37:01 provos Exp $ */
+
+/*
+ * Copyright 1998 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
+ * such a mathematical system to generate more random (yet non-repeating)
+ * ids to solve the resolver/named problem. But Niels designed the
+ * actual system based on the constraints.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Niels Provos.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * seed = random 15bit
+ * n = prime, g0 = generator to n,
+ * j = random so that gcd(j,n-1) == 1
+ * g = g0^j mod n will be a generator again.
+ *
+ * X[0] = random seed.
+ * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
+ * with a = 7^(even random) mod m,
+ * b = random with gcd(b,m) == 1
+ * m = 31104 and a maximal period of m-1.
+ *
+ * The transaction id is determined by:
+ * id[n] = seed xor (g^X[n] mod n)
+ *
+ * Effectivly the id is restricted to the lower 15 bits, thus
+ * yielding two different cycles by toggling the msb on and off.
+ * This avoids reuse issues caused by reseeding.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+
+#define RU_OUT 180 /* Time after wich will be reseeded */
+#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
+#define RU_GEN 2 /* Starting generator */
+#define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */
+#define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */
+#define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */
+
+#define PFAC_N 3
+const static u_int16_t pfacts[PFAC_N] = {
+ 2,
+ 3,
+ 2729
+};
+
+static u_int16_t ru_x;
+static u_int16_t ru_seed, ru_seed2;
+static u_int16_t ru_a, ru_b;
+static u_int16_t ru_g;
+static u_int16_t ru_counter = 0;
+static u_int16_t ru_msb = 0;
+static long ru_reseed;
+static u_int32_t tmp; /* Storage for unused random */
+
+static u_int16_t pmod __P((u_int16_t, u_int16_t, u_int16_t));
+static void ip_initid __P((void));
+u_int16_t ip_randomid __P((void));
+
+/*
+ * Do a fast modular exponation, returned value will be in the range
+ * of 0 - (mod-1)
+ */
+
+#ifdef __STDC__
+static u_int16_t
+pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
+#else
+static u_int16_t
+pmod(gen, exp, mod)
+ u_int16_t gen, exp, mod;
+#endif
+{
+ u_int16_t s, t, u;
+
+ s = 1;
+ t = gen;
+ u = exp;
+
+ while (u) {
+ if (u & 1)
+ s = (s*t) % mod;
+ u >>= 1;
+ t = (t*t) % mod;
+ }
+ return (s);
+}
+
+/*
+ * Initalizes the seed and chooses a suitable generator. Also toggles
+ * the msb flag. The msb flag is used to generate two distinct
+ * cycles of random numbers and thus avoiding reuse of ids.
+ *
+ * This function is called from id_randomid() when needed, an
+ * application does not have to worry about it.
+ */
+static void
+ip_initid(void)
+{
+ u_int16_t j, i;
+ int noprime = 1;
+
+ get_random_bytes((void *) &tmp, sizeof(tmp));
+ ru_x = (tmp & 0xFFFF) % RU_M;
+
+ /* 15 bits of random seed */
+ ru_seed = (tmp >> 16) & 0x7FFF;
+ get_random_bytes((void *) &tmp, sizeof(tmp));
+ ru_seed2 = tmp & 0x7FFF;
+
+ get_random_bytes((void *) &tmp, sizeof(tmp));
+
+ /* Determine the LCG we use */
+ ru_b = (tmp & 0xfffe) | 1;
+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
+ while (ru_b % 3 == 0)
+ ru_b += 2;
+
+ get_random_bytes((void *) &tmp, sizeof(tmp));
+ j = tmp % RU_N;
+ tmp = tmp >> 16;
+
+ /*
+ * Do a fast gcd(j,RU_N-1), so we can find a j with
+ * gcd(j, RU_N-1) == 1, giving a new generator for
+ * RU_GEN^j mod RU_N
+ */
+
+ while (noprime) {
+ for (i=0; i<PFAC_N; i++)
+ if (j%pfacts[i] == 0)
+ break;
+
+ if (i>=PFAC_N)
+ noprime = 0;
+ else
+ j = (j+1) % RU_N;
+ }
+
+ ru_g = pmod(RU_GEN,j,RU_N);
+ ru_counter = 0;
+
+ ru_reseed = time.tv_sec + RU_OUT;
+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
+}
+
+u_int16_t
+ip_randomid(void)
+{
+ int i, n;
+
+ if (ru_counter >= RU_MAX || time.tv_sec > ru_reseed)
+ ip_initid();
+
+ if (!tmp)
+ get_random_bytes((void *) &tmp, sizeof(tmp));
+
+ /* Skip a random number of ids */
+ n = tmp & 0x3; tmp = tmp >> 2;
+ if (ru_counter + n >= RU_MAX)
+ ip_initid();
+
+ for (i = 0; i <= n; i++)
+ /* Linear Congruential Generator */
+ ru_x = (ru_a*ru_x + ru_b) % RU_M;
+
+ ru_counter += i;
+
+ return (ru_seed ^ pmod(ru_g,ru_seed2 ^ ru_x,RU_N)) | ru_msb;
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/ip_input.c b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_input.c
new file mode 100644
index 0000000..b3850a9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_input.c
@@ -0,0 +1,1562 @@
+//==========================================================================
+//
+// sys/netinet/ip_input.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_input.c,v 1.44 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
+ */
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#ifndef __ECOS
+#include <sys/syslog.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_ipsp.h>
+
+#ifdef __ECOS
+#include <stdio.h> // for 'sprintf()'
+#endif
+
+#ifndef IPFORWARDING
+#ifdef GATEWAY
+#define IPFORWARDING 1 /* forward IP packets not for us */
+#else /* GATEWAY */
+#define IPFORWARDING 0 /* don't forward IP packets not for us */
+#endif /* GATEWAY */
+#endif /* IPFORWARDING */
+#ifndef IPSENDREDIRECTS
+#define IPSENDREDIRECTS 1
+#endif
+
+int encdebug = 0;
+
+/*
+ * Note: DIRECTED_BROADCAST is handled this way so that previous
+ * configuration using this option will Just Work.
+ */
+#ifndef IPDIRECTEDBCAST
+#ifdef DIRECTED_BROADCAST
+#define IPDIRECTEDBCAST 1
+#else
+#define IPDIRECTEDBCAST 0
+#endif /* DIRECTED_BROADCAST */
+#endif /* IPDIRECTEDBCAST */
+int ipforwarding = IPFORWARDING;
+int ipsendredirects = IPSENDREDIRECTS;
+int ip_dosourceroute = 0; /* no src-routing unless sysctl'd to enable */
+int ip_defttl = IPDEFTTL;
+int ip_directedbcast = IPDIRECTEDBCAST;
+#ifdef DIAGNOSTIC
+int ipprintfs = 0;
+#endif
+
+int ipsec_auth_default_level = IPSEC_AUTH_LEVEL_DEFAULT;
+int ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT;
+int ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT;
+
+/* Keep track of memory used for reassembly */
+int ip_maxqueue = 300;
+int ip_frags = 0;
+
+/* from in_pcb.c */
+extern int ipport_firstauto;
+extern int ipport_lastauto;
+extern int ipport_hifirstauto;
+extern int ipport_hilastauto;
+extern struct baddynamicports baddynamicports;
+
+extern struct domain inetdomain;
+extern struct protosw inetsw[];
+u_char ip_protox[IPPROTO_MAX];
+int ipqmaxlen = IFQ_MAXLEN;
+struct in_ifaddrhead in_ifaddr;
+struct ifqueue ipintrq;
+struct ipstat ipstat;
+#if defined(IPFILTER) || defined(IPFILTER_LKM)
+int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int,
+ struct mbuf **));
+#endif
+
+int ipq_locked;
+static __inline int ipq_lock_try __P((void));
+static __inline void ipq_unlock __P((void));
+
+static __inline int
+ipq_lock_try()
+{
+ int s;
+
+ s = splimp();
+ if (ipq_locked) {
+ splx(s);
+ return (0);
+ }
+ ipq_locked = 1;
+ splx(s);
+ return (1);
+}
+
+#define ipq_lock() ipq_lock_try()
+
+static __inline void
+ipq_unlock()
+{
+ int s;
+
+ s = splimp();
+ ipq_locked = 0;
+ splx(s);
+}
+
+#if 0 // Now in common layer
+
+static char *ui8tod( cyg_uint8 n, char *p )
+{
+ if( n > 99 ) *p++ = (n/100) + '0';
+ if( n > 9 ) *p++ = ((n/10)%10) + '0';
+ *p++ = (n%10) + '0';
+ return p;
+}
+
+char *
+inet_ntoa(ina)
+ struct in_addr ina;
+{
+ static char buf[4*sizeof "123"];
+ char *p = buf;
+ unsigned char *ucp = (unsigned char *)&ina;
+
+// sprintf(buf, "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
+// ucp[2] & 0xff, ucp[3] & 0xff);
+
+ p = ui8tod( ucp[0] & 0xFF, p);
+ *p++ = '.';
+ p = ui8tod( ucp[1] & 0xFF, p);
+ *p++ = '.';
+ p = ui8tod( ucp[2] & 0xFF, p);
+ *p++ = '.';
+ p = ui8tod( ucp[3] & 0xFF, p);
+ *p++ = '\0';
+
+ return (buf);
+}
+#endif
+
+/*
+ * We need to save the IP options in case a protocol wants to respond
+ * to an incoming packet over the same route if the packet got here
+ * using IP source routing. This allows connection establishment and
+ * maintenance when the remote end is on a network that is not known
+ * to us.
+ */
+int ip_nhops = 0;
+static struct ip_srcrt {
+ struct in_addr dst; /* final destination */
+ char nop; /* one NOP to align */
+ char srcopt[IPOPT_OFFSET + 1]; /* OPTVAL, OLEN and OFFSET */
+ struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
+} ip_srcrt;
+
+static void save_rte __P((u_char *, struct in_addr));
+static int ip_weadvertise(u_int32_t);
+
+/*
+ * IP initialization: fill in IP protocol switch table.
+ * All protocols not implemented in kernel go to raw IP protocol handler.
+ */
+void
+ip_init()
+{
+ register struct protosw *pr;
+ register int i;
+ const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP;
+ const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP;
+
+ pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
+ if (pr == 0)
+ panic("ip_init");
+ for (i = 0; i < IPPROTO_MAX; i++)
+ ip_protox[i] = pr - inetsw;
+ for (pr = inetdomain.dom_protosw;
+ pr < inetdomain.dom_protoswNPROTOSW; pr++)
+ if (pr->pr_domain->dom_family == PF_INET &&
+ pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
+ ip_protox[pr->pr_protocol] = pr - inetsw;
+ LIST_INIT(&ipq);
+ ipintrq.ifq_maxlen = ipqmaxlen;
+ TAILQ_INIT(&in_ifaddr);
+
+ /* Fill in list of ports not to allocate dynamically. */
+ bzero((void *)&baddynamicports, sizeof(baddynamicports));
+ for (i = 0; defbaddynamicports_tcp[i] != 0; i++)
+ DP_SET(baddynamicports.tcp, defbaddynamicports_tcp[i]);
+ for (i = 0; defbaddynamicports_udp[i] != 0; i++)
+ DP_SET(baddynamicports.udp, defbaddynamicports_tcp[i]);
+}
+
+struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
+struct route ipforward_rt;
+
+void
+ipintr()
+{
+ register struct mbuf *m;
+ int s;
+
+ if (needqueuedrain)
+ m_reclaim();
+
+ while (1) {
+ /*
+ * Get next datagram off input queue and get IP header
+ * in first mbuf.
+ */
+ s = splimp();
+ IF_DEQUEUE(&ipintrq, m);
+ splx(s);
+ if (m == 0)
+ return;
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("ipintr no HDR");
+#endif
+ ipv4_input(m, 0, NULL, 0);
+ }
+}
+
+/*
+ * Ip input routine. Checksum and byte swap header. If fragmented
+ * try to reassemble. Process options. Pass to next level.
+ */
+void
+ipv4_input(struct mbuf *m, ...)
+{
+ register struct ip *ip;
+ register struct ipq *fp;
+ struct in_ifaddr *ia;
+ struct ipqent *ipqe;
+ int hlen, mff;
+ va_list ap;
+ int extra;
+
+ va_start(ap, m);
+ extra = va_arg(ap, int);
+ va_end(ap);
+
+ if (extra) {
+ struct mbuf *newpacket;
+
+ if (!(newpacket = m_split(m, extra, M_NOWAIT))) {
+ m_freem(m);
+ return;
+ }
+
+ newpacket->m_flags |= m->m_flags;
+ m_freem(m);
+ m = newpacket;
+ extra = 0;
+ }
+
+ /*
+ * If no IP addresses have been set yet but the interfaces
+ * are receiving, can't do anything with incoming packets yet.
+ */
+ if (in_ifaddr.tqh_first == 0)
+ goto bad;
+ ipstat.ips_total++;
+ if (m->m_len < sizeof (struct ip) &&
+ (m = m_pullup(m, sizeof (struct ip))) == 0) {
+ ipstat.ips_toosmall++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ if (ip->ip_v != IPVERSION) {
+ ipstat.ips_badvers++;
+ goto bad;
+ }
+ hlen = ip->ip_hl << 2;
+ if (hlen < sizeof(struct ip)) { /* minimum header length */
+ ipstat.ips_badhlen++;
+ goto bad;
+ }
+ if (hlen > m->m_len) {
+ if ((m = m_pullup(m, hlen)) == 0) {
+ ipstat.ips_badhlen++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+ if ((ip->ip_sum = in_cksum(m, hlen)) != 0) {
+ ipstat.ips_badsum++;
+ goto bad;
+ }
+
+ /*
+ * Convert fields to host representation.
+ */
+ NTOHS(ip->ip_len);
+ if (ip->ip_len < hlen) {
+ ipstat.ips_badlen++;
+ goto bad;
+ }
+ NTOHS(ip->ip_id);
+ NTOHS(ip->ip_off);
+
+ /*
+ * Check that the amount of data in the buffers
+ * is as at least much as the IP header would have us expect.
+ * Trim mbufs if longer than we expect.
+ * Drop packet if shorter than we expect.
+ */
+ if (m->m_pkthdr.len < ip->ip_len) {
+ ipstat.ips_tooshort++;
+ goto bad;
+ }
+ if (m->m_pkthdr.len > ip->ip_len) {
+ if (m->m_len == m->m_pkthdr.len) {
+ m->m_len = ip->ip_len;
+ m->m_pkthdr.len = ip->ip_len;
+ } else
+ m_adj(m, ip->ip_len - m->m_pkthdr.len);
+ }
+
+#if defined(IPFILTER) || defined(IPFILTER_LKM)
+ /*
+ * Check if we want to allow this packet to be processed.
+ * Consider it to be bad if not.
+ */
+ {
+ struct mbuf *m0 = m;
+ if (fr_checkp && (*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m0))
+ return;
+ ip = mtod(m = m0, struct ip *);
+ }
+#endif
+
+ /*
+ * Process options and, if not destined for us,
+ * ship it on. ip_dooptions returns 1 when an
+ * error was detected (causing an icmp message
+ * to be sent and the original packet to be freed).
+ */
+ ip_nhops = 0; /* for source routed packets */
+ if (hlen > sizeof (struct ip) && ip_dooptions(m))
+ return;
+
+ /*
+ * Check our list of addresses, to see if the packet is for us.
+ */
+ if ((ia = in_iawithaddr(ip->ip_dst, m)) != NULL &&
+ (ia->ia_ifp->if_flags & IFF_UP))
+ goto ours;
+
+ if (IN_MULTICAST(ip->ip_dst.s_addr)) {
+ struct in_multi *inm;
+#ifdef MROUTING
+ extern struct socket *ip_mrouter;
+
+ if (m->m_flags & M_EXT) {
+ if ((m = m_pullup(m, hlen)) == 0) {
+ ipstat.ips_toosmall++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+
+ if (ip_mrouter) {
+ /*
+ * If we are acting as a multicast router, all
+ * incoming multicast packets are passed to the
+ * kernel-level multicast forwarding function.
+ * The packet is returned (relatively) intact; if
+ * ip_mforward() returns a non-zero value, the packet
+ * must be discarded, else it may be accepted below.
+ *
+ * (The IP ident field is put in the same byte order
+ * as expected when ip_mforward() is called from
+ * ip_output().)
+ */
+ ip->ip_id = htons(ip->ip_id);
+ if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ return;
+ }
+ ip->ip_id = ntohs(ip->ip_id);
+
+ /*
+ * The process-level routing demon needs to receive
+ * all multicast IGMP packets, whether or not this
+ * host belongs to their destination groups.
+ */
+ if (ip->ip_p == IPPROTO_IGMP)
+ goto ours;
+ ipstat.ips_forward++;
+ }
+#endif
+ /*
+ * See if we belong to the destination multicast group on the
+ * arrival interface.
+ */
+ IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);
+ if (inm == NULL) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ return;
+ }
+ goto ours;
+ }
+ if (ip->ip_dst.s_addr == INADDR_BROADCAST ||
+ ip->ip_dst.s_addr == INADDR_ANY)
+ goto ours;
+
+ /*
+ * Not for us; forward if possible and desirable.
+ */
+ if (ipforwarding == 0) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ } else
+ ip_forward(m, 0);
+ return;
+
+ours:
+ /*
+ * If offset or IP_MF are set, must reassemble.
+ * Otherwise, nothing need be done.
+ * (We could look in the reassembly queue to see
+ * if the packet was previously fragmented,
+ * but it's not worth the time; just let them time out.)
+ */
+ if (ip->ip_off &~ (IP_DF | IP_RF)) {
+ if (m->m_flags & M_EXT) { /* XXX */
+ if ((m = m_pullup(m, hlen)) == 0) {
+ ipstat.ips_toosmall++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+
+ /*
+ * Look for queue of fragments
+ * of this datagram.
+ */
+ ipq_lock();
+ for (fp = ipq.lh_first; fp != NULL; fp = fp->ipq_q.le_next)
+ if (ip->ip_id == fp->ipq_id &&
+ ip->ip_src.s_addr == fp->ipq_src.s_addr &&
+ ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
+ ip->ip_p == fp->ipq_p)
+ goto found;
+ fp = 0;
+found:
+
+ /*
+ * Adjust ip_len to not reflect header,
+ * set ipqe_mff if more fragments are expected,
+ * convert offset of this to bytes.
+ */
+ ip->ip_len -= hlen;
+ mff = (ip->ip_off & IP_MF) != 0;
+ if (mff) {
+ /*
+ * Make sure that fragments have a data length
+ * that's a non-zero multiple of 8 bytes.
+ */
+ if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {
+ ipstat.ips_badfrags++;
+ ipq_unlock();
+ goto bad;
+ }
+ }
+ ip->ip_off <<= 3;
+
+ /*
+ * If datagram marked as having more fragments
+ * or if this is not the first fragment,
+ * attempt reassembly; if it succeeds, proceed.
+ */
+ if (mff || ip->ip_off) {
+ ipstat.ips_fragments++;
+ if (ip_frags + 1 > ip_maxqueue) {
+ ip_flush();
+ ipstat.ips_rcvmemdrop++;
+ ipq_unlock();
+ goto bad;
+ }
+
+ MALLOC(ipqe, struct ipqent *, sizeof (struct ipqent),
+ M_IPQ, M_NOWAIT);
+ if (ipqe == NULL) {
+ ipstat.ips_rcvmemdrop++;
+ ipq_unlock();
+ goto bad;
+ }
+ ip_frags++;
+ ipqe->ipqe_mff = mff;
+ ipqe->ipqe_ip = ip;
+ ip = ip_reass(ipqe, fp);
+ if (ip == 0) {
+ ipq_unlock();
+ return;
+ }
+ ipstat.ips_reassembled++;
+ m = dtom(ip);
+ hlen = ip->ip_hl << 2;
+ } else
+ if (fp)
+ ip_freef(fp);
+ ipq_unlock();
+ } else
+ ip->ip_len -= hlen;
+
+ /*
+ * Switch out to protocol's input routine.
+ */
+ ipstat.ips_delivered++;
+ (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen, NULL, 0);
+ return;
+bad:
+ m_freem(m);
+}
+
+struct in_ifaddr *
+in_iawithaddr(ina, m)
+ struct in_addr ina;
+ register struct mbuf *m;
+{
+ register struct in_ifaddr *ia;
+
+ for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) {
+ if ((ina.s_addr == ia->ia_addr.sin_addr.s_addr) ||
+ ((ia->ia_ifp->if_flags & (IFF_LOOPBACK|IFF_LINK1)) ==
+ (IFF_LOOPBACK|IFF_LINK1) &&
+ ia->ia_subnet == (ina.s_addr & ia->ia_subnetmask)))
+ return ia;
+ if (m && ((ip_directedbcast == 0) || (ip_directedbcast &&
+ ia->ia_ifp == m->m_pkthdr.rcvif)) &&
+ (ia->ia_ifp->if_flags & IFF_BROADCAST)) {
+ if (ina.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
+ ina.s_addr == ia->ia_netbroadcast.s_addr ||
+ /*
+ * Look for all-0's host part (old broadcast addr),
+ * either for subnet or net.
+ */
+ ina.s_addr == ia->ia_subnet ||
+ ina.s_addr == ia->ia_net) {
+ /* Make sure M_BCAST is set */
+ m->m_flags |= M_BCAST;
+ return ia;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Take incoming datagram fragment and try to
+ * reassemble it into whole datagram. If a chain for
+ * reassembly of this datagram already exists, then it
+ * is given as fp; otherwise have to make a chain.
+ */
+struct ip *
+ip_reass(ipqe, fp)
+ register struct ipqent *ipqe;
+ register struct ipq *fp;
+{
+ register struct mbuf *m = dtom(ipqe->ipqe_ip);
+ register struct ipqent *nq, *p, *q;
+ struct ip *ip;
+ struct mbuf *t;
+ int hlen = ipqe->ipqe_ip->ip_hl << 2;
+ int i, next;
+
+ /*
+ * Presence of header sizes in mbufs
+ * would confuse code below.
+ */
+ m->m_data += hlen;
+ m->m_len -= hlen;
+
+ /*
+ * If first fragment to arrive, create a reassembly queue.
+ */
+ if (fp == 0) {
+ if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
+ goto dropfrag;
+ fp = mtod(t, struct ipq *);
+ LIST_INSERT_HEAD(&ipq, fp, ipq_q);
+ fp->ipq_ttl = IPFRAGTTL;
+ fp->ipq_p = ipqe->ipqe_ip->ip_p;
+ fp->ipq_id = ipqe->ipqe_ip->ip_id;
+ LIST_INIT(&fp->ipq_fragq);
+ fp->ipq_src = ipqe->ipqe_ip->ip_src;
+ fp->ipq_dst = ipqe->ipqe_ip->ip_dst;
+ p = NULL;
+ goto insert;
+ }
+
+ /*
+ * Find a segment which begins after this one does.
+ */
+ for (p = NULL, q = fp->ipq_fragq.lh_first; q != NULL;
+ p = q, q = q->ipqe_q.le_next)
+ if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off)
+ break;
+
+ /*
+ * If there is a preceding segment, it may provide some of
+ * our data already. If so, drop the data from the incoming
+ * segment. If it provides all of our data, drop us.
+ */
+ if (p != NULL) {
+ i = p->ipqe_ip->ip_off + p->ipqe_ip->ip_len -
+ ipqe->ipqe_ip->ip_off;
+ if (i > 0) {
+ if (i >= ipqe->ipqe_ip->ip_len)
+ goto dropfrag;
+ m_adj(dtom(ipqe->ipqe_ip), i);
+ ipqe->ipqe_ip->ip_off += i;
+ ipqe->ipqe_ip->ip_len -= i;
+ }
+ }
+
+ /*
+ * While we overlap succeeding segments trim them or,
+ * if they are completely covered, dequeue them.
+ */
+ for (; q != NULL && ipqe->ipqe_ip->ip_off + ipqe->ipqe_ip->ip_len >
+ q->ipqe_ip->ip_off; q = nq) {
+ i = (ipqe->ipqe_ip->ip_off + ipqe->ipqe_ip->ip_len) -
+ q->ipqe_ip->ip_off;
+ if (i < q->ipqe_ip->ip_len) {
+ q->ipqe_ip->ip_len -= i;
+ q->ipqe_ip->ip_off += i;
+ m_adj(dtom(q->ipqe_ip), i);
+ break;
+ }
+ nq = q->ipqe_q.le_next;
+ m_freem(dtom(q->ipqe_ip));
+ LIST_REMOVE(q, ipqe_q);
+ FREE(q, M_IPQ);
+ ip_frags--;
+ }
+
+insert:
+ /*
+ * Stick new segment in its place;
+ * check for complete reassembly.
+ */
+ if (p == NULL) {
+ LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q);
+ } else {
+ LIST_INSERT_AFTER(p, ipqe, ipqe_q);
+ }
+ next = 0;
+ for (p = NULL, q = fp->ipq_fragq.lh_first; q != NULL;
+ p = q, q = q->ipqe_q.le_next) {
+ if (q->ipqe_ip->ip_off != next)
+ return (0);
+ next += q->ipqe_ip->ip_len;
+ }
+ if (p->ipqe_mff)
+ return (0);
+
+ /*
+ * Reassembly is complete. Check for a bogus message size and
+ * concatenate fragments.
+ */
+ q = fp->ipq_fragq.lh_first;
+ ip = q->ipqe_ip;
+ if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
+ ipstat.ips_toolong++;
+ ip_freef(fp);
+ return (0);
+ }
+ m = dtom(q->ipqe_ip);
+ t = m->m_next;
+ m->m_next = 0;
+ m_cat(m, t);
+ nq = q->ipqe_q.le_next;
+ FREE(q, M_IPQ);
+ ip_frags--;
+ for (q = nq; q != NULL; q = nq) {
+ t = dtom(q->ipqe_ip);
+ nq = q->ipqe_q.le_next;
+ FREE(q, M_IPQ);
+ ip_frags--;
+ m_cat(m, t);
+ }
+
+ /*
+ * Create header for new ip packet by
+ * modifying header of first packet;
+ * dequeue and discard fragment reassembly header.
+ * Make header visible.
+ */
+ ip->ip_len = next;
+ ip->ip_ttl = 0; /* xxx */
+ ip->ip_sum = 0;
+ ip->ip_src = fp->ipq_src;
+ ip->ip_dst = fp->ipq_dst;
+ LIST_REMOVE(fp, ipq_q);
+ (void) m_free(dtom(fp));
+ m->m_len += (ip->ip_hl << 2);
+ m->m_data -= (ip->ip_hl << 2);
+ /* some debugging cruft by sklower, below, will go away soon */
+ if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
+ register int plen = 0;
+ for (t = m; m; m = m->m_next)
+ plen += m->m_len;
+ t->m_pkthdr.len = plen;
+ }
+ return (ip);
+
+dropfrag:
+ ipstat.ips_fragdropped++;
+ m_freem(m);
+ FREE(ipqe, M_IPQ);
+ ip_frags--;
+ return (0);
+}
+
+/*
+ * Free a fragment reassembly header and all
+ * associated datagrams.
+ */
+void
+ip_freef(fp)
+ struct ipq *fp;
+{
+ register struct ipqent *q, *p;
+
+ for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {
+ p = q->ipqe_q.le_next;
+ m_freem(dtom(q->ipqe_ip));
+ LIST_REMOVE(q, ipqe_q);
+ FREE(q, M_IPQ);
+ ip_frags--;
+ }
+ LIST_REMOVE(fp, ipq_q);
+ (void) m_free(dtom(fp));
+}
+
+/*
+ * IP timer processing;
+ * if a timer expires on a reassembly
+ * queue, discard it.
+ */
+void
+ip_slowtimo()
+{
+ register struct ipq *fp, *nfp;
+ int s = splsoftnet();
+
+ ipq_lock();
+ for (fp = ipq.lh_first; fp != NULL; fp = nfp) {
+ nfp = fp->ipq_q.le_next;
+ if (--fp->ipq_ttl == 0) {
+ ipstat.ips_fragtimeout++;
+ ip_freef(fp);
+ }
+ }
+ ipq_unlock();
+ splx(s);
+}
+
+/*
+ * Drain off all datagram fragments.
+ */
+void
+ip_drain()
+{
+
+ if (ipq_lock_try() == 0)
+ return;
+ while (ipq.lh_first != NULL) {
+ ipstat.ips_fragdropped++;
+ ip_freef(ipq.lh_first);
+ }
+ ipq_unlock();
+}
+
+/*
+ * Flush a bunch of datagram fragments, till we are down to 75%.
+ */
+void
+ip_flush()
+{
+ int max = 50;
+
+ /* ipq already locked */
+ while (ipq.lh_first != NULL && ip_frags > ip_maxqueue * 3 / 4 && --max) {
+ ipstat.ips_fragdropped++;
+ ip_freef(ipq.lh_first);
+ }
+}
+
+/*
+ * Do option processing on a datagram,
+ * possibly discarding it if bad options are encountered,
+ * or forwarding it if source-routed.
+ * Returns 1 if packet has been forwarded/freed,
+ * 0 if the packet should be processed further.
+ */
+int
+ip_dooptions(m)
+ struct mbuf *m;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register u_char *cp;
+ register struct ip_timestamp *ipt;
+ register struct in_ifaddr *ia;
+ int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;
+ struct in_addr *sin, dst;
+ n_time ntime;
+
+ dst = ip->ip_dst;
+ cp = (u_char *)(ip + 1);
+ cnt = (ip->ip_hl << 2) - sizeof (struct ip);
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[IPOPT_OLEN];
+ if (optlen <= 0 || optlen > cnt) {
+ code = &cp[IPOPT_OLEN] - (u_char *)ip;
+ goto bad;
+ }
+ }
+ switch (opt) {
+
+ default:
+ break;
+
+ /*
+ * Source routing with record.
+ * Find interface with current destination address.
+ * If none on this machine then drop if strictly routed,
+ * or do nothing if loosely routed.
+ * Record interface address and bring up next address
+ * component. If strictly routed make sure next
+ * address is on directly accessible net.
+ */
+ case IPOPT_LSRR:
+ case IPOPT_SSRR:
+ if (!ip_dosourceroute) {
+#ifndef __ECOS
+ char buf[4*sizeof "123"];
+
+ strcpy(buf, inet_ntoa(ip->ip_dst));
+ log(LOG_WARNING,
+ "attempted source route from %s to %s\n",
+ inet_ntoa(ip->ip_src), buf);
+#endif
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_SRCFAIL;
+ goto bad;
+ }
+ if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
+ code = &cp[IPOPT_OFFSET] - (u_char *)ip;
+ goto bad;
+ }
+ ipaddr.sin_addr = ip->ip_dst;
+ ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr)));
+ if (ia == 0) {
+ if (opt == IPOPT_SSRR) {
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_SRCFAIL;
+ goto bad;
+ }
+ /*
+ * Loose routing, and not at next destination
+ * yet; nothing to do except forward.
+ */
+ break;
+ }
+ off--; /* 0 origin */
+ if (off > optlen - sizeof(struct in_addr)) {
+ /*
+ * End of source route. Should be for us.
+ */
+ save_rte(cp, ip->ip_src);
+ break;
+ }
+
+ /*
+ * locate outgoing interface
+ */
+ bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
+ sizeof(ipaddr.sin_addr));
+ if (opt == IPOPT_SSRR) {
+#define INA struct in_ifaddr *
+#define SA struct sockaddr *
+ if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
+ ia = (INA)ifa_ifwithnet((SA)&ipaddr);
+ } else
+ ia = ip_rtaddr(ipaddr.sin_addr);
+ if (ia == 0) {
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_SRCFAIL;
+ goto bad;
+ }
+ ip->ip_dst = ipaddr.sin_addr;
+ bcopy((caddr_t)&ia->ia_addr.sin_addr,
+ (caddr_t)(cp + off), sizeof(struct in_addr));
+ cp[IPOPT_OFFSET] += sizeof(struct in_addr);
+ /*
+ * Let ip_intr's mcast routing check handle mcast pkts
+ */
+ forward = !IN_MULTICAST(ip->ip_dst.s_addr);
+ break;
+
+ case IPOPT_RR:
+ if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
+ code = &cp[IPOPT_OFFSET] - (u_char *)ip;
+ goto bad;
+ }
+
+ /*
+ * If no space remains, ignore.
+ */
+ off--; /* 0 origin */
+ if (off > optlen - sizeof(struct in_addr))
+ break;
+ bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
+ sizeof(ipaddr.sin_addr));
+ /*
+ * locate outgoing interface; if we're the destination,
+ * use the incoming interface (should be same).
+ */
+ if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
+ (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_HOST;
+ goto bad;
+ }
+ bcopy((caddr_t)&ia->ia_addr.sin_addr,
+ (caddr_t)(cp + off), sizeof(struct in_addr));
+ cp[IPOPT_OFFSET] += sizeof(struct in_addr);
+ break;
+
+ case IPOPT_TS:
+ code = cp - (u_char *)ip;
+ ipt = (struct ip_timestamp *)cp;
+ if (ipt->ipt_ptr < 5 || ipt->ipt_len < 5)
+ goto bad;
+ if (ipt->ipt_ptr - 1 + sizeof(n_time) > ipt->ipt_len) {
+ if (++ipt->ipt_oflw == 0)
+ goto bad;
+ break;
+ }
+ sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
+ switch (ipt->ipt_flg) {
+
+ case IPOPT_TS_TSONLY:
+ break;
+
+ case IPOPT_TS_TSANDADDR:
+ if (ipt->ipt_ptr - 1 + sizeof(n_time) +
+ sizeof(struct in_addr) > ipt->ipt_len)
+ goto bad;
+ ipaddr.sin_addr = dst;
+ ia = (INA)ifaof_ifpforaddr((SA)&ipaddr,
+ m->m_pkthdr.rcvif);
+ if (ia == 0)
+ continue;
+ bcopy((caddr_t)&ia->ia_addr.sin_addr,
+ (caddr_t)sin, sizeof(struct in_addr));
+ ipt->ipt_ptr += sizeof(struct in_addr);
+ break;
+
+ case IPOPT_TS_PRESPEC:
+ if (ipt->ipt_ptr - 1 + sizeof(n_time) +
+ sizeof(struct in_addr) > ipt->ipt_len)
+ goto bad;
+ bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
+ sizeof(struct in_addr));
+ if (ifa_ifwithaddr((SA)&ipaddr) == 0)
+ continue;
+ ipt->ipt_ptr += sizeof(struct in_addr);
+ break;
+
+ default:
+ goto bad;
+ }
+ ntime = iptime();
+ bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
+ sizeof(n_time));
+ ipt->ipt_ptr += sizeof(n_time);
+ }
+ }
+ if (forward && ipforwarding) {
+ ip_forward(m, 1);
+ return (1);
+ }
+ return (0);
+bad:
+ ip->ip_len -= ip->ip_hl << 2; /* XXX icmp_error adds in hdr length */
+ HTONS(ip->ip_len); /* XXX because ip_input changed these three */
+ HTONS(ip->ip_id);
+ HTONS(ip->ip_off);
+ icmp_error(m, type, code, 0, 0);
+ ipstat.ips_badoptions++;
+ return (1);
+}
+
+/*
+ * Given address of next destination (final or next hop),
+ * return internet address info of interface to be used to get there.
+ */
+struct in_ifaddr *
+ip_rtaddr(dst)
+ struct in_addr dst;
+{
+ register struct sockaddr_in *sin;
+
+ sin = satosin(&ipforward_rt.ro_dst);
+
+ if (ipforward_rt.ro_rt == 0 || dst.s_addr != sin->sin_addr.s_addr) {
+ if (ipforward_rt.ro_rt) {
+ RTFREE(ipforward_rt.ro_rt);
+ ipforward_rt.ro_rt = 0;
+ }
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = dst;
+
+ rtalloc(&ipforward_rt);
+ }
+ if (ipforward_rt.ro_rt == 0)
+ return ((struct in_ifaddr *)0);
+ return (ifatoia(ipforward_rt.ro_rt->rt_ifa));
+}
+
+/*
+ * Save incoming source route for use in replies,
+ * to be picked up later by ip_srcroute if the receiver is interested.
+ */
+void
+save_rte(option, dst)
+ u_char *option;
+ struct in_addr dst;
+{
+ unsigned olen;
+
+ olen = option[IPOPT_OLEN];
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("save_rte: olen %d\n", olen);
+#endif /* 0 */
+ if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))
+ return;
+ bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen);
+ ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);
+ ip_srcrt.dst = dst;
+}
+
+/*
+ * Check whether we do proxy ARP for this address and we point to ourselves.
+ * Code shamelessly copied from arplookup().
+ */
+static int
+ip_weadvertise(addr)
+ u_int32_t addr;
+{
+ register struct rtentry *rt;
+ register struct ifnet *ifp;
+ register struct ifaddr *ifa;
+ struct sockaddr_inarp sin;
+
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = addr;
+ sin.sin_other = SIN_PROXY;
+ rt = rtalloc1(sintosa(&sin), 0);
+ if (rt == 0)
+ return 0;
+
+ RTFREE(rt);
+
+ if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
+ rt->rt_gateway->sa_family != AF_LINK)
+ return 0;
+
+ for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
+ ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != rt->rt_gateway->sa_family)
+ continue;
+
+ if (!bcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr),
+ LLADDR((struct sockaddr_dl *)rt->rt_gateway),
+ ETHER_ADDR_LEN))
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Retrieve incoming source route for use in replies,
+ * in the same form used by setsockopt.
+ * The first hop is placed before the options, will be removed later.
+ */
+struct mbuf *
+ip_srcroute()
+{
+ register struct in_addr *p, *q;
+ register struct mbuf *m;
+
+ if (ip_nhops == 0)
+ return ((struct mbuf *)0);
+ m = m_get(M_DONTWAIT, MT_SOOPTS);
+ if (m == 0)
+ return ((struct mbuf *)0);
+
+#define OPTSIZ (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt))
+
+ /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */
+ m->m_len = ip_nhops * sizeof(struct in_addr) + sizeof(struct in_addr) +
+ OPTSIZ;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("ip_srcroute: nhops %d mlen %d", ip_nhops, m->m_len);
+#endif
+
+ /*
+ * First save first hop for return route
+ */
+ p = &ip_srcrt.route[ip_nhops - 1];
+ *(mtod(m, struct in_addr *)) = *p--;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf(" hops %x", ntohl(mtod(m, struct in_addr *)->s_addr));
+#endif
+
+ /*
+ * Copy option fields and padding (nop) to mbuf.
+ */
+ ip_srcrt.nop = IPOPT_NOP;
+ ip_srcrt.srcopt[IPOPT_OFFSET] = IPOPT_MINOFF;
+ bcopy((caddr_t)&ip_srcrt.nop,
+ mtod(m, caddr_t) + sizeof(struct in_addr), OPTSIZ);
+ q = (struct in_addr *)(mtod(m, caddr_t) +
+ sizeof(struct in_addr) + OPTSIZ);
+#undef OPTSIZ
+ /*
+ * Record return path as an IP source route,
+ * reversing the path (pointers are now aligned).
+ */
+ while (p >= ip_srcrt.route) {
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf(" %x", ntohl(q->s_addr));
+#endif
+ *q++ = *p--;
+ }
+ /*
+ * Last hop goes to final destination.
+ */
+ *q = ip_srcrt.dst;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf(" %x\n", ntohl(q->s_addr));
+#endif
+ return (m);
+}
+
+/*
+ * Strip out IP options, at higher
+ * level protocol in the kernel.
+ * Second argument is buffer to which options
+ * will be moved, and return value is their length.
+ * XXX should be deleted; last arg currently ignored.
+ */
+void
+ip_stripoptions(m, mopt)
+ register struct mbuf *m;
+ struct mbuf *mopt;
+{
+ register int i;
+ struct ip *ip = mtod(m, struct ip *);
+ register caddr_t opts;
+ int olen;
+
+ olen = (ip->ip_hl<<2) - sizeof (struct ip);
+ opts = (caddr_t)(ip + 1);
+ i = m->m_len - (sizeof (struct ip) + olen);
+ bcopy(opts + olen, opts, (unsigned)i);
+ m->m_len -= olen;
+ if (m->m_flags & M_PKTHDR)
+ m->m_pkthdr.len -= olen;
+ ip->ip_hl = sizeof(struct ip) >> 2;
+}
+
+int inetctlerrmap[PRC_NCMDS] = {
+ 0, 0, 0, 0,
+ 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
+ EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
+ EMSGSIZE, EHOSTUNREACH, 0, 0,
+ 0, 0, 0, 0,
+ ENOPROTOOPT
+};
+
+/*
+ * Forward a packet. If some error occurs return the sender
+ * an icmp packet. Note we can't always generate a meaningful
+ * icmp message because icmp doesn't have a large enough repertoire
+ * of codes and types.
+ *
+ * If not forwarding, just drop the packet. This could be confusing
+ * if ipforwarding was zero but some routing protocol was advancing
+ * us as a gateway to somewhere. However, we must let the routing
+ * protocol deal with that.
+ *
+ * The srcrt parameter indicates whether the packet is being forwarded
+ * via a source route.
+ */
+void
+ip_forward(m, srcrt)
+ struct mbuf *m;
+ int srcrt;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register struct sockaddr_in *sin;
+ register struct rtentry *rt;
+ int error, type = 0, code = 0;
+ struct mbuf *mcopy;
+ n_long dest;
+ struct ifnet *destifp;
+#if 0 /*KAME IPSEC*/
+ struct ifnet dummyifp;
+#endif
+
+ dest = 0;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("forward: src %x dst %x ttl %x\n", ip->ip_src.s_addr,
+ ip->ip_dst.s_addr, ip->ip_ttl);
+#endif
+ if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ return;
+ }
+ HTONS(ip->ip_id);
+ if (ip->ip_ttl <= IPTTLDEC) {
+ icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
+ return;
+ }
+ ip->ip_ttl -= IPTTLDEC;
+
+ sin = satosin(&ipforward_rt.ro_dst);
+ if ((rt = ipforward_rt.ro_rt) == 0 ||
+ ip->ip_dst.s_addr != sin->sin_addr.s_addr) {
+ if (ipforward_rt.ro_rt) {
+ RTFREE(ipforward_rt.ro_rt);
+ ipforward_rt.ro_rt = 0;
+ }
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = ip->ip_dst;
+
+ rtalloc(&ipforward_rt);
+ if (ipforward_rt.ro_rt == 0) {
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
+ return;
+ }
+ rt = ipforward_rt.ro_rt;
+ }
+
+ /*
+ * Save at most 68 bytes of the packet in case
+ * we need to generate an ICMP message to the src.
+ */
+ mcopy = m_copy(m, 0, imin((int)ip->ip_len, 68));
+
+ /*
+ * If forwarding packet using same interface that it came in on,
+ * perhaps should send a redirect to sender to shortcut a hop.
+ * Only send redirect if source is sending directly to us,
+ * and if packet was not source routed (or has any options).
+ * Also, don't send redirect if forwarding using a default route
+ * or a route modified by a redirect.
+ * Don't send redirect if we advertise destination's arp address
+ * as ours (proxy arp).
+ */
+ if (rt->rt_ifp == m->m_pkthdr.rcvif &&
+ (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
+ satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
+ ipsendredirects && !srcrt &&
+ !ip_weadvertise(satosin(rt_key(rt))->sin_addr.s_addr)) {
+ if (rt->rt_ifa &&
+ (ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) ==
+ ifatoia(rt->rt_ifa)->ia_subnet) {
+ if (rt->rt_flags & RTF_GATEWAY)
+ dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
+ else
+ dest = ip->ip_dst.s_addr;
+ /* Router requirements says to only send host redirects */
+ type = ICMP_REDIRECT;
+ code = ICMP_REDIRECT_HOST;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("redirect (%d) to %x\n", code, (u_int32_t)dest);
+#endif
+ }
+ }
+
+#if 0 /*KAME IPSEC*/
+ m->m_pkthdr.rcvif = NULL;
+#endif /*IPSEC*/
+ error = ip_output(m, (struct mbuf *)0, &ipforward_rt,
+ (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
+ 0, NULL, NULL);
+ if (error)
+ ipstat.ips_cantforward++;
+ else {
+ ipstat.ips_forward++;
+ if (type)
+ ipstat.ips_redirectsent++;
+ else {
+ if (mcopy)
+ m_freem(mcopy);
+ return;
+ }
+ }
+ if (mcopy == NULL)
+ return;
+ destifp = NULL;
+
+ switch (error) {
+
+ case 0: /* forwarded, but need redirect */
+ /* type, code set above */
+ break;
+
+ case ENETUNREACH: /* shouldn't happen, checked above */
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case EHOSTDOWN:
+ default:
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_HOST;
+ break;
+
+ case EMSGSIZE:
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_NEEDFRAG;
+#if 1 /*KAME IPSEC*/
+ if (ipforward_rt.ro_rt)
+ destifp = ipforward_rt.ro_rt->rt_ifp;
+#else
+ /*
+ * If the packet is routed over IPsec tunnel, tell the
+ * originator the tunnel MTU.
+ * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
+ * XXX quickhack!!!
+ */
+ if (ipforward_rt.ro_rt) {
+ struct secpolicy *sp;
+ int ipsecerror;
+ int ipsechdr;
+ struct route *ro;
+
+ sp = ipsec4_getpolicybyaddr(mcopy,
+ IP_FORWARDING,
+ &ipsecerror);
+
+ if (sp == NULL)
+ destifp = ipforward_rt.ro_rt->rt_ifp;
+ else {
+ /* count IPsec header size */
+ ipsechdr = ipsec4_hdrsiz(mcopy, NULL);
+
+ /*
+ * find the correct route for outer IPv4
+ * header, compute tunnel MTU.
+ *
+ * XXX BUG ALERT
+ * The "dummyifp" code relies upon the fact
+ * that icmp_error() touches only ifp->if_mtu.
+ */
+ /*XXX*/
+ destifp = NULL;
+ if (sp->req != NULL
+ && sp->req->sa != NULL) {
+ ro = &sp->req->sa->saidx->sa_route;
+ if (ro->ro_rt && ro->ro_rt->rt_ifp) {
+ dummyifp.if_mtu =
+ ro->ro_rt->rt_ifp->if_mtu;
+ dummyifp.if_mtu -= ipsechdr;
+ destifp = &dummyifp;
+ }
+ }
+
+ key_freesp(sp);
+ }
+ }
+#endif /*IPSEC*/
+ ipstat.ips_cantfrag++;
+ break;
+
+ case ENOBUFS:
+ type = ICMP_SOURCEQUENCH;
+ code = 0;
+ break;
+ }
+
+ icmp_error(mcopy, type, code, dest, destifp);
+}
+
+#ifdef CYGPKG_NET_SYSCTL
+int
+ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+{
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case IPCTL_FORWARDING:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &ipforwarding));
+ case IPCTL_SENDREDIRECTS:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ipsendredirects));
+ case IPCTL_DEFTTL:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_defttl));
+#ifdef notyet
+ case IPCTL_DEFMTU:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu));
+#endif
+ case IPCTL_SOURCEROUTE:
+ /*
+ * Don't allow this to change in a secure environment.
+ */
+ if (newp && securelevel > 0)
+ return (EPERM);
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ip_dosourceroute));
+ case IPCTL_DIRECTEDBCAST:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ip_directedbcast));
+ case IPCTL_IPPORT_FIRSTAUTO:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ipport_firstauto));
+ case IPCTL_IPPORT_LASTAUTO:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ipport_lastauto));
+ case IPCTL_IPPORT_HIFIRSTAUTO:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ipport_hifirstauto));
+ case IPCTL_IPPORT_HILASTAUTO:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ipport_hilastauto));
+ case IPCTL_IPPORT_MAXQUEUE:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &ip_maxqueue));
+ case IPCTL_ENCDEBUG:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &encdebug));
+ default:
+ return (EOPNOTSUPP);
+ }
+ /* NOTREACHED */
+}
+#endif // CYGPKG_NET_SYSCTL
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/ip_output.c b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_output.c
new file mode 100644
index 0000000..40f125a
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/ip_output.c
@@ -0,0 +1,1757 @@
+//==========================================================================
+//
+// sys/netinet/ip_output.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: ip_output.c,v 1.57 1999/12/10 08:55:23 angelos Exp $ */
+/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/kernel.h>
+#ifndef __ECOS
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <sys/proc.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+
+#ifdef vax
+#include <machine/mtpr.h>
+#endif
+
+#include <machine/stdarg.h>
+
+#ifdef IPSEC
+#include <netinet/ip_ah.h>
+#include <netinet/ip_esp.h>
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+#include <net/pfkeyv2.h>
+
+#ifdef ENCDEBUG
+#define DPRINTF(x) do { if (encdebug) printf x ; } while (0)
+#else
+#define DPRINTF(x)
+#endif
+
+#ifndef offsetof
+#define offsetof(s, e) ((int)&((s *)0)->e)
+#endif
+
+extern u_int8_t get_sa_require __P((struct inpcb *));
+
+#endif /* IPSEC */
+
+static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
+static void ip_mloopback
+ __P((struct ifnet *, struct mbuf *, struct sockaddr_in *));
+#if defined(IPFILTER) || defined(IPFILTER_LKM)
+int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+#endif
+
+#ifdef IPSEC
+extern int ipsec_auth_default_level;
+extern int ipsec_esp_trans_default_level;
+extern int ipsec_esp_network_default_level;
+
+extern int pfkeyv2_acquire(struct tdb *, int);
+#endif
+
+#ifndef RAMDOM_IP_ID
+u_short ip_id;
+#endif
+
+/*
+ * IP output. The packet in mbuf chain m contains a skeletal IP
+ * header (with len, off, ttl, proto, tos, src, dst).
+ * The mbuf chain containing the packet will be freed.
+ * The mbuf opt, if present, will not be freed.
+ */
+int
+#if __STDC__
+ip_output(struct mbuf *m0, ...)
+#else
+ip_output(m0, va_alist)
+ struct mbuf *m0;
+ va_dcl
+#endif
+{
+ register struct ip *ip, *mhip;
+ register struct ifnet *ifp;
+ register struct mbuf *m = m0;
+ register int hlen = sizeof (struct ip);
+ int len, off, error = 0;
+ struct route iproute;
+ struct sockaddr_in *dst;
+ struct in_ifaddr *ia;
+ struct mbuf *opt;
+ struct route *ro;
+ int flags;
+ struct ip_moptions *imo;
+ va_list ap;
+#ifdef IPSEC
+ union sockaddr_union sunion;
+ struct mbuf *mp;
+ struct udphdr *udp;
+ struct tcphdr *tcp;
+ struct inpcb *inp;
+
+ struct route_enc re0, *re = &re0;
+ struct sockaddr_encap *ddst, *gw;
+ u_int8_t sa_require, sa_have = 0;
+ struct tdb *tdb, *t;
+ int s, ip6flag;
+
+#ifdef INET6
+ struct ip6_hdr *ip6;
+#endif /* INET6 */
+#endif /* IPSEC */
+
+ va_start(ap, m0);
+ opt = va_arg(ap, struct mbuf *);
+ ro = va_arg(ap, struct route *);
+ flags = va_arg(ap, int);
+ imo = va_arg(ap, struct ip_moptions *);
+#ifdef IPSEC
+ inp = va_arg(ap, struct inpcb *);
+#endif /* IPSEC */
+ va_end(ap);
+
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("ip_output no HDR");
+#endif
+ if (opt) {
+ m = ip_insertoptions(m, opt, &len);
+ hlen = len;
+ }
+ ip = mtod(m, struct ip *);
+ /*
+ * Fill in IP header.
+ */
+ if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
+ ip->ip_v = IPVERSION;
+ ip->ip_off &= IP_DF;
+#ifdef RANDOM_IP_ID
+ ip->ip_id = ip_randomid();
+#else
+ ip->ip_id = htons(ip_id++);
+#endif
+ ip->ip_hl = hlen >> 2;
+ ipstat.ips_localout++;
+ } else {
+ hlen = ip->ip_hl << 2;
+ }
+
+ /*
+ * Route packet.
+ */
+ if (ro == 0) {
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof (*ro));
+ }
+ dst = satosin(&ro->ro_dst);
+ /*
+ * If there is a cached route,
+ * check that it is to the same destination
+ * and is still up. If not, free it and try again.
+ */
+ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
+ dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = (struct rtentry *)0;
+ }
+ if (ro->ro_rt == 0) {
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = ip->ip_dst;
+ }
+ /*
+ * If routing to interface only,
+ * short circuit routing lookup.
+ */
+ if (flags & IP_ROUTETOIF) {
+ if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
+ }
+ ifp = ia->ia_ifp;
+ ip->ip_ttl = 1;
+ } else {
+ if (ro->ro_rt == 0)
+ rtalloc(ro);
+ if (ro->ro_rt == 0) {
+ ipstat.ips_noroute++;
+ error = EHOSTUNREACH;
+ goto bad;
+ }
+ ia = ifatoia(ro->ro_rt->rt_ifa);
+ ifp = ro->ro_rt->rt_ifp;
+ ro->ro_rt->rt_use++;
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = satosin(ro->ro_rt->rt_gateway);
+ }
+ if (IN_MULTICAST(ip->ip_dst.s_addr)) {
+ struct in_multi *inm;
+
+ m->m_flags |= M_MCAST;
+ /*
+ * IP destination address is multicast. Make sure "dst"
+ * still points to the address in "ro". (It may have been
+ * changed to point to a gateway address, above.)
+ */
+ dst = satosin(&ro->ro_dst);
+ /*
+ * See if the caller provided any multicast options
+ */
+ if (imo != NULL) {
+ ip->ip_ttl = imo->imo_multicast_ttl;
+ if (imo->imo_multicast_ifp != NULL)
+ ifp = imo->imo_multicast_ifp;
+ } else
+ ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
+ /*
+ * Confirm that the outgoing interface supports multicast.
+ */
+ if ((ifp->if_flags & IFF_MULTICAST) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
+ }
+ /*
+ * If source address not specified yet, use address
+ * of outgoing interface.
+ */
+ if (ip->ip_src.s_addr == INADDR_ANY) {
+ register struct in_ifaddr *ia;
+
+ for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next)
+ if (ia->ia_ifp == ifp) {
+ ip->ip_src = ia->ia_addr.sin_addr;
+ break;
+ }
+ }
+
+ IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
+ if (inm != NULL &&
+ (imo == NULL || imo->imo_multicast_loop)) {
+ /*
+ * If we belong to the destination multicast group
+ * on the outgoing interface, and the caller did not
+ * forbid loopback, loop back a copy.
+ */
+ ip_mloopback(ifp, m, dst);
+ }
+#ifdef MROUTING
+ else {
+ /*
+ * If we are acting as a multicast router, perform
+ * multicast forwarding as if the packet had just
+ * arrived on the interface to which we are about
+ * to send. The multicast forwarding function
+ * recursively calls this function, using the
+ * IP_FORWARDING flag to prevent infinite recursion.
+ *
+ * Multicasts that are looped back by ip_mloopback(),
+ * above, will be forwarded by the ip_input() routine,
+ * if necessary.
+ */
+ extern struct socket *ip_mrouter;
+
+ if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
+ if (ip_mforward(m, ifp) != 0) {
+ m_freem(m);
+ goto done;
+ }
+ }
+ }
+#endif
+ /*
+ * Multicasts with a time-to-live of zero may be looped-
+ * back, above, but must not be transmitted on a network.
+ * Also, multicasts addressed to the loopback interface
+ * are not sent -- the above call to ip_mloopback() will
+ * loop back a copy if this host actually belongs to the
+ * destination group on the loopback interface.
+ */
+ if (ip->ip_ttl == 0 || (ifp->if_flags & IFF_LOOPBACK) != 0) {
+ m_freem(m);
+ goto done;
+ }
+
+ goto sendit;
+ }
+#ifndef notdef
+ /*
+ * If source address not specified yet, use address
+ * of outgoing interface.
+ */
+ if (ip->ip_src.s_addr == INADDR_ANY)
+ ip->ip_src = ia->ia_addr.sin_addr;
+#endif
+ /*
+ * Look for broadcast address and
+ * and verify user is allowed to send
+ * such a packet.
+ */
+ if (in_broadcast(dst->sin_addr, ifp)) {
+ if ((ifp->if_flags & IFF_BROADCAST) == 0) {
+ error = EADDRNOTAVAIL;
+ goto bad;
+ }
+ if ((flags & IP_ALLOWBROADCAST) == 0) {
+ error = EACCES;
+ goto bad;
+ }
+ /* don't allow broadcast messages to be fragmented */
+ if ((u_int16_t)ip->ip_len > ifp->if_mtu) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+ m->m_flags |= M_BCAST;
+ } else
+ m->m_flags &= ~M_BCAST;
+
+sendit:
+#ifdef IPSEC
+ /*
+ * Check if the packet needs encapsulation.
+ */
+ if (!(flags & IP_ENCAPSULATED) &&
+ (inp == NULL ||
+ inp->inp_seclevel[SL_AUTH] != IPSEC_LEVEL_BYPASS ||
+ inp->inp_seclevel[SL_ESP_TRANS] != IPSEC_LEVEL_BYPASS ||
+ inp->inp_seclevel[SL_ESP_NETWORK] != IPSEC_LEVEL_BYPASS)) {
+ if (inp == NULL)
+ sa_require = get_sa_require(inp);
+ else
+ sa_require = inp->inp_secrequire;
+
+ bzero((caddr_t) re, sizeof(*re));
+
+ /*
+ * splnet is chosen over spltdb because we are not allowed to
+ * lower the level, and udp_output calls us in splnet().
+ */
+ s = splnet();
+
+ /*
+ * Check if there was an outgoing SA bound to the flow
+ * from a transport protocol.
+ */
+ if (inp && inp->inp_tdb &&
+ (inp->inp_tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY ||
+ !bcmp(&inp->inp_tdb->tdb_dst.sin.sin_addr,
+ &ip->ip_dst, sizeof(ip->ip_dst)))) {
+ tdb = inp->inp_tdb;
+ goto have_tdb;
+ }
+
+ if (!ipsec_in_use) {
+ splx(s);
+ goto no_encap;
+ }
+
+ ddst = (struct sockaddr_encap *) &re->re_dst;
+ ddst->sen_family = PF_KEY;
+ ddst->sen_len = SENT_IP4_LEN;
+ ddst->sen_type = SENT_IP4;
+ ddst->sen_ip_src = ip->ip_src;
+ ddst->sen_ip_dst = ip->ip_dst;
+ ddst->sen_proto = ip->ip_p;
+
+ switch (ip->ip_p) {
+ case IPPROTO_UDP:
+ if (m->m_len < hlen + 2 * sizeof(u_int16_t)) {
+ if ((m = m_pullup(m, hlen + 2 *
+ sizeof(u_int16_t))) == 0)
+ return ENOBUFS;
+ ip = mtod(m, struct ip *);
+ }
+ udp = (struct udphdr *) (mtod(m, u_char *) + hlen);
+ ddst->sen_sport = ntohs(udp->uh_sport);
+ ddst->sen_dport = ntohs(udp->uh_dport);
+ break;
+
+ case IPPROTO_TCP:
+ if (m->m_len < hlen + 2 * sizeof(u_int16_t)) {
+ if ((m = m_pullup(m, hlen + 2 *
+ sizeof(u_int16_t))) == 0)
+ return ENOBUFS;
+ ip = mtod(m, struct ip *);
+ }
+ tcp = (struct tcphdr *) (mtod(m, u_char *) + hlen);
+ ddst->sen_sport = ntohs(tcp->th_sport);
+ ddst->sen_dport = ntohs(tcp->th_dport);
+ break;
+
+ default:
+ ddst->sen_sport = 0;
+ ddst->sen_dport = 0;
+ }
+
+ rtalloc((struct route *) re);
+ if (re->re_rt == NULL) {
+ splx(s);
+ goto no_encap;
+ }
+
+ gw = (struct sockaddr_encap *) (re->re_rt->rt_gateway);
+
+ /* Sanity check */
+ if (gw == NULL || ((gw->sen_type != SENT_IPSP) &&
+ (gw->sen_type != SENT_IPSP6))) {
+ splx(s);
+ DPRINTF(("ip_output(): no gw or gw data not IPSP\n"));
+
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ error = EHOSTUNREACH;
+ m_freem(m);
+ goto done;
+ }
+
+ /*
+ * There might be a specific route, that tells us to avoid
+ * doing IPsec; this is useful for specific routes that we
+ * don't want to have IPsec applied on, like the key
+ * management ports.
+ */
+
+ if ((gw != NULL) && (gw->sen_ipsp_sproto == 0) &&
+ (gw->sen_ipsp_spi == 0)) {
+ if ((gw->sen_family == AF_INET) &&
+ (gw->sen_ipsp_dst.s_addr == 0)) {
+ splx(s);
+ goto no_encap;
+ }
+
+#ifdef INET6
+ if ((gw->sen_family == AF_INET6) &&
+ IN6_IS_ADDR_UNSPECIFIED(&gw->sen_ipsp6_dst)) {
+ splx(s);
+ goto no_encap;
+ }
+#endif /* INET6 */
+ }
+
+ /*
+ * At this point we have an IPSP "gateway" (tunnel) spec.
+ * Use the destination of the tunnel and the SPI to
+ * look up the necessary Tunnel Control Block. Look it up,
+ * and then pass it, along with the packet and the gw,
+ * to the appropriate transformation.
+ */
+ bzero(&sunion, sizeof(sunion));
+
+ if (gw->sen_type == SENT_IPSP) {
+ sunion.sin.sin_family = AF_INET;
+ sunion.sin.sin_len = sizeof(struct sockaddr_in);
+ sunion.sin.sin_addr = gw->sen_ipsp_dst;
+ }
+#ifdef INET6
+ if (gw->sen_type == SENT_IPSP6) {
+ sunion.sin6.sin6_family = AF_INET6;
+ sunion.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sunion.sin6.sin6_addr = gw->sen_ipsp6_dst;
+ }
+#endif /* INET6 */
+
+ tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, &sunion,
+ gw->sen_ipsp_sproto);
+
+ /*
+ * For VPNs a route with a reserved SPI is used to
+ * indicate the need for an SA when none is established.
+ */
+ if (((ntohl(gw->sen_ipsp_spi) == SPI_LOCAL_USE) &&
+ (gw->sen_type == SENT_IPSP)) ||
+ ((ntohl(gw->sen_ipsp6_spi) == SPI_LOCAL_USE) &&
+ (gw->sen_type == SENT_IPSP6))) {
+ if (tdb == NULL) {
+ /*
+ * XXX We should construct a TDB from system
+ * default (which should be tunable via sysctl).
+ * For now, drop packet and ignore SPD entry.
+ */
+ splx(s);
+ goto no_encap;
+ }
+ else {
+ if (tdb->tdb_authalgxform)
+ sa_require = NOTIFY_SATYPE_AUTH;
+ if (tdb->tdb_encalgxform)
+ sa_require |= NOTIFY_SATYPE_CONF;
+ if (tdb->tdb_flags & TDBF_TUNNELING)
+ sa_require |= NOTIFY_SATYPE_TUNNEL;
+ }
+
+ /* PF_KEYv2 notification message */
+ if (tdb && tdb->tdb_satype != SADB_X_SATYPE_BYPASS)
+ if ((error = pfkeyv2_acquire(tdb, 0)) != 0)
+ return error;
+
+ splx(s);
+
+ /*
+ * When sa_require is set, the packet will be dropped
+ * at no_encap.
+ */
+ goto no_encap;
+ }
+
+ have_tdb:
+
+ ip->ip_len = htons((u_short) ip->ip_len);
+ ip->ip_off = htons((u_short) ip->ip_off);
+ ip->ip_sum = 0;
+
+ /*
+ * Now we check if this tdb has all the transforms which
+ * are requried by the socket or our default policy.
+ */
+ SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb);
+
+ if (sa_require & ~sa_have)
+ goto no_encap;
+
+ if (tdb == NULL) {
+ splx(s);
+ if (gw->sen_type == SENT_IPSP)
+ DPRINTF(("ip_output(): non-existant TDB for SA %s/%08x/%u\n", inet_ntoa4(gw->sen_ipsp_dst), ntohl(gw->sen_ipsp_spi), gw->sen_ipsp_sproto));
+#ifdef INET6
+ else
+ DPRINTF(("ip_output(): non-existant TDB for SA %s/%08x/%u\n", inet6_ntoa4(gw->sen_ipsp6_dst), ntohl(gw->sen_ipsp6_spi), gw->sen_ipsp6_sproto));
+#endif /* INET6 */
+
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ error = EHOSTUNREACH;
+ m_freem(m);
+ goto done;
+ }
+
+ for (t = tdb; t != NULL; t = t->tdb_onext)
+ if ((t->tdb_sproto == IPPROTO_ESP && !esp_enable) ||
+ (t->tdb_sproto == IPPROTO_AH && !ah_enable)) {
+ DPRINTF(("ip_output(): IPSec outbound packet dropped due to policy\n"));
+
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ error = EHOSTUNREACH;
+ m_freem(m);
+ goto done;
+ }
+
+ while (tdb && tdb->tdb_xform) {
+ /* Check if the SPI is invalid */
+ if (tdb->tdb_flags & TDBF_INVALID) {
+ splx(s);
+ DPRINTF(("ip_output(): attempt to use invalid SA %s/%08x/%u\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi), tdb->tdb_sproto));
+ m_freem(m);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ return ENXIO;
+ }
+
+#ifndef INET6
+ /* Sanity check */
+ if (tdb->tdb_dst.sa.sa_family != AF_INET) {
+ splx(s);
+ DPRINTF(("ip_output(): attempt to use SA %s/%08x/%u for protocol family %d\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi), tdb->tdb_sproto, tdb->tdb_dst.sa.sa_family));
+ m_freem(m);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ return ENXIO;
+ }
+#endif /* INET6 */
+
+ /* Register first use, setup expiration timer */
+ if (tdb->tdb_first_use == 0) {
+ tdb->tdb_first_use = time.tv_sec;
+ tdb_expiration(tdb, TDBEXP_TIMEOUT);
+ }
+
+ /* Check for tunneling */
+ if (((tdb->tdb_dst.sa.sa_family == AF_INET) &&
+ (tdb->tdb_dst.sin.sin_addr.s_addr !=
+ INADDR_ANY) &&
+ (tdb->tdb_dst.sin.sin_addr.s_addr !=
+ ip->ip_dst.s_addr)) ||
+ (tdb->tdb_dst.sa.sa_family == AF_INET6) ||
+ ((tdb->tdb_flags & TDBF_TUNNELING) &&
+ (tdb->tdb_xform->xf_type != XF_IP4))) {
+ /* Fix length and checksum */
+ ip->ip_len = htons(m->m_pkthdr.len);
+ ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+ error = ipe4_output(m, tdb, &mp,
+ ip->ip_hl << 2,
+ offsetof(struct ip, ip_p));
+ if (mp == NULL)
+ error = EFAULT;
+ if (error) {
+ splx(s);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ return error;
+ }
+ if (tdb->tdb_dst.sa.sa_family == AF_INET)
+ ip6flag = 0;
+#ifdef INET6
+ if (tdb->tdb_dst.sa.sa_family == AF_INET6)
+ ip6flag = 1;
+#endif /* INET6 */
+ m = mp;
+ mp = NULL;
+ }
+
+ if ((tdb->tdb_xform->xf_type == XF_IP4) &&
+ (tdb->tdb_dst.sa.sa_family == AF_INET)) {
+ ip = mtod(m, struct ip *);
+ ip->ip_len = htons(m->m_pkthdr.len);
+ ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+ }
+
+#ifdef INET6
+ if ((tdb->tdb_xform->xf_type == XF_IP4) &&
+ (tdb->tdb_dst.sa.sa_family == AF_INET6)) {
+ ip6 = mtod(m, struct ip6_hdr *);
+ ip6->ip6_plen = htons(m->m_pkthdr.len);
+ }
+#endif /* INET6 */
+
+#ifdef INET6
+ /*
+ * This assumes that there is only just an IPv6
+ * header prepended.
+ */
+ if (ip6flag)
+ error = (*(tdb->tdb_xform->xf_output))(m, tdb, &mp, sizeof(struct ip6_hdr), offsetof(struct ip6_hdr, ip6_nxt));
+#endif /* INET6 */
+
+ if (!ip6flag)
+ error = (*(tdb->tdb_xform->xf_output))(m, tdb, &mp, ip->ip_hl << 2, offsetof(struct ip, ip_p));
+ if (!error && mp == NULL)
+ error = EFAULT;
+ if (error) {
+ splx(s);
+ if (mp != NULL)
+ m_freem(mp);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ return error;
+ }
+
+ m = mp;
+ mp = NULL;
+
+ if (!ip6flag) {
+ ip = mtod(m, struct ip *);
+ ip->ip_len = htons(m->m_pkthdr.len);
+ }
+
+#ifdef INET6
+ if (ip6flag) {
+ ip6 = mtod(m, struct ip6_hdr *);
+ ip6->ip6_plen = htons(m->m_pkthdr.len);
+ }
+#endif /* INET6 */
+ tdb = tdb->tdb_onext;
+ }
+ splx(s);
+
+ if (!ip6flag)
+ ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+
+ /*
+ * At this point, m is pointing to an mbuf chain with the
+ * processed packet. Call ourselves recursively, but
+ * bypass the encap code.
+ */
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+
+ if (!ip6flag) {
+ ip = mtod(m, struct ip *);
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+
+ return ip_output(m, NULL, NULL,
+ IP_ENCAPSULATED | IP_RAWOUTPUT,
+ NULL, NULL);
+ }
+
+#ifdef INET6
+ if (ip6flag) {
+ ip6 = mtod(m, struct ip6_hdr *);
+ NTOHS(ip6->ip6_plen);
+
+ /* Naturally, ip6_output() has to honor those two flags */
+ return ip6_output(m, NULL, NULL,
+ IP_ENCAPSULATED | IP_RAWOUTPUT,
+ NULL, NULL);
+ }
+#endif /* INET6 */
+
+no_encap:
+ /* This is for possible future use, don't move or delete */
+ if (re->re_rt)
+ RTFREE(re->re_rt);
+ /* No IPSec processing though it was required, drop packet */
+ if (sa_require) {
+ error = EHOSTUNREACH;
+ m_freem(m);
+ goto done;
+ }
+ }
+#endif /* IPSEC */
+
+#if defined(IPFILTER) || defined(IPFILTER_LKM)
+ /*
+ * looks like most checking has been done now...do a filter check
+ */
+ {
+ struct mbuf *m0 = m;
+ if (fr_checkp && (*fr_checkp)(ip, hlen, ifp, 1, &m0)) {
+ error = EHOSTUNREACH;
+ goto done;
+ } else
+ ip = mtod(m = m0, struct ip *);
+ }
+#endif
+ /*
+ * If small enough for interface, can just send directly.
+ */
+ if ((u_int16_t)ip->ip_len <= ifp->if_mtu) {
+ ip->ip_len = htons((u_int16_t)ip->ip_len);
+ ip->ip_off = htons((u_int16_t)ip->ip_off);
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m, hlen);
+ error = (*ifp->if_output)(ifp, m, sintosa(dst), ro->ro_rt);
+ goto done;
+ }
+
+ /*
+ * Too large for interface; fragment if possible.
+ * Must be able to put at least 8 bytes per fragment.
+ */
+#if 0
+ /*
+ * If IPsec packet is too big for the interface, try fragment it.
+ * XXX This really is a quickhack. May be inappropriate.
+ * XXX fails if somebody is sending AH'ed packet, with:
+ * sizeof(packet without AH) < mtu < sizeof(packet with AH)
+ */
+ if (sab && ip->ip_p != IPPROTO_AH && (flags & IP_FORWARDING) == 0)
+ ip->ip_off &= ~IP_DF;
+#endif /*IPSEC*/
+ if (ip->ip_off & IP_DF) {
+ error = EMSGSIZE;
+ ipstat.ips_cantfrag++;
+ goto bad;
+ }
+ len = (ifp->if_mtu - hlen) &~ 7;
+ if (len < 8) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+
+ {
+ int mhlen, firstlen = len;
+ struct mbuf **mnext = &m->m_nextpkt;
+
+ /*
+ * Loop through length of segment after first fragment,
+ * make new header and copy data of each part and link onto chain.
+ */
+ m0 = m;
+ mhlen = sizeof (struct ip);
+ for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m == 0) {
+ error = ENOBUFS;
+ ipstat.ips_odropped++;
+ goto sendorfree;
+ }
+ *mnext = m;
+ mnext = &m->m_nextpkt;
+ m->m_data += max_linkhdr;
+ mhip = mtod(m, struct ip *);
+ *mhip = *ip;
+ if (hlen > sizeof (struct ip)) {
+ mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
+ mhip->ip_hl = mhlen >> 2;
+ }
+ m->m_len = mhlen;
+ mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
+ if (ip->ip_off & IP_MF)
+ mhip->ip_off |= IP_MF;
+ if (off + len >= (u_int16_t)ip->ip_len)
+ len = (u_int16_t)ip->ip_len - off;
+ else
+ mhip->ip_off |= IP_MF;
+ mhip->ip_len = htons((u_int16_t)(len + mhlen));
+ m->m_next = m_copy(m0, off, len);
+ if (m->m_next == 0) {
+ error = ENOBUFS; /* ??? */
+ ipstat.ips_odropped++;
+ goto sendorfree;
+ }
+ m->m_pkthdr.len = mhlen + len;
+ m->m_pkthdr.rcvif = (struct ifnet *)0;
+ mhip->ip_off = htons((u_int16_t)mhip->ip_off);
+ mhip->ip_sum = 0;
+ mhip->ip_sum = in_cksum(m, mhlen);
+ ipstat.ips_ofragments++;
+ }
+ /*
+ * Update first fragment by trimming what's been copied out
+ * and updating header, then send each fragment (in order).
+ */
+ m = m0;
+ m_adj(m, hlen + firstlen - (u_int16_t)ip->ip_len);
+ m->m_pkthdr.len = hlen + firstlen;
+ ip->ip_len = htons((u_int16_t)m->m_pkthdr.len);
+ ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m, hlen);
+sendorfree:
+ for (m = m0; m; m = m0) {
+ m0 = m->m_nextpkt;
+ m->m_nextpkt = 0;
+ if (error == 0)
+ error = (*ifp->if_output)(ifp, m, sintosa(dst),
+ ro->ro_rt);
+ else
+ m_freem(m);
+ }
+
+ if (error == 0)
+ ipstat.ips_fragmented++;
+ }
+done:
+ if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt)
+ RTFREE(ro->ro_rt);
+ return (error);
+bad:
+ m_freem(m0);
+ goto done;
+}
+
+/*
+ * Insert IP options into preformed packet.
+ * Adjust IP destination as required for IP source routing,
+ * as indicated by a non-zero in_addr at the start of the options.
+ */
+static struct mbuf *
+ip_insertoptions(m, opt, phlen)
+ register struct mbuf *m;
+ struct mbuf *opt;
+ int *phlen;
+{
+ register struct ipoption *p = mtod(opt, struct ipoption *);
+ struct mbuf *n;
+ register struct ip *ip = mtod(m, struct ip *);
+ unsigned optlen;
+
+ optlen = opt->m_len - sizeof(p->ipopt_dst);
+ if (optlen + (u_int16_t)ip->ip_len > IP_MAXPACKET)
+ return (m); /* XXX should fail */
+ if (p->ipopt_dst.s_addr)
+ ip->ip_dst = p->ipopt_dst;
+ if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
+ MGETHDR(n, M_DONTWAIT, MT_HEADER);
+ if (n == 0)
+ return (m);
+ n->m_pkthdr.len = m->m_pkthdr.len + optlen;
+ m->m_len -= sizeof(struct ip);
+ m->m_data += sizeof(struct ip);
+ n->m_next = m;
+ m = n;
+ m->m_len = optlen + sizeof(struct ip);
+ m->m_data += max_linkhdr;
+ bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
+ } else {
+ m->m_data -= optlen;
+ m->m_len += optlen;
+ m->m_pkthdr.len += optlen;
+ ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
+ }
+ ip = mtod(m, struct ip *);
+ bcopy((caddr_t)p->ipopt_list, (caddr_t)(ip + 1), (unsigned)optlen);
+ *phlen = sizeof(struct ip) + optlen;
+ ip->ip_len += optlen;
+ return (m);
+}
+
+/*
+ * Copy options from ip to jp,
+ * omitting those not copied during fragmentation.
+ */
+int
+ip_optcopy(ip, jp)
+ struct ip *ip, *jp;
+{
+ register u_char *cp, *dp;
+ int opt, optlen, cnt;
+
+ cp = (u_char *)(ip + 1);
+ dp = (u_char *)(jp + 1);
+ cnt = (ip->ip_hl << 2) - sizeof (struct ip);
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[0];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP) {
+ /* Preserve for IP mcast tunnel's LSRR alignment. */
+ *dp++ = IPOPT_NOP;
+ optlen = 1;
+ continue;
+ } else
+ optlen = cp[IPOPT_OLEN];
+ /* bogus lengths should have been caught by ip_dooptions */
+ if (optlen > cnt)
+ optlen = cnt;
+ if (IPOPT_COPIED(opt)) {
+ bcopy((caddr_t)cp, (caddr_t)dp, (unsigned)optlen);
+ dp += optlen;
+ }
+ }
+ for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
+ *dp++ = IPOPT_EOL;
+ return (optlen);
+}
+
+/*
+ * IP socket option processing.
+ */
+int
+ip_ctloutput(op, so, level, optname, mp)
+ int op;
+ struct socket *so;
+ int level, optname;
+ struct mbuf **mp;
+{
+ register struct inpcb *inp = sotoinpcb(so);
+ register struct mbuf *m = *mp;
+ register int optval = 0;
+#ifdef IPSEC
+ struct proc *p = curproc; /* XXX */
+ struct tdb *tdb;
+ struct tdb_ident *tdbip, tdbi;
+ int s;
+#endif
+ int error = 0;
+
+ if (level != IPPROTO_IP) {
+ error = EINVAL;
+ if (op == PRCO_SETOPT && *mp)
+ (void) m_free(*mp);
+ } else switch (op) {
+
+ case PRCO_SETOPT:
+ switch (optname) {
+ case IP_OPTIONS:
+#ifdef notyet
+ case IP_RETOPTS:
+ return (ip_pcbopts(optname, &inp->inp_options, m));
+#else
+ return (ip_pcbopts(&inp->inp_options, m));
+#endif
+
+ case IP_TOS:
+ case IP_TTL:
+ case IP_RECVOPTS:
+ case IP_RECVRETOPTS:
+ case IP_RECVDSTADDR:
+ if (m == NULL || m->m_len != sizeof(int))
+ error = EINVAL;
+ else {
+ optval = *mtod(m, int *);
+ switch (optname) {
+
+ case IP_TOS:
+ inp->inp_ip.ip_tos = optval;
+ break;
+
+ case IP_TTL:
+ inp->inp_ip.ip_ttl = optval;
+ break;
+#define OPTSET(bit) \
+ if (optval) \
+ inp->inp_flags |= bit; \
+ else \
+ inp->inp_flags &= ~bit;
+
+ case IP_RECVOPTS:
+ OPTSET(INP_RECVOPTS);
+ break;
+
+ case IP_RECVRETOPTS:
+ OPTSET(INP_RECVRETOPTS);
+ break;
+
+ case IP_RECVDSTADDR:
+ OPTSET(INP_RECVDSTADDR);
+ break;
+ }
+ }
+ break;
+#undef OPTSET
+
+ case IP_MULTICAST_IF:
+ case IP_MULTICAST_TTL:
+ case IP_MULTICAST_LOOP:
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ error = ip_setmoptions(optname, &inp->inp_moptions, m);
+ break;
+
+ case IP_PORTRANGE:
+ if (m == 0 || m->m_len != sizeof(int))
+ error = EINVAL;
+ else {
+ optval = *mtod(m, int *);
+
+ switch (optval) {
+
+ case IP_PORTRANGE_DEFAULT:
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ break;
+
+ case IP_PORTRANGE_HIGH:
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags |= INP_HIGHPORT;
+ break;
+
+ case IP_PORTRANGE_LOW:
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ inp->inp_flags |= INP_LOWPORT;
+ break;
+
+ default:
+
+ error = EINVAL;
+ break;
+ }
+ }
+ break;
+ case IPSEC_OUTSA:
+#ifndef IPSEC
+ error = EINVAL;
+#else
+ s = spltdb();
+ if (m == 0 || m->m_len != sizeof(struct tdb_ident)) {
+ error = EINVAL;
+ } else {
+ tdbip = mtod(m, struct tdb_ident *);
+ tdb = gettdb(tdbip->spi, &tdbip->dst,
+ tdbip->proto);
+ if (tdb == NULL)
+ error = ESRCH;
+ else
+ tdb_add_inp(tdb, inp);
+ }
+ splx(s);
+#endif /* IPSEC */
+ break;
+
+ case IP_AUTH_LEVEL:
+ case IP_ESP_TRANS_LEVEL:
+ case IP_ESP_NETWORK_LEVEL:
+#ifndef IPSEC
+ error = EINVAL;
+#else
+ if (m == 0 || m->m_len != sizeof(int)) {
+ error = EINVAL;
+ break;
+ }
+ optval = *mtod(m, u_char *);
+
+ if (optval < IPSEC_LEVEL_BYPASS ||
+ optval > IPSEC_LEVEL_UNIQUE) {
+ error = EINVAL;
+ break;
+ }
+
+ switch (optname) {
+ case IP_AUTH_LEVEL:
+ if (optval < ipsec_auth_default_level &&
+ suser(p->p_ucred, &p->p_acflag)) {
+ error = EACCES;
+ break;
+ }
+ inp->inp_seclevel[SL_AUTH] = optval;
+ break;
+
+ case IP_ESP_TRANS_LEVEL:
+ if (optval < ipsec_esp_trans_default_level &&
+ suser(p->p_ucred, &p->p_acflag)) {
+ error = EACCES;
+ break;
+ }
+ inp->inp_seclevel[SL_ESP_TRANS] = optval;
+ break;
+
+ case IP_ESP_NETWORK_LEVEL:
+ if (optval < ipsec_esp_network_default_level &&
+ suser(p->p_ucred, &p->p_acflag)) {
+ error = EACCES;
+ break;
+ }
+ inp->inp_seclevel[SL_ESP_NETWORK] = optval;
+ break;
+ }
+ if (!error)
+ inp->inp_secrequire = get_sa_require(inp);
+#endif
+ break;
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ if (m)
+ (void)m_free(m);
+ break;
+
+ case PRCO_GETOPT:
+ switch (optname) {
+ case IP_OPTIONS:
+ case IP_RETOPTS:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ if (inp->inp_options) {
+ m->m_len = inp->inp_options->m_len;
+ bcopy(mtod(inp->inp_options, caddr_t),
+ mtod(m, caddr_t), (unsigned)m->m_len);
+ } else
+ m->m_len = 0;
+ break;
+
+ case IP_TOS:
+ case IP_TTL:
+ case IP_RECVOPTS:
+ case IP_RECVRETOPTS:
+ case IP_RECVDSTADDR:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+ switch (optname) {
+
+ case IP_TOS:
+ optval = inp->inp_ip.ip_tos;
+ break;
+
+ case IP_TTL:
+ optval = inp->inp_ip.ip_ttl;
+ break;
+
+#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
+
+ case IP_RECVOPTS:
+ optval = OPTBIT(INP_RECVOPTS);
+ break;
+
+ case IP_RECVRETOPTS:
+ optval = OPTBIT(INP_RECVRETOPTS);
+ break;
+
+ case IP_RECVDSTADDR:
+ optval = OPTBIT(INP_RECVDSTADDR);
+ break;
+ }
+ *mtod(m, int *) = optval;
+ break;
+
+ case IP_MULTICAST_IF:
+ case IP_MULTICAST_TTL:
+ case IP_MULTICAST_LOOP:
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ error = ip_getmoptions(optname, inp->inp_moptions, mp);
+ break;
+
+ case IP_PORTRANGE:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+
+ if (inp->inp_flags & INP_HIGHPORT)
+ optval = IP_PORTRANGE_HIGH;
+ else if (inp->inp_flags & INP_LOWPORT)
+ optval = IP_PORTRANGE_LOW;
+ else
+ optval = 0;
+
+ *mtod(m, int *) = optval;
+ break;
+
+ case IPSEC_OUTSA:
+#ifndef IPSEC
+ error = EINVAL;
+#else
+ s = spltdb();
+ if (inp->inp_tdb == NULL) {
+ error = ENOENT;
+ } else {
+ tdbi.spi = inp->inp_tdb->tdb_spi;
+ tdbi.dst = inp->inp_tdb->tdb_dst;
+ tdbi.proto = inp->inp_tdb->tdb_sproto;
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(tdbi);
+ bcopy((caddr_t)&tdbi, mtod(m, caddr_t),
+ (unsigned)m->m_len);
+ }
+ splx(s);
+#endif /* IPSEC */
+ break;
+
+ case IP_AUTH_LEVEL:
+ case IP_ESP_TRANS_LEVEL:
+ case IP_ESP_NETWORK_LEVEL:
+#ifndef IPSEC
+ *mtod(m, int *) = IPSEC_LEVEL_NONE;
+#else
+ switch (optname) {
+ case IP_AUTH_LEVEL:
+ optval = inp->inp_seclevel[SL_AUTH];
+ break;
+
+ case IP_ESP_TRANS_LEVEL:
+ optval = inp->inp_seclevel[SL_ESP_TRANS];
+ break;
+
+ case IP_ESP_NETWORK_LEVEL:
+ optval = inp->inp_seclevel[SL_ESP_NETWORK];
+ break;
+ }
+ *mtod(m, int *) = optval;
+#endif
+ break;
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ break;
+ }
+ return (error);
+}
+
+/*
+ * Set up IP options in pcb for insertion in output packets.
+ * Store in mbuf with pointer in pcbopt, adding pseudo-option
+ * with destination address if source routed.
+ */
+int
+#ifdef notyet
+ip_pcbopts(optname, pcbopt, m)
+ int optname;
+#else
+ip_pcbopts(pcbopt, m)
+#endif
+ struct mbuf **pcbopt;
+ register struct mbuf *m;
+{
+ register int cnt, optlen;
+ register u_char *cp;
+ u_char opt;
+
+ /* turn off any old options */
+ if (*pcbopt)
+ (void)m_free(*pcbopt);
+ *pcbopt = 0;
+ if (m == (struct mbuf *)0 || m->m_len == 0) {
+ /*
+ * Only turning off any previous options.
+ */
+ if (m)
+ (void)m_free(m);
+ return (0);
+ }
+
+#ifndef vax
+ if (m->m_len % sizeof(int32_t))
+ goto bad;
+#endif
+ /*
+ * IP first-hop destination address will be stored before
+ * actual options; move other options back
+ * and clear it when none present.
+ */
+ if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
+ goto bad;
+ cnt = m->m_len;
+ m->m_len += sizeof(struct in_addr);
+ cp = mtod(m, u_char *) + sizeof(struct in_addr);
+ ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);
+ bzero(mtod(m, caddr_t), sizeof(struct in_addr));
+
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[IPOPT_OLEN];
+ if (optlen <= IPOPT_OLEN || optlen > cnt)
+ goto bad;
+ }
+ switch (opt) {
+
+ default:
+ break;
+
+ case IPOPT_LSRR:
+ case IPOPT_SSRR:
+ /*
+ * user process specifies route as:
+ * ->A->B->C->D
+ * D must be our final destination (but we can't
+ * check that since we may not have connected yet).
+ * A is first hop destination, which doesn't appear in
+ * actual IP option, but is stored before the options.
+ */
+ if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
+ goto bad;
+ m->m_len -= sizeof(struct in_addr);
+ cnt -= sizeof(struct in_addr);
+ optlen -= sizeof(struct in_addr);
+ cp[IPOPT_OLEN] = optlen;
+ /*
+ * Move first hop before start of options.
+ */
+ bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
+ sizeof(struct in_addr));
+ /*
+ * Then copy rest of options back
+ * to close up the deleted entry.
+ */
+ ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +
+ sizeof(struct in_addr)),
+ (caddr_t)&cp[IPOPT_OFFSET+1],
+ (unsigned)cnt + sizeof(struct in_addr));
+ break;
+ }
+ }
+ if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
+ goto bad;
+ *pcbopt = m;
+ return (0);
+
+bad:
+ (void)m_free(m);
+ return (EINVAL);
+}
+
+/*
+ * Set the IP multicast options in response to user setsockopt().
+ */
+int
+ip_setmoptions(optname, imop, m)
+ int optname;
+ struct ip_moptions **imop;
+ struct mbuf *m;
+{
+ register int error = 0;
+ u_char loop;
+ register int i;
+ struct in_addr addr;
+ register struct ip_mreq *mreq;
+ register struct ifnet *ifp;
+ register struct ip_moptions *imo = *imop;
+ struct route ro;
+ register struct sockaddr_in *dst;
+
+ if (imo == NULL) {
+ /*
+ * No multicast option buffer attached to the pcb;
+ * allocate one and initialize to default values.
+ */
+ imo = (struct ip_moptions *)malloc(sizeof(*imo), M_IPMOPTS,
+ M_WAITOK);
+
+ if (imo == NULL)
+ return (ENOBUFS);
+ *imop = imo;
+ imo->imo_multicast_ifp = NULL;
+ imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
+ imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
+ imo->imo_num_memberships = 0;
+ }
+
+ switch (optname) {
+
+ case IP_MULTICAST_IF:
+ /*
+ * Select the interface for outgoing multicast packets.
+ */
+ if (m == NULL || m->m_len != sizeof(struct in_addr)) {
+ error = EINVAL;
+ break;
+ }
+ addr = *(mtod(m, struct in_addr *));
+ /*
+ * INADDR_ANY is used to remove a previous selection.
+ * When no interface is selected, a default one is
+ * chosen every time a multicast packet is sent.
+ */
+ if (addr.s_addr == INADDR_ANY) {
+ imo->imo_multicast_ifp = NULL;
+ break;
+ }
+ /*
+ * The selected interface is identified by its local
+ * IP address. Find the interface and confirm that
+ * it supports multicasting.
+ */
+ INADDR_TO_IFP(addr, ifp);
+ if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ imo->imo_multicast_ifp = ifp;
+ break;
+
+ case IP_MULTICAST_TTL:
+ /*
+ * Set the IP time-to-live for outgoing multicast packets.
+ */
+ if (m == NULL || m->m_len != 1) {
+ error = EINVAL;
+ break;
+ }
+ imo->imo_multicast_ttl = *(mtod(m, u_char *));
+ break;
+
+ case IP_MULTICAST_LOOP:
+ /*
+ * Set the loopback flag for outgoing multicast packets.
+ * Must be zero or one.
+ */
+ if (m == NULL || m->m_len != 1 ||
+ (loop = *(mtod(m, u_char *))) > 1) {
+ error = EINVAL;
+ break;
+ }
+ imo->imo_multicast_loop = loop;
+ break;
+
+ case IP_ADD_MEMBERSHIP:
+ /*
+ * Add a multicast group membership.
+ * Group must be a valid IP multicast address.
+ */
+ if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
+ error = EINVAL;
+ break;
+ }
+ mreq = mtod(m, struct ip_mreq *);
+ if (!IN_MULTICAST(mreq->imr_multiaddr.s_addr)) {
+ error = EINVAL;
+ break;
+ }
+ /*
+ * If no interface address was provided, use the interface of
+ * the route to the given multicast address.
+ */
+ if (mreq->imr_interface.s_addr == INADDR_ANY) {
+ ro.ro_rt = NULL;
+ dst = satosin(&ro.ro_dst);
+ dst->sin_len = sizeof(*dst);
+ dst->sin_family = AF_INET;
+ dst->sin_addr = mreq->imr_multiaddr;
+ rtalloc(&ro);
+ if (ro.ro_rt == NULL) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ ifp = ro.ro_rt->rt_ifp;
+ rtfree(ro.ro_rt);
+ } else {
+ INADDR_TO_IFP(mreq->imr_interface, ifp);
+ }
+ /*
+ * See if we found an interface, and confirm that it
+ * supports multicast.
+ */
+ if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ /*
+ * See if the membership already exists or if all the
+ * membership slots are full.
+ */
+ for (i = 0; i < imo->imo_num_memberships; ++i) {
+ if (imo->imo_membership[i]->inm_ifp == ifp &&
+ imo->imo_membership[i]->inm_addr.s_addr
+ == mreq->imr_multiaddr.s_addr)
+ break;
+ }
+ if (i < imo->imo_num_memberships) {
+ error = EADDRINUSE;
+ break;
+ }
+ if (i == IP_MAX_MEMBERSHIPS) {
+ error = ETOOMANYREFS;
+ break;
+ }
+ /*
+ * Everything looks good; add a new record to the multicast
+ * address list for the given interface.
+ */
+ if ((imo->imo_membership[i] =
+ in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) {
+ error = ENOBUFS;
+ break;
+ }
+ ++imo->imo_num_memberships;
+ break;
+
+ case IP_DROP_MEMBERSHIP:
+ /*
+ * Drop a multicast group membership.
+ * Group must be a valid IP multicast address.
+ */
+ if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
+ error = EINVAL;
+ break;
+ }
+ mreq = mtod(m, struct ip_mreq *);
+ if (!IN_MULTICAST(mreq->imr_multiaddr.s_addr)) {
+ error = EINVAL;
+ break;
+ }
+ /*
+ * If an interface address was specified, get a pointer
+ * to its ifnet structure.
+ */
+ if (mreq->imr_interface.s_addr == INADDR_ANY)
+ ifp = NULL;
+ else {
+ INADDR_TO_IFP(mreq->imr_interface, ifp);
+ if (ifp == NULL) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ }
+ /*
+ * Find the membership in the membership array.
+ */
+ for (i = 0; i < imo->imo_num_memberships; ++i) {
+ if ((ifp == NULL ||
+ imo->imo_membership[i]->inm_ifp == ifp) &&
+ imo->imo_membership[i]->inm_addr.s_addr ==
+ mreq->imr_multiaddr.s_addr)
+ break;
+ }
+ if (i == imo->imo_num_memberships) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ /*
+ * Give up the multicast address record to which the
+ * membership points.
+ */
+ in_delmulti(imo->imo_membership[i]);
+ /*
+ * Remove the gap in the membership array.
+ */
+ for (++i; i < imo->imo_num_memberships; ++i)
+ imo->imo_membership[i-1] = imo->imo_membership[i];
+ --imo->imo_num_memberships;
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ /*
+ * If all options have default values, no need to keep the mbuf.
+ */
+ if (imo->imo_multicast_ifp == NULL &&
+ imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
+ imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
+ imo->imo_num_memberships == 0) {
+ free(*imop, M_IPMOPTS);
+ *imop = NULL;
+ }
+
+ return (error);
+}
+
+/*
+ * Return the IP multicast options in response to user getsockopt().
+ */
+int
+ip_getmoptions(optname, imo, mp)
+ int optname;
+ register struct ip_moptions *imo;
+ register struct mbuf **mp;
+{
+ u_char *ttl;
+ u_char *loop;
+ struct in_addr *addr;
+ struct in_ifaddr *ia;
+
+ *mp = m_get(M_WAIT, MT_SOOPTS);
+
+ switch (optname) {
+
+ case IP_MULTICAST_IF:
+ addr = mtod(*mp, struct in_addr *);
+ (*mp)->m_len = sizeof(struct in_addr);
+ if (imo == NULL || imo->imo_multicast_ifp == NULL)
+ addr->s_addr = INADDR_ANY;
+ else {
+ IFP_TO_IA(imo->imo_multicast_ifp, ia);
+ addr->s_addr = (ia == NULL) ? INADDR_ANY
+ : ia->ia_addr.sin_addr.s_addr;
+ }
+ return (0);
+
+ case IP_MULTICAST_TTL:
+ ttl = mtod(*mp, u_char *);
+ (*mp)->m_len = 1;
+ *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL
+ : imo->imo_multicast_ttl;
+ return (0);
+
+ case IP_MULTICAST_LOOP:
+ loop = mtod(*mp, u_char *);
+ (*mp)->m_len = 1;
+ *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP
+ : imo->imo_multicast_loop;
+ return (0);
+
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+/*
+ * Discard the IP multicast options.
+ */
+void
+ip_freemoptions(imo)
+ register struct ip_moptions *imo;
+{
+ register int i;
+
+ if (imo != NULL) {
+ for (i = 0; i < imo->imo_num_memberships; ++i)
+ in_delmulti(imo->imo_membership[i]);
+ free(imo, M_IPMOPTS);
+ }
+}
+
+/*
+ * Routine called from ip_output() to loop back a copy of an IP multicast
+ * packet to the input queue of a specified interface. Note that this
+ * calls the output routine of the loopback "driver", but with an interface
+ * pointer that might NOT be &loif -- easier than replicating that code here.
+ */
+static void
+ip_mloopback(ifp, m, dst)
+ struct ifnet *ifp;
+ register struct mbuf *m;
+ register struct sockaddr_in *dst;
+{
+ register struct ip *ip;
+ struct mbuf *copym;
+
+ copym = m_copy(m, 0, M_COPYALL);
+ if (copym != NULL) {
+ /*
+ * We don't bother to fragment if the IP length is greater
+ * than the interface's MTU. Can this possibly matter?
+ */
+ ip = mtod(copym, struct ip *);
+ ip->ip_len = htons((u_int16_t)ip->ip_len);
+ ip->ip_off = htons((u_int16_t)ip->ip_off);
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(copym, ip->ip_hl << 2);
+ (void) looutput(ifp, copym, sintosa(dst), NULL);
+ }
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/raw_ip.c b/ecos/packages/net/tcpip/current/src/sys/netinet/raw_ip.c
new file mode 100644
index 0000000..06d86e1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/raw_ip.c
@@ -0,0 +1,522 @@
+//==========================================================================
+//
+// sys/netinet/raw_ip.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: raw_ip.c,v 1.19 1999/09/23 07:20:35 deraadt Exp $ */
+/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/ip_var.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_icmp.h>
+
+#ifdef IPSEC
+extern int check_ipsec_policy __P((struct inpcb *, u_int32_t));
+#endif
+
+#include <machine/stdarg.h>
+
+struct inpcbtable rawcbtable;
+
+/*
+ * Nominal space allocated to a raw ip socket.
+ */
+#define RIPSNDQ 8192
+#define RIPRCVQ 8192
+
+/*
+ * Raw interface to IP protocol.
+ */
+
+/*
+ * Initialize raw connection block q.
+ */
+void
+rip_init()
+{
+
+ in_pcbinit(&rawcbtable, 1);
+}
+
+struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
+
+/*
+ * Setup generic address and protocol structures
+ * for raw_input routine, then pass them along with
+ * mbuf chain.
+ */
+void
+#if __STDC__
+rip_input(struct mbuf *m, ...)
+#else
+rip_input(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register struct inpcb *inp;
+ struct socket *last = 0;
+
+ ripsrc.sin_addr = ip->ip_src;
+ for (inp = rawcbtable.inpt_queue.cqh_first;
+ inp != (struct inpcb *)&rawcbtable.inpt_queue;
+ inp = inp->inp_queue.cqe_next) {
+ if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
+ continue;
+ if (inp->inp_laddr.s_addr &&
+ inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
+ continue;
+ if (inp->inp_faddr.s_addr &&
+ inp->inp_faddr.s_addr != ip->ip_src.s_addr)
+ continue;
+ if (last) {
+ struct mbuf *n;
+ if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
+ if (sbappendaddr(&last->so_rcv,
+ sintosa(&ripsrc), n,
+ (struct mbuf *)0) == 0)
+ /* should notify about lost packet */
+ m_freem(n);
+ else
+ sorwakeup(last);
+ }
+ }
+ last = inp->inp_socket;
+ }
+ if (last) {
+ if (sbappendaddr(&last->so_rcv, sintosa(&ripsrc), m,
+ (struct mbuf *)0) == 0)
+ m_freem(m);
+ else
+ sorwakeup(last);
+ } else {
+ if (ip->ip_p != IPPROTO_ICMP)
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, 0, 0);
+ else
+ m_freem(m);
+ ipstat.ips_noproto++;
+ ipstat.ips_delivered--;
+ }
+}
+
+/*
+ * Generate IP header and pass packet to ip_output.
+ * Tack on options user may have setup with control call.
+ */
+int
+#if __STDC__
+rip_output(struct mbuf *m, ...)
+#else
+rip_output(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ struct socket *so;
+ u_long dst;
+ register struct ip *ip;
+ register struct inpcb *inp;
+ int flags;
+ va_list ap;
+
+ va_start(ap, m);
+ so = va_arg(ap, struct socket *);
+ dst = va_arg(ap, u_long);
+ va_end(ap);
+
+ inp = sotoinpcb(so);
+ flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;
+
+ /*
+ * If the user handed us a complete IP packet, use it.
+ * Otherwise, allocate an mbuf for a header and fill it in.
+ */
+ if ((inp->inp_flags & INP_HDRINCL) == 0) {
+ if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) {
+ m_freem(m);
+ return (EMSGSIZE);
+ }
+ M_PREPEND(m, sizeof(struct ip), M_WAIT);
+ ip = mtod(m, struct ip *);
+ ip->ip_tos = 0;
+ ip->ip_off = 0;
+ ip->ip_p = inp->inp_ip.ip_p;
+ ip->ip_len = m->m_pkthdr.len;
+ ip->ip_src = inp->inp_laddr;
+ ip->ip_dst.s_addr = dst;
+ ip->ip_ttl = MAXTTL;
+ } else {
+ if (m->m_pkthdr.len > IP_MAXPACKET) {
+ m_freem(m);
+ return (EMSGSIZE);
+ }
+ ip = mtod(m, struct ip *);
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+ /*
+ * don't allow both user specified and setsockopt options,
+ * and don't allow packet length sizes that will crash
+ */
+ if ((ip->ip_hl != (sizeof (*ip) >> 2) && inp->inp_options) ||
+ ip->ip_len > m->m_pkthdr.len ||
+ ip->ip_len < ip->ip_hl << 2) {
+ m_freem(m);
+ return (EINVAL);
+ }
+ if (ip->ip_id == 0) {
+#ifdef RANDOM_IP_ID
+ ip->ip_id = ip_randomid();
+#else
+ ip->ip_id = htons(ip_id++);
+#endif
+ }
+ /* XXX prevent ip_output from overwriting header fields */
+ flags |= IP_RAWOUTPUT;
+ ipstat.ips_rawout++;
+ }
+#ifdef INET6
+ /*
+ * A thought: Even though raw IP shouldn't be able to set IPv6
+ * multicast options, if it does, the last parameter to
+ * ip_output should be guarded against v6/v4 problems.
+ */
+#endif
+ return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
+ inp->inp_moptions, inp));
+}
+
+/*
+ * Raw IP socket option processing.
+ */
+int
+rip_ctloutput(op, so, level, optname, m)
+ int op;
+ struct socket *so;
+ int level, optname;
+ struct mbuf **m;
+{
+ register struct inpcb *inp = sotoinpcb(so);
+ register int error;
+
+ if (level != IPPROTO_IP) {
+ if (op == PRCO_SETOPT && *m)
+ (void) m_free(*m);
+ return (EINVAL);
+ }
+
+ switch (optname) {
+
+ case IP_HDRINCL:
+ error = 0;
+ if (op == PRCO_SETOPT) {
+ if (*m == 0 || (*m)->m_len < sizeof (int))
+ error = EINVAL;
+ else if (*mtod(*m, int *))
+ inp->inp_flags |= INP_HDRINCL;
+ else
+ inp->inp_flags &= ~INP_HDRINCL;
+ if (*m)
+ (void)m_free(*m);
+ } else {
+ *m = m_get(M_WAIT, M_SOOPTS);
+ (*m)->m_len = sizeof(int);
+ *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL;
+ }
+ return (error);
+
+ case MRT_INIT:
+ case MRT_DONE:
+ case MRT_ADD_VIF:
+ case MRT_DEL_VIF:
+ case MRT_ADD_MFC:
+ case MRT_DEL_MFC:
+ case MRT_VERSION:
+ case MRT_ASSERT:
+#ifdef MROUTING
+ switch (op) {
+ case PRCO_SETOPT:
+ error = ip_mrouter_set(optname, so, m);
+ break;
+ case PRCO_GETOPT:
+ error = ip_mrouter_get(optname, so, m);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+#else
+ if (op == PRCO_SETOPT && *m)
+ m_free(*m);
+ return (EOPNOTSUPP);
+#endif
+ }
+ return (ip_ctloutput(op, so, level, optname, m));
+}
+
+u_long rip_sendspace = RIPSNDQ;
+u_long rip_recvspace = RIPRCVQ;
+
+/*ARGSUSED*/
+int
+rip_usrreq(so, req, m, nam, control)
+ register struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ register int error = 0;
+ register struct inpcb *inp = sotoinpcb(so);
+#ifdef MROUTING
+ extern struct socket *ip_mrouter;
+#endif
+ if (req == PRU_CONTROL)
+ return (in_control(so, (u_long)m, (caddr_t)nam,
+ (struct ifnet *)control));
+
+ if (inp == NULL && req != PRU_ATTACH) {
+ error = EINVAL;
+ goto release;
+ }
+
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (inp)
+ panic("rip_attach");
+#ifndef __ECOS
+ if ((so->so_state & SS_PRIV) == 0) {
+ error = EACCES;
+ break;
+ }
+#endif
+ if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
+ (error = in_pcballoc(so, &rawcbtable)))
+ break;
+ inp = (struct inpcb *)so->so_pcb;
+ inp->inp_ip.ip_p = (long)nam;
+ break;
+
+ case PRU_DISCONNECT:
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ /* FALLTHROUGH */
+ case PRU_ABORT:
+ soisdisconnected(so);
+ /* FALLTHROUGH */
+ case PRU_DETACH:
+ if (inp == 0)
+ panic("rip_detach");
+#ifdef MROUTING
+ if (so == ip_mrouter)
+ ip_mrouter_done();
+#endif
+ in_pcbdetach(inp);
+ break;
+
+ case PRU_BIND:
+ {
+ struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof(*addr)) {
+ error = EINVAL;
+ break;
+ }
+ if ((ifnet.tqh_first == 0) ||
+ ((addr->sin_family != AF_INET) &&
+ (addr->sin_family != AF_IMPLINK)) ||
+ (addr->sin_addr.s_addr &&
+ ifa_ifwithaddr(sintosa(addr)) == 0)) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ inp->inp_laddr = addr->sin_addr;
+ break;
+ }
+ case PRU_CONNECT:
+ {
+ struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof(*addr)) {
+ error = EINVAL;
+ break;
+ }
+ if (ifnet.tqh_first == 0) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ if ((addr->sin_family != AF_INET) &&
+ (addr->sin_family != AF_IMPLINK)) {
+ error = EAFNOSUPPORT;
+ break;
+ }
+ inp->inp_faddr = addr->sin_addr;
+ soisconnected(so);
+ break;
+ }
+
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ break;
+
+ /*
+ * Mark the connection as being incapable of further input.
+ */
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ /*
+ * Ship a packet out. The appropriate raw output
+ * routine handles any massaging necessary.
+ */
+ case PRU_SEND:
+ {
+ register u_int32_t dst;
+
+ if (so->so_state & SS_ISCONNECTED) {
+ if (nam) {
+ error = EISCONN;
+ break;
+ }
+ dst = inp->inp_faddr.s_addr;
+ } else {
+ if (nam == NULL) {
+ error = ENOTCONN;
+ break;
+ }
+ dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr;
+ }
+#ifdef IPSEC
+ if (!(error = check_ipsec_policy(inp, dst)))
+#endif
+ error = rip_output(m, so, dst);
+ m = NULL;
+ break;
+ }
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ return (0);
+
+ /*
+ * Not supported.
+ */
+ case PRU_RCVOOB:
+ case PRU_RCVD:
+ case PRU_LISTEN:
+ case PRU_ACCEPT:
+ case PRU_SENDOOB:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SOCKADDR:
+ in_setsockaddr(inp, nam);
+ break;
+
+ case PRU_PEERADDR:
+ in_setpeeraddr(inp, nam);
+ break;
+
+ default:
+ panic("rip_usrreq");
+ }
+release:
+ if (m != NULL)
+ m_freem(m);
+ return (error);
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_debug.c b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_debug.c
new file mode 100644
index 0000000..a4627b6
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_debug.c
@@ -0,0 +1,235 @@
+//==========================================================================
+//
+// sys/netinet/tcp_debug.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_debug.c,v 1.6 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: tcp_debug.c,v 1.10 1996/02/13 23:43:36 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_debug.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#ifdef TCPDEBUG
+/* load symbolic names */
+#define PRUREQUESTS
+#define TCPSTATES
+#define TCPTIMERS
+#define TANAMES
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/route.h>
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_debug.h>
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <netinet6/ip6.h>
+#endif /* INET6 */
+
+#ifdef TCPDEBUG
+int tcpconsdebug = 1;
+#endif
+/*
+ * Tcp debug routines
+ */
+void
+tcp_trace(act, ostate, tp, headers, req, len)
+ short act, ostate;
+ struct tcpcb *tp;
+ caddr_t headers;
+ int req;
+ int len;
+{
+#ifdef TCPDEBUG
+ tcp_seq seq, ack;
+ int flags;
+#endif
+ struct tcp_debug *td = &tcp_debug[tcp_debx++];
+ struct tcpiphdr *ti = (struct tcpiphdr *)headers;
+#ifdef INET6
+ struct tcphdr *th;
+ struct tcpipv6hdr *ti6 = (struct tcpipv6hdr *)ti;
+#endif
+
+ if (tcp_debx == TCP_NDEBUG)
+ tcp_debx = 0;
+ td->td_time = iptime();
+ td->td_act = act;
+ td->td_ostate = ostate;
+ td->td_tcb = (caddr_t)tp;
+ if (tp)
+ td->td_cb = *tp;
+ else
+ bzero((caddr_t)&td->td_cb, sizeof (*tp));
+#ifdef INET6
+ if (tp->pf == PF_INET6) {
+ if (ti) {
+ th = &ti6->ti6_t;
+ td->td_ti6 = *ti6;
+ } else {
+ bzero(&td->td_ti6, sizeof(struct tcpipv6hdr));
+ }
+ } else {
+ if (ti) {
+ th = &ti->ti_t;
+ td->td_ti = *ti;
+ } else {
+ bzero(&td->td_ti, sizeof(struct tcpiphdr));
+ }
+ }
+#else /* INET6 */
+ if (ti)
+ td->td_ti = *ti;
+ else
+ bzero((caddr_t)&td->td_ti, sizeof (*ti));
+#endif /* INET6 */
+
+ td->td_req = req;
+#ifdef TCPDEBUG
+ if (tcpconsdebug == 0)
+ return;
+ if (tp)
+ printf("%x %s:", tp, tcpstates[ostate]);
+ else
+ printf("???????? ");
+ printf("%s ", tanames[act]);
+ switch (act) {
+
+ case TA_INPUT:
+ case TA_OUTPUT:
+ case TA_DROP:
+ if (ti == 0)
+ break;
+ seq = th->th_seq;
+ ack = th->th_ack;
+ if (act == TA_OUTPUT) {
+ seq = ntohl(seq);
+ ack = ntohl(ack);
+ }
+ if (len)
+ printf("[%x..%x)", seq, seq+len);
+ else
+ printf("%x", seq);
+ printf("@%x, urp=%x", ack, th->th_urp);
+ flags = th->th_flags;
+ if (flags) {
+#ifndef lint
+ char *cp = "<";
+#define pf(f) { if (th->th_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
+ pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
+#endif
+ printf(">");
+ }
+ break;
+
+ case TA_USER:
+ printf("%s", prurequests[req&0xff]);
+ if ((req & 0xff) == PRU_SLOWTIMO)
+ printf("<%s>", tcptimers[req>>8]);
+ break;
+ }
+ if (tp)
+ printf(" -> %s", tcpstates[tp->t_state]);
+ /* print out internal state of tp !?! */
+ printf("\n");
+ if (tp == 0)
+ return;
+ printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
+ tp->rcv_nxt, tp->rcv_wnd, tp->rcv_up, tp->snd_una, tp->snd_nxt,
+ tp->snd_max);
+ printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
+ tp->snd_wl1, tp->snd_wl2, tp->snd_wnd);
+#endif /* TCPDEBUG */
+}
+#endif
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_input.c b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_input.c
new file mode 100644
index 0000000..b7a4ad9
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_input.c
@@ -0,0 +1,2996 @@
+//==========================================================================
+//
+// sys/netinet/tcp_input.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_input.c,v 1.54 1999/12/15 16:37:20 provos Exp $ */
+/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#ifndef TUBA_INCLUDE
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_debug.h>
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+#include <machine/stdarg.h>
+#ifndef __ECOS
+#include <sys/md5k.h>
+#endif
+
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+#endif /* IPSEC */
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <sys/domain.h>
+#include <netinet6/in6_var.h>
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/tcpipv6.h>
+#include <netinet/icmp6.h>
+#include <netinet6/nd6.h>
+
+#ifndef CREATE_IPV6_MAPPED
+#define CREATE_IPV6_MAPPED(a6, a4) \
+do { \
+ bzero(&(a6), sizeof(a6)); \
+ (a6).s6_addr[10] = (a6).s6_addr[11] = 0xff; \
+ *(u_int32_t *)&(a6).s6_addr[12] = (a4); \
+} while (0)
+#endif
+
+struct tcpiphdr tcp_saveti;
+struct tcpipv6hdr tcp_saveti6;
+
+/* for the packet header length in the mbuf */
+#define M_PH_LEN(m) (((struct mbuf *)(m))->m_pkthdr.len)
+#define M_V6_LEN(m) (M_PH_LEN(m) - sizeof(struct ip6_hdr))
+#define M_V4_LEN(m) (M_PH_LEN(m) - sizeof(struct ip))
+#endif /* INET6 */
+
+int tcprexmtthresh = 3;
+struct tcpiphdr tcp_saveti;
+int tcptv_keep_init = TCPTV_KEEP_INIT;
+
+extern u_long sb_max;
+
+#endif /* TUBA_INCLUDE */
+#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
+
+/* for modulo comparisons of timestamps */
+#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
+#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
+
+/*
+ * Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint.
+ */
+#ifdef INET6
+#define ND6_HINT(tp) \
+do { \
+ if (tp && tp->t_inpcb && (tp->t_inpcb->inp_flags & INP_IPV6) \
+ && !(tp->t_inpcb->inp_flags & INP_IPV6_MAPPED) \
+ && tp->t_inpcb->inp_route6.ro_rt) { \
+ nd6_nud_hint(tp->t_inpcb->inp_route6.ro_rt, NULL); \
+ } \
+} while (0)
+#else
+#define ND6_HINT(tp)
+#endif
+
+/*
+ * Insert segment ti into reassembly queue of tcp with
+ * control block tp. Return TH_FIN if reassembly now includes
+ * a segment with FIN. The macro form does the common case inline
+ * (segment is the next to be received on an established connection,
+ * and the queue is empty), avoiding linkage into and removal
+ * from the queue and repetition of various conversions.
+ * Set DELACK for segments received in order, but ack immediately
+ * when segments are out of order (so fast retransmit can work).
+ */
+
+#ifndef TUBA_INCLUDE
+
+int
+tcp_reass(tp, th, m, tlen)
+ register struct tcpcb *tp;
+ register struct tcphdr *th;
+ struct mbuf *m;
+ int *tlen;
+{
+ register struct ipqent *p, *q, *nq, *tiqe;
+ struct socket *so = tp->t_inpcb->inp_socket;
+ int flags;
+
+ /*
+ * Call with th==0 after become established to
+ * force pre-ESTABLISHED data up to user socket.
+ */
+ if (th == 0)
+ goto present;
+
+ /*
+ * Allocate a new queue entry, before we throw away any data.
+ * If we can't, just drop the packet. XXX
+ */
+ MALLOC(tiqe, struct ipqent *, sizeof (struct ipqent), M_IPQ, M_NOWAIT);
+ if (tiqe == NULL) {
+ tcpstat.tcps_rcvmemdrop++;
+ m_freem(m);
+ return (0);
+ }
+
+ /*
+ * Find a segment which begins after this one does.
+ */
+ for (p = NULL, q = tp->segq.lh_first; q != NULL;
+ p = q, q = q->ipqe_q.le_next)
+ if (SEQ_GT(q->ipqe_tcp->th_seq, th->th_seq))
+ break;
+
+ /*
+ * If there is a preceding segment, it may provide some of
+ * our data already. If so, drop the data from the incoming
+ * segment. If it provides all of our data, drop us.
+ */
+ if (p != NULL) {
+ register struct tcphdr *phdr = p->ipqe_tcp;
+ register int i;
+
+ /* conversion to int (in i) handles seq wraparound */
+ i = phdr->th_seq + phdr->th_reseqlen - th->th_seq;
+ if (i > 0) {
+ if (i >= *tlen) {
+ tcpstat.tcps_rcvduppack++;
+ tcpstat.tcps_rcvdupbyte += *tlen;
+ m_freem(m);
+ FREE(tiqe, M_IPQ);
+ return (0);
+ }
+ m_adj(m, i);
+ *tlen -= i;
+ th->th_seq += i;
+ }
+ }
+ tcpstat.tcps_rcvoopack++;
+ tcpstat.tcps_rcvoobyte += *tlen;
+
+ /*
+ * While we overlap succeeding segments trim them or,
+ * if they are completely covered, dequeue them.
+ */
+ for (; q != NULL; q = nq) {
+ register struct tcphdr *qhdr = q->ipqe_tcp;
+ register int i = (th->th_seq + *tlen) - qhdr->th_seq;
+
+ if (i <= 0)
+ break;
+ if (i < qhdr->th_reseqlen) {
+ qhdr->th_seq += i;
+ qhdr->th_reseqlen -= i;
+ m_adj(q->ipqe_m, i);
+ break;
+ }
+ nq = q->ipqe_q.le_next;
+ m_freem(q->ipqe_m);
+ LIST_REMOVE(q, ipqe_q);
+ FREE(q, M_IPQ);
+ }
+
+ /* Insert the new fragment queue entry into place. */
+ tiqe->ipqe_m = m;
+ th->th_reseqlen = *tlen;
+ tiqe->ipqe_tcp = th;
+ if (p == NULL) {
+ LIST_INSERT_HEAD(&tp->segq, tiqe, ipqe_q);
+ } else {
+ LIST_INSERT_AFTER(p, tiqe, ipqe_q);
+ }
+
+present:
+ /*
+ * Present data to user, advancing rcv_nxt through
+ * completed sequence space.
+ */
+ if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
+ return (0);
+ q = tp->segq.lh_first;
+ if (q == NULL || q->ipqe_tcp->th_seq != tp->rcv_nxt)
+ return (0);
+ if (tp->t_state == TCPS_SYN_RECEIVED && q->ipqe_tcp->th_reseqlen)
+ return (0);
+ do {
+ tp->rcv_nxt += q->ipqe_tcp->th_reseqlen;
+ flags = q->ipqe_tcp->th_flags & TH_FIN;
+
+ nq = q->ipqe_q.le_next;
+ LIST_REMOVE(q, ipqe_q);
+ ND6_HINT(tp);
+ if (so->so_state & SS_CANTRCVMORE)
+ m_freem(q->ipqe_m);
+ else
+ sbappend(&so->so_rcv, q->ipqe_m);
+ FREE(q, M_IPQ);
+ q = nq;
+ } while (q != NULL && q->ipqe_tcp->th_seq == tp->rcv_nxt);
+ sorwakeup(so);
+ return (flags);
+}
+
+/*
+ * First check for a port-specific bomb. We do not want to drop half-opens
+ * for other ports if this is the only port being bombed. We only check
+ * the bottom 40 half open connections, to avoid wasting too much time.
+ *
+ * Or, otherwise it is more likely a generic syn bomb, so delete the oldest
+ * half-open connection.
+ */
+void
+tcpdropoldhalfopen(avoidtp, port)
+ struct tcpcb *avoidtp;
+ u_int16_t port;
+{
+ register struct inpcb *inp;
+ register struct tcpcb *tp;
+ int ncheck = 40;
+ int s;
+
+ s = splnet();
+ inp = tcbtable.inpt_queue.cqh_first;
+ if (inp) /* XXX */
+ for (; inp != (struct inpcb *)&tcbtable.inpt_queue && --ncheck;
+ inp = inp->inp_queue.cqe_prev) {
+ if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
+ tp != avoidtp &&
+ tp->t_state == TCPS_SYN_RECEIVED &&
+ port == inp->inp_lport) {
+ tcp_close(tp);
+ goto done;
+ }
+ }
+
+ inp = tcbtable.inpt_queue.cqh_first;
+ if (inp) /* XXX */
+ for (; inp != (struct inpcb *)&tcbtable.inpt_queue;
+ inp = inp->inp_queue.cqe_prev) {
+ if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
+ tp != avoidtp &&
+ tp->t_state == TCPS_SYN_RECEIVED) {
+ tcp_close(tp);
+ goto done;
+ }
+ }
+done:
+ splx(s);
+}
+
+#if defined(INET6) && !defined(TCP6)
+int
+tcp6_input(mp, offp, proto)
+ struct mbuf **mp;
+ int *offp, proto;
+{
+ struct mbuf *m = *mp;
+
+#if defined(NFAITH) && 0 < NFAITH
+ if (m->m_pkthdr.rcvif) {
+ if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
+ /* XXX send icmp6 host/port unreach? */
+ m_freem(m);
+ return IPPROTO_DONE;
+ }
+ }
+#endif
+
+ /*
+ * draft-itojun-ipv6-tcp-to-anycast
+ * better place to put this in?
+ */
+ if (m->m_flags & M_ANYCAST6) {
+ if (m->m_len >= sizeof(struct ip6_hdr)) {
+ struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ icmp6_error(m, ICMP6_DST_UNREACH,
+ ICMP6_DST_UNREACH_ADDR,
+ (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
+ } else
+ m_freem(m);
+ return IPPROTO_DONE;
+ }
+
+ tcp_input(m, *offp, proto);
+ return IPPROTO_DONE;
+}
+#endif
+
+/*
+ * TCP input routine, follows pages 65-76 of the
+ * protocol specification dated September, 1981 very closely.
+ */
+void
+#if __STDC__
+tcp_input(struct mbuf *m, ...)
+#else
+tcp_input(m, va_alist)
+ register struct mbuf *m;
+#endif
+{
+ register struct tcpiphdr *ti;
+ register struct inpcb *inp;
+ caddr_t optp = NULL;
+ int optlen = 0;
+ int len, tlen, off;
+ register struct tcpcb *tp = 0;
+ register int tiflags;
+ struct socket *so = NULL;
+ int todrop, acked, ourfinisacked, needoutput = 0;
+ int hdroptlen = 0;
+ short ostate = 0;
+ struct in_addr laddr;
+ int dropsocket = 0;
+ int iss = 0;
+ u_long tiwin;
+ u_int32_t ts_val, ts_ecr;
+ int ts_present = 0;
+ int iphlen;
+ va_list ap;
+ register struct tcphdr *th;
+#ifdef IPSEC
+ struct tdb *tdb = NULL;
+#endif /* IPSEC */
+#ifdef INET6
+ struct in6_addr laddr6;
+ unsigned short is_ipv6; /* Type of incoming datagram. */
+ struct ip6_hdr *ipv6 = NULL;
+#endif /* INET6 */
+
+ va_start(ap, m);
+ iphlen = va_arg(ap, int);
+ va_end(ap);
+
+ tcpstat.tcps_rcvtotal++;
+
+#ifdef IPSEC
+ /* Save the last SA which was used to process the mbuf */
+ if ((m->m_flags & (M_CONF|M_AUTH)) && m->m_pkthdr.tdbi) {
+ struct tdb_ident *tdbi = m->m_pkthdr.tdbi;
+ /* XXX gettdb() should really be called at spltdb(). */
+ /* XXX this is splsoftnet(), currently they are the same. */
+ tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
+#endif /* IPSEC */
+#ifdef INET6
+ /*
+ * Before we do ANYTHING, we have to figure out if it's TCP/IPv6 or
+ * TCP/IPv4.
+ */
+ is_ipv6 = mtod(m, struct ip *)->ip_v == 6;
+#endif /* INET6 */
+
+ /*
+ * Get IP and TCP header together in first mbuf.
+ * Note: IP leaves IP header in first mbuf.
+ */
+#ifndef INET6
+ ti = mtod(m, struct tcpiphdr *);
+#else /* INET6 */
+ if (!is_ipv6)
+#endif /* INET6 */
+ if (iphlen > sizeof (struct ip)) {
+#if 0 /*XXX*/
+ ip_stripoptions(m, (struct mbuf *)0);
+#else
+#ifdef __ECOS
+ diag_printf("extension headers are not allowed\n");
+#else
+ printf("extension headers are not allowed\n");
+#endif
+ m_freem(m);
+ return;
+#endif
+ }
+ if (m->m_len < iphlen + sizeof(struct tcphdr)) {
+ if ((m = m_pullup2(m, iphlen + sizeof(struct tcphdr))) == 0) {
+ tcpstat.tcps_rcvshort++;
+ return;
+ }
+#ifndef INET6
+ ti = mtod(m, struct tcpiphdr *);
+#endif /* INET6 */
+ }
+
+ tlen = m->m_pkthdr.len - iphlen;
+
+#ifdef INET6
+ /*
+ * After that, do initial segment processing which is still very
+ * dependent on what IP version you're using.
+ */
+
+ if (is_ipv6) {
+#ifdef DIAGNOSTIC
+ if (iphlen < sizeof(struct ip6_hdr)) {
+ m_freem(m);
+ return;
+ }
+#endif /* DIAGNOSTIC */
+
+ /* strip off any options */
+ if (iphlen > sizeof(struct ip6_hdr)) {
+#if 0 /*XXX*/
+ ipv6_stripoptions(m, iphlen);
+#else
+#ifdef __ECOS
+ diag_printf("extension headers are not allowed\n");
+#else
+ printf("extension headers are not allowed\n");
+#endif
+ m_freem(m);
+ return;
+#endif
+ iphlen = sizeof(struct ip6_hdr);
+ }
+
+ ti = NULL;
+ ipv6 = mtod(m, struct ip6_hdr *);
+
+ if (in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr), tlen)) {
+ tcpstat.tcps_rcvbadsum++;
+ goto drop;
+ } /* endif in6_cksum */
+ } else {
+ ti = mtod(m, struct tcpiphdr *);
+#endif /* INET6 */
+
+ /*
+ * Checksum extended TCP header and data.
+ */
+#ifndef INET6
+ tlen = ((struct ip *)ti)->ip_len;
+#endif /* INET6 */
+ len = sizeof (struct ip) + tlen;
+ bzero(ti->ti_x1, sizeof ti->ti_x1);
+ ti->ti_len = (u_int16_t)tlen;
+ HTONS(ti->ti_len);
+ if ((ti->ti_sum = in_cksum(m, len)) != 0) {
+ tcpstat.tcps_rcvbadsum++;
+ goto drop;
+ }
+#ifdef INET6
+ }
+#endif /* INET6 */
+#endif /* TUBA_INCLUDE */
+
+ th = (struct tcphdr *)(mtod(m, caddr_t) + iphlen);
+
+ /*
+ * Check that TCP offset makes sense,
+ * pull out TCP options and adjust length. XXX
+ */
+ off = th->th_off << 2;
+ if (off < sizeof (struct tcphdr) || off > tlen) {
+ tcpstat.tcps_rcvbadoff++;
+ goto drop;
+ }
+ tlen -= off;
+ if (off > sizeof (struct tcphdr)) {
+ if (m->m_len < iphlen + off) {
+ if ((m = m_pullup2(m, iphlen + off)) == 0) {
+ tcpstat.tcps_rcvshort++;
+ return;
+ }
+#ifdef INET6
+ if (is_ipv6)
+ ipv6 = mtod(m, struct ip6_hdr *);
+ else
+#endif /* INET6 */
+ ti = mtod(m, struct tcpiphdr *);
+ th = (struct tcphdr *)(mtod(m, caddr_t) + iphlen);
+ }
+ optlen = off - sizeof (struct tcphdr);
+ optp = mtod(m, caddr_t) + iphlen + sizeof(struct tcphdr);
+ /*
+ * Do quick retrieval of timestamp options ("options
+ * prediction?"). If timestamp is the only option and it's
+ * formatted as recommended in RFC 1323 appendix A, we
+ * quickly get the values now and not bother calling
+ * tcp_dooptions(), etc.
+ */
+ if ((optlen == TCPOLEN_TSTAMP_APPA ||
+ (optlen > TCPOLEN_TSTAMP_APPA &&
+ optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
+ *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
+ (th->th_flags & TH_SYN) == 0) {
+ ts_present = 1;
+ ts_val = ntohl(*(u_int32_t *)(optp + 4));
+ ts_ecr = ntohl(*(u_int32_t *)(optp + 8));
+ optp = NULL; /* we've parsed the options */
+ }
+ }
+ tiflags = th->th_flags;
+
+ /*
+ * Convert TCP protocol specific fields to host format.
+ */
+ NTOHL(th->th_seq);
+ NTOHL(th->th_ack);
+ NTOHS(th->th_win);
+ NTOHS(th->th_urp);
+
+ /*
+ * Locate pcb for segment.
+ */
+findpcb:
+#ifdef INET6
+ if (is_ipv6) {
+ inp = in6_pcbhashlookup(&tcbtable, &ipv6->ip6_src, th->th_sport,
+ &ipv6->ip6_dst, th->th_dport);
+ } else
+#endif /* INET6 */
+ inp = in_pcbhashlookup(&tcbtable, ti->ti_src, ti->ti_sport,
+ ti->ti_dst, ti->ti_dport);
+ if (inp == 0) {
+ ++tcpstat.tcps_pcbhashmiss;
+#ifdef INET6
+ if (is_ipv6)
+ inp = in_pcblookup(&tcbtable, &ipv6->ip6_src,
+ th->th_sport, &ipv6->ip6_dst, th->th_dport,
+ INPLOOKUP_WILDCARD | INPLOOKUP_IPV6);
+ else
+#endif /* INET6 */
+ inp = in_pcblookup(&tcbtable, &ti->ti_src, ti->ti_sport,
+ &ti->ti_dst, ti->ti_dport, INPLOOKUP_WILDCARD);
+ /*
+ * If the state is CLOSED (i.e., TCB does not exist) then
+ * all data in the incoming segment is discarded.
+ * If the TCB exists but is in CLOSED state, it is embryonic,
+ * but should either do a listen or a connect soon.
+ */
+ if (inp == 0) {
+ ++tcpstat.tcps_noport;
+ goto dropwithreset;
+ }
+ }
+
+ tp = intotcpcb(inp);
+ if (tp == 0)
+ goto dropwithreset;
+ if (tp->t_state == TCPS_CLOSED)
+ goto drop;
+
+ /* Unscale the window into a 32-bit value. */
+ if ((tiflags & TH_SYN) == 0)
+ tiwin = th->th_win << tp->snd_scale;
+ else
+ tiwin = th->th_win;
+
+ so = inp->inp_socket;
+ if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
+ if (so->so_options & SO_DEBUG) {
+ ostate = tp->t_state;
+#ifdef INET6
+ if (is_ipv6)
+ tcp_saveti6 = *(mtod(m, struct tcpipv6hdr *));
+ else
+#endif /* INET6 */
+ tcp_saveti = *ti;
+ }
+ if (so->so_options & SO_ACCEPTCONN) {
+ struct socket *so1;
+
+ so1 = sonewconn(so, 0);
+ if (so1 == NULL) {
+ tcpdropoldhalfopen(tp, th->th_dport);
+ so1 = sonewconn(so, 0);
+ if (so1 == NULL)
+ goto drop;
+ }
+ so = so1;
+ /*
+ * This is ugly, but ....
+ *
+ * Mark socket as temporary until we're
+ * committed to keeping it. The code at
+ * ``drop'' and ``dropwithreset'' check the
+ * flag dropsocket to see if the temporary
+ * socket created here should be discarded.
+ * We mark the socket as discardable until
+ * we're committed to it below in TCPS_LISTEN.
+ */
+ dropsocket++;
+#ifdef IPSEC
+ /*
+ * We need to copy the required security levels
+ * from the old pcb.
+ */
+ {
+ struct inpcb *newinp = (struct inpcb *)so->so_pcb;
+ bcopy(inp->inp_seclevel, newinp->inp_seclevel,
+ sizeof(inp->inp_seclevel));
+ newinp->inp_secrequire = inp->inp_secrequire;
+ }
+#endif /* IPSEC */
+#ifdef INET6
+ /*
+ * inp still has the OLD in_pcb stuff, set the
+ * v6-related flags on the new guy, too. This is
+ * done particularly for the case where an AF_INET6
+ * socket is bound only to a port, and a v4 connection
+ * comes in on that port.
+ * we also copy the flowinfo from the original pcb
+ * to the new one.
+ */
+ {
+ int flags = inp->inp_flags;
+ struct inpcb *oldinpcb = inp;
+
+ inp = (struct inpcb *)so->so_pcb;
+ inp->inp_flags |= (flags & (INP_IPV6 | INP_IPV6_UNDEC
+ | INP_IPV6_MAPPED));
+ if ((inp->inp_flags & INP_IPV6) &&
+ !(inp->inp_flags & INP_IPV6_MAPPED)) {
+ inp->inp_ipv6.ip6_hlim =
+ oldinpcb->inp_ipv6.ip6_hlim;
+ inp->inp_ipv6.ip6_flow =
+ oldinpcb->inp_ipv6.ip6_flow;
+ }
+ }
+#else /* INET6 */
+ inp = (struct inpcb *)so->so_pcb;
+#endif /* INET6 */
+ inp->inp_lport = th->th_dport;
+#ifdef INET6
+ if (is_ipv6) {
+ inp->inp_laddr6 = ipv6->ip6_dst;
+ inp->inp_fflowinfo = htonl(0x0fffffff) &
+ ipv6->ip6_flow;
+
+ /*inp->inp_options = ip6_srcroute();*/ /* soon. */
+ /* still need to tweak outbound options
+ processing to include this mbuf in
+ the right place and put the correct
+ NextHdr values in the right places.
+ XXX rja */
+ } else {
+ if (inp->inp_flags & INP_IPV6) {/* v4 to v6 socket */
+ CREATE_IPV6_MAPPED(inp->inp_laddr6,
+ ti->ti_dst.s_addr);
+ } else {
+#endif /* INET6 */
+ inp->inp_laddr = ti->ti_dst;
+ inp->inp_options = ip_srcroute();
+#ifdef INET6
+ }
+ }
+#endif /* INET6 */
+ in_pcbrehash(inp);
+ tp = intotcpcb(inp);
+ tp->t_state = TCPS_LISTEN;
+
+ /* Compute proper scaling value from buffer space
+ */
+ while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
+ TCP_MAXWIN << tp->request_r_scale < so->so_rcv.sb_hiwat)
+ tp->request_r_scale++;
+ }
+ }
+
+#ifdef IPSEC
+ /* Check if this socket requires security for incoming packets */
+ if ((inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_AUTH)) ||
+ (inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_CONF))) {
+#ifdef notyet
+#ifdef INET6
+ if (is_ipv6)
+ icmp6_error(m, ICMPV6_BLAH, ICMPV6_BLAH, 0);
+ else
+#endif /* INET6 */
+ icmp_error(m, ICMP_BLAH, ICMP_BLAH, 0, 0);
+#endif /* notyet */
+ tcpstat.tcps_rcvnosec++;
+ goto drop;
+ }
+ /* Use tdb_bind_out for this inp's outbound communication */
+ if (tdb)
+ tdb_add_inp(tdb, inp);
+#endif /*IPSEC */
+
+ /*
+ * Segment received on connection.
+ * Reset idle time and keep-alive timer.
+ */
+ tp->t_idle = 0;
+ if (tp->t_state != TCPS_SYN_RECEIVED)
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+
+#ifdef TCP_SACK
+ if (!tp->sack_disable)
+ tcp_del_sackholes(tp, th); /* Delete stale SACK holes */
+#endif /* TCP_SACK */
+
+ /*
+ * Process options if not in LISTEN state,
+ * else do it below (after getting remote address).
+ */
+ if (optp && tp->t_state != TCPS_LISTEN)
+ tcp_dooptions(tp, optp, optlen, th,
+ &ts_present, &ts_val, &ts_ecr);
+
+#ifdef TCP_SACK
+ if (!tp->sack_disable) {
+ tp->rcv_laststart = th->th_seq; /* last rec'vd segment*/
+ tp->rcv_lastend = th->th_seq + tlen;
+ }
+#endif /* TCP_SACK */
+ /*
+ * Header prediction: check for the two common cases
+ * of a uni-directional data xfer. If the packet has
+ * no control flags, is in-sequence, the window didn't
+ * change and we're not retransmitting, it's a
+ * candidate. If the length is zero and the ack moved
+ * forward, we're the sender side of the xfer. Just
+ * free the data acked & wake any higher level process
+ * that was blocked waiting for space. If the length
+ * is non-zero and the ack didn't move, we're the
+ * receiver side. If we're getting packets in-order
+ * (the reassembly queue is empty), add the data to
+ * the socket buffer and note that we need a delayed ack.
+ */
+ if (tp->t_state == TCPS_ESTABLISHED &&
+ (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
+ (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) &&
+ th->th_seq == tp->rcv_nxt &&
+ tiwin && tiwin == tp->snd_wnd &&
+ tp->snd_nxt == tp->snd_max) {
+
+ /*
+ * If last ACK falls within this segment's sequence numbers,
+ * record the timestamp.
+ * Fix from Braden, see Stevens p. 870
+ */
+ if (ts_present && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) {
+ tp->ts_recent_age = tcp_now;
+ tp->ts_recent = ts_val;
+ }
+
+ if (tlen == 0) {
+ if (SEQ_GT(th->th_ack, tp->snd_una) &&
+ SEQ_LEQ(th->th_ack, tp->snd_max) &&
+ tp->snd_cwnd >= tp->snd_wnd &&
+ tp->t_dupacks == 0) {
+ /*
+ * this is a pure ack for outstanding data.
+ */
+ ++tcpstat.tcps_predack;
+ if (ts_present)
+ tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
+ else if (tp->t_rtt &&
+ SEQ_GT(th->th_ack, tp->t_rtseq))
+ tcp_xmit_timer(tp, tp->t_rtt);
+ acked = th->th_ack - tp->snd_una;
+ tcpstat.tcps_rcvackpack++;
+ tcpstat.tcps_rcvackbyte += acked;
+ ND6_HINT(tp);
+ sbdrop(&so->so_snd, acked);
+ tp->snd_una = th->th_ack;
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ /*
+ * We want snd_last to track snd_una so
+ * as to avoid sequence wraparound problems
+ * for very large transfers.
+ */
+ tp->snd_last = tp->snd_una;
+#endif /* TCP_SACK or TCP_NEWRENO */
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ tp->snd_fack = tp->snd_una;
+ tp->retran_data = 0;
+#endif /* TCP_FACK */
+ m_freem(m);
+
+ /*
+ * If all outstanding data are acked, stop
+ * retransmit timer, otherwise restart timer
+ * using current (possibly backed-off) value.
+ * If process is waiting for space,
+ * wakeup/selwakeup/signal. If data
+ * are ready to send, let tcp_output
+ * decide between more output or persist.
+ */
+ if (tp->snd_una == tp->snd_max)
+ tp->t_timer[TCPT_REXMT] = 0;
+ else if (tp->t_timer[TCPT_PERSIST] == 0)
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+
+ if (sb_notify(&so->so_snd))
+ sowwakeup(so);
+ if (so->so_snd.sb_cc)
+ (void) tcp_output(tp);
+ return;
+ }
+ } else if (th->th_ack == tp->snd_una &&
+ tp->segq.lh_first == NULL &&
+ tlen <= sbspace(&so->so_rcv)) {
+ /*
+ * This is a pure, in-sequence data packet
+ * with nothing on the reassembly queue and
+ * we have enough buffer space to take it.
+ */
+#ifdef TCP_SACK
+ /* Clean receiver SACK report if present */
+ if (!tp->sack_disable && tp->rcv_numsacks)
+ tcp_clean_sackreport(tp);
+#endif /* TCP_SACK */
+ ++tcpstat.tcps_preddat;
+ tp->rcv_nxt += tlen;
+ tcpstat.tcps_rcvpack++;
+ tcpstat.tcps_rcvbyte += tlen;
+ ND6_HINT(tp);
+ /*
+ * Drop TCP, IP headers and TCP options then add data
+ * to socket buffer.
+ */
+ m_adj(m, iphlen + off);
+ sbappend(&so->so_rcv, m);
+ sorwakeup(so);
+ if (th->th_flags & TH_PUSH)
+ tp->t_flags |= TF_ACKNOW;
+ else
+ tp->t_flags |= TF_DELACK;
+ return;
+ }
+ }
+
+ /*
+ * Compute mbuf offset to TCP data segment.
+ */
+ hdroptlen = iphlen + off;
+
+ /*
+ * Calculate amount of space in receive window,
+ * and then do TCP input processing.
+ * Receive window is amount of space in rcv queue,
+ * but not less than advertised window.
+ */
+ { int win;
+
+ win = sbspace(&so->so_rcv);
+ if (win < 0)
+ win = 0;
+ tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt));
+ }
+
+ switch (tp->t_state) {
+
+ /*
+ * If the state is LISTEN then ignore segment if it contains an RST.
+ * If the segment contains an ACK then it is bad and send a RST.
+ * If it does not contain a SYN then it is not interesting; drop it.
+ * If it is from this socket, drop it, it must be forged.
+ * Don't bother responding if the destination was a broadcast.
+ * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
+ * tp->iss, and send a segment:
+ * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
+ * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
+ * Fill in remote peer address fields if not previously specified.
+ * Enter SYN_RECEIVED state, and process any other fields of this
+ * segment in this state.
+ */
+ case TCPS_LISTEN: {
+ struct mbuf *am;
+ register struct sockaddr_in *sin;
+#ifdef INET6
+ register struct sockaddr_in6 *sin6;
+#endif /* INET6 */
+
+ if (tiflags & TH_RST)
+ goto drop;
+ if (tiflags & TH_ACK)
+ goto dropwithreset;
+ if ((tiflags & TH_SYN) == 0)
+ goto drop;
+ if (th->th_dport == th->th_sport) {
+#ifdef INET6
+ if (is_ipv6) {
+ if (IN6_ARE_ADDR_EQUAL(&ipv6->ip6_src, &ipv6->ip6_dst))
+ goto drop;
+ } else {
+#endif /* INET6 */
+ if (ti->ti_dst.s_addr == ti->ti_src.s_addr)
+ goto drop;
+#ifdef INET6
+ }
+#endif /* INET6 */
+ }
+
+ /*
+ * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
+ * in_broadcast() should never return true on a received
+ * packet with M_BCAST not set.
+ */
+ if (m->m_flags & (M_BCAST|M_MCAST))
+ goto drop;
+#ifdef INET6
+ if (is_ipv6) {
+ /* XXX What about IPv6 Anycasting ?? :-( rja */
+ if (IN6_IS_ADDR_MULTICAST(&ipv6->ip6_dst))
+ goto drop;
+ } else
+#endif /* INET6 */
+ if (IN_MULTICAST(ti->ti_dst.s_addr))
+ goto drop;
+ am = m_get(M_DONTWAIT, MT_SONAME); /* XXX */
+ if (am == NULL)
+ goto drop;
+#ifdef INET6
+ if (is_ipv6) {
+ /*
+ * This is probably the place to set the tp->pf value.
+ * (Don't forget to do it in the v4 code as well!)
+ *
+ * Also, remember to blank out things like flowlabel, or
+ * set flowlabel for accepted sockets in v6.
+ *
+ * FURTHERMORE, this is PROBABLY the place where the whole
+ * business of key munging is set up for passive
+ * connections.
+ */
+ am->m_len = sizeof(struct sockaddr_in6);
+ sin6 = mtod(am, struct sockaddr_in6 *);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+ sin6->sin6_addr = ipv6->ip6_src;
+ sin6->sin6_port = th->th_sport;
+ sin6->sin6_flowinfo = htonl(0x0fffffff) &
+ inp->inp_ipv6.ip6_flow;
+ laddr6 = inp->inp_laddr6;
+ if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
+ inp->inp_laddr6 = ipv6->ip6_dst;
+ /* This is a good optimization. */
+ if (in6_pcbconnect(inp, am)) {
+ inp->inp_laddr6 = laddr6;
+ (void) m_free(am);
+ goto drop;
+ } /* endif in6_pcbconnect() */
+ tp->pf = PF_INET6;
+ } else {
+ /*
+ * Letting v4 incoming datagrams to reach valid
+ * PF_INET6 sockets causes some overhead here.
+ */
+ if (inp->inp_flags & INP_IPV6) {
+ if (!(inp->inp_flags & (INP_IPV6_UNDEC|INP_IPV6_MAPPED))) {
+ (void) m_free(am);
+ goto drop;
+ }
+
+ am->m_len = sizeof(struct sockaddr_in6);
+
+ sin6 = mtod(am, struct sockaddr_in6 *);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
+ CREATE_IPV6_MAPPED(sin6->sin6_addr, ti->ti_src.s_addr);
+ sin6->sin6_port = th->th_sport;
+ sin6->sin6_flowinfo = 0;
+
+ laddr6 = inp->inp_laddr6;
+ if (inp->inp_laddr.s_addr == INADDR_ANY)
+ CREATE_IPV6_MAPPED(inp->inp_laddr6, ti->ti_dst.s_addr);
+
+ /*
+ * The pcb initially has the v6 default hoplimit
+ * set. We're sending v4 packets so we need to set
+ * the v4 ttl and tos.
+ */
+ inp->inp_ip.ip_ttl = ip_defttl;
+ inp->inp_ip.ip_tos = 0;
+
+ if (in6_pcbconnect(inp, am)) {
+ inp->inp_laddr6 = laddr6;
+ (void) m_freem(am);
+ goto drop;
+ }
+ tp->pf = PF_INET;
+ } else {
+#endif /* INET6 */
+ am->m_len = sizeof (struct sockaddr_in);
+ sin = mtod(am, struct sockaddr_in *);
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = ti->ti_src;
+ sin->sin_port = ti->ti_sport;
+ bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero));
+ laddr = inp->inp_laddr;
+ if (inp->inp_laddr.s_addr == INADDR_ANY)
+ inp->inp_laddr = ti->ti_dst;
+ if (in_pcbconnect(inp, am)) {
+ inp->inp_laddr = laddr;
+ (void) m_free(am);
+ goto drop;
+ }
+ (void) m_free(am);
+ tp->pf = PF_INET;
+#ifdef INET6
+ } /* if (inp->inp_flags & INP_IPV6) */
+ } /* if (is_ipv6) */
+#endif /* INET6 */
+ tp->t_template = tcp_template(tp);
+ if (tp->t_template == 0) {
+ tp = tcp_drop(tp, ENOBUFS);
+ dropsocket = 0; /* socket is already gone */
+ goto drop;
+ }
+ if (optp)
+ tcp_dooptions(tp, optp, optlen, th,
+ &ts_present, &ts_val, &ts_ecr);
+#ifdef TCP_SACK
+ /*
+ * If peer did not send a SACK_PERMITTED option (i.e., if
+ * tcp_dooptions() did not set TF_SACK_PERMIT), set
+ * sack_disable to 1 if it is currently 0.
+ */
+ if (!tp->sack_disable)
+ if ((tp->t_flags & TF_SACK_PERMIT) == 0)
+ tp->sack_disable = 1;
+#endif
+
+ if (iss)
+ tp->iss = iss;
+ else
+ tp->iss = tcp_iss;
+#ifdef TCP_COMPAT_42
+ tcp_iss += TCP_ISSINCR/2;
+#else /* TCP_COMPAT_42 */
+ tcp_iss += arc4random() % TCP_ISSINCR + 1;
+#endif /* !TCP_COMPAT_42 */
+ tp->irs = th->th_seq;
+ tcp_sendseqinit(tp);
+#if defined (TCP_SACK) || defined (TCP_NEWRENO)
+ tp->snd_last = tp->snd_una;
+#endif /* TCP_SACK || TCP_NEWRENO */
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ tp->snd_fack = tp->snd_una;
+ tp->retran_data = 0;
+ tp->snd_awnd = 0;
+#endif /* TCP_FACK */
+ tcp_rcvseqinit(tp);
+ tp->t_flags |= TF_ACKNOW;
+ tp->t_state = TCPS_SYN_RECEIVED;
+ tp->t_timer[TCPT_KEEP] = tcptv_keep_init;
+ dropsocket = 0; /* committed to socket */
+ tcpstat.tcps_accepts++;
+ goto trimthenstep6;
+ }
+
+ /*
+ * If the state is SYN_RECEIVED:
+ * if seg contains SYN/ACK, send an RST.
+ * if seg contains an ACK, but not for our SYN/ACK, send an RST
+ */
+
+ case TCPS_SYN_RECEIVED:
+ if (tiflags & TH_ACK) {
+ if (tiflags & TH_SYN) {
+ tcpstat.tcps_badsyn++;
+ goto dropwithreset;
+ }
+ if (SEQ_LEQ(th->th_ack, tp->snd_una) ||
+ SEQ_GT(th->th_ack, tp->snd_max))
+ goto dropwithreset;
+ }
+ break;
+
+ /*
+ * If the state is SYN_SENT:
+ * if seg contains an ACK, but not for our SYN, drop the input.
+ * if seg contains a RST, then drop the connection.
+ * if seg does not contain SYN, then drop it.
+ * Otherwise this is an acceptable SYN segment
+ * initialize tp->rcv_nxt and tp->irs
+ * if seg contains ack then advance tp->snd_una
+ * if SYN has been acked change to ESTABLISHED else SYN_RCVD state
+ * arrange for segment to be acked (eventually)
+ * continue processing rest of data/controls, beginning with URG
+ */
+ case TCPS_SYN_SENT:
+ if ((tiflags & TH_ACK) &&
+ (SEQ_LEQ(th->th_ack, tp->iss) ||
+ SEQ_GT(th->th_ack, tp->snd_max)))
+ goto dropwithreset;
+ if (tiflags & TH_RST) {
+ if (tiflags & TH_ACK)
+ tp = tcp_drop(tp, ECONNREFUSED);
+ goto drop;
+ }
+ if ((tiflags & TH_SYN) == 0)
+ goto drop;
+ if (tiflags & TH_ACK) {
+ tp->snd_una = th->th_ack;
+ if (SEQ_LT(tp->snd_nxt, tp->snd_una))
+ tp->snd_nxt = tp->snd_una;
+ }
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->irs = th->th_seq;
+ tcp_rcvseqinit(tp);
+ tp->t_flags |= TF_ACKNOW;
+#ifdef TCP_SACK
+ /*
+ * If we've sent a SACK_PERMITTED option, and the peer
+ * also replied with one, then TF_SACK_PERMIT should have
+ * been set in tcp_dooptions(). If it was not, disable SACKs.
+ */
+ if (!tp->sack_disable)
+ if ((tp->t_flags & TF_SACK_PERMIT) == 0)
+ tp->sack_disable = 1;
+#endif
+ if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
+ tcpstat.tcps_connects++;
+ soisconnected(so);
+ tp->t_state = TCPS_ESTABLISHED;
+ /* Do window scaling on this connection? */
+ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
+ (TF_RCVD_SCALE|TF_REQ_SCALE)) {
+ tp->snd_scale = tp->requested_s_scale;
+ tp->rcv_scale = tp->request_r_scale;
+ }
+ (void) tcp_reass(tp, (struct tcphdr *)0,
+ (struct mbuf *)0, &tlen);
+ /*
+ * if we didn't have to retransmit the SYN,
+ * use its rtt as our initial srtt & rtt var.
+ */
+ if (tp->t_rtt)
+ tcp_xmit_timer(tp, tp->t_rtt);
+ /*
+ * Since new data was acked (the SYN), open the
+ * congestion window by one MSS. We do this
+ * here, because we won't go through the normal
+ * ACK processing below. And since this is the
+ * start of the connection, we know we are in
+ * the exponential phase of slow-start.
+ */
+ tp->snd_cwnd += tp->t_maxseg;
+ } else
+ tp->t_state = TCPS_SYN_RECEIVED;
+
+trimthenstep6:
+ /*
+ * Advance ti->ti_seq to correspond to first data byte.
+ * If data, trim to stay within window,
+ * dropping FIN if necessary.
+ */
+ th->th_seq++;
+ if (tlen > tp->rcv_wnd) {
+ todrop = tlen - tp->rcv_wnd;
+ m_adj(m, -todrop);
+ tlen = tp->rcv_wnd;
+ tiflags &= ~TH_FIN;
+ tcpstat.tcps_rcvpackafterwin++;
+ tcpstat.tcps_rcvbyteafterwin += todrop;
+ }
+ tp->snd_wl1 = th->th_seq - 1;
+ tp->rcv_up = th->th_seq;
+ goto step6;
+ }
+
+ /*
+ * States other than LISTEN or SYN_SENT.
+ * First check timestamp, if present.
+ * Then check that at least some bytes of segment are within
+ * receive window. If segment begins before rcv_nxt,
+ * drop leading data (and SYN); if nothing left, just ack.
+ *
+ * RFC 1323 PAWS: If we have a timestamp reply on this segment
+ * and it's less than ts_recent, drop it.
+ */
+ if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent &&
+ TSTMP_LT(ts_val, tp->ts_recent)) {
+
+ /* Check to see if ts_recent is over 24 days old. */
+ if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
+ /*
+ * Invalidate ts_recent. If this segment updates
+ * ts_recent, the age will be reset later and ts_recent
+ * will get a valid value. If it does not, setting
+ * ts_recent to zero will at least satisfy the
+ * requirement that zero be placed in the timestamp
+ * echo reply when ts_recent isn't valid. The
+ * age isn't reset until we get a valid ts_recent
+ * because we don't want out-of-order segments to be
+ * dropped when ts_recent is old.
+ */
+ tp->ts_recent = 0;
+ } else {
+ tcpstat.tcps_rcvduppack++;
+ tcpstat.tcps_rcvdupbyte += tlen;
+ tcpstat.tcps_pawsdrop++;
+ goto dropafterack;
+ }
+ }
+
+ todrop = tp->rcv_nxt - th->th_seq;
+ if (todrop > 0) {
+ if (tiflags & TH_SYN) {
+ tiflags &= ~TH_SYN;
+ th->th_seq++;
+ if (th->th_urp > 1)
+ th->th_urp--;
+ else
+ tiflags &= ~TH_URG;
+ todrop--;
+ }
+ if (todrop >= tlen ||
+ (todrop == tlen && (tiflags & TH_FIN) == 0)) {
+ /*
+ * Any valid FIN must be to the left of the
+ * window. At this point, FIN must be a
+ * duplicate or out-of-sequence, so drop it.
+ */
+ tiflags &= ~TH_FIN;
+ /*
+ * Send ACK to resynchronize, and drop any data,
+ * but keep on processing for RST or ACK.
+ */
+ tp->t_flags |= TF_ACKNOW;
+ tcpstat.tcps_rcvdupbyte += todrop = tlen;
+ tcpstat.tcps_rcvduppack++;
+ } else {
+ tcpstat.tcps_rcvpartduppack++;
+ tcpstat.tcps_rcvpartdupbyte += todrop;
+ }
+ hdroptlen += todrop; /* drop from head afterwards */
+ th->th_seq += todrop;
+ tlen -= todrop;
+ if (th->th_urp > todrop)
+ th->th_urp -= todrop;
+ else {
+ tiflags &= ~TH_URG;
+ th->th_urp = 0;
+ }
+ }
+
+ /*
+ * If new data are received on a connection after the
+ * user processes are gone, then RST the other end.
+ */
+ if ((so->so_state & SS_NOFDREF) &&
+ tp->t_state > TCPS_CLOSE_WAIT && tlen) {
+ tp = tcp_close(tp);
+ tcpstat.tcps_rcvafterclose++;
+ goto dropwithreset;
+ }
+
+ /*
+ * If segment ends after window, drop trailing data
+ * (and PUSH and FIN); if nothing left, just ACK.
+ */
+ todrop = (th->th_seq + tlen) - (tp->rcv_nxt+tp->rcv_wnd);
+ if (todrop > 0) {
+ tcpstat.tcps_rcvpackafterwin++;
+ if (todrop >= tlen) {
+ tcpstat.tcps_rcvbyteafterwin += tlen;
+ /*
+ * If a new connection request is received
+ * while in TIME_WAIT, drop the old connection
+ * and start over if the sequence numbers
+ * are above the previous ones.
+ */
+ if (tiflags & TH_SYN &&
+ tp->t_state == TCPS_TIME_WAIT &&
+ SEQ_GT(th->th_seq, tp->rcv_nxt)) {
+ iss = tp->snd_nxt + TCP_ISSINCR;
+ tp = tcp_close(tp);
+ goto findpcb;
+ }
+ /*
+ * If window is closed can only take segments at
+ * window edge, and have to drop data and PUSH from
+ * incoming segments. Continue processing, but
+ * remember to ack. Otherwise, drop segment
+ * and ack.
+ */
+ if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) {
+ tp->t_flags |= TF_ACKNOW;
+ tcpstat.tcps_rcvwinprobe++;
+ } else
+ goto dropafterack;
+ } else
+ tcpstat.tcps_rcvbyteafterwin += todrop;
+ m_adj(m, -todrop);
+ tlen -= todrop;
+ tiflags &= ~(TH_PUSH|TH_FIN);
+ }
+
+ /*
+ * If last ACK falls within this segment's sequence numbers,
+ * record its timestamp.
+ * Fix from Braden, see Stevens p. 870
+ */
+ if (ts_present && TSTMP_GEQ(ts_val, tp->ts_recent) &&
+ SEQ_LEQ(th->th_seq, tp->last_ack_sent)) {
+ tp->ts_recent_age = tcp_now;
+ tp->ts_recent = ts_val;
+ }
+
+ /*
+ * If the RST bit is set examine the state:
+ * SYN_RECEIVED STATE:
+ * If passive open, return to LISTEN state.
+ * If active open, inform user that connection was refused.
+ * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
+ * Inform user that connection was reset, and close tcb.
+ * CLOSING, LAST_ACK, TIME_WAIT STATES
+ * Close the tcb.
+ */
+ if (tiflags & TH_RST) {
+#ifndef INET6
+ if (ti->ti_seq != tp->last_ack_sent)
+#else
+ if (th->th_seq != tp->last_ack_sent)
+#endif
+ goto drop;
+
+ switch (tp->t_state) {
+ case TCPS_SYN_RECEIVED:
+ so->so_error = ECONNREFUSED;
+ goto close;
+
+ case TCPS_ESTABLISHED:
+ case TCPS_FIN_WAIT_1:
+ case TCPS_FIN_WAIT_2:
+ case TCPS_CLOSE_WAIT:
+ so->so_error = ECONNRESET;
+ close:
+ tp->t_state = TCPS_CLOSED;
+ tcpstat.tcps_drops++;
+ tp = tcp_close(tp);
+ goto drop;
+ case TCPS_CLOSING:
+ case TCPS_LAST_ACK:
+ case TCPS_TIME_WAIT:
+ tp = tcp_close(tp);
+ goto drop;
+ }
+ }
+
+ /*
+ * If a SYN is in the window, then this is an
+ * error and we send an RST and drop the connection.
+ */
+ if (tiflags & TH_SYN) {
+ tp = tcp_drop(tp, ECONNRESET);
+ goto dropwithreset;
+ }
+
+ /*
+ * If the ACK bit is off we drop the segment and return.
+ */
+ if ((tiflags & TH_ACK) == 0) {
+ if (tp->t_flags & TF_ACKNOW)
+ goto dropafterack;
+ else
+ goto drop;
+ }
+
+ /*
+ * Ack processing.
+ */
+ switch (tp->t_state) {
+
+ /*
+ * In SYN_RECEIVED state, the ack ACKs our SYN, so enter
+ * ESTABLISHED state and continue processing.
+ * The ACK was checked above.
+ */
+ case TCPS_SYN_RECEIVED:
+ tcpstat.tcps_connects++;
+ soisconnected(so);
+ tp->t_state = TCPS_ESTABLISHED;
+ /* Do window scaling? */
+ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
+ (TF_RCVD_SCALE|TF_REQ_SCALE)) {
+ tp->snd_scale = tp->requested_s_scale;
+ tp->rcv_scale = tp->request_r_scale;
+ }
+ (void) tcp_reass(tp, (struct tcphdr *)0, (struct mbuf *)0,
+ &tlen);
+ tp->snd_wl1 = th->th_seq - 1;
+ /* fall into ... */
+
+ /*
+ * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
+ * ACKs. If the ack is in the range
+ * tp->snd_una < ti->ti_ack <= tp->snd_max
+ * then advance tp->snd_una to ti->ti_ack and drop
+ * data from the retransmission queue. If this ACK reflects
+ * more up to date window information we update our window information.
+ */
+ case TCPS_ESTABLISHED:
+ case TCPS_FIN_WAIT_1:
+ case TCPS_FIN_WAIT_2:
+ case TCPS_CLOSE_WAIT:
+ case TCPS_CLOSING:
+ case TCPS_LAST_ACK:
+ case TCPS_TIME_WAIT:
+ if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
+ /*
+ * Duplicate/old ACK processing.
+ * Increments t_dupacks:
+ * Pure duplicate (same seq/ack/window, no data)
+ * Doesn't affect t_dupacks:
+ * Data packets.
+ * Normal window updates (window opens)
+ * Resets t_dupacks:
+ * New data ACKed.
+ * Window shrinks
+ * Old ACK
+ */
+ if (tlen)
+ break;
+ /*
+ * If we get an old ACK, there is probably packet
+ * reordering going on. Be conservative and reset
+ * t_dupacks so that we are less agressive in
+ * doing a fast retransmit.
+ */
+ if (th->th_ack != tp->snd_una) {
+ tp->t_dupacks = 0;
+ break;
+ }
+ if (tiwin == tp->snd_wnd) {
+ tcpstat.tcps_rcvdupack++;
+ /*
+ * If we have outstanding data (other than
+ * a window probe), this is a completely
+ * duplicate ack (ie, window info didn't
+ * change), the ack is the biggest we've
+ * seen and we've seen exactly our rexmt
+ * threshhold of them, assume a packet
+ * has been dropped and retransmit it.
+ * Kludge snd_nxt & the congestion
+ * window so we send only this one
+ * packet.
+ *
+ * We know we're losing at the current
+ * window size so do congestion avoidance
+ * (set ssthresh to half the current window
+ * and pull our congestion window back to
+ * the new ssthresh).
+ *
+ * Dup acks mean that packets have left the
+ * network (they're now cached at the receiver)
+ * so bump cwnd by the amount in the receiver
+ * to keep a constant cwnd packets in the
+ * network.
+ */
+ if (tp->t_timer[TCPT_REXMT] == 0)
+ tp->t_dupacks = 0;
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /*
+ * In FACK, can enter fast rec. if the receiver
+ * reports a reass. queue longer than 3 segs.
+ */
+ else if (++tp->t_dupacks == tcprexmtthresh ||
+ ((SEQ_GT(tp->snd_fack, tcprexmtthresh *
+ tp->t_maxseg + tp->snd_una)) &&
+ SEQ_GT(tp->snd_una, tp->snd_last))) {
+#else
+ else if (++tp->t_dupacks == tcprexmtthresh) {
+#endif /* TCP_FACK */
+ tcp_seq onxt = tp->snd_nxt;
+ u_long win =
+ ulmin(tp->snd_wnd, tp->snd_cwnd) /
+ 2 / tp->t_maxseg;
+
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ if (SEQ_LT(th->th_ack, tp->snd_last)){
+ /*
+ * False fast retx after
+ * timeout. Do not cut window.
+ */
+ tp->snd_cwnd += tp->t_maxseg;
+ tp->t_dupacks = 0;
+ (void) tcp_output(tp);
+ goto drop;
+ }
+#endif
+ if (win < 2)
+ win = 2;
+ tp->snd_ssthresh = win * tp->t_maxseg;
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ tp->snd_last = tp->snd_max;
+#endif
+#ifdef TCP_SACK
+ if (!tp->sack_disable) {
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->t_rtt = 0;
+ tcpstat.tcps_sndrexmitfast++;
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ (void) tcp_output(tp);
+ /*
+ * During FR, snd_cwnd is held
+ * constant for FACK.
+ */
+ tp->snd_cwnd = tp->snd_ssthresh;
+ tp->t_dupacks = tcprexmtthresh;
+#else
+ /*
+ * tcp_output() will send
+ * oldest SACK-eligible rtx.
+ */
+ (void) tcp_output(tp);
+ tp->snd_cwnd = tp->snd_ssthresh+
+ tp->t_maxseg * tp->t_dupacks;
+#endif /* TCP_FACK */
+ goto drop;
+ }
+#endif /* TCP_SACK */
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->t_rtt = 0;
+ tp->snd_nxt = th->th_ack;
+ tp->snd_cwnd = tp->t_maxseg;
+ tcpstat.tcps_sndrexmitfast++;
+ (void) tcp_output(tp);
+
+ tp->snd_cwnd = tp->snd_ssthresh +
+ tp->t_maxseg * tp->t_dupacks;
+ if (SEQ_GT(onxt, tp->snd_nxt))
+ tp->snd_nxt = onxt;
+ goto drop;
+ } else if (tp->t_dupacks > tcprexmtthresh) {
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /*
+ * while (awnd < cwnd)
+ * sendsomething();
+ */
+ if (!tp->sack_disable) {
+ if (tp->snd_awnd < tp->snd_cwnd)
+ tcp_output(tp);
+ goto drop;
+ }
+#endif /* TCP_FACK */
+ tp->snd_cwnd += tp->t_maxseg;
+ (void) tcp_output(tp);
+ goto drop;
+ }
+ } else if (tiwin < tp->snd_wnd) {
+ /*
+ * The window was retracted! Previous dup
+ * ACKs may have been due to packets arriving
+ * after the shrunken window, not a missing
+ * packet, so play it safe and reset t_dupacks
+ */
+ tp->t_dupacks = 0;
+ }
+ break;
+ }
+ /*
+ * If the congestion window was inflated to account
+ * for the other side's cached packets, retract it.
+ */
+#ifdef TCP_NEWRENO
+ if (tp->t_dupacks >= tcprexmtthresh && !tcp_newreno(tp, th)) {
+ /* Out of fast recovery */
+ tp->snd_cwnd = tp->snd_ssthresh;
+ /*
+ * Window inflation should have left us with approx.
+ * snd_ssthresh outstanding data. But in case we
+ * would be inclined to send a burst, better to do
+ * it via the slow start mechanism.
+ */
+ if (tcp_seq_subtract(tp->snd_max, th->th_ack) <
+ tp->snd_ssthresh)
+ tp->snd_cwnd = tcp_seq_subtract(tp->snd_max,
+ th->th_ack) + tp->t_maxseg;
+ tp->t_dupacks = 0;
+ }
+#elif defined(TCP_SACK)
+ if (!tp->sack_disable) {
+ if (tp->t_dupacks >= tcprexmtthresh) {
+ /* Check for a partial ACK */
+ if (tcp_sack_partialack(tp, th)) {
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /* Force call to tcp_output */
+ if (tp->snd_awnd < tp->snd_cwnd)
+ needoutput = 1;
+#else
+ tp->snd_cwnd += tp->t_maxseg;
+ needoutput = 1;
+#endif /* TCP_FACK */
+ } else {
+ /* Out of fast recovery */
+ tp->snd_cwnd = tp->snd_ssthresh;
+ if (tcp_seq_subtract(tp->snd_max,
+ th->th_ack) < tp->snd_ssthresh)
+ tp->snd_cwnd =
+ tcp_seq_subtract(tp->snd_max,
+ th->th_ack) + tp->t_maxseg;
+ tp->t_dupacks = 0;
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ if (SEQ_GT(th->th_ack, tp->snd_fack))
+ tp->snd_fack = th->th_ack;
+#endif /* TCP_FACK */
+ }
+ }
+ } else {
+ if (tp->t_dupacks >= tcprexmtthresh &&
+ !tcp_newreno(tp, th)) {
+ /* Out of fast recovery */
+ tp->snd_cwnd = tp->snd_ssthresh;
+ if (tcp_seq_subtract(tp->snd_max, th->th_ack) <
+ tp->snd_ssthresh)
+ tp->snd_cwnd =
+ tcp_seq_subtract(tp->snd_max,
+ th->th_ack) + tp->t_maxseg;
+ tp->t_dupacks = 0;
+ }
+ }
+#else /* else neither TCP_NEWRENO nor TCP_SACK */
+ if (tp->t_dupacks >= tcprexmtthresh &&
+ tp->snd_cwnd > tp->snd_ssthresh)
+ tp->snd_cwnd = tp->snd_ssthresh;
+ tp->t_dupacks = 0;
+#endif
+ if (SEQ_GT(th->th_ack, tp->snd_max)) {
+ tcpstat.tcps_rcvacktoomuch++;
+ goto dropafterack;
+ }
+ acked = th->th_ack - tp->snd_una;
+ tcpstat.tcps_rcvackpack++;
+ tcpstat.tcps_rcvackbyte += acked;
+
+ /*
+ * If we have a timestamp reply, update smoothed
+ * round trip time. If no timestamp is present but
+ * transmit timer is running and timed sequence
+ * number was acked, update smoothed round trip time.
+ * Since we now have an rtt measurement, cancel the
+ * timer backoff (cf., Phil Karn's retransmit alg.).
+ * Recompute the initial retransmit timer.
+ */
+ if (ts_present)
+ tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
+ else if (tp->t_rtt && SEQ_GT(th->th_ack, tp->t_rtseq))
+ tcp_xmit_timer(tp,tp->t_rtt);
+
+ /*
+ * If all outstanding data is acked, stop retransmit
+ * timer and remember to restart (more output or persist).
+ * If there is more data to be acked, restart retransmit
+ * timer, using current (possibly backed-off) value.
+ */
+ if (th->th_ack == tp->snd_max) {
+ tp->t_timer[TCPT_REXMT] = 0;
+ needoutput = 1;
+ } else if (tp->t_timer[TCPT_PERSIST] == 0)
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ /*
+ * When new data is acked, open the congestion window.
+ * If the window gives us less than ssthresh packets
+ * in flight, open exponentially (maxseg per packet).
+ * Otherwise open linearly: maxseg per window
+ * (maxseg^2 / cwnd per packet).
+ */
+ {
+ register u_int cw = tp->snd_cwnd;
+ register u_int incr = tp->t_maxseg;
+
+ if (cw > tp->snd_ssthresh)
+ incr = incr * incr / cw;
+#if defined (TCP_NEWRENO) || defined (TCP_SACK)
+ if (SEQ_GEQ(th->th_ack, tp->snd_last))
+#endif
+ tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale);
+ }
+ ND6_HINT(tp);
+ if (acked > so->so_snd.sb_cc) {
+ tp->snd_wnd -= so->so_snd.sb_cc;
+ sbdrop(&so->so_snd, (int)so->so_snd.sb_cc);
+ ourfinisacked = 1;
+ } else {
+ sbdrop(&so->so_snd, acked);
+ tp->snd_wnd -= acked;
+ ourfinisacked = 0;
+ }
+ if (sb_notify(&so->so_snd))
+ sowwakeup(so);
+ tp->snd_una = th->th_ack;
+ if (SEQ_LT(tp->snd_nxt, tp->snd_una))
+ tp->snd_nxt = tp->snd_una;
+#if defined (TCP_SACK) && defined (TCP_FACK)
+ if (SEQ_GT(tp->snd_una, tp->snd_fack))
+ tp->snd_fack = tp->snd_una;
+#endif
+
+ switch (tp->t_state) {
+
+ /*
+ * In FIN_WAIT_1 STATE in addition to the processing
+ * for the ESTABLISHED state if our FIN is now acknowledged
+ * then enter FIN_WAIT_2.
+ */
+ case TCPS_FIN_WAIT_1:
+ if (ourfinisacked) {
+ /*
+ * If we can't receive any more
+ * data, then closing user can proceed.
+ * Starting the timer is contrary to the
+ * specification, but if we don't get a FIN
+ * we'll hang forever.
+ */
+ if (so->so_state & SS_CANTRCVMORE) {
+ soisdisconnected(so);
+ tp->t_timer[TCPT_2MSL] = tcp_maxidle;
+ }
+ tp->t_state = TCPS_FIN_WAIT_2;
+ }
+ break;
+
+ /*
+ * In CLOSING STATE in addition to the processing for
+ * the ESTABLISHED state if the ACK acknowledges our FIN
+ * then enter the TIME-WAIT state, otherwise ignore
+ * the segment.
+ */
+ case TCPS_CLOSING:
+ if (ourfinisacked) {
+ tp->t_state = TCPS_TIME_WAIT;
+ tcp_canceltimers(tp);
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ soisdisconnected(so);
+ }
+ break;
+
+ /*
+ * In LAST_ACK, we may still be waiting for data to drain
+ * and/or to be acked, as well as for the ack of our FIN.
+ * If our FIN is now acknowledged, delete the TCB,
+ * enter the closed state and return.
+ */
+ case TCPS_LAST_ACK:
+ if (ourfinisacked) {
+ tp = tcp_close(tp);
+ goto drop;
+ }
+ break;
+
+ /*
+ * In TIME_WAIT state the only thing that should arrive
+ * is a retransmission of the remote FIN. Acknowledge
+ * it and restart the finack timer.
+ */
+ case TCPS_TIME_WAIT:
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ goto dropafterack;
+ }
+ }
+
+step6:
+ /*
+ * Update window information.
+ * Don't look at window if no ACK: TAC's send garbage on first SYN.
+ */
+ if ((tiflags & TH_ACK) && (SEQ_LT(tp->snd_wl1, th->th_seq) ||
+ (tp->snd_wl1 == th->th_seq && SEQ_LT(tp->snd_wl2, th->th_ack)) ||
+ (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))) {
+ /* keep track of pure window updates */
+ if (tlen == 0 &&
+ tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
+ tcpstat.tcps_rcvwinupd++;
+ tp->snd_wnd = tiwin;
+ tp->snd_wl1 = th->th_seq;
+ tp->snd_wl2 = th->th_ack;
+ if (tp->snd_wnd > tp->max_sndwnd)
+ tp->max_sndwnd = tp->snd_wnd;
+ needoutput = 1;
+ }
+
+ /*
+ * Process segments with URG.
+ */
+ if ((tiflags & TH_URG) && th->th_urp &&
+ TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+ /*
+ * This is a kludge, but if we receive and accept
+ * random urgent pointers, we'll crash in
+ * soreceive. It's hard to imagine someone
+ * actually wanting to send this much urgent data.
+ */
+ if (th->th_urp + so->so_rcv.sb_cc > sb_max) {
+ th->th_urp = 0; /* XXX */
+ tiflags &= ~TH_URG; /* XXX */
+ goto dodata; /* XXX */
+ }
+ /*
+ * If this segment advances the known urgent pointer,
+ * then mark the data stream. This should not happen
+ * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
+ * a FIN has been received from the remote side.
+ * In these states we ignore the URG.
+ *
+ * According to RFC961 (Assigned Protocols),
+ * the urgent pointer points to the last octet
+ * of urgent data. We continue, however,
+ * to consider it to indicate the first octet
+ * of data past the urgent section as the original
+ * spec states (in one of two places).
+ */
+ if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) {
+ tp->rcv_up = th->th_seq + th->th_urp;
+ so->so_oobmark = so->so_rcv.sb_cc +
+ (tp->rcv_up - tp->rcv_nxt) - 1;
+ if (so->so_oobmark == 0)
+ so->so_state |= SS_RCVATMARK;
+ sohasoutofband(so);
+ tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA);
+ }
+ /*
+ * Remove out of band data so doesn't get presented to user.
+ * This can happen independent of advancing the URG pointer,
+ * but if two URG's are pending at once, some out-of-band
+ * data may creep in... ick.
+ */
+ if (th->th_urp <= (u_int16_t) tlen
+#ifdef SO_OOBINLINE
+ && (so->so_options & SO_OOBINLINE) == 0
+#endif
+ )
+ tcp_pulloutofband(so, th->th_urp, m, hdroptlen);
+ } else
+ /*
+ * If no out of band data is expected,
+ * pull receive urgent pointer along
+ * with the receive window.
+ */
+ if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
+ tp->rcv_up = tp->rcv_nxt;
+dodata: /* XXX */
+
+ /*
+ * Process the segment text, merging it into the TCP sequencing queue,
+ * and arranging for acknowledgment of receipt if necessary.
+ * This process logically involves adjusting tp->rcv_wnd as data
+ * is presented to the user (this happens in tcp_usrreq.c,
+ * case PRU_RCVD). If a FIN has already been received on this
+ * connection then we just ignore the text.
+ */
+ if ((tlen || (tiflags & TH_FIN)) &&
+ TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+ if (th->th_seq == tp->rcv_nxt && tp->segq.lh_first == NULL &&
+ tp->t_state == TCPS_ESTABLISHED) {
+ if (th->th_flags & TH_PUSH)
+ tp->t_flags |= TF_ACKNOW;
+ else
+ tp->t_flags |= TF_DELACK;
+ tp->rcv_nxt += tlen;
+ tiflags = th->th_flags & TH_FIN;
+ tcpstat.tcps_rcvpack++;
+ tcpstat.tcps_rcvbyte += tlen;
+ ND6_HINT(tp);
+ m_adj(m, hdroptlen);
+ sbappend(&so->so_rcv, m);
+ sorwakeup(so);
+ } else {
+ m_adj(m, hdroptlen);
+ tiflags = tcp_reass(tp, th, m, &tlen);
+ tp->t_flags |= TF_ACKNOW;
+ }
+#ifdef TCP_SACK
+ if (!tp->sack_disable)
+ tcp_update_sack_list(tp);
+#endif
+
+ /*
+ * variable len never referenced again in modern BSD,
+ * so why bother computing it ??
+ */
+#if 0
+ /*
+ * Note the amount of data that peer has sent into
+ * our window, in order to estimate the sender's
+ * buffer size.
+ */
+ len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt);
+#endif /* 0 */
+ } else {
+ m_freem(m);
+ tiflags &= ~TH_FIN;
+ }
+
+ /*
+ * If FIN is received ACK the FIN and let the user know
+ * that the connection is closing. Ignore a FIN received before
+ * the connection is fully established.
+ */
+ if ((tiflags & TH_FIN) && TCPS_HAVEESTABLISHED(tp->t_state)) {
+ if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+ socantrcvmore(so);
+ tp->t_flags |= TF_ACKNOW;
+ tp->rcv_nxt++;
+ }
+ switch (tp->t_state) {
+
+ /*
+ * In ESTABLISHED STATE enter the CLOSE_WAIT state.
+ */
+ case TCPS_ESTABLISHED:
+ tp->t_state = TCPS_CLOSE_WAIT;
+ break;
+
+ /*
+ * If still in FIN_WAIT_1 STATE FIN has not been acked so
+ * enter the CLOSING state.
+ */
+ case TCPS_FIN_WAIT_1:
+ tp->t_state = TCPS_CLOSING;
+ break;
+
+ /*
+ * In FIN_WAIT_2 state enter the TIME_WAIT state,
+ * starting the time-wait timer, turning off the other
+ * standard timers.
+ */
+ case TCPS_FIN_WAIT_2:
+ tp->t_state = TCPS_TIME_WAIT;
+ tcp_canceltimers(tp);
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ soisdisconnected(so);
+ break;
+
+ /*
+ * In TIME_WAIT state restart the 2 MSL time_wait timer.
+ */
+ case TCPS_TIME_WAIT:
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ break;
+ }
+ }
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG) {
+#ifdef INET6
+ if (tp->pf == PF_INET6)
+ tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti6, 0, tlen);
+ else
+#endif /* INET6 */
+ tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti, 0, tlen);
+ }
+#endif /* TCPDEBUG */
+
+ /*
+ * Return any desired output.
+ */
+ if (needoutput || (tp->t_flags & TF_ACKNOW)) {
+ (void) tcp_output(tp);
+ }
+ return;
+
+dropafterack:
+ /*
+ * Generate an ACK dropping incoming segment if it occupies
+ * sequence space, where the ACK reflects our state.
+ */
+ if (tiflags & TH_RST)
+ goto drop;
+ m_freem(m);
+ tp->t_flags |= TF_ACKNOW;
+ (void) tcp_output(tp);
+ return;
+
+dropwithreset:
+ /*
+ * Generate a RST, dropping incoming segment.
+ * Make ACK acceptable to originator of segment.
+ * Don't bother to respond if destination was broadcast/multicast.
+ */
+ if ((tiflags & TH_RST) || m->m_flags & (M_BCAST|M_MCAST))
+ goto drop;
+#ifdef INET6
+ if (is_ipv6) {
+ /* For following calls to tcp_respond */
+ ti = mtod(m, struct tcpiphdr *);
+ if (IN6_IS_ADDR_MULTICAST(&ipv6->ip6_dst))
+ goto drop;
+ } else {
+#endif /* INET6 */
+ if (IN_MULTICAST(ti->ti_dst.s_addr))
+ goto drop;
+#ifdef INET6
+ }
+#endif /* INET6 */
+ if (tiflags & TH_ACK)
+ tcp_respond(tp, (caddr_t) ti, m, (tcp_seq)0, th->th_ack, TH_RST);
+ else {
+ if (tiflags & TH_SYN)
+ tlen++;
+ tcp_respond(tp, (caddr_t) ti, m, th->th_seq+tlen, (tcp_seq)0,
+ TH_RST|TH_ACK);
+ }
+ /* destroy temporarily created socket */
+ if (dropsocket)
+ (void) soabort(so);
+ return;
+
+drop:
+ /*
+ * Drop space held by incoming segment and return.
+ */
+#ifdef TCPDEBUG
+ if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) {
+#ifdef INET6
+ if (tp->pf == PF_INET6)
+ tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti6, 0, tlen);
+ else
+#endif /* INET6 */
+ tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti, 0, tlen);
+ }
+#endif /* TCPDEBUG */
+
+ m_freem(m);
+ /* destroy temporarily created socket */
+ if (dropsocket)
+ (void) soabort(so);
+ return;
+#ifndef TUBA_INCLUDE
+}
+
+void
+tcp_dooptions(tp, cp, cnt, th, ts_present, ts_val, ts_ecr)
+ struct tcpcb *tp;
+ u_char *cp;
+ int cnt;
+ struct tcphdr *th;
+ int *ts_present;
+ u_int32_t *ts_val, *ts_ecr;
+{
+ u_int16_t mss = 0;
+ int opt, optlen;
+
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ if (opt == TCPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[1];
+ if (optlen <= 0)
+ break;
+ }
+ switch (opt) {
+
+ default:
+ continue;
+
+ case TCPOPT_MAXSEG:
+ if (optlen != TCPOLEN_MAXSEG)
+ continue;
+ if (!(th->th_flags & TH_SYN))
+ continue;
+ bcopy((char *) cp + 2, (char *) &mss, sizeof(mss));
+ NTOHS(mss);
+ break;
+
+ case TCPOPT_WINDOW:
+ if (optlen != TCPOLEN_WINDOW)
+ continue;
+ if (!(th->th_flags & TH_SYN))
+ continue;
+ tp->t_flags |= TF_RCVD_SCALE;
+ tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT);
+ break;
+
+ case TCPOPT_TIMESTAMP:
+ if (optlen != TCPOLEN_TIMESTAMP)
+ continue;
+ *ts_present = 1;
+ bcopy((char *)cp + 2, (char *) ts_val, sizeof(*ts_val));
+ NTOHL(*ts_val);
+ bcopy((char *)cp + 6, (char *) ts_ecr, sizeof(*ts_ecr));
+ NTOHL(*ts_ecr);
+
+ /*
+ * A timestamp received in a SYN makes
+ * it ok to send timestamp requests and replies.
+ */
+ if (th->th_flags & TH_SYN) {
+ tp->t_flags |= TF_RCVD_TSTMP;
+ tp->ts_recent = *ts_val;
+ tp->ts_recent_age = tcp_now;
+ }
+ break;
+
+#ifdef TCP_SACK
+ case TCPOPT_SACK_PERMITTED:
+ if (tp->sack_disable || optlen!=TCPOLEN_SACK_PERMITTED)
+ continue;
+ if (th->th_flags & TH_SYN)
+ /* MUST only be set on SYN */
+ tp->t_flags |= TF_SACK_PERMIT;
+ break;
+ case TCPOPT_SACK:
+ if (tcp_sack_option(tp, th, cp, optlen))
+ continue;
+ break;
+#endif
+ }
+ }
+ /* Update t_maxopd and t_maxseg after all options are processed */
+ if (th->th_flags & TH_SYN)
+ (void) tcp_mss(tp, mss); /* sets t_maxseg */
+}
+
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+u_long
+tcp_seq_subtract(a, b)
+ u_long a, b;
+{
+ return ((long)(a - b));
+}
+#endif
+
+
+#ifdef TCP_SACK
+/*
+ * This function is called upon receipt of new valid data (while not in header
+ * prediction mode), and it updates the ordered list of sacks.
+ */
+void
+tcp_update_sack_list(tp)
+ struct tcpcb *tp;
+{
+ /*
+ * First reported block MUST be the most recent one. Subsequent
+ * blocks SHOULD be in the order in which they arrived at the
+ * receiver. These two conditions make the implementation fully
+ * compliant with RFC 2018.
+ */
+ int i, j = 0, count = 0, lastpos = -1;
+ struct sackblk sack, firstsack, temp[MAX_SACK_BLKS];
+
+ /* First clean up current list of sacks */
+ for (i = 0; i < tp->rcv_numsacks; i++) {
+ sack = tp->sackblks[i];
+ if (sack.start == 0 && sack.end == 0) {
+ count++; /* count = number of blocks to be discarded */
+ continue;
+ }
+ if (SEQ_LEQ(sack.end, tp->rcv_nxt)) {
+ tp->sackblks[i].start = tp->sackblks[i].end = 0;
+ count++;
+ } else {
+ temp[j].start = tp->sackblks[i].start;
+ temp[j++].end = tp->sackblks[i].end;
+ }
+ }
+ tp->rcv_numsacks -= count;
+ if (tp->rcv_numsacks == 0) { /* no sack blocks currently (fast path) */
+ tcp_clean_sackreport(tp);
+ if (SEQ_LT(tp->rcv_nxt, tp->rcv_laststart)) {
+ /* ==> need first sack block */
+ tp->sackblks[0].start = tp->rcv_laststart;
+ tp->sackblks[0].end = tp->rcv_lastend;
+ tp->rcv_numsacks = 1;
+ }
+ return;
+ }
+ /* Otherwise, sack blocks are already present. */
+ for (i = 0; i < tp->rcv_numsacks; i++)
+ tp->sackblks[i] = temp[i]; /* first copy back sack list */
+ if (SEQ_GEQ(tp->rcv_nxt, tp->rcv_lastend))
+ return; /* sack list remains unchanged */
+ /*
+ * From here, segment just received should be (part of) the 1st sack.
+ * Go through list, possibly coalescing sack block entries.
+ */
+ firstsack.start = tp->rcv_laststart;
+ firstsack.end = tp->rcv_lastend;
+ for (i = 0; i < tp->rcv_numsacks; i++) {
+ sack = tp->sackblks[i];
+ if (SEQ_LT(sack.end, firstsack.start) ||
+ SEQ_GT(sack.start, firstsack.end))
+ continue; /* no overlap */
+ if (sack.start == firstsack.start && sack.end == firstsack.end){
+ /*
+ * identical block; delete it here since we will
+ * move it to the front of the list.
+ */
+ tp->sackblks[i].start = tp->sackblks[i].end = 0;
+ lastpos = i; /* last posn with a zero entry */
+ continue;
+ }
+ if (SEQ_LEQ(sack.start, firstsack.start))
+ firstsack.start = sack.start; /* merge blocks */
+ if (SEQ_GEQ(sack.end, firstsack.end))
+ firstsack.end = sack.end; /* merge blocks */
+ tp->sackblks[i].start = tp->sackblks[i].end = 0;
+ lastpos = i; /* last posn with a zero entry */
+ }
+ if (lastpos != -1) { /* at least one merge */
+ for (i = 0, j = 1; i < tp->rcv_numsacks; i++) {
+ sack = tp->sackblks[i];
+ if (sack.start == 0 && sack.end == 0)
+ continue;
+ temp[j++] = sack;
+ }
+ tp->rcv_numsacks = j; /* including first blk (added later) */
+ for (i = 1; i < tp->rcv_numsacks; i++) /* now copy back */
+ tp->sackblks[i] = temp[i];
+ } else { /* no merges -- shift sacks by 1 */
+ if (tp->rcv_numsacks < MAX_SACK_BLKS)
+ tp->rcv_numsacks++;
+ for (i = tp->rcv_numsacks-1; i > 0; i--)
+ tp->sackblks[i] = tp->sackblks[i-1];
+ }
+ tp->sackblks[0] = firstsack;
+ return;
+}
+
+/*
+ * Process the TCP SACK option. Returns 1 if tcp_dooptions() should continue,
+ * and 0 otherwise, if the option was fine. tp->snd_holes is an ordered list
+ * of holes (oldest to newest, in terms of the sequence space).
+ */
+int
+tcp_sack_option(tp, th, cp, optlen)
+ struct tcpcb *tp;
+ struct tcphdr *th;
+ u_char *cp;
+ int optlen;
+{
+ int tmp_olen;
+ u_char *tmp_cp;
+ struct sackhole *cur, *p, *temp;
+
+ if (tp->sack_disable)
+ return 1;
+
+ /* Note: TCPOLEN_SACK must be 2*sizeof(tcp_seq) */
+ if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0)
+ return 1;
+ tmp_cp = cp + 2;
+ tmp_olen = optlen - 2;
+ if (tp->snd_numholes < 0)
+ tp->snd_numholes = 0;
+ if (tp->t_maxseg == 0)
+ panic("tcp_sack_option"); /* Should never happen */
+ while (tmp_olen > 0) {
+ struct sackblk sack;
+
+ bcopy((char *) tmp_cp, (char *) &(sack.start), sizeof(tcp_seq));
+ NTOHL(sack.start);
+ bcopy((char *) tmp_cp + sizeof(tcp_seq),
+ (char *) &(sack.end), sizeof(tcp_seq));
+ NTOHL(sack.end);
+ tmp_olen -= TCPOLEN_SACK;
+ tmp_cp += TCPOLEN_SACK;
+ if (SEQ_LEQ(sack.end, sack.start))
+ continue; /* bad SACK fields */
+ if (SEQ_LEQ(sack.end, tp->snd_una))
+ continue; /* old block */
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /* Updates snd_fack. */
+ if (SEQ_GEQ(sack.end, tp->snd_fack))
+ tp->snd_fack = sack.end;
+#endif /* TCP_FACK */
+ if (SEQ_GT(th->th_ack, tp->snd_una)) {
+ if (SEQ_LT(sack.start, th->th_ack))
+ continue;
+ } else {
+ if (SEQ_LT(sack.start, tp->snd_una))
+ continue;
+ }
+ if (SEQ_GT(sack.end, tp->snd_max))
+ continue;
+ if (tp->snd_holes == 0) { /* first hole */
+ tp->snd_holes = (struct sackhole *)
+ malloc(sizeof(struct sackhole), M_PCB, M_NOWAIT);
+ if (tp->snd_holes == NULL) {
+ /* ENOBUFS, so ignore SACKed block for now*/
+ continue;
+ }
+ cur = tp->snd_holes;
+ cur->start = th->th_ack;
+ cur->end = sack.start;
+ cur->rxmit = cur->start;
+ cur->next = 0;
+ tp->snd_numholes = 1;
+ tp->rcv_lastsack = sack.end;
+ /*
+ * dups is at least one. If more data has been
+ * SACKed, it can be greater than one.
+ */
+ cur->dups = min(tcprexmtthresh,
+ ((sack.end - cur->end)/tp->t_maxseg));
+ if (cur->dups < 1)
+ cur->dups = 1;
+ continue; /* with next sack block */
+ }
+ /* Go thru list of holes: p = previous, cur = current */
+ p = cur = tp->snd_holes;
+ while (cur) {
+ if (SEQ_LEQ(sack.end, cur->start))
+ /* SACKs data before the current hole */
+ break; /* no use going through more holes */
+ if (SEQ_GEQ(sack.start, cur->end)) {
+ /* SACKs data beyond the current hole */
+ cur->dups++;
+ if ( ((sack.end - cur->end)/tp->t_maxseg) >=
+ tcprexmtthresh)
+ cur->dups = tcprexmtthresh;
+ p = cur;
+ cur = cur->next;
+ continue;
+ }
+ if (SEQ_LEQ(sack.start, cur->start)) {
+ /* Data acks at least the beginning of hole */
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ if (SEQ_GT(sack.end, cur->rxmit))
+ tp->retran_data -=
+ tcp_seq_subtract(cur->rxmit,
+ cur->start);
+ else
+ tp->retran_data -=
+ tcp_seq_subtract(sack.end,
+ cur->start);
+#endif /* TCP_FACK */
+ if (SEQ_GEQ(sack.end,cur->end)){
+ /* Acks entire hole, so delete hole */
+ if (p != cur) {
+ p->next = cur->next;
+ free(cur, M_PCB);
+ cur = p->next;
+ } else {
+ cur=cur->next;
+ free(p, M_PCB);
+ p = cur;
+ tp->snd_holes = p;
+ }
+ tp->snd_numholes--;
+ continue;
+ }
+ /* otherwise, move start of hole forward */
+ cur->start = sack.end;
+ cur->rxmit = max (cur->rxmit, cur->start);
+ p = cur;
+ cur = cur->next;
+ continue;
+ }
+ /* move end of hole backward */
+ if (SEQ_GEQ(sack.end, cur->end)) {
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ if (SEQ_GT(cur->rxmit, sack.start))
+ tp->retran_data -=
+ tcp_seq_subtract(cur->rxmit,
+ sack.start);
+#endif /* TCP_FACK */
+ cur->end = sack.start;
+ cur->rxmit = min (cur->rxmit, cur->end);
+ cur->dups++;
+ if ( ((sack.end - cur->end)/tp->t_maxseg) >=
+ tcprexmtthresh)
+ cur->dups = tcprexmtthresh;
+ p = cur;
+ cur = cur->next;
+ continue;
+ }
+ if (SEQ_LT(cur->start, sack.start) &&
+ SEQ_GT(cur->end, sack.end)) {
+ /*
+ * ACKs some data in middle of a hole; need to
+ * split current hole
+ */
+ temp = (struct sackhole *)malloc(sizeof(*temp),
+ M_PCB,M_NOWAIT);
+ if (temp == NULL)
+ continue; /* ENOBUFS */
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ if (SEQ_GT(cur->rxmit, sack.end))
+ tp->retran_data -=
+ tcp_seq_subtract(sack.end,
+ sack.start);
+ else if (SEQ_GT(cur->rxmit, sack.start))
+ tp->retran_data -=
+ tcp_seq_subtract(cur->rxmit,
+ sack.start);
+#endif /* TCP_FACK */
+ temp->next = cur->next;
+ temp->start = sack.end;
+ temp->end = cur->end;
+ temp->dups = cur->dups;
+ temp->rxmit = max (cur->rxmit, temp->start);
+ cur->end = sack.start;
+ cur->rxmit = min (cur->rxmit, cur->end);
+ cur->dups++;
+ if ( ((sack.end - cur->end)/tp->t_maxseg) >=
+ tcprexmtthresh)
+ cur->dups = tcprexmtthresh;
+ cur->next = temp;
+ p = temp;
+ cur = p->next;
+ tp->snd_numholes++;
+ }
+ }
+ /* At this point, p points to the last hole on the list */
+ if (SEQ_LT(tp->rcv_lastsack, sack.start)) {
+ /*
+ * Need to append new hole at end.
+ * Last hole is p (and it's not NULL).
+ */
+ temp = (struct sackhole *) malloc(sizeof(*temp),
+ M_PCB, M_NOWAIT);
+ if (temp == NULL)
+ continue; /* ENOBUFS */
+ temp->start = tp->rcv_lastsack;
+ temp->end = sack.start;
+ temp->dups = min(tcprexmtthresh,
+ ((sack.end - sack.start)/tp->t_maxseg));
+ if (temp->dups < 1)
+ temp->dups = 1;
+ temp->rxmit = temp->start;
+ temp->next = 0;
+ p->next = temp;
+ tp->rcv_lastsack = sack.end;
+ tp->snd_numholes++;
+ }
+ }
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /*
+ * Update retran_data and snd_awnd. Go through the list of
+ * holes. Increment retran_data by (hole->rxmit - hole->start).
+ */
+ tp->retran_data = 0;
+ cur = tp->snd_holes;
+ while (cur) {
+ tp->retran_data += cur->rxmit - cur->start;
+ cur = cur->next;
+ }
+ tp->snd_awnd = tcp_seq_subtract(tp->snd_nxt, tp->snd_fack) +
+ tp->retran_data;
+#endif /* TCP_FACK */
+
+ return 0;
+}
+
+/*
+ * Delete stale (i.e, cumulatively ack'd) holes. Hole is deleted only if
+ * it is completely acked; otherwise, tcp_sack_option(), called from
+ * tcp_dooptions(), will fix up the hole.
+ */
+void
+tcp_del_sackholes(tp, th)
+ struct tcpcb *tp;
+ struct tcphdr *th;
+{
+ if (!tp->sack_disable && tp->t_state != TCPS_LISTEN) {
+ /* max because this could be an older ack just arrived */
+ tcp_seq lastack = SEQ_GT(th->th_ack, tp->snd_una) ?
+ th->th_ack : tp->snd_una;
+ struct sackhole *cur = tp->snd_holes;
+ struct sackhole *prev = cur;
+ while (cur)
+ if (SEQ_LEQ(cur->end, lastack)) {
+ cur = cur->next;
+ free(prev, M_PCB);
+ prev = cur;
+ tp->snd_numholes--;
+ } else if (SEQ_LT(cur->start, lastack)) {
+ cur->start = lastack;
+ break;
+ } else
+ break;
+ tp->snd_holes = cur;
+ }
+}
+
+/*
+ * Delete all receiver-side SACK information.
+ */
+void
+tcp_clean_sackreport(tp)
+ struct tcpcb *tp;
+{
+ int i;
+
+ tp->rcv_numsacks = 0;
+ for (i = 0; i < MAX_SACK_BLKS; i++)
+ tp->sackblks[i].start = tp->sackblks[i].end=0;
+
+}
+
+/*
+ * Checks for partial ack. If partial ack arrives, turn off retransmission
+ * timer, deflate the window, do not clear tp->t_dupacks, and return 1.
+ * If the ack advances at least to tp->snd_last, return 0.
+ */
+int
+tcp_sack_partialack(tp, th)
+ struct tcpcb *tp;
+ struct tcphdr *th;
+{
+ if (SEQ_LT(th->th_ack, tp->snd_last)) {
+ /* Turn off retx. timer (will start again next segment) */
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->t_rtt = 0;
+#ifndef TCP_FACK
+ /*
+ * Partial window deflation. This statement relies on the
+ * fact that tp->snd_una has not been updated yet. In FACK
+ * hold snd_cwnd constant during fast recovery.
+ */
+ tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
+#endif
+ return 1;
+ }
+ return 0;
+}
+#endif /* TCP_SACK */
+
+/*
+ * Pull out of band byte out of a segment so
+ * it doesn't appear in the user's data queue.
+ * It is still reflected in the segment length for
+ * sequencing purposes.
+ */
+void
+tcp_pulloutofband(so, urgent, m, off)
+ struct socket *so;
+ u_int urgent;
+ register struct mbuf *m;
+ int off;
+{
+ int cnt = off + urgent - 1;
+
+ while (cnt >= 0) {
+ if (m->m_len > cnt) {
+ char *cp = mtod(m, caddr_t) + cnt;
+ struct tcpcb *tp = sototcpcb(so);
+
+ tp->t_iobc = *cp;
+ tp->t_oobflags |= TCPOOB_HAVEDATA;
+ bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1));
+ m->m_len--;
+ return;
+ }
+ cnt -= m->m_len;
+ m = m->m_next;
+ if (m == 0)
+ break;
+ }
+ panic("tcp_pulloutofband");
+}
+
+/*
+ * Collect new round-trip time estimate
+ * and update averages and current timeout.
+ */
+void
+tcp_xmit_timer(tp, rtt)
+ register struct tcpcb *tp;
+ short rtt;
+{
+ register short delta;
+ short rttmin;
+
+ tcpstat.tcps_rttupdated++;
+ --rtt;
+ if (tp->t_srtt != 0) {
+ /*
+ * srtt is stored as fixed point with 3 bits after the
+ * binary point (i.e., scaled by 8). The following magic
+ * is equivalent to the smoothing algorithm in rfc793 with
+ * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed
+ * point). Adjust rtt to origin 0.
+ */
+ delta = (rtt << 2) - (tp->t_srtt >> TCP_RTT_SHIFT);
+ if ((tp->t_srtt += delta) <= 0)
+ tp->t_srtt = 1;
+ /*
+ * We accumulate a smoothed rtt variance (actually, a
+ * smoothed mean difference), then set the retransmit
+ * timer to smoothed rtt + 4 times the smoothed variance.
+ * rttvar is stored as fixed point with 2 bits after the
+ * binary point (scaled by 4). The following is
+ * equivalent to rfc793 smoothing with an alpha of .75
+ * (rttvar = rttvar*3/4 + |delta| / 4). This replaces
+ * rfc793's wired-in beta.
+ */
+ if (delta < 0)
+ delta = -delta;
+ delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT);
+ if ((tp->t_rttvar += delta) <= 0)
+ tp->t_rttvar = 1;
+ } else {
+ /*
+ * No rtt measurement yet - use the unsmoothed rtt.
+ * Set the variance to half the rtt (so our first
+ * retransmit happens at 3*rtt).
+ */
+ tp->t_srtt = rtt << (TCP_RTT_SHIFT + 2);
+ tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT + 2 - 1);
+ }
+ tp->t_rtt = 0;
+ tp->t_rxtshift = 0;
+
+ /*
+ * the retransmit should happen at rtt + 4 * rttvar.
+ * Because of the way we do the smoothing, srtt and rttvar
+ * will each average +1/2 tick of bias. When we compute
+ * the retransmit timer, we want 1/2 tick of rounding and
+ * 1 extra tick because of +-1/2 tick uncertainty in the
+ * firing of the timer. The bias will give us exactly the
+ * 1.5 tick we need. But, because the bias is
+ * statistical, we have to test that we don't drop below
+ * the minimum feasible timer (which is 2 ticks).
+ */
+ if (tp->t_rttmin > rtt + 2)
+ rttmin = tp->t_rttmin;
+ else
+ rttmin = rtt + 2;
+ TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), rttmin, TCPTV_REXMTMAX);
+
+ /*
+ * We received an ack for a packet that wasn't retransmitted;
+ * it is probably safe to discard any error indications we've
+ * received recently. This isn't quite right, but close enough
+ * for now (a route might have failed after we sent a segment,
+ * and the return path might not be symmetrical).
+ */
+ tp->t_softerror = 0;
+}
+
+/*
+ * Determine a reasonable value for maxseg size.
+ * If the route is known, check route for mtu.
+ * If none, use an mss that can be handled on the outgoing
+ * interface without forcing IP to fragment; if bigger than
+ * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES
+ * to utilize large mbufs. If no route is found, route has no mtu,
+ * or the destination isn't local, use a default, hopefully conservative
+ * size (usually 512 or the default IP max size, but no more than the mtu
+ * of the interface), as we can't discover anything about intervening
+ * gateways or networks. We also initialize the congestion/slow start
+ * window to be a single segment if the destination isn't local.
+ * While looking at the routing entry, we also initialize other path-dependent
+ * parameters from pre-set or cached values in the routing entry.
+ *
+ * Also take into account the space needed for options that we
+ * send regularly. Make maxseg shorter by that amount to assure
+ * that we can send maxseg amount of data even when the options
+ * are present. Store the upper limit of the length of options plus
+ * data in maxopd.
+ */
+int
+tcp_mss(tp, offer)
+ register struct tcpcb *tp;
+ u_int offer;
+{
+ struct route *ro;
+ register struct rtentry *rt;
+ struct ifnet *ifp;
+ register int rtt, mss;
+ u_long bufsize;
+ struct inpcb *inp;
+ struct socket *so;
+
+ inp = tp->t_inpcb;
+ ro = &inp->inp_route;
+ so = inp->inp_socket;
+
+ if ((rt = ro->ro_rt) == (struct rtentry *)0) {
+ /* No route yet, so try to acquire one */
+#ifdef INET6
+ /*
+ * Get a new IPv6 route if an IPv6 destination, otherwise, get
+ * and IPv4 route (including those pesky IPv4-mapped addresses).
+ */
+ bzero(ro,sizeof(struct route_in6));
+ if (sotopf(so) == AF_INET6) {
+ if (IN6_IS_ADDR_V4MAPPED(&inp->inp_faddr6)) {
+ /* Get an IPv4 route. */
+ ro->ro_dst.sa_family = AF_INET;
+ ro->ro_dst.sa_len = sizeof(ro->ro_dst);
+ ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
+ inp->inp_faddr;
+ rtalloc(ro);
+ } else {
+ ro->ro_dst.sa_family = AF_INET6;
+ ro->ro_dst.sa_len = sizeof(struct sockaddr_in6);
+ ((struct sockaddr_in6 *) &ro->ro_dst)->sin6_addr =
+ inp->inp_faddr6;
+ rtalloc(ro);
+ }
+ } else
+#endif /* INET6 */
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ ro->ro_dst.sa_family = AF_INET;
+ ro->ro_dst.sa_len = sizeof(ro->ro_dst);
+ satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr;
+ rtalloc(ro);
+ }
+ if ((rt = ro->ro_rt) == (struct rtentry *)0) {
+ tp->t_maxopd = tp->t_maxseg = tcp_mssdflt;
+ return (tcp_mssdflt);
+ }
+ }
+ ifp = rt->rt_ifp;
+
+#ifdef RTV_MTU /* if route characteristics exist ... */
+ /*
+ * While we're here, check if there's an initial rtt
+ * or rttvar. Convert from the route-table units
+ * to scaled multiples of the slow timeout timer.
+ */
+ if (tp->t_srtt == 0 && (rtt = rt->rt_rmx.rmx_rtt)) {
+ /*
+ * XXX the lock bit for MTU indicates that the value
+ * is also a minimum value; this is subject to time.
+ */
+ if (rt->rt_rmx.rmx_locks & RTV_RTT)
+ TCPT_RANGESET(tp->t_rttmin,
+ rtt / (RTM_RTTUNIT / PR_SLOWHZ),
+ TCPTV_MIN, TCPTV_REXMTMAX);
+ tp->t_srtt = rtt / (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
+ if (rt->rt_rmx.rmx_rttvar)
+ tp->t_rttvar = rt->rt_rmx.rmx_rttvar /
+ (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
+ else
+ /* default variation is +- 1 rtt */
+ tp->t_rttvar =
+ tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE;
+ TCPT_RANGESET(tp->t_rxtcur,
+ ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1,
+ tp->t_rttmin, TCPTV_REXMTMAX);
+ }
+ /*
+ * if there's an mtu associated with the route, use it
+ */
+ if (rt->rt_rmx.rmx_mtu)
+#ifdef INET6
+ {
+ /*
+ * One may wish to lower MSS to take into account options,
+ * especially security-related options.
+ */
+ if (tp->pf == AF_INET6)
+ mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpipv6hdr);
+ else
+#endif /* INET6 */
+ mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr);
+#ifdef INET6
+ }
+#endif /* INET6 */
+ else
+#endif /* RTV_MTU */
+ {
+ /*
+ * ifp may be null and rmx_mtu may be zero in certain
+ * v6 cases (e.g., if ND wasn't able to resolve the
+ * destination host.
+ */
+ mss = ifp ? ifp->if_mtu - sizeof(struct tcpiphdr) : 0;
+#ifdef INET6
+ if (tp->pf == AF_INET)
+#endif /* INET6 */
+ if (!in_localaddr(inp->inp_faddr))
+ mss = min(mss, tcp_mssdflt);
+ }
+ /*
+ * The current mss, t_maxseg, is initialized to the default value.
+ * If we compute a smaller value, reduce the current mss.
+ * If we compute a larger value, return it for use in sending
+ * a max seg size option, but don't store it for use
+ * unless we received an offer at least that large from peer.
+ * However, do not accept offers under 32 bytes.
+ */
+ if (offer)
+ mss = min(mss, offer);
+ mss = max(mss, 64); /* sanity - at least max opt. space */
+ /*
+ * maxopd stores the maximum length of data AND options
+ * in a segment; maxseg is the amount of data in a normal
+ * segment. We need to store this value (maxopd) apart
+ * from maxseg, because now every segment carries options
+ * and thus we normally have somewhat less data in segments.
+ */
+ tp->t_maxopd = mss;
+
+ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
+ (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
+ mss -= TCPOLEN_TSTAMP_APPA;
+
+#if (MCLBYTES & (MCLBYTES - 1)) == 0
+ if (mss > MCLBYTES)
+ mss &= ~(MCLBYTES-1);
+#else
+ if (mss > MCLBYTES)
+ mss = mss / MCLBYTES * MCLBYTES;
+#endif
+ /*
+ * If there's a pipesize, change the socket buffer
+ * to that size. Make the socket buffers an integral
+ * number of mss units; if the mss is larger than
+ * the socket buffer, decrease the mss.
+ */
+#ifdef RTV_SPIPE
+ if ((bufsize = rt->rt_rmx.rmx_sendpipe) == 0)
+#endif
+ bufsize = so->so_snd.sb_hiwat;
+ if (bufsize < mss)
+ mss = bufsize;
+ else {
+ bufsize = roundup(bufsize, mss);
+ if (bufsize > sb_max)
+ bufsize = sb_max;
+ (void)sbreserve(&so->so_snd, bufsize);
+ }
+ tp->t_maxseg = mss;
+
+#ifdef RTV_RPIPE
+ if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0)
+#endif
+ bufsize = so->so_rcv.sb_hiwat;
+ if (bufsize > mss) {
+ bufsize = roundup(bufsize, mss);
+ if (bufsize > sb_max)
+ bufsize = sb_max;
+ (void)sbreserve(&so->so_rcv, bufsize);
+ }
+ tp->snd_cwnd = mss;
+
+#ifdef RTV_SSTHRESH
+ if (rt->rt_rmx.rmx_ssthresh) {
+ /*
+ * There's some sort of gateway or interface
+ * buffer limit on the path. Use this to set
+ * the slow start threshhold, but set the
+ * threshold to no less than 2*mss.
+ */
+ tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh);
+ }
+#endif /* RTV_MTU */
+ return (mss);
+}
+#endif /* TUBA_INCLUDE */
+
+#if defined(TCP_NEWRENO) || defined (TCP_SACK)
+/*
+ * Checks for partial ack. If partial ack arrives, force the retransmission
+ * of the next unacknowledged segment, do not clear tp->t_dupacks, and return
+ * 1. By setting snd_nxt to ti_ack, this forces retransmission timer to
+ * be started again. If the ack advances at least to tp->snd_last, return 0.
+ */
+int
+tcp_newreno(tp, th)
+ struct tcpcb *tp;
+ struct tcphdr *th;
+{
+ if (SEQ_LT(th->th_ack, tp->snd_last)) {
+ /*
+ * snd_una has not been updated and the socket send buffer
+ * not yet drained of the acked data, so we have to leave
+ * snd_una as it was to get the correct data offset in
+ * tcp_output().
+ */
+ tcp_seq onxt = tp->snd_nxt;
+ u_long ocwnd = tp->snd_cwnd;
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->t_rtt = 0;
+ tp->snd_nxt = th->th_ack;
+ /*
+ * Set snd_cwnd to one segment beyond acknowledged offset
+ * (tp->snd_una not yet updated when this function is called)
+ */
+ tp->snd_cwnd = tp->t_maxseg + (th->th_ack - tp->snd_una);
+ (void) tcp_output(tp);
+ tp->snd_cwnd = ocwnd;
+ if (SEQ_GT(onxt, tp->snd_nxt))
+ tp->snd_nxt = onxt;
+ /*
+ * Partial window deflation. Relies on fact that tp->snd_una
+ * not updated yet.
+ */
+ tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
+ return 1;
+ }
+ return 0;
+}
+#endif /* TCP_NEWRENO || TCP_SACK */
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_output.c b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_output.c
new file mode 100644
index 0000000..adab0e1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_output.c
@@ -0,0 +1,1124 @@
+//==========================================================================
+//
+// sys/netinet/tcp_output.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_output.c,v 1.27 1999/12/15 16:37:20 provos Exp $ */
+/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/domain.h>
+
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#define TCPOUTFLAGS
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_debug.h>
+
+#ifdef TUBA
+#include <netiso/iso.h>
+#include <netiso/tuba_table.h>
+#endif
+
+#ifdef INET6
+#include <netinet6/tcpipv6.h>
+#endif /* INET6 */
+
+#ifdef TCP_SIGNATURE
+#include <sys/md5k.h>
+#endif /* TCP_SIGNATURE */
+
+#ifdef notyet
+extern struct mbuf *m_copypack();
+#endif
+
+#ifdef TCP_SACK
+extern int tcprexmtthresh;
+#endif
+
+#ifdef TCP_SACK
+#ifdef TCP_SACK_DEBUG
+void
+tcp_print_holes(tp)
+struct tcpcb *tp;
+{
+ struct sackhole *p = tp->snd_holes;
+ if (p == 0)
+ return;
+ printf("Hole report: start--end dups rxmit\n");
+ while (p) {
+ printf("%x--%x d %d r %x\n", p->start, p->end, p->dups,
+ p->rxmit);
+ p = p->next;
+ }
+ printf("\n");
+}
+#endif /* TCP_SACK_DEBUG */
+
+/*
+ * Returns pointer to a sackhole if there are any pending retransmissions;
+ * NULL otherwise.
+ */
+struct sackhole *
+tcp_sack_output(tp)
+register struct tcpcb *tp;
+{
+ struct sackhole *p;
+ if (tp->sack_disable)
+ return 0;
+ p = tp->snd_holes;
+ while (p) {
+ if (p->dups >= tcprexmtthresh && SEQ_LT(p->rxmit, p->end)) {
+ if (SEQ_LT(p->rxmit, tp->snd_una)) {/* old SACK hole */
+ p = p->next;
+ continue;
+ }
+#ifdef TCP_SACK_DEBUG
+ if (p)
+ tcp_print_holes(tp);
+#endif
+ return p;
+ }
+ p = p->next;
+ }
+ return 0;
+}
+
+/*
+ * After a timeout, the SACK list may be rebuilt. This SACK information
+ * should be used to avoid retransmitting SACKed data. This function
+ * traverses the SACK list to see if snd_nxt should be moved forward.
+ */
+void
+tcp_sack_adjust(tp)
+ struct tcpcb *tp;
+{
+ int i;
+
+ for (i = 0; i < tp->rcv_numsacks; i++) {
+ if (SEQ_LT(tp->snd_nxt, tp->sackblks[i].start))
+ break;
+ if (SEQ_LEQ(tp->sackblks[i].end, tp->snd_nxt))
+ continue;
+ if (tp->sackblks[i].start == 0 && tp->sackblks[i].end == 0)
+ continue;
+ /* snd_nxt must be in middle of block of SACKed data */
+ tp->snd_nxt = tp->sackblks[i].end;
+ break;
+ }
+}
+#endif /* TCP_SACK */
+
+/*
+ * Tcp output routine: figure out what should be sent and send it.
+ */
+int
+tcp_output(tp)
+ register struct tcpcb *tp;
+{
+ register struct socket *so = tp->t_inpcb->inp_socket;
+ register long len, win;
+ int off, flags, error = 0;
+ register struct mbuf *m;
+ register struct tcphdr *th;
+ u_char opt[MAX_TCPOPTLEN];
+ unsigned int optlen, hdrlen;
+ int idle, sendalot;
+#ifdef TCP_SACK
+ int i, sack_rxmit = 0;
+ struct sackhole *p;
+#endif
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ int maxburst = TCP_MAXBURST;
+#endif
+#ifdef TCP_SIGNATURE
+ unsigned int sigoff;
+#endif /* TCP_SIGNATURE */
+
+#if defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC)
+ if (!tp->sack_disable && (tp->t_flags & TF_SIGNATURE))
+ return (EINVAL);
+#endif /* defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC) */
+
+ /*
+ * Determine length of data that should be transmitted,
+ * and flags that will be used.
+ * If there is some data or critical controls (SYN, RST)
+ * to send, then transmit; otherwise, investigate further.
+ */
+ idle = (tp->snd_max == tp->snd_una);
+ if (idle && tp->t_idle >= tp->t_rxtcur)
+ /*
+ * We have been idle for "a while" and no acks are
+ * expected to clock out any data we send --
+ * slow start to get ack "clock" running again.
+ */
+ tp->snd_cwnd = tp->t_maxseg;
+again:
+ sendalot = 0;
+#ifdef TCP_SACK
+ /*
+ * If we've recently taken a timeout, snd_max will be greater than
+ * snd_nxt. There may be SACK information that allows us to avoid
+ * resending already delivered data. Adjust snd_nxt accordingly.
+ */
+ if (!tp->sack_disable && SEQ_LT(tp->snd_nxt, tp->snd_max))
+ tcp_sack_adjust(tp);
+#endif
+ off = tp->snd_nxt - tp->snd_una;
+ win = ulmin(tp->snd_wnd, tp->snd_cwnd);
+
+ flags = tcp_outflags[tp->t_state];
+ /*
+ * If in persist timeout with window of 0, send 1 byte.
+ * Otherwise, if window is small but nonzero
+ * and timer expired, we will send what we can
+ * and go to transmit state.
+ */
+
+#ifdef TCP_SACK
+ /*
+ * Send any SACK-generated retransmissions. If we're explicitly trying
+ * to send out new data (when sendalot is 1), bypass this function.
+ * If we retransmit in fast recovery mode, decrement snd_cwnd, since
+ * we're replacing a (future) new transmission with a retransmission
+ * now, and we previously incremented snd_cwnd in tcp_input().
+ */
+ if (!tp->sack_disable && !sendalot) {
+ if ((p = tcp_sack_output(tp))) {
+ off = p->rxmit - tp->snd_una;
+ sack_rxmit = 1;
+#if 0
+ /* Coalesce holes into a single retransmission */
+#endif
+ len = min(tp->t_maxseg, p->end - p->rxmit);
+#ifndef TCP_FACK
+ /* in FACK, hold snd_cwnd constant during recovery */
+ if (SEQ_LT(tp->snd_una, tp->snd_last))
+ tp->snd_cwnd -= tp->t_maxseg;
+#endif
+ }
+ }
+#endif /* TCP_SACK */
+
+ if (tp->t_force) {
+ if (win == 0) {
+ /*
+ * If we still have some data to send, then
+ * clear the FIN bit. Usually this would
+ * happen below when it realizes that we
+ * aren't sending all the data. However,
+ * if we have exactly 1 byte of unset data,
+ * then it won't clear the FIN bit below,
+ * and if we are in persist state, we wind
+ * up sending the packet without recording
+ * that we sent the FIN bit.
+ *
+ * We can't just blindly clear the FIN bit,
+ * because if we don't have any more data
+ * to send then the probe will be the FIN
+ * itself.
+ */
+ if (off < so->so_snd.sb_cc)
+ flags &= ~TH_FIN;
+ win = 1;
+ } else {
+ tp->t_timer[TCPT_PERSIST] = 0;
+ tp->t_rxtshift = 0;
+ }
+ }
+
+#ifdef TCP_SACK
+ if (!sack_rxmit) {
+#endif
+ len = ulmin(so->so_snd.sb_cc, win) - off;
+
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /*
+ * If we're in fast recovery (SEQ_GT(tp->snd_last, tp->snd_una)), and
+ * amount of outstanding data (snd_awnd) is >= snd_cwnd, then
+ * do not send data (like zero window conditions)
+ */
+ if (!tp->sack_disable && len && SEQ_GT(tp->snd_last, tp->snd_una) &&
+ (tp->snd_awnd >= tp->snd_cwnd))
+ len = 0;
+#endif /* TCP_FACK */
+#ifdef TCP_SACK
+ }
+#endif
+
+ if (len < 0) {
+ /*
+ * If FIN has been sent but not acked,
+ * but we haven't been called to retransmit,
+ * len will be -1. Otherwise, window shrank
+ * after we sent into it. If window shrank to 0,
+ * cancel pending retransmit and pull snd_nxt
+ * back to (closed) window. We will enter persist
+ * state below. If the window didn't close completely,
+ * just wait for an ACK.
+ */
+ len = 0;
+ if (win == 0) {
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->snd_nxt = tp->snd_una;
+ }
+ }
+ if (len > tp->t_maxseg) {
+ len = tp->t_maxseg;
+ sendalot = 1;
+ }
+ if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
+ flags &= ~TH_FIN;
+
+ win = sbspace(&so->so_rcv);
+
+ /*
+ * Sender silly window avoidance. If connection is idle
+ * and can send all data, a maximum segment,
+ * at least a maximum default-size segment do it,
+ * or are forced, do it; otherwise don't bother.
+ * If peer's buffer is tiny, then send
+ * when window is at least half open.
+ * If retransmitting (possibly after persist timer forced us
+ * to send into a small window), then must resend.
+ */
+ if (len) {
+ if (len == tp->t_maxseg)
+ goto send;
+ if ((idle || tp->t_flags & TF_NODELAY) &&
+ len + off >= so->so_snd.sb_cc)
+ goto send;
+ if (tp->t_force)
+ goto send;
+ if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
+ goto send;
+ if (SEQ_LT(tp->snd_nxt, tp->snd_max))
+ goto send;
+#ifdef TCP_SACK
+ if (sack_rxmit)
+ goto send;
+#endif
+ }
+
+ /*
+ * Compare available window to amount of window
+ * known to peer (as advertised window less
+ * next expected input). If the difference is at least two
+ * max size segments, or at least 50% of the maximum possible
+ * window, then want to send a window update to peer.
+ */
+ if (win > 0) {
+ /*
+ * "adv" is the amount we can increase the window,
+ * taking into account that we are limited by
+ * TCP_MAXWIN << tp->rcv_scale.
+ */
+ long adv = lmin(win, (long)TCP_MAXWIN << tp->rcv_scale) -
+ (tp->rcv_adv - tp->rcv_nxt);
+
+ if (adv >= (long) (2 * tp->t_maxseg))
+ goto send;
+ if (2 * adv >= (long) so->so_rcv.sb_hiwat)
+ goto send;
+ }
+
+ /*
+ * Send if we owe peer an ACK.
+ */
+ if (tp->t_flags & TF_ACKNOW)
+ goto send;
+ if (flags & (TH_SYN|TH_RST))
+ goto send;
+ if (SEQ_GT(tp->snd_up, tp->snd_una))
+ goto send;
+ /*
+ * If our state indicates that FIN should be sent
+ * and we have not yet done so, or we're retransmitting the FIN,
+ * then we need to send.
+ */
+ if (flags & TH_FIN &&
+ ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
+ goto send;
+#ifdef TCP_SACK
+ /*
+ * In SACK, it is possible for tcp_output to fail to send a segment
+ * after the retransmission timer has been turned off. Make sure
+ * that the retransmission timer is set.
+ */
+ if (SEQ_GT(tp->snd_max, tp->snd_una) &&
+ tp->t_timer[TCPT_REXMT] == 0 &&
+ tp->t_timer[TCPT_PERSIST] == 0) {
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ return (0);
+ }
+#endif /* TCP_SACK */
+
+ /*
+ * TCP window updates are not reliable, rather a polling protocol
+ * using ``persist'' packets is used to insure receipt of window
+ * updates. The three ``states'' for the output side are:
+ * idle not doing retransmits or persists
+ * persisting to move a small or zero window
+ * (re)transmitting and thereby not persisting
+ *
+ * tp->t_timer[TCPT_PERSIST]
+ * is set when we are in persist state.
+ * tp->t_force
+ * is set when we are called to send a persist packet.
+ * tp->t_timer[TCPT_REXMT]
+ * is set when we are retransmitting
+ * The output side is idle when both timers are zero.
+ *
+ * If send window is too small, there is data to transmit, and no
+ * retransmit or persist is pending, then go to persist state.
+ * If nothing happens soon, send when timer expires:
+ * if window is nonzero, transmit what we can,
+ * otherwise force out a byte.
+ */
+ if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
+ tp->t_timer[TCPT_PERSIST] == 0) {
+ tp->t_rxtshift = 0;
+ tcp_setpersist(tp);
+ }
+
+ /*
+ * No reason to send a segment, just return.
+ */
+ return (0);
+
+send:
+ /*
+ * Before ESTABLISHED, force sending of initial options
+ * unless TCP set not to do any options.
+ * NOTE: we assume that the IP/TCP header plus TCP options
+ * always fit in a single mbuf, leaving room for a maximum
+ * link header, i.e.
+ * max_linkhdr + sizeof(network header) + sizeof(struct tcphdr +
+ * optlen <= MHLEN
+ */
+ optlen = 0;
+
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case PF_INET:
+ hdrlen = sizeof(struct ip) + sizeof(struct tcphdr);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case PF_INET6:
+ hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
+ break;
+#endif /* INET6 */
+ default:
+ return (EPFNOSUPPORT);
+ }
+
+ if (flags & TH_SYN) {
+ tp->snd_nxt = tp->iss;
+ if ((tp->t_flags & TF_NOOPT) == 0) {
+ u_int16_t mss;
+
+ opt[0] = TCPOPT_MAXSEG;
+ opt[1] = 4;
+ mss = htons((u_int16_t) tcp_mss(tp, 0));
+ bcopy((caddr_t)&mss, (caddr_t)(opt + 2), sizeof(mss));
+ optlen = 4;
+#ifdef TCP_SACK
+ /*
+ * If this is the first SYN of connection (not a SYN
+ * ACK), include SACK_PERMIT_HDR option. If this is a
+ * SYN ACK, include SACK_PERMIT_HDR option if peer has
+ * already done so.
+ */
+ if (!tp->sack_disable && ((flags & TH_ACK) == 0 ||
+ (tp->t_flags & TF_SACK_PERMIT))) {
+ *((u_int32_t *) (opt + optlen)) =
+ htonl(TCPOPT_SACK_PERMIT_HDR);
+ optlen += 4;
+ }
+#endif
+
+ if ((tp->t_flags & TF_REQ_SCALE) &&
+ ((flags & TH_ACK) == 0 ||
+ (tp->t_flags & TF_RCVD_SCALE))) {
+ *((u_int32_t *) (opt + optlen)) = htonl(
+ TCPOPT_NOP << 24 |
+ TCPOPT_WINDOW << 16 |
+ TCPOLEN_WINDOW << 8 |
+ tp->request_r_scale);
+ optlen += 4;
+ }
+ }
+ }
+
+ /*
+ * Send a timestamp and echo-reply if this is a SYN and our side
+ * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
+ * and our peer have sent timestamps in our SYN's.
+ */
+ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
+ (flags & TH_RST) == 0 &&
+ ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
+ (tp->t_flags & TF_RCVD_TSTMP))) {
+ u_int32_t *lp = (u_int32_t *)(opt + optlen);
+
+ /* Form timestamp option as shown in appendix A of RFC 1323. */
+ *lp++ = htonl(TCPOPT_TSTAMP_HDR);
+ *lp++ = htonl(tcp_now);
+ *lp = htonl(tp->ts_recent);
+ optlen += TCPOLEN_TSTAMP_APPA;
+ }
+
+#ifdef TCP_SIGNATURE
+ if (tp->t_flags & TF_SIGNATURE) {
+ u_int8_t *bp = (u_int8_t *)(opt + optlen);
+
+ /* Send signature option */
+ *(bp++) = TCPOPT_SIGNATURE;
+ *(bp++) = TCPOLEN_SIGNATURE;
+ sigoff = optlen + 2;
+
+ {
+ unsigned int i;
+
+ for (i = 0; i < 16; i++)
+ *(bp++) = 0;
+ }
+
+ optlen += TCPOLEN_SIGNATURE;
+
+ /* Pad options list to the next 32 bit boundary and
+ * terminate it.
+ */
+ *bp++ = TCPOPT_NOP;
+ *bp++ = TCPOPT_EOL;
+ optlen += 2;
+ }
+#endif /* TCP_SIGNATURE */
+
+#ifdef TCP_SACK
+ /*
+ * Send SACKs if necessary. This should be the last option processed.
+ * Only as many SACKs are sent as are permitted by the maximum options
+ * size. No more than three SACKs are sent.
+ */
+ if (!tp->sack_disable && tp->t_state == TCPS_ESTABLISHED &&
+ (tp->t_flags & (TF_SACK_PERMIT|TF_NOOPT)) == TF_SACK_PERMIT &&
+ tp->rcv_numsacks) {
+ u_int32_t *lp = (u_int32_t *)(opt + optlen);
+ u_int32_t *olp = lp++;
+ int count = 0; /* actual number of SACKs inserted */
+ int maxsack = (MAX_TCPOPTLEN - (optlen + 4))/TCPOLEN_SACK;
+
+ maxsack = min(maxsack, TCP_MAX_SACK);
+ for (i = 0; (i < tp->rcv_numsacks && count < maxsack); i++) {
+ struct sackblk sack = tp->sackblks[i];
+ if (sack.start == 0 && sack.end == 0)
+ continue;
+ *lp++ = htonl(sack.start);
+ *lp++ = htonl(sack.end);
+ count++;
+ }
+ *olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2));
+ optlen += TCPOLEN_SACK*count + 4; /* including leading NOPs */
+ }
+#endif /* TCP_SACK */
+
+#ifdef DIAGNOSTIC
+ if (optlen > MAX_TCPOPTLEN)
+ panic("tcp_output: options too long");
+#endif /* DIAGNOSTIC */
+
+ hdrlen += optlen;
+
+ /*
+ * Adjust data length if insertion of options will
+ * bump the packet length beyond the t_maxopd length.
+ */
+ if (len > tp->t_maxopd - optlen) {
+ len = tp->t_maxopd - optlen;
+ sendalot = 1;
+ flags &= ~TH_FIN;
+ }
+
+#ifdef DIAGNOSTIC
+ if (max_linkhdr + hdrlen > MCLBYTES)
+ panic("tcphdr too big");
+#endif
+
+ /*
+ * Grab a header mbuf, attaching a copy of data to
+ * be transmitted, and initialize the header from
+ * the template for sends on this connection.
+ */
+ if (len) {
+ if (tp->t_force && len == 1)
+ tcpstat.tcps_sndprobe++;
+ else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
+ tcpstat.tcps_sndrexmitpack++;
+ tcpstat.tcps_sndrexmitbyte += len;
+ } else {
+ tcpstat.tcps_sndpack++;
+ tcpstat.tcps_sndbyte += len;
+ }
+#ifdef notyet
+ if ((m = m_copypack(so->so_snd.sb_mb, off,
+ (int)len, max_linkhdr + hdrlen)) == 0) {
+ error = ENOBUFS;
+ goto out;
+ }
+ /*
+ * m_copypack left space for our hdr; use it.
+ */
+ m->m_len += hdrlen;
+ m->m_data -= hdrlen;
+#else
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m != NULL) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ m = NULL;
+ }
+ }
+ if (m == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ m->m_data += max_linkhdr;
+ m->m_len = hdrlen;
+ if (len <= MCLBYTES - hdrlen - max_linkhdr) {
+ m_copydata(so->so_snd.sb_mb, off, (int) len,
+ mtod(m, caddr_t) + hdrlen);
+ m->m_len += len;
+ } else {
+ m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
+ if (m->m_next == 0) {
+ (void) m_free(m);
+ error = ENOBUFS;
+ goto out;
+ }
+ }
+#endif
+ /*
+ * If we're sending everything we've got, set PUSH.
+ * (This will keep happy those implementations which only
+ * give data to the user when a buffer fills or
+ * a PUSH comes in.)
+ */
+ if (off + len == so->so_snd.sb_cc)
+ flags |= TH_PUSH;
+ } else {
+ if (tp->t_flags & TF_ACKNOW)
+ tcpstat.tcps_sndacks++;
+ else if (flags & (TH_SYN|TH_FIN|TH_RST))
+ tcpstat.tcps_sndctrl++;
+ else if (SEQ_GT(tp->snd_up, tp->snd_una))
+ tcpstat.tcps_sndurg++;
+ else
+ tcpstat.tcps_sndwinup++;
+
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m != NULL) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ m = NULL;
+ }
+ }
+ if (m == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ m->m_data += max_linkhdr;
+ m->m_len = hdrlen;
+ }
+ m->m_pkthdr.rcvif = (struct ifnet *)0;
+
+ if (!tp->t_template)
+ panic("tcp_output");
+#ifdef DIAGNOSTIC
+ if (tp->t_template->m_len != hdrlen - optlen)
+ panic("tcp_output: template len != hdrlen - optlen");
+#endif /* DIAGNOSTIC */
+ bcopy(mtod(tp->t_template, caddr_t), mtod(m, caddr_t),
+ tp->t_template->m_len);
+ th = (struct tcphdr *)(mtod(m, caddr_t) + tp->t_template->m_len -
+ sizeof(struct tcphdr));
+
+ /*
+ * Fill in fields, remembering maximum advertised
+ * window for use in delaying messages about window sizes.
+ * If resending a FIN, be sure not to use a new sequence number.
+ */
+ if ((flags & TH_FIN) && (tp->t_flags & TF_SENTFIN) &&
+ (tp->snd_nxt == tp->snd_max))
+ tp->snd_nxt--;
+ /*
+ * If we are doing retransmissions, then snd_nxt will
+ * not reflect the first unsent octet. For ACK only
+ * packets, we do not want the sequence number of the
+ * retransmitted packet, we want the sequence number
+ * of the next unsent octet. So, if there is no data
+ * (and no SYN or FIN), use snd_max instead of snd_nxt
+ * when filling in ti_seq. But if we are in persist
+ * state, snd_max might reflect one byte beyond the
+ * right edge of the window, so use snd_nxt in that
+ * case, since we know we aren't doing a retransmission.
+ * (retransmit and persist are mutually exclusive...)
+ */
+ if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
+ th->th_seq = htonl(tp->snd_nxt);
+ else
+ th->th_seq = htonl(tp->snd_max);
+
+#ifdef TCP_SACK
+ if (sack_rxmit) {
+ /*
+ * If sendalot was turned on (due to option stuffing), turn it
+ * off. Properly set th_seq field. Advance the ret'x pointer
+ * by len.
+ */
+ if (sendalot)
+ sendalot = 0;
+ th->th_seq = htonl(p->rxmit);
+ p->rxmit += len;
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ tp->retran_data += len;
+#endif /* TCP_FACK */
+ }
+#endif /* TCP_SACK */
+
+ th->th_ack = htonl(tp->rcv_nxt);
+ if (optlen) {
+ bcopy((caddr_t)opt, (caddr_t)(th + 1), optlen);
+ th->th_off = (sizeof (struct tcphdr) + optlen) >> 2;
+ }
+ th->th_flags = flags;
+
+ /*
+ * Calculate receive window. Don't shrink window,
+ * but avoid silly window syndrome.
+ */
+ if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
+ win = 0;
+ if (win > (long)TCP_MAXWIN << tp->rcv_scale)
+ win = (long)TCP_MAXWIN << tp->rcv_scale;
+ if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
+ win = (long)(tp->rcv_adv - tp->rcv_nxt);
+ if (flags & TH_RST)
+ win = 0;
+ th->th_win = htons((u_int16_t) (win>>tp->rcv_scale));
+ if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
+ u_int32_t urp = tp->snd_up - tp->snd_nxt;
+ if (urp > IP_MAXPACKET)
+ urp = IP_MAXPACKET;
+ th->th_urp = htons((u_int16_t)urp);
+ th->th_flags |= TH_URG;
+ } else
+ /*
+ * If no urgent pointer to send, then we pull
+ * the urgent pointer to the left edge of the send window
+ * so that it doesn't drift into the send window on sequence
+ * number wraparound.
+ */
+ tp->snd_up = tp->snd_una; /* drag it along */
+
+ /* Put TCP length in pseudo-header */
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case AF_INET:
+ if (len + optlen)
+ mtod(m, struct ipovly *)->ih_len = htons((u_int16_t)(
+ sizeof (struct tcphdr) + optlen + len));
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif /* INET6 */
+ }
+
+#ifdef TCP_SIGNATURE
+ if (tp->t_flags & TF_SIGNATURE) {
+ MD5_CTX ctx;
+ union sockaddr_union sa;
+ struct tdb *tdb;
+
+ memset(&sa, 0, sizeof(union sockaddr_union));
+
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case AF_INET:
+ sa.sa.sa_len = sizeof(struct sockaddr_in);
+ sa.sa.sa_family = AF_INET;
+ sa.sin.sin_addr = mtod(m, struct ip *)->ip_dst;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ sa.sa.sa_len = sizeof(struct sockaddr_in6);
+ sa.sa.sa_family = AF_INET6;
+ sa.sin6.sin6_addr = mtod(m, struct ip6_hdr *)->ip6_dst;
+ break;
+#endif /* INET6 */
+ }
+
+ /* XXX gettdb() should really be called at spltdb(). */
+ /* XXX this is splsoftnet(), currently they are the same. */
+ tdb = gettdb(0, &sa, IPPROTO_TCP);
+ if (tdb == NULL)
+ return (EPERM);
+
+ MD5Init(&ctx);
+
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case AF_INET:
+ {
+ struct ippseudo ippseudo;
+ struct ipovly *ipovly;
+
+ ipovly = mtod(m, struct ipovly *);
+
+ ippseudo.ippseudo_src = ipovly->ih_src;
+ ippseudo.ippseudo_dst = ipovly->ih_dst;
+ ippseudo.ippseudo_pad = 0;
+ ippseudo.ippseudo_p = IPPROTO_TCP;
+ ippseudo.ippseudo_len = ipovly->ih_len;
+ MD5Update(&ctx, (char *)&ippseudo,
+ sizeof(struct ippseudo));
+ MD5Update(&ctx, mtod(m, caddr_t) +
+ sizeof(struct ip),
+ sizeof(struct tcphdr));
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ {
+ static int printed = 0;
+
+ if (!printed) {
+ printf("error: TCP MD5 support for "
+ "IPv6 not yet implemented.\n");
+ printed = 1;
+ }
+ }
+ break;
+#endif /* INET6 */
+ }
+
+ if (len && m_apply(m, hdrlen, len, tcp_signature_apply,
+ (caddr_t)&ctx))
+ return (EINVAL);
+
+ MD5Update(&ctx, tdb->tdb_amxkey, tdb->tdb_amxkeylen);
+ MD5Final(mtod(m, caddr_t) + hdrlen - optlen + sigoff, &ctx);
+ }
+#endif /* TCP_SIGNATURE */
+
+ /*
+ * Put TCP length in extended header, and then
+ * checksum extended header and data.
+ */
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case AF_INET:
+ th->th_sum = in_cksum(m, (int)(hdrlen + len));
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ m->m_pkthdr.len = hdrlen + len;
+ th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr),
+ hdrlen - sizeof(struct ip6_hdr) + len);
+ break;
+#endif /* INET6 */
+ }
+
+ /*
+ * In transmit state, time the transmission and arrange for
+ * the retransmit. In persist state, just set snd_max.
+ */
+ if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
+ tcp_seq startseq = tp->snd_nxt;
+
+ /*
+ * Advance snd_nxt over sequence space of this segment.
+ */
+ if (flags & (TH_SYN|TH_FIN)) {
+ if (flags & TH_SYN)
+ tp->snd_nxt++;
+ if (flags & TH_FIN) {
+ tp->snd_nxt++;
+ tp->t_flags |= TF_SENTFIN;
+ }
+ }
+#ifdef TCP_SACK
+ if (!tp->sack_disable) {
+ if (sack_rxmit && (p->rxmit != tp->snd_nxt)) {
+ goto timer;
+ }
+ }
+#endif
+ tp->snd_nxt += len;
+ if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
+ tp->snd_max = tp->snd_nxt;
+ /*
+ * Time this transmission if not a retransmission and
+ * not currently timing anything.
+ */
+ if (tp->t_rtt == 0) {
+ tp->t_rtt = 1;
+ tp->t_rtseq = startseq;
+ tcpstat.tcps_segstimed++;
+ }
+ }
+
+ /*
+ * Set retransmit timer if not currently set,
+ * and not doing an ack or a keep-alive probe.
+ * Initial value for retransmit timer is smoothed
+ * round-trip time + 2 * round-trip time variance.
+ * Initialize shift counter which is used for backoff
+ * of retransmit time.
+ */
+#ifdef TCP_SACK
+ timer:
+ if (!tp->sack_disable && sack_rxmit &&
+ tp->t_timer[TCPT_REXMT] == 0 &&
+ tp->snd_nxt != tp->snd_max) {
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ if (tp->t_timer[TCPT_PERSIST]) {
+ tp->t_timer[TCPT_PERSIST] = 0;
+ tp->t_rxtshift = 0;
+ }
+ }
+#endif
+
+ if (tp->t_timer[TCPT_REXMT] == 0 &&
+ tp->snd_nxt != tp->snd_una) {
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ if (tp->t_timer[TCPT_PERSIST]) {
+ tp->t_timer[TCPT_PERSIST] = 0;
+ tp->t_rxtshift = 0;
+ }
+ }
+ } else
+ if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
+ tp->snd_max = tp->snd_nxt + len;
+
+ /*
+ * Trace.
+ */
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, caddr_t), 0,
+ len);
+#endif /* TCPDEBUG */
+
+ /*
+ * Fill in IP length and desired time to live and
+ * send to IP level. There should be a better way
+ * to handle ttl and tos; we could keep them in
+ * the template, but need a way to checksum without them.
+ */
+ m->m_pkthdr.len = hdrlen + len;
+
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case AF_INET:
+ {
+ struct ip *ip;
+
+ ip = mtod(m, struct ip *);
+ ip->ip_len = m->m_pkthdr.len;
+ ip->ip_ttl = tp->t_inpcb->inp_ip.ip_ttl;
+ ip->ip_tos = tp->t_inpcb->inp_ip.ip_tos;
+ }
+ error = ip_output(m, tp->t_inpcb->inp_options,
+ &tp->t_inpcb->inp_route, so->so_options & SO_DONTROUTE,
+ 0, tp->t_inpcb);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct ip6_hdr *ipv6;
+
+ ipv6 = mtod(m, struct ip6_hdr *);
+ ipv6->ip6_plen = m->m_pkthdr.len -
+ sizeof(struct ip6_hdr);
+ ipv6->ip6_nxt = IPPROTO_TCP;
+ ipv6->ip6_hlim = in6_selecthlim(tp->t_inpcb, NULL);
+ }
+ error = ip6_output(m, tp->t_inpcb->inp_outputopts6,
+ &tp->t_inpcb->inp_route6,
+ (so->so_options & SO_DONTROUTE), NULL, NULL);
+ break;
+#endif /* INET6 */
+#ifdef TUBA
+ case AF_ISO:
+ if (tp->t_tuba_pcb)
+ error = tuba_output(m, tp);
+ break;
+#endif /* TUBA */
+ }
+
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ /* Update snd_awnd to reflect the new data that was sent. */
+ tp->snd_awnd = tcp_seq_subtract(tp->snd_max, tp->snd_fack) +
+ tp->retran_data;
+#endif /* defined(TCP_SACK) && defined(TCP_FACK) */
+
+ if (error) {
+out:
+ if (error == ENOBUFS) {
+ tcp_quench(tp->t_inpcb, 0);
+ return (0);
+ }
+ if ((error == EHOSTUNREACH || error == ENETDOWN)
+ && TCPS_HAVERCVDSYN(tp->t_state)) {
+ tp->t_softerror = error;
+ return (0);
+ }
+ return (error);
+ }
+ tcpstat.tcps_sndtotal++;
+
+ /*
+ * Data sent (as far as we can tell).
+ * If this advertises a larger window than any other segment,
+ * then remember the size of the advertised window.
+ * Any pending ACK has now been sent.
+ */
+ if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
+ tp->rcv_adv = tp->rcv_nxt + win;
+ tp->last_ack_sent = tp->rcv_nxt;
+ tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ if (sendalot && --maxburst)
+#else
+ if (sendalot)
+#endif
+ goto again;
+ return (0);
+}
+
+void
+tcp_setpersist(tp)
+ register struct tcpcb *tp;
+{
+ register int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
+
+ if (tp->t_timer[TCPT_REXMT])
+ panic("tcp_output REXMT");
+ /*
+ * Start/restart persistance timer.
+ */
+ if (t < tp->t_rttmin)
+ t = tp->t_rttmin;
+ TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
+ t * tcp_backoff[tp->t_rxtshift],
+ TCPTV_PERSMIN, TCPTV_PERSMAX);
+ if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
+ tp->t_rxtshift++;
+}
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_subr.c b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_subr.c
new file mode 100644
index 0000000..24937e1
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_subr.c
@@ -0,0 +1,899 @@
+//==========================================================================
+//
+// sys/netinet/tcp_subr.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_subr.c,v 1.21 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/proc.h>
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+#ifdef __ECOS
+#undef errno
+#endif
+
+#include <net/route.h>
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+
+#ifdef INET6
+#include <netinet6/ip6_var.h>
+#include <netinet6/tcpipv6.h>
+#include <sys/domain.h>
+#endif /* INET6 */
+
+#ifdef TCP_SIGNATURE
+#include <sys/md5k.h>
+#endif /* TCP_SIGNATURE */
+
+/* patchable/settable parameters for tcp */
+int tcp_mssdflt = TCP_MSS;
+int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
+
+/*
+ * Configure kernel with options "TCP_DO_RFC1323=0" to disable RFC1323 stuff.
+ * This is a good idea over slow SLIP/PPP links, because the timestamp
+ * pretty well destroys the VJ compression (any packet with a timestamp
+ * different from the previous one can't be compressed), as well as adding
+ * more overhead.
+ * XXX And it should be a settable per route characteristic (with this just
+ * used as the default).
+ */
+#ifndef TCP_DO_RFC1323
+#define TCP_DO_RFC1323 1
+#endif
+int tcp_do_rfc1323 = TCP_DO_RFC1323;
+
+#ifndef TCP_DO_SACK
+#ifdef TCP_SACK
+#define TCP_DO_SACK 0 /* XXX - make this 1 when SACK is fixed */
+#else
+#define TCP_DO_SACK 0
+#endif
+#endif
+int tcp_do_sack = TCP_DO_SACK; /* RFC 2018 selective ACKs */
+
+#ifndef TCBHASHSIZE
+#define TCBHASHSIZE 128
+#endif
+int tcbhashsize = TCBHASHSIZE;
+
+#ifdef INET6
+extern int ip6_defhlim;
+#endif /* INET6 */
+
+/*
+ * Tcp initialization
+ */
+void
+tcp_init()
+{
+#ifdef TCP_COMPAT_42
+ tcp_iss = 1; /* wrong */
+#else /* TCP_COMPAT_42 */
+ tcp_iss = arc4random() + 1;
+#endif /* !TCP_COMPAT_42 */
+ in_pcbinit(&tcbtable, tcbhashsize);
+
+#ifdef INET6
+ /*
+ * Since sizeof(struct ip6_hdr) > sizeof(struct ip), we
+ * do max length checks/computations only on the former.
+ */
+ if (max_protohdr < (sizeof(struct ip6_hdr) + sizeof(struct tcphdr)))
+ max_protohdr = (sizeof(struct ip6_hdr) + sizeof(struct tcphdr));
+ if ((max_linkhdr + sizeof(struct ip6_hdr) + sizeof(struct tcphdr)) >
+ MHLEN)
+ panic("tcp_init");
+#endif /* INET6 */
+}
+
+/*
+ * Create template to be used to send tcp packets on a connection.
+ * Call after host entry created, allocates an mbuf and fills
+ * in a skeletal tcp/ip header, minimizing the amount of work
+ * necessary when the connection is used.
+ *
+ * To support IPv6 in addition to IPv4 and considering that the sizes of
+ * the IPv4 and IPv6 headers are not the same, we now use a separate pointer
+ * for the TCP header. Also, we made the former tcpiphdr header pointer
+ * into just an IP overlay pointer, with casting as appropriate for v6. rja
+ */
+struct mbuf *
+tcp_template(tp)
+ struct tcpcb *tp;
+{
+ register struct inpcb *inp = tp->t_inpcb;
+ register struct mbuf *m;
+ register struct tcphdr *th = (struct tcphdr *)0;
+
+ if ((m = tp->t_template) == 0) {
+ m = m_get(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return (0);
+
+ switch (tp->pf) {
+ case 0: /*default to PF_INET*/
+#ifdef INET
+ case AF_INET:
+ m->m_len = sizeof(struct ip);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ m->m_len = sizeof(struct ip6_hdr);
+ break;
+#endif /* INET6 */
+ }
+ m->m_len += sizeof (struct tcphdr);
+
+ /*
+ * The link header, network header, TCP header, and TCP options
+ * all must fit in this mbuf. For now, assume the worst case of
+ * TCP options size. Eventually, compute this from tp flags.
+ */
+ if (m->m_len + MAX_TCPOPTLEN + max_linkhdr >= MHLEN) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_free(m);
+ return (0);
+ }
+ }
+ }
+
+ switch(tp->pf) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct ipovly *ipovly;
+
+ ipovly = mtod(m, struct ipovly *);
+
+ bzero(ipovly->ih_x1, sizeof ipovly->ih_x1);
+ ipovly->ih_pr = IPPROTO_TCP;
+ ipovly->ih_len = htons(sizeof (struct tcpiphdr) -
+ sizeof (struct ip));
+ ipovly->ih_src = inp->inp_laddr;
+ ipovly->ih_dst = inp->inp_faddr;
+
+ th = (struct tcphdr *)(mtod(m, caddr_t) +
+ sizeof(struct ip));
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct ip6_hdr *ipv6;
+
+ ipv6 = mtod(m, struct ip6_hdr *);
+
+ ipv6->ip6_src = inp->inp_laddr6;
+ ipv6->ip6_dst = inp->inp_faddr6;
+ ipv6->ip6_flow = htonl(0x60000000) |
+ (inp->inp_ipv6.ip6_flow & htonl(0x0fffffff));
+
+
+ ipv6->ip6_nxt = IPPROTO_TCP;
+ ipv6->ip6_plen = htons(sizeof(struct tcphdr)); /*XXX*/
+ ipv6->ip6_hlim = in6_selecthlim(inp, NULL); /*XXX*/
+
+ th = (struct tcphdr *)(mtod(m, caddr_t) +
+ sizeof(struct ip6_hdr));
+ }
+ break;
+#endif /* INET6 */
+ }
+
+ th->th_sport = inp->inp_lport;
+ th->th_dport = inp->inp_fport;
+ th->th_seq = 0;
+ th->th_ack = 0;
+ th->th_x2 = 0;
+ th->th_off = 5;
+ th->th_flags = 0;
+ th->th_win = 0;
+ th->th_sum = 0;
+ th->th_urp = 0;
+ return (m);
+}
+
+/*
+ * Send a single message to the TCP at address specified by
+ * the given TCP/IP header. If m == 0, then we make a copy
+ * of the tcpiphdr at ti and send directly to the addressed host.
+ * This is used to force keep alive messages out using the TCP
+ * template for a connection tp->t_template. If flags are given
+ * then we send a message back to the TCP which originated the
+ * segment ti, and discard the mbuf containing it and any other
+ * attached mbufs.
+ *
+ * In any case the ack and sequence number of the transmitted
+ * segment are as specified by the parameters.
+ */
+#ifdef INET6
+/* This function looks hairy, because it was so IPv4-dependent. */
+#endif /* INET6 */
+void
+tcp_respond(tp, template, m, ack, seq, flags)
+ struct tcpcb *tp;
+ caddr_t template;
+ register struct mbuf *m;
+ tcp_seq ack, seq;
+ int flags;
+{
+ register int tlen;
+ int win = 0;
+ struct route *ro = 0;
+ register struct tcphdr *th;
+ register struct tcpiphdr *ti = (struct tcpiphdr *)template;
+#ifdef INET6
+ int is_ipv6 = 0; /* true iff IPv6 */
+#endif /* INET6 */
+
+ if (tp) {
+ win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
+#ifdef INET6
+ /*
+ * If this is called with an unconnected
+ * socket/tp/pcb (tp->pf is 0), we lose.
+ */
+ is_ipv6 = (tp->pf == PF_INET6);
+
+ /*
+ * The route/route6 distinction is meaningless
+ * unless you're allocating space or passing parameters.
+ */
+#endif /* INET6 */
+ ro = &tp->t_inpcb->inp_route;
+ }
+#ifdef INET6
+ else
+ is_ipv6 = (((struct ip *)ti)->ip_v == 6);
+#endif /* INET6 */
+ if (m == 0) {
+ m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return;
+#ifdef TCP_COMPAT_42
+ tlen = 1;
+#else
+ tlen = 0;
+#endif
+ m->m_data += max_linkhdr;
+#ifdef INET6
+ if (is_ipv6)
+ bcopy(ti, mtod(m, caddr_t), sizeof(struct tcphdr) +
+ sizeof(struct ip6_hdr));
+ else
+#endif /* INET6 */
+ bcopy(ti, mtod(m, caddr_t), sizeof(struct tcphdr) +
+ sizeof(struct ip));
+
+ ti = mtod(m, struct tcpiphdr *);
+ flags = TH_ACK;
+ } else {
+ m_freem(m->m_next);
+ m->m_next = 0;
+ m->m_data = (caddr_t)ti;
+ tlen = 0;
+#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
+#ifdef INET6
+ if (is_ipv6) {
+ m->m_len = sizeof(struct tcphdr) + sizeof(struct ip6_hdr);
+ xchg(((struct ip6_hdr *)ti)->ip6_dst,\
+ ((struct ip6_hdr *)ti)->ip6_src,\
+ struct in6_addr);
+ th = (void *)ti + sizeof(struct ip6_hdr);
+ } else
+#endif /* INET6 */
+ {
+ m->m_len = sizeof (struct tcpiphdr);
+ xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t);
+ th = (void *)((caddr_t)ti + sizeof(struct ip));
+ }
+ xchg(th->th_dport, th->th_sport, u_int16_t);
+#undef xchg
+ }
+#ifdef INET6
+ if (is_ipv6) {
+ tlen += sizeof(struct tcphdr) + sizeof(struct ip6_hdr);
+ th = (struct tcphdr *)((caddr_t)ti + sizeof(struct ip6_hdr));
+ } else
+#endif /* INET6 */
+ {
+ ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + tlen));
+ tlen += sizeof (struct tcpiphdr);
+ th = (struct tcphdr *)((caddr_t)ti + sizeof(struct ip));
+ }
+
+ m->m_len = tlen;
+ m->m_pkthdr.len = tlen;
+ m->m_pkthdr.rcvif = (struct ifnet *) 0;
+ th->th_seq = htonl(seq);
+ th->th_ack = htonl(ack);
+ th->th_x2 = 0;
+ th->th_off = sizeof (struct tcphdr) >> 2;
+ th->th_flags = flags;
+ if (tp)
+ th->th_win = htons((u_int16_t) (win >> tp->rcv_scale));
+ else
+ th->th_win = htons((u_int16_t)win);
+ th->th_urp = 0;
+
+#ifdef INET6
+ if (is_ipv6) {
+ ((struct ip6_hdr *)ti)->ip6_flow = htonl(0x60000000);
+ ((struct ip6_hdr *)ti)->ip6_nxt = IPPROTO_TCP;
+ ((struct ip6_hdr *)ti)->ip6_hlim =
+ in6_selecthlim(tp ? tp->t_inpcb : NULL, NULL); /*XXX*/
+ ((struct ip6_hdr *)ti)->ip6_plen = tlen - sizeof(struct ip6_hdr);
+ th->th_sum = 0;
+ th->th_sum = in6_cksum(m, IPPROTO_TCP,
+ sizeof(struct ip6_hdr), ((struct ip6_hdr *)ti)->ip6_plen);
+ HTONS(((struct ip6_hdr *)ti)->ip6_plen);
+ ip6_output(m, tp ? tp->t_inpcb->inp_outputopts6 : NULL,
+ (struct route_in6 *)ro, 0, NULL, NULL);
+ } else
+#endif /* INET6 */
+ {
+ bzero(ti->ti_x1, sizeof ti->ti_x1);
+ ti->ti_len = htons((u_short)tlen - sizeof(struct ip));
+ th->th_sum = in_cksum(m, tlen);
+ ((struct ip *)ti)->ip_len = tlen;
+ ((struct ip *)ti)->ip_ttl = ip_defttl;
+ ip_output(m, NULL, ro, 0, NULL, tp ? tp->t_inpcb : NULL);
+ }
+}
+
+/*
+ * Create a new TCP control block, making an
+ * empty reassembly queue and hooking it to the argument
+ * protocol control block.
+ */
+struct tcpcb *
+tcp_newtcpcb(inp)
+ struct inpcb *inp;
+{
+ register struct tcpcb *tp;
+
+ tp = malloc(sizeof(*tp), M_PCB, M_NOWAIT);
+ if (tp == NULL)
+ return ((struct tcpcb *)0);
+ bzero((char *) tp, sizeof(struct tcpcb));
+ LIST_INIT(&tp->segq);
+ tp->t_maxseg = tp->t_maxopd = tcp_mssdflt;
+
+#ifdef TCP_SACK
+ tp->sack_disable = tcp_do_sack ? 0 : 1;
+#endif
+ tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
+ tp->t_inpcb = inp;
+ /*
+ * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
+ * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives
+ * reasonable initial retransmit time.
+ */
+ tp->t_srtt = TCPTV_SRTTBASE;
+ tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << (TCP_RTTVAR_SHIFT + 2 - 1);
+ tp->t_rttmin = TCPTV_MIN;
+ TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
+ TCPTV_MIN, TCPTV_REXMTMAX);
+ tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
+ tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
+#ifdef INET6
+ /*
+ * If we want to use tp->pf for a quick-n-easy way to determine
+ * the outbound dgram type, we cannot make this decision
+ * until a connection is established! Bzero() sets pf to zero, and
+ * that's the way we want it, unless, of course, it's an AF_INET
+ * socket...
+ */
+ if ((inp->inp_flags & INP_IPV6) == 0)
+ tp->pf = PF_INET; /* If AF_INET socket, we can't do v6 from it. */
+#else
+ tp->pf = PF_INET;
+#endif
+
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ inp->inp_ipv6.ip6_hlim = ip6_defhlim;
+ else
+#endif /* INET6 */
+ inp->inp_ip.ip_ttl = ip_defttl;
+
+ inp->inp_ppcb = (caddr_t)tp;
+ return (tp);
+}
+
+/*
+ * Drop a TCP connection, reporting
+ * the specified error. If connection is synchronized,
+ * then send a RST to peer.
+ */
+struct tcpcb *
+tcp_drop(tp, errno)
+ register struct tcpcb *tp;
+ int errno;
+{
+ struct socket *so = tp->t_inpcb->inp_socket;
+
+ if (TCPS_HAVERCVDSYN(tp->t_state)) {
+ tp->t_state = TCPS_CLOSED;
+ (void) tcp_output(tp);
+ tcpstat.tcps_drops++;
+ } else
+ tcpstat.tcps_conndrops++;
+ if (errno == ETIMEDOUT && tp->t_softerror)
+ errno = tp->t_softerror;
+ so->so_error = errno;
+ return (tcp_close(tp));
+}
+
+/*
+ * Close a TCP control block:
+ * discard all space held by the tcp
+ * discard internet protocol block
+ * wake up any sleepers
+ */
+struct tcpcb *
+tcp_close(tp)
+ register struct tcpcb *tp;
+{
+ register struct ipqent *qe;
+ struct inpcb *inp = tp->t_inpcb;
+ struct socket *so = inp->inp_socket;
+#ifdef TCP_SACK
+ struct sackhole *p, *q;
+#endif
+#ifdef RTV_RTT
+ register struct rtentry *rt;
+#ifdef INET6
+ register int bound_to_specific = 0; /* I.e. non-default */
+
+ /*
+ * This code checks the nature of the route for this connection.
+ * Normally this is done by two simple checks in the next
+ * INET/INET6 ifdef block, but because of two possible lower layers,
+ * that check is done here.
+ *
+ * Perhaps should be doing this only for a RTF_HOST route.
+ */
+ rt = inp->inp_route.ro_rt; /* Same for route or route6. */
+ if (tp->pf == PF_INET6) {
+ if (rt)
+ bound_to_specific =
+ !(IN6_IS_ADDR_UNSPECIFIED(&
+ ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr));
+ } else {
+ if (rt)
+ bound_to_specific =
+ (((struct sockaddr_in *)rt_key(rt))->
+ sin_addr.s_addr != INADDR_ANY);
+ }
+#endif /* INET6 */
+
+ /*
+ * If we sent enough data to get some meaningful characteristics,
+ * save them in the routing entry. 'Enough' is arbitrarily
+ * defined as the sendpipesize (default 4K) * 16. This would
+ * give us 16 rtt samples assuming we only get one sample per
+ * window (the usual case on a long haul net). 16 samples is
+ * enough for the srtt filter to converge to within 5% of the correct
+ * value; fewer samples and we could save a very bogus rtt.
+ *
+ * Don't update the default route's characteristics and don't
+ * update anything that the user "locked".
+ */
+#ifdef INET6
+ /*
+ * Note that rt and bound_to_specific are set above.
+ */
+ if (SEQ_LT(tp->iss + so->so_snd.sb_hiwat * 16, tp->snd_max) &&
+ rt && bound_to_specific) {
+#else /* INET6 */
+ if (SEQ_LT(tp->iss + so->so_snd.sb_hiwat * 16, tp->snd_max) &&
+ (rt = inp->inp_route.ro_rt) &&
+ satosin(rt_key(rt))->sin_addr.s_addr != INADDR_ANY) {
+#endif /* INET6 */
+ register u_long i = 0;
+
+ if ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0) {
+ i = tp->t_srtt *
+ (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
+ if (rt->rt_rmx.rmx_rtt && i)
+ /*
+ * filter this update to half the old & half
+ * the new values, converting scale.
+ * See route.h and tcp_var.h for a
+ * description of the scaling constants.
+ */
+ rt->rt_rmx.rmx_rtt =
+ (rt->rt_rmx.rmx_rtt + i) / 2;
+ else
+ rt->rt_rmx.rmx_rtt = i;
+ }
+ if ((rt->rt_rmx.rmx_locks & RTV_RTTVAR) == 0) {
+ i = tp->t_rttvar *
+ (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
+ if (rt->rt_rmx.rmx_rttvar && i)
+ rt->rt_rmx.rmx_rttvar =
+ (rt->rt_rmx.rmx_rttvar + i) / 2;
+ else
+ rt->rt_rmx.rmx_rttvar = i;
+ }
+ /*
+ * update the pipelimit (ssthresh) if it has been updated
+ * already or if a pipesize was specified & the threshhold
+ * got below half the pipesize. I.e., wait for bad news
+ * before we start updating, then update on both good
+ * and bad news.
+ */
+ if (((rt->rt_rmx.rmx_locks & RTV_SSTHRESH) == 0 &&
+ (i = tp->snd_ssthresh) && rt->rt_rmx.rmx_ssthresh) ||
+ i < (rt->rt_rmx.rmx_sendpipe / 2)) {
+ /*
+ * convert the limit from user data bytes to
+ * packets then to packet data bytes.
+ */
+ i = (i + tp->t_maxseg / 2) / tp->t_maxseg;
+ if (i < 2)
+ i = 2;
+#ifdef INET6
+ if (tp->pf == PF_INET6)
+ i *= (u_long)(tp->t_maxseg + sizeof (struct tcphdr)
+ + sizeof(struct ip6_hdr));
+ else
+#endif /* INET6 */
+ i *= (u_long)(tp->t_maxseg +
+ sizeof (struct tcpiphdr));
+
+ if (rt->rt_rmx.rmx_ssthresh)
+ rt->rt_rmx.rmx_ssthresh =
+ (rt->rt_rmx.rmx_ssthresh + i) / 2;
+ else
+ rt->rt_rmx.rmx_ssthresh = i;
+ }
+ }
+#endif /* RTV_RTT */
+
+ /* free the reassembly queue, if any */
+#ifdef INET6
+ /* Reassembling TCP segments in v6 might be sufficiently different
+ * to merit two codepaths to free the reasssembly queue.
+ * If an undecided TCP socket, then the IPv4 codepath will be used
+ * because it won't matter much anyway.
+ */
+ if (tp->pf == AF_INET6) {
+ while ((qe = tp->segq.lh_first) != NULL) {
+ LIST_REMOVE(qe, ipqe_q);
+ m_freem(qe->ipqe_m);
+ FREE(qe, M_IPQ);
+ }
+ } else
+#endif /* INET6 */
+ while ((qe = tp->segq.lh_first) != NULL) {
+ LIST_REMOVE(qe, ipqe_q);
+ m_freem(qe->ipqe_m);
+ FREE(qe, M_IPQ);
+ }
+#ifdef TCP_SACK
+ /* Free SACK holes. */
+ q = p = tp->snd_holes;
+ while (p != 0) {
+ q = p->next;
+ free(p, M_PCB);
+ p = q;
+ }
+#endif
+ if (tp->t_template)
+ (void) m_free(tp->t_template);
+ free(tp, M_PCB);
+ inp->inp_ppcb = 0;
+ soisdisconnected(so);
+ in_pcbdetach(inp);
+ tcpstat.tcps_closed++;
+ return ((struct tcpcb *)0);
+}
+
+void
+tcp_drain()
+{
+
+}
+
+/*
+ * Notify a tcp user of an asynchronous error;
+ * store error as soft error, but wake up user
+ * (for now, won't do anything until can select for soft error).
+ */
+void
+tcp_notify(inp, error)
+ struct inpcb *inp;
+ int error;
+{
+ register struct tcpcb *tp = (struct tcpcb *)inp->inp_ppcb;
+ register struct socket *so = inp->inp_socket;
+
+ /*
+ * Ignore some errors if we are hooked up.
+ * If connection hasn't completed, has retransmitted several times,
+ * and receives a second error, give up now. This is better
+ * than waiting a long time to establish a connection that
+ * can never complete.
+ */
+ if (tp->t_state == TCPS_ESTABLISHED &&
+ (error == EHOSTUNREACH || error == ENETUNREACH ||
+ error == EHOSTDOWN)) {
+ return;
+ } else if (TCPS_HAVEESTABLISHED(tp->t_state) == 0 &&
+ tp->t_rxtshift > 3 && tp->t_softerror)
+ so->so_error = error;
+ else
+ tp->t_softerror = error;
+ wakeup((caddr_t) &so->so_timeo);
+ sorwakeup(so);
+ sowwakeup(so);
+}
+
+#if defined(INET6) && !defined(TCP6)
+void
+tcp6_ctlinput(cmd, sa, d)
+ int cmd;
+ struct sockaddr *sa;
+ void *d;
+{
+ (void)tcp_ctlinput(cmd, sa, NULL); /*XXX*/
+}
+#endif
+
+void *
+tcp_ctlinput(cmd, sa, v)
+ int cmd;
+ struct sockaddr *sa;
+ register void *v;
+{
+ register struct ip *ip = v;
+ register struct tcphdr *th;
+ extern int inetctlerrmap[];
+ void (*notify) __P((struct inpcb *, int)) = tcp_notify;
+ int errno;
+
+ if ((unsigned)cmd >= PRC_NCMDS)
+ return NULL;
+ errno = inetctlerrmap[cmd];
+ if (cmd == PRC_QUENCH)
+ notify = tcp_quench;
+ else if (PRC_IS_REDIRECT(cmd))
+ notify = in_rtchange, ip = 0;
+ else if (cmd == PRC_HOSTDEAD)
+ ip = 0;
+ else if (errno == 0)
+ return NULL;
+
+#ifdef INET6
+ if (sa->sa_family == AF_INET6) {
+ if (ip) {
+ struct ip6_hdr *ipv6 = (struct ip6_hdr *)ip;
+
+ th = (struct tcphdr *)(ipv6 + 1);
+#if 0 /*XXX*/
+ in6_pcbnotify(&tcbtable, sa, th->th_dport,
+ &ipv6->ip6_src, th->th_sport, cmd, notify);
+#endif
+ } else {
+#if 0 /*XXX*/
+ in6_pcbnotify(&tcbtable, sa, 0,
+ (struct in6_addr *)&in6addr_any, 0, cmd, notify);
+#endif
+ }
+ } else
+#endif /* INET6 */
+ {
+ if (ip) {
+ th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ in_pcbnotify(&tcbtable, sa, th->th_dport, ip->ip_src,
+ th->th_sport, errno, notify);
+ } else
+ in_pcbnotifyall(&tcbtable, sa, errno, notify);
+ }
+ return NULL;
+}
+
+/*
+ * When a source quench is received, close congestion window
+ * to one segment. We will gradually open it again as we proceed.
+ */
+void
+tcp_quench(inp, errno)
+ struct inpcb *inp;
+ int errno;
+{
+ struct tcpcb *tp = intotcpcb(inp);
+
+ if (tp)
+ tp->snd_cwnd = tp->t_maxseg;
+}
+
+#ifdef TCP_SIGNATURE
+int
+tcp_signature_tdb_attach()
+{
+ return (0);
+}
+
+int
+tcp_signature_tdb_init(tdbp, xsp, ii)
+ struct tdb *tdbp;
+ struct xformsw *xsp;
+ struct ipsecinit *ii;
+{
+ char *c;
+#define isdigit(c) (((c) >= '0') && ((c) <= '9'))
+#define isalpha(c) ( (((c) >= 'A') && ((c) <= 'Z')) || \
+ (((c) >= 'a') && ((c) <= 'z')) )
+
+ if ((ii->ii_authkeylen < 1) || (ii->ii_authkeylen > 80))
+ return (EINVAL);
+
+ c = (char *)ii->ii_authkey;
+
+ while (c < (char *)ii->ii_authkey + ii->ii_authkeylen - 1) {
+ if (isdigit(*c)) {
+ if (*(c + 1) == ' ')
+ return (EINVAL);
+ } else {
+ if (!isalpha(*c))
+ return (EINVAL);
+ }
+
+ c++;
+ }
+
+ if (!isdigit(*c) && !isalpha(*c))
+ return (EINVAL);
+
+ tdbp->tdb_amxkey = malloc(ii->ii_authkeylen, M_XDATA, M_DONTWAIT);
+ if (tdbp->tdb_amxkey == NULL)
+ return (ENOMEM);
+ bcopy(ii->ii_authkey, tdbp->tdb_amxkey, ii->ii_authkeylen);
+ tdbp->tdb_amxkeylen = ii->ii_authkeylen;
+
+ return (0);
+}
+
+int
+tcp_signature_tdb_zeroize(tdbp)
+ struct tdb *tdbp;
+{
+ if (tdbp->tdb_amxkey) {
+ bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
+ free(tdbp->tdb_amxkey, M_XDATA);
+ tdbp->tdb_amxkey = NULL;
+ }
+
+ return (0);
+}
+
+struct mbuf *
+tcp_signature_tdb_input(m, tdbp)
+ struct mbuf *m;
+ struct tdb *tdbp;
+{
+ return (0);
+}
+
+int
+tcp_signature_tdb_output(m, tdbp, mp)
+ struct mbuf *m;
+ struct tdb *tdbp;
+ struct mbuf **mp;
+{
+ return (EINVAL);
+}
+
+int
+tcp_signature_apply(fstate, data, len)
+ caddr_t fstate;
+ caddr_t data;
+ unsigned int len;
+{
+ MD5Update((MD5_CTX *)fstate, (char *)data, len);
+ return 0;
+}
+#endif /* TCP_SIGNATURE */
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_timer.c b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_timer.c
new file mode 100644
index 0000000..514b76b
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_timer.c
@@ -0,0 +1,412 @@
+//==========================================================================
+//
+// sys/netinet/tcp_timer.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_timer.c,v 1.15 1999/11/15 05:50:59 hugh Exp $ */
+/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef TUBA_INCLUDE
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+
+int tcp_keepidle = TCPTV_KEEP_IDLE;
+int tcp_keepintvl = TCPTV_KEEPINTVL;
+int tcp_maxpersistidle = TCPTV_KEEP_IDLE; /* max idle time in persist */
+int tcp_maxidle;
+#endif /* TUBA_INCLUDE */
+/*
+ * Fast timeout routine for processing delayed acks
+ */
+void
+tcp_fasttimo()
+{
+ register struct inpcb *inp;
+ register struct tcpcb *tp;
+ int s;
+
+ s = splsoftnet();
+ inp = tcbtable.inpt_queue.cqh_first;
+ if (inp) /* XXX */
+ for (; inp != (struct inpcb *)&tcbtable.inpt_queue;
+ inp = inp->inp_queue.cqe_next) {
+ if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
+ (tp->t_flags & TF_DELACK)) {
+ tp->t_flags &= ~TF_DELACK;
+ tp->t_flags |= TF_ACKNOW;
+ tcpstat.tcps_delack++;
+ (void) tcp_output(tp);
+ }
+ }
+ splx(s);
+}
+
+/*
+ * Tcp protocol timeout routine called every 500 ms.
+ * Updates the timers in all active tcb's and
+ * causes finite state machine actions if timers expire.
+ */
+void
+tcp_slowtimo()
+{
+ register struct inpcb *ip, *ipnxt;
+ register struct tcpcb *tp;
+ int s;
+ register long i;
+
+ s = splsoftnet();
+ tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
+ /*
+ * Search through tcb's and update active timers.
+ */
+ ip = tcbtable.inpt_queue.cqh_first;
+ if (ip == (struct inpcb *)0) { /* XXX */
+ splx(s);
+ return;
+ }
+ for (; ip != (struct inpcb *)&tcbtable.inpt_queue; ip = ipnxt) {
+ ipnxt = ip->inp_queue.cqe_next;
+ tp = intotcpcb(ip);
+ if (tp == 0 || tp->t_state == TCPS_LISTEN)
+ continue;
+ for (i = 0; i < TCPT_NTIMERS; i++) {
+ if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
+ (void) tcp_usrreq(tp->t_inpcb->inp_socket,
+ PRU_SLOWTIMO, (struct mbuf *)0,
+ (struct mbuf *)i, (struct mbuf *)0);
+ /* XXX NOT MP SAFE */
+ if ((ipnxt == (void *)&tcbtable.inpt_queue &&
+ tcbtable.inpt_queue.cqh_last != ip) ||
+ ipnxt->inp_queue.cqe_prev != ip)
+ goto tpgone;
+ }
+ }
+ tp->t_idle++;
+ if (tp->t_rtt)
+ tp->t_rtt++;
+tpgone:
+ ;
+ }
+#ifdef TCP_COMPAT_42
+ tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
+ if ((int)tcp_iss < 0)
+ tcp_iss = 0; /* XXX */
+#else /* TCP_COMPAT_42 */
+ tcp_iss += arc4random() % (2 * TCP_ISSINCR / PR_SLOWHZ) + 1; /* increment iss */
+#endif /* !TCP_COMPAT_42 */
+ tcp_now++; /* for timestamps */
+ splx(s);
+}
+#ifndef TUBA_INCLUDE
+
+/*
+ * Cancel all timers for TCP tp.
+ */
+void
+tcp_canceltimers(tp)
+ struct tcpcb *tp;
+{
+ register int i;
+
+ for (i = 0; i < TCPT_NTIMERS; i++)
+ tp->t_timer[i] = 0;
+}
+
+int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
+ { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
+
+int tcp_totbackoff = 511; /* sum of tcp_backoff[] */
+
+/*
+ * TCP timer processing.
+ */
+struct tcpcb *
+tcp_timers(tp, timer)
+ register struct tcpcb *tp;
+ int timer;
+{
+ short rto;
+#ifdef TCP_SACK
+ struct sackhole *p, *q;
+ /*
+ * Free SACK holes for 2MSL and REXMT timers.
+ */
+ if (timer == TCPT_2MSL || timer == TCPT_REXMT) {
+ q = p = tp->snd_holes;
+ while (p != 0) {
+ q = p->next;
+ free(p, M_PCB);
+ p = q;
+ }
+ tp->snd_holes = 0;
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ tp->snd_fack = tp->snd_una;
+ tp->retran_data = 0;
+ tp->snd_awnd = 0;
+#endif /* TCP_FACK */
+ }
+#endif /* TCP_SACK */
+
+ switch (timer) {
+
+ /*
+ * 2 MSL timeout in shutdown went off. If we're closed but
+ * still waiting for peer to close and connection has been idle
+ * too long, or if 2MSL time is up from TIME_WAIT, delete connection
+ * control block. Otherwise, check again in a bit.
+ */
+ case TCPT_2MSL:
+ if (tp->t_state != TCPS_TIME_WAIT &&
+ tp->t_idle <= tcp_maxidle)
+ tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
+ else
+ tp = tcp_close(tp);
+ break;
+
+ /*
+ * Retransmission timer went off. Message has not
+ * been acked within retransmit interval. Back off
+ * to a longer retransmit interval and retransmit one segment.
+ */
+ case TCPT_REXMT:
+ if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
+ tp->t_rxtshift = TCP_MAXRXTSHIFT;
+ tcpstat.tcps_timeoutdrop++;
+ tp = tcp_drop(tp, tp->t_softerror ?
+ tp->t_softerror : ETIMEDOUT);
+ break;
+ }
+ tcpstat.tcps_rexmttimeo++;
+ rto = TCP_REXMTVAL(tp);
+ if (rto < tp->t_rttmin)
+ rto = tp->t_rttmin;
+ TCPT_RANGESET(tp->t_rxtcur,
+ rto * tcp_backoff[tp->t_rxtshift],
+ tp->t_rttmin, TCPTV_REXMTMAX);
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ /*
+ * If losing, let the lower level know and try for
+ * a better route. Also, if we backed off this far,
+ * our srtt estimate is probably bogus. Clobber it
+ * so we'll take the next rtt measurement as our srtt;
+ * move the current srtt into rttvar to keep the current
+ * retransmit times until then.
+ */
+ if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
+ in_losing(tp->t_inpcb);
+ tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
+ tp->t_srtt = 0;
+ }
+ tp->snd_nxt = tp->snd_una;
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ /*
+ * Note: We overload snd_last to function also as the
+ * snd_last variable described in RFC 2582
+ */
+ tp->snd_last = tp->snd_max;
+#endif /* TCP_SACK or TCP_NEWRENO */
+ /*
+ * If timing a segment in this window, stop the timer.
+ */
+ tp->t_rtt = 0;
+ /*
+ * Close the congestion window down to one segment
+ * (we'll open it by one segment for each ack we get).
+ * Since we probably have a window's worth of unacked
+ * data accumulated, this "slow start" keeps us from
+ * dumping all that data as back-to-back packets (which
+ * might overwhelm an intermediate gateway).
+ *
+ * There are two phases to the opening: Initially we
+ * open by one mss on each ack. This makes the window
+ * size increase exponentially with time. If the
+ * window is larger than the path can handle, this
+ * exponential growth results in dropped packet(s)
+ * almost immediately. To get more time between
+ * drops but still "push" the network to take advantage
+ * of improving conditions, we switch from exponential
+ * to linear window opening at some threshhold size.
+ * For a threshhold, we use half the current window
+ * size, truncated to a multiple of the mss.
+ *
+ * (the minimum cwnd that will give us exponential
+ * growth is 2 mss. We don't allow the threshhold
+ * to go below this.)
+ */
+ {
+ u_long win = ulmin(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
+ if (win < 2)
+ win = 2;
+ tp->snd_cwnd = tp->t_maxseg;
+ tp->snd_ssthresh = win * tp->t_maxseg;
+ tp->t_dupacks = 0;
+ }
+ (void) tcp_output(tp);
+ break;
+
+ /*
+ * Persistance timer into zero window.
+ * Force a byte to be output, if possible.
+ */
+ case TCPT_PERSIST:
+ tcpstat.tcps_persisttimeo++;
+ /*
+ * Hack: if the peer is dead/unreachable, we do not
+ * time out if the window is closed. After a full
+ * backoff, drop the connection if the idle time
+ * (no responses to probes) reaches the maximum
+ * backoff that we would use if retransmitting.
+ */
+ rto = TCP_REXMTVAL(tp);
+ if (rto < tp->t_rttmin)
+ rto = tp->t_rttmin;
+ if (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
+ (tp->t_idle >= tcp_maxpersistidle ||
+ tp->t_idle >= rto * tcp_totbackoff)) {
+ tcpstat.tcps_persistdrop++;
+ tp = tcp_drop(tp, ETIMEDOUT);
+ break;
+ }
+ tcp_setpersist(tp);
+ tp->t_force = 1;
+ (void) tcp_output(tp);
+ tp->t_force = 0;
+ break;
+
+ /*
+ * Keep-alive timer went off; send something
+ * or drop connection if idle for too long.
+ */
+ case TCPT_KEEP:
+ tcpstat.tcps_keeptimeo++;
+ if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
+ goto dropit;
+ if (tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE &&
+ tp->t_state <= TCPS_CLOSE_WAIT) {
+ if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
+ goto dropit;
+ /*
+ * Send a packet designed to force a response
+ * if the peer is up and reachable:
+ * either an ACK if the connection is still alive,
+ * or an RST if the peer has closed the connection
+ * due to timeout or reboot.
+ * Using sequence number tp->snd_una-1
+ * causes the transmitted zero-length segment
+ * to lie outside the receive window;
+ * by the protocol spec, this requires the
+ * correspondent TCP to respond.
+ */
+ tcpstat.tcps_keepprobe++;
+#ifdef TCP_COMPAT_42
+ /*
+ * The keepalive packet must have nonzero length
+ * to get a 4.2 host to respond.
+ */
+ tcp_respond(tp,
+ mtod(tp->t_template, caddr_t),
+ (struct mbuf *)NULL,
+ tp->rcv_nxt - 1, tp->snd_una - 1, 0);
+#else
+ tcp_respond(tp,
+ mtod(tp->t_template, caddr_t),
+ (struct mbuf *)NULL,
+ tp->rcv_nxt, tp->snd_una - 1, 0);
+#endif
+ tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
+ } else
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+ break;
+ dropit:
+ tcpstat.tcps_keepdrops++;
+ tp = tcp_drop(tp, ETIMEDOUT);
+ break;
+ }
+ return (tp);
+}
+#endif /* TUBA_INCLUDE */
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_usrreq.c b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_usrreq.c
new file mode 100644
index 0000000..5f049a8
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/tcp_usrreq.c
@@ -0,0 +1,942 @@
+//==========================================================================
+//
+// sys/netinet/tcp_usrreq.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: tcp_usrreq.c,v 1.37 1999/12/08 06:50:20 itojun Exp $ */
+/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#ifndef __ECOS
+#include <sys/systm.h>
+#endif
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+#ifndef __ECOS
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/ucred.h>
+
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_debug.h>
+#ifndef __ECOS
+#include <dev/rndvar.h>
+#endif
+
+#ifdef IPSEC
+extern int check_ipsec_policy __P((struct inpcb *, u_int32_t));
+#endif
+
+#ifdef INET6
+#include <sys/domain.h>
+#endif /* INET6 */
+
+/*
+ * TCP protocol interface to socket abstraction.
+ */
+extern char *tcpstates[];
+extern int tcptv_keep_init;
+
+/* from in_pcb.c */
+extern struct baddynamicports baddynamicports;
+
+int tcp_ident __P((void *, size_t *, void *, size_t));
+
+#if defined(INET6) && !defined(TCP6)
+int
+tcp6_usrreq(so, req, m, nam, control, p)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+ struct proc *p;
+{
+ return tcp_usrreq(so, req, m, nam, control);
+}
+#endif
+
+/*
+ * Process a TCP user request for TCP tb. If this is a send request
+ * then m is the mbuf chain of send data. If this is a timer expiration
+ * (called from the software clock routine), then timertype tells which timer.
+ */
+/*ARGSUSED*/
+int
+tcp_usrreq(so, req, m, nam, control)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ struct sockaddr_in *sin;
+ register struct inpcb *inp;
+ register struct tcpcb *tp = NULL;
+ int s;
+ int error = 0;
+ int ostate;
+
+ if (req == PRU_CONTROL) {
+#ifdef INET6
+ if (sotopf(so) == PF_INET6)
+ return in6_control(so, (u_long)m, (caddr_t)nam,
+ (struct ifnet *)control, 0);
+ else
+#endif /* INET6 */
+ return (in_control(so, (u_long)m, (caddr_t)nam,
+ (struct ifnet *)control));
+ }
+ if (control && control->m_len) {
+ m_freem(control);
+ if (m)
+ m_freem(m);
+ return (EINVAL);
+ }
+
+ s = splsoftnet();
+ inp = sotoinpcb(so);
+ /*
+ * When a TCP is attached to a socket, then there will be
+ * a (struct inpcb) pointed at by the socket, and this
+ * structure will point at a subsidary (struct tcpcb).
+ */
+ if (inp == 0 && req != PRU_ATTACH) {
+ splx(s);
+ /*
+ * The following corrects an mbuf leak under rare
+ * circumstances
+ */
+ if (m && (req == PRU_SEND || req == PRU_SENDOOB))
+ m_freem(m);
+ return (EINVAL); /* XXX */
+ }
+ if (inp) {
+ tp = intotcpcb(inp);
+ /* WHAT IF TP IS 0? */
+#ifdef KPROF
+ tcp_acounts[tp->t_state][req]++;
+#endif
+ ostate = tp->t_state;
+ } else
+ ostate = 0;
+ switch (req) {
+
+ /*
+ * TCP attaches to socket via PRU_ATTACH, reserving space,
+ * and an internet control block.
+ */
+ case PRU_ATTACH:
+ if (inp) {
+ error = EISCONN;
+ break;
+ }
+ error = tcp_attach(so);
+ if (error)
+ break;
+ if ((so->so_options & SO_LINGER) && so->so_linger == 0)
+ so->so_linger = TCP_LINGERTIME;
+ tp = sototcpcb(so);
+ break;
+
+ /*
+ * PRU_DETACH detaches the TCP protocol from the socket.
+ * If the protocol state is non-embryonic, then can't
+ * do this directly: have to initiate a PRU_DISCONNECT,
+ * which may finish later; embryonic TCB's can just
+ * be discarded here.
+ */
+ case PRU_DETACH:
+ tp = tcp_disconnect(tp);
+ break;
+
+ /*
+ * Give the socket an address.
+ */
+ case PRU_BIND:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ error = in6_pcbbind(inp, nam);
+ else
+#endif
+ error = in_pcbbind(inp, nam);
+ if (error)
+ break;
+#ifdef INET6
+ /*
+ * If we bind to an address, set up the tp->pf accordingly!
+ */
+ if (inp->inp_flags & INP_IPV6) {
+ /* If a PF_INET6 socket... */
+ if (inp->inp_flags & INP_IPV6_MAPPED)
+ tp->pf = AF_INET;
+ else if ((inp->inp_flags & INP_IPV6_UNDEC) == 0)
+ tp->pf = AF_INET6;
+ /* else tp->pf is still 0. */
+ }
+ /* else socket is PF_INET, and tp->pf is PF_INET. */
+#endif /* INET6 */
+ break;
+
+ /*
+ * Prepare to accept connections.
+ */
+ case PRU_LISTEN:
+ if (inp->inp_lport == 0) {
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ error = in6_pcbbind(inp, NULL);
+ else
+#endif
+ error = in_pcbbind(inp, NULL);
+ }
+ /* If the in_pcbbind() above is called, the tp->pf
+ should still be whatever it was before. */
+ if (error == 0)
+ tp->t_state = TCPS_LISTEN;
+ break;
+
+ /*
+ * Initiate connection to peer.
+ * Create a template for use in transmissions on this connection.
+ * Enter SYN_SENT state, and mark socket as connecting.
+ * Start keep-alive timer, and seed output sequence space.
+ * Send initial segment on connection.
+ */
+ case PRU_CONNECT:
+ sin = mtod(nam, struct sockaddr_in *);
+
+#ifdef INET6
+ if (sin->sin_family == AF_INET6) {
+ struct in6_addr *in6_addr = &mtod(nam,
+ struct sockaddr_in6 *)->sin6_addr;
+
+ if (IN6_IS_ADDR_UNSPECIFIED(in6_addr) ||
+ IN6_IS_ADDR_MULTICAST(in6_addr) ||
+ (IN6_IS_ADDR_V4MAPPED(in6_addr) &&
+ ((in6_addr->s6_addr32[3] == INADDR_ANY) ||
+ IN_MULTICAST(in6_addr->s6_addr32[3]) ||
+ in_broadcast(sin->sin_addr, NULL)))) {
+ error = EINVAL;
+ break;
+ }
+
+ if (inp->inp_lport == 0) {
+ error = in6_pcbbind(inp, NULL);
+ if (error)
+ break;
+ }
+ error = in6_pcbconnect(inp, nam);
+ } else if (sin->sin_family == AF_INET)
+#endif /* INET6 */
+ {
+ if ((sin->sin_addr.s_addr == INADDR_ANY) ||
+ IN_MULTICAST(sin->sin_addr.s_addr) ||
+ in_broadcast(sin->sin_addr, NULL)) {
+ error = EINVAL;
+ break;
+ }
+
+ /* Trying to connect to some broadcast address */
+ if (in_broadcast(sin->sin_addr, NULL)) {
+ error = EINVAL;
+ break;
+ }
+
+ if (inp->inp_lport == 0) {
+ error = in_pcbbind(inp, NULL);
+ if (error)
+ break;
+ }
+ error = in_pcbconnect(inp, nam);
+ }
+
+ if (error)
+ break;
+
+#ifdef INET6
+ /*
+ * With a connection, I now know the version of IP
+ * is in use and hence can set tp->pf with authority.
+ */
+ if (inp->inp_flags & INP_IPV6) {
+ if (inp->inp_flags & INP_IPV6_MAPPED)
+ tp->pf = PF_INET;
+ else
+ tp->pf = PF_INET6;
+ }
+ /* else I'm a PF_INET socket, and hence tp->pf is PF_INET. */
+#endif /* INET6 */
+
+ tp->t_template = tcp_template(tp);
+ if (tp->t_template == 0) {
+ in_pcbdisconnect(inp);
+ error = ENOBUFS;
+ break;
+ }
+
+#ifdef INET6
+ if ((inp->inp_flags & INP_IPV6) && (tp->pf == PF_INET)) {
+ inp->inp_ip.ip_ttl = ip_defttl;
+ inp->inp_ip.ip_tos = 0;
+ }
+#endif /* INET6 */
+
+ so->so_state |= SS_CONNECTOUT;
+ /* Compute window scaling to request. */
+ while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
+ (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
+ tp->request_r_scale++;
+ soisconnecting(so);
+ tcpstat.tcps_connattempt++;
+ tp->t_state = TCPS_SYN_SENT;
+ tp->t_timer[TCPT_KEEP] = tcptv_keep_init;
+ tp->iss = tcp_iss;
+#ifdef TCP_COMPAT_42
+ tcp_iss += TCP_ISSINCR/2;
+#else /* TCP_COMPAT_42 */
+ tcp_iss += arc4random() % TCP_ISSINCR + 1;
+#endif /* !TCP_COMPAT_42 */
+ tcp_sendseqinit(tp);
+#if defined(TCP_SACK) || defined(TCP_NEWRENO)
+ tp->snd_last = tp->snd_una;
+#endif
+#if defined(TCP_SACK) && defined(TCP_FACK)
+ tp->snd_fack = tp->snd_una;
+ tp->retran_data = 0;
+ tp->snd_awnd = 0;
+#endif
+ error = tcp_output(tp);
+ break;
+
+ /*
+ * Create a TCP connection between two sockets.
+ */
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ break;
+
+ /*
+ * Initiate disconnect from peer.
+ * If connection never passed embryonic stage, just drop;
+ * else if don't need to let data drain, then can just drop anyways,
+ * else have to begin TCP shutdown process: mark socket disconnecting,
+ * drain unread data, state switch to reflect user close, and
+ * send segment (e.g. FIN) to peer. Socket will be really disconnected
+ * when peer sends FIN and acks ours.
+ *
+ * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
+ */
+ case PRU_DISCONNECT:
+ tp = tcp_disconnect(tp);
+ break;
+
+ /*
+ * Accept a connection. Essentially all the work is
+ * done at higher levels; just return the address
+ * of the peer, storing through addr.
+ */
+ case PRU_ACCEPT:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ in6_setpeeraddr(inp, nam);
+ else
+#endif
+ in_setpeeraddr(inp, nam);
+ break;
+
+ /*
+ * Mark the connection as being incapable of further output.
+ */
+ case PRU_SHUTDOWN:
+ if (so->so_state & SS_CANTSENDMORE)
+ break;
+ socantsendmore(so);
+ tp = tcp_usrclosed(tp);
+ if (tp)
+ error = tcp_output(tp);
+ break;
+
+ /*
+ * After a receive, possibly send window update to peer.
+ */
+ case PRU_RCVD:
+ (void) tcp_output(tp);
+ break;
+
+ /*
+ * Do a send by putting data in output queue and updating urgent
+ * marker if URG set. Possibly send more data.
+ */
+ case PRU_SEND:
+#ifdef IPSEC
+ error = check_ipsec_policy(inp, 0);
+ if (error)
+ break;
+#endif
+ sbappend(&so->so_snd, m);
+ error = tcp_output(tp);
+ break;
+
+ /*
+ * Abort the TCP.
+ */
+ case PRU_ABORT:
+ tp = tcp_drop(tp, ECONNABORTED);
+ break;
+
+ case PRU_SENSE:
+#ifndef __ECOS
+ ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
+#endif
+ (void) splx(s);
+ return (0);
+
+ case PRU_RCVOOB:
+ if ((so->so_oobmark == 0 &&
+ (so->so_state & SS_RCVATMARK) == 0) ||
+ so->so_options & SO_OOBINLINE ||
+ tp->t_oobflags & TCPOOB_HADDATA) {
+ error = EINVAL;
+ break;
+ }
+ if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
+ error = EWOULDBLOCK;
+ break;
+ }
+ m->m_len = 1;
+ *mtod(m, caddr_t) = tp->t_iobc;
+ if (((long)nam & MSG_PEEK) == 0)
+ tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
+ break;
+
+ case PRU_SENDOOB:
+ if (sbspace(&so->so_snd) < -512) {
+ m_freem(m);
+ error = ENOBUFS;
+ break;
+ }
+ /*
+ * According to RFC961 (Assigned Protocols),
+ * the urgent pointer points to the last octet
+ * of urgent data. We continue, however,
+ * to consider it to indicate the first octet
+ * of data past the urgent section.
+ * Otherwise, snd_up should be one lower.
+ */
+ sbappend(&so->so_snd, m);
+ tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
+ tp->t_force = 1;
+ error = tcp_output(tp);
+ tp->t_force = 0;
+ break;
+
+ case PRU_SOCKADDR:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ in6_setsockaddr(inp, nam);
+ else
+#endif
+ in_setsockaddr(inp, nam);
+ break;
+
+ case PRU_PEERADDR:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ in6_setpeeraddr(inp, nam);
+ else
+#endif
+ in_setpeeraddr(inp, nam);
+ break;
+
+ /*
+ * TCP slow timer went off; going through this
+ * routine for tracing's sake.
+ */
+ case PRU_SLOWTIMO:
+ tp = tcp_timers(tp, (long)nam);
+ req |= (long)nam << 8; /* for debug's sake */
+ break;
+
+ default:
+ panic("tcp_usrreq");
+ }
+#ifdef TCPDEBUG
+ if (tp && (so->so_options & SO_DEBUG))
+ tcp_trace(TA_USER, ostate, tp, (caddr_t)0, req, 0);
+#endif /* TCPDEBUG */
+ splx(s);
+ return (error);
+}
+
+int
+tcp_ctloutput(op, so, level, optname, mp)
+ int op;
+ struct socket *so;
+ int level, optname;
+ struct mbuf **mp;
+{
+ int error = 0, s;
+ struct inpcb *inp;
+ register struct tcpcb *tp;
+ register struct mbuf *m;
+ register int i;
+
+ s = splsoftnet();
+ inp = sotoinpcb(so);
+ if (inp == NULL) {
+ splx(s);
+ if (op == PRCO_SETOPT && *mp)
+ (void) m_free(*mp);
+ return (ECONNRESET);
+ }
+#ifdef INET6
+ tp = intotcpcb(inp);
+#endif /* INET6 */
+ if (level != IPPROTO_TCP) {
+#ifdef INET6
+ /*
+ * Not sure if this is the best approach.
+ * It seems to be, but we don't set tp->pf until the connection
+ * is established, which may lead to confusion in the case of
+ * AF_INET6 sockets which get SET/GET options for IPv4.
+ */
+ if (tp->pf == PF_INET6)
+ error = ip6_ctloutput(op, so, level, optname, mp);
+ else
+#endif /* INET6 */
+ error = ip_ctloutput(op, so, level, optname, mp);
+ splx(s);
+ return (error);
+ }
+#ifndef INET6
+ tp = intotcpcb(inp);
+#endif /* !INET6 */
+
+ switch (op) {
+
+ case PRCO_SETOPT:
+ m = *mp;
+ switch (optname) {
+
+ case TCP_NODELAY:
+ if (m == NULL || m->m_len < sizeof (int))
+ error = EINVAL;
+ else if (*mtod(m, int *))
+ tp->t_flags |= TF_NODELAY;
+ else
+ tp->t_flags &= ~TF_NODELAY;
+ break;
+
+ case TCP_MAXSEG:
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ break;
+ }
+
+ i = *mtod(m, int *);
+ if (i > 0 && i <= tp->t_maxseg)
+ tp->t_maxseg = i;
+ else
+ error = EINVAL;
+ break;
+
+#ifdef TCP_SACK
+ case TCP_SACK_DISABLE:
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ break;
+ }
+
+ if (TCPS_HAVEESTABLISHED(tp->t_state)) {
+ error = EPERM;
+ break;
+ }
+
+ if (tp->t_flags & TF_SIGNATURE) {
+ error = EPERM;
+ break;
+ }
+
+ if (*mtod(m, int *))
+ tp->sack_disable = 1;
+ else
+ tp->sack_disable = 0;
+ break;
+#endif
+#ifdef TCP_SIGNATURE
+ case TCP_SIGNATURE_ENABLE:
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ break;
+ }
+
+ if (TCPS_HAVEESTABLISHED(tp->t_state)) {
+ error = EPERM;
+ break;
+ }
+
+ if (*mtod(m, int *)) {
+ tp->t_flags |= TF_SIGNATURE;
+#ifdef TCP_SACK
+ tp->sack_disable = 1;
+#endif /* TCP_SACK */
+ } else
+ tp->t_flags &= ~TF_SIGNATURE;
+ break;
+#endif /* TCP_SIGNATURE */
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ if (m)
+ (void) m_free(m);
+ break;
+
+ case PRCO_GETOPT:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+
+ switch (optname) {
+ case TCP_NODELAY:
+ *mtod(m, int *) = tp->t_flags & TF_NODELAY;
+ break;
+ case TCP_MAXSEG:
+ *mtod(m, int *) = tp->t_maxseg;
+ break;
+#ifdef TCP_SACK
+ case TCP_SACK_DISABLE:
+ *mtod(m, int *) = tp->sack_disable;
+ break;
+#endif
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ break;
+ }
+ splx(s);
+ return (error);
+}
+
+#ifndef TCP_SENDSPACE
+#define TCP_SENDSPACE 1024*16;
+#endif
+u_int tcp_sendspace = TCP_SENDSPACE;
+#ifndef TCP_RECVSPACE
+#define TCP_RECVSPACE 1024*16;
+#endif
+u_int tcp_recvspace = TCP_RECVSPACE;
+
+/*
+ * Attach TCP protocol to socket, allocating
+ * internet protocol control block, tcp control block,
+ * bufer space, and entering LISTEN state if to accept connections.
+ */
+int
+tcp_attach(so)
+ struct socket *so;
+{
+ register struct tcpcb *tp;
+ struct inpcb *inp;
+ int error;
+
+ if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+ error = soreserve(so, tcp_sendspace, tcp_recvspace);
+ if (error)
+ return (error);
+ }
+ error = in_pcballoc(so, &tcbtable);
+ if (error)
+ return (error);
+ inp = sotoinpcb(so);
+ tp = tcp_newtcpcb(inp);
+ if (tp == NULL) {
+ int nofd = so->so_state & SS_NOFDREF; /* XXX */
+
+ so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
+ in_pcbdetach(inp);
+ so->so_state |= nofd;
+ return (ENOBUFS);
+ }
+ tp->t_state = TCPS_CLOSED;
+ return (0);
+}
+
+/*
+ * Initiate (or continue) disconnect.
+ * If embryonic state, just send reset (once).
+ * If in ``let data drain'' option and linger null, just drop.
+ * Otherwise (hard), mark socket disconnecting and drop
+ * current input data; switch states based on user close, and
+ * send segment to peer (with FIN).
+ */
+struct tcpcb *
+tcp_disconnect(tp)
+ register struct tcpcb *tp;
+{
+ struct socket *so = tp->t_inpcb->inp_socket;
+
+ if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
+ tp = tcp_close(tp);
+ else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
+ tp = tcp_drop(tp, 0);
+ else {
+ soisdisconnecting(so);
+ sbflush(&so->so_rcv);
+ tp = tcp_usrclosed(tp);
+ if (tp)
+ (void) tcp_output(tp);
+ }
+ return (tp);
+}
+
+/*
+ * User issued close, and wish to trail through shutdown states:
+ * if never received SYN, just forget it. If got a SYN from peer,
+ * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
+ * If already got a FIN from peer, then almost done; go to LAST_ACK
+ * state. In all other cases, have already sent FIN to peer (e.g.
+ * after PRU_SHUTDOWN), and just have to play tedious game waiting
+ * for peer to send FIN or not respond to keep-alives, etc.
+ * We can let the user exit from the close as soon as the FIN is acked.
+ */
+struct tcpcb *
+tcp_usrclosed(tp)
+ register struct tcpcb *tp;
+{
+
+ switch (tp->t_state) {
+
+ case TCPS_CLOSED:
+ case TCPS_LISTEN:
+ case TCPS_SYN_SENT:
+ tp->t_state = TCPS_CLOSED;
+ tp = tcp_close(tp);
+ break;
+
+ case TCPS_SYN_RECEIVED:
+ case TCPS_ESTABLISHED:
+ tp->t_state = TCPS_FIN_WAIT_1;
+ break;
+
+ case TCPS_CLOSE_WAIT:
+ tp->t_state = TCPS_LAST_ACK;
+ break;
+ }
+ if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
+ soisdisconnected(tp->t_inpcb->inp_socket);
+ /*
+ * If we are in FIN_WAIT_2, we arrived here because the
+ * application did a shutdown of the send side. Like the
+ * case of a transition from FIN_WAIT_1 to FIN_WAIT_2 after
+ * a full close, we start a timer to make sure sockets are
+ * not left in FIN_WAIT_2 forever.
+ */
+ if (tp->t_state == TCPS_FIN_WAIT_2)
+ tp->t_timer[TCPT_2MSL] = tcp_maxidle;
+ }
+ return (tp);
+}
+
+/*
+ * Look up a socket for ident..
+ */
+int
+tcp_ident(oldp, oldlenp, newp, newlen)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+{
+ int error = 0, s;
+ struct tcp_ident_mapping tir;
+ struct inpcb *inp;
+ struct sockaddr_in *fin, *lin;
+
+ if (oldp == NULL || newp != NULL || newlen != 0)
+ return (EINVAL);
+ if (*oldlenp < sizeof(tir))
+ return (ENOMEM);
+ if ((error = copyin(oldp, &tir, sizeof (tir))) != 0 )
+ return (error);
+ if (tir.faddr.sa_len != sizeof (struct sockaddr) ||
+ tir.faddr.sa_family != AF_INET)
+ return (EINVAL);
+ fin = (struct sockaddr_in *)&tir.faddr;
+ lin = (struct sockaddr_in *)&tir.laddr;
+
+ s = splsoftnet();
+ inp = in_pcbhashlookup(&tcbtable, fin->sin_addr, fin->sin_port,
+ lin->sin_addr, lin->sin_port);
+ if (inp == NULL) {
+ ++tcpstat.tcps_pcbhashmiss;
+ inp = in_pcblookup(&tcbtable, &fin->sin_addr, fin->sin_port,
+ &lin->sin_addr, lin->sin_port, 0);
+ }
+ if (inp != NULL && (inp->inp_socket->so_state & SS_CONNECTOUT)) {
+ tir.ruid = inp->inp_socket->so_ruid;
+ tir.euid = inp->inp_socket->so_euid;
+ } else {
+ tir.ruid = -1;
+ tir.euid = -1;
+ }
+ splx(s);
+
+ *oldlenp = sizeof (tir);
+ error = copyout((void *)&tir, oldp, sizeof (tir));
+ return (error);
+}
+
+#ifdef CYGPKG_NET_SYSCTL
+/*
+ * Sysctl for tcp variables.
+ */
+int
+tcp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+{
+
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case TCPCTL_RFC1323:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &tcp_do_rfc1323));
+#ifdef TCP_SACK
+ case TCPCTL_SACK:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &tcp_do_sack));
+#endif
+ case TCPCTL_MSSDFLT:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &tcp_mssdflt));
+ case TCPCTL_KEEPINITTIME:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &tcptv_keep_init));
+
+ case TCPCTL_KEEPIDLE:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &tcp_keepidle));
+
+ case TCPCTL_KEEPINTVL:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &tcp_keepintvl));
+
+ case TCPCTL_SLOWHZ:
+ return (sysctl_rdint(oldp, oldlenp, newp, PR_SLOWHZ));
+
+ case TCPCTL_BADDYNAMIC:
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ baddynamicports.tcp, sizeof(baddynamicports.tcp)));
+
+ case TCPCTL_RECVSPACE:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,&tcp_recvspace));
+
+ case TCPCTL_SENDSPACE:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,&tcp_sendspace));
+ case TCPCTL_IDENT:
+ return (tcp_ident(oldp, oldlenp, newp, newlen));
+ default:
+ return (ENOPROTOOPT);
+ }
+ /* NOTREACHED */
+}
+#endif // CYGPKG_NET_SYSCTL
diff --git a/ecos/packages/net/tcpip/current/src/sys/netinet/udp_usrreq.c b/ecos/packages/net/tcpip/current/src/sys/netinet/udp_usrreq.c
new file mode 100644
index 0000000..b5549f6
--- /dev/null
+++ b/ecos/packages/net/tcpip/current/src/sys/netinet/udp_usrreq.c
@@ -0,0 +1,1371 @@
+//==========================================================================
+//
+// sys/netinet/udp_usrreq.c
+//
+//
+//
+//==========================================================================
+// ####BSDALTCOPYRIGHTBEGIN####
+// -------------------------------------------
+// Portions of this software may have been derived from OpenBSD
+// or other sources, and if so are covered by the appropriate copyright
+// and license included herein.
+// -------------------------------------------
+// ####BSDALTCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+/* $OpenBSD: udp_usrreq.c,v 1.30 1999/12/12 10:59:41 itojun Exp $ */
+/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94
+ */
+
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#ifdef __ECOS
+#undef errno
+#endif
+#ifndef __ECOS
+#include <sys/stat.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+
+extern int check_ipsec_policy __P((struct inpcb *, u_int32_t));
+#endif
+
+#include <machine/stdarg.h>
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <netinet6/ip6.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/icmp6.h>
+#include <netinet6/ip6protosw.h>
+
+#ifndef CREATE_IPV6_MAPPED
+#define CREATE_IPV6_MAPPED(a6, a4) \
+do { \
+ bzero(&(a6), sizeof(a6)); \
+ (a6).s6_addr[10] = (a6).s6_addr[11] = 0xff; \
+ *(u_int32_t *)&(a6).s6_addr[12] = (a4); \
+} while (0)
+#endif
+
+extern int ip6_defhlim;
+
+#endif /* INET6 */
+
+/*
+ * UDP protocol implementation.
+ * Per RFC 768, August, 1980.
+ */
+int udpcksum = 1;
+
+
+static void udp_detach __P((struct inpcb *));
+static void udp_notify __P((struct inpcb *, int));
+static struct mbuf *udp_saveopt __P((caddr_t, int, int));
+
+#ifndef UDBHASHSIZE
+#define UDBHASHSIZE 128
+#endif
+int udbhashsize = UDBHASHSIZE;
+
+/* from in_pcb.c */
+extern struct baddynamicports baddynamicports;
+
+void
+udp_init()
+{
+
+ in_pcbinit(&udbtable, udbhashsize);
+}
+
+#if defined(INET6) && !defined(TCP6)
+int
+udp6_input(mp, offp, proto)
+ struct mbuf **mp;
+ int *offp, proto;
+{
+ struct mbuf *m = *mp;
+
+#if defined(NFAITH) && 0 < NFAITH
+ if (m->m_pkthdr.rcvif) {
+ if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
+ /* XXX send icmp6 host/port unreach? */
+ m_freem(m);
+ return IPPROTO_DONE;
+ }
+ }
+#endif
+
+ udp_input(m, *offp, proto);
+ return IPPROTO_DONE;
+}
+#endif
+
+void
+#if __STDC__
+udp_input(struct mbuf *m, ...)
+#else
+udp_input(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ register struct ip *ip;
+ register struct udphdr *uh;
+ register struct inpcb *inp;
+ struct mbuf *opts = 0;
+ int len;
+ struct ip save_ip;
+ int iphlen;
+ va_list ap;
+ u_int16_t savesum;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+#ifdef INET6
+ struct sockaddr_in6 sin6;
+#endif /* INET6 */
+ } srcsa, dstsa;
+#ifdef INET6
+ struct ip6_hdr *ipv6;
+ struct sockaddr_in6 src_v4mapped;
+#endif /* INET6 */
+#ifdef IPSEC
+ struct tdb *tdb = NULL;
+#endif /* IPSEC */
+
+ va_start(ap, m);
+ iphlen = va_arg(ap, int);
+ va_end(ap);
+
+ udpstat.udps_ipackets++;
+
+#ifdef IPSEC
+ /* Save the last SA which was used to process the mbuf */
+ if ((m->m_flags & (M_CONF|M_AUTH)) && m->m_pkthdr.tdbi) {
+ struct tdb_ident *tdbi = m->m_pkthdr.tdbi;
+ /* XXX gettdb() should really be called at spltdb(). */
+ /* XXX this is splsoftnet(), currently they are the same. */
+ tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
+#endif /* IPSEC */
+
+ switch (mtod(m, struct ip *)->ip_v) {
+ case 4:
+ ip = mtod(m, struct ip *);
+#ifdef INET6
+ ipv6 = NULL;
+#endif /* INET6 */
+ srcsa.sa.sa_family = AF_INET;
+ break;
+#ifdef INET6
+ case 6:
+ ip = NULL;
+ ipv6 = mtod(m, struct ip6_hdr *);
+ srcsa.sa.sa_family = AF_INET6;
+ break;
+#endif /* INET6 */
+ default:
+#ifdef __ECOS
+ diag_printf("udp_input: received unknown IP version %d",
+ mtod(m, struct ip *)->ip_v);
+#else
+ printf("udp_input: received unknown IP version %d",
+ mtod(m, struct ip *)->ip_v);
+#endif
+ goto bad;
+ }
+
+ /*
+ * Strip IP options, if any; should skip this,
+ * make available to user, and use on returned packets,
+ * but we don't yet have a way to check the checksum
+ * with options still present.
+ */
+ /*
+ * (contd. from above...) Furthermore, we may want to strip options
+ * for such things as ICMP errors, where options just get in the way.
+ */
+ if (ip && iphlen > sizeof (struct ip)) {
+ ip_stripoptions(m, (struct mbuf *)0);
+ iphlen = sizeof(struct ip);
+ }
+
+ /*
+ * Get IP and UDP header together in first mbuf.
+ */
+ if (m->m_len < iphlen + sizeof(struct udphdr)) {
+ if ((m = m_pullup2(m, iphlen + sizeof(struct udphdr))) == 0) {
+ udpstat.udps_hdrops++;
+ return;
+ }
+#ifdef INET6
+ if (ipv6)
+ ipv6 = mtod(m, struct ip6_hdr *);
+ else
+#endif /* INET6 */
+ ip = mtod(m, struct ip *);
+ }
+ uh = (struct udphdr *)(mtod(m, caddr_t) + iphlen);
+
+ /*
+ * Make mbuf data length reflect UDP length.
+ * If not enough data to reflect UDP length, drop.
+ */
+ len = ntohs((u_int16_t)uh->uh_ulen);
+ if (m->m_pkthdr.len - iphlen != len) {
+ if (len > (m->m_pkthdr.len - iphlen) ||
+ len < sizeof(struct udphdr)) {
+ udpstat.udps_badlen++;
+ goto bad;
+ }
+ m_adj(m, len - (m->m_pkthdr.len - iphlen));
+ }
+ /*
+ * Save a copy of the IP header in case we want restore it
+ * for sending an ICMP error message in response.
+ */
+ if (ip)
+ save_ip = *ip;
+
+ /*
+ * Checksum extended UDP header and data.
+ * from W.R.Stevens: check incoming udp cksums even if
+ * udpcksum is not set.
+ */
+ savesum = uh->uh_sum;
+#ifdef INET6
+ if (ipv6) {
+ /*
+ * In IPv6, the UDP checksum is ALWAYS used.
+ */
+ if ((uh->uh_sum = in6_cksum(m, IPPROTO_UDP, iphlen, len))) {
+ udpstat.udps_badsum++;
+ goto bad;
+ }
+ } else
+#endif /* INET6 */
+ if (uh->uh_sum) {
+ bzero(((struct ipovly *)ip)->ih_x1,
+ sizeof ((struct ipovly *)ip)->ih_x1);
+ ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
+ if ((uh->uh_sum = in_cksum(m, len + sizeof (struct ip))) != 0) {
+ udpstat.udps_badsum++;
+ m_freem(m);
+ return;
+ }
+ } else
+ udpstat.udps_nosum++;
+
+ switch (srcsa.sa.sa_family) {
+ case AF_INET:
+ bzero(&srcsa, sizeof(struct sockaddr_in));
+ srcsa.sin.sin_len = sizeof(struct sockaddr_in);
+ srcsa.sin.sin_family = AF_INET;
+ srcsa.sin.sin_port = uh->uh_sport;
+ srcsa.sin.sin_addr = ip->ip_src;
+
+#ifdef INET6
+ bzero(&src_v4mapped, sizeof(struct sockaddr_in6));
+ src_v4mapped.sin6_len = sizeof(struct sockaddr_in6);
+ src_v4mapped.sin6_family = AF_INET6;
+ src_v4mapped.sin6_port = uh->uh_sport;
+ CREATE_IPV6_MAPPED(src_v4mapped.sin6_addr, ip->ip_src.s_addr);
+#endif /* INET6 */
+
+ bzero(&dstsa, sizeof(struct sockaddr_in));
+ dstsa.sin.sin_len = sizeof(struct sockaddr_in);
+ dstsa.sin.sin_family = AF_INET;
+ dstsa.sin.sin_port = uh->uh_dport;
+ dstsa.sin.sin_addr = ip->ip_dst;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ bzero(&srcsa, sizeof(struct sockaddr_in6));
+ srcsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ srcsa.sin6.sin6_family = AF_INET6;
+ srcsa.sin6.sin6_port = uh->uh_sport;
+ srcsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ipv6->ip6_flow;
+ srcsa.sin6.sin6_addr = ipv6->ip6_src;
+ if (IN6_IS_SCOPE_LINKLOCAL(&srcsa.sin6.sin6_addr))
+ srcsa.sin6.sin6_addr.s6_addr16[1] = 0;
+ if (m->m_pkthdr.rcvif) {
+ if (IN6_IS_SCOPE_LINKLOCAL(&srcsa.sin6.sin6_addr)) {
+ srcsa.sin6.sin6_scope_id =
+ m->m_pkthdr.rcvif->if_index;
+ } else
+ srcsa.sin6.sin6_scope_id = 0;
+ } else
+ srcsa.sin6.sin6_scope_id = 0;
+
+ bzero(&dstsa, sizeof(struct sockaddr_in6));
+ dstsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ dstsa.sin6.sin6_family = AF_INET6;
+ dstsa.sin6.sin6_port = uh->uh_dport;
+ dstsa.sin6.sin6_addr = ipv6->ip6_dst;
+ break;
+#endif /* INET6 */
+ }
+
+#ifdef INET6
+ if ((ipv6 && IN6_IS_ADDR_MULTICAST(&ipv6->ip6_dst)) ||
+ (ip && IN_MULTICAST(ip->ip_dst.s_addr)) ||
+ (ip && in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))) {
+#else /* INET6 */
+ if (IN_MULTICAST(ip->ip_dst.s_addr) ||
+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
+#endif /* INET6 */
+ struct socket *last;
+ /*
+ * Deliver a multicast or broadcast datagram to *all* sockets
+ * for which the local and remote addresses and ports match
+ * those of the incoming datagram. This allows more than
+ * one process to receive multi/broadcasts on the same port.
+ * (This really ought to be done for unicast datagrams as
+ * well, but that would cause problems with existing
+ * applications that open both address-specific sockets and
+ * a wildcard socket listening to the same port -- they would
+ * end up receiving duplicates of every unicast datagram.
+ * Those applications open the multiple sockets to overcome an
+ * inadequacy of the UDP socket interface, but for backwards
+ * compatibility we avoid the problem here rather than
+ * fixing the interface. Maybe 4.5BSD will remedy this?)
+ */
+
+ iphlen += sizeof(struct udphdr);
+
+ /*
+ * Locate pcb(s) for datagram.
+ * (Algorithm copied from raw_intr().)
+ */
+ last = NULL;
+ for (inp = udbtable.inpt_queue.cqh_first;
+ inp != (struct inpcb *)&udbtable.inpt_queue;
+ inp = inp->inp_queue.cqe_next) {
+ if (inp->inp_lport != uh->uh_dport)
+ continue;
+#ifdef INET6
+ if (ipv6) {
+ if (!(inp->inp_flags & INP_IPV6))
+ continue;
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
+ if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6,
+ &ipv6->ip6_dst))
+ continue;
+ } else
+#endif /* INET6 */
+ if (inp->inp_laddr.s_addr != INADDR_ANY) {
+ if (inp->inp_laddr.s_addr !=
+ ip->ip_dst.s_addr)
+ continue;
+ }
+#ifdef INET6
+ if (ipv6) {
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
+ if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6,
+ &ipv6->ip6_src) ||
+ inp->inp_fport != uh->uh_sport)
+ continue;
+ } else
+#endif /* INET6 */
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ if (inp->inp_faddr.s_addr !=
+ ip->ip_src.s_addr ||
+ inp->inp_fport != uh->uh_sport)
+ continue;
+ }
+
+ if (last != NULL) {
+ struct mbuf *n;
+
+ if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
+ opts = NULL;
+#ifdef INET6
+ if (ipv6 && (inp->inp_flags & IN6P_CONTROLOPTS))
+ ip6_savecontrol(inp, &opts, ipv6, n);
+#endif /* INET6 */
+ m_adj(n, iphlen);
+ if (sbappendaddr(&last->so_rcv,
+#ifdef INET6
+ /*
+ * This cruft is needed in (the rare)
+ * case I deliver a {multi,broad}cast
+ * IPv4 packet to an AF_INET6 socket.
+ */
+ ((((struct inpcb *)last->so_pcb)->inp_flags
+ & INP_IPV6) && ip) ?
+ (struct sockaddr *)&src_v4mapped :
+#endif /* INET6 */
+ &srcsa.sa, n, opts) == 0) {
+ m_freem(n);
+ udpstat.udps_fullsock++;
+ } else
+ sorwakeup(last);
+ }
+ }
+ last = inp->inp_socket;
+ /*
+ * Don't look for additional matches if this one does
+ * not have either the SO_REUSEPORT or SO_REUSEADDR
+ * socket options set. This heuristic avoids searching
+ * through all pcbs in the common case of a non-shared
+ * port. It * assumes that an application will never
+ * clear these options after setting them.
+ */
+ if ((last->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0)
+ break;
+ }
+
+ if (last == NULL) {
+ /*
+ * No matching pcb found; discard datagram.
+ * (No need to send an ICMP Port Unreachable
+ * for a broadcast or multicast datgram.)
+ */
+ udpstat.udps_noportbcast++;
+ goto bad;
+ }
+
+ opts = NULL;
+#ifdef INET6
+ if (ipv6 && (inp->inp_flags & IN6P_CONTROLOPTS))
+ ip6_savecontrol(inp, &opts, ipv6, m);
+#endif /* INET6 */
+ m_adj(m, iphlen);
+ if (sbappendaddr(&last->so_rcv,
+#ifdef INET6
+ /*
+ * This cruft is needed in (the rare) case I
+ * deliver a {multi,broad}cast IPv4 packet to
+ * an AF_INET6 socket.
+ */
+ ((((struct inpcb *)last->so_pcb)->inp_flags & INP_IPV6) && ip) ?
+ (struct sockaddr *)&src_v4mapped :
+#endif /* INET6 */
+ &srcsa.sa, m, opts) == 0) {
+ udpstat.udps_fullsock++;
+ goto bad;
+ }
+ sorwakeup(last);
+ return;
+ }
+ /*
+ * Locate pcb for datagram.
+ */
+#ifdef INET6
+ if (ipv6)
+ inp = in6_pcbhashlookup(&udbtable, &ipv6->ip6_src, uh->uh_sport,
+ &ipv6->ip6_dst, uh->uh_dport);
+ else
+#endif /* INET6 */
+ inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
+ ip->ip_dst, uh->uh_dport);
+ if (inp == 0) {
+ ++udpstat.udps_pcbhashmiss;
+#ifdef INET6
+ if (ipv6) {
+ inp = in_pcblookup(&udbtable,
+ (struct in_addr *)&(ipv6->ip6_src),
+ uh->uh_sport, (struct in_addr *)&(ipv6->ip6_dst),
+ uh->uh_dport, INPLOOKUP_WILDCARD | INPLOOKUP_IPV6);
+ } else
+#endif /* INET6 */
+ inp = in_pcblookup(&udbtable, &ip->ip_src, uh->uh_sport,
+ &ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD);
+ if (inp == 0) {
+ udpstat.udps_noport++;
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ udpstat.udps_noportbcast++;
+ goto bad;
+ }
+#ifdef INET6
+ if (ipv6) {
+ icmp6_error(m, ICMP6_DST_UNREACH,
+ ICMP6_DST_UNREACH_NOPORT,0);
+ } else
+#endif /* INET6 */
+ {
+ *ip = save_ip;
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_id);
+ HTONS(ip->ip_off);
+ uh->uh_sum = savesum;
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT,
+ 0, 0);
+ }
+ return;
+ }
+ }
+
+#ifdef IPSEC
+ /* Check if this socket requires security for incoming packets */
+ if ((inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_AUTH)) ||
+ (inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_CONF))) {
+#ifdef notyet
+#ifdef INET6
+ if (ipv6)
+ ipv6_icmp_error(m, ICMPV6_BLAH, ICMPV6_BLAH, 0);
+ else
+#endif /* INET6 */
+ icmp_error(m, ICMP_BLAH, ICMP_BLAH, 0, 0);
+ m = NULL;
+#endif /* notyet */
+ udpstat.udps_nosec++;
+ goto bad;
+ }
+ /* Use tdb_bind_out for this inp's outbound communication */
+ if (tdb)
+ tdb_add_inp(tdb, inp);
+#endif /*IPSEC */
+
+ opts = NULL;
+#ifdef INET6
+ if (ipv6 && (inp->inp_flags & IN6P_CONTROLOPTS))
+ ip6_savecontrol(inp, &opts, ipv6, m);
+#endif /* INET6 */
+ if (ip && (inp->inp_flags & INP_CONTROLOPTS)) {
+ struct mbuf **mp = &opts;
+
+ if (inp->inp_flags & INP_RECVDSTADDR) {
+ *mp = udp_saveopt((caddr_t) &ip->ip_dst,
+ sizeof(struct in_addr), IP_RECVDSTADDR);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+#ifdef notyet
+ /* options were tossed above */
+ if (inp->inp_flags & INP_RECVOPTS) {
+ *mp = udp_saveopt((caddr_t) opts_deleted_above,
+ sizeof(struct in_addr), IP_RECVOPTS);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+ /* ip_srcroute doesn't do what we want here, need to fix */
+ if (inp->inp_flags & INP_RECVRETOPTS) {
+ *mp = udp_saveopt((caddr_t) ip_srcroute(),
+ sizeof(struct in_addr), IP_RECVRETOPTS);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+#endif
+ }
+ iphlen += sizeof(struct udphdr);
+ m_adj(m, iphlen);
+ if (sbappendaddr(&inp->inp_socket->so_rcv,
+#ifdef INET6
+ /*
+ * This cruft is needed to deliver a IPv4 packet to
+ * an AF_INET6 socket.
+ */
+ ((((struct inpcb *)inp->inp_socket->so_pcb)->inp_flags & INP_IPV6)
+ && ip) ? (struct sockaddr *)&src_v4mapped :
+#endif /* INET6 */
+ &srcsa.sa, m, opts) == 0) {
+ udpstat.udps_fullsock++;
+ goto bad;
+ }
+ sorwakeup(inp->inp_socket);
+ return;
+bad:
+ m_freem(m);
+ if (opts)
+ m_freem(opts);
+}
+
+/*
+ * Create a "control" mbuf containing the specified data
+ * with the specified type for presentation with a datagram.
+ */
+struct mbuf *
+udp_saveopt(p, size, type)
+ caddr_t p;
+ register int size;
+ int type;
+{
+ register struct cmsghdr *cp;
+ struct mbuf *m;
+
+ if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)
+ return ((struct mbuf *) NULL);
+ cp = (struct cmsghdr *) mtod(m, struct cmsghdr *);
+ bcopy(p, CMSG_DATA(cp), size);
+ size += sizeof(*cp);
+ m->m_len = size;
+ cp->cmsg_len = size;
+ cp->cmsg_level = IPPROTO_IP;
+ cp->cmsg_type = type;
+ return (m);
+}
+
+/*
+ * Notify a udp user of an asynchronous error;
+ * just wake up so that he can collect error status.
+ */
+static void
+udp_notify(inp, errno)
+ register struct inpcb *inp;
+ int errno;
+{
+ inp->inp_socket->so_error = errno;
+ sorwakeup(inp->inp_socket);
+ sowwakeup(inp->inp_socket);
+}
+
+#if defined(INET6) && !defined(TCP6)
+void
+udp6_ctlinput(cmd, sa, d)
+ int cmd;
+ struct sockaddr *sa;
+ void *d;
+{
+ struct sockaddr_in6 sa6;
+ struct ip6_hdr *ip6;
+ struct mbuf *m;
+ int off;
+
+ if (sa == NULL)
+ return;
+ if (sa->sa_family != AF_INET6)
+ return;
+
+ /* decode parameter from icmp6. */
+ if (d != NULL) {
+ struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
+ ip6 = ip6cp->ip6c_ip6;
+ m = ip6cp->ip6c_m;
+ off = ip6cp->ip6c_off;
+ } else
+ return;
+
+ /* translate addresses into internal form */
+ sa6 = *(struct sockaddr_in6 *)sa;
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr) && m && m->m_pkthdr.rcvif)
+ sa6.sin6_addr.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
+ sa = (struct sockaddr *)&sa6;
+
+ (void)udp_ctlinput(cmd, sa, (void *)ip6);
+}
+#endif
+
+void *
+udp_ctlinput(cmd, sa, v)
+ int cmd;
+ struct sockaddr *sa;
+ void *v;
+{
+ register struct ip *ip = v;
+ register struct udphdr *uh;
+ extern int inetctlerrmap[];
+ void (*notify) __P((struct inpcb *, int)) = udp_notify;
+ int errno;
+
+ if ((unsigned)cmd >= PRC_NCMDS)
+ return NULL;
+ errno = inetctlerrmap[cmd];
+ if (PRC_IS_REDIRECT(cmd))
+ notify = in_rtchange, ip = 0;
+ else if (cmd == PRC_HOSTDEAD)
+ ip = 0;
+ else if (errno == 0)
+ return NULL;
+ if (sa == NULL)
+ return NULL;
+#ifdef INET6
+ if (sa->sa_family == AF_INET6) {
+ if (ip) {
+ struct ip6_hdr *ipv6 = (struct ip6_hdr *)ip;
+
+ uh = (struct udphdr *)((caddr_t)ipv6 + sizeof(struct ip6_hdr));
+#if 0 /*XXX*/
+ in6_pcbnotify(&udbtable, sa, uh->uh_dport,
+ &(ipv6->ip6_src), uh->uh_sport, cmd, udp_notify);
+#endif
+ } else {
+#if 0 /*XXX*/
+ in6_pcbnotify(&udbtable, sa, 0,
+ (struct in6_addr *)&in6addr_any, 0, cmd, udp_notify);
+#endif
+ }
+ } else
+#endif /* INET6 */
+ if (ip) {
+ uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ in_pcbnotify(&udbtable, sa, uh->uh_dport, ip->ip_src,
+ uh->uh_sport, errno, notify);
+ } else
+ in_pcbnotifyall(&udbtable, sa, errno, notify);
+ return NULL;
+}
+
+int
+#if __STDC__
+udp_output(struct mbuf *m, ...)
+#else
+udp_output(m, va_alist)
+ struct mbuf *m;
+ va_dcl
+#endif
+{
+ register struct inpcb *inp;
+ struct mbuf *addr, *control;
+ register struct udpiphdr *ui;
+ register int len = m->m_pkthdr.len;
+ struct in_addr laddr;
+ int s = 0, error = 0;
+ va_list ap;
+#ifdef INET6
+ register struct in6_addr laddr6;
+ int v6packet = 0;
+ struct sockaddr_in6 *sin6 = NULL;
+ struct ip6_pktopts opt, *stickyopt = NULL;
+#endif /* INET6 */
+ int pcbflags = 0;
+
+ va_start(ap, m);
+ inp = va_arg(ap, struct inpcb *);
+ addr = va_arg(ap, struct mbuf *);
+ control = va_arg(ap, struct mbuf *);
+ va_end(ap);
+
+#ifdef INET6
+ v6packet = ((inp->inp_flags & INP_IPV6) &&
+ !(inp->inp_flags & INP_IPV6_MAPPED));
+#endif
+
+#ifdef INET6
+ stickyopt = inp->inp_outputopts6;
+ if (control && v6packet) {
+ error = ip6_setpktoptions(control, &opt,
+ ((inp->inp_socket->so_state & SS_PRIV) != 0));
+ if (error != 0)
+ goto release;
+ inp->inp_outputopts6 = &opt;
+ }
+#endif
+
+ if (addr) {
+#ifdef INET6
+ sin6 = mtod(addr, struct sockaddr_in6 *);
+#endif
+
+ /*
+ * Save current PCB flags because they may change during
+ * temporary connection, particularly the INP_IPV6_UNDEC
+ * flag.
+ */
+ pcbflags = inp->inp_flags;
+
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ laddr6 = inp->inp_laddr6;
+ else
+#endif /* INET6 */
+ laddr = inp->inp_laddr;
+#ifdef INET6
+ if (((inp->inp_flags & INP_IPV6) &&
+ !IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) ||
+ (inp->inp_faddr.s_addr != INADDR_ANY))
+#else /* INET6 */
+ if (inp->inp_faddr.s_addr != INADDR_ANY)
+#endif /* INET6 */
+ {
+ error = EISCONN;
+ goto release;
+ }
+ /*
+ * Must block input while temporarily connected.
+ */
+ s = splsoftnet();
+ error = in_pcbconnect(inp, addr);
+ if (error) {
+ splx(s);
+ goto release;
+ }
+ } else {
+#ifdef INET6
+ if (((inp->inp_flags & INP_IPV6) &&
+ IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) ||
+ (inp->inp_faddr.s_addr == INADDR_ANY))
+#else /* INET6 */
+ if (inp->inp_faddr.s_addr == INADDR_ANY)
+#endif /* INET6 */
+ {
+ error = ENOTCONN;
+ goto release;
+ }
+ }
+ /*
+ * Calculate data length and get a mbuf
+ * for UDP and IP headers.
+ */
+#ifdef INET6
+ /*
+ * Handles IPv4-mapped IPv6 address because temporary connect sets
+ * the right flag.
+ */
+ M_PREPEND(m, v6packet ? (sizeof(struct udphdr) +
+ sizeof(struct ip6_hdr)) : sizeof(struct udpiphdr), M_DONTWAIT);
+#else /* INET6 */
+ M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
+#endif /* INET6 */
+ if (m == 0) {
+ error = ENOBUFS;
+ goto bail;
+ }
+
+ /*
+ * Compute the packet length of the IP header, and
+ * punt if the length looks bogus.
+ */
+ if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
+ error = EMSGSIZE;
+ goto release;
+ }
+
+ /*
+ * Fill in mbuf with extended UDP header
+ * and addresses and length put into network format.
+ */
+#ifdef INET6
+ if (v6packet) {
+ struct ip6_hdr *ipv6 = mtod(m, struct ip6_hdr *);
+ struct udphdr *uh = (struct udphdr *)(mtod(m, caddr_t) +
+ sizeof(struct ip6_hdr));
+ int payload = sizeof(struct ip6_hdr);
+ struct in6_addr *faddr;
+ struct in6_addr *laddr;
+ struct ifnet *oifp = NULL;
+
+ ipv6->ip6_flow = htonl(0x60000000) |
+ (inp->inp_ipv6.ip6_flow & htonl(0x0fffffff));
+
+ ipv6->ip6_nxt = IPPROTO_UDP;
+ ipv6->ip6_dst = inp->inp_faddr6;
+ /*
+ * If the scope of the destination is link-local,
+ * embed the interface
+ * index in the address.
+ *
+ * XXX advanced-api value overrides sin6_scope_id
+ */
+ faddr = &ipv6->ip6_dst;
+ if (IN6_IS_ADDR_LINKLOCAL(faddr) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(faddr)) {
+ struct ip6_pktopts *optp = inp->inp_outputopts6;
+ struct in6_pktinfo *pi = NULL;
+ struct ip6_moptions *mopt = NULL;
+
+ /*
+ * XXX Boundary check is assumed to be already done in
+ * ip6_setpktoptions().
+ */
+ if (optp && (pi = optp->ip6po_pktinfo) &&
+ pi->ipi6_ifindex) {
+ faddr->s6_addr16[1] = htons(pi->ipi6_ifindex);
+ oifp = ifindex2ifnet[pi->ipi6_ifindex];
+ }
+ else if (IN6_IS_ADDR_MULTICAST(faddr) &&
+ (mopt = inp->inp_moptions6) &&
+ mopt->im6o_multicast_ifp) {
+ oifp = mopt->im6o_multicast_ifp;
+ faddr->s6_addr16[1] = oifp->if_index;
+ } else if (sin6 && sin6->sin6_scope_id) {
+ /* boundary check */
+ if (sin6->sin6_scope_id < 0
+ || if_index < sin6->sin6_scope_id) {
+ error = ENXIO; /* XXX EINVAL? */
+ goto release;
+ }
+ /* XXX */
+ faddr->s6_addr16[1] =
+ htons(sin6->sin6_scope_id & 0xffff);
+ }
+ }
+ ipv6->ip6_hlim = in6_selecthlim(inp, oifp);
+ if (sin6) { /*XXX*/
+ laddr = in6_selectsrc(sin6, inp->inp_outputopts6,
+ inp->inp_moptions6,
+ &inp->inp_route6,
+ &inp->inp_laddr6, &error);
+ if (laddr == NULL) {
+ if (error == 0)
+ error = EADDRNOTAVAIL;
+ goto release;
+ }
+ } else
+ laddr = &inp->inp_laddr6;
+
+ ipv6->ip6_src = *laddr;
+
+ ipv6->ip6_plen = (u_short)len + sizeof(struct udphdr);
+
+ uh->uh_sport = inp->inp_lport;
+ uh->uh_dport = inp->inp_fport;
+ uh->uh_ulen = htons(ipv6->ip6_plen);
+ uh->uh_sum = 0;
+
+ /*
+ * Always calculate udp checksum for IPv6 datagrams
+ */
+ if (!(uh->uh_sum = in6_cksum(m, IPPROTO_UDP,
+ payload, len + sizeof(struct udphdr))))
+ uh->uh_sum = 0xffff;
+
+ error = ip6_output(m, inp->inp_outputopts6, &inp->inp_route6,
+ inp->inp_socket->so_options & SO_DONTROUTE,
+ (inp->inp_flags & INP_IPV6_MCAST)?inp->inp_moptions6:NULL,
+ NULL);
+ } else
+#endif /* INET6 */
+ {
+ ui = mtod(m, struct udpiphdr *);
+ bzero(ui->ui_x1, sizeof ui->ui_x1);
+ ui->ui_pr = IPPROTO_UDP;
+ ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr));
+ ui->ui_src = inp->inp_laddr;
+ ui->ui_dst = inp->inp_faddr;
+ ui->ui_sport = inp->inp_lport;
+ ui->ui_dport = inp->inp_fport;
+ ui->ui_ulen = ui->ui_len;
+
+ /*
+ * Stuff checksum and output datagram.
+ */
+
+ ui->ui_sum = 0;
+ if (udpcksum) {
+ if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) +
+ len)) == 0)
+ ui->ui_sum = 0xffff;
+ }
+ ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
+#ifdef INET6
+ /*
+ * For now, we use the default values for ttl and tos for
+ * v4 packets sent using a v6 pcb. We probably want to
+ * later allow v4 setsockopt operations on a v6 socket to
+ * modify the ttl and tos for v4 packets sent using
+ * the mapped address format. We really ought to
+ * save the v4 ttl and v6 hoplimit in separate places
+ * instead of craming both in the inp_hu union.
+ */
+ if (inp->inp_flags & INP_IPV6) {
+ ((struct ip *)ui)->ip_ttl = ip_defttl;
+ ((struct ip *)ui)->ip_tos = 0;
+ } else
+#endif /* INET6 */
+ {
+ ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl;
+ ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos;
+ }
+
+ udpstat.udps_opackets++;
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6_MCAST) {
+ error = ip_output(m, inp->inp_options, &inp->inp_route,
+ inp->inp_socket->so_options &
+ (SO_DONTROUTE | SO_BROADCAST),
+ NULL, NULL, inp->inp_socket);
+ } else
+#endif /* INET6 */
+ {
+ error = ip_output(m, inp->inp_options, &inp->inp_route,
+ inp->inp_socket->so_options &
+ (SO_DONTROUTE | SO_BROADCAST),
+ inp->inp_moptions, inp, NULL);
+ }
+ }
+
+bail:
+ if (addr) {
+ in_pcbdisconnect(inp);
+ inp->inp_flags = pcbflags;
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ inp->inp_laddr6 = laddr6;
+ else
+#endif
+ inp->inp_laddr = laddr;
+ splx(s);
+ }
+ if (control) {
+#ifdef INET6
+ if (v6packet)
+ inp->inp_outputopts6 = stickyopt;
+#endif
+ m_freem(control);
+ }
+ return (error);
+
+release:
+ m_freem(m);
+ if (control) {
+#ifdef INET6
+ if (v6packet)
+ inp->inp_outputopts6 = stickyopt;
+#endif
+ m_freem(control);
+ }
+ return (error);
+}
+
+u_int udp_sendspace = 9216; /* really max datagram size */
+u_int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
+ /* 40 1K datagrams */
+
+#if defined(INET6) && !defined(TCP6)
+/*ARGSUSED*/
+int
+udp6_usrreq(so, req, m, addr, control, p)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *addr, *control;
+ struct proc *p;
+{
+ return udp_usrreq(so, req, m, addr, control);
+}
+#endif
+
+/*ARGSUSED*/
+int
+udp_usrreq(so, req, m, addr, control)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *addr, *control;
+{
+ struct inpcb *inp = sotoinpcb(so);
+ int error = 0;
+ int s;
+
+ if (req == PRU_CONTROL) {
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ return (in6_control(so, (u_long)m, (caddr_t)addr,
+ (struct ifnet *)control, 0));
+ else
+#endif /* INET6 */
+ return (in_control(so, (u_long)m, (caddr_t)addr,
+ (struct ifnet *)control));
+ }
+ if (inp == NULL && req != PRU_ATTACH) {
+ error = EINVAL;
+ goto release;
+ }
+ /*
+ * Note: need to block udp_input while changing
+ * the udp pcb queue and/or pcb addresses.
+ */
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (inp != NULL) {
+ error = EINVAL;
+ break;
+ }
+ s = splsoftnet();
+ error = in_pcballoc(so, &udbtable);
+ splx(s);
+ if (error)
+ break;
+ error = soreserve(so, udp_sendspace, udp_recvspace);
+ if (error)
+ break;
+#ifdef INET6
+ if (((struct inpcb *)so->so_pcb)->inp_flags & INP_IPV6)
+ ((struct inpcb *) so->so_pcb)->inp_ipv6.ip6_hlim =
+ ip6_defhlim;
+ else
+#endif /* INET6 */
+ ((struct inpcb *) so->so_pcb)->inp_ip.ip_ttl = ip_defttl;
+ break;
+
+ case PRU_DETACH:
+ udp_detach(inp);
+ break;
+
+ case PRU_BIND:
+ s = splsoftnet();
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ error = in6_pcbbind(inp, addr);
+ else
+#endif
+ error = in_pcbbind(inp, addr);
+ splx(s);
+ break;
+
+ case PRU_LISTEN:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_CONNECT:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6) {
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
+ error = EISCONN;
+ break;
+ }
+ s = splsoftnet();
+ error = in6_pcbconnect(inp, addr);
+ splx(s);
+ } else
+#endif /* INET6 */
+ {
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ error = EISCONN;
+ break;
+ }
+ s = splsoftnet();
+ error = in_pcbconnect(inp, addr);
+ splx(s);
+ }
+
+ if (error == 0)
+ soisconnected(so);
+ break;
+
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_ACCEPT:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_DISCONNECT:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6) {
+ if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
+ error = ENOTCONN;
+ break;
+ }
+ } else
+#endif /* INET6 */
+ if (inp->inp_faddr.s_addr == INADDR_ANY) {
+ error = ENOTCONN;
+ break;
+ }
+
+ s = splsoftnet();
+ in_pcbdisconnect(inp);
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ inp->inp_laddr6 = in6addr_any;
+ else
+#endif /* INET6 */
+ inp->inp_laddr.s_addr = INADDR_ANY;
+
+ splx(s);
+ so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ break;
+
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ case PRU_SEND:
+#ifdef IPSEC
+ error = check_ipsec_policy(inp,0);
+ if (error)
+ return (error);
+#endif
+ return (udp_output(m, inp, addr, control));
+
+ case PRU_ABORT:
+ soisdisconnected(so);
+ udp_detach(inp);
+ break;
+
+ case PRU_SOCKADDR:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ in6_setsockaddr(inp, addr);
+ else
+#endif /* INET6 */
+ in_setsockaddr(inp, addr);
+ break;
+
+ case PRU_PEERADDR:
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ in6_setpeeraddr(inp, addr);
+ else
+#endif /* INET6 */
+ in_setpeeraddr(inp, addr);
+ break;
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ /*
+ * Perhaps Path MTU might be returned for a connected
+ * UDP socket in this case.
+ */
+ return (0);
+
+ case PRU_SENDOOB:
+ case PRU_FASTTIMO:
+ case PRU_SLOWTIMO:
+ case PRU_PROTORCV:
+ case PRU_PROTOSEND:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_RCVD:
+ case PRU_RCVOOB:
+ return (EOPNOTSUPP); /* do not free mbuf's */
+
+ default:
+ panic("udp_usrreq");
+ }
+
+release:
+ if (control) {
+#ifdef __ECOS
+ diag_printf("udp control data unexpectedly retained\n");
+#else
+ printf("udp control data unexpectedly retained\n");
+#endif
+ m_freem(control);
+ }
+ if (m)
+ m_freem(m);
+ return (error);
+}
+
+static void
+udp_detach(inp)
+ struct inpcb *inp;
+{
+ int s = splsoftnet();
+
+ in_pcbdetach(inp);
+ splx(s);
+}
+
+#ifdef CYGPKG_NET_SYSCTL
+/*
+ * Sysctl for udp variables.
+ */
+int
+udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+{
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case UDPCTL_CHECKSUM:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum));
+ case UDPCTL_BADDYNAMIC:
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ baddynamicports.udp, sizeof(baddynamicports.udp)));
+ case UDPCTL_RECVSPACE:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,&udp_recvspace));
+ case UDPCTL_SENDSPACE:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,&udp_sendspace));
+ default:
+ return (ENOPROTOOPT);
+ }
+ /* NOTREACHED */
+}
+#endif // CYGPKG_NET_SYSCTL