Merge of branches/team/network/new_stack - not yet complete as SVN does only support
replacing files when merging when you don't have deleted them manually (for some reason, it only works as part of the merge operation, and we didn't copy the whole tree to have "a fresh start" - next time we know better, at least if SVN still suffers from that same limitation). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18456 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
70418bc5bf
commit
5adca30a18
build/jam
headers
posix
arpa
net
netdb.hnetinet
icmp_var.hif_ether.hin.hin_pcb.hin_systm.hin_var.hip.hip_icmp.htcp_debug.htcp_fsm.htcp_seq.htcp_timer.htcp_var.htcpip.hudp_var.h
netinet6
resolv.hsys
private/net
src/add-ons/kernel
drivers/network/stack
network
@ -22,13 +22,13 @@ if $(INCLUDE_GPL_ADDONS) = 1 {
|
||||
|
||||
BEOS_BIN = addattr alert basename beep cat catattr chgrp chmod chop chown clear
|
||||
clockconfig cmp comm cp copyattr csplit cut date dd desklink df diff dirname driveinfo
|
||||
dstcheck du echo eject env error factor false ffm find finddir fortune funzip gawk
|
||||
dstcheck du echo eject env error factor false ffm find finddir fortune ftp funzip gawk
|
||||
$(X86_ONLY)gdb grep groups gzip head hey id ideinfo idestatus ifconfig iroster isvolume
|
||||
join keymap kill less lessecho lesskey link listarea listattr listdev listimage
|
||||
listport listres listsem ln locate logger logname ls lsindex makebootable md5sum mimeset
|
||||
mkdir mkindex modifiers mount mountvolume mv open pathchk ping play playfile playsound
|
||||
playwav ppp_up pppconfig ps pwd
|
||||
query quit renice rm rmattr rmindex rmdir roster safemode screen_blanker sed settype
|
||||
query quit renice rm rmattr rmindex rmdir roster route safemode screen_blanker sed settype
|
||||
setversion setvolume sh shutdown sleep sort split strace su sum sync sysinfo
|
||||
tail tar tee top touch tput traceroute translate true tty uname unmount unzip unzipsfx
|
||||
uptime version waitfor wc whoami xargs xres yes zdiff zforce zgrep zip zipcloak
|
||||
@ -43,20 +43,20 @@ BEOS_APPS = Terminal Expander People ShowImage Clock Pulse ProcessController
|
||||
BEOS_PREFERENCES = Backgrounds DataTranslations FileTypes Fonts Media Menu
|
||||
Mouse Keyboard Keymap Screen ScreenSaver Sounds Time VirtualMemory
|
||||
;
|
||||
BEOS_SYSTEM_LIB = libbe.so $(HAIKU_LIBSTDC++) libnet.so libmedia.so libtracker.so
|
||||
libtranslation.so libnetwork.so libbind.so libnetapi.so libsocket.so libdebug.so
|
||||
BEOS_SYSTEM_LIB = libbe.so $(HAIKU_LIBSTDC++) libmedia.so libtracker.so
|
||||
libtranslation.so libnetwork.so libdebug.so libbsd.so
|
||||
libtextencoding.so libz.so libfreetype.so libpng.so libmidi.so libmidi2.so
|
||||
libdevice.so libgame.so libscreensaver.so libroot.so libmail.so $(X86_ONLY)libGL.so
|
||||
libdevice.so libgame.so libscreensaver.so libroot.so $(X86_ONLY)libGL.so
|
||||
libfluidsynth.so
|
||||
;
|
||||
BEOS_SYSTEM_SERVERS = registrar debug_server syslog_daemon media_server
|
||||
media_addon_server input_server app_server fake_app_server midi_server
|
||||
;
|
||||
|
||||
BEOS_NETWORK_CORE = core ;
|
||||
BEOS_NETWORK_INTERFACES = ethernet loopback ppp ;
|
||||
BEOS_NETWORK_PPP = ipcp modem pap pppoe ;
|
||||
BEOS_NETWORK_PROTOCOLS = icmp ipv4 raw route tcp udp ;
|
||||
BEOS_NETWORK_DEVICES = ethernet loopback ;
|
||||
BEOS_NETWORK_DATALINK_PROTOCOLS = ethernet_frame <module>arp ;
|
||||
#BEOS_NETWORK_PPP = ipcp modem pap pppoe ;
|
||||
BEOS_NETWORK_PROTOCOLS = ipv4 tcp udp icmp ;
|
||||
|
||||
BEOS_ADD_ONS_ACCELERANTS = $(X86_ONLY)radeon.accelerant $(X86_ONLY)nv.accelerant
|
||||
$(X86_ONLY)mga.accelerant $(X86_ONLY)nm.accelerant $(X86_ONLY)intel_extreme.accelerant
|
||||
@ -86,7 +86,7 @@ BEOS_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon.driver $(X86_ONLY)nv.driver
|
||||
$(X86_ONLY)nm.driver $(X86_ONLY)mga.driver $(X86_ONLY)intel_extreme vesa
|
||||
;
|
||||
BEOS_ADD_ONS_DRIVERS_NET = etherpci ipro1000 rtl8139 rtl8169 sis900
|
||||
via-rhine wb840 net_stack_driver
|
||||
etherpci via-rhine wb840 net_stack
|
||||
$(GPL_ONLY)bcm440x $(GPL_ONLY)bcm570x
|
||||
;
|
||||
BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button $(X86_ONLY)acpi_ns_dump ;
|
||||
@ -132,6 +132,8 @@ AddFilesToHaikuImage beos system : kernel_$(TARGET_ARCH) ;
|
||||
|
||||
# libs
|
||||
AddFilesToHaikuImage beos system lib : $(BEOS_SYSTEM_LIB) ;
|
||||
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libsocket.so ;
|
||||
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libbind.so ;
|
||||
|
||||
# servers
|
||||
AddFilesToHaikuImage beos system servers : $(BEOS_SYSTEM_SERVERS) ;
|
||||
@ -186,11 +188,11 @@ AddFilesToHaikuImage beos etc KanBe dic canna : $(kanbeDicCanna) ;
|
||||
AddDirectoryToHaikuImage beos etc KanBe dic group ;
|
||||
AddDirectoryToHaikuImage beos etc KanBe dic user ;
|
||||
|
||||
local libnetFiles = networks protocols resolv.conf services ;
|
||||
libnetFiles = $(libnetFiles:G=libnet-files) ;
|
||||
SEARCH on $(libnetFiles)
|
||||
= [ FDirName $(HAIKU_TOP) src kits network compat libnet ] ;
|
||||
AddFilesToHaikuImage beos etc : $(libnetFiles) ;
|
||||
#local libnetFiles = networks protocols resolv.conf services ;
|
||||
#libnetFiles = $(libnetFiles:G=libnet-files) ;
|
||||
#SEARCH on $(libnetFiles)
|
||||
# = [ FDirName $(HAIKU_TOP) src kits network compat libnet ] ;
|
||||
#AddFilesToHaikuImage beos etc : $(libnetFiles) ;
|
||||
|
||||
local keymapFiles = [ GLOB [ FDirName $(HAIKU_TOP) src data etc keymaps ] : *.keymap ] ;
|
||||
keymapFiles = $(keymapFiles:BG=keymap) ;
|
||||
@ -238,9 +240,11 @@ AddFilesToHaikuImage beos system add-ons input_server devices
|
||||
AddFilesToHaikuImage beos system add-ons input_server filters : screen_saver ;
|
||||
# AddFilesToHaikuImage beos system add-ons input_server methods : canna ;
|
||||
AddFilesToHaikuImage beos system add-ons kernel network
|
||||
: $(BEOS_NETWORK_CORE) ;
|
||||
AddFilesToHaikuImage beos system add-ons kernel network interfaces
|
||||
: $(BEOS_NETWORK_INTERFACES) ;
|
||||
: stack ;
|
||||
AddFilesToHaikuImage beos system add-ons kernel network devices
|
||||
: $(BEOS_NETWORK_DEVICES) ;
|
||||
AddFilesToHaikuImage beos system add-ons kernel network datalink_protocols
|
||||
: $(BEOS_NETWORK_DATALINK_PROTOCOLS) ;
|
||||
AddFilesToHaikuImage beos system add-ons kernel network ppp
|
||||
: $(BEOS_NETWORK_PPP) ;
|
||||
AddFilesToHaikuImage beos system add-ons kernel network protocols
|
||||
|
@ -1,6 +1,9 @@
|
||||
/*
|
||||
* ++Copyright++ 1983, 1993
|
||||
* -
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -49,58 +52,57 @@
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
/*
|
||||
* @(#)inet.h 8.1 (Berkeley) 6/2/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INET_H_
|
||||
#define _INET_H_
|
||||
|
||||
/* External definitions for functions in inet(3) */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/bitypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
|
||||
#define inet_addr __inet_addr
|
||||
#define inet_aton __inet_aton
|
||||
#define inet_lnaof __inet_lnaof
|
||||
#define inet_makeaddr __inet_makeaddr
|
||||
#define inet_makeaddr __inet_makeaddr
|
||||
#define inet_neta __inet_neta
|
||||
#define inet_netof __inet_netof
|
||||
#define inet_network __inet_network
|
||||
#define inet_net_ntop __inet_net_ntop
|
||||
#define inet_net_pton __inet_net_pton
|
||||
#define inet_cidr_ntop __inet_cidr_ntop
|
||||
#define inet_cidr_pton __inet_cidr_pton
|
||||
#define inet_network __inet_network
|
||||
#define inet_net_ntop __inet_net_ntop
|
||||
#define inet_net_pton __inet_net_pton
|
||||
#define inet_cidr_ntop __inet_cidr_ntop
|
||||
#define inet_cidr_pton __inet_cidr_pton
|
||||
#define inet_ntoa __inet_ntoa
|
||||
#define inet_pton __inet_pton
|
||||
#define inet_ntop __inet_ntop
|
||||
#define inet_nsap_addr __inet_nsap_addr
|
||||
#define inet_nsap_ntoa __inet_nsap_ntoa
|
||||
#define inet_nsap_addr __inet_nsap_addr
|
||||
#define inet_nsap_ntoa __inet_nsap_ntoa
|
||||
|
||||
__BEGIN_DECLS
|
||||
unsigned long inet_addr __P((const char *));
|
||||
int inet_aton __P((const char *, struct in_addr *));
|
||||
unsigned long inet_lnaof __P((struct in_addr));
|
||||
struct in_addr inet_makeaddr __P((u_long , u_long));
|
||||
char * inet_neta __P((u_long, char *, size_t));
|
||||
unsigned long inet_netof __P((struct in_addr));
|
||||
unsigned long inet_network __P((const char *));
|
||||
char *inet_net_ntop __P((int, const void *, int, char *, size_t));
|
||||
int inet_net_pton __P((int, const char *, void *, size_t));
|
||||
char *inet_cidr_ntop __P((int, const void *, int, char *, size_t));
|
||||
int inet_cidr_pton __P((int, const char *, void *, int *));
|
||||
/*const*/ char *inet_ntoa __P((struct in_addr));
|
||||
int inet_pton __P((int, const char *, void *));
|
||||
const char *inet_ntop __P((int, const void *, char *, size_t));
|
||||
u_int inet_nsap_addr __P((const char *, u_char *, int));
|
||||
char *inet_nsap_ntoa __P((int, const u_char *, char *));
|
||||
__END_DECLS
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#endif /* !_INET_H_ */
|
||||
in_addr_t inet_addr(const char *);
|
||||
int inet_aton(const char *, struct in_addr *);
|
||||
unsigned long inet_lnaof(struct in_addr);
|
||||
struct in_addr inet_makeaddr(u_long , u_long);
|
||||
char *inet_neta(u_long, char *, size_t);
|
||||
unsigned long inet_netof(struct in_addr);
|
||||
unsigned long inet_network(const char *);
|
||||
char *inet_net_ntop(int, const void *, int, char *, size_t);
|
||||
int inet_net_pton(int, const char *, void *, size_t);
|
||||
char *inet_cidr_ntop(int, const void *, int, char *, size_t);
|
||||
int inet_cidr_pton(int, const char *, void *, int *);
|
||||
char *inet_ntoa(struct in_addr);
|
||||
int inet_pton(int, const char *, void *);
|
||||
const char *inet_ntop(int, const void *, char *, size_t);
|
||||
u_int inet_nsap_addr(const char *, u_char *, int);
|
||||
char *inet_nsap_ntoa(int, const u_char *, char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _INET_H_ */
|
||||
|
@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -47,19 +52,15 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_NAMESER_H_
|
||||
#define _ARPA_NAMESER_H_
|
||||
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/bitypes.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
/*
|
||||
* Revision information. This is the release date in YYYYMMDD format.
|
||||
@ -68,27 +69,26 @@
|
||||
* compare for equality; rather, use it to determine whether your libbind.a
|
||||
* contains a new enough lib/nameser/ to support the feature you need.
|
||||
*/
|
||||
|
||||
#define __NAMESER 19991006 /* New interface version stamp. */
|
||||
|
||||
/*
|
||||
* Define constants based on RFC 883, RFC 1034, RFC 1035
|
||||
*/
|
||||
#define NS_PACKETSZ 512 /* default UDP packet size */
|
||||
#define NS_MAXDNAME 1025 /* maximum domain name */
|
||||
#define NS_MAXMSG 65535 /* maximum message size */
|
||||
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
|
||||
#define NS_MAXLABEL 63 /* maximum length of domain label */
|
||||
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
|
||||
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
|
||||
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
|
||||
#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
|
||||
#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
|
||||
#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
|
||||
#define NS_INADDRSZ 4 /* IPv4 T_A */
|
||||
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
|
||||
#define NS_PACKETSZ 512 /* default UDP packet size */
|
||||
#define NS_MAXDNAME 1025 /* maximum domain name */
|
||||
#define NS_MAXMSG 65535 /* maximum message size */
|
||||
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
|
||||
#define NS_MAXLABEL 63 /* maximum length of domain label */
|
||||
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
|
||||
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
|
||||
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
|
||||
#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
|
||||
#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
|
||||
#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
|
||||
#define NS_INADDRSZ 4 /* IPv4 T_A */
|
||||
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
|
||||
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
|
||||
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
|
||||
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
|
||||
|
||||
/*
|
||||
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
|
||||
@ -111,11 +111,14 @@ typedef enum __ns_sect {
|
||||
* leading _'s on the member names. Use the accessor functions, not the _'s.
|
||||
*/
|
||||
typedef struct __ns_msg {
|
||||
const u_char *_msg, *_eom;
|
||||
u_int16_t _id, _flags, _counts[ns_s_max];
|
||||
const u_char *_msg;
|
||||
const u_char *_eom;
|
||||
u_int16_t _id;
|
||||
u_int16_t _flags;
|
||||
u_int16_t _counts[ns_s_max];
|
||||
const u_char *_sections[ns_s_max];
|
||||
ns_sect _sect;
|
||||
int _rrnum;
|
||||
ns_sect _sect;
|
||||
int _rrnum;
|
||||
const u_char *_msg_ptr;
|
||||
} ns_msg;
|
||||
|
||||
@ -135,12 +138,12 @@ extern struct _ns_flagdata _ns_flagdata[];
|
||||
* This is a parsed record. It is caller allocated and has no dynamic data.
|
||||
*/
|
||||
typedef struct __ns_rr {
|
||||
char name[NS_MAXDNAME];
|
||||
u_int16_t type;
|
||||
u_int16_t rr_class;
|
||||
u_int32_t ttl;
|
||||
u_int16_t rdlength;
|
||||
const u_char * rdata;
|
||||
char name[NS_MAXDNAME];
|
||||
u_int16_t type;
|
||||
u_int16_t rr_class;
|
||||
u_int32_t ttl;
|
||||
u_int16_t rdlength;
|
||||
const u_char *rdata;
|
||||
} ns_rr;
|
||||
|
||||
/* Accessor macros - this is part of the public interface. */
|
||||
@ -158,7 +161,7 @@ typedef struct __ns_rr {
|
||||
*/
|
||||
typedef enum __ns_flag {
|
||||
ns_f_qr, /* Question/Response. */
|
||||
ns_f_opcode, /* Operation code. */
|
||||
ns_f_opcode, /* Operation code. */
|
||||
ns_f_aa, /* Authoritative Answer. */
|
||||
ns_f_tc, /* Truncation occurred. */
|
||||
ns_f_rd, /* Recursion Desired. */
|
||||
@ -177,7 +180,7 @@ typedef enum __ns_opcode {
|
||||
ns_o_query = 0, /* Standard query. */
|
||||
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
|
||||
ns_o_status = 2, /* Name server status query (unsupported). */
|
||||
/* Opcode 3 is undefined/reserved. */
|
||||
/* Opcode 3 is undefined/reserved. */
|
||||
ns_o_notify = 4, /* Zone change notification. */
|
||||
ns_o_update = 5, /* Zone update message. */
|
||||
ns_o_max = 6
|
||||
@ -219,9 +222,10 @@ typedef enum __ns_update_operation {
|
||||
* This structure is used for TSIG authenticated messages
|
||||
*/
|
||||
struct ns_tsig_key {
|
||||
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
|
||||
unsigned char *data;
|
||||
int len;
|
||||
char name[NS_MAXDNAME];
|
||||
char alg[NS_MAXDNAME];
|
||||
unsigned char *data;
|
||||
int len;
|
||||
};
|
||||
typedef struct ns_tsig_key ns_tsig_key;
|
||||
|
||||
@ -229,11 +233,11 @@ typedef struct ns_tsig_key ns_tsig_key;
|
||||
* This structure is used for TSIG authenticated TCP messages
|
||||
*/
|
||||
struct ns_tcp_tsig_state {
|
||||
int counter;
|
||||
struct dst_key *key;
|
||||
void *ctx;
|
||||
unsigned char sig[NS_PACKETSZ];
|
||||
int siglen;
|
||||
int counter;
|
||||
struct dst_key *key;
|
||||
void *ctx;
|
||||
unsigned char sig[NS_PACKETSZ];
|
||||
int siglen;
|
||||
};
|
||||
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
|
||||
|
||||
@ -250,7 +254,7 @@ typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
|
||||
*/
|
||||
typedef enum __ns_type {
|
||||
ns_t_invalid = 0, /* Cookie. */
|
||||
ns_t_a = 1, /* Host address. */
|
||||
ns_t_a = 1, /* Host address. */
|
||||
ns_t_ns = 2, /* Authoritative server. */
|
||||
ns_t_md = 3, /* Mail destination. */
|
||||
ns_t_mf = 4, /* Mail forwarder. */
|
||||
@ -473,14 +477,14 @@ typedef enum __ns_cert_types {
|
||||
* ANSI C identifier hiding for bind's lib/nameser.
|
||||
*/
|
||||
#define ns_msg_getflag __ns_msg_getflag
|
||||
#define ns_get16 __ns_get16
|
||||
#define ns_get32 __ns_get32
|
||||
#define ns_put16 __ns_put16
|
||||
#define ns_put32 __ns_put32
|
||||
#define ns_get16 __ns_get16
|
||||
#define ns_get32 __ns_get32
|
||||
#define ns_put16 __ns_put16
|
||||
#define ns_put32 __ns_put32
|
||||
#define ns_initparse __ns_initparse
|
||||
#define ns_skiprr __ns_skiprr
|
||||
#define ns_parserr __ns_parserr
|
||||
#define ns_sprintrr __ns_sprintrr
|
||||
#define ns_skiprr __ns_skiprr
|
||||
#define ns_parserr __ns_parserr
|
||||
#define ns_sprintrr __ns_sprintrr
|
||||
#define ns_sprintrrf __ns_sprintrrf
|
||||
#define ns_format_ttl __ns_format_ttl
|
||||
#define ns_parse_ttl __ns_parse_ttl
|
||||
@ -494,79 +498,81 @@ typedef enum __ns_cert_types {
|
||||
#define ns_name_uncompress __ns_name_uncompress
|
||||
#define ns_name_skip __ns_name_skip
|
||||
#define ns_name_rollback __ns_name_rollback
|
||||
#define ns_sign __ns_sign
|
||||
#define ns_sign2 __ns_sign2
|
||||
#define ns_sign_tcp __ns_sign_tcp
|
||||
#define ns_sign __ns_sign
|
||||
#define ns_sign2 __ns_sign2
|
||||
#define ns_sign_tcp __ns_sign_tcp
|
||||
#define ns_sign_tcp2 __ns_sign_tcp2
|
||||
#define ns_sign_tcp_init __ns_sign_tcp_init
|
||||
#define ns_find_tsig __ns_find_tsig
|
||||
#define ns_verify __ns_verify
|
||||
#define ns_verify __ns_verify
|
||||
#define ns_verify_tcp __ns_verify_tcp
|
||||
#define ns_verify_tcp_init __ns_verify_tcp_init
|
||||
#define ns_samedomain __ns_samedomain
|
||||
#define ns_subdomain __ns_subdomain
|
||||
#define ns_makecanon __ns_makecanon
|
||||
#define ns_samename __ns_samename
|
||||
#define ns_samename __ns_samename
|
||||
|
||||
__BEGIN_DECLS
|
||||
int ns_msg_getflag __P((ns_msg, int));
|
||||
u_int ns_get16 __P((const u_char *));
|
||||
u_long ns_get32 __P((const u_char *));
|
||||
void ns_put16 __P((u_int, u_char *));
|
||||
void ns_put32 __P((u_long, u_char *));
|
||||
int ns_initparse __P((const u_char *, int, ns_msg *));
|
||||
int ns_skiprr __P((const u_char *, const u_char *, ns_sect, int));
|
||||
int ns_parserr __P((ns_msg *, ns_sect, int, ns_rr *));
|
||||
int ns_sprintrr __P((const ns_msg *, const ns_rr *,
|
||||
const char *, const char *, char *, size_t));
|
||||
int ns_sprintrrf __P((const u_char *, size_t, const char *,
|
||||
ns_class, ns_type, u_long, const u_char *,
|
||||
size_t, const char *, const char *,
|
||||
char *, size_t));
|
||||
int ns_format_ttl __P((u_long, char *, size_t));
|
||||
int ns_parse_ttl __P((const char *, u_long *));
|
||||
u_int32_t ns_datetosecs __P((const char *cp, int *errp));
|
||||
int ns_name_ntol __P((const u_char *, u_char *, size_t));
|
||||
int ns_name_ntop __P((const u_char *, char *, size_t));
|
||||
int ns_name_pton __P((const char *, u_char *, size_t));
|
||||
int ns_name_unpack __P((const u_char *, const u_char *,
|
||||
const u_char *, u_char *, size_t));
|
||||
int ns_name_pack __P((const u_char *, u_char *, int,
|
||||
const u_char **, const u_char **));
|
||||
int ns_name_uncompress __P((const u_char *, const u_char *,
|
||||
const u_char *, char *, size_t));
|
||||
int ns_name_compress __P((const char *, u_char *, size_t,
|
||||
const u_char **, const u_char **));
|
||||
int ns_name_skip __P((const u_char **, const u_char *));
|
||||
void ns_name_rollback __P((const u_char *, const u_char **,
|
||||
const u_char **));
|
||||
int ns_sign __P((u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t));
|
||||
int ns_sign2 __P((u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t,
|
||||
u_char **, u_char **));
|
||||
int ns_sign_tcp __P((u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int));
|
||||
int ns_sign_tcp2 __P((u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int,
|
||||
u_char **, u_char **));
|
||||
int ns_sign_tcp_init __P((void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *));
|
||||
u_char *ns_find_tsig __P((u_char *, u_char *));
|
||||
int ns_verify __P((u_char *, int *, void *,
|
||||
const u_char *, int, u_char *, int *,
|
||||
time_t *, int));
|
||||
int ns_verify_tcp __P((u_char *, int *, ns_tcp_tsig_state *, int));
|
||||
int ns_verify_tcp_init __P((void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *));
|
||||
int ns_samedomain __P((const char *, const char *));
|
||||
int ns_subdomain __P((const char *, const char *));
|
||||
int ns_makecanon __P((const char *, char *, size_t));
|
||||
int ns_samename __P((const char *, const char *));
|
||||
__END_DECLS
|
||||
|
||||
#ifdef BIND_4_COMPAT
|
||||
#include <arpa/nameser_compat.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#endif /* !_ARPA_NAMESER_H_ */
|
||||
int ns_msg_getflag(ns_msg, int);
|
||||
u_int ns_get16(const u_char *);
|
||||
u_long ns_get32(const u_char *);
|
||||
void ns_put16(u_int, u_char *);
|
||||
void ns_put32(u_long, u_char *);
|
||||
int ns_initparse(const u_char *, int, ns_msg *);
|
||||
int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
|
||||
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
|
||||
int ns_sprintrr(const ns_msg *, const ns_rr *,
|
||||
const char *, const char *, char *, size_t);
|
||||
int ns_sprintrrf(const u_char *, size_t, const char *,
|
||||
ns_class, ns_type, u_long, const u_char *,
|
||||
size_t, const char *, const char *,
|
||||
char *, size_t);
|
||||
int ns_format_ttl(u_long, char *, size_t);
|
||||
int ns_parse_ttl(const char *, u_long *);
|
||||
u_int32_t ns_datetosecs(const char *cp, int *errp);
|
||||
int ns_name_ntol(const u_char *, u_char *, size_t);
|
||||
int ns_name_ntop(const u_char *, char *, size_t);
|
||||
int ns_name_pton(const char *, u_char *, size_t);
|
||||
int ns_name_unpack(const u_char *, const u_char *,
|
||||
const u_char *, u_char *, size_t);
|
||||
int ns_name_pack(const u_char *, u_char *, int,
|
||||
const u_char **, const u_char **);
|
||||
int ns_name_uncompress(const u_char *, const u_char *,
|
||||
const u_char *, char *, size_t);
|
||||
int ns_name_compress(const char *, u_char *, size_t,
|
||||
const u_char **, const u_char **);
|
||||
int ns_name_skip(const u_char **, const u_char *);
|
||||
void ns_name_rollback(const u_char *, const u_char **,
|
||||
const u_char **);
|
||||
int ns_sign(u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t);
|
||||
int ns_sign2(u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t,
|
||||
u_char **, u_char **);
|
||||
int ns_sign_tcp(u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int);
|
||||
int ns_sign_tcp2(u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int,
|
||||
u_char **, u_char **);
|
||||
int ns_sign_tcp_init(void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *);
|
||||
u_char *ns_find_tsig(u_char *, u_char *);
|
||||
int ns_verify(u_char *, int *, void *,
|
||||
const u_char *, int, u_char *, int *,
|
||||
time_t *, int);
|
||||
int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
|
||||
int ns_verify_tcp_init(void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *);
|
||||
int ns_samedomain(const char *, const char *);
|
||||
int ns_subdomain(const char *, const char *);
|
||||
int ns_makecanon(const char *, char *, size_t);
|
||||
int ns_samename(const char *, const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ARPA_NAMESER_H_ */
|
||||
|
@ -1,278 +1,100 @@
|
||||
/* if.h
|
||||
* Interface definitions for beos
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_H
|
||||
#define _NET_IF_H
|
||||
|
||||
/* FIXME: this file is NOT POSIX compliant, and rely on way too much OS-dependent
|
||||
definition.
|
||||
Moving private parts to private headers should help clean up this file
|
||||
|
||||
POSIX net/if.h spec:
|
||||
http://www.opengroup.org/onlinepubs/007904975/basedefs/net/if.h.html
|
||||
*/
|
||||
|
||||
#include <OS.h> /* FIXME */
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/route.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#define IF_NAMESIZE 32
|
||||
|
||||
/* BSD specific/proprietary part */
|
||||
|
||||
#define IFNAMSIZ IF_NAMESIZE
|
||||
|
||||
struct ifreq_parameter {
|
||||
char base_name[IF_NAMESIZE];
|
||||
char device[128];
|
||||
uint8_t sub_type;
|
||||
};
|
||||
|
||||
struct ifreq_stream_stats {
|
||||
uint32_t packets;
|
||||
uint32_t errors;
|
||||
uint64_t bytes;
|
||||
uint32_t multicast_packets;
|
||||
uint32_t dropped;
|
||||
};
|
||||
|
||||
struct ifreq_stats {
|
||||
struct ifreq_stream_stats receive;
|
||||
struct ifreq_stream_stats send;
|
||||
uint32_t collisions;
|
||||
};
|
||||
|
||||
struct ifreq {
|
||||
char ifr_name[IF_NAMESIZE];
|
||||
union {
|
||||
struct sockaddr ifr_addr;
|
||||
struct sockaddr ifr_dstaddr;
|
||||
struct sockaddr ifr_broadaddr;
|
||||
struct sockaddr ifr_mask;
|
||||
struct ifreq_parameter ifr_parameter;
|
||||
struct ifreq_stats ifr_stats;
|
||||
struct route_entry ifr_route;
|
||||
int ifr_flags;
|
||||
int ifr_index;
|
||||
int ifr_metric;
|
||||
int ifr_mtu;
|
||||
int ifr_media;
|
||||
int ifr_type;
|
||||
};
|
||||
};
|
||||
|
||||
/* interface flags */
|
||||
#define IFF_UP 0x0001
|
||||
#define IFF_BROADCAST 0x0002 /* valid broadcast address */
|
||||
#define IFF_LOOPBACK 0x0008
|
||||
#define IFF_POINTOPOINT 0x0010 /* point-to-point link */
|
||||
#define IFF_NOARP 0x0040 /* no address resolution */
|
||||
#define IFF_AUTOUP 0x0080 /* auto dial */
|
||||
#define IFF_PROMISC 0x0100 /* receive all packets */
|
||||
#define IFF_ALLMULTI 0x0200 /* receive all multicast packets */
|
||||
#define IFF_SIMPLEX 0x0800 /* doesn't receive own transmissions */
|
||||
#define IFF_MULTICAST 0x8000 /* supports multicast */
|
||||
|
||||
struct ifconf {
|
||||
int ifc_len; /* size of buffer */
|
||||
union {
|
||||
void *ifc_buf;
|
||||
struct ifreq *ifc_req;
|
||||
int ifc_value;
|
||||
};
|
||||
};
|
||||
|
||||
/* POSIX definitions follow */
|
||||
|
||||
struct if_nameindex {
|
||||
unsigned if_index; /* positive interface index */
|
||||
char *if_name; /* interface name, ie. "loopback" */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Forward reference... */
|
||||
struct socket;
|
||||
|
||||
/* Media types are now listed in net/if_types.h */
|
||||
|
||||
/* Interface flags */
|
||||
enum {
|
||||
IFF_UP = 0x0001,
|
||||
IFF_DOWN = 0x0002,
|
||||
IFF_PROMISC = 0x0004,
|
||||
IFF_RUNNING = 0x0008,
|
||||
IFF_MULTICAST = 0x0010,
|
||||
IFF_BROADCAST = 0x0020,
|
||||
IFF_POINTOPOINT = 0x0040,
|
||||
IFF_NOARP = 0x0080,
|
||||
IFF_LOOPBACK = 0x0100,
|
||||
IFF_DEBUG = 0x0200,
|
||||
IFF_LINK0 = 0x0400,
|
||||
IFF_LINK1 = 0x0800,
|
||||
IFF_LINK2 = 0x1000,
|
||||
IFF_SIMPLEX = 0x2000
|
||||
};
|
||||
|
||||
struct ifq {
|
||||
struct mbuf *head;
|
||||
struct mbuf *tail;
|
||||
int maxlen;
|
||||
int len;
|
||||
sem_id lock;
|
||||
sem_id pop;
|
||||
};
|
||||
|
||||
#define IFQ_FULL(ifq) (ifq->len >= ifq->maxlen)
|
||||
|
||||
#define IFQ_ENQUEUE(ifq, m) { \
|
||||
acquire_sem((ifq)->lock); \
|
||||
(m)->m_nextpkt = 0; \
|
||||
if ((ifq)->tail == 0) \
|
||||
(ifq)->head = m; \
|
||||
else \
|
||||
(ifq)->tail->m_nextpkt = m; \
|
||||
(ifq)->tail = m; \
|
||||
(ifq)->len++; \
|
||||
release_sem((ifq)->lock); \
|
||||
release_sem((ifq)->pop); \
|
||||
}
|
||||
|
||||
#define IFQ_DEQUEUE(ifq, m) { \
|
||||
acquire_sem((ifq)->lock); \
|
||||
(m) = (ifq)->head; \
|
||||
if (m) { \
|
||||
if (((ifq)->head = (m)->m_nextpkt) == 0) \
|
||||
(ifq)->tail = 0; \
|
||||
(m)->m_nextpkt = 0; \
|
||||
(ifq)->len--; \
|
||||
} \
|
||||
release_sem((ifq)->lock); \
|
||||
}
|
||||
|
||||
struct ifaddr {
|
||||
struct ifaddr *ifa_next; /* the next address for the interface */
|
||||
struct ifnet *ifa_ifp; /* pointer to the interface structure */
|
||||
|
||||
struct sockaddr *ifa_addr; /* the address - cast to be a suitable type, so we
|
||||
* use this structure to store any type of address that
|
||||
* we have a struct sockaddr_? for. e.g.
|
||||
* link level address via sockaddr_dl and
|
||||
* ipv4 via sockeddr_in
|
||||
* same for next 2 pointers as well
|
||||
*/
|
||||
struct sockaddr *ifa_dstaddr; /* if we're on a point-to-point link this
|
||||
* is the other end */
|
||||
struct sockaddr *ifa_netmask; /* The netmask we're using */
|
||||
|
||||
/* check or clean routes... */
|
||||
void (*ifa_rtrequest)(int, struct rtentry *, struct sockaddr *);
|
||||
uint8 ifa_flags; /* flags (mainly routing */
|
||||
uint16 ifa_refcnt; /* how many references are there to
|
||||
* this structure? */
|
||||
int ifa_metric; /* the metirc for this interface/address */
|
||||
};
|
||||
#define ifa_broadaddr ifa_dstaddr
|
||||
|
||||
struct if_data {
|
||||
uint8 ifi_type; /* type of media */
|
||||
uint8 ifi_addrlen; /* length of media address length */
|
||||
uint8 ifi_hdrlen; /* size of media header */
|
||||
uint32 ifi_mtu; /* mtu */
|
||||
uint32 ifi_metric; /* routing metric */
|
||||
uint32 ifi_baudrate; /* baudrate of line */
|
||||
/* statistics!! */
|
||||
int32 ifi_ipackets; /* packets received on interface */
|
||||
int32 ifi_ierrors; /* input errors on interface */
|
||||
int32 ifi_opackets; /* packets sent on interface */
|
||||
int32 ifi_oerrors; /* output errors on interface */
|
||||
int32 ifi_collisions; /* collisions on csma interfaces */
|
||||
int32 ifi_ibytes; /* total number of octets received */
|
||||
int32 ifi_obytes; /* total number of octets sent */
|
||||
int32 ifi_imcasts; /* packets received via multicast */
|
||||
int32 ifi_omcasts; /* packets sent via multicast */
|
||||
int32 ifi_iqdrops; /* dropped on input, this interface */
|
||||
int32 ifi_noproto; /* destined for unsupported protocol */
|
||||
};
|
||||
|
||||
struct ifnet {
|
||||
struct ifnet *if_next; /* next device */
|
||||
struct ifaddr *if_addrlist; /* linked list of addresses */
|
||||
int devid; /* our device id if we have one... */
|
||||
int id; /* id within the stack's device list */
|
||||
char *name; /* name of driver e.g. tulip */
|
||||
int if_unit; /* number of unit e.g 0 */
|
||||
char *if_name; /* full name, e.g. tulip0 */
|
||||
struct if_data ifd; /* if_data structure, shortcuts below */
|
||||
int if_flags; /* if flags */
|
||||
int if_index; /* our index in ifnet_addrs and interfaces */
|
||||
|
||||
struct ifq *rxq;
|
||||
thread_id rx_thread;
|
||||
struct ifq *txq;
|
||||
thread_id tx_thread;
|
||||
struct ifq *devq;
|
||||
|
||||
int (*start) (struct ifnet *);
|
||||
int (*stop) (struct ifnet *);
|
||||
void (*input) (struct mbuf*);
|
||||
int (*output)(struct ifnet *, struct mbuf*,
|
||||
struct sockaddr*, struct rtentry *);
|
||||
int (*ioctl) (struct ifnet *, ulong, caddr_t);
|
||||
};
|
||||
#define if_mtu ifd.ifi_mtu
|
||||
#define if_type ifd.ifi_type
|
||||
#define if_addrlen ifd.ifi_addrlen
|
||||
#define if_hdrlen ifd.ifi_hdrlen
|
||||
#define if_metric ifd.ifi_metric
|
||||
#define if_baudrate ifd.ifi_baudrate
|
||||
#define if_ipackets ifd.ifi_ipackets
|
||||
#define if_ierrors ifd.ifi_ierrors
|
||||
#define if_opackets ifd.ifi_opackets
|
||||
#define if_oerrors ifd.ifi_oerrors
|
||||
#define if_collisions ifd.ifi_collisions
|
||||
#define if_ibytes ifd.ifi_ibytes
|
||||
#define if_obytes ifd.ifi_obytes
|
||||
#define if_imcasts ifd.ifi_imcasts
|
||||
#define if_omcasts ifd.ifi_omcasts
|
||||
#define if_iqdrops ifd.ifi_iqdrops
|
||||
#define if_noproto ifd.ifi_noproto
|
||||
|
||||
#define IFNAMSIZ 16
|
||||
|
||||
/* This structure is used for passing interface requests via ioctl */
|
||||
struct ifreq {
|
||||
char ifr_name[IFNAMSIZ]; /* name of interface */
|
||||
union {
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_dstaddr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
uint16 ifru_flags;
|
||||
int ifru_metric;
|
||||
char * ifru_data;
|
||||
} ifr_ifru;
|
||||
};
|
||||
#define ifr_addr ifr_ifru.ifru_addr
|
||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
|
||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr
|
||||
#define ifr_flags ifr_ifru.ifru_flags
|
||||
#define ifr_metric ifr_ifru.ifru_metric
|
||||
#define ifr_mtu ifr_ifru.ifru_metric /* sneaky overload :) */
|
||||
#define ifr_data ifr_ifru.ifru_data
|
||||
|
||||
struct ifconf {
|
||||
int ifc_len; /* length of associated buffer */
|
||||
union {
|
||||
char * ifcu_buf;
|
||||
struct ifreq *ifcu_req;
|
||||
} ifc_ifcu;
|
||||
};
|
||||
#define ifc_buf ifc_ifcu.ifcu_buf
|
||||
#define ifc_req ifc_ifcu.ifcu_req
|
||||
|
||||
|
||||
#define IFAFREE(ifa) \
|
||||
do { \
|
||||
if ((ifa)->ifa_refcnt <= 0) \
|
||||
ifafree(ifa); \
|
||||
else \
|
||||
(ifa)->ifa_refcnt--; \
|
||||
} while (0)
|
||||
|
||||
/* used to pass in additional information, such as aliases */
|
||||
struct ifaliasreq {
|
||||
char ifa_name[IFNAMSIZ];
|
||||
struct sockaddr ifra_addr;
|
||||
struct sockaddr ifra_broadaddr;
|
||||
#define ifra_dstaddr ifra_broadaddr
|
||||
struct sockaddr ifra_mask;
|
||||
};
|
||||
|
||||
#define IFA_ROUTE RTF_UP
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
};
|
||||
|
||||
/* function declaration */
|
||||
struct ifq *start_ifq(void);
|
||||
void stop_ifq(struct ifq *);
|
||||
struct ifnet *get_interfaces(void);
|
||||
struct ifnet *ifunit(char *name);
|
||||
struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithaf(int);
|
||||
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithnet(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithroute(int, struct sockaddr *,
|
||||
struct sockaddr *);
|
||||
struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
|
||||
void ifafree(struct ifaddr *);
|
||||
|
||||
void if_attach(struct ifnet *ifp);
|
||||
void if_detach(struct ifnet *ifp);
|
||||
|
||||
int ifioctl(struct socket *so, ulong cmd, caddr_t data);
|
||||
int ifconf(int cmd, char *data);
|
||||
void if_init(void);
|
||||
unsigned if_nametoindex(const char *name);
|
||||
char *if_indextoname(unsigned index, char *nameBuffer);
|
||||
struct if_nameindex *if_nameindex(void);
|
||||
void if_freenameindex(struct if_nameindex *interfaceArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NET_IF_H */
|
||||
|
||||
#endif /* _NET_IF_H */
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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 {
|
||||
uint16 ar_hrd; /* format of hardware address */
|
||||
uint16 ar_pro; /* format of protocol address */
|
||||
uint8 ar_hln; /* length of hardware address */
|
||||
uint8 ar_pln; /* length of protocol address */
|
||||
uint16 ar_op; /* one of: */
|
||||
/*
|
||||
* The remaining fields are variable in size,
|
||||
* according to the sizes above.
|
||||
*/
|
||||
#ifdef COMMENT_ONLY
|
||||
uint8 ar_sha[]; /* sender hardware address */
|
||||
uint8 ar_spa[]; /* sender protocol address */
|
||||
uint8 ar_tha[]; /* target hardware address */
|
||||
uint8 ar_tpa[]; /* target protocol address */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ARPHRD_ETHER 1 /* ethernet hardware format */
|
||||
#define ARPHRD_IEEE802 6 /* IEEE 802 hardware format */
|
||||
#define ARPHRD_FRELAY 15 /* frame relay hardware format */
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* 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 */
|
@ -1,38 +1,28 @@
|
||||
/* if.h
|
||||
* Interface definitions for beos
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NET_IF_DL_H
|
||||
#define _NET_IF_DL_H
|
||||
|
||||
#ifndef OBOS_IF_DL_H
|
||||
#define OBOS_IF_DL_H
|
||||
|
||||
#include <net/if.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* link level sockaddr structure */
|
||||
/* Link level sockaddr structure */
|
||||
struct sockaddr_dl {
|
||||
uint8 sdl_len; /* Total length of sockaddr */
|
||||
uint8 sdl_family; /* AF_LINK */
|
||||
uint16 sdl_index; /* if != 0, system given index for interface */
|
||||
uint8 sdl_type; /* interface type */
|
||||
uint8 sdl_nlen; /* interface name length, no trailing 0 reqd. */
|
||||
uint8 sdl_alen; /* link level address length */
|
||||
uint8 sdl_slen; /* link layer selector length */
|
||||
char sdl_data[24]; /* minimum work area, can be larger;
|
||||
contains both if name and ll address */
|
||||
uint8_t sdl_len; /* Total length of sockaddr */
|
||||
uint8_t sdl_family; /* AF_LINK */
|
||||
uint16_t sdl_e_type; /* link level frame type */
|
||||
uint32_t sdl_index; /* index for interface */
|
||||
uint8_t sdl_type; /* interface type */
|
||||
uint8_t sdl_nlen; /* interface name length (not terminated with a null byte) */
|
||||
uint8_t sdl_alen; /* link level address length */
|
||||
uint8_t sdl_slen; /* link layer selector length */
|
||||
char sdl_data[20]; /* minimum work area, can be larger */
|
||||
};
|
||||
|
||||
/* Macro to get a pointer to the link level address */
|
||||
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
|
||||
|
||||
void link_addr (const char *, struct sockaddr_dl *);
|
||||
char *link_ntoa (const struct sockaddr_dl *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OBOS_IF_DL_H */
|
||||
#define LLADDR(s) ((char *)((s)->sdl_data + (s)->sdl_nlen))
|
||||
|
||||
#endif /* _NET_IF_DL_H */
|
||||
|
@ -1,129 +0,0 @@
|
||||
/* $OpenBSD: if_ppp.h,v 1.6 2001/06/09 06:16:38 angelos Exp $ */
|
||||
/* $NetBSD: if_ppp.h,v 1.11 1996/03/15 02:28:05 paulus Exp $ */
|
||||
|
||||
/*
|
||||
* if_ppp.h - Point-to-Point Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PPP_H_
|
||||
#define _NET_IF_PPP_H_
|
||||
|
||||
/*
|
||||
* Bit definitions for flags.
|
||||
*/
|
||||
#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */
|
||||
#define SC_COMP_AC 0x00000002 /* header compression (output) */
|
||||
#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */
|
||||
#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */
|
||||
#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */
|
||||
#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */
|
||||
#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */
|
||||
#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */
|
||||
#define SC_DEBUG 0x00010000 /* enable debug messages */
|
||||
#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */
|
||||
#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
|
||||
#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
|
||||
#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
|
||||
#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
|
||||
#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
|
||||
#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */
|
||||
#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */
|
||||
#define SC_MASK 0x0fff00ff /* bits that user can change */
|
||||
|
||||
/*
|
||||
* State bits in sc_flags, not changeable by user.
|
||||
*/
|
||||
#define SC_TIMEOUT 0x00000400 /* timeout is currently pending */
|
||||
#define SC_VJ_RESET 0x00000800 /* need to reset VJ decomp */
|
||||
#define SC_COMP_RUN 0x00001000 /* compressor has been inited */
|
||||
#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */
|
||||
#define SC_DC_ERROR 0x00004000 /* non-fatal decomp error detected */
|
||||
#define SC_DC_FERROR 0x00008000 /* fatal decomp error detected */
|
||||
#define SC_TBUSY 0x10000000 /* xmitter doesn't need a packet yet */
|
||||
#define SC_PKTLOST 0x20000000 /* have lost or dropped a packet */
|
||||
#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */
|
||||
#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */
|
||||
|
||||
/*
|
||||
* Ioctl definitions.
|
||||
*/
|
||||
|
||||
struct npioctl {
|
||||
int protocol; /* PPP procotol, e.g. PPP_IP */
|
||||
int on;
|
||||
};
|
||||
|
||||
/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
|
||||
struct ppp_option_data {
|
||||
u_char *ptr;
|
||||
u_int length;
|
||||
int transmit;
|
||||
};
|
||||
|
||||
struct ifpppstatsreq {
|
||||
char ifr_name[IFNAMSIZ];
|
||||
struct ppp_stats stats;
|
||||
};
|
||||
|
||||
struct ifpppcstatsreq {
|
||||
char ifr_name[IFNAMSIZ];
|
||||
struct ppp_comp_stats stats;
|
||||
};
|
||||
|
||||
/*
|
||||
* Ioctl definitions.
|
||||
*/
|
||||
|
||||
#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */
|
||||
#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */
|
||||
#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */
|
||||
#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */
|
||||
#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
|
||||
#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */
|
||||
#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */
|
||||
#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */
|
||||
#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */
|
||||
#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */
|
||||
#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
|
||||
#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
|
||||
#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */
|
||||
#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
|
||||
#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */
|
||||
#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
|
||||
#define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */
|
||||
#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */
|
||||
#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */
|
||||
|
||||
/* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */
|
||||
#define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */
|
||||
#define PPPIOCSMTU _IOW('t', 72, int) /* set interface MTU */
|
||||
|
||||
/*
|
||||
* These two are interface ioctls so that pppstats can do them on
|
||||
* a socket without having to open the serial device.
|
||||
*/
|
||||
#define SIOCGPPPSTATS _IOWR('i', 123, struct ifpppstatsreq)
|
||||
#define SIOCGPPPCSTATS _IOWR('i', 122, struct ifpppcstatsreq)
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
int pppoutput (struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct rtentry *);
|
||||
void pppinput (struct mbuf *);
|
||||
#endif
|
||||
|
||||
#endif /* _NET_IF_PPP_H_ */
|
@ -1,23 +1,15 @@
|
||||
/* if_types.h
|
||||
*
|
||||
* <URL:http://www.iana.org/assignments/ianaiftype-mib>
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NET_IF_TYPES_H
|
||||
#define _NET_IF_TYPES_H
|
||||
|
||||
#ifndef NET_IF_TYPES_H
|
||||
#define NET_IF_TYPES_H
|
||||
|
||||
/* We just list the ones here we actually use... */
|
||||
|
||||
#define IFT_ETHER 0x06
|
||||
#define IFT_PPP 0x17
|
||||
#define IFT_LOOP 0x18
|
||||
#define IFT_SLIP 0x1c
|
||||
#define IFT_RS232 0x21
|
||||
#define IFT_PARA 0x22 /* Parallel port! ?? */
|
||||
#define IFT_ATM 0x25
|
||||
#define IFT_MODEM 0x31 /* Just a simple generic modem */
|
||||
#define IFT_FASTETHER 0x32 /* 100BaseT ethernet */
|
||||
#define IFT_ISDN 0x3f /* ISDN / X.25 */
|
||||
|
||||
#endif /* NET_IF_TYPES_H */
|
||||
#define IFT_OTHER 0x01
|
||||
#define IFT_ETHER 0x06
|
||||
#define IFT_PPP 0x17
|
||||
#define IFT_LOOP 0x18
|
||||
#define IFT_SLIP 0x1c
|
||||
#define IFT_MODEM 0x30
|
||||
|
||||
#endif /* _NET_IF_TYPES_H */
|
||||
|
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* $FreeBSD: src/sys/net/radix.h,v 1.16.2.1 2000/05/03 19:17:11 wollman Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NET_RADIX_H_
|
||||
#define _NET_RADIX_H_
|
||||
|
||||
//#include <memheap.h>
|
||||
|
||||
/*
|
||||
* Radix search tree node layout.
|
||||
*/
|
||||
|
||||
struct radix_node {
|
||||
struct radix_mask *rn_mklist; /* list of masks contained in subtree */
|
||||
struct radix_node *rn_parent; /* parent */
|
||||
short rn_bit; /* 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: */
|
||||
char * rn_Key; /* object of search */
|
||||
char * 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_offset rn_u.rn_node.rn_Off
|
||||
#define rn_left rn_u.rn_node.rn_L
|
||||
#define rn_right rn_u.rn_node.rn_R
|
||||
|
||||
/*
|
||||
* Annotations to tree concerning potential routes applying to subtrees.
|
||||
*/
|
||||
|
||||
struct radix_mask {
|
||||
short rm_bit; /* 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 {
|
||||
char * rmu_mask; /* the mask */
|
||||
struct radix_node *rmu_leaf; /* for normal routes */
|
||||
} rm_rmu;
|
||||
int rm_refs; /* # of references to this struct */
|
||||
};
|
||||
|
||||
#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);}
|
||||
|
||||
typedef int walktree_f_t (struct radix_node *, void *);
|
||||
|
||||
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 */
|
||||
(void *v, void *mask,
|
||||
struct radix_node_head *head, struct radix_node nodes[]);
|
||||
struct radix_node *(*rnh_addpkt) /* add based on packet hdr */
|
||||
(void *v, void *mask,
|
||||
struct radix_node_head *head, struct radix_node nodes[]);
|
||||
struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */
|
||||
(void *v, void *mask, struct radix_node_head *head);
|
||||
struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */
|
||||
(void *v, void *mask, struct radix_node_head *head);
|
||||
struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */
|
||||
(void *v, struct radix_node_head *head);
|
||||
struct radix_node *(*rnh_lookup) /* locate based on sockaddr */
|
||||
(void *v, void *mask, struct radix_node_head *head);
|
||||
struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */
|
||||
(void *v, struct radix_node_head *head);
|
||||
int (*rnh_walktree) /* traverse tree */
|
||||
(struct radix_node_head *head, walktree_f_t *f, void *w);
|
||||
int (*rnh_walktree_from) /* traverse tree below a */
|
||||
(struct radix_node_head *head, void *a, void *m,
|
||||
walktree_f_t *f, void *w);
|
||||
void (*rnh_close) /* do something when the last ref drops */
|
||||
(struct radix_node *rn, struct radix_node_head *head);
|
||||
struct radix_node rnh_nodes[3]; /* empty tree for common case */
|
||||
};
|
||||
|
||||
#define Bcmp(a, b, n) memcmp(((char *)(a)), ((char *)(b)), (n))
|
||||
#define Bcopy(a, b, n) memcpy(((char *)(b)), ((char *)(a)), (unsigned)(n))
|
||||
#define Bzero(p, n) memset((char *)(p),0, (int)(n));
|
||||
#define R_Malloc(p, t, n) do { \
|
||||
(p = (t) malloc((unsigned int)(n))); \
|
||||
memset(p, 0, sizeof(*p)); \
|
||||
} while (0)
|
||||
#define Free(p) free((char *)p);
|
||||
|
||||
void rn_init (void);
|
||||
int rn_inithead (void **, int);
|
||||
int rn_refines (void *, void *);
|
||||
struct radix_node
|
||||
*rn_addmask (void *, int, int),
|
||||
*rn_addroute (void *, void *, struct radix_node_head *,
|
||||
struct radix_node [2]),
|
||||
*rn_delete (void *, void *, struct radix_node_head *),
|
||||
*rn_lookup (void *v_arg, void *m_arg,
|
||||
struct radix_node_head *head),
|
||||
*rn_match (void *, struct radix_node_head *);
|
||||
|
||||
/* extra fucntion so we don't have to export the mask_rnhead */
|
||||
struct radix_node *rn_head_search(void *argv_v);
|
||||
|
||||
#endif /* _NET_RADIX_H_ */
|
@ -1,17 +0,0 @@
|
||||
/* raw_cb.h */
|
||||
|
||||
#ifndef NET_RAW_CB_H
|
||||
#define NET_RAW_CB_H
|
||||
|
||||
struct rawcb {
|
||||
struct rawcb *rcb_next;
|
||||
struct rawcb *rcb_prev;
|
||||
struct socket *rcb_socket;
|
||||
struct sockaddr *rcb_faddr;
|
||||
struct sockaddr *rcb_laddr;
|
||||
struct sockproto rcb_proto;
|
||||
};
|
||||
|
||||
#define sotorawcb(so) ((struct rawcb*)(so)->so_pcb)
|
||||
|
||||
#endif /* NET_RAW_CB_H */
|
@ -1,208 +1,34 @@
|
||||
/* route.h */
|
||||
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NET_ROUTE_H
|
||||
#define _NET_ROUTE_H
|
||||
|
||||
#include <net/radix.h>
|
||||
#include <sys/socket.h> /* for AF_MAX */
|
||||
/*
|
||||
* 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;
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#define RTF_UP 0x00000001
|
||||
#define RTF_GATEWAY 0x00000002
|
||||
#define RTF_HOST 0x00000004
|
||||
#define RTF_REJECT 0x00000008
|
||||
#define RTF_DYNAMIC 0x00000010
|
||||
#define RTF_MODIFIED 0x00000020
|
||||
#define RTF_DEFAULT 0x00000080
|
||||
#define RTF_STATIC 0x00000800
|
||||
#define RTF_BLACKHOLE 0x00001000
|
||||
#define RTF_LOCAL 0x00200000
|
||||
|
||||
// This structure is used to pass routes to and from the network stack
|
||||
// (via struct ifreq)
|
||||
|
||||
struct route_entry {
|
||||
struct sockaddr *destination;
|
||||
struct sockaddr *mask;
|
||||
struct sockaddr *gateway;
|
||||
uint32_t flags;
|
||||
uint32_t mtu;
|
||||
};
|
||||
|
||||
/*
|
||||
* These numbers are used by reliable protocols for determining
|
||||
* retransmission behavior and are included in the routing structure.
|
||||
*/
|
||||
struct rt_metrics {
|
||||
uint32 rmx_locks; /* Kernel must leave these values alone */
|
||||
uint32 rmx_mtu; /* MTU for this path */
|
||||
uint32 rmx_hopcount; /* max hops expected */
|
||||
uint32 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))
|
||||
|
||||
struct rtentry {
|
||||
struct radix_node rt_nodes[2]; /* tree glue, and other values */
|
||||
struct sockaddr *rt_gateway; /* value */
|
||||
uint rt_flags; /* up/down?, host/net */
|
||||
int rt_refcnt; /* # held references */
|
||||
uint32 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 */
|
||||
char * 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. */
|
||||
/* XXX - add this! */
|
||||
// rt_timer; * queue of timeouts for misc funcs *
|
||||
};
|
||||
#define rt_use rt_rmx.rmx_pksent
|
||||
#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key))
|
||||
#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask))
|
||||
|
||||
#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 */
|
||||
|
||||
#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_msghdr {
|
||||
uint16 rtm_msglen;
|
||||
uint8 rtm_version;
|
||||
uint8 rtm_type;
|
||||
|
||||
uint16 rtm_index;
|
||||
int rtm_flags;
|
||||
int rtm_addrs;
|
||||
int rtm_seq;
|
||||
int rtm_errno;
|
||||
int rtm_use;
|
||||
uint32 rtm_inits;
|
||||
struct rt_metrics rtm_rmx;
|
||||
};
|
||||
|
||||
struct rt_addrinfo {
|
||||
int rti_addrs;
|
||||
struct sockaddr *rti_info[RTAX_MAX];
|
||||
int rti_flags;
|
||||
struct ifaddr *rti_ifa;
|
||||
struct ifnet *rti_ifp;
|
||||
struct rt_msghdr *rti_rtm;
|
||||
};
|
||||
|
||||
struct route_cb {
|
||||
int32 ip_count; /* how many AF_INET structures we have */
|
||||
int32 any_count; /* total of all above... */
|
||||
};
|
||||
|
||||
struct walkarg {
|
||||
int w_op;
|
||||
int w_arg;
|
||||
int w_given;
|
||||
int w_needed;
|
||||
int w_tmemsize;
|
||||
char * w_where;
|
||||
char * w_tmem;
|
||||
};
|
||||
|
||||
/*
|
||||
* Routing statistics.
|
||||
*/
|
||||
struct rtstat {
|
||||
int32 rts_badredirect; /* bogus redirect calls */
|
||||
int32 rts_dynamic; /* routes created by redirects */
|
||||
int32 rts_newgateway; /* routes modified by redirects */
|
||||
int32 rts_unreach; /* lookups which failed */
|
||||
int32 rts_wildcard; /* lookups satisfied by a wildcard */
|
||||
};
|
||||
|
||||
#define RTFREE(rt) do { \
|
||||
if ((rt)->rt_refcnt <= 1) \
|
||||
rtfree(rt); \
|
||||
else \
|
||||
(rt)->rt_refcnt--; \
|
||||
} while (0)
|
||||
|
||||
extern struct rtstat rtstat;
|
||||
extern struct radix_node_head *rt_tables[AF_MAX+1];
|
||||
|
||||
void route_init(void);
|
||||
|
||||
int rtinit (struct ifaddr *, int, int);
|
||||
void rtalloc (struct route *);
|
||||
struct rtentry *rtalloc1 (struct sockaddr *, int);
|
||||
void rtfree (struct rtentry *);
|
||||
int rtrequest (int, struct sockaddr *,
|
||||
struct sockaddr *, struct sockaddr *, int,
|
||||
struct rtentry **);
|
||||
void rt_maskedcopy(struct sockaddr *src,
|
||||
struct sockaddr *dst,
|
||||
struct sockaddr *netmask);
|
||||
int rt_setgate (struct rtentry *, struct sockaddr *,
|
||||
struct sockaddr *);
|
||||
|
||||
struct radix_node_head ** get_rt_tables(void);
|
||||
|
||||
#endif /* NET_ROUTE_H */
|
||||
#endif /* _NET_ROUTE_H */
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* ++Copyright++ 1980, 1983, 1988, 1993
|
||||
* -
|
||||
* Copyright (c) 1980, 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -80,20 +78,12 @@
|
||||
* 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--
|
||||
*/
|
||||
|
||||
/*
|
||||
* @(#)netdb.h 8.1 (Berkeley) 6/2/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NETDB_H_
|
||||
#define _NETDB_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bitypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -1,59 +0,0 @@
|
||||
/* Parts of this file are covered under the following copyright */
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include "netinet/ip_icmp.h"
|
||||
|
||||
struct icmpstat {
|
||||
int32 icps_oldicmp;
|
||||
int32 icps_oldshort;
|
||||
int32 icps_badcode;
|
||||
int32 icps_badlen;
|
||||
int32 icps_checksum;
|
||||
int32 icps_tooshort;
|
||||
int32 icps_error;
|
||||
int32 icps_reflect;
|
||||
int32 icps_outhist[ICMP_MAXTYPE + 1];
|
||||
int32 icps_inhist[ICMP_MAXTYPE + 1];
|
||||
};
|
||||
|
||||
//#ifdef _KERNEL_MODE
|
||||
//struct icmpstat icmpstat;
|
||||
//#endif
|
||||
|
||||
#endif /* NETINET_ICMP_VAR_H */
|
@ -1,198 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include "net/if_arp.h"
|
||||
|
||||
/*
|
||||
* Ethernet address - 6 octets
|
||||
* this is only used by the ethers(3) functions.
|
||||
*/
|
||||
struct ether_addr {
|
||||
uint8 ether_addr_octet[6];
|
||||
};
|
||||
|
||||
/*
|
||||
* Some Ethernet constants.
|
||||
*/
|
||||
#define ETHER_ADDR_LEN 6 /* Ethernet address length */
|
||||
#define ETHER_TYPE_LEN 2 /* Ethernet type field length */
|
||||
#define ETHER_CRC_LEN 4 /* Ethernet CRC lenght */
|
||||
#define ETHER_HDR_LEN ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)
|
||||
#define ETHER_MIN_LEN 64 /* Minimum frame length, CRC included */
|
||||
#define ETHER_MAX_LEN 1518 /* Maximum frame length, CRC included */
|
||||
|
||||
struct ether_header {
|
||||
uint8 ether_dhost[ETHER_ADDR_LEN];
|
||||
uint8 ether_shost[ETHER_ADDR_LEN];
|
||||
uint16 ether_type;
|
||||
};
|
||||
|
||||
#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_8021Q 0x8100 /* IEEE 802.1Q VLAN tagging */
|
||||
#define ETHERTYPE_IPV6 0x86DD /* IPv6 protocol */
|
||||
#define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
|
||||
#define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
|
||||
#define ETHERTYPE_LOOPBACK 0x9000 /* used to test interfaces */
|
||||
|
||||
#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
|
||||
|
||||
#define ETHERMTU (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
|
||||
#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
|
||||
|
||||
|
||||
//#ifdef _NETWORK_STACK
|
||||
|
||||
/*
|
||||
* 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] = ((uint8 *)ipaddr)[1] & 0x7f; \
|
||||
(enaddr)[4] = ((uint8 *)ipaddr)[2]; \
|
||||
(enaddr)[5] = ((uint8 *)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
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
uint8 ac_enaddr[ETHER_ADDR_LEN]; /* ethernet hardware address */
|
||||
struct in_addr ac_ipaddr;
|
||||
char ac__pad[2]; /* pad for some machines */
|
||||
// struct ether_multi *ac_multiaddrs; /* list of ether multicast addrs */
|
||||
int ac_multicnt; /* length of ac_multiaddrs list */
|
||||
};
|
||||
|
||||
struct ether_device {
|
||||
struct arpcom sc_ac;
|
||||
struct ether_device *next; /* next ether_device */
|
||||
};
|
||||
#define sc_if sc_ac.ac_if
|
||||
#define sc_addr sc_ac.ac_enaddr
|
||||
|
||||
struct ether_arp {
|
||||
struct arphdr ea_hdr;
|
||||
u_char arp_sha[6];
|
||||
u_char arp_spa[4];
|
||||
u_char arp_tha[6];
|
||||
u_char arp_tpa[4];
|
||||
};
|
||||
#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
|
||||
|
||||
struct llinfo_arp {
|
||||
struct llinfo_arp *la_next;
|
||||
struct llinfo_arp *la_prev;
|
||||
struct rtentry *la_rt;
|
||||
struct mbuf *la_hold;
|
||||
int32 la_asked;
|
||||
};
|
||||
|
||||
#define la_timer la_rt->rt_rmx.rmx_expire
|
||||
|
||||
struct sockaddr_inarp {
|
||||
uint8 sin_len;
|
||||
uint8 sin_family;
|
||||
uint16 sin_port;
|
||||
struct in_addr sin_addr;
|
||||
struct in_addr sin_srcaddr;
|
||||
uint16 sin_tos;
|
||||
uint16 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 _NETWORK_STACK
|
||||
|
||||
int arpresolve(struct arpcom *ac, struct rtentry *rt, struct mbuf *m,
|
||||
struct sockaddr *dst, uint8 *desten);
|
||||
//void arpwhohas(struct arpcom *ac, struct in_addr *ia);
|
||||
|
||||
|
||||
//#else
|
||||
|
||||
char *ether_ntoa (struct ether_addr *);
|
||||
struct ether_addr *ether_aton (char *);
|
||||
int ether_ntohost (char *, struct ether_addr *);
|
||||
int ether_hostton (char *, struct ether_addr *);
|
||||
int ether_line(char *line, struct ether_addr *e, char *hostname);
|
||||
|
||||
//#endif
|
||||
|
||||
#endif /* NETINET_IF_ETHER_H */
|
||||
|
@ -6,20 +6,21 @@
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <endian.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned short in_port_t;
|
||||
typedef unsigned long in_addr_t;
|
||||
typedef uint16_t in_port_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
|
||||
/* We can't include <ByteOrder.h> since we are a posix file,
|
||||
* and we are not allowed to import all the BeOS types here.
|
||||
*/
|
||||
#ifndef htonl
|
||||
extern unsigned long __swap_int32(unsigned long); /* private */
|
||||
extern unsigned short __swap_int16(unsigned short); /* private */
|
||||
extern uint32_t __swap_int32(uint32_t); /* private */
|
||||
extern uint16_t __swap_int16(uint16_t); /* private */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define htonl(x) __swap_int32(x)
|
||||
#define ntohl(x) __swap_int32(x)
|
||||
@ -73,11 +74,11 @@ struct in_addr {
|
||||
* IP Version 4 socket address.
|
||||
*/
|
||||
struct sockaddr_in {
|
||||
uint8 sin_len;
|
||||
uint8 sin_family;
|
||||
uint16 sin_port;
|
||||
uint8_t sin_len;
|
||||
uint8_t sin_family;
|
||||
uint16_t sin_port;
|
||||
struct in_addr sin_addr;
|
||||
int8 sin_zero[24];
|
||||
int8_t sin_zero[24];
|
||||
};
|
||||
/* the address is therefore at sin_addr.s_addr */
|
||||
|
||||
@ -99,7 +100,7 @@ struct sockaddr_in {
|
||||
#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */
|
||||
#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */
|
||||
|
||||
#define __IPADDR(x) ((uint32) htonl((uint32)(x)))
|
||||
#define __IPADDR(x) ((uint32_t)htonl((uint32_t)(x)))
|
||||
|
||||
#define INADDR_ANY __IPADDR(0x00000000)
|
||||
#define INADDR_LOOPBACK __IPADDR(0x7f000001)
|
||||
@ -114,27 +115,27 @@ struct sockaddr_in {
|
||||
|
||||
#define INADDR_NONE __IPADDR(0xffffffff)
|
||||
|
||||
#define IN_CLASSA(i) (((uint32)(i) & __IPADDR(0x80000000)) == \
|
||||
#define IN_CLASSA(i) (((uint32_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) (((uint32)(i) & __IPADDR(0xc0000000)) == \
|
||||
#define IN_CLASSB(i) (((uint32_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) (((uint32)(i) & __IPADDR(0xe0000000)) == \
|
||||
#define IN_CLASSC(i) (((uint32_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) (((uint32)(i) & __IPADDR(0xf0000000)) == \
|
||||
#define IN_CLASSD(i) (((uint32_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)
|
||||
@ -143,8 +144,8 @@ struct sockaddr_in {
|
||||
|
||||
#define IN_MULTICAST(i) IN_CLASSD(i)
|
||||
|
||||
#define IN_EXPERIMENTAL(i) (((uint32)(i) & 0xf0000000) == 0xf0000000)
|
||||
#define IN_BADCLASS(i) (((uint32)(i) & 0xf0000000) == 0xf0000000)
|
||||
#define IN_EXPERIMENTAL(i) (((uint32_t)(i) & 0xf0000000) == 0xf0000000)
|
||||
#define IN_BADCLASS(i) (((uint32_t)(i) & 0xf0000000) == 0xf0000000)
|
||||
|
||||
#define IP_MAX_MEMBERSHIPS 20
|
||||
|
||||
@ -163,7 +164,7 @@ int in_localaddr (struct in_addr);
|
||||
void in_socktrim (struct sockaddr_in*);
|
||||
/* uint16 in_cksum (struct mbuf *, int); */
|
||||
struct mbuf;
|
||||
uint16 in_cksum(struct mbuf *m, int len, int off);
|
||||
uint16_t in_cksum(struct mbuf *m, int len, int off);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
/* in_pcb.h
|
||||
* internet protcol control blocks
|
||||
*/
|
||||
|
||||
//#include <sys/socketvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <pools.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#ifndef _NETINET_INPCB_H
|
||||
#define _NETINET_INPCB_H
|
||||
|
||||
enum {
|
||||
INP_HDRINCL = 0x01,
|
||||
INP_RECVOPTS = 0x02,
|
||||
INP_RECVRETOPTS = 0x04,
|
||||
INP_RECVDSTADDR = 0x08 /* receive IP destination as control inf. */
|
||||
};
|
||||
#define INP_CONTROLOPT (INP_RECVOPTS | INP_RECVRETOPTS | INP_RECVDSTADDR)
|
||||
|
||||
/* Constants for in_pcblookup */
|
||||
enum {
|
||||
INPLOOKUP_WILDCARD = 1,
|
||||
INPLOOKUP_SETLOCAL = 2,
|
||||
INPLOOKUP_IPV6 = 4
|
||||
};
|
||||
|
||||
struct inpcb {
|
||||
struct inpcb *inp_next;
|
||||
struct inpcb *inp_prev;
|
||||
struct inpcb *inp_head;
|
||||
|
||||
struct in_addr faddr; /* foreign address */
|
||||
uint16 fport; /* foreign port # */
|
||||
struct in_addr laddr; /* local address */
|
||||
uint16 lport; /* local port # */
|
||||
|
||||
struct socket *inp_socket;
|
||||
char *inp_ppcb; /* pointer to a per protocol pcb*/
|
||||
struct ip inp_ip; /* header prototype */
|
||||
int inp_flags; /* flags */
|
||||
struct mbuf *inp_options; /* IP options */
|
||||
/* more will be required */
|
||||
struct route inp_route; /* the route to host */
|
||||
};
|
||||
|
||||
int in_pcbinit (void);
|
||||
int in_pcballoc (struct socket *, struct inpcb *);
|
||||
int in_pcbbind (struct inpcb *, struct mbuf *);
|
||||
int in_pcbconnect (struct inpcb *, struct mbuf *);
|
||||
void in_pcbdetach (struct inpcb *);
|
||||
int in_pcbdisconnect (struct inpcb *);
|
||||
void in_losing (struct inpcb *);
|
||||
void in_setpeeraddr (struct inpcb *, struct mbuf *);
|
||||
void in_setsockaddr (struct inpcb *, struct mbuf *);
|
||||
|
||||
struct inpcb *in_pcblookup(struct inpcb *head, struct in_addr faddr,
|
||||
uint16 fport_a, struct in_addr laddr,
|
||||
uint16 lport_a, int flags);
|
||||
struct rtentry *in_pcbrtentry (struct inpcb *);
|
||||
void in_pcbnotify (struct inpcb *, struct sockaddr *,
|
||||
uint16, struct in_addr, uint16,
|
||||
int, void (*)(struct inpcb *, int));
|
||||
|
||||
/* helpful macro's */
|
||||
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
|
||||
|
||||
#endif /* _NETINET_INPCB_H */
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <stdint.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 uint16_t n_short; /* short as received from the net */
|
||||
typedef uint32_t n_long; /* long as received from the net */
|
||||
|
||||
typedef uint32_t n_time; /* ms since 00:00 GMT, byte rev */
|
||||
|
||||
#define iptime() (htonl((uint32_t)real_time_clock_usecs()))
|
||||
|
||||
#endif /* NETINET_IN_SYSTM_H */
|
||||
|
||||
|
@ -1,66 +0,0 @@
|
||||
/* in_var.h */
|
||||
#ifndef NETINET_IN_VAR_H
|
||||
#define NETINET_IN_VAR_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
|
||||
struct in_ifaddr {
|
||||
struct ifaddr ia_ifa;
|
||||
struct in_ifaddr *ia_next;
|
||||
|
||||
uint32 ia_net;
|
||||
uint32 ia_netmask;
|
||||
uint32 ia_subnet;
|
||||
uint32 ia_subnetmask;
|
||||
struct in_addr ia_netbroadcast;
|
||||
struct sockaddr_in ia_addr;
|
||||
struct sockaddr_in ia_dstaddr; /* broadcast address */
|
||||
struct sockaddr_in ia_sockmask;
|
||||
/*XXX - milticast address list */
|
||||
};
|
||||
#define ia_ifp ia_ifa.ifa_ifp
|
||||
#define ia_flags ia_ifa.ifa_flags
|
||||
#define ia_broadaddr ia_dstaddr
|
||||
|
||||
#define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
|
||||
#define sintosa(sin) ((struct sockaddr *)(sin))
|
||||
|
||||
/* used to pass in additional information, such as aliases */
|
||||
struct in_aliasreq {
|
||||
char ifa_name[IFNAMSIZ];
|
||||
struct sockaddr_in ifra_addr;
|
||||
struct sockaddr_in ifra_broadaddr;
|
||||
#define ifra_dstaddr ifra_broadaddr
|
||||
struct sockaddr_in ifra_mask;
|
||||
};
|
||||
|
||||
|
||||
struct in_multi {
|
||||
struct in_addr inm_addr;
|
||||
struct ifnet *inm_ifp;
|
||||
struct in_ifaddr *inm_ia;
|
||||
uint inm_refcount;
|
||||
uint inm_timer;
|
||||
struct in_multi *next;
|
||||
struct in_multi **prev;
|
||||
uint inm_state;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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))
|
||||
|
||||
// extern struct in_ifaddr *in_ifaddr;
|
||||
|
||||
int in_control(struct socket *so, int cmd, char *data, struct ifnet *ifp);
|
||||
int in_ifinit(struct ifnet *dev, struct in_ifaddr *ia, struct sockaddr_in *sin,
|
||||
int scrub);
|
||||
int inetctlerr(int cmd);
|
||||
struct in_ifaddr *get_primary_addr(void);
|
||||
|
||||
#endif /* NETINET_IN_VAR_H */
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef _NETINET_IP_H
|
||||
#define _NETINET_IP_H
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -81,10 +80,10 @@ struct ip_timestamp {
|
||||
ipt_oflw:4;
|
||||
#endif
|
||||
union ipt_timestamp {
|
||||
n_time ipt_time[1];
|
||||
uint32_t ipt_time[1];
|
||||
struct ipt_ta {
|
||||
struct in_addr ipt_addr;
|
||||
n_time ipt_time;
|
||||
uint32_t ipt_time;
|
||||
} ipt_ta;
|
||||
} ipt_timestamp;
|
||||
};
|
||||
|
@ -50,27 +50,27 @@ struct icmp {
|
||||
uint8_t ih_pptr;
|
||||
struct in_addr ih_gwaddr;
|
||||
struct ih_idseq {
|
||||
n_short icd_id;
|
||||
n_short icd_seq;
|
||||
uint16_t icd_id;
|
||||
uint16_t icd_seq;
|
||||
} ih_idseq;
|
||||
int32_t ih_void;
|
||||
|
||||
/* ICMP_UNREACH_NEEDFRAG (RFC 1191) */
|
||||
struct ih_pmtu {
|
||||
n_short ipm_void;
|
||||
n_short ipm_nextmtu;
|
||||
uint16_t ipm_void;
|
||||
uint16_t ipm_nextmtu;
|
||||
} ih_pmtu;
|
||||
} icmp_hun;
|
||||
union {
|
||||
struct id_ts {
|
||||
n_time its_otime;
|
||||
n_time its_rtime;
|
||||
n_time its_ttime;
|
||||
uint32_t its_otime;
|
||||
uint32_t its_rtime;
|
||||
uint32_t its_ttime;
|
||||
} id_ts;
|
||||
struct id_ip {
|
||||
struct ip idi_ip;
|
||||
} id_ip;
|
||||
uint32 id_mask;
|
||||
uint32_t id_mask;
|
||||
char id_data[1];
|
||||
} icmp_dun;
|
||||
};
|
||||
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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_
|
||||
|
||||
struct tcp_debug {
|
||||
n_time td_time;
|
||||
short td_act;
|
||||
short td_ostate;
|
||||
caddr_t td_tcb;
|
||||
struct tcpiphdr td_ti;
|
||||
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
|
||||
|
||||
//#ifdef TANAMES
|
||||
//char *tanames[] =
|
||||
// { "input", "output", "user", "respond", "drop" };
|
||||
//#endif /* TANAMES */
|
||||
|
||||
#define TCP_NDEBUG 100
|
||||
struct tcp_debug tcp_debug[TCP_NDEBUG];
|
||||
int tcp_debx;
|
||||
#endif /* _NETINET_TCP_DEBUG_H_ */
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* 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 /* TCPOUTFLAGS */
|
||||
|
||||
#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 /* TCPSTATES */
|
||||
#endif /* _NETINET_TCP_FSM_H_ */
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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 _NETWORK_STACK
|
||||
extern tcp_seq tcp_iss; /* tcp initial send seq # */
|
||||
//#endif /* _NETWORK_STACK */
|
||||
|
||||
#endif /* _NETINET_TCP_SEQ_H_ */
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NETINET_TCP_TIMERS_H
|
||||
#define NETINET_TCP_TIMERS_H
|
||||
|
||||
/*
|
||||
* Definitions of the TCP timers. These timers are counted
|
||||
* down PR_SLOWHZ times a second.
|
||||
*/
|
||||
#define TCPT_NTIMERS 4
|
||||
|
||||
#define TCPT_REXMT 0 /* retransmission timer */
|
||||
#define TCPT_PERSIST 1 /* presist timer */
|
||||
#define TCPT_KEEP 2 /* keeplaive timer or conn est timer */
|
||||
#define TCPT_2MSL 3 /* 2MSL timer or FIN_WAIT_2 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 /* at most 2 minutes... */
|
||||
#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
|
||||
|
||||
//#ifdef TCPTIMERS
|
||||
//char *tcptimers[] =
|
||||
// { "REXMT", "PERSIST", "KEEP", "2MSL" };
|
||||
//#endif /* TCPTIMERS */
|
||||
extern char *tcptimers[];
|
||||
|
||||
/*
|
||||
* 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 _NETWORK_STACK
|
||||
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 /* _NETWORK_STACK */
|
||||
|
||||
#endif /* NETINET_TCP_TIMERS_H */
|
@ -1,282 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NETINET_TCP_VAR_H
|
||||
#define NETINET_TCP_VAR_H
|
||||
|
||||
/*
|
||||
* Tcp control block, one per tcp connection
|
||||
*/
|
||||
struct tcpcb {
|
||||
struct tcpiphdr *seg_next;
|
||||
struct tcpiphdr *seg_prev;
|
||||
int16 t_state; /* state of this connection */
|
||||
int16 t_timer[TCPT_NTIMERS]; /* tcp timers */
|
||||
int16 t_rxtshift; /* log(2) of rexmt exp. backoff */
|
||||
int16 t_rxtcur; /* current retransmit value */
|
||||
int16 t_dupacks; /* consecutive dup acks recd */
|
||||
uint16 t_maxseg; /* maximum segment size */
|
||||
int8 t_force; /* 1 if forcing out a byte */
|
||||
uint16 t_flags;
|
||||
|
||||
struct tcpiphdr *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 */
|
||||
unsigned long snd_wnd; /* send window */
|
||||
|
||||
/* receive sequence variables */
|
||||
unsigned 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 */
|
||||
|
||||
/*
|
||||
* 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) */
|
||||
unsigned long snd_cwnd; /* congestion-controlled window */
|
||||
unsigned long snd_ssthresh; /* snd_cwnd size threshhold for
|
||||
* for slow start exponential to
|
||||
* linear switch
|
||||
*/
|
||||
uint16 t_maxopd; /* mss plus options */
|
||||
uint16 t_peermss; /* peer's maximum segment size */
|
||||
|
||||
/*
|
||||
* transmit timing stuff. See below for scale of srtt and rttvar.
|
||||
* "Variance" is actually smoothed difference.
|
||||
*/
|
||||
int16 t_idle; /* inactivity time */
|
||||
int16 t_rtt; /* round trip time */
|
||||
tcp_seq t_rtseq; /* sequence number being timed */
|
||||
uint16 t_srtt; /* smoothed round-trip time */
|
||||
uint16 t_rttvar; /* variance in round-trip time */
|
||||
uint16 t_rttmin; /* minimum rtt allowed */
|
||||
uint32 max_sndwnd; /* largest window peer has offered */
|
||||
|
||||
/* out-of-band data */
|
||||
int8 t_oobflags; /* have some */
|
||||
int8 t_iobc; /* input character */
|
||||
int16 t_softerror; /* possible error, not yet reported... */
|
||||
/* RFC 1323 variables */
|
||||
uint8 snd_scale; /* window scaling for send window */
|
||||
uint8 rcv_scale; /* window scaling for recv window */
|
||||
uint8 request_r_scale; /* pending window scaling */
|
||||
uint8 requested_s_scale;
|
||||
uint32 ts_recent; /* timestamp echo data */
|
||||
uint32 ts_recent_age; /* when last updated */
|
||||
tcp_seq last_ack_sent;
|
||||
};
|
||||
|
||||
#define intotcpcb(ip) ((struct tcpcb*)(ip)->inp_ppcb)
|
||||
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
|
||||
|
||||
#define TF_ACKNOW 0x0001 /* send ACK immeadiately */
|
||||
#define TF_DELACK 0x0002 /* send 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 */
|
||||
|
||||
#define TCPOOB_HAVEDATA 0x01 /* we have TCP OOB data */
|
||||
#define TCPOOB_HADDATA 0x02 /* we've had some TCP OOB data */
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
#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 {
|
||||
uint32 tcps_connattempt; /* connections initiated */
|
||||
uint32 tcps_accepts; /* connections accepted */
|
||||
uint32 tcps_connects; /* connections established */
|
||||
uint32 tcps_drops; /* connections dropped */
|
||||
uint32 tcps_conndrops; /* embryonic connections dropped */
|
||||
uint32 tcps_closed; /* conn. closed (includes drops) */
|
||||
uint32 tcps_segstimed; /* segs where we tried to get rtt */
|
||||
uint32 tcps_rttupdated; /* times we succeeded */
|
||||
uint32 tcps_delack; /* delayed acks sent */
|
||||
uint32 tcps_timeoutdrop; /* conn. dropped in rxmt timeout */
|
||||
uint32 tcps_rexmttimeo; /* retransmit timeouts */
|
||||
uint32 tcps_persisttimeo; /* persist timeouts */
|
||||
uint32 tcps_persistdrop; /* connections dropped in persist */
|
||||
uint32 tcps_keeptimeo; /* keepalive timeouts */
|
||||
uint32 tcps_keepprobe; /* keepalive probes sent */
|
||||
uint32 tcps_keepdrops; /* connections dropped in keepalive */
|
||||
|
||||
uint32 tcps_sndtotal; /* total packets sent */
|
||||
uint32 tcps_sndpack; /* data packets sent */
|
||||
uint64 tcps_sndbyte; /* data bytes sent */
|
||||
uint32 tcps_sndrexmitpack; /* data packets retransmitted */
|
||||
uint64 tcps_sndrexmitbyte; /* data bytes retransmitted */
|
||||
uint64 tcps_sndrexmitfast; /* Fast retransmits */
|
||||
uint32 tcps_sndacks; /* ack-only packets sent */
|
||||
uint32 tcps_sndprobe; /* window probes sent */
|
||||
uint32 tcps_sndurg; /* packets sent with URG only */
|
||||
uint32 tcps_sndwinup; /* window update-only packets sent */
|
||||
uint32 tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */
|
||||
|
||||
uint32 tcps_rcvtotal; /* total packets received */
|
||||
uint32 tcps_rcvpack; /* packets received in sequence */
|
||||
uint64 tcps_rcvbyte; /* bytes received in sequence */
|
||||
uint32 tcps_rcvbadsum; /* packets received with ccksum errs */
|
||||
uint32 tcps_rcvbadoff; /* packets received with bad offset */
|
||||
uint32 tcps_rcvmemdrop; /* packets dropped for lack of memory */
|
||||
uint32 tcps_rcvnosec; /* packets dropped for lack of ipsec */
|
||||
uint32 tcps_rcvshort; /* packets received too short */
|
||||
uint32 tcps_rcvduppack; /* duplicate-only packets received */
|
||||
uint64 tcps_rcvdupbyte; /* duplicate-only bytes received */
|
||||
uint32 tcps_rcvpartduppack; /* packets with some duplicate data */
|
||||
uint64 tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */
|
||||
uint32 tcps_rcvoopack; /* out-of-order packets received */
|
||||
uint64 tcps_rcvoobyte; /* out-of-order bytes received */
|
||||
uint32 tcps_rcvpackafterwin; /* packets with data after window */
|
||||
uint64 tcps_rcvbyteafterwin; /* bytes rcvd after window */
|
||||
uint32 tcps_rcvafterclose; /* packets rcvd after "close" */
|
||||
uint32 tcps_rcvwinprobe; /* rcvd window probe packets */
|
||||
uint32 tcps_rcvdupack; /* rcvd duplicate acks */
|
||||
uint32 tcps_rcvacktoomuch; /* rcvd acks for unsent data */
|
||||
uint32 tcps_rcvackpack; /* rcvd ack packets */
|
||||
uint64 tcps_rcvackbyte; /* bytes acked by rcvd acks */
|
||||
uint32 tcps_rcvwinupd; /* rcvd window update packets */
|
||||
uint32 tcps_pawsdrop; /* segments dropped due to PAWS */
|
||||
uint32 tcps_predack; /* times hdr predict ok for acks */
|
||||
uint32 tcps_preddat; /* times hdr predict ok for data pkts */
|
||||
|
||||
uint32 tcps_pcbhashmiss; /* input packets missing pcb hash */
|
||||
uint32 tcps_noport; /* no socket on port */
|
||||
uint32 tcps_badsyn; /* SYN packet with src==dst rcv'ed */
|
||||
|
||||
uint32 tcps_rcvbadsig; /* rcvd bad/missing TCP signatures */
|
||||
uint64 tcps_rcvgoodsig; /* rcvd good TCP signatures */
|
||||
uint32 tcps_inhwcsum; /* input hardware-checksummed packets */
|
||||
uint32 tcps_outhwcsum; /* output hardware-checksummed packets */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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_RSTPPSLIMIT 12 /* RST pps limit */
|
||||
#define TCPCTL_MAXID 13
|
||||
|
||||
//#ifdef _NETWORK_STACK
|
||||
|
||||
extern struct inpcb tcb;
|
||||
extern struct tcpstat tcpstat;
|
||||
extern int tcp_mssdflt;
|
||||
extern int tcp_do_rfc1323;
|
||||
extern unsigned long tcp_now;
|
||||
|
||||
|
||||
void tcp_input(struct mbuf *, int);
|
||||
int tcp_output(struct tcpcb*);
|
||||
int tcp_mss(struct tcpcb *, uint);
|
||||
void tcp_mss_update(struct tcpcb *);
|
||||
void tcp_quench(struct inpcb *, int);
|
||||
int tcp_userreq(struct socket *, int, struct mbuf *, struct mbuf *,
|
||||
struct mbuf *);
|
||||
struct tcpcb * tcp_timers(struct tcpcb *, int);
|
||||
struct tcpcb *tcp_close(struct tcpcb *);
|
||||
void tcp_setpersist(struct tcpcb *);
|
||||
struct tcpcb *tcp_drop(struct tcpcb *, int);
|
||||
void tcp_respond(struct tcpcb *, struct tcpiphdr *, struct mbuf *,
|
||||
tcp_seq, tcp_seq, int);
|
||||
void tcp_xmit_timer(struct tcpcb *, int16);
|
||||
void tcp_dooptions(struct tcpcb *, u_char *, int, struct tcpiphdr *,
|
||||
int *, uint32 *, uint32 *);
|
||||
struct tcpiphdr *tcp_template(struct tcpcb *);
|
||||
void tcp_pulloutofband(struct socket *, struct tcpiphdr *, struct mbuf *);
|
||||
|
||||
void tcp_canceltimers(struct tcpcb *);
|
||||
void tcp_trace(int16, int16, struct tcpcb *, void *, int, int);
|
||||
|
||||
void tcp_slowtimer(void *data);
|
||||
void tcp_fasttimer(void *data);
|
||||
|
||||
|
||||
|
||||
//#endif
|
||||
|
||||
#endif /* NETINET_TCP_VAR_H */
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NETINET_TCPIP_H
|
||||
#define NETINET_TCPIP_H
|
||||
|
||||
/* The TCP + IPv4 header (NB no options) */
|
||||
struct tcpiphdr {
|
||||
struct ipovly ti_i;
|
||||
struct tcphdr ti_t;
|
||||
};
|
||||
|
||||
#define ti_next ti_i.ih_next
|
||||
#define ti_prev ti_i.ih_prev
|
||||
#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
|
||||
|
||||
#define REASS_MBUF(ti) (*(struct mbuf **)&((ti)->ti_t))
|
||||
|
||||
#endif /* NETINET_TCPIP_H */
|
@ -1,51 +0,0 @@
|
||||
/* udp_var.h */
|
||||
|
||||
#ifndef UDP_VAR_H
|
||||
#define UDP_VAR_H
|
||||
|
||||
#include "netinet/ip_var.h"
|
||||
|
||||
struct udpiphdr {
|
||||
struct ipovly ui_i;
|
||||
struct udphdr ui_u;
|
||||
};
|
||||
#define ui_next ui_i.ih_next
|
||||
#define ui_prev ui_i.ih_prev
|
||||
#define ui_x1 ui_i.ih_x1 /* NB _x1 (one) */
|
||||
#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: */
|
||||
uint32 udps_ipackets; /* total input packets */
|
||||
uint32 udps_hdrops; /* packet shorter than header */
|
||||
uint32 udps_badsum; /* checksum error */
|
||||
uint32 udps_nosum; /* no checksum */
|
||||
uint32 udps_badlen; /* data length larger than packet */
|
||||
uint32 udps_noport; /* no socket on port */
|
||||
uint32 udps_noportbcast; /* of above, arrived as broadcast */
|
||||
uint32 udps_nosec; /* dropped for lack of ipsec */
|
||||
uint32 udps_fullsock; /* not delivered, input socket full */
|
||||
uint32 udps_pcbhashmiss; /* input packets missing pcb hash */
|
||||
uint32 udps_inhwcsum; /* input hardware-csummed packets */
|
||||
/* output statistics: */
|
||||
uint32 udps_opackets; /* total output packets */
|
||||
uint32 udps_outhwcsum; /* output hardware-csummed 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
|
||||
|
||||
#endif
|
30
headers/posix/netinet6/in6.h
Normal file
30
headers/posix/netinet6/in6.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NETINET6_IN6_H_
|
||||
#define _NETINET6_IN6_H_
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
struct in6_addr {
|
||||
uint8_t s6_addr[16];
|
||||
};
|
||||
|
||||
/*
|
||||
* IP Version 6 socket address.
|
||||
*/
|
||||
|
||||
struct sockaddr_in6 {
|
||||
uint8_t sin6_len;
|
||||
sa_family_t sin6_family;
|
||||
in_port_t sin6_port
|
||||
uint32_t sin6_flowinfo;
|
||||
struct in6_addr sin6_addr;
|
||||
uint32_t sin6_scope_id;
|
||||
};
|
||||
|
||||
#endif /* _NETINET6_IN6_H_ */
|
@ -57,7 +57,7 @@
|
||||
#define _RESOLV_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bitypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
|
@ -1,3 +0,0 @@
|
||||
#include <OS.h>
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
@ -1,6 +0,0 @@
|
||||
#ifndef _SYS_FILE_H
|
||||
#define _SYS_FILE_H
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* @file sys/filio.h
|
||||
* @brief ioctl() definitions for file descriptor operations
|
||||
*/
|
||||
|
||||
#ifndef _SYS_FILIO_H
|
||||
#define _SYS_FILIO_H
|
||||
/**
|
||||
* @defgroup IOCTL_filio sys/filio.h
|
||||
* @brief ioctl() definitions for file descriptor operations
|
||||
* @ingroup OpenBeOS_POSIX
|
||||
* @ingroup IOCTL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/** @def FIOCLEX set close on exec
|
||||
* @ref FD_CLOEXEC */
|
||||
#define FIOCLEX _IO('f', 1)
|
||||
/** @def FIONCLEX remove close on exec flag
|
||||
* @ref FD_CLOEXEC*/
|
||||
#define FIONCLEX _IO('f', 2)
|
||||
/** @def FIBMAP get logical block
|
||||
* @note this is not yet implemented on OpenBeOS */
|
||||
#define FIBMAP _IOWR('f', 122, void *)
|
||||
/** @def FIOASYNC set/clear async I/O */
|
||||
#define FIOASYNC _IOW('f', 123, int)
|
||||
/** @def FIOGETOWN get owner */
|
||||
#define FIOGETOWN _IOR('f', 123, int)
|
||||
/** @def FIOSETOWN set owner */
|
||||
#define FIOSETOWN _IOW('f', 123, int)
|
||||
/** @def FIONBIO set/clear non-blocking I/O */
|
||||
#define FIONBIO _IOW('f', 126, int)
|
||||
/** @def FIONREAD get number of bytes available to read */
|
||||
#define FIONREAD _IOW('f', 127, int)
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _SYS_FILIO_H */
|
@ -1,80 +0,0 @@
|
||||
/**
|
||||
* @file sys/ioccom.h
|
||||
* @brief Definitions & maros common to ioctl
|
||||
*/
|
||||
|
||||
#ifndef _SYS_IOCCOM_H
|
||||
#define _SYS_IOCCOM_H
|
||||
|
||||
/**
|
||||
* @defgroup IOCTL_common sys/ioccom.h
|
||||
* @brief Definitions & maros common to ioctl()
|
||||
* @ingroup OpenBeOS_POSIX
|
||||
* @ingroup IOCTL
|
||||
* Ioctl values passed as the command (2nd) variable have the
|
||||
* command encoded in the lower word and the size of any parameters
|
||||
* in the upper word (in or out).
|
||||
* The high 3 bits are used to encode whether it's in or out.
|
||||
* Due to this you can't just give an ioctl value, you need to encode
|
||||
* it using macros described in
|
||||
* @ref IOCTL_macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IOCTL_parm ioctl() parameter definitions
|
||||
* @ingroup IOCTL_common
|
||||
* @{
|
||||
*/
|
||||
/** @def IOC_VOID */
|
||||
#define IOC_VOID (ulong)0x20000000
|
||||
/** @def IOC_OUT ioctl expects data (output) */
|
||||
#define IOC_OUT (ulong)0x40000000
|
||||
/** @def IOC_IN ioctl passes a value in */
|
||||
#define IOC_IN (ulong)0x80000000
|
||||
/** @def IOC_INOUT ioctl passes data in and out */
|
||||
#define IOC_INOUT (IOC_IN|IOC_OUT)
|
||||
/** @def IOC_DIRMASK */
|
||||
#define IOC_DIRMASK (ulong)0xe0000000
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup IOCTL_macros IOCTL macros
|
||||
* These should be used to define the values passed in as cmd to
|
||||
* ioctl()
|
||||
* @ingroup IOCTL_common
|
||||
* @{
|
||||
*/
|
||||
/** @def IOCPARM_MASK mask used to for following macros */
|
||||
#define IOCPARM_MASK 0x1fff
|
||||
/** @def IOCPARM_LEN(x) length of the data passed as param */
|
||||
#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
|
||||
/** @def IOCBASECMD(x) the base command encoded in the ioctl value */
|
||||
#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
|
||||
/** @def IOCGROUP(x) which group of ioctl() commands does this belong to? */
|
||||
#define IOCGROUP(x) (((x) >> 8) & 0xff)
|
||||
/** @def IOCPARM_MAX Maximum size of parameter that can be passed (20 bytes) */
|
||||
#define IOCPARM_MAX 20
|
||||
|
||||
/**
|
||||
* @defgroup IOCTL_createmacros macro's to create ioctl() values
|
||||
* @brief these macro's should be used to create new ioctl() values
|
||||
* @ingroup IOCTL_common
|
||||
* @{
|
||||
*/
|
||||
/** @def _IOC(inout, group, num , len) create a new ioctl */
|
||||
#define _IOC(inout, group, num, len) \
|
||||
(inout | ((len & IOCPARM_MASK)<<16) | ((group) << 8) | (num))
|
||||
/** @def _IO(g,n) create a new void ioctl for group g, number n */
|
||||
#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
|
||||
/** @def _IOR(g,n,t) create a ioctl() that reads a value of type t*/
|
||||
#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
|
||||
/** @def _IOW(g,n,t) ioctl() that writes value of type t, group g, number n */
|
||||
#define _IOW(g,n,t) _IOC(IOC_IN , (g), (n), sizeof(t))
|
||||
/** @def _IOWR(g,n,t) ioctl() that reads/writes value of type t
|
||||
* @note this isn't _IORW as this causes name conflicts on some systems */
|
||||
#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _SYS_IOCCOM_H */
|
@ -1,39 +1,12 @@
|
||||
/**
|
||||
* @file sys/ioctl.h
|
||||
* @brief I/O control functions
|
||||
/*
|
||||
* Copyright 2006, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_IOCTL_H
|
||||
#define _SYS_IOCTL_H
|
||||
|
||||
/**
|
||||
* @defgroup IOCTL sys/ioctl.h
|
||||
* @brief I/O control functions
|
||||
* @ingroup OpenBeOS_POSIX
|
||||
* @{
|
||||
*/
|
||||
/* These only work on sockets for now */
|
||||
#define FIONBIO 0xbe000000
|
||||
#define FIONREAD 0xbe000001
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
/** @fn int ioctl(int fd, ulong cmd, ...)
|
||||
* Manipulates the characteristics of the affected descriptor. May be used
|
||||
* on all forms of descriptor, including sockets and pipes. cmd should be one
|
||||
* of the values given in
|
||||
* @ref IOCTL_cmds
|
||||
*/
|
||||
int ioctl(int, ulong, ...);
|
||||
#endif /* !_KERNEL_MODE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif /* _SYS_IOCTL_H */
|
||||
#endif /* _SYS_IOCTL_H */
|
||||
|
@ -1,8 +1,9 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYS_SELECT_H
|
||||
#define _SYS_SELECT_H
|
||||
/*
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/time.h>
|
||||
|
@ -1,68 +1,47 @@
|
||||
/* sys/socket.h */
|
||||
|
||||
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYS_SOCKET_H
|
||||
#define _SYS_SOCKET_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef uint32_t socklen_t;
|
||||
|
||||
/* These are the address/protocol families we'll be using... */
|
||||
/* NB these should be added to as required... */
|
||||
|
||||
/* If we want to have Binary compatability we may need to alter these
|
||||
* to agree with the Be versions...
|
||||
*/
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_INET 1
|
||||
#define AF_LOCAL 2
|
||||
#define AF_UNIX AF_LOCAL /* for compatability */
|
||||
#define AF_ROUTE 3
|
||||
#define AF_LINK 4
|
||||
#define AF_INET6 5
|
||||
#define AF_IPX 7
|
||||
#define AF_IMPLINK 20
|
||||
|
||||
#define AF_MAX 24
|
||||
/* Address families */
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_INET 1
|
||||
#define AF_APPLETALK 2
|
||||
#define AF_ROUTE 3
|
||||
#define AF_LINK 4
|
||||
#define AF_INET6 5
|
||||
#define AF_DLI 6
|
||||
#define AF_IPX 7
|
||||
#define AF_NOTIFY 8
|
||||
#define AF_LOCAL 9
|
||||
#define AF_UNIX AF_LOCAL
|
||||
#define AF_MAX 10
|
||||
|
||||
/* Protocol families, deprecated */
|
||||
#define PF_UNSPEC AF_UNSPEC
|
||||
#define PF_INET AF_INET
|
||||
#define PF_ROUTE AF_ROUTE
|
||||
#define PF_LINK AF_LINK
|
||||
#define PF_INET6 AF_INET6
|
||||
#define PF_IPX AF_IPX
|
||||
#define PF_IMPLINK AF_IMPLINK
|
||||
#define PF_INET6 AF_INET6
|
||||
|
||||
/* Types of socket we can create (eventually) */
|
||||
#ifndef BUILDING_R5_LIBNET
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_RAW 3
|
||||
#define SOCK_MISC 255
|
||||
#else /* BUILDING_R5_LIBNET */
|
||||
/* XXX: HACK: we use socket emulation for libnet.so */
|
||||
#define SOCK_DGRAM 10
|
||||
#define SOCK_STREAM 11
|
||||
#define SOCK_RAW 12
|
||||
#define SOCK_MISC 255
|
||||
#define SOCK_NATIVE_STREAM 1
|
||||
#define SOCK_NATIVE_DGRAM 2
|
||||
#define SOCK_NATIVE_RAW 3
|
||||
#define SOCK_NATIVE_MISC 255
|
||||
#endif /* BUILDING_R5_LIBNET */
|
||||
/* Socket types */
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_RAW 3
|
||||
#define SOCK_MISC 255
|
||||
|
||||
/*
|
||||
* Option flags per-socket.
|
||||
*/
|
||||
#define SOL_SOCKET 0xffffffff
|
||||
/* Socket options for SOL_SOCKET level */
|
||||
#define SOL_SOCKET -1
|
||||
|
||||
#define SO_ACCEPTCONN 0x00000001 /* socket has had listen() */
|
||||
#define SO_BROADCAST 0x00000002 /* permit sending of broadcast msgs */
|
||||
@ -75,9 +54,6 @@ typedef uint32_t socklen_t;
|
||||
#define SO_USELOOPBACK 0x00000100 /* bypass hardware when possible */
|
||||
#define SO_LINGER 0x00000200 /* linger on close if data present */
|
||||
|
||||
/*
|
||||
* Additional options, not kept in so_options.
|
||||
*/
|
||||
#define SO_SNDBUF 0x40000001 /* send buffer size */
|
||||
#define SO_SNDLOWAT 0x40000002 /* send low-water mark */
|
||||
#define SO_SNDTIMEO 0x40000003 /* send timeout */
|
||||
@ -86,206 +62,94 @@ typedef uint32_t socklen_t;
|
||||
#define SO_RCVTIMEO 0x40000006 /* receive timeout */
|
||||
#define SO_ERROR 0x40000007 /* get error status and clear */
|
||||
#define SO_TYPE 0x40000008 /* get socket type */
|
||||
|
||||
/* not handled by OpenBeOS */
|
||||
#define SO_NONBLOCK 0x40000009
|
||||
#define SO_BINDTODEVICE 0x4000000a
|
||||
|
||||
/* only defined in OpenBeOS */
|
||||
#define SO_NETPROC 0x00001020 /* multiplex; network processing */
|
||||
|
||||
/*
|
||||
* These are the valid values for the "how" field used by shutdown(2).
|
||||
*/
|
||||
/* Shutdown options */
|
||||
#define SHUT_RD 0
|
||||
#define SHUT_WR 1
|
||||
#define SHUT_RDWR 2
|
||||
/* for BONE compatibility */
|
||||
#define SHUTDOWN_RECV SHUT_RD
|
||||
#define SHUTDOWN_SEND SHUT_WR
|
||||
#define SHUTDOWN_BOTH SHUT_RDWR
|
||||
|
||||
#define SOMAXCONN 32 /* Max listen queue for a socket */
|
||||
|
||||
struct linger {
|
||||
int l_onoff;
|
||||
int l_linger;
|
||||
int l_onoff;
|
||||
int l_linger;
|
||||
};
|
||||
|
||||
struct sockaddr {
|
||||
uint8_t sa_len;
|
||||
uint8_t sa_family;
|
||||
uint8_t sa_data[30];
|
||||
uint8_t sa_len;
|
||||
uint8_t sa_family;
|
||||
uint8_t sa_data[30];
|
||||
};
|
||||
|
||||
/* this can hold ANY sockaddr we care to throw at it! */
|
||||
struct sockaddr_storage {
|
||||
uint8_t ss_len; /* total length */
|
||||
uint8_t ss_family; /* address family */
|
||||
uint8_t __ss_pad1[6]; /* align to quad */
|
||||
uint64_t __ss_pad2; /* force alignment for stupid compilers */
|
||||
uint8_t __ss_pad3[240]; /* pad to a total of 256 bytes */
|
||||
uint8_t ss_len; /* total length */
|
||||
uint8_t ss_family; /* address family */
|
||||
uint8_t __ss_pad1[6]; /* align to quad */
|
||||
uint64_t __ss_pad2; /* force alignment for stupid compilers */
|
||||
uint8_t __ss_pad3[112]; /* pad to a total of 128 bytes */
|
||||
};
|
||||
|
||||
struct sockproto {
|
||||
uint16_t sp_family;
|
||||
uint16_t sp_protocol;
|
||||
};
|
||||
|
||||
#define CTL_NET 4
|
||||
|
||||
#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 }, \
|
||||
}
|
||||
|
||||
/* Max listen queue for a socket */
|
||||
#define SOMAXCONN 5 /* defined as 128 in OpenBSD */
|
||||
|
||||
struct msghdr {
|
||||
char * msg_name; /* address we're using (optional) */
|
||||
uint msg_namelen; /* length of address */
|
||||
struct iovec *msg_iov; /* scatter/gather array we'll use */
|
||||
uint msg_iovlen; /* # elements in msg_iov */
|
||||
char * msg_control; /* extra data */
|
||||
uint msg_controllen; /* length of extra data */
|
||||
int msg_flags; /* flags */
|
||||
char *msg_name; /* address we're using (optional) */
|
||||
socklen_t msg_namelen; /* length of address */
|
||||
struct iovec *msg_iov; /* scatter/gather array we'll use */
|
||||
int msg_iovlen; /* # elements in msg_iov */
|
||||
char *msg_control; /* extra data */
|
||||
socklen_t msg_controllen; /* length of extra data */
|
||||
int msg_flags; /* flags */
|
||||
};
|
||||
|
||||
/* Defines used in msghdr structure. */
|
||||
#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 */
|
||||
/* not defind in OpenBeOS */
|
||||
#define MSG_EOF 0x400 /* data completes connection */
|
||||
|
||||
/* Flags for the msghdr.msg_flags field */
|
||||
#define MSG_OOB 0x0001 /* process out-of-band data */
|
||||
#define MSG_PEEK 0x0002 /* peek at incoming message */
|
||||
#define MSG_DONTROUTE 0x0004 /* send without using routing tables */
|
||||
#define MSG_EOR 0x0008 /* data completes record */
|
||||
#define MSG_TRUNC 0x0010 /* data discarded before delivery */
|
||||
#define MSG_CTRUNC 0x0020 /* control data lost before delivery */
|
||||
#define MSG_WAITALL 0x0040 /* wait for full request or error */
|
||||
#define MSG_DONTWAIT 0x0080 /* this message should be nonblocking */
|
||||
#define MSG_BCAST 0x0100 /* this message rec'd as broadcast */
|
||||
#define MSG_MCAST 0x0200 /* this message rec'd as multicast */
|
||||
#define MSG_EOF 0x0400 /* data completes connection */
|
||||
|
||||
struct cmsghdr {
|
||||
uint cmsg_len;
|
||||
int cmsg_level;
|
||||
int cmsg_type;
|
||||
/* there now follows uchar[] cmsg_data */
|
||||
socklen_t cmsg_len;
|
||||
int cmsg_level;
|
||||
int cmsg_type;
|
||||
/* data follows */
|
||||
};
|
||||
|
||||
|
||||
#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? */
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
|
||||
#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
|
||||
|
||||
#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 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 */
|
||||
|
||||
#define SIOCGIFMTU _IOWR('i', 126, struct ifreq) /* get ifnet MTU */
|
||||
#define SIOCSIFMTU _IOW('i', 127, struct ifreq) /* set ifnet MTU */
|
||||
|
||||
#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
|
||||
#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */
|
||||
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
/* Function declarations */
|
||||
int socket (int, int, int);
|
||||
int socketpair(int domain, int type, int protocol, int socket_vector[2]);
|
||||
int bind(int, const struct sockaddr *, socklen_t);
|
||||
int connect(int, const struct sockaddr *, socklen_t);
|
||||
int listen(int, int);
|
||||
int accept(int, struct sockaddr *, socklen_t *);
|
||||
int closesocket(int);
|
||||
int shutdown(int sock, int how);
|
||||
|
||||
ssize_t send(int, const void *, size_t, int);
|
||||
ssize_t recv(int, void *, size_t, int);
|
||||
ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
|
||||
ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
|
||||
|
||||
int setsockopt(int, int, int, const void *, socklen_t);
|
||||
int getsockopt(int, int, int, void *, socklen_t *);
|
||||
int getpeername(int, struct sockaddr *, socklen_t *);
|
||||
int getsockname(int, struct sockaddr *, socklen_t *);
|
||||
#endif /* _KERNEL_MODE */
|
||||
int accept(int socket, struct sockaddr *address, socklen_t *_addressLength);
|
||||
int bind(int socket, const struct sockaddr *address, socklen_t addressLength);
|
||||
int connect(int socket, const struct sockaddr *address, socklen_t addressLength);
|
||||
int getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength);
|
||||
int getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength);
|
||||
int getsockopt(int socket, int level, int option, void *value, socklen_t *_length);
|
||||
int listen(int socket, int backlog);
|
||||
ssize_t recv(int socket, void *buffer, size_t length, int flags);
|
||||
ssize_t recvfrom(int socket, void *buffer, size_t bufferLength, int flags,
|
||||
struct sockaddr *address, socklen_t *_addressLength);
|
||||
ssize_t recvmsg(int socket, struct msghdr *message, int flags);
|
||||
ssize_t send(int socket, const void *buffer, size_t length, int flags);
|
||||
ssize_t sendmsg(int socket, const struct msghdr *message, int flags);
|
||||
ssize_t sendto(int socket, const void *message, size_t length, int flags,
|
||||
const struct sockaddr *address, socklen_t addressLength);
|
||||
int setsockopt(int socket, int level, int option, const void *value, socklen_t length);
|
||||
int shutdown(int socket, int how);
|
||||
int socket(int domain, int type, int protocol);
|
||||
int sockatmark(int socket);
|
||||
int socketpair(int domain, int type, int protocol, int socketVector[2]);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _SYS_SOCKET_H */
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_SOCKET_H */
|
||||
|
56
headers/posix/sys/sockio.h
Normal file
56
headers/posix/sys/sockio.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYS_SOCKIO_H
|
||||
#define _SYS_SOCKIO_H
|
||||
|
||||
|
||||
enum {
|
||||
SIOCADDRT = 8900, /* add route */
|
||||
SIOCDELRT, /* delete route */
|
||||
SIOCSIFADDR, /* set interface address */
|
||||
SIOCGIFADDR, /* get interface address */
|
||||
SIOCSIFDSTADDR, /* set point-to-point address */
|
||||
SIOCGIFDSTADDR, /* get point-to-point address */
|
||||
SIOCSIFFLAGS, /* set interface flags */
|
||||
SIOCGIFFLAGS, /* get interface flags */
|
||||
SIOCGIFBRDADDR, /* get broadcast address */
|
||||
SIOCSIFBRDADDR, /* set broadcast address */
|
||||
SIOCGIFCOUNT, /* count interfaces */
|
||||
SIOCGIFCONF, /* get interface list */
|
||||
SIOCGIFINDEX, /* interface name -> index */
|
||||
SIOCGIFNAME, /* interface index -> name */
|
||||
SIOCGIFNETMASK, /* get net address mask */
|
||||
SIOCSIFNETMASK, /* set net address mask */
|
||||
SIOCGIFMETRIC, /* get interface metric */
|
||||
SIOCSIFMETRIC, /* set interface metric */
|
||||
SIOCDIFADDR, /* delete interface address */
|
||||
SIOCAIFADDR, /* configure interface alias */
|
||||
SIOCADDMULTI, /* add multicast address */
|
||||
SIOCDELMULTI, /* delete multicast address */
|
||||
SIOCGIFMTU, /* get interface MTU */
|
||||
SIOCSIFMTU, /* set interface MTU */
|
||||
SIOCSIFMEDIA, /* set net media */
|
||||
SIOCGIFMEDIA, /* get net media */
|
||||
|
||||
SIOCGRTSIZE, /* get route table size */
|
||||
SIOCGRTTABLE, /* get route table */
|
||||
|
||||
SIOCGIFSTATS, /* get interface stats */
|
||||
SIOCGIFPARAM, /* get interface parameter */
|
||||
SIOCGIFTYPE, /* get interface type */
|
||||
|
||||
SIOCSPACKETCAP, /* Start capturing packets on an interface */
|
||||
SIOCCPACKETCAP, /* Stop capturing packets on an interface */
|
||||
|
||||
SIOCSHIWAT, /* set high watermark */
|
||||
SIOCGHIWAT, /* get high watermark */
|
||||
SIOCSLOWAT, /* set low watermark */
|
||||
SIOCGLOWAT, /* get low watermark */
|
||||
SIOCATMARK, /* at out-of-band mark? */
|
||||
SIOCSPGRP, /* set process group */
|
||||
SIOCGPGRP /* get process group */
|
||||
};
|
||||
|
||||
#endif /* _SYS_SOCKIO_H */
|
@ -1,8 +1,9 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYS_UIO_H
|
||||
#define _SYS_UIO_H
|
||||
/*
|
||||
** Distributed under the terms of the Haiku License.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -1,110 +0,0 @@
|
||||
/* core_funcs.h
|
||||
* convenience macros to for calling core functions in the kernel
|
||||
*/
|
||||
|
||||
#ifndef OBOS_CORE_FUNCS_H
|
||||
#define OBOS_CORE_FUNCS_H
|
||||
|
||||
#include "core_module.h"
|
||||
|
||||
# define add_protosw core->add_protosw
|
||||
# define add_domain core->add_domain
|
||||
# define remove_domain core->remove_domain
|
||||
# define add_protocol core->add_protocol
|
||||
# define remove_protocol core->remove_protocol
|
||||
# define start_rx_thread core->start_rx_thread
|
||||
# define start_tx_thread core->start_tx_thread
|
||||
|
||||
# define get_max_hdr core->get_max_hdr
|
||||
# define set_max_linkhdr core->set_max_linkhdr
|
||||
# define get_max_linkhdr core->get_max_linkhdr
|
||||
# define set_max_protohdr core->set_max_protohdr
|
||||
# define get_max_protohdr core->get_max_protohdr
|
||||
|
||||
# define net_add_timer core->net_add_timer
|
||||
# define net_remove_timer core->net_remove_timer
|
||||
|
||||
# define start_ifq core->start_ifq
|
||||
# define stop_ifq core->stop_ifq
|
||||
|
||||
# define pool_init core->pool_init
|
||||
# define pool_get core->pool_get
|
||||
# define pool_put core->pool_put
|
||||
|
||||
# define m_get core->m_get
|
||||
# define m_gethdr core->m_gethdr
|
||||
# define m_free core->m_free
|
||||
# define m_freem core->m_freem
|
||||
# define m_cat core->m_cat
|
||||
# define m_adj core->m_adj
|
||||
# define m_prepend core->m_prepend
|
||||
# define m_pullup core->m_pullup
|
||||
# define m_copydata core->m_copydata
|
||||
# define m_copyback core->m_copyback
|
||||
# define m_copym core->m_copym
|
||||
# define m_reserve core->m_reserve
|
||||
# define m_devget core->m_devget
|
||||
|
||||
# define if_attach core->if_attach
|
||||
# define if_detach core->if_detach
|
||||
|
||||
# define in_pcballoc core->in_pcballoc
|
||||
# define in_pcbconnect core->in_pcbconnect
|
||||
# define in_pcbdisconnect core->in_pcbdisconnect
|
||||
# define in_pcbbind core->in_pcbbind
|
||||
# define in_pcblookup core->in_pcblookup
|
||||
# define in_pcbdetach core->in_pcbdetach
|
||||
# define in_pcbrtentry core->in_pcbrtentry
|
||||
# define in_canforward core->in_canforward
|
||||
# define in_localaddr core->in_localaddr
|
||||
# define in_losing core->in_losing
|
||||
# define in_broadcast core->in_broadcast
|
||||
# define in_control core->in_control
|
||||
# define in_setsockaddr core->in_setsockaddr
|
||||
# define in_setpeeraddr core->in_setpeeraddr
|
||||
# define in_pcbnotify core->in_pcbnotify
|
||||
# define inetctlerrmap core->inetctlerrmap
|
||||
# define in_cksum core->in_cksum
|
||||
|
||||
# define ifa_ifwithdstaddr core->ifa_ifwithdstaddr
|
||||
# define ifa_ifwithaddr core->ifa_ifwithaddr
|
||||
# define ifa_ifwithnet core->ifa_ifwithnet
|
||||
# define ifa_ifwithroute core->ifa_ifwithroute
|
||||
# define ifaof_ifpforaddr core->ifaof_ifpforaddr
|
||||
# define ifafree core->ifafree
|
||||
|
||||
# define sockbuf_append core->sockbuf_append
|
||||
# define sockbuf_appendaddr core->sockbuf_appendaddr
|
||||
# define sockbuf_drop core->sockbuf_drop
|
||||
# define sockbuf_flush core->sockbuf_flush
|
||||
# define sockbuf_reserve core->sockbuf_reserve
|
||||
|
||||
# define soreserve core->soreserve
|
||||
# define sowakeup core->sowakeup
|
||||
# define sonewconn core->sonewconn
|
||||
|
||||
# define socket_set_connected core->socket_set_connected
|
||||
# define socket_set_connecting core->socket_set_connecting
|
||||
# define socket_set_disconnected core->socket_set_disconnected
|
||||
# define socket_set_disconnecting core->socket_set_disconnecting
|
||||
# define socket_set_hasoutofband core->socket_set_hasoutofband
|
||||
# define socket_set_cantsendmore core->socket_set_cantsendmore
|
||||
# define socket_set_cantrcvmore core->socket_set_cantrcvmore
|
||||
|
||||
# define rtfree core->rtfree
|
||||
# define rtalloc core->rtalloc
|
||||
# define rtalloc1 core->rtalloc1
|
||||
# define rtrequest core->rtrequest
|
||||
|
||||
# define rt_setgate core->rt_setgate
|
||||
# define get_rt_tables core->get_rt_tables
|
||||
|
||||
# define rn_addmask core->rn_addmask
|
||||
# define rn_head_search core->rn_head_search
|
||||
|
||||
# define get_interfaces core->get_interfaces
|
||||
# define get_primary_addr core->get_primary_addr
|
||||
|
||||
# define net_sysctl core->net_sysctl
|
||||
|
||||
#endif /* OBOS_CORE_FUNCS_H */
|
@ -1,167 +0,0 @@
|
||||
/* core_module.h
|
||||
* definitions needed by the core networking module
|
||||
*/
|
||||
|
||||
#ifndef OBOS_CORE_MODULE_H
|
||||
#define OBOS_CORE_MODULE_H
|
||||
|
||||
#include <mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <net/if.h>
|
||||
#include <net_timer.h>
|
||||
#include <net_module.h>
|
||||
|
||||
struct core_module_info {
|
||||
module_info module;
|
||||
|
||||
int (*start)(void);
|
||||
int (*stop)(void);
|
||||
status_t (*control_net_module)(const char *name, uint32 op, void *data,
|
||||
size_t length);
|
||||
void (*add_domain)(struct domain *, int);
|
||||
void (*remove_domain)(int);
|
||||
void (*add_protocol)(struct protosw *, int);
|
||||
void (*remove_protocol)(struct protosw *pr);
|
||||
void (*add_protosw)(struct protosw *prt[], int layer);
|
||||
void (*start_rx_thread)(struct ifnet *dev);
|
||||
void (*start_tx_thread)(struct ifnet *dev);
|
||||
|
||||
// functions for the 'max_xxx' values
|
||||
int (*get_max_hdr)(void);
|
||||
void (*set_max_linkhdr)(int maxLinkHdr);
|
||||
int (*get_max_linkhdr)(void);
|
||||
void (*set_max_protohdr)(int maxProtoHdr);
|
||||
int (*get_max_protohdr)(void);
|
||||
|
||||
/* timer functions */
|
||||
net_timer_id (*net_add_timer)(net_timer_hook ,void *,
|
||||
bigtime_t);
|
||||
status_t (*net_remove_timer)(net_timer_id);
|
||||
|
||||
/* ifq functions */
|
||||
struct ifq *(*start_ifq)(void);
|
||||
void (*stop_ifq)(struct ifq *);
|
||||
|
||||
/* pool functions */
|
||||
status_t (*pool_init)(pool_ctl **p, size_t sz);
|
||||
char *(*pool_get)(pool_ctl *p);
|
||||
void (*pool_put)(pool_ctl *p, void *ptr);
|
||||
void (*pool_destroy)(pool_ctl *p);
|
||||
|
||||
/* socket functions - called "internally" */
|
||||
struct socket *(*sonewconn)(struct socket *, int);
|
||||
int (*soreserve)(struct socket *, uint32, uint32);
|
||||
int (*sockbuf_reserve)(struct sockbuf *, uint32);
|
||||
void (*sockbuf_append)(struct sockbuf *, struct mbuf *);
|
||||
int (*sockbuf_appendaddr)(struct sockbuf *, struct sockaddr *,
|
||||
struct mbuf *, struct mbuf *);
|
||||
void (*sockbuf_drop)(struct sockbuf *, int);
|
||||
void (*sockbuf_flush)(struct sockbuf *sb);
|
||||
void (*sowakeup)(struct socket *, struct sockbuf *);
|
||||
void (*socket_set_connected)(struct socket *so);
|
||||
void (*socket_set_connecting)(struct socket *so);
|
||||
void (*socket_set_disconnected)(struct socket *so);
|
||||
void (*socket_set_disconnecting)(struct socket *so);
|
||||
void (*socket_set_hasoutofband)(struct socket *so);
|
||||
void (*socket_set_cantrcvmore)(struct socket *so);
|
||||
void (*socket_set_cantsendmore)(struct socket *so);
|
||||
|
||||
/* pcb options */
|
||||
int (*in_pcballoc)(struct socket *, struct inpcb *);
|
||||
void (*in_pcbdetach)(struct inpcb *);
|
||||
int (*in_pcbbind)(struct inpcb *, struct mbuf *);
|
||||
int (*in_pcbconnect)(struct inpcb *, struct mbuf *);
|
||||
int (*in_pcbdisconnect)(struct inpcb *);
|
||||
struct inpcb * (*in_pcblookup)(struct inpcb *,
|
||||
struct in_addr, uint16, struct in_addr, uint16, int);
|
||||
int (*in_control)(struct socket *, int, caddr_t,
|
||||
struct ifnet *);
|
||||
void (*in_losing)(struct inpcb *);
|
||||
int (*in_canforward)(struct in_addr);
|
||||
int (*in_localaddr)(struct in_addr);
|
||||
struct rtentry *(*in_pcbrtentry)(struct inpcb *);
|
||||
void (*in_setsockaddr)(struct inpcb *, struct mbuf *);
|
||||
void (*in_setpeeraddr)(struct inpcb *, struct mbuf *);
|
||||
void (*in_pcbnotify)(struct inpcb *, struct sockaddr *,
|
||||
uint16, struct in_addr, uint16,
|
||||
int, void (*)(struct inpcb *, int));
|
||||
int (*inetctlerrmap)(int);
|
||||
uint16 (*in_cksum)(struct mbuf *m, int len, int off);
|
||||
|
||||
|
||||
/* mbuf routines... */
|
||||
struct mbuf * (*m_gethdr)(int);
|
||||
struct mbuf * (*m_get)(int);
|
||||
void (*m_cat)(struct mbuf *, struct mbuf *);
|
||||
void (*m_adj)(struct mbuf*, int);
|
||||
struct mbuf * (*m_prepend)(struct mbuf*, int);
|
||||
struct mbuf *(*m_pullup)(struct mbuf *, int);
|
||||
void (*m_copyback)(struct mbuf *, int, int, caddr_t);
|
||||
void (*m_copydata)(struct mbuf *, int, int, caddr_t);
|
||||
struct mbuf *(*m_copym)(struct mbuf *, int, int);
|
||||
struct mbuf * (*m_free)(struct mbuf *);
|
||||
void (*m_freem)(struct mbuf *);
|
||||
void (*m_reserve)(struct mbuf *, int);
|
||||
struct mbuf *(*m_devget)(char *, int, int, struct ifnet *,
|
||||
void (*copy)(const void *, void *, size_t));
|
||||
|
||||
/* module control routines... */
|
||||
void (*add_device)(struct ifnet *);
|
||||
struct ifnet *(*get_interfaces)(void);
|
||||
int (*in_broadcast)(struct in_addr, struct ifnet *);
|
||||
|
||||
/* routing */
|
||||
void (*rtalloc)(struct route *ro);
|
||||
struct rtentry *(*rtalloc1)(struct sockaddr *, int);
|
||||
void (*rtfree)(struct rtentry *);
|
||||
int (*rtrequest)(int, struct sockaddr *,
|
||||
struct sockaddr *, struct sockaddr *, int,
|
||||
struct rtentry **);
|
||||
struct radix_node *(*rn_addmask)(void *, int, int);
|
||||
struct radix_node *(*rn_head_search)(void *argv_v);
|
||||
struct radix_node_head **(*get_rt_tables)(void);
|
||||
int (*rt_setgate)(struct rtentry *, struct sockaddr *,
|
||||
struct sockaddr *);
|
||||
|
||||
/* ifnet functions */
|
||||
struct ifaddr *(*ifa_ifwithdstaddr)(struct sockaddr *addr);
|
||||
struct ifaddr *(*ifa_ifwithnet)(struct sockaddr *addr);
|
||||
void (*if_attach)(struct ifnet *);
|
||||
void (*if_detach)(struct ifnet *);
|
||||
struct ifaddr *(*ifa_ifwithaddr)(struct sockaddr *);
|
||||
struct ifaddr *(*ifa_ifwithroute)(int, struct sockaddr *,
|
||||
struct sockaddr *);
|
||||
struct ifaddr *(*ifaof_ifpforaddr)(struct sockaddr *, struct ifnet *);
|
||||
void (*ifafree)(struct ifaddr *);
|
||||
|
||||
struct in_ifaddr *(*get_primary_addr)(void);
|
||||
|
||||
int (*net_sysctl)(int *, uint, void *, size_t *, void *, size_t);
|
||||
|
||||
/* socket functions - used by socket driver */
|
||||
int (*socket_init) (struct socket **nso);
|
||||
int (*socket_create) (struct socket *so, int dom, int type, int proto);
|
||||
int (*socket_close) (struct socket *so);
|
||||
int (*socket_bind) (struct socket *so, caddr_t, int);
|
||||
int (*socket_listen) (struct socket *so, int backlog);
|
||||
int (*socket_connect) (struct socket *so, caddr_t, int);
|
||||
int (*socket_accept) (struct socket *so, struct socket **nso, void *, int *);
|
||||
int (*socket_recv) (struct socket *so, struct msghdr *, caddr_t namelenp, int *retsize);
|
||||
int (*socket_send) (struct socket *so, struct msghdr *, int flags, int *retsize);
|
||||
int (*socket_ioctl) (struct socket *so, int, caddr_t);
|
||||
int (*socket_writev) (struct socket *so, struct iovec *, int flags);
|
||||
int (*socket_readv) (struct socket *so, struct iovec *, int *flags);
|
||||
int (*socket_setsockopt) (struct socket *so, int, int, const void *, size_t);
|
||||
int (*socket_getsockopt) (struct socket *so, int, int, void *, size_t *);
|
||||
int (*socket_getpeername) (struct socket *so, struct sockaddr *, int *);
|
||||
int (*socket_getsockname) (struct socket *so, struct sockaddr *, int *);
|
||||
int (*socket_socketpair) (struct socket *so, struct socket **nso);
|
||||
int (*socket_set_event_callback)(struct socket *so, socket_event_callback, void *, int);
|
||||
int (*socket_shutdown) (struct socket *so, int how);
|
||||
};
|
||||
|
||||
#define NET_CORE_MODULE_NAME NETWORK_MODULES_ROOT "core/v1"
|
||||
|
||||
#endif /* OBOS_CORE_MODULE_H */
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* ether_driver.h
|
||||
*
|
||||
* Ethernet driver: handles NE2000 and 3C503 cards
|
||||
*/
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
#ifndef _ETHER_DRIVER_H
|
||||
#define _ETHER_DRIVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <Drivers.h>
|
||||
|
||||
/*
|
||||
* ioctls: belongs in a public header file
|
||||
* somewhere, so that the net_server and other ethernet drivers can use.
|
||||
*/
|
||||
enum {
|
||||
ETHER_GETADDR = B_DEVICE_OP_CODES_END, /* get ethernet address */
|
||||
ETHER_INIT, /* set irq and port */
|
||||
ETHER_NONBLOCK, /* set/unset nonblocking mode */
|
||||
ETHER_ADDMULTI, /* add multicast addr */
|
||||
ETHER_REMMULTI, /* rem multicast addr */
|
||||
ETHER_SETPROMISC, /* set promiscuous */
|
||||
ETHER_GETFRAMESIZE, /* get frame size */
|
||||
ETHER_ADDTIMESTAMP, /* (try to) add timestamps to packets (BONE ext) */
|
||||
ETHER_HASIOVECS, /* does the driver implement writev ? (BONE ext) (bool *) */
|
||||
ETHER_GETIFTYPE, /* get the IFT_ type of the interface (int *) */
|
||||
ETHER_GETLINKSTATE /* get line speed, quality, duplex mode, etc. */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 48-bit ethernet address, passed back from ETHER_GETADDR
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char ebyte[6];
|
||||
} ether_address_t;
|
||||
|
||||
|
||||
/*
|
||||
* info passed to ETHER_INIT
|
||||
*/
|
||||
|
||||
typedef struct ether_init_params {
|
||||
short port;
|
||||
short irq;
|
||||
unsigned long mem;
|
||||
} ether_init_params_t;
|
||||
|
||||
/*
|
||||
* info returned from ETHER_GETLINKSTATE
|
||||
*/
|
||||
|
||||
typedef struct ether_link_state {
|
||||
float link_speed; /* In Mbits per second */
|
||||
float link_quality; /* Set to zero if not connected */
|
||||
char duplex_mode; /* Set to 1 for full duplex, 0 for half */
|
||||
} ether_link_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ETHER_DRIVER_H */
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
ethernet_module.h
|
||||
*/
|
||||
|
||||
#ifndef ETHERNET_MODULE_H
|
||||
#define ETHERNET_MODULE_H
|
||||
|
||||
#include "net_module.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#define NET_ETHERNET_MODULE_NAME NETWORK_MODULES_ROOT "interfaces/ethernet"
|
||||
|
||||
typedef void (*ethernet_receiver_func)(struct mbuf *buf);
|
||||
|
||||
struct ethernet_module_info {
|
||||
struct kernel_net_module_info info;
|
||||
|
||||
void (*set_pppoe_receiver)(ethernet_receiver_func func);
|
||||
void (*unset_pppoe_receiver)(void);
|
||||
};
|
||||
|
||||
#endif /* ETHERNET_MODULE_H */
|
@ -1,19 +0,0 @@
|
||||
/* icmp_module.h
|
||||
*/
|
||||
|
||||
#ifndef ICMP_MODULE_H
|
||||
#define ICMP_MODULE_H
|
||||
|
||||
#include "net_module.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#define NET_ICMP_MODULE_NAME NETWORK_MODULES_ROOT "protocols/icmp"
|
||||
|
||||
struct icmp_module_info {
|
||||
struct kernel_net_module_info info;
|
||||
|
||||
void (*error)(struct mbuf *, int, int, n_long, struct ifnet *);
|
||||
};
|
||||
|
||||
#endif /* ICMP_MODULE_H */
|
@ -1,32 +0,0 @@
|
||||
/* ipv4_module.h
|
||||
* definitions for ipv4 protocol
|
||||
*/
|
||||
|
||||
#ifndef IPV4_MODULE_H
|
||||
#define IPV4_MODULE_H
|
||||
|
||||
#include "net_module.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#define NET_IPV4_MODULE_NAME NETWORK_MODULES_ROOT "protocols/ipv4"
|
||||
|
||||
struct ipv4_module_info {
|
||||
struct kernel_net_module_info info;
|
||||
|
||||
int (*output)(struct mbuf *,
|
||||
struct mbuf *,
|
||||
struct route *,
|
||||
int, void *);
|
||||
uint16 (*ip_id)(void);
|
||||
int (*ctloutput)(int,
|
||||
struct socket *,
|
||||
int, int,
|
||||
struct mbuf **);
|
||||
struct mbuf *(*ip_srcroute)(void);
|
||||
void (*ip_stripoptions)(struct mbuf *,
|
||||
struct mbuf *);
|
||||
struct mbuf *(*srcroute)(void);
|
||||
};
|
||||
|
||||
#endif /* IPV4_MODULE_H */
|
@ -1,128 +0,0 @@
|
||||
#ifndef LOCK_H
|
||||
#define LOCK_H
|
||||
/* lock.h - benaphore locking, "faster semaphores", read/write locks
|
||||
** sorry for all those macros; I wish C would support C++-style
|
||||
** inline functions.
|
||||
**
|
||||
** Initial version by Axel Dörfler, axeld@pinc-software.de
|
||||
**
|
||||
** This file may be used under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
// for read/write locks
|
||||
#define MAX_READERS 100000
|
||||
|
||||
|
||||
struct benaphore {
|
||||
sem_id sem;
|
||||
int32 count;
|
||||
};
|
||||
|
||||
typedef struct benaphore benaphore;
|
||||
|
||||
// it may make sense to add a status field to the rw_lock to
|
||||
// be able to check if the semaphore could be locked
|
||||
|
||||
struct rw_lock {
|
||||
sem_id sem;
|
||||
int32 count;
|
||||
benaphore writeLock;
|
||||
};
|
||||
|
||||
typedef struct rw_lock rw_lock;
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
#define INIT_BENAPHORE(lock,name) \
|
||||
{ \
|
||||
(lock).count = 1; \
|
||||
(lock).sem = create_sem(0, name); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define INIT_BENAPHORE(lock,name) \
|
||||
{ \
|
||||
(lock).count = 1; \
|
||||
(lock).sem = create_sem(0, name); \
|
||||
set_sem_owner((lock).sem, B_SYSTEM_TEAM); \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define CHECK_BENAPHORE(lock) \
|
||||
((lock).sem)
|
||||
|
||||
#define UNINIT_BENAPHORE(lock) \
|
||||
delete_sem((lock).sem);
|
||||
|
||||
#define ACQUIRE_BENAPHORE(lock) \
|
||||
(atomic_add(&((lock).count), -1) <= 0 ? \
|
||||
acquire_sem_etc((lock).sem, 1, B_CAN_INTERRUPT, 0) \
|
||||
: B_OK)
|
||||
|
||||
#define RELEASE_BENAPHORE(lock) \
|
||||
{ \
|
||||
if (atomic_add(&((lock).count), 1) < 0) \
|
||||
release_sem((lock).sem); \
|
||||
}
|
||||
|
||||
/* read/write lock */
|
||||
#ifndef _KERNEL_MODE
|
||||
#define INIT_RW_LOCK(lock,name) \
|
||||
{ \
|
||||
(lock).sem = create_sem(0, name); \
|
||||
(lock).count = MAX_READERS; \
|
||||
INIT_BENAPHORE((lock).writeLock, "r/w write lock"); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define INIT_RW_LOCK(lock,name) \
|
||||
{ \
|
||||
(lock).sem = create_sem(0, name); \
|
||||
set_sem_owner((lock).sem, B_SYSTEM_TEAM); \
|
||||
(lock).count = MAX_READERS; \
|
||||
INIT_BENAPHORE((lock).writeLock, "r/w write lock"); \
|
||||
}
|
||||
|
||||
#endif
|
||||
#define CHECK_RW_LOCK(lock) \
|
||||
((lock).sem)
|
||||
|
||||
#define UNINIT_RW_LOCK(lock) \
|
||||
delete_sem((lock).sem); \
|
||||
UNINIT_BENAPHORE((lock).writeLock)
|
||||
|
||||
#define ACQUIRE_READ_LOCK(lock) \
|
||||
{ \
|
||||
if (atomic_add(&(lock).count, -1) <= 0) \
|
||||
acquire_sem((lock).sem); \
|
||||
}
|
||||
|
||||
#define RELEASE_READ_LOCK(lock) \
|
||||
{ \
|
||||
if (atomic_add(&(lock).count, 1) < 0) \
|
||||
release_sem((lock).sem); \
|
||||
}
|
||||
|
||||
#define ACQUIRE_WRITE_LOCK(lock) \
|
||||
{ \
|
||||
int32 readers; \
|
||||
ACQUIRE_BENAPHORE((lock).writeLock); \
|
||||
readers = atomic_add(&(lock).count, -MAX_READERS); \
|
||||
if (readers < MAX_READERS) \
|
||||
acquire_sem_etc((lock).sem,readers <= 0 ? 1 : MAX_READERS - readers,0,0); \
|
||||
RELEASE_BENAPHORE((lock).writeLock); \
|
||||
}
|
||||
|
||||
#define RELEASE_WRITE_LOCK(lock) \
|
||||
{ \
|
||||
int32 readers = atomic_add(&(lock).count,MAX_READERS); \
|
||||
if (readers < 0) \
|
||||
release_sem_etc((lock).sem,readers <= -MAX_READERS ? 1 : -readers,B_CAN_INTERRUPT); \
|
||||
}
|
||||
|
||||
#endif /* LOCK_H */
|
@ -1,311 +0,0 @@
|
||||
/* mbuf.h
|
||||
* network buffer definitions
|
||||
*
|
||||
* Based on BSD's mbuf principal.
|
||||
*/
|
||||
|
||||
#include "pools.h"
|
||||
|
||||
#ifndef OBOS_MBUF_H
|
||||
#define OBOS_MBUF_H
|
||||
|
||||
/* MBuf's are all of a single size, MSIZE bytes. If we have more data
|
||||
* than can be fitted we can add a single "MBuf cluster" which is of
|
||||
* fixed size MCLBYTES.
|
||||
* If the data to be written is larger than MCLMINBYTES bytes we won't use
|
||||
* the storage provided within the MBuf, but rather all data will go
|
||||
* directly into an added cluster.
|
||||
*/
|
||||
|
||||
#define MSIZE 256 /* total size of structure */
|
||||
#define MCLSHIFT 11
|
||||
#define MCLBYTES (1 << MCLSHIFT)
|
||||
|
||||
#define MCLMAXBYTES 2048 /* they can't be bigger than 2k */
|
||||
#define MLEN (MSIZE - sizeof(struct m_hdr)) /* data length w/o a pkt_hdr */
|
||||
#define MHLEN (MLEN - sizeof(struct pkt_hdr)) /* data length w/pkt_hdr */
|
||||
#define CLLEN (MCLBYTES - sizeof(struct cl_hdr))
|
||||
|
||||
#define MINCLSIZE (MHLEN + 1)
|
||||
|
||||
/* mbuf header structure
|
||||
* This appears at teh start of every MBuf
|
||||
*/
|
||||
struct m_hdr {
|
||||
struct mbuf *m_next; /* next mbuf in a chain */
|
||||
struct mbuf *m_nxtpkt; /* next chain in a packet/queue */
|
||||
char * m_data; /* pointer to data */
|
||||
uint32 m_len; /* length data in this mbuf NB NOT total length */
|
||||
uint16 m_type; /* what sort of data do we have ? */
|
||||
uint16 m_flags; /* flags as defined below */
|
||||
uint16 m_cksum; /* flags about the checksum on the packet */
|
||||
};
|
||||
|
||||
/* pkt_hdr
|
||||
* This is ONLY found in the first MBuf in a chain and is valid
|
||||
* ONLY if we have the M_PKTHDR flag is set
|
||||
*/
|
||||
/* XXX - we also need to record things like the interface and also maintain
|
||||
* a list of the packets associated with this message here.
|
||||
*/
|
||||
struct pkt_hdr {
|
||||
struct ifnet *rcvif; /* interface we came it on */
|
||||
int len; /* total length */
|
||||
int csum; /* hardware cksum info... */
|
||||
};
|
||||
|
||||
/* m_ext
|
||||
* External storage, i.e. a cluster
|
||||
*/
|
||||
struct m_ext {
|
||||
char *ext_buf; /* start of the buffer */
|
||||
// void *(ext_free)(); /* free routine (if not standard) */
|
||||
uint ext_size; /* how big is the buffer */
|
||||
};
|
||||
|
||||
/* struct mbuf
|
||||
* The actual buffer structure.
|
||||
* This is defined as unions as the size is slightly variable
|
||||
* depending on the options set.
|
||||
*/
|
||||
|
||||
struct mbuf {
|
||||
struct m_hdr m_hdr;
|
||||
union {
|
||||
struct {
|
||||
struct pkt_hdr MH_pkthdr;
|
||||
union {
|
||||
struct m_ext MH_ext;
|
||||
char MH_databuf[MHLEN];
|
||||
} MH_dat;
|
||||
} MH;
|
||||
char m_databuf[MLEN];
|
||||
} um_dat;
|
||||
};
|
||||
|
||||
/* these are simply shortcuts... */
|
||||
#define m_next m_hdr.m_next
|
||||
#define m_len m_hdr.m_len
|
||||
#define m_data m_hdr.m_data
|
||||
#define m_type m_hdr.m_type
|
||||
#define m_flags m_hdr.m_flags
|
||||
#define m_cksum m_hdr.m_cksum
|
||||
#define m_nextpkt m_hdr.m_nxtpkt
|
||||
#define m_ext um_dat.MH.MH_dat.MH_ext
|
||||
#define m_pktdat um_dat.MH.MH_dat.MH_databuf
|
||||
#define m_pkthdr um_dat.MH.MH_pkthdr
|
||||
#define m_dat um_dat.m_databuf
|
||||
|
||||
/* define a little macro that gives us the data pointer for an mbuf */
|
||||
#define mtod(m, t) ((t)((m)->m_data))
|
||||
#define dtom(x) ((struct mbuf *)((int)(x) & ~(MSIZE-1)))
|
||||
|
||||
/* mbuf flags */
|
||||
enum {
|
||||
M_EXT = 0x0001, /* has extenal storage attached */
|
||||
M_PKTHDR = 0x0002, /* contains the packet header */
|
||||
M_EOR = 0x0004, /* end of record (not used for tcp/udp) */
|
||||
M_CLUSTER = 0x0008, /* external storage is a cluster */
|
||||
/*
|
||||
M_PROTO = 0x0010, * protocol specific *
|
||||
*/
|
||||
M_BCAST = 0x0100, /* rx/tx as a link-level broadcast */
|
||||
M_MCAST = 0x0200, /* rx/tx as a link-level multicast */
|
||||
M_CONF = 0x0400, /* packet was encrypted?? */
|
||||
M_AUTH = 0x0800, /* packet was authenticated */
|
||||
M_COMP = 0x1000, /* packet was compressed */
|
||||
M_ANYCAST6 = 0x4000 /* it was an IPv6 anycast packet */
|
||||
};
|
||||
/* the M_COPYFLAGS lists the flags that can be copied when we copy
|
||||
* an mbuf with the M_PKTHDR flag set */
|
||||
#define M_COPYFLAGS (M_PKTHDR | M_EOR | M_BCAST | M_MCAST)
|
||||
|
||||
/* checksum flags */
|
||||
enum {
|
||||
M_IPV4_CSUM_OUT = 0x0001, /* ipv4 checksum required */
|
||||
M_TCPV4_CSUM_OUT = 0x0002, /* TCP v4 checksum required */
|
||||
M_UDPV4_CSUM_OUT = 0x0004,
|
||||
|
||||
M_IPV4_CSUM_IN_OK = 0x0008,
|
||||
M_IPV4_CSUM_IN_OUT = 0x0010,
|
||||
|
||||
M_TCP_CSUM_IN_OK = 0x0020,
|
||||
M_TCP_CSUM_IN_BAD = 0x0040,
|
||||
|
||||
M_UDP_CSUM_IN_OK = 0x0080,
|
||||
M_UDP_CSUM_IN_BAD = 0x0100
|
||||
};
|
||||
|
||||
/* MBuf types */
|
||||
enum {
|
||||
MT_FREE = 0, /* should be on free list */
|
||||
MT_DATA = 1, /* dynamic data allocation */
|
||||
MT_HEADER = 2, /* packet header */
|
||||
MT_SONAME = 3,
|
||||
MT_SOOPTS = 4,
|
||||
MT_FTABLE = 5, /* fragment reassembly header */
|
||||
MT_CONTROL = 6, /* extra-data protocol message */
|
||||
MT_OOBDATA = 7 /* out-of-band data */
|
||||
};
|
||||
|
||||
/* length to m_copy to copy all */
|
||||
#define M_COPYALL 1000000000
|
||||
|
||||
/* now some macro's to make life easier... */
|
||||
|
||||
/* need to add the macro's here :) */
|
||||
|
||||
#define MRESETDATA(m) do { \
|
||||
if ((m)->m_flags & M_EXT) \
|
||||
(m)->m_data = (m)->m_ext.ext_buf; \
|
||||
else if ((m)->m_flags & M_PKTHDR) \
|
||||
(m)->m_data = (m)->m_pktdat; \
|
||||
else \
|
||||
(m)->m_data = (m)->dat; \
|
||||
} while (0)
|
||||
|
||||
/* fill in an mbuf */
|
||||
#define MGET(n, type) \
|
||||
n = (struct mbuf*) pool_get(mbpool); \
|
||||
if (n) { \
|
||||
(n)->m_type = (type); \
|
||||
(n)->m_next = NULL; \
|
||||
(n)->m_nextpkt = NULL; \
|
||||
(n)->m_data = (n)->m_dat; \
|
||||
(n)->m_flags = 0; \
|
||||
(n)->m_cksum = 0; \
|
||||
}
|
||||
|
||||
#define MGETHDR(n, type) \
|
||||
n = (struct mbuf*) pool_get(mbpool); \
|
||||
if (n) { \
|
||||
(n)->m_type = (type); \
|
||||
(n)->m_next = NULL; \
|
||||
(n)->m_nextpkt = NULL; \
|
||||
(n)->m_data = (n)->m_pktdat; \
|
||||
(n)->m_flags = M_PKTHDR; \
|
||||
(n)->m_cksum = 0; \
|
||||
}
|
||||
|
||||
#define _MEXTREMOVE(m) do { \
|
||||
if ((m)->m_flags & M_CLUSTER) { \
|
||||
pool_put(clpool, (m)->m_ext.ext_buf); \
|
||||
} \
|
||||
(m)->m_flags &= ~(M_CLUSTER|M_EXT); \
|
||||
(m)->m_ext.ext_size = 0; \
|
||||
} while (0)
|
||||
|
||||
#define MFREE(m, n) \
|
||||
if ((m)->m_flags & M_EXT) { \
|
||||
_MEXTREMOVE(m); \
|
||||
} \
|
||||
(n) = (m)->m_next; \
|
||||
pool_put(mbpool, m);
|
||||
|
||||
/* set the data pointer to place an object of size len at the end
|
||||
* of the mbuf, aligned to long word (16 bits)
|
||||
*/
|
||||
#define M_ALIGN(m, len) \
|
||||
{ (m)->m_data += (MLEN - (len)) &~ (sizeof(int16) -1);}
|
||||
|
||||
#define MH_ALIGN(m, len) \
|
||||
{ (m)->m_data += (MHLEN - (len)) &~ (sizeof(int16) -1);}
|
||||
|
||||
#define M_MOVE_HDR(to, from) { \
|
||||
(to)->m_pkthdr = (from)->m_pkthdr; \
|
||||
(from)->m_flags &= ~M_PKTHDR; \
|
||||
}
|
||||
|
||||
#define M_MOVE_PKTHDR(to, from) { \
|
||||
(to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
|
||||
M_MOVE_HDR((to), (from)); \
|
||||
(to)->m_data = (to)->m_pktdat; \
|
||||
}
|
||||
|
||||
#define MCLGET(m) do { \
|
||||
(m)->m_ext.ext_buf = pool_get(clpool); \
|
||||
if ((m)->m_ext.ext_buf != NULL) { \
|
||||
(m)->m_data = (m)->m_ext.ext_buf; \
|
||||
(m)->m_flags |= M_EXT|M_CLUSTER; \
|
||||
(m)->m_ext.ext_size = MCLBYTES; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define M_LEADINGSPACE(m) \
|
||||
((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf : \
|
||||
(m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
|
||||
(m)->m_data - (m)->m_dat)
|
||||
|
||||
#define M_PREPEND(m, plen) { \
|
||||
if (M_LEADINGSPACE(m) >= (plen)) { \
|
||||
(m)->m_data -= (plen); \
|
||||
(m)->m_len += (plen); \
|
||||
} else \
|
||||
(m) = m_prepend((m), (plen)); \
|
||||
if ((m) && (m)->m_flags & M_PKTHDR) \
|
||||
(m)->m_pkthdr.len += (plen); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicate just m_pkthdr from from to to.
|
||||
*/
|
||||
#define M_DUP_HDR(to, from) { \
|
||||
(to)->m_pkthdr = (from)->m_pkthdr; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicate mbuf pkthdr from from to to.
|
||||
* from must have M_PKTHDR set, and to must be empty.
|
||||
*/
|
||||
#define M_DUP_PKTHDR(to, from) { \
|
||||
(to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
|
||||
M_DUP_HDR((to), (from)); \
|
||||
(to)->m_data = (to)->m_pktdat; \
|
||||
}
|
||||
|
||||
#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))
|
||||
|
||||
#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
|
||||
|
||||
#define M_DATASTART(m) \
|
||||
(M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
|
||||
(m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
|
||||
|
||||
#define M_DATASIZE(m) \
|
||||
(M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
|
||||
(m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
|
||||
|
||||
/* Functions! */
|
||||
void mbinit(void);
|
||||
struct mbuf *m_get(int type);
|
||||
|
||||
struct mbuf *m_gethdr(int type);
|
||||
struct mbuf *m_getclr(int type);
|
||||
|
||||
struct mbuf *m_prepend(struct mbuf *m, int len);
|
||||
struct mbuf *m_devget(char *buf, int totlen, int off0,
|
||||
struct ifnet *ifp,
|
||||
void (*copy)(const void *, void *, size_t));
|
||||
struct mbuf *m_pullup(struct mbuf *, int len);
|
||||
void m_copyback(struct mbuf *m0, int off, int len, caddr_t cp);
|
||||
|
||||
struct mbuf *m_free(struct mbuf *mfree);
|
||||
void m_freem(struct mbuf *m);
|
||||
|
||||
void m_reserve(struct mbuf *mp, int len);
|
||||
void m_cat(struct mbuf *m, struct mbuf *n);
|
||||
void m_adj(struct mbuf *mp, int req_len);
|
||||
void m_copydata(struct mbuf *m, int off, int len, caddr_t cp);
|
||||
struct mbuf *m_copym(struct mbuf *m, int off0, int len);
|
||||
|
||||
/* debug functions */
|
||||
void dump_freelist(void);
|
||||
|
||||
/* Stats structure */
|
||||
/* XXX - add me! */
|
||||
|
||||
|
||||
#endif /* OBOS_MBUF_H */
|
@ -1,37 +0,0 @@
|
||||
/* net_malloc.h
|
||||
*
|
||||
* Are we useing the system amlloc or our own...
|
||||
*/
|
||||
|
||||
#ifndef NET_MALLOC_H
|
||||
#define NET_MALLOC_H
|
||||
|
||||
#include <malloc.h>
|
||||
#include "net_misc.h"
|
||||
|
||||
#if USE_DEBUG_MALLOC
|
||||
|
||||
|
||||
|
||||
/* We check the boundary of the malloc'd area at one end of the
|
||||
* area allocated. If we are outside the area it'll stop, but we can
|
||||
* check only one end of the boundary. So the following essentially
|
||||
* allows us to choose which end.
|
||||
*/
|
||||
//#define OVERRUN
|
||||
#ifdef OVERRUN
|
||||
#define CHECK_OVERRUN 1
|
||||
#else
|
||||
#define CHECK_UNDERRUN 1
|
||||
#endif
|
||||
|
||||
/* use the area malloc code from marcus Overhagen */
|
||||
void *dbg_malloc(char *file, int line, size_t size);
|
||||
void dbg_free (char *file, int line, void *ptr);
|
||||
|
||||
#define malloc(s) dbg_malloc(__FILE__, __LINE__, s)
|
||||
#define free(s) do { dbg_free(__FILE__, __LINE__, s); s = NULL; } while (0)
|
||||
#endif /* USE_DEBUG_MALLOC */
|
||||
|
||||
#endif /* NET_MALLOC_H */
|
||||
|
@ -1,98 +0,0 @@
|
||||
/* net_misc.h
|
||||
* Miscellaneous networking stuff that doesn't yet have a home.
|
||||
*/
|
||||
|
||||
//#ifdef _NETWORK_STACK
|
||||
|
||||
#ifndef OBOS_NET_MISC_H
|
||||
#define OBOS_NET_MISC_H
|
||||
|
||||
//#include <kernel/OS.h>
|
||||
#include <Errors.h>
|
||||
#include <mbuf.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#define printf dprintf
|
||||
#endif
|
||||
|
||||
#ifndef __HAIKU__
|
||||
/* Not really sure if this is safe... */
|
||||
#define EHOSTDOWN (B_POSIX_ERROR_BASE + 45)
|
||||
#endif
|
||||
|
||||
/* These are GCC only, so we'll need PPC version eventually... */
|
||||
struct quehead {
|
||||
struct quehead *qh_link;
|
||||
struct quehead *qh_rlink;
|
||||
};
|
||||
|
||||
static __inline void insque(void *a, void *b)
|
||||
{
|
||||
struct quehead *element = (struct quehead *)a,
|
||||
*head = (struct quehead *)b;
|
||||
|
||||
element->qh_link = head->qh_link;
|
||||
element->qh_rlink = head;
|
||||
head->qh_link = element;
|
||||
element->qh_link->qh_rlink = element;
|
||||
}
|
||||
|
||||
static __inline void remque(void *a)
|
||||
{
|
||||
struct quehead *element = (struct quehead *)a;
|
||||
|
||||
element->qh_link->qh_rlink = element->qh_rlink;
|
||||
element->qh_rlink->qh_link = element->qh_link;
|
||||
element->qh_rlink = 0;
|
||||
}
|
||||
|
||||
/* DEBUG Options!
|
||||
*
|
||||
* Having a single option is sort of lame so I'm going to start adding more here...
|
||||
*
|
||||
*/
|
||||
#define SHOW_DEBUG 0 /* general debugging stuff (verbose!) */
|
||||
#define SHOW_ROUTE 0 /* show routing information */
|
||||
#define ARP_DEBUG 0 /* show ARP debug info */
|
||||
#define USE_DEBUG_MALLOC 0 /* use the debug malloc code*/
|
||||
|
||||
typedef struct ifnet ifnet;
|
||||
|
||||
/* ARP lookup return codes... */
|
||||
enum {
|
||||
ARP_LOOKUP_OK = 1,
|
||||
ARP_LOOKUP_QUEUED = 2,
|
||||
ARP_LOOKUP_FAILED = 3
|
||||
};
|
||||
|
||||
typedef uint32 ipv4_addr;
|
||||
|
||||
/* XXX - add some macro's for inserting various types of address
|
||||
*/
|
||||
|
||||
void net_server_add_device(ifnet *ifn);
|
||||
//XXX already in netinet/in.h
|
||||
//uint16 in_cksum(struct mbuf *m, int len, int off);
|
||||
void local_init(void);
|
||||
|
||||
/* sockets and in_pcb init */
|
||||
int sockets_init(void);
|
||||
void sockets_shutdown(void);
|
||||
int inpcb_init(void);
|
||||
|
||||
void start_tx_thread(ifnet *dev);
|
||||
void start_rx_thread(ifnet *dev);
|
||||
|
||||
/* Useful debugging functions */
|
||||
void dump_ipv4_addr(char *msg, void *ad);
|
||||
void print_ipv4_addr(void *ad);
|
||||
void dump_ether_addr(char *msg, void *ma);
|
||||
void print_ether_addr(void *ea);
|
||||
void dump_buffer(char *buffer, int len);
|
||||
void dump_sockaddr(void *ptr);
|
||||
|
||||
#endif /* OBOS_NET_MISC_H */
|
||||
|
||||
//#endif /* _NETWORK_STACK */
|
||||
|
@ -1,41 +0,0 @@
|
||||
/* net_module.h
|
||||
* fundtions and staructures for all modules using the
|
||||
* net_server
|
||||
*/
|
||||
|
||||
#ifndef OBOS_NET_MODULE_H
|
||||
#define OBOS_NET_MODULE_H
|
||||
|
||||
#include <kernel/OS.h>
|
||||
#include <image.h>
|
||||
|
||||
#include "mbuf.h"
|
||||
#include "net_misc.h"
|
||||
#include "sys/socketvar.h"
|
||||
#include "net/if.h"
|
||||
#include "net/route.h"
|
||||
|
||||
#include <module.h>
|
||||
|
||||
#ifndef __HAIKU__
|
||||
#define NETWORK_MODULES_ROOT "obos_network/"
|
||||
#else
|
||||
#define NETWORK_MODULES_ROOT "network/"
|
||||
#endif
|
||||
|
||||
struct kernel_net_module_info {
|
||||
module_info info;
|
||||
int (*start)(void *);
|
||||
int (*stop)(void);
|
||||
status_t (*control)(uint32 op, void *data, size_t length);
|
||||
};
|
||||
|
||||
struct net_module {
|
||||
struct net_module *next;
|
||||
char *name;
|
||||
struct kernel_net_module_info *ptr;
|
||||
int status;
|
||||
};
|
||||
|
||||
#endif /* OBOS_NET_MODULE_H */
|
||||
|
@ -1,79 +0,0 @@
|
||||
#ifndef _NET_SOCKET_H
|
||||
#define _NET_SOCKET_H
|
||||
|
||||
#include <sys/socketvar.h>
|
||||
#include <mbuf.h>
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/* These functions are exported through the core module */
|
||||
|
||||
int socket_init (struct socket **nso);
|
||||
int socket_create (struct socket *so, int dom, int type, int proto);
|
||||
int socket_shutdown (struct socket *so, int how); // XXX this one is not used at all
|
||||
int socket_close (struct socket *so);
|
||||
|
||||
int socket_bind (struct socket *so, char *, int);
|
||||
int socket_listen (struct socket *so, int backlog);
|
||||
int socket_connect (struct socket *so, char *, int);
|
||||
int socket_accept (struct socket *so, struct socket **nso, void *, int *);
|
||||
|
||||
int socket_writev (struct socket *so, struct iovec *, int flags);
|
||||
int socket_readv (struct socket *so, struct iovec *, int *flags);
|
||||
int socket_send (struct socket *so, struct msghdr *, int flags, int *retsize);
|
||||
int socket_recv (struct socket *so, struct msghdr *, caddr_t namelenp, int *retsize);
|
||||
|
||||
int socket_setsockopt (struct socket *so, int, int, const void *, size_t);
|
||||
int socket_getsockopt (struct socket *so, int, int, void *, size_t *);
|
||||
int socket_ioctl (struct socket *so, int cmd, caddr_t data);
|
||||
|
||||
int socket_getpeername (struct socket *so, struct sockaddr *, int *);
|
||||
int socket_getsockname (struct socket *so, struct sockaddr *, int *);
|
||||
|
||||
int socket_socketpair (struct socket *so, struct socket **nso);
|
||||
|
||||
int socket_set_event_callback(struct socket *so, socket_event_callback, void *, int);
|
||||
|
||||
|
||||
/* these are all private to the stack...although may be shared with
|
||||
* other network modules.
|
||||
*/
|
||||
|
||||
|
||||
struct socket *sonewconn(struct socket *head, int connstatus);
|
||||
int soreserve (struct socket *so, uint32 sndcc, uint32 rcvcc);
|
||||
|
||||
void sockbuf_release(struct sockbuf *sb);
|
||||
int sockbuf_reserve(struct sockbuf *sb, uint32 cc);
|
||||
void sockbuf_drop(struct sockbuf *sb, int len);
|
||||
void sockbuf_droprecord(struct sockbuf *sb);
|
||||
void sockbuf_flush(struct sockbuf *sb);
|
||||
int sockbuf_wait(struct sockbuf *sb);
|
||||
void sockbuf_append(struct sockbuf *sb, struct mbuf *m);
|
||||
int sockbuf_appendaddr(struct sockbuf *sb, struct sockaddr *asa,
|
||||
struct mbuf *m0, struct mbuf *control);
|
||||
int sockbuf_appendcontrol(struct sockbuf *sb, struct mbuf *m0,
|
||||
struct mbuf *control);
|
||||
void sockbuf_appendrecord(struct sockbuf *sb, struct mbuf *m0);
|
||||
void sockbuf_compress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
|
||||
void sockbuf_insertoob(struct sockbuf *, struct mbuf *);
|
||||
|
||||
void sowakeup(struct socket *so, struct sockbuf *sb);
|
||||
|
||||
int sodisconnect(struct socket *);
|
||||
|
||||
void socket_set_hasoutofband(struct socket *so);
|
||||
void socket_set_cantsendmore(struct socket *so);
|
||||
void socket_set_cantrcvmore(struct socket *so);
|
||||
void socket_set_connected(struct socket *so);
|
||||
void socket_set_connecting(struct socket *so);
|
||||
void socket_set_disconnected(struct socket *so);
|
||||
void socket_set_disconnecting(struct socket *so);
|
||||
|
||||
int sorflush(struct socket *so);
|
||||
|
||||
int sockbuf_lock(struct sockbuf *sb);
|
||||
int nsleep(sem_id chan, char *msg, int timeo);
|
||||
void wakeup(sem_id chan);
|
||||
|
||||
#endif
|
@ -1,169 +0,0 @@
|
||||
/* net_stack_driver.h
|
||||
* structures and defines to deal with the network stack pseudo-driver...
|
||||
*/
|
||||
|
||||
#ifndef NET_STACK_DRIVER_H
|
||||
#define NET_STACK_DRIVER_H
|
||||
|
||||
#include <OS.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
// Forward declaration
|
||||
struct sockaddr;
|
||||
|
||||
#define NET_STACK_DRIVER_DEV "net/stack"
|
||||
#define NET_STACK_DRIVER_PATH "/dev/" NET_STACK_DRIVER_DEV
|
||||
|
||||
enum {
|
||||
// Paranoia mode: be far away of B_DEVICE_OP_CODES_END opcodes!!!
|
||||
// You never know what another device driver ioctl() will do
|
||||
// if think our NET_STACK_* is in fact his DO_RISKY_BUSINESS opcode, or whatever...
|
||||
NET_IOCTL_BASE = 0xbe230000,
|
||||
NET_STACK_IOCTL_BASE = NET_IOCTL_BASE + 0x200
|
||||
};
|
||||
|
||||
enum {
|
||||
// ops not acting on an existing socket
|
||||
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
||||
NET_STACK_GET_COOKIE, // void **
|
||||
NET_STACK_CONTROL_NET_MODULE, // control_net_module_args *
|
||||
NET_STACK_SYSCTL, // sysctl_args *
|
||||
|
||||
// ops acting on an existing socket
|
||||
NET_STACK_BIND, // sockaddr_args *
|
||||
NET_STACK_RECVFROM, // struct msghdr *
|
||||
NET_STACK_RECV, // transfer_args *
|
||||
NET_STACK_SENDTO, // struct msghdr *
|
||||
NET_STACK_SEND, // transfer_args *
|
||||
NET_STACK_LISTEN, // int_args * (value = backlog)
|
||||
NET_STACK_ACCEPT, // sockaddr_args *
|
||||
NET_STACK_CONNECT, // sockaddr_args *
|
||||
NET_STACK_SHUTDOWN, // int_args * (value = how)
|
||||
NET_STACK_GETSOCKOPT, // sockopt_args *
|
||||
NET_STACK_SETSOCKOPT, // sockopt_args *
|
||||
NET_STACK_GETSOCKNAME, // sockaddr_args *
|
||||
NET_STACK_GETPEERNAME, // sockaddr_args *
|
||||
NET_STACK_SOCKETPAIR, // socketpair_args *
|
||||
|
||||
// TODO: remove R5 select() emulation
|
||||
NET_STACK_SELECT, // select_args *
|
||||
NET_STACK_DESELECT, // select_args *
|
||||
|
||||
NET_STACK_NOTIFY_SOCKET_EVENT, // notify_socket_event_args * (userland stack only)
|
||||
|
||||
NET_STACK_IOCTL_MAX
|
||||
};
|
||||
|
||||
struct sockaddr_args { // used by NET_STACK_CONNECT/_BIND/_GETSOCKNAME/_GETPEERNAME
|
||||
struct sockaddr *addr;
|
||||
socklen_t addrlen;
|
||||
};
|
||||
|
||||
struct sockopt_args { // used by NET_STACK_SETSOCKOPT/_GETSOCKOPT
|
||||
int level;
|
||||
int option;
|
||||
void *optval;
|
||||
int optlen;
|
||||
};
|
||||
|
||||
struct transfer_args { // used by NET_STACK_SEND/_RECV
|
||||
void *data;
|
||||
size_t datalen;
|
||||
int flags;
|
||||
struct sockaddr *addr; // unused in *_SEND and *_RECV cases
|
||||
int addrlen; // unused in *_SEND and *_RECV cases
|
||||
};
|
||||
|
||||
struct socket_args { // used by NET_STACK_SOCKET
|
||||
int family;
|
||||
int type;
|
||||
int proto;
|
||||
};
|
||||
|
||||
struct socketpair_args { // used by NET_STACK_SOCKETPAIR
|
||||
void *cookie;
|
||||
};
|
||||
|
||||
struct accept_args { // used by NET_STACK_ACCEPT
|
||||
void *cookie;
|
||||
struct sockaddr *addr;
|
||||
socklen_t addrlen;
|
||||
};
|
||||
|
||||
struct sysctl_args { // used by NET_STACK_SYSCTL
|
||||
int *name;
|
||||
uint namelen;
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
size_t newlen;
|
||||
};
|
||||
|
||||
struct control_net_module_args { // used by NET_STACK_CONTROL_NET_MODULE
|
||||
const char *name;
|
||||
uint32 op;
|
||||
void *data;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
/*
|
||||
Userland stack driver on_socket_event() callback mecanism implementation:
|
||||
the driver start a kernel thread waiting on a port for
|
||||
a NET_STACK_SOCKET_EVENT_MSG message, which come with a socket_event_data block.
|
||||
|
||||
The on_socket_event() mechanism stay in driver (kernelland) because it's
|
||||
only there we can call kernel's notify_select_event() on BONE systems.
|
||||
For non-BONE systems, we use our own r5_notify_select_event()
|
||||
implementation, that could be moved into the userland net_server code,
|
||||
but it'll have split (again!) the /dev/net/stack driver code...
|
||||
*/
|
||||
|
||||
struct notify_socket_event_args { // used by NET_STACK_NOTIFY_SOCKET_EVENT
|
||||
port_id notify_port; // port waiting for notification, -1 = stop notify
|
||||
void * cookie; // this cookie value will be pass back in the socket_event_args
|
||||
};
|
||||
|
||||
#define NET_STACK_SOCKET_EVENT_NOTIFICATION 'sevn'
|
||||
|
||||
struct socket_event_data {
|
||||
uint32 event; // B_SELECT_READ, B_SELECT_WRITE or B_SELECT_ERROR
|
||||
void * cookie; // The cookie as set in notify_socket_event_args for this socket
|
||||
};
|
||||
|
||||
/*
|
||||
R5.0.3 and before select() kernel support is too buggy to be used, so
|
||||
here are the structures we used to support select() on sockets, and *only* on
|
||||
sockets!
|
||||
*/
|
||||
|
||||
struct select_args { // used by NET_STACK_SELECT and NET_STACK_DESELECT
|
||||
struct selectsync * sync; // in fact, it's the area_id of a r5_selectsync struct!!!
|
||||
uint32 ref;
|
||||
};
|
||||
|
||||
struct r5_selectsync {
|
||||
sem_id lock; // lock this r5_selectsync
|
||||
sem_id wakeup; // sem to release to wakeup select()
|
||||
struct fd_set rbits; // read event bits field
|
||||
struct fd_set wbits; // write event bits field
|
||||
struct fd_set ebits; // exception event bits field
|
||||
};
|
||||
|
||||
|
||||
struct stack_driver_args {
|
||||
union {
|
||||
int integer;
|
||||
struct socket_args socket;
|
||||
struct accept_args accept;
|
||||
struct sockaddr_args sockaddr;
|
||||
struct sockopt_args sockopt;
|
||||
struct transfer_args transfer;
|
||||
struct sysctl_args sysctl;
|
||||
struct select_args select;
|
||||
struct control_net_module_args control;
|
||||
struct socketpair_args socketpair;
|
||||
} u;
|
||||
};
|
||||
|
||||
#endif /* NET_STACK_DRIVER_H */
|
@ -1,26 +0,0 @@
|
||||
#ifndef NET_TIMER_H
|
||||
#define NET_TIMER_H
|
||||
/* net_timer.h - a small and more or less inaccurate timer for net modules.
|
||||
** The registered hooks will be called in the thread of the timer.
|
||||
**
|
||||
** Initial version by Axel Dörfler, axeld@pinc-software.de
|
||||
**
|
||||
** This file may be used under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
typedef void (*net_timer_hook)(void *);
|
||||
typedef int32 net_timer_id;
|
||||
|
||||
|
||||
extern status_t net_init_timer(void);
|
||||
extern void net_shutdown_timer(void);
|
||||
|
||||
extern net_timer_id net_add_timer(net_timer_hook hook, void *data, bigtime_t interval);
|
||||
extern status_t net_remove_timer(net_timer_id);
|
||||
|
||||
|
||||
#endif /* NET_TIMER_H */
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
/*
|
||||
* netconfig.h
|
||||
* Copyright (c) 1995 Be, Inc. All Rights Reserved
|
||||
*
|
||||
* Stuff for reading info out of the /boot/system/netconfig file
|
||||
*/
|
||||
#ifndef _NETCONFIG_H
|
||||
#define _NETCONFIG_H
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <net_settings.h>
|
||||
|
||||
#define NC_MAXCLASSLEN 256
|
||||
#define NC_MAXNAMELEN 256
|
||||
#define NC_MAXVALLEN 256
|
||||
|
||||
|
||||
static const char NETCONFIGFILE[] = "/network";
|
||||
static const char NETCONFIGFILE_TMP[] = "/network.tmp";
|
||||
|
||||
|
||||
typedef struct _netconfig {
|
||||
FILE *ncfile;
|
||||
char ncbuf[1020];
|
||||
} NETCONFIG;
|
||||
|
||||
typedef char nc_data_t[NC_MAXVALLEN];
|
||||
|
||||
typedef struct nc_private {
|
||||
nc_data_t key;
|
||||
nc_data_t value;
|
||||
} nc_private_t;
|
||||
|
||||
_IMPEXP_NET NETCONFIG *_netconfig_open(const char *heading);
|
||||
_IMPEXP_NET char *_netconfig_find(const char *heading, const char *name, char *value,
|
||||
int nbytes);
|
||||
_IMPEXP_NET int _netconfig_set(const char *heading, const char *name, const char *value);
|
||||
|
||||
|
||||
_IMPEXP_NET net_settings *_net_settings_open(const char *fname);
|
||||
|
||||
_IMPEXP_NET void _net_settings_makedefault(net_settings *ncw);
|
||||
_IMPEXP_NET int _net_settings_save(net_settings *ncw);
|
||||
_IMPEXP_NET int _net_settings_save_as(net_settings *ncw, const char *fname);
|
||||
_IMPEXP_NET void _net_settings_close(net_settings *ncw);
|
||||
|
||||
_IMPEXP_NET int _netconfig_getnext(
|
||||
NETCONFIG *netconfig,
|
||||
char **name,
|
||||
char **value
|
||||
);
|
||||
|
||||
_IMPEXP_NET void _netconfig_close(NETCONFIG *netconfig);
|
||||
|
||||
|
||||
#define net_settings_isdirty(ncw) (ncw)->_dirty
|
||||
#define net_settings_makedirty(ncw, mkdirty) (ncw)->_dirty = mkdirty
|
||||
#define net_settings_makedefault _net_settings_makedefault
|
||||
#define netconfig_open _netconfig_open
|
||||
#define net_settings_open _net_settings_open
|
||||
#define netconfig_find _netconfig_find
|
||||
#define netconfig_set _netconfig_set
|
||||
#define net_settings_save _net_settings_save
|
||||
#define net_settings_save_as _net_settings_save_as
|
||||
#define net_settings_close _net_settings_close
|
||||
#define netconfig_getnext _netconfig_getnext
|
||||
#define netconfig_close _netconfig_close
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _NETCONFIG_H */
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* netdebug.h
|
||||
*
|
||||
* Debugging message support. Nothing really network specific about
|
||||
* it, but renamed from "debug.h" to distinguish it from other debug.h's
|
||||
* that live around the system, and because the *&^%$#@! Metrowerks
|
||||
* compiler can't deal with subdirs in include directives.
|
||||
*/
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
#ifndef _NETDEBUG_H
|
||||
#define _NETDEBUG_H
|
||||
|
||||
#include <BeBuild.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERNC extern "C"
|
||||
#else
|
||||
#define EXTERNC extern
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debug messages can go to a file, to the console, to both or to nowhere.
|
||||
* Use debug_setflags() to set.
|
||||
*/
|
||||
#define DEBUG_CONSOLE 1
|
||||
#define DEBUG_FILE 2
|
||||
#define DEBUG_NOFLUSH 4
|
||||
|
||||
EXTERNC _IMPEXP_NET void _debug_setflags(unsigned flags);
|
||||
EXTERNC _IMPEXP_NET unsigned _debug_getflags(void);
|
||||
|
||||
#define debug_setflags _debug_setflags
|
||||
#define debug_getflags _debug_getflags
|
||||
|
||||
/*
|
||||
* function -DDEBUG=? comment
|
||||
* _____________________________________________________
|
||||
* wprintf anything for warnings
|
||||
* dprintf DEBUG > 0 for debugging messages
|
||||
* ddprintf DEBUG > 1 for extra debugging messages
|
||||
*/
|
||||
|
||||
EXTERNC _IMPEXP_NET int _wprintf(const char *format, ...);
|
||||
EXTERNC _IMPEXP_NET int _dprintf(const char *format, ...);
|
||||
|
||||
/*
|
||||
* Define null function "noprintf"
|
||||
*/
|
||||
#define noprintf (void)
|
||||
|
||||
#if DEBUG
|
||||
#define wprintf _dprintf
|
||||
#define dprintf _dprintf
|
||||
|
||||
#if DEBUG > 1
|
||||
#define ddprintf _dprintf
|
||||
#else /* DEBUG > 1 */
|
||||
#define ddprintf noprintf
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
#else /* DEBUG */
|
||||
|
||||
#define wprintf _wprintf
|
||||
#define dprintf noprintf
|
||||
#define ddprintf noprintf
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* _NETDEBUG_H */
|
@ -1,24 +0,0 @@
|
||||
#ifndef netgroup_h
|
||||
#define netgroup_h
|
||||
#ifndef __GLIBC__
|
||||
|
||||
/*
|
||||
* The standard is crazy. These values "belong" to getnetgrent() and
|
||||
* shouldn't be altered by the caller.
|
||||
*/
|
||||
int getnetgrent __P((/* const */ char **, /* const */ char **,
|
||||
/* const */ char **));
|
||||
|
||||
int getnetgrent_r __P((char **, char **, char **, char *, int));
|
||||
|
||||
void endnetgrent __P((void));
|
||||
|
||||
#ifdef __osf__
|
||||
int innetgr __P((char *, char *, char *, char *));
|
||||
void setnetgrent __P((char *));
|
||||
#else
|
||||
void setnetgrent __P((const char *));
|
||||
int innetgr __P((const char *, const char *, const char *, const char *));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
/* nhash.h
|
||||
*/
|
||||
|
||||
#ifndef OBOS_NHASH_H
|
||||
#define OBOS_NHASH_H
|
||||
|
||||
#include "pools.h"
|
||||
|
||||
typedef struct net_hash_entry net_hash_entry;
|
||||
typedef struct net_hash net_hash;
|
||||
typedef struct net_hash_index net_hash_index;
|
||||
|
||||
struct net_hash_entry {
|
||||
net_hash_entry *next;
|
||||
int hash;
|
||||
const void *key;
|
||||
ssize_t klen;
|
||||
const void *val;
|
||||
};
|
||||
|
||||
struct net_hash_index {
|
||||
net_hash *nh;
|
||||
net_hash_entry *this;
|
||||
net_hash_entry *next;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct net_hash {
|
||||
net_hash_entry **array;
|
||||
net_hash_index iterator;
|
||||
int count;
|
||||
int max;
|
||||
struct pool_ctl *pool;
|
||||
};
|
||||
|
||||
net_hash *nhash_make(void);
|
||||
void *nhash_get(net_hash *, const void *key, ssize_t klen);
|
||||
void nhash_set(net_hash *, const void *, ssize_t , const void *);
|
||||
|
||||
#endif /* OBOS_NHASH_H */
|
@ -1,55 +0,0 @@
|
||||
/* pools.h
|
||||
* simple fixed size block allocator
|
||||
*/
|
||||
|
||||
#ifndef OBOS_POOLS_H
|
||||
#define OBOS_POOLS_H
|
||||
|
||||
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#include "lock.h"
|
||||
|
||||
|
||||
typedef struct pool_ctl pool_ctl;
|
||||
|
||||
struct pool_mem {
|
||||
struct pool_mem *next;
|
||||
area_id aid;
|
||||
char *base_addr;
|
||||
size_t mem_size;
|
||||
char *ptr;
|
||||
size_t avail;
|
||||
benaphore lock;
|
||||
};
|
||||
|
||||
struct free_blk {
|
||||
char *next;
|
||||
};
|
||||
|
||||
#define POOL_USES_BENAPHORES 0
|
||||
#define POOL_DEBUG_NAME_SZ 32
|
||||
|
||||
struct pool_ctl {
|
||||
struct pool_mem *list;
|
||||
char *freelist;
|
||||
size_t alloc_size;
|
||||
size_t block_size;
|
||||
#if POOL_USES_BENAPHORES
|
||||
benaphore lock;
|
||||
#else
|
||||
rw_lock lock;
|
||||
#endif
|
||||
int debug;
|
||||
char name[POOL_DEBUG_NAME_SZ];
|
||||
};
|
||||
|
||||
status_t pool_init(pool_ctl **p, size_t sz);
|
||||
char *pool_get(pool_ctl *p);
|
||||
void pool_put(pool_ctl *p, void *ptr);
|
||||
void pool_destroy(pool_ctl *p);
|
||||
void pool_debug(struct pool_ctl *p, char *name);
|
||||
|
||||
void pool_debug_walk(pool_ctl *p);
|
||||
|
||||
#endif /* OBOS_POOLS_H */
|
@ -1,48 +0,0 @@
|
||||
/* protocols.h
|
||||
* The various protocols we're likely to come across as
|
||||
* they're identified in the type fields of packets...
|
||||
*/
|
||||
|
||||
#include "netinet/in.h"
|
||||
|
||||
#ifndef OBOS_PROTOCOLS_H
|
||||
#define OBOS_PROTOCOLS_H
|
||||
|
||||
/* define some protocol numbers unique to ethernet */
|
||||
enum {
|
||||
ETHER_IPV4 = 0x0800,
|
||||
ETHER_ARP = 0x0806,
|
||||
ETHER_RARP = 0x8035,
|
||||
ETHER_ATALK = 0x809b, /* Appletalk */
|
||||
ETHER_SNMP = 0x814c, /* SNMP */
|
||||
ETHER_IPV6 = 0x86dd, /* IPv6 */
|
||||
ETHER_PPPOE_DISC = 0x8863, /* PPPoE Discovery */
|
||||
ETHER_PPPOE_SESS = 0x8864 /* PPPoE Session */
|
||||
};
|
||||
|
||||
/* these are used when assigning slots in the protocol table, so they
|
||||
* should tie in with IP numbers wherever possible, with other
|
||||
* protocols fitting in.
|
||||
* These are used in the module definitions.
|
||||
*/
|
||||
enum {
|
||||
NS_IPV4 = IPPROTO_IP,
|
||||
NS_ICMP = IPPROTO_ICMP,
|
||||
NS_IGMP = IPPROTO_IGMP,
|
||||
NS_TCP = IPPROTO_TCP,
|
||||
NS_UDP = IPPROTO_UDP,
|
||||
NS_ETHER=200,
|
||||
NS_IPV6,
|
||||
NS_ATALK,
|
||||
NS_ARP,
|
||||
NS_RARP,
|
||||
NS_PPPOE,
|
||||
NS_SERIAL,
|
||||
NS_LOOP,
|
||||
NS_SOCKET,
|
||||
NS_ROUTE
|
||||
};
|
||||
|
||||
|
||||
#endif /* OBOS_PROTOCOLS_H */
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* raw_module.h
|
||||
*/
|
||||
|
||||
#ifndef RAW_MODULE_H
|
||||
#define RAW_MODULE_H
|
||||
|
||||
#include "net_module.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
|
||||
#define NET_RAW_MODULE_NAME NETWORK_MODULES_ROOT "protocols/raw"
|
||||
|
||||
struct raw_module_info {
|
||||
struct kernel_net_module_info info;
|
||||
|
||||
void (*input)(struct mbuf *, int);
|
||||
};
|
||||
|
||||
#endif /* RAW_MODULE_H */
|
@ -1,35 +0,0 @@
|
||||
/* domain.h */
|
||||
|
||||
/* A domain is just a container for like minded protocols! */
|
||||
|
||||
#ifndef _SYS_DOMAIN_H
|
||||
#define _SYS_DOMAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct domain {
|
||||
int dom_family; /* AF_INET and so on */
|
||||
char *dom_name;
|
||||
|
||||
void (*dom_init)(void); /* initialise */
|
||||
|
||||
struct protosw *dom_protosw; /* the protocols we have */
|
||||
struct domain *dom_next;
|
||||
|
||||
int (*dom_rtattach)(void **, int);
|
||||
int dom_rtoffset;
|
||||
int dom_maxrtkey;
|
||||
};
|
||||
|
||||
extern struct domain *domains;
|
||||
|
||||
void add_domain (struct domain *dom, int fam);
|
||||
void remove_domain (int fam);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_DOMAIN_H */
|
@ -1,156 +0,0 @@
|
||||
/* protosw.h */
|
||||
|
||||
#ifndef _SYS_PROTOSW_H
|
||||
#define _SYS_PROTOSW_H
|
||||
|
||||
#include <sys/socketvar.h> /* for struct socket */
|
||||
#include <net/route.h>
|
||||
|
||||
#define PRCO_SETOPT 0
|
||||
#define PRCO_GETOPT 1
|
||||
|
||||
/* every protocol module init's one of these and passes it into
|
||||
* the add_protocol() function, defined below */
|
||||
/* NB The pr_domain pointer will be filled in during the
|
||||
* add_protocol() call
|
||||
*/
|
||||
struct protosw {
|
||||
char *name;
|
||||
char *mod_path;
|
||||
uint16 pr_type; /* SOCK_xxx */
|
||||
struct domain *pr_domain;
|
||||
uint16 pr_protocol; /* protocol number */
|
||||
uint16 pr_flags; /* flags, PR_xxx */
|
||||
int layer; /* which layer are we? */
|
||||
|
||||
/* the functions! */
|
||||
void (*pr_init)(void);
|
||||
void (*pr_input)(struct mbuf*, int);
|
||||
int (*pr_output)(struct mbuf *, struct mbuf *,
|
||||
struct route *,
|
||||
int, void *);
|
||||
|
||||
int (*pr_userreq)(struct socket *, int,
|
||||
struct mbuf *,
|
||||
struct mbuf *,
|
||||
struct mbuf *);
|
||||
int (*pr_sysctl)(int *, uint, void *, size_t *, void *, size_t);
|
||||
void (*pr_ctlinput)(int, struct sockaddr *, void *);
|
||||
int (*pr_ctloutput)(int, struct socket*, int, int, struct mbuf **);
|
||||
|
||||
struct protosw *pr_next; /* pointer to next proto structure */
|
||||
struct protosw *dom_next; /* next protosw pointed by the domain */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
#define PR_ABRTACPTDIS 0x20 /* abort on accept(2) to disconnected
|
||||
socket */
|
||||
|
||||
#define PR_SLOWHZ 2 /* 2 timeouts per second... */
|
||||
#define PR_FASTHZ 5 /* 5 timeouts per second */
|
||||
/*
|
||||
* Defines for the userreq function req field are below.
|
||||
*
|
||||
* (*usrreq)(up, req, m, nam, opt);
|
||||
*
|
||||
* 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,
|
||||
* 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_PEEREID 22 /* get local peer eid */
|
||||
|
||||
#define PRU_NREQ 22
|
||||
|
||||
/*
|
||||
* 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_MTUINC 2 /* increase in mtu to host */
|
||||
#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)
|
||||
|
||||
|
||||
/* Network stack defines... */
|
||||
// struct protosw *protocols;
|
||||
|
||||
enum {
|
||||
NET_LAYER1 = 1,
|
||||
NET_LAYER2,
|
||||
NET_LAYER3,
|
||||
NET_LAYER4
|
||||
};
|
||||
|
||||
//XXX conflicts with src/add-ons/kernel/network/core/core.c:69
|
||||
// void add_protosw (struct protosw *prt[], int);
|
||||
void add_protocol (struct protosw *, int);
|
||||
void remove_protocol (struct protosw *);
|
||||
|
||||
struct protosw *pffindproto(int domain, int protocol, int type);
|
||||
struct protosw *pffindtype(int domain, int type);
|
||||
|
||||
#endif /* _SYS_PROTOSW_H */
|
@ -1,155 +0,0 @@
|
||||
/* socketvar.h */
|
||||
|
||||
|
||||
#ifndef _SYS_SOCKETVAR_H
|
||||
#define _SYS_SOCKETVAR_H
|
||||
|
||||
#include <OS.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct mbuf;
|
||||
|
||||
struct sockbuf {
|
||||
int32 sb_cc; /* actual chars in buffer */
|
||||
int32 sb_hiwat; /* max actual char count (high water mark) */
|
||||
int32 sb_mbcnt; /* chars of mbufs used */
|
||||
int32 sb_mbmax; /* max chars of mbufs to use */
|
||||
int32 sb_lowat; /* low water mark */
|
||||
struct mbuf *sb_mb; /* the mbuf chain */
|
||||
int16 sb_flags; /* flags, see below */
|
||||
int32 sb_timeo; /* timeout for read/write */
|
||||
sem_id sb_sleep; /* our sleep sem */
|
||||
sem_id sb_pop; /* sem to wait on... */
|
||||
};
|
||||
|
||||
#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 */
|
||||
#define SB_KNOTE 0x80 /* kernel note attached */
|
||||
#define SB_NOTIFY (SB_WAIT|SB_SEL|SB_ASYNC)
|
||||
|
||||
typedef void (*socket_event_callback)(void * socket, uint32 event, void * cookie);
|
||||
|
||||
struct socket {
|
||||
uint16 so_type; /* type of socket */
|
||||
uint16 so_options; /* socket options */
|
||||
int16 so_linger; /* dreaded linger value */
|
||||
int16 so_state; /* socket state */
|
||||
char *so_pcb; /* pointer to the control block */
|
||||
sem_id so_lock; /* socket lock */
|
||||
sem_id so_timeo; /* our wait channel */
|
||||
|
||||
struct protosw *so_proto; /* pointer to protocol module */
|
||||
|
||||
struct socket *so_head;
|
||||
struct socket *so_q0;
|
||||
struct socket *so_q;
|
||||
|
||||
int16 so_q0len;
|
||||
int16 so_qlen;
|
||||
int16 so_qlimit;
|
||||
int32 so_error;
|
||||
// pid_t so_pgid;
|
||||
uint32 so_oobmark;
|
||||
|
||||
/* our send/recv buffers */
|
||||
struct sockbuf so_snd;
|
||||
struct sockbuf so_rcv;
|
||||
|
||||
// event callback
|
||||
socket_event_callback event_callback;
|
||||
void * event_callback_cookie;
|
||||
int sel_ev;
|
||||
};
|
||||
|
||||
/* Select event bit mask */
|
||||
#define SEL_READ 0x01
|
||||
#define SEL_WRITE 0x02
|
||||
#define SEL_EX 0x04
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/* helpful defines... */
|
||||
|
||||
/* 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; \
|
||||
}
|
||||
|
||||
#define sbspace(sb) \
|
||||
(abs(min((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)
|
||||
|
||||
/* 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; \
|
||||
}
|
||||
|
||||
#define soreadable(so) \
|
||||
((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
|
||||
((so)->so_state & SS_CANTRCVMORE) || \
|
||||
(so)->so_qlen || (so)->so_error)
|
||||
|
||||
#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))
|
||||
|
||||
#define M_WAITOK 0x0000
|
||||
#define M_NOWAIT 0x0001
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define sblock(sb, wf) ((sb)->sb_flags & SB_LOCK ? \
|
||||
(((wf) == M_WAITOK) ? sockbuf_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((sb)->sb_sleep); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define sorwakeup(so) sowakeup((so), &(so)->so_rcv)
|
||||
/* we don't handle upcall for sockets */
|
||||
#define sowwakeup(so) sowakeup((so), &(so)->so_snd)
|
||||
|
||||
#endif /* _SYS_SOCKETVAR_H */
|
@ -1,45 +0,0 @@
|
||||
#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 SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
|
||||
#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
|
||||
|
||||
#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 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 */
|
||||
|
||||
#define SIOCGIFMTU _IOWR('i', 126, struct ifreq) /* get ifnet MTU */
|
||||
#define SIOCSIFMTU _IOW('i', 127, struct ifreq) /* set ifnet MTU */
|
||||
|
||||
#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
|
||||
#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */
|
||||
|
||||
#endif /* SYS_NET_IOCTL_H */
|
||||
|
@ -1,65 +0,0 @@
|
||||
#ifndef USERLAND_IPC_H
|
||||
#define USERLAND_IPC_H
|
||||
/* userland_ipc - Communication between the network driver
|
||||
** and the userland stack.
|
||||
**
|
||||
** Initial version by Axel Dörfler, axeld@pinc-software.de
|
||||
** This file may be used under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <Drivers.h>
|
||||
|
||||
#include "net_stack_driver.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NET_STACK_PORTNAME "net_server connection"
|
||||
|
||||
enum {
|
||||
NET_STACK_OPEN = NET_STACK_IOCTL_MAX,
|
||||
NET_STACK_CLOSE,
|
||||
NET_STACK_NEW_CONNECTION,
|
||||
};
|
||||
|
||||
#define MAX_NET_AREAS 16
|
||||
|
||||
typedef struct {
|
||||
area_id id;
|
||||
uint8 *offset;
|
||||
} net_area_info;
|
||||
|
||||
typedef struct {
|
||||
int32 op;
|
||||
// int32 buffer;
|
||||
uint8 *data;
|
||||
int32 length;
|
||||
int32 result;
|
||||
net_area_info area[MAX_NET_AREAS];
|
||||
} net_command;
|
||||
|
||||
#define CONNECTION_QUEUE_LENGTH 128
|
||||
#define CONNECTION_COMMAND_SIZE 2048
|
||||
|
||||
typedef struct {
|
||||
port_id port;
|
||||
area_id area;
|
||||
thread_id socket_thread;
|
||||
|
||||
sem_id commandSemaphore; // command queue
|
||||
uint32 numCommands,bufferSize;
|
||||
} net_connection;
|
||||
|
||||
|
||||
extern status_t init_userland_ipc(void);
|
||||
extern void shutdown_userland_ipc(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* USERLAND_IPC_H */
|
@ -14,41 +14,41 @@ UsePrivateHeaders net ;
|
||||
|
||||
# a) Userland stack version:
|
||||
|
||||
KernelAddon net_server_driver : kernel drivers bin :
|
||||
net_server_driver.c
|
||||
KernelAddon userland_net_server : kernel drivers bin :
|
||||
userland_server.cpp
|
||||
;
|
||||
|
||||
# b) Kernelland stack version:
|
||||
|
||||
KernelAddon net_stack_driver : kernel drivers bin :
|
||||
net_stack_driver.c
|
||||
KernelAddon net_stack : kernel drivers bin :
|
||||
kernel_stack.cpp
|
||||
;
|
||||
|
||||
# Installation
|
||||
|
||||
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/drivers/bin :
|
||||
net_server_driver
|
||||
net_stack_driver
|
||||
userland_net_server
|
||||
net_stack
|
||||
;
|
||||
|
||||
HaikuInstallRelSymLink install-networking : /boot/home/config/add-ons/kernel/drivers/dev/net :
|
||||
<installed>net_server_driver
|
||||
<installed>net_stack_driver :
|
||||
<installed>userland_net_server
|
||||
<installed>net_stack :
|
||||
installed-symlink
|
||||
;
|
||||
|
||||
HaikuInstall install-userland-networking : /boot/home/config/add-ons/kernel/drivers/bin :
|
||||
net_server_driver :
|
||||
userland_net_server :
|
||||
installed-userland-networking
|
||||
;
|
||||
|
||||
HaikuInstallRelSymLink install-userland-networking : /boot/home/config/add-ons/kernel/drivers/dev/net :
|
||||
<installed-userland-networking>net_server_driver :
|
||||
<installed-userland-networking>userland_net_server :
|
||||
installed-userland-networking-symlink
|
||||
;
|
||||
Package haiku-networkingkit-cvs :
|
||||
net_stack_driver net_server_driver :
|
||||
net_stack userland_net_server :
|
||||
boot home config add-ons kernel drivers bin ;
|
||||
|
||||
PackageDriverSymLink haiku-networkingkit-cvs : net net_stack_driver ;
|
||||
PackageDriverSymLink haiku-networkingkit-cvs : net net_server_driver ;
|
||||
PackageDriverSymLink haiku-networkingkit-cvs : net net_stack ;
|
||||
PackageDriverSymLink haiku-networkingkit-cvs : net userland_net_server ;
|
||||
|
778
src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp
Normal file
778
src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp
Normal file
@ -0,0 +1,778 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku, Inc. All Rights Reserved.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
This file implements a very simple socket driver that is intended to
|
||||
act as an interface to the networking stack.
|
||||
*/
|
||||
|
||||
#include <net_socket.h>
|
||||
#include <net_stack_driver.h>
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// debugging macros
|
||||
#define LOGID "net_stack_driver: "
|
||||
#define ERROR(format, args...) dprintf(LOGID "ERROR: " format, ## args)
|
||||
#define WARN(format, args...) dprintf(LOGID "WARNING: " format, ## args)
|
||||
|
||||
#ifdef DEBUG
|
||||
# define TRACE(format, args...) dprintf(format, ## args)
|
||||
#else
|
||||
# define TRACE(format, args...)
|
||||
#endif
|
||||
|
||||
|
||||
// Local definitions
|
||||
|
||||
// this struct will store one select() event to monitor per thread
|
||||
typedef struct selecter {
|
||||
struct selecter *next;
|
||||
thread_id thread;
|
||||
uint32 event;
|
||||
selectsync *sync;
|
||||
uint32 ref;
|
||||
} selecter;
|
||||
|
||||
// the cookie we attach to each file descriptor opened on our driver entry
|
||||
typedef struct net_stack_cookie {
|
||||
net_socket *socket; // NULL before ioctl(fd, NET_STACK_SOCKET/_ACCEPT)
|
||||
sem_id selecters_lock; // protect the selecters linked-list
|
||||
selecter *selecters; // the select()'ers lists (thread-aware)
|
||||
} net_stack_cookie;
|
||||
|
||||
// TODO: disabled
|
||||
/* To unload this driver execute
|
||||
* $ echo unload > /dev/net/stack
|
||||
* As soon as the last app stops using sockets the netstack will be unloaded.
|
||||
*/
|
||||
//static const char *kUnloadCommand = "unload";
|
||||
|
||||
|
||||
// prototypes of device hooks functions
|
||||
static status_t net_stack_open(const char *name, uint32 flags, void **_cookie);
|
||||
static status_t net_stack_close(void *cookie);
|
||||
static status_t net_stack_free_cookie(void *cookie);
|
||||
static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t length);
|
||||
static status_t net_stack_read(void *cookie, off_t pos, void *data, size_t *_length);
|
||||
static status_t net_stack_write(void *cookie, off_t pos, const void *data, size_t *_length);
|
||||
static status_t net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync);
|
||||
static status_t net_stack_deselect(void *cookie, uint8 event, selectsync *sync);
|
||||
static status_t net_stack_readv(void *cookie, off_t pos, const iovec *vecs, size_t count, size_t *_length);
|
||||
static status_t net_stack_writev(void *cookie, off_t pos, const iovec *vecs, size_t count, size_t *_length);
|
||||
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
static int32 sOpenCount = 0;
|
||||
static struct net_socket_module_info *sSocket = NULL;
|
||||
|
||||
|
||||
// #pragma mark - internal functions
|
||||
|
||||
|
||||
template<typename ArgType> status_t
|
||||
return_address(ArgType &args, void *data)
|
||||
{
|
||||
sockaddr_storage *target;
|
||||
|
||||
if (user_memcpy(&target, &((ArgType *)data)->address, sizeof(void *)) < B_OK
|
||||
|| user_memcpy(&((ArgType *)data)->address_length, &args.address_length, sizeof(socklen_t)) < B_OK
|
||||
|| user_memcpy(target, args.address, args.address_length) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
template<typename ArgType> status_t
|
||||
check_args_and_address(ArgType &args, sockaddr_storage &address, void *data, size_t length,
|
||||
bool copyAddress = true)
|
||||
{
|
||||
if (data == NULL || length != sizeof(ArgType))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (user_memcpy(&args, data, sizeof(ArgType)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
if (args.address_length > sizeof(sockaddr_storage))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (copyAddress && user_memcpy(&address, args.address, args.address_length) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
args.address = (sockaddr *)&address;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
template<typename ArgType> status_t
|
||||
check_args(ArgType &args, void *data, size_t length)
|
||||
{
|
||||
if (data == NULL || length != sizeof(ArgType))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (user_memcpy(&args, data, sizeof(ArgType)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
on_socket_event(void * socket, uint32 event, void *_cookie)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *) _cookie;
|
||||
selecter *s;
|
||||
|
||||
if (!cookie)
|
||||
return;
|
||||
|
||||
if (cookie->socket != socket) {
|
||||
ERROR("on_socket_event(%p, %ld, %p): socket is higly suspect! Aborting.\n",
|
||||
socket, event, cookie);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("on_socket_event(%p, %ld, %p)\n", socket, event, cookie);
|
||||
|
||||
// lock the selecters list
|
||||
if (acquire_sem(cookie->selecters_lock) != B_OK)
|
||||
return;
|
||||
|
||||
s = cookie->selecters;
|
||||
while (s) {
|
||||
if (s->event == event)
|
||||
// notify this selecter (thread/event pair)
|
||||
#ifdef COMPILE_FOR_R5
|
||||
notify_select_event(s->sync, s->ref);
|
||||
#else
|
||||
notify_select_event(s->sync, s->ref, event);
|
||||
#endif
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
|
||||
// unlock the selecters list
|
||||
release_sem(cookie->selecters_lock);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char*
|
||||
opcode_name(int op)
|
||||
{
|
||||
#define C2N(op) { op, #op }
|
||||
// op-code to name
|
||||
struct commands_info {
|
||||
int op;
|
||||
const char *name;
|
||||
} *ci, commands_info[] = {
|
||||
C2N(NET_STACK_SOCKET),
|
||||
C2N(NET_STACK_BIND),
|
||||
C2N(NET_STACK_RECVFROM),
|
||||
C2N(NET_STACK_RECV),
|
||||
C2N(NET_STACK_SENDTO),
|
||||
C2N(NET_STACK_SEND),
|
||||
C2N(NET_STACK_LISTEN),
|
||||
C2N(NET_STACK_ACCEPT),
|
||||
C2N(NET_STACK_CONNECT),
|
||||
C2N(NET_STACK_SHUTDOWN),
|
||||
C2N(NET_STACK_GETSOCKOPT),
|
||||
C2N(NET_STACK_SETSOCKOPT),
|
||||
C2N(NET_STACK_GETSOCKNAME),
|
||||
C2N(NET_STACK_GETPEERNAME),
|
||||
C2N(NET_STACK_SYSCTL),
|
||||
C2N(NET_STACK_SELECT),
|
||||
C2N(NET_STACK_DESELECT),
|
||||
C2N(NET_STACK_GET_COOKIE),
|
||||
C2N(NET_STACK_NOTIFY_SOCKET_EVENT),
|
||||
C2N(NET_STACK_CONTROL_NET_MODULE),
|
||||
|
||||
// Userland IPC-specific opcodes
|
||||
// C2N(NET_STACK_OPEN),
|
||||
// C2N(NET_STACK_CLOSE),
|
||||
// C2N(NET_STACK_NEW_CONNECTION),
|
||||
|
||||
// Standard BeOS opcodes
|
||||
C2N(B_SET_BLOCKING_IO),
|
||||
C2N(B_SET_NONBLOCKING_IO),
|
||||
|
||||
{ 0, "Unknown!" }
|
||||
};
|
||||
#undef C2N
|
||||
|
||||
ci = commands_info;
|
||||
while(ci && ci->op) {
|
||||
if (ci->op == op)
|
||||
return ci->name;
|
||||
ci++;
|
||||
}
|
||||
|
||||
return "???";
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
// #pragma mark - driver
|
||||
|
||||
|
||||
/** Do we init ourselves? If we're in safe mode we'll decline so if things
|
||||
* screw up we can boot and delete the broken driver!
|
||||
* After my experiences earlier - a good idea!
|
||||
*/
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
|
||||
if (settings != NULL) {
|
||||
// we got a pointer, now get settings...
|
||||
bool safemode = get_driver_boolean_parameter(settings, B_SAFEMODE_SAFE_MODE, false, false);
|
||||
// now get rid of settings
|
||||
unload_driver_settings(settings);
|
||||
|
||||
if (safemode) {
|
||||
WARN("init_hardware: declining offer to join the party.\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("init_hardware done.\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_driver(void)
|
||||
{
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_driver(void)
|
||||
{
|
||||
TRACE("uninit_driver\n");
|
||||
|
||||
put_module(NET_SOCKET_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
||||
const char **
|
||||
publish_devices(void)
|
||||
{
|
||||
static const char *devices[] = { NET_STACK_DRIVER_DEV, NULL };
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
||||
device_hooks*
|
||||
find_device(const char* device_name)
|
||||
{
|
||||
static device_hooks hooks = {
|
||||
net_stack_open,
|
||||
net_stack_close,
|
||||
net_stack_free_cookie,
|
||||
net_stack_control,
|
||||
net_stack_read,
|
||||
net_stack_write,
|
||||
net_stack_select,
|
||||
net_stack_deselect,
|
||||
net_stack_readv,
|
||||
net_stack_writev,
|
||||
};
|
||||
|
||||
return &hooks;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - device
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_open(const char *name, uint32 flags, void **_cookie)
|
||||
{
|
||||
if (atomic_add(&sOpenCount, 1) == 0) {
|
||||
// When we're opened for the first time, we'll try to load the
|
||||
// networking stack
|
||||
status_t status = get_module(NET_SOCKET_MODULE_NAME, (module_info **)&sSocket);
|
||||
if (status < B_OK) {
|
||||
ERROR("Can't load " NET_SOCKET_MODULE_NAME " module: %ld\n", status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)malloc(sizeof(net_stack_cookie));
|
||||
if (cookie == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(cookie, 0, sizeof(net_stack_cookie));
|
||||
cookie->socket = NULL; // the socket will be allocated in NET_STACK_SOCKET ioctl
|
||||
cookie->selecters_lock = create_sem(1, "socket_selecters_lock");
|
||||
|
||||
// attach this new net_socket_cookie to file descriptor
|
||||
*_cookie = cookie;
|
||||
|
||||
TRACE("net_stack_open(%s, %s%s) return this cookie: %p\n",
|
||||
name,
|
||||
(((flags & O_RWMASK) == O_RDONLY) ? "O_RDONLY" :
|
||||
((flags & O_RWMASK) == O_WRONLY) ? "O_WRONLY" : "O_RDWR"),
|
||||
(flags & O_NONBLOCK) ? " O_NONBLOCK" : "",
|
||||
cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_close(void *_cookie)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
|
||||
TRACE("net_stack_close(%p)\n", cookie);
|
||||
|
||||
if (cookie->socket == NULL)
|
||||
return B_OK;
|
||||
|
||||
return sSocket->close(cookie->socket);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_free_cookie(void *_cookie)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
selecter *s;
|
||||
|
||||
TRACE("net_stack_free_cookie(%p)\n", cookie);
|
||||
|
||||
// free the selecters list
|
||||
delete_sem(cookie->selecters_lock);
|
||||
s = cookie->selecters;
|
||||
while (s) {
|
||||
selecter *tmp = s;
|
||||
s = s->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
if (cookie->socket != NULL)
|
||||
sSocket->free(cookie->socket);
|
||||
|
||||
// free the cookie
|
||||
free(cookie);
|
||||
|
||||
if (atomic_add(&sOpenCount, -1) == 1) {
|
||||
// the last reference to us has been removed, unload the networking
|
||||
// stack again
|
||||
put_module(NET_SOCKET_MODULE_NAME);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_control(void *_cookie, uint32 op, void *data, size_t length)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
status_t status = B_BAD_VALUE;
|
||||
|
||||
TRACE("net_stack_control(%p, %s (0x%lX), %p, %ld)\n",
|
||||
_cookie, opcode_name(op), op, data, len);
|
||||
|
||||
if (op < NET_STACK_IOCTL_BASE || op > NET_STACK_IOCTL_END) {
|
||||
// we only accept networking ioctl()s to get into our stack
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (cookie->socket == NULL) {
|
||||
switch (op) {
|
||||
case NET_STACK_SOCKET:
|
||||
{
|
||||
socket_args args;
|
||||
status = check_args(args, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return sSocket->socket(args.family, args.type, args.protocol, &cookie->socket);
|
||||
}
|
||||
|
||||
case NET_STACK_GET_COOKIE:
|
||||
// This is needed by accept() call, allowing libnet.so accept() to pass back
|
||||
// in NET_STACK_ACCEPT opcode the cookie (aka the net_stack_cookie!)
|
||||
// of the file descriptor to use for the new accepted socket
|
||||
return user_memcpy(data, cookie, sizeof(void *));
|
||||
}
|
||||
} else {
|
||||
switch (op) {
|
||||
case NET_STACK_CONNECT:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
sockaddr_args args;
|
||||
status = check_args_and_address(args, address, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return sSocket->connect(cookie->socket, args.address, args.address_length);
|
||||
}
|
||||
|
||||
case NET_STACK_BIND:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
sockaddr_args args;
|
||||
status = check_args_and_address(args, address, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return sSocket->bind(cookie->socket, args.address, args.address_length);
|
||||
}
|
||||
|
||||
case NET_STACK_LISTEN:
|
||||
// backlog to set
|
||||
return sSocket->listen(cookie->socket, (int)data);
|
||||
|
||||
case NET_STACK_ACCEPT:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
accept_args args;
|
||||
status = check_args_and_address(args, address, data, length, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// args.cookie is the net_stack_cookie of the already opened socket
|
||||
// TODO: find a safer way to do this!
|
||||
|
||||
net_stack_cookie *acceptCookie = (net_stack_cookie *)args.cookie;
|
||||
status = sSocket->accept(cookie->socket, args.address,
|
||||
&args.address_length, &acceptCookie->socket);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return return_address(args, data);
|
||||
}
|
||||
|
||||
case NET_STACK_SHUTDOWN:
|
||||
return sSocket->shutdown(cookie->socket, (int)data);
|
||||
|
||||
case NET_STACK_SEND:
|
||||
{
|
||||
transfer_args args;
|
||||
status = check_args(args, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return sSocket->send(cookie->socket, args.data, args.data_length, args.flags);
|
||||
}
|
||||
case NET_STACK_SENDTO:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
transfer_args args;
|
||||
status = check_args_and_address(args, address, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return sSocket->sendto(cookie->socket, args.data, args.data_length,
|
||||
args.flags, args.address, args.address_length);
|
||||
}
|
||||
|
||||
case NET_STACK_RECV:
|
||||
{
|
||||
transfer_args args;
|
||||
status = check_args(args, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return sSocket->recv(cookie->socket, args.data, args.data_length, args.flags);
|
||||
}
|
||||
case NET_STACK_RECVFROM:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
transfer_args args;
|
||||
status = check_args_and_address(args, address, data, length, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
ssize_t bytesRead = sSocket->recvfrom(cookie->socket, args.data,
|
||||
args.data_length, args.flags, args.address, &args.address_length);
|
||||
if (bytesRead < B_OK)
|
||||
return bytesRead;
|
||||
|
||||
status = return_address(args, data);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
case NET_STACK_GETSOCKOPT:
|
||||
{
|
||||
sockopt_args args;
|
||||
status = check_args(args, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
char valueBuffer[128];
|
||||
if (args.length > (int)sizeof(valueBuffer))
|
||||
args.length = (int)sizeof(valueBuffer);
|
||||
|
||||
status = sSocket->getsockopt(cookie->socket, args.level, args.option,
|
||||
valueBuffer, &args.length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
if (user_memcpy(args.value, valueBuffer, args.length) < B_OK
|
||||
|| user_memcpy(&((sockopt_args *)data)->length, &args.length, sizeof(int)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NET_STACK_SETSOCKOPT:
|
||||
{
|
||||
sockopt_args args;
|
||||
status = check_args(args, data, length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
char valueBuffer[128];
|
||||
if (args.length > (int)sizeof(valueBuffer))
|
||||
return B_BAD_VALUE;
|
||||
if (user_memcpy(valueBuffer, args.value, args.length) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return sSocket->setsockopt(cookie->socket, args.level, args.option,
|
||||
valueBuffer, args.length);
|
||||
}
|
||||
|
||||
case NET_STACK_GETSOCKNAME:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
sockaddr_args args;
|
||||
status = check_args_and_address(args, address, data, length, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = sSocket->getsockname(cookie->socket, args.address,
|
||||
&args.address_length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return return_address(args, data);
|
||||
}
|
||||
|
||||
case NET_STACK_GETPEERNAME:
|
||||
{
|
||||
sockaddr_storage address;
|
||||
sockaddr_args args;
|
||||
status = check_args_and_address(args, address, data, length, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = sSocket->getpeername(cookie->socket, args.address,
|
||||
&args.address_length);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return return_address(args, data);
|
||||
}
|
||||
|
||||
case FIONBIO:
|
||||
{
|
||||
int value = (int)data;
|
||||
return sSocket->setsockopt(cookie->socket, SOL_SOCKET, SO_NONBLOCK,
|
||||
&value, sizeof(int));
|
||||
}
|
||||
|
||||
case B_SET_BLOCKING_IO:
|
||||
case B_SET_NONBLOCKING_IO:
|
||||
{
|
||||
int value = op == B_SET_NONBLOCKING_IO;
|
||||
return sSocket->setsockopt(cookie->socket, SOL_SOCKET, SO_NONBLOCK,
|
||||
&value, sizeof(int));
|
||||
}
|
||||
|
||||
default:
|
||||
return sSocket->control(cookie->socket, op, data, length);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_read(void *_cookie, off_t /*offset*/, void *buffer, size_t *_length)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
|
||||
TRACE("net_stack_read(%p, %p, %ld)\n", cookie, buffer, *_length);
|
||||
|
||||
if (cookie->socket == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ssize_t bytesRead = sSocket->recv(cookie->socket, buffer, *_length, 0);
|
||||
if (bytesRead < 0) {
|
||||
*_length = 0;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
*_length = bytesRead;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_readv(void *_cookie, off_t /*offset*/, const struct iovec *vecs,
|
||||
size_t count, size_t *_length)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
|
||||
TRACE("net_stack_readv(%p, (%p, %lu), %ld)\n", cookie, vecs, count, *_length);
|
||||
|
||||
if (cookie->socket == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return sSocket->readv(cookie->socket, vecs, count, _length);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_write(void *_cookie, off_t /*offset*/, const void *buffer, size_t *_length)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
|
||||
TRACE("net_stack_write(%p, %p, %ld)\n", cookie, buffer, *_length);
|
||||
|
||||
if (cookie->socket == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ssize_t bytesWritten = sSocket->send(cookie->socket, buffer, *_length, 0);
|
||||
if (bytesWritten < 0) {
|
||||
*_length = 0;
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
*_length = bytesWritten;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_writev(void *_cookie, off_t /*offset*/, const struct iovec *vecs,
|
||||
size_t count, size_t *_length)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
|
||||
TRACE("net_stack_writev(%p, (%p, %lu), %ld)\n", cookie, vecs, count, *_length);
|
||||
|
||||
if (cookie->socket == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return sSocket->writev(cookie->socket, vecs, count, _length);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
status_t status;
|
||||
|
||||
TRACE("net_stack_select(%p, %d, %ld, %p)\n", cookie, event, ref, sync);
|
||||
|
||||
if (cookie->socket == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
selecter *s = (selecter *)malloc(sizeof(selecter));
|
||||
if (s == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
s->thread = find_thread(NULL);
|
||||
s->event = event;
|
||||
s->sync = sync;
|
||||
s->ref = ref;
|
||||
|
||||
// lock the selecters list
|
||||
status = acquire_sem(cookie->selecters_lock);
|
||||
if (status != B_OK) {
|
||||
free(s);
|
||||
return status;
|
||||
}
|
||||
|
||||
// add it to selecters list
|
||||
s->next = cookie->selecters;
|
||||
cookie->selecters = s;
|
||||
|
||||
// unlock the selecters list
|
||||
release_sem(cookie->selecters_lock);
|
||||
|
||||
// start (or continue) to monitor for socket event
|
||||
// TODO: enable select() notification
|
||||
// return sSocket->socket_set_event_callback(cookie->socket, on_socket_event, cookie, event);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_deselect(void *_cookie, uint8 event, selectsync *sync)
|
||||
{
|
||||
net_stack_cookie *cookie = (net_stack_cookie *)_cookie;
|
||||
|
||||
TRACE("net_stack_deselect(%p, %d, %p)\n", cookie, event, sync);
|
||||
|
||||
if (!cookie || !cookie->socket)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// lock the selecters list
|
||||
status_t status = acquire_sem(cookie->selecters_lock);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
thread_id currentThread = find_thread(NULL);;
|
||||
selecter *previous = NULL;
|
||||
selecter *s = cookie->selecters;
|
||||
|
||||
while (s) {
|
||||
if (s->thread == currentThread
|
||||
&& s->event == event && s->sync == sync) {
|
||||
// selecter found!
|
||||
break;
|
||||
}
|
||||
|
||||
previous = s;
|
||||
s = s->next;
|
||||
}
|
||||
|
||||
if (s != NULL) {
|
||||
// remove it from selecters list
|
||||
if (previous)
|
||||
previous->next = s->next;
|
||||
else
|
||||
cookie->selecters = s->next;
|
||||
free(s);
|
||||
}
|
||||
|
||||
// TODO: enable deselect()
|
||||
if (cookie->selecters == NULL) {
|
||||
// selecters list is empty: no need to monitor socket events anymore
|
||||
//sSocket->socket_set_event_callback(cookie->socket, NULL, NULL, event);
|
||||
}
|
||||
|
||||
// unlock the selecters list
|
||||
return release_sem(cookie->selecters_lock);
|
||||
}
|
@ -1,709 +0,0 @@
|
||||
/* net_stack_driver.c
|
||||
*
|
||||
* This file implements a very simple socket driver that is intended to
|
||||
* act as an interface to the networking stack.
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
#error "This module MUST be built as a kernel driver!"
|
||||
#endif
|
||||
|
||||
// public/system includes
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <drivers/Drivers.h>
|
||||
#include <drivers/KernelExport.h>
|
||||
#include <drivers/driver_settings.h>
|
||||
#include <drivers/module.h> // for get_module()/put_module()
|
||||
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
// private includes
|
||||
#include <net_stack_driver.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <core_module.h>
|
||||
|
||||
|
||||
// debugging macros
|
||||
#define LOGID "net_stack_driver: "
|
||||
#define ERROR(format, args...) dprintf(LOGID "ERROR: " format, ## args)
|
||||
#define WARN(format, args...) dprintf(LOGID "WARNING: " format, ## args)
|
||||
#ifdef DEBUG
|
||||
#define TRACE(format, args...) dprintf(format, ## args)
|
||||
#else
|
||||
#define TRACE(format, args...)
|
||||
#endif
|
||||
|
||||
|
||||
// Local definitions
|
||||
|
||||
// this struct will store one select() event to monitor per thread
|
||||
typedef struct selecter {
|
||||
struct selecter *next;
|
||||
thread_id thread;
|
||||
uint32 event;
|
||||
selectsync *sync;
|
||||
uint32 ref;
|
||||
} selecter;
|
||||
|
||||
// the cookie we attach to each file descriptor opened on our driver entry
|
||||
typedef struct net_stack_cookie {
|
||||
struct socket *socket; // NULL before ioctl(fd, NET_STACK_SOCKET/_ACCEPT)
|
||||
uint32 open_flags; // the open() flags (mostly for storing O_NONBLOCK mode)
|
||||
sem_id selecters_lock; // protect the selecters linked-list
|
||||
selecter *selecters; // the select()'ers lists (thread-aware)
|
||||
} net_stack_cookie;
|
||||
|
||||
/* To unload this driver execute
|
||||
* $ echo unload > /dev/net/stack
|
||||
* As soon as the last app stops using sockets the netstack will be unloaded.
|
||||
*/
|
||||
static const char *kUnloadCommand = "unload";
|
||||
|
||||
|
||||
// prototypes of device hooks functions
|
||||
static status_t net_stack_open(const char *name, uint32 flags, void **cookie);
|
||||
static status_t net_stack_close(void *cookie);
|
||||
static status_t net_stack_free_cookie(void *cookie);
|
||||
static status_t net_stack_control(void *cookie, uint32 msg, void *data, size_t datalen);
|
||||
static status_t net_stack_read(void *cookie, off_t pos, void *data, size_t *datalen);
|
||||
static status_t net_stack_write(void *cookie, off_t pos, const void *data, size_t *datalen);
|
||||
static status_t net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync);
|
||||
static status_t net_stack_deselect(void *cookie, uint8 event, selectsync *sync);
|
||||
// static status_t net_stack_readv(void *cookie, off_t pos, const iovec *vec, size_t count, size_t *len);
|
||||
// static status_t net_stack_writev(void *cookie, off_t pos, const iovec *vec, size_t count, size_t *len);
|
||||
|
||||
// privates prototypes
|
||||
static void on_socket_event(void *socket, uint32 event, void *cookie);
|
||||
|
||||
static status_t keep_driver_loaded();
|
||||
static status_t unload_driver();
|
||||
|
||||
static const char *opcode_name(int op);
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
static const char *sDevices[] = { NET_STACK_DRIVER_DEV, NULL };
|
||||
|
||||
static device_hooks sDeviceHooks =
|
||||
{
|
||||
net_stack_open, /* -> open entry point */
|
||||
net_stack_close, /* -> close entry point */
|
||||
net_stack_free_cookie, /* -> free entry point */
|
||||
net_stack_control, /* -> control entry point */
|
||||
net_stack_read, /* -> read entry point */
|
||||
net_stack_write, /* -> write entry point */
|
||||
net_stack_select, /* -> select entry point */
|
||||
net_stack_deselect, /* -> deselect entry point */
|
||||
NULL, /* -> readv entry pint */
|
||||
NULL /* ->writev entry point */
|
||||
};
|
||||
|
||||
static struct core_module_info *sCore = NULL;
|
||||
|
||||
static int sStayLoadedFD = -1;
|
||||
|
||||
|
||||
// internal functions
|
||||
static status_t
|
||||
keep_driver_loaded()
|
||||
{
|
||||
if (sStayLoadedFD != -1)
|
||||
return B_OK;
|
||||
|
||||
/* force the driver to stay loaded by opening himself */
|
||||
TRACE("keep_driver_loaded: opening " NET_STACK_DRIVER_PATH " to stay loaded...\n");
|
||||
|
||||
sStayLoadedFD = open(NET_STACK_DRIVER_PATH, 0);
|
||||
|
||||
if (sStayLoadedFD < 0)
|
||||
ERROR("keep_driver_loaded: couldn't open(" NET_STACK_DRIVER_PATH ")!\n");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
unload_driver()
|
||||
{
|
||||
if (sStayLoadedFD >= 0) {
|
||||
int tmp_fd;
|
||||
|
||||
/* we need to set sStayLoadedFD to < 0 if we don't want
|
||||
* the next close enter again in this case, and so on...
|
||||
*/
|
||||
TRACE("unload_driver: unload requested.\n");
|
||||
|
||||
tmp_fd = sStayLoadedFD;
|
||||
sStayLoadedFD = -1;
|
||||
|
||||
close(tmp_fd);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Driver API calls
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
_EXPORT int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
|
||||
|
||||
/* Do we init ourselves? If we're in safe mode we'll decline so if things
|
||||
* screw up we can boot and delete the broken driver!
|
||||
* After my experiences earlier - a good idea!
|
||||
*
|
||||
* Also we'll turn on the serial debugger to aid in our debugging
|
||||
* experience.
|
||||
*/
|
||||
_EXPORT status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
bool safemode = false;
|
||||
void *sfmptr;
|
||||
|
||||
// get a pointer to the driver settings...
|
||||
sfmptr = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
|
||||
|
||||
// only use the pointer if it's valid
|
||||
if (sfmptr != NULL) {
|
||||
// we got a pointer, now get settings...
|
||||
safemode = get_driver_boolean_parameter(sfmptr, B_SAFEMODE_SAFE_MODE, false, false);
|
||||
// now get rid of settings
|
||||
unload_driver_settings(sfmptr);
|
||||
}
|
||||
|
||||
if (safemode) {
|
||||
WARN("init_hardware: declining offer to join the party.\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
TRACE("init_hardware done.\n");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/* init_driver()
|
||||
* called every time we're loaded.
|
||||
*/
|
||||
_EXPORT status_t
|
||||
init_driver(void)
|
||||
{
|
||||
// only get the core module if we don't have it loaded already
|
||||
if (!sCore) {
|
||||
int rv = 0;
|
||||
rv = get_module(NET_CORE_MODULE_NAME, (module_info **) &sCore);
|
||||
if (rv < 0) {
|
||||
ERROR("init_driver: Can't load " NET_CORE_MODULE_NAME " module: %d\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
TRACE("init_driver: built %s %s, core = %p\n", __DATE__, __TIME__, sCore);
|
||||
|
||||
// start the network stack
|
||||
sCore->start();
|
||||
}
|
||||
|
||||
keep_driver_loaded();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/* uninit_driver()
|
||||
* called every time the driver is unloaded
|
||||
*/
|
||||
_EXPORT void
|
||||
uninit_driver(void)
|
||||
{
|
||||
TRACE("uninit_driver\n");
|
||||
|
||||
if (sCore) {
|
||||
// shutdown the network stack
|
||||
sCore->stop();
|
||||
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
sCore = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* publish_devices()
|
||||
* called to publish our device.
|
||||
*/
|
||||
_EXPORT const char**
|
||||
publish_devices()
|
||||
{
|
||||
return sDevices;
|
||||
}
|
||||
|
||||
|
||||
_EXPORT device_hooks*
|
||||
find_device(const char* device_name)
|
||||
{
|
||||
return &sDeviceHooks;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Device hooks
|
||||
* ------------
|
||||
*/
|
||||
|
||||
// the network stack functions - mainly just pass throughs...
|
||||
static status_t
|
||||
net_stack_open(const char *name, uint32 flags, void **cookie)
|
||||
{
|
||||
net_stack_cookie *nsc;
|
||||
|
||||
nsc = (net_stack_cookie *) malloc(sizeof(*nsc));
|
||||
if (!nsc)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(nsc, 0, sizeof(*nsc));
|
||||
nsc->socket = NULL; // the socket will be allocated in NET_STACK_SOCKET ioctl
|
||||
nsc->open_flags = flags;
|
||||
nsc->selecters_lock = create_sem(1, "socket_selecters_lock");
|
||||
nsc->selecters = NULL;
|
||||
|
||||
// attach this new net_socket_cookie to file descriptor
|
||||
*cookie = nsc;
|
||||
|
||||
TRACE("net_stack_open(%s, %s%s) return this cookie: %p\n",
|
||||
name,
|
||||
(((flags & O_RWMASK) == O_RDONLY) ? "O_RDONLY" :
|
||||
((flags & O_RWMASK) == O_WRONLY) ? "O_WRONLY" : "O_RDWR"),
|
||||
(flags & O_NONBLOCK) ? " O_NONBLOCK" : "",
|
||||
*cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_close(void *cookie)
|
||||
{
|
||||
net_stack_cookie *nsc = cookie;
|
||||
int rv;
|
||||
|
||||
TRACE("net_stack_close(%p)\n", nsc);
|
||||
|
||||
rv = B_ERROR;
|
||||
if (nsc->socket) {
|
||||
// if a socket was opened on this fd, close it now.
|
||||
rv = sCore->socket_close(nsc->socket);
|
||||
nsc->socket = NULL;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_free_cookie(void *cookie)
|
||||
{
|
||||
net_stack_cookie *nsc = cookie;
|
||||
selecter *s;
|
||||
|
||||
TRACE("net_stack_free_cookie(%p)\n", cookie);
|
||||
|
||||
// free the selecters list
|
||||
delete_sem(nsc->selecters_lock);
|
||||
s = nsc->selecters;
|
||||
while (s) {
|
||||
selecter *tmp = s;
|
||||
s = s->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
// free the cookie
|
||||
free(cookie);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_control(void *cookie, uint32 op, void *data, size_t len)
|
||||
{
|
||||
net_stack_cookie *nsc = cookie;
|
||||
struct stack_driver_args *args = data;
|
||||
int err = B_BAD_VALUE;
|
||||
|
||||
TRACE("net_stack_control(%p, %s (0x%lX), %p, %ld)\n",
|
||||
cookie, opcode_name(op), op, data, len);
|
||||
|
||||
if (!nsc->socket) {
|
||||
switch (op) {
|
||||
case NET_STACK_SOCKET: {
|
||||
// okay, now try to open a real socket behind this fd/net_stack_cookie pair
|
||||
err = sCore->socket_init(&nsc->socket);
|
||||
if (err == 0)
|
||||
err = sCore->socket_create(nsc->socket, args->u.socket.family,
|
||||
args->u.socket.type, args->u.socket.proto);
|
||||
|
||||
// TODO: handle some more open_flags
|
||||
if(nsc->open_flags & O_NONBLOCK) {
|
||||
int on = true;
|
||||
return sCore->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &on);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
case NET_STACK_GET_COOKIE: {
|
||||
/* this is needed by accept() call, allowing libnet.so accept() to pass back
|
||||
* in NET_STACK_ACCEPT opcode the cookie (aka the net_stack_cookie!)
|
||||
* of the filedescriptor to use for the new accepted socket
|
||||
*/
|
||||
|
||||
*((void **) data) = cookie;
|
||||
return B_OK;
|
||||
}
|
||||
case NET_STACK_CONTROL_NET_MODULE: {
|
||||
return sCore->control_net_module(args->u.control.name,
|
||||
args->u.control.op, args->u.control.data, args->u.control.length);
|
||||
}
|
||||
case NET_STACK_SYSCTL:
|
||||
return sCore->net_sysctl(args->u.sysctl.name, args->u.sysctl.namelen,
|
||||
args->u.sysctl.oldp, args->u.sysctl.oldlenp,
|
||||
args->u.sysctl.newp, args->u.sysctl.newlen);
|
||||
}
|
||||
} else {
|
||||
switch (op) {
|
||||
case NET_STACK_CONNECT:
|
||||
return sCore->socket_connect(nsc->socket,
|
||||
(caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen);
|
||||
|
||||
case NET_STACK_SHUTDOWN:
|
||||
return sCore->socket_shutdown(nsc->socket, args->u.integer);
|
||||
|
||||
case NET_STACK_BIND:
|
||||
return sCore->socket_bind(nsc->socket, (caddr_t) args->u.sockaddr.addr,
|
||||
args->u.sockaddr.addrlen);
|
||||
|
||||
case NET_STACK_LISTEN:
|
||||
// backlog to set
|
||||
return sCore->socket_listen(nsc->socket, args->u.integer);
|
||||
|
||||
case NET_STACK_ACCEPT: {
|
||||
/* args->u.accept.cookie == net_stack_cookie of the already opened fd
|
||||
* in libnet.so accept() call to bind to newly accepted socket
|
||||
*/
|
||||
|
||||
net_stack_cookie *ansc = args->u.accept.cookie;
|
||||
return sCore->socket_accept(nsc->socket, &ansc->socket,
|
||||
(void *)args->u.accept.addr, &args->u.accept.addrlen);
|
||||
}
|
||||
case NET_STACK_SEND:
|
||||
// TODO: flags gets ignored here...
|
||||
return net_stack_write(cookie, 0, args->u.transfer.data,
|
||||
&args->u.transfer.datalen);
|
||||
|
||||
case NET_STACK_RECV:
|
||||
// TODO: flags gets ignored here...
|
||||
return net_stack_read(cookie, 0, args->u.transfer.data,
|
||||
&args->u.transfer.datalen);
|
||||
|
||||
case NET_STACK_RECVFROM: {
|
||||
struct msghdr * mh = (struct msghdr *) data;
|
||||
int retsize;
|
||||
|
||||
err = sCore->socket_recv(nsc->socket, mh, (caddr_t)&mh->msg_namelen,
|
||||
&retsize);
|
||||
if (err == 0)
|
||||
return retsize;
|
||||
return err;
|
||||
}
|
||||
case NET_STACK_SENDTO: {
|
||||
struct msghdr * mh = (struct msghdr *) data;
|
||||
int retsize;
|
||||
|
||||
err = sCore->socket_send(nsc->socket, mh, mh->msg_flags, &retsize);
|
||||
if (err == 0)
|
||||
return retsize;
|
||||
return err;
|
||||
}
|
||||
case NET_STACK_GETSOCKOPT:
|
||||
return sCore->socket_getsockopt(nsc->socket, args->u.sockopt.level,
|
||||
args->u.sockopt.option, args->u.sockopt.optval,
|
||||
(size_t *) &args->u.sockopt.optlen);
|
||||
|
||||
case NET_STACK_SETSOCKOPT:
|
||||
return sCore->socket_setsockopt(nsc->socket, args->u.sockopt.level,
|
||||
args->u.sockopt.option, (const void *) args->u.sockopt.optval,
|
||||
args->u.sockopt.optlen);
|
||||
|
||||
case NET_STACK_GETSOCKNAME:
|
||||
return sCore->socket_getsockname(nsc->socket, args->u.sockaddr.addr,
|
||||
&args->u.sockaddr.addrlen);
|
||||
|
||||
case NET_STACK_GETPEERNAME:
|
||||
return sCore->socket_getpeername(nsc->socket, args->u.sockaddr.addr,
|
||||
&args->u.sockaddr.addrlen);
|
||||
|
||||
case NET_STACK_SOCKETPAIR: {
|
||||
net_stack_cookie *ansc = args->u.socketpair.cookie;
|
||||
return sCore->socket_socketpair(nsc->socket, &ansc->socket);
|
||||
}
|
||||
case B_SET_BLOCKING_IO: {
|
||||
int off = false;
|
||||
nsc->open_flags &= ~O_NONBLOCK;
|
||||
return sCore->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &off);
|
||||
}
|
||||
|
||||
case B_SET_NONBLOCKING_IO: {
|
||||
int on = true;
|
||||
nsc->open_flags |= O_NONBLOCK;
|
||||
return sCore->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &on);
|
||||
}
|
||||
|
||||
default:
|
||||
return sCore->socket_ioctl(nsc->socket, op, data);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_read(void *cookie, off_t position, void *buffer, size_t *readlen)
|
||||
{
|
||||
net_stack_cookie *nsc = (net_stack_cookie *) cookie;
|
||||
struct iovec iov;
|
||||
int error;
|
||||
int flags = 0;
|
||||
|
||||
TRACE("net_stack_read(%p, %Ld, %p, %ld)\n", cookie, position, buffer, *readlen);
|
||||
|
||||
if (!nsc->socket)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
iov.iov_base = buffer;
|
||||
iov.iov_len = *readlen;
|
||||
|
||||
error = sCore->socket_readv(nsc->socket, &iov, &flags);
|
||||
*readlen = error;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_write(void *cookie, off_t position, const void *buffer, size_t *writelen)
|
||||
{
|
||||
net_stack_cookie *nsc = (net_stack_cookie *) cookie;
|
||||
struct iovec iov;
|
||||
int error;
|
||||
int flags = 0;
|
||||
|
||||
TRACE("net_stack_write(%p, %Ld, %p, %ld)\n", cookie, position, buffer, *writelen);
|
||||
|
||||
if (! nsc->socket) {
|
||||
if (*writelen >= strlen(kUnloadCommand)
|
||||
&& strncmp(buffer, kUnloadCommand, strlen(kUnloadCommand)) == 0)
|
||||
return unload_driver();
|
||||
// we are told to unload this driver
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
iov.iov_base = (void*) buffer;
|
||||
iov.iov_len = *writelen;
|
||||
|
||||
error = sCore->socket_writev(nsc->socket, &iov, flags);
|
||||
*writelen = error;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync)
|
||||
{
|
||||
net_stack_cookie * nsc = (net_stack_cookie *) cookie;
|
||||
selecter *s;
|
||||
status_t status;
|
||||
|
||||
TRACE("net_stack_select(%p, %d, %ld, %p)\n", cookie, event, ref, sync);
|
||||
|
||||
if (!nsc->socket)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
s = (selecter *) malloc(sizeof(selecter));
|
||||
if (! s)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
s->thread = find_thread(NULL); // current thread id
|
||||
s->event = event;
|
||||
s->sync = sync;
|
||||
s->ref = ref;
|
||||
|
||||
// lock the selecters list
|
||||
status = acquire_sem(nsc->selecters_lock);
|
||||
if (status != B_OK) {
|
||||
free(s);
|
||||
return status;
|
||||
}
|
||||
|
||||
// add it to selecters list
|
||||
s->next = nsc->selecters;
|
||||
nsc->selecters = s;
|
||||
|
||||
// unlock the selecters list
|
||||
release_sem(nsc->selecters_lock);
|
||||
|
||||
// start (or continue) to monitor for socket event
|
||||
return sCore->socket_set_event_callback(nsc->socket, on_socket_event, nsc, event);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
net_stack_deselect(void *cookie, uint8 event, selectsync *sync)
|
||||
{
|
||||
net_stack_cookie *nsc = (net_stack_cookie *) cookie;
|
||||
selecter *previous;
|
||||
selecter *s;
|
||||
thread_id current_thread;
|
||||
status_t status;
|
||||
|
||||
TRACE("net_stack_deselect(%p, %d, %p)\n", cookie, event, sync);
|
||||
|
||||
if (!nsc || !nsc->socket)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
current_thread = find_thread(NULL);
|
||||
|
||||
// lock the selecters list
|
||||
status = acquire_sem(nsc->selecters_lock);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
previous = NULL;
|
||||
s = nsc->selecters;
|
||||
while (s) {
|
||||
if (s->thread == current_thread &&
|
||||
s->event == event && s->sync == sync)
|
||||
// selecter found!
|
||||
break;
|
||||
|
||||
previous = s;
|
||||
s = s->next;
|
||||
}
|
||||
|
||||
if (s != NULL) {
|
||||
// remove it from selecters list
|
||||
if (previous)
|
||||
previous->next = s->next;
|
||||
else
|
||||
nsc->selecters = s->next;
|
||||
free(s);
|
||||
}
|
||||
|
||||
if (nsc->selecters == NULL)
|
||||
// selecters list is empty: no need to monitor socket events anymore
|
||||
sCore->socket_set_event_callback(nsc->socket, NULL, NULL, event);
|
||||
|
||||
// unlock the selecters list
|
||||
return release_sem(nsc->selecters_lock);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_socket_event(void * socket, uint32 event, void *cookie)
|
||||
{
|
||||
net_stack_cookie *nsc = (net_stack_cookie *) cookie;
|
||||
selecter *s;
|
||||
|
||||
if (!nsc)
|
||||
return;
|
||||
|
||||
if (nsc->socket != socket) {
|
||||
ERROR("on_socket_event(%p, %ld, %p): socket is higly suspect! Aborting.\n",
|
||||
socket, event, cookie);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("on_socket_event(%p, %ld, %p)\n", socket, event, cookie);
|
||||
|
||||
// lock the selecters list
|
||||
if (acquire_sem(nsc->selecters_lock) != B_OK)
|
||||
return;
|
||||
|
||||
s = nsc->selecters;
|
||||
while (s) {
|
||||
if (s->event == event)
|
||||
// notify this selecter (thread/event pair)
|
||||
#ifdef COMPILE_FOR_R5
|
||||
notify_select_event(s->sync, s->ref);
|
||||
#else
|
||||
notify_select_event(s->sync, s->ref, event);
|
||||
#endif
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
|
||||
// unlock the selecters list
|
||||
release_sem(nsc->selecters_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
opcode_name(int op)
|
||||
{
|
||||
#define C2N(op) { op, #op }
|
||||
// op-code to name
|
||||
struct commands_info {
|
||||
int op;
|
||||
const char *name;
|
||||
} *ci, commands_info[] = {
|
||||
C2N(NET_STACK_SOCKET),
|
||||
C2N(NET_STACK_BIND),
|
||||
C2N(NET_STACK_RECVFROM),
|
||||
C2N(NET_STACK_RECV),
|
||||
C2N(NET_STACK_SENDTO),
|
||||
C2N(NET_STACK_SEND),
|
||||
C2N(NET_STACK_LISTEN),
|
||||
C2N(NET_STACK_ACCEPT),
|
||||
C2N(NET_STACK_CONNECT),
|
||||
C2N(NET_STACK_SHUTDOWN),
|
||||
C2N(NET_STACK_GETSOCKOPT),
|
||||
C2N(NET_STACK_SETSOCKOPT),
|
||||
C2N(NET_STACK_GETSOCKNAME),
|
||||
C2N(NET_STACK_GETPEERNAME),
|
||||
C2N(NET_STACK_SYSCTL),
|
||||
C2N(NET_STACK_SELECT),
|
||||
C2N(NET_STACK_DESELECT),
|
||||
C2N(NET_STACK_GET_COOKIE),
|
||||
C2N(NET_STACK_NOTIFY_SOCKET_EVENT),
|
||||
C2N(NET_STACK_CONTROL_NET_MODULE),
|
||||
|
||||
// Userland IPC-specific opcodes
|
||||
// C2N(NET_STACK_OPEN),
|
||||
// C2N(NET_STACK_CLOSE),
|
||||
// C2N(NET_STACK_NEW_CONNECTION),
|
||||
|
||||
// Standard BeOS opcodes
|
||||
C2N(B_SET_BLOCKING_IO),
|
||||
C2N(B_SET_NONBLOCKING_IO),
|
||||
|
||||
{ 0, "Unknown!" }
|
||||
};
|
||||
|
||||
#undef C2N
|
||||
|
||||
ci = commands_info;
|
||||
while(ci && ci->op) {
|
||||
if (ci->op == op)
|
||||
return ci->name;
|
||||
ci++;
|
||||
}
|
||||
|
||||
return "???";
|
||||
}
|
@ -1,39 +1,35 @@
|
||||
/* net_server_driver - This file implements a very simple socket driver
|
||||
** that is intended to act as an interface to the networking stack when
|
||||
** it is loaded in userland, hosted by a net_server-like app.
|
||||
** The communication is slow, and could probably be much better, but it's
|
||||
** working, and that should be enough for now.
|
||||
**
|
||||
** Initial version by Axel Dörfler, axeld@pinc-software.de
|
||||
** This file may be used under the terms of the OpenBeOS License.
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku, Inc. All Rights Reserved.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
This file implements a very simple socket driver
|
||||
that is intended to act as an interface to the networking stack when
|
||||
it is loaded in userland, hosted by a net_server-like app.
|
||||
The communication is slow, and could probably be much better, but it's
|
||||
working, and that should be enough for now.
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
# error "This module MUST be built as a kernel driver!"
|
||||
#endif
|
||||
|
||||
#error "This module MUST be built as a kernel driver!"
|
||||
|
||||
#else
|
||||
|
||||
// Public includes
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <drivers/Drivers.h>
|
||||
#include <drivers/KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
// Private includes
|
||||
#include <net_stack_driver.h>
|
||||
#include <userland_ipc.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
//*****************************************************/
|
||||
// Debug output
|
||||
//*****************************************************/
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#define DEBUG_PREFIX "net_server_driver: "
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define DEBUG_PREFIX "userland_net_server: "
|
||||
#define __out dprintf
|
||||
|
||||
#define DEBUG 1
|
||||
@ -59,14 +55,7 @@
|
||||
#define D(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************/
|
||||
// Structure definitions
|
||||
//*****************************************************/
|
||||
|
||||
#ifndef DRIVER_NAME
|
||||
# define DRIVER_NAME "net_server_driver"
|
||||
#endif
|
||||
#define NET_SERVER_DRIVER_DEV "net/userland_server"
|
||||
|
||||
/* wait one second when waiting on the stack */
|
||||
#define STACK_TIMEOUT 1000000LL
|
||||
@ -104,11 +93,6 @@ typedef struct {
|
||||
selecter * selecters; // the select()'ers lists (thread-aware)
|
||||
} net_server_cookie;
|
||||
|
||||
|
||||
//*****************************************************/
|
||||
// Prototypes
|
||||
//*****************************************************/
|
||||
|
||||
/* device hooks */
|
||||
static status_t net_server_open(const char *name, uint32 flags, void **cookie);
|
||||
static status_t net_server_close(void *cookie);
|
||||
@ -118,8 +102,6 @@ static status_t net_server_read(void *cookie, off_t pos, void *data, size_t *dat
|
||||
static status_t net_server_write(void *cookie, off_t pos, const void *data, size_t *datalen);
|
||||
static status_t net_server_select(void *cookie, uint8 event, uint32 ref, selectsync *sync);
|
||||
static status_t net_server_deselect(void *cookie, uint8 event, selectsync *sync);
|
||||
// static status_t net_server_readv(void *cookie, off_t pos, const iovec *vec, size_t count, size_t *len);
|
||||
// static status_t net_server_writev(void *cookie, off_t pos, const iovec *vec, size_t count, size_t *len);
|
||||
|
||||
/* select() support */
|
||||
static int32 socket_event_listener(void *data);
|
||||
@ -132,62 +114,33 @@ static void shutdown_connection(net_server_cookie *nsc);
|
||||
static net_command *get_command(net_server_cookie *nsc, int32 *index);
|
||||
static status_t execute_command(net_server_cookie *nsc, uint32 op, void *data, uint32 length);
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
#define NET_SERVER_DRIVER_DEV "net/server"
|
||||
#define NET_SERVER_DRIVER_PATH "/dev/" ## NET_SERVER_DRIVER_DEV
|
||||
|
||||
const char * g_device_names_list[] = {
|
||||
"net/server",
|
||||
NULL
|
||||
};
|
||||
|
||||
device_hooks g_net_server_driver_hooks =
|
||||
{
|
||||
net_server_open, /* -> open entry point */
|
||||
net_server_close, /* -> close entry point */
|
||||
net_server_free_cookie, /* -> free entry point */
|
||||
net_server_control, /* -> control entry point */
|
||||
net_server_read, /* -> read entry point */
|
||||
net_server_write, /* -> write entry point */
|
||||
net_server_select, /* -> select entry point */
|
||||
net_server_deselect, /* -> deselect entry point */
|
||||
NULL, /* -> readv entry pint */
|
||||
NULL /* -> writev entry point */
|
||||
};
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
// by default, assert we can use kernel select() support
|
||||
notify_select_event_function g_nse = notify_select_event;
|
||||
thread_id g_socket_event_listener_thread = -1;
|
||||
port_id g_socket_event_listener_port = -1;
|
||||
thread_id sSocketEventThread = -1;
|
||||
port_id sSocketEventPort = -1;
|
||||
|
||||
port_id g_stack_port = -1;
|
||||
static port_id sUserlandPort = -1;
|
||||
|
||||
|
||||
/*
|
||||
* Driver API calls
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
_EXPORT int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
// #pragma mark - driver
|
||||
|
||||
|
||||
_EXPORT status_t
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
_EXPORT status_t
|
||||
init_driver (void)
|
||||
status_t
|
||||
init_driver(void)
|
||||
{
|
||||
thread_id thread;
|
||||
port_id port;
|
||||
|
||||
|
||||
FUNCTION();
|
||||
|
||||
port = create_port(32, "socket_event_listener");
|
||||
@ -200,40 +153,58 @@ init_driver (void)
|
||||
if (thread < B_OK) {
|
||||
delete_port(port);
|
||||
return thread;
|
||||
};
|
||||
|
||||
g_socket_event_listener_thread = thread;
|
||||
g_socket_event_listener_port = port;
|
||||
|
||||
}
|
||||
|
||||
sSocketEventThread = thread;
|
||||
sSocketEventPort = port;
|
||||
|
||||
return resume_thread(thread);
|
||||
}
|
||||
|
||||
|
||||
_EXPORT void
|
||||
uninit_driver (void)
|
||||
void
|
||||
uninit_driver(void)
|
||||
{
|
||||
status_t dummy;
|
||||
|
||||
FUNCTION();
|
||||
|
||||
delete_port(g_socket_event_listener_port);
|
||||
wait_for_thread(g_socket_event_listener_thread, &dummy);
|
||||
delete_port(sSocketEventPort);
|
||||
|
||||
status_t dummy;
|
||||
wait_for_thread(sSocketEventThread, &dummy);
|
||||
}
|
||||
|
||||
|
||||
_EXPORT const char **
|
||||
publish_devices()
|
||||
const char **
|
||||
publish_devices(void)
|
||||
{
|
||||
FUNCTION();
|
||||
return g_device_names_list;
|
||||
static const char *deviceNames[] = {
|
||||
"net/userland_server",
|
||||
NULL
|
||||
};
|
||||
|
||||
return deviceNames;
|
||||
}
|
||||
|
||||
|
||||
_EXPORT device_hooks *
|
||||
device_hooks *
|
||||
find_device(const char *deviceName)
|
||||
{
|
||||
FUNCTION();
|
||||
return &g_net_server_driver_hooks;
|
||||
device_hooks hooks = {
|
||||
net_server_open,
|
||||
net_server_close,
|
||||
net_server_free_cookie,
|
||||
net_server_control,
|
||||
net_server_read,
|
||||
net_server_write,
|
||||
net_server_select,
|
||||
net_server_deselect,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
return &hooks;
|
||||
}
|
||||
|
||||
|
||||
@ -393,7 +364,7 @@ net_server_select(void *cookie, uint8 event, uint32 ref, selectsync *sync)
|
||||
|
||||
// Tell the net_server to notify event(s) for this socket
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.notify_port = g_socket_event_listener_port;
|
||||
args.notify_port = sSocketEventPort;
|
||||
args.cookie = cookie;;
|
||||
|
||||
return execute_command(nsc, NET_STACK_NOTIFY_SOCKET_EVENT, &args, sizeof(args));
|
||||
@ -484,7 +455,7 @@ static int32 socket_event_listener(void *data)
|
||||
ssize_t bytes;
|
||||
|
||||
while(true) {
|
||||
bytes = read_port(g_socket_event_listener_port, &msg, &sed, sizeof(sed));
|
||||
bytes = read_port(sSocketEventPort, &msg, &sed, sizeof(sed));
|
||||
if (bytes < B_OK)
|
||||
return bytes;
|
||||
|
||||
@ -775,11 +746,11 @@ init_connection(void **cookie)
|
||||
}
|
||||
set_port_owner(nsc->local_port, B_SYSTEM_TEAM);
|
||||
|
||||
bytes = write_port(g_stack_port, NET_STACK_NEW_CONNECTION, &nsc->local_port, sizeof(port_id));
|
||||
bytes = write_port(sUserlandPort, NET_STACK_NEW_CONNECTION, &nsc->local_port, sizeof(port_id));
|
||||
if (bytes == B_BAD_PORT_ID) {
|
||||
g_stack_port = find_port(NET_STACK_PORTNAME);
|
||||
PRINT(("try to get net_server's port id: %ld\n", g_stack_port));
|
||||
bytes = write_port(g_stack_port, NET_STACK_NEW_CONNECTION, &nsc->local_port, sizeof(port_id));
|
||||
sUserlandPort = find_port(NET_STACK_PORTNAME);
|
||||
PRINT(("try to get net_server's port id: %ld\n", sUserlandPort));
|
||||
bytes = write_port(sUserlandPort, NET_STACK_NEW_CONNECTION, &nsc->local_port, sizeof(port_id));
|
||||
}
|
||||
if (bytes < B_OK) {
|
||||
FATAL(("open: couldn't contact stack: %s\n",strerror(bytes)));
|
||||
@ -861,5 +832,3 @@ shutdown_connection(net_server_cookie *nsc)
|
||||
free(nsc);
|
||||
}
|
||||
|
||||
#endif // #ifndef _KERNEL_MODE
|
||||
|
@ -1,6 +1,6 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel network core ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network interfaces ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network devices ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network stack ;
|
||||
|
@ -1,40 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network core ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||
# Needed for <support/Errors.h> and maybe other stuff.
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
KernelAddon core : kernel obos_network :
|
||||
cksum.c
|
||||
core.c
|
||||
if.c
|
||||
ifq.c
|
||||
in.c
|
||||
inpcb.c
|
||||
mbuf.c
|
||||
misc.c
|
||||
net_timer.c
|
||||
nhash.c
|
||||
pools.c
|
||||
radix.c
|
||||
route.c
|
||||
sockbuf.c
|
||||
socket.c
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/obos_network
|
||||
: core ;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
core :
|
||||
boot home config add-ons kernel obos_network ;
|
@ -1,123 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#define printf dprintf
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <mbuf.h>
|
||||
|
||||
/* This from Stevens Vol.2 */
|
||||
#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);}
|
||||
|
||||
uint16 in_cksum(struct mbuf *m, int len, int off)
|
||||
{
|
||||
uint16 *w;
|
||||
int sum = 0;
|
||||
int mlen = 0;
|
||||
int byte_swapped = 0;
|
||||
struct mbuf *orig_m = m;
|
||||
|
||||
union {
|
||||
uint8 c[2];
|
||||
uint16 s;
|
||||
} s_util;
|
||||
union {
|
||||
uint16 s[2];
|
||||
uint32 l;
|
||||
} l_util;
|
||||
|
||||
if (off) {
|
||||
m->m_len -= off;
|
||||
m->m_data += off;
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len -= off;
|
||||
}
|
||||
|
||||
for (; m && len; m=m->m_next) {
|
||||
if (m->m_len == 0)
|
||||
continue;
|
||||
w = mtod(m, uint16 *);
|
||||
if (mlen == -1) {
|
||||
/* first byte is a continuation of
|
||||
* a 16 bit word spanning this mbuf
|
||||
* and the previous one.
|
||||
*
|
||||
* s_util.c[0] is already saved.
|
||||
*/
|
||||
s_util.c[1] = *(char*)w;
|
||||
sum += s_util.s;
|
||||
w = (uint16*) ((char*) w + 1);
|
||||
mlen = m->m_len - 1;
|
||||
len--;
|
||||
} else
|
||||
mlen = m->m_len;
|
||||
if (len < mlen)
|
||||
mlen = len;
|
||||
len -= mlen;
|
||||
/* force to even boundry */
|
||||
if ((1 & (int)w) && (mlen > 0)) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
s_util.c[0] = *(char*)w;
|
||||
w = (uint16*)((char*)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] = *(char*)w;
|
||||
sum += s_util.s;
|
||||
mlen = 0;
|
||||
} else
|
||||
mlen = -1;
|
||||
} else if (mlen == -1)
|
||||
s_util.c[0] = *(char*)w;
|
||||
}
|
||||
if (len)
|
||||
printf("cksum: out of data!\n");
|
||||
if (mlen == -1) {
|
||||
/* last mbuf was an odd number of bytes! */
|
||||
s_util.c[1] = 0;
|
||||
sum += s_util.s;
|
||||
}
|
||||
REDUCE;
|
||||
|
||||
if (off) {
|
||||
orig_m->m_len += off;
|
||||
orig_m->m_data -= off;
|
||||
if (orig_m->m_flags & M_PKTHDR)
|
||||
orig_m->m_pkthdr.len += off;
|
||||
}
|
||||
return (uint16)(~sum & 0xffff);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,40 +0,0 @@
|
||||
#ifndef _CORE_PRIVATE__H
|
||||
#define _CORE_PRIVATE__H
|
||||
|
||||
|
||||
struct iovec;
|
||||
|
||||
enum uio_rw { UIO_READ, UIO_WRITE };
|
||||
|
||||
/* Segment flag values. */
|
||||
enum uio_seg {
|
||||
UIO_USERSPACE, /* from user data space */
|
||||
UIO_SYSSPACE /* from system space */
|
||||
};
|
||||
|
||||
struct uio {
|
||||
struct iovec *uio_iov; /* pointer to array of iovecs */
|
||||
int uio_iovcnt; /* number of iovecs in array */
|
||||
off_t uio_offset; /* offset into file this uio corresponds to */
|
||||
size_t uio_resid; /* residual i/o count */
|
||||
enum uio_seg uio_segflg; /* see above */
|
||||
enum uio_rw uio_rw; /* see above */
|
||||
// struct proc *uio_procp; /* process if UIO_USERSPACE */
|
||||
};
|
||||
|
||||
struct ifnet;
|
||||
|
||||
|
||||
int uiomove(char *cp, int n, struct uio *uio);
|
||||
|
||||
void in_if_detach(struct ifnet *ifp);
|
||||
// this removes all IP related references for this interface (route, address)
|
||||
|
||||
extern struct pool_ctl *mbpool;
|
||||
extern struct pool_ctl *clpool;
|
||||
|
||||
extern int max_hdr; /* largest link+protocol header */
|
||||
extern int max_linkhdr; /* largest link level header */
|
||||
extern int max_protohdr; /* largest protocol header */
|
||||
|
||||
#endif
|
@ -1,499 +0,0 @@
|
||||
/* if helper functions */
|
||||
|
||||
#include <kernel/OS.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#define printf dprintf
|
||||
#endif
|
||||
|
||||
#include "core_private.h"
|
||||
#include "netinet/in.h"
|
||||
#include "sys/socketvar.h"
|
||||
#include "net/if.h"
|
||||
#include "net/if_dl.h"
|
||||
#include "sys/sockio.h"
|
||||
#include "netinet/in_var.h"
|
||||
#include "net/route.h"
|
||||
#include "sys/protosw.h"
|
||||
|
||||
extern struct ifnet *devices;
|
||||
extern int ndevs;
|
||||
|
||||
/* Variables used outside this file */
|
||||
struct ifaddr **ifnet_addrs;
|
||||
|
||||
/* Private variables */
|
||||
static int if_index;
|
||||
static int if_indexlim;
|
||||
|
||||
void dump_sockaddr(void *ptr);
|
||||
void *protocol_address(struct ifnet *ifa, int family);
|
||||
|
||||
|
||||
static inline bool
|
||||
equal(struct sockaddr *addr1, struct sockaddr *addr2)
|
||||
{
|
||||
return !memcmp(addr1, addr2, addr1->sa_len);
|
||||
}
|
||||
|
||||
|
||||
struct ifnet *
|
||||
get_interfaces(void)
|
||||
{
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
if_init(void)
|
||||
{
|
||||
ifnet_addrs = NULL;
|
||||
if_index = 0;
|
||||
if_indexlim = 8; /* initial value */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ifioctl(struct socket *so, ulong cmd, caddr_t data)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifreq *ifr;
|
||||
|
||||
#if DEBUG
|
||||
printf("ifioctl(0x%lX)\n", cmd);
|
||||
#endif
|
||||
|
||||
if (cmd == SIOCGIFCONF)
|
||||
return (ifconf(cmd, data));
|
||||
|
||||
ifr = (struct ifreq*) data;
|
||||
ifp = ifunit(ifr->ifr_name);
|
||||
if (ifp == NULL)
|
||||
return ENXIO;
|
||||
|
||||
switch(cmd) {
|
||||
case SIOCGIFFLAGS:
|
||||
/* get interface flags */
|
||||
ifr->ifr_flags = ifp->if_flags;
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
/* get interface metric */
|
||||
ifr->ifr_metric = ifp->if_metric;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
/* get interface MTU */
|
||||
ifr->ifr_mtu = ifp->if_mtu;
|
||||
break;
|
||||
case SIOCSIFFLAGS:
|
||||
ifp->if_flags = ifr->ifr_flags;
|
||||
/* restart card with new settings... */
|
||||
break;
|
||||
case SIOCSIFMETRIC:
|
||||
/* set interface metric */
|
||||
ifp->if_metric = ifr->ifr_metric;
|
||||
break;
|
||||
default:
|
||||
#if DEBUG
|
||||
printf("ifioctl: Unknown cmd!\n");
|
||||
#endif
|
||||
if (so->so_proto == NULL)
|
||||
return EOPNOTSUPP;
|
||||
return (*so->so_proto->pr_userreq)(so, PRU_CONTROL,
|
||||
(struct mbuf*)cmd, (struct mbuf*)data, (struct mbuf*)ifp);
|
||||
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
printf("ifioctl: done\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct ifnet *
|
||||
ifunit(char *name)
|
||||
{
|
||||
struct ifnet *d = devices;
|
||||
|
||||
for (d=devices;d;d = d->if_next)
|
||||
if (strcmp(d->if_name, name) == 0)
|
||||
return d;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dump_sockaddr(void *ptr)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)ptr;
|
||||
uint8 *d = NULL;
|
||||
int i;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_LINK: {
|
||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *)ptr;
|
||||
if (sdl->sdl_type == IFT_ETHER) {
|
||||
printf("\t\tETHERNET: ");
|
||||
printf("Interface ");
|
||||
d = (unsigned char *)&sdl->sdl_data[0];
|
||||
for (i=0;i<sdl->sdl_nlen;i++, d++) {
|
||||
printf("%c", *d);
|
||||
}
|
||||
printf(" -> ");
|
||||
for (i=0;i<sdl->sdl_alen;i++, d++) {
|
||||
printf("%02x", *d);
|
||||
if (i< 5)
|
||||
printf(":");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)ptr;
|
||||
struct in_addr ho;
|
||||
ho.s_addr = sin->sin_addr.s_addr;
|
||||
printf("\t\tIPv4: ");
|
||||
d = (uint8*)&ho.s_addr;
|
||||
for (i=0;i<4;i++, d++) {
|
||||
printf("%d", *d);
|
||||
if (i < 3)
|
||||
printf(".");
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("Unknown type... %d\n", sa->sa_family);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
protocol_address(struct ifnet *ifa, int family)
|
||||
{
|
||||
struct ifaddr *a = ifa->if_addrlist;
|
||||
|
||||
for (; a != NULL; a = a->ifa_next) {
|
||||
if (a->ifa_addr->sa_family == family) {
|
||||
if (family == AF_INET) {
|
||||
return &((struct sockaddr_in*)a->ifa_addr)->sin_addr;
|
||||
} else {
|
||||
return &a->ifa_addr->sa_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find an interface address specific to an interface best matching
|
||||
* a given address.
|
||||
*/
|
||||
struct ifaddr *
|
||||
ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
char *cp, *cp2, *cp3;
|
||||
char *cplim;
|
||||
struct ifaddr *ifa_maybe = 0;
|
||||
uint af = addr->sa_family;
|
||||
|
||||
if (af >= AF_MAX)
|
||||
return (NULL);
|
||||
|
||||
for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_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 = (char *)addr->sa_data;
|
||||
cp2 = (char *)ifa->ifa_addr->sa_data;
|
||||
cp3 = (char *)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);
|
||||
}
|
||||
|
||||
|
||||
struct ifaddr *
|
||||
ifa_ifwithdstaddr(struct sockaddr *addr)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
|
||||
for (ifp = devices; ifp != NULL; ifp = ifp->if_next)
|
||||
if (ifp->if_flags & IFF_POINTOPOINT)
|
||||
for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_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);
|
||||
}
|
||||
|
||||
|
||||
struct ifaddr *
|
||||
ifa_ifwithaddr(struct sockaddr *addr)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
|
||||
for (ifp = devices; ifp != NULL; ifp = ifp->if_next) {
|
||||
for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_addr))
|
||||
return (ifa);
|
||||
if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
|
||||
/* IPv6 doesn't have broadcast */
|
||||
ifa->ifa_broadaddr->sa_len != 0 &&
|
||||
equal(ifa->ifa_broadaddr, addr))
|
||||
return (ifa);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find an interface on a specific network. If many, choice
|
||||
* is most specific found.
|
||||
*/
|
||||
|
||||
struct ifaddr *
|
||||
ifa_ifwithnet(struct sockaddr *addr)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
struct ifaddr *ifa_maybe = NULL;
|
||||
uint af = addr->sa_family;
|
||||
char *addr_data = (char *)addr->sa_data, *cplim;
|
||||
|
||||
if (af == AF_LINK) {
|
||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
|
||||
if (sdl->sdl_index && sdl->sdl_index <= ndevs)
|
||||
return (ifnet_addrs[sdl->sdl_index]);
|
||||
}
|
||||
for (ifp = devices; ifp != NULL; ifp = ifp->if_next)
|
||||
for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
register char *cp, *cp2, *cp3;
|
||||
|
||||
if (ifa->ifa_addr->sa_family != af ||
|
||||
ifa->ifa_netmask == 0)
|
||||
next:
|
||||
continue;
|
||||
cp = addr_data;
|
||||
cp2 = (char *)ifa->ifa_addr->sa_data;
|
||||
cp3 = (char *)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);
|
||||
}
|
||||
|
||||
/* XXX - we have a memory leak here! When we clean up we need to free the memory
|
||||
* that is malloc'd here
|
||||
*/
|
||||
void if_attach(struct ifnet *ifp)
|
||||
{
|
||||
uint socksize, ifasize;
|
||||
int namelen, masklen;
|
||||
struct ifnet **p = &devices;
|
||||
struct sockaddr_dl *sdl;
|
||||
struct ifaddr *ifa;
|
||||
char dname[IFNAMSIZ];
|
||||
|
||||
if (!ifp)
|
||||
return;
|
||||
|
||||
sprintf(dname, "%s%d", ifp->name, ifp->if_unit);
|
||||
ifp->if_name = strdup(dname);
|
||||
|
||||
while (*p)
|
||||
p = &((*p)->if_next);
|
||||
|
||||
*p = ifp;
|
||||
ifp->if_index = ++if_index; /* atomic add ? */
|
||||
|
||||
/* allocate memory for ifnet_addrs if required... */
|
||||
if (ifnet_addrs == NULL || if_index >= if_indexlim) {
|
||||
uint n = (if_indexlim <<= 1) * sizeof(*ifa);
|
||||
struct ifaddr **q = (struct ifaddr**)malloc(n);
|
||||
if (ifnet_addrs) {
|
||||
memcpy((caddr_t)q, (caddr_t)ifnet_addrs, n / 2);
|
||||
free(ifnet_addrs);
|
||||
}
|
||||
ifnet_addrs = q;
|
||||
}
|
||||
|
||||
/* get the unit # as a string */
|
||||
namelen = strlen(ifp->if_name);
|
||||
|
||||
/* memory: we need to allocate enough memory for the following...
|
||||
* struct ifaddr
|
||||
* struct sockaddr_dl that will hold the link level address and name
|
||||
* struct sockaddr_dl that will hold the mask
|
||||
*/
|
||||
|
||||
#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(int32) -1)))
|
||||
socksize = ROUNDUP(socksize);
|
||||
|
||||
if (socksize < sizeof(*sdl))
|
||||
socksize = sizeof(*sdl);
|
||||
ifasize = sizeof(*ifa) + 2 * socksize;
|
||||
if ((ifa = (struct ifaddr*)malloc(ifasize))) {
|
||||
memset(ifa, 0, ifasize);
|
||||
|
||||
sdl = (struct sockaddr_dl *)(ifa + 1);
|
||||
sdl->sdl_len = socksize;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
memcpy(&sdl->sdl_data, ifp->if_name, namelen);
|
||||
sdl->sdl_nlen = namelen;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = ifp->if_type;
|
||||
ifnet_addrs[if_index - 1] = ifa;
|
||||
ifa->ifa_ifp = ifp;
|
||||
ifa->ifa_next = ifp->if_addrlist;
|
||||
ifp->if_addrlist = ifa;
|
||||
ifa->ifa_addr = (struct sockaddr*)sdl;
|
||||
|
||||
/* now do mask... */
|
||||
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
|
||||
ifa->ifa_netmask = (struct sockaddr*)sdl;
|
||||
sdl->sdl_len = masklen;
|
||||
/* build the mask */
|
||||
while (namelen != 0)
|
||||
sdl->sdl_data[--namelen] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void if_detach(struct ifnet *ifp)
|
||||
{
|
||||
struct ifnet *p = devices, *q = NULL;
|
||||
int32 index;
|
||||
bool found = false;
|
||||
|
||||
for(; p && p != ifp; p = p->if_next)
|
||||
q = p;
|
||||
|
||||
if(!p)
|
||||
return;
|
||||
|
||||
// XXX: this is a hack, but we don't want to invest too much work into this stack
|
||||
in_if_detach(ifp);
|
||||
// this should also remove all remaining routes
|
||||
|
||||
// remove the ifa entry from ifnet_addrs and reduce all following ifnet indices
|
||||
for(index = 0; index < if_index; index++) {
|
||||
if(found) {
|
||||
--ifnet_addrs[index]->ifa_ifp->if_index;
|
||||
ifnet_addrs[index - 1] = ifnet_addrs[index];
|
||||
}
|
||||
|
||||
if(ifnet_addrs[index]->ifa_ifp == ifp) {
|
||||
found = true;
|
||||
free(ifnet_addrs[index]);
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
--if_index;
|
||||
|
||||
if(q)
|
||||
q->if_next = p->if_next;
|
||||
else
|
||||
devices = p->if_next;
|
||||
|
||||
free(p->if_name);
|
||||
}
|
||||
|
||||
/* XXX - memcpy used as copyin / copyout not available. I did look
|
||||
* for the source for them but was unable to find them in the
|
||||
* code jungle that is OpenBSD and FreeBSD!
|
||||
*
|
||||
* copyin / copyout should maybe be added if they'd add a speed improvement as
|
||||
* they're used in a lot of other places as well
|
||||
*/
|
||||
int ifconf(int cmd, caddr_t data)
|
||||
{
|
||||
struct ifconf *ifc = (struct ifconf*)data;
|
||||
struct ifnet *ifp = devices;
|
||||
struct ifaddr *ifa = NULL;
|
||||
char *cp, *ep;
|
||||
struct ifreq ifr, *ifrp;
|
||||
int space = ifc->ifc_len; /* how big the buffer is */
|
||||
void *copyptr = NULL;
|
||||
|
||||
ifrp = ifc->ifc_req;
|
||||
ep = ifr.ifr_name + sizeof(ifr.ifr_name) - 2;
|
||||
|
||||
for (; space > (int) sizeof(ifr) && ifp; ifp = ifp->if_next) {
|
||||
strncpy(ifr.ifr_name, ifp->if_name, sizeof(ifr.ifr_name) - 2);
|
||||
for (cp = ifr.ifr_name;cp < ep && *cp; cp++)
|
||||
continue;
|
||||
*cp = '\0';
|
||||
if ((ifa = ifp->if_addrlist) == NULL) {
|
||||
memset((caddr_t)&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
|
||||
copyptr = memcpy((caddr_t) ifrp, (caddr_t) &ifr, sizeof(ifr));
|
||||
if (copyptr == NULL)
|
||||
break;
|
||||
space -= sizeof(ifr), ifrp++;
|
||||
} else {
|
||||
for (; space > (int) sizeof(ifr) && ifa; ifa = ifa->ifa_next) {
|
||||
struct sockaddr *sa = ifa->ifa_addr;
|
||||
if (sa->sa_len <= sizeof(*sa)) {
|
||||
printf("sa->sa_len = %d compared to %ld, sa->sa_family = %d\n",
|
||||
sa->sa_len, sizeof(*sa), sa->sa_family);
|
||||
|
||||
ifr.ifr_addr = *sa;
|
||||
copyptr = memcpy((caddr_t)ifrp, (caddr_t)&ifr, sizeof(ifr));
|
||||
ifrp++;
|
||||
} else {
|
||||
space -= sa->sa_len - sizeof(*sa);
|
||||
if (space < (int) sizeof(ifr))
|
||||
break;
|
||||
copyptr = memcpy((caddr_t)ifrp, (caddr_t)&ifr, sizeof(ifr.ifr_name));
|
||||
if (copyptr != NULL)
|
||||
copyptr = memcpy((caddr_t)&ifrp->ifr_addr, (caddr_t)sa, sa->sa_len);
|
||||
ifrp = (struct ifreq*)(sa->sa_len + (caddr_t)&ifrp->ifr_addr);
|
||||
}
|
||||
if (copyptr == NULL)
|
||||
break;
|
||||
space -= sizeof(ifr);
|
||||
}
|
||||
}
|
||||
}
|
||||
ifc->ifc_len -= space;
|
||||
/* Yuck! */
|
||||
return (copyptr == NULL ? -1 : 0);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/* some misc functions... */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <mbuf.h>
|
||||
|
||||
struct ifq *start_ifq(void)
|
||||
{
|
||||
struct ifq *nifq = (struct ifq*)malloc(sizeof(*nifq));
|
||||
|
||||
if (!nifq)
|
||||
return NULL;
|
||||
|
||||
memset(nifq, 0, sizeof(*nifq));
|
||||
|
||||
nifq->lock = create_sem(1, "ifq_lock");
|
||||
nifq->pop = create_sem(0, "ifq_pop");
|
||||
#ifdef _KERNEL_MODE
|
||||
set_sem_owner(nifq->lock, B_SYSTEM_TEAM);
|
||||
set_sem_owner(nifq->pop, B_SYSTEM_TEAM);
|
||||
#endif
|
||||
|
||||
if (nifq->lock < B_OK || nifq->pop < B_OK)
|
||||
return NULL;
|
||||
|
||||
nifq->len = 0;
|
||||
nifq->maxlen = 50;
|
||||
nifq->head = nifq->tail = NULL;
|
||||
return nifq;
|
||||
}
|
||||
|
||||
void stop_ifq(struct ifq *q)
|
||||
{
|
||||
struct mbuf *m = NULL;
|
||||
|
||||
acquire_sem_etc(q->lock, 1, B_CAN_INTERRUPT, 0);
|
||||
while (q->head) {
|
||||
m = q->head;
|
||||
q->head = m->m_nextpkt;
|
||||
m->m_nextpkt = NULL;
|
||||
m_freem(m);
|
||||
}
|
||||
q->len = 0;
|
||||
delete_sem(q->pop);
|
||||
release_sem_etc(q->lock, 1, B_CAN_INTERRUPT);
|
||||
delete_sem(q->lock);
|
||||
free(q);
|
||||
}
|
@ -1,537 +0,0 @@
|
||||
/* in.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include "core_private.h"
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#define printf dprintf
|
||||
#endif
|
||||
|
||||
extern struct ifnet **ifnet_addrs;
|
||||
|
||||
struct in_ifaddr *in_ifaddr = NULL; //XXX is this ever initialized correctly?
|
||||
|
||||
struct in_ifaddr *get_primary_addr(void)
|
||||
{
|
||||
return in_ifaddr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Trim a mask in a sockaddr
|
||||
*/
|
||||
void in_socktrim(struct sockaddr_in *ap)
|
||||
{
|
||||
char *cplim = (char *) &ap->sin_addr;
|
||||
char *cp = (char *) (&ap->sin_addr + 1);
|
||||
|
||||
ap->sin_len = 0;
|
||||
while (--cp >= cplim)
|
||||
if (*cp) {
|
||||
(ap)->sin_len = cp - (char *) (ap) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define rtinitflags(x) \
|
||||
((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
|
||||
? RTF_HOST : 0)
|
||||
|
||||
void
|
||||
in_if_detach(struct ifnet *ifp)
|
||||
{
|
||||
// remove all references to this ifnet
|
||||
struct in_ifaddr *ia = NULL, *previous = NULL;
|
||||
struct ifaddr *ifa;
|
||||
|
||||
if(!ifp || !in_ifaddr)
|
||||
return;
|
||||
|
||||
if(in_ifaddr->ia_ifp == ifp)
|
||||
ia = in_ifaddr;
|
||||
else {
|
||||
for(previous = in_ifaddr; previous && previous->ia_next;
|
||||
previous = previous->ia_next)
|
||||
if(previous->ia_next->ia_ifp == ifp) {
|
||||
ia = previous->ia_next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ia)
|
||||
return;
|
||||
|
||||
if(rtinit(&(ia->ia_ifa), RTM_DELETE, rtinitflags(ia)))
|
||||
printf("core.c.: in_if_detach(): Could not delete route!\n");
|
||||
|
||||
if(ifp->if_addrlist) {
|
||||
ifa = ifp->if_addrlist;
|
||||
if(ifa->ifa_addr->sa_family == AF_INET)
|
||||
ifp->if_addrlist = ifa->ifa_next;
|
||||
else
|
||||
for(; ifa; ifa = ifa->ifa_next)
|
||||
if(ifa->ifa_next && ifa->ifa_next->ifa_addr->sa_family == AF_INET) {
|
||||
struct ifaddr *tmp = ifa;
|
||||
ifa = ifa->ifa_next;
|
||||
tmp->ifa_next = ifa->ifa_next;
|
||||
}
|
||||
|
||||
if(ifa)
|
||||
free(ifa);
|
||||
}
|
||||
|
||||
if(previous)
|
||||
previous->ia_next = ia->ia_next;
|
||||
else
|
||||
in_ifaddr = ia->ia_next;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove a route to prefix ("connected route" in cisco terminology).
|
||||
* re-installs the route by using another interface address, if there's one
|
||||
* with the same prefix (otherwise we lose the route mistakenly).
|
||||
*/
|
||||
static int in_scrubprefix(struct in_ifaddr *target)
|
||||
{
|
||||
struct in_ifaddr *ia;
|
||||
struct in_addr prefix, mask, p;
|
||||
int error;
|
||||
|
||||
if ((target->ia_flags & IFA_ROUTE) == 0)
|
||||
return 0;
|
||||
|
||||
if (rtinitflags(target))
|
||||
prefix = target->ia_dstaddr.sin_addr;
|
||||
else
|
||||
prefix = target->ia_addr.sin_addr;
|
||||
mask = target->ia_sockmask.sin_addr;
|
||||
prefix.s_addr &= mask.s_addr;
|
||||
|
||||
for (ia = in_ifaddr; ia; ia = ia->ia_next) {
|
||||
/* easy one first */
|
||||
if (mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
|
||||
continue;
|
||||
|
||||
if (rtinitflags(ia))
|
||||
p = ia->ia_dstaddr.sin_addr;
|
||||
else
|
||||
p = ia->ia_addr.sin_addr;
|
||||
p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
|
||||
if (prefix.s_addr != p.s_addr)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* if we got a matching prefix route, move IFA_ROUTE to him
|
||||
*/
|
||||
if ((ia->ia_flags & IFA_ROUTE) == 0) {
|
||||
rtinit(&(target->ia_ifa), (int)RTM_DELETE,
|
||||
rtinitflags(target));
|
||||
target->ia_flags &= ~IFA_ROUTE;
|
||||
|
||||
error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
|
||||
rtinitflags(ia) | RTF_UP);
|
||||
if (error == 0)
|
||||
ia->ia_flags |= IFA_ROUTE;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* noone seem to have prefix route. remove it.
|
||||
*/
|
||||
rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
|
||||
target->ia_flags &= ~IFA_ROUTE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef rtinitflags
|
||||
|
||||
int in_ifinit(struct ifnet *dev, struct in_ifaddr *ia, struct sockaddr_in *sin,
|
||||
int scrub)
|
||||
{
|
||||
uint32 i = sin->sin_addr.s_addr;
|
||||
struct sockaddr_in oldsin;
|
||||
int error;
|
||||
int flags = RTF_UP;
|
||||
|
||||
oldsin = ia->ia_addr;
|
||||
ia->ia_addr = *sin;
|
||||
|
||||
if (dev && dev->ioctl) {
|
||||
error = (*dev->ioctl)(dev, SIOCSIFADDR, (caddr_t)ia);
|
||||
if (error) {
|
||||
ia->ia_addr = oldsin;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->if_type == IFT_ETHER) {
|
||||
ia->ia_ifa.ifa_flags |= RTF_CLONING;
|
||||
}
|
||||
|
||||
if (scrub) {
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr*)&oldsin;
|
||||
in_scrubprefix(ia);
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr*)&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;
|
||||
|
||||
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);
|
||||
|
||||
ia->ia_ifa.ifa_metric = dev->if_metric;
|
||||
if (dev->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 (dev->if_flags & IFF_LOOPBACK) {
|
||||
ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
|
||||
flags |= RTF_HOST;
|
||||
} else if (dev->if_flags & IFF_POINTOPOINT) {
|
||||
if (ia->ia_dstaddr.sin_family != AF_INET)
|
||||
return 0;
|
||||
flags |= RTF_HOST;
|
||||
}
|
||||
|
||||
/* This is really useful debugging code, but not needed at the moment... */
|
||||
#if 0
|
||||
printf("in_ifaddr:\n");
|
||||
printf(" : ia_net : %08lx\n", ia->ia_net);
|
||||
printf(" : ia_netmask : %08lx\n", ia->ia_netmask);
|
||||
printf(" : ia_subnet : %08lx\n", ia->ia_subnet);
|
||||
printf(" : ia_subnetmask : %08lx\n", ia->ia_subnetmask);
|
||||
printf(" : ia_netbroadcast : %08lx\n", ia->ia_netbroadcast.s_addr);
|
||||
printf(" : ia_addr : %08lx\n", ia->ia_addr.sin_addr.s_addr);
|
||||
printf(" : ia_dstaddr : %08lx\n", ia->ia_dstaddr.sin_addr.s_addr);
|
||||
printf(" : ia_sockmask : %08lx\n", ia->ia_sockmask.sin_addr.s_addr);
|
||||
#endif
|
||||
|
||||
error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags);
|
||||
if (error == 0)
|
||||
ia->ia_flags |= IFA_ROUTE;
|
||||
|
||||
/* XXX - Multicast address list */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int in_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp)
|
||||
{
|
||||
struct ifreq *ifr = (struct ifreq*)data;
|
||||
struct in_ifaddr *ia = NULL;
|
||||
struct ifaddr *ifa;
|
||||
struct in_ifaddr *oia;
|
||||
struct in_aliasreq *ifra = (struct in_aliasreq*)data;
|
||||
struct sockaddr_in oldaddr;
|
||||
int error = 0, hostIsNew, maskIsNew;
|
||||
long i;
|
||||
|
||||
if (ifp) /* we need to find the in_ifaddr */
|
||||
for (ia = in_ifaddr; ia; ia = ia->ia_next)
|
||||
if (ia->ia_ifp == ifp)
|
||||
break;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCAIFADDR:
|
||||
printf("SIOCAIFADDR\n");
|
||||
/* add an address */
|
||||
case SIOCDIFADDR:
|
||||
printf("SIODIFADDR\n");
|
||||
/* delete an address */
|
||||
if (ifra->ifra_addr.sin_family == AF_INET)
|
||||
for (oia = ia; ia; ia = ia->ia_next) {
|
||||
if (ia->ia_ifp == ifp &&
|
||||
ia->ia_addr.sin_addr.s_addr == ifra->ifra_addr.sin_addr.s_addr)
|
||||
break;
|
||||
}
|
||||
if (cmd == (int) SIOCDIFADDR && ia == NULL)
|
||||
return EADDRNOTAVAIL;
|
||||
case SIOCSIFADDR:
|
||||
printf("SIOCSIFADDR\n");
|
||||
/* set an address */
|
||||
case SIOCSIFNETMASK:
|
||||
printf("SIOCSIFNETMASK #1 (%d)\n", cmd);
|
||||
/* set a net mask */
|
||||
case SIOCSIFDSTADDR:
|
||||
/* set the destination address of a point to point link */
|
||||
if (!ifp) {
|
||||
printf("No interface pointer!\n");
|
||||
return EINVAL;
|
||||
}
|
||||
if (ia == NULL) {
|
||||
oia = (struct in_ifaddr*)malloc(sizeof(struct in_ifaddr));
|
||||
if (oia == NULL)
|
||||
return ENOMEM;
|
||||
memset(oia, 0, sizeof(*oia));
|
||||
if ((ia = in_ifaddr)) {
|
||||
/* we've got other structures - add at end */
|
||||
for (; ia->ia_next; ia = ia->ia_next)
|
||||
continue;
|
||||
ia->ia_next = oia;
|
||||
} else
|
||||
in_ifaddr = oia;
|
||||
|
||||
ia = oia;
|
||||
if ((ifa = ifp->if_addrlist)) {
|
||||
for (; ifa->ifa_next; ifa = ifa->ifa_next)
|
||||
continue;
|
||||
ifa->ifa_next = (struct ifaddr*)ia;
|
||||
} else
|
||||
ifp->if_addrlist = (struct ifaddr*)ia;
|
||||
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr*) &ia->ia_addr;
|
||||
ia->ia_ifa.ifa_dstaddr = (struct sockaddr*) &ia->ia_dstaddr;
|
||||
ia->ia_ifa.ifa_netmask = (struct sockaddr*) &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;
|
||||
}
|
||||
break;
|
||||
case SIOCSIFBRDADDR:
|
||||
case SIOCGIFADDR:
|
||||
case SIOCGIFNETMASK:
|
||||
case SIOCGIFDSTADDR:
|
||||
case SIOCGIFBRDADDR:
|
||||
if (ia == NULL)
|
||||
return EADDRNOTAVAIL;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
printf("loop #2 : %d [%ld]\n", cmd, SIOCSIFNETMASK);
|
||||
|
||||
switch(cmd) {
|
||||
case SIOCGIFADDR:
|
||||
/* get interface address */
|
||||
*((struct sockaddr_in*) &ifr->ifr_addr) = ia->ia_addr;
|
||||
break;
|
||||
case SIOCGIFDSTADDR:
|
||||
/* get interface point to point destination address */
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
|
||||
/* we're not a point to point interface */
|
||||
return EINVAL;
|
||||
*((struct sockaddr_in*) &ifr->ifr_dstaddr) = ia->ia_dstaddr;
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
/* get interface broadcast address */
|
||||
if ((ifp->if_flags & IFF_BROADCAST) == 0)
|
||||
/* we're not a broadcast capable interface */
|
||||
return EINVAL;
|
||||
*((struct sockaddr_in*) &ifr->ifr_dstaddr) = ia->ia_broadaddr;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
/* get interface netmask */
|
||||
*((struct sockaddr_in*) &ifr->ifr_addr) = ia->ia_sockmask;
|
||||
break;
|
||||
case SIOCSIFADDR:
|
||||
printf("SIOCSIFADDR #2\n");
|
||||
return in_ifinit(ifp, ia, (struct sockaddr_in*)&ifr->ifr_addr, 1);
|
||||
case SIOCSIFNETMASK:
|
||||
printf("Setting netmask\n");
|
||||
/* set the netmask for the interface... */
|
||||
/* set i to the network netmask (network host order) */
|
||||
i = ifra->ifra_addr.sin_addr.s_addr;
|
||||
/* set the host byte order netmask into ia_subnetmask */
|
||||
ia->ia_subnetmask = ntohl((ia->ia_sockmask.sin_addr.s_addr = i));
|
||||
printf("ia->ia_subnetmask: %08lx\n", ia->ia_subnetmask);
|
||||
break;
|
||||
case SIOCSIFDSTADDR:
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
|
||||
return EINVAL;
|
||||
oldaddr = ia->ia_dstaddr;
|
||||
ia->ia_dstaddr = *(struct sockaddr_in*)&ifr->ifr_dstaddr;
|
||||
/* update the interface if required */
|
||||
if (ifp->ioctl) {
|
||||
error = ifp->ioctl(ifp, SIOCSIFDSTADDR, (caddr_t) ia);
|
||||
if (error) {
|
||||
ia->ia_dstaddr = oldaddr;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
/* change the routing info if it's been set */
|
||||
if (ia->ia_flags & IFA_ROUTE) {
|
||||
ia->ia_ifa.ifa_dstaddr = (struct sockaddr*)&oldaddr;
|
||||
rtinit(&(ia->ia_ifa), RTM_DELETE, RTF_HOST);
|
||||
ia->ia_ifa.ifa_dstaddr = (struct sockaddr*)&ia->ia_dstaddr;
|
||||
rtinit(&(ia->ia_ifa), RTM_ADD, RTF_HOST|RTF_UP);
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCSIFBRDADDR:
|
||||
/* set the broadcast address if interface supports it */
|
||||
if ((ifp->if_flags & IFF_BROADCAST) == 0)
|
||||
/* we don't support broadcast on that interface */
|
||||
return EINVAL;
|
||||
ia->ia_broadaddr = *(struct sockaddr_in*) &ifr->ifr_broadaddr;
|
||||
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_scrubprefix(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_scrubprefix(ia);
|
||||
ia->ia_dstaddr = ifra->ifra_dstaddr;
|
||||
maskIsNew = 1;
|
||||
}
|
||||
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;
|
||||
default:
|
||||
printf("2nd iteration: default (%d)\n", cmd);
|
||||
/* if we don't have enough to do the default, return */
|
||||
if (ifp == NULL || ifp->ioctl == NULL)
|
||||
return EINVAL; /* XXX - should be EOPNOTSUPP */
|
||||
/* send to the card and let it process it */
|
||||
return ifp->ioctl(ifp, cmd, data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return 1 if the address might be a local broadcast address.
|
||||
*/
|
||||
int in_broadcast(struct in_addr in, struct ifnet *ifp)
|
||||
{
|
||||
struct ifnet *ifn, *if_first, *if_target;
|
||||
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_addrs;
|
||||
if_target = 0;
|
||||
} else {
|
||||
if_first = ifp;
|
||||
if_target = ifp->if_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_next) {
|
||||
for (ifa = ifn->if_addrlist; ifa; ifa = ifa->ifa_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
|
||||
}
|
||||
|
||||
#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(struct in_addr in)
|
||||
{
|
||||
struct in_ifaddr *ia;
|
||||
|
||||
if (subnetsarelocal) {
|
||||
for (ia = in_ifaddr; ia != 0; ia = ia->ia_next)
|
||||
if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
|
||||
return (1);
|
||||
} else {
|
||||
for (ia = in_ifaddr; ia != 0; ia = ia->ia_next)
|
||||
if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int in_canforward(struct in_addr in)
|
||||
{
|
||||
uint32 i = ntohl(in.s_addr);
|
||||
uint32 net;
|
||||
|
||||
if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
|
||||
return 0;
|
||||
if (IN_CLASSA(i)) {
|
||||
net = i & IN_CLASSA_NET;
|
||||
if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,469 +0,0 @@
|
||||
/* inpcb.c
|
||||
*
|
||||
* implementation of internet control blocks code
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#define printf dprintf
|
||||
#endif
|
||||
|
||||
#include "pools.h"
|
||||
#include "sys/socketvar.h"
|
||||
#include "netinet/in.h"
|
||||
#include "netinet/in_pcb.h"
|
||||
#include "net/if.h"
|
||||
#include "netinet/in_var.h"
|
||||
#include "sys/protosw.h"
|
||||
#include <net_misc.h>
|
||||
|
||||
extern struct in_ifaddr *in_ifaddr;
|
||||
|
||||
static struct pool_ctl *pcbpool = NULL;
|
||||
static struct in_addr zeroin_addr;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
int inpcb_init(void)
|
||||
{
|
||||
in_ifaddr = NULL;
|
||||
|
||||
if (!pcbpool)
|
||||
pool_init(&pcbpool, sizeof(struct inpcb));
|
||||
|
||||
if (!pcbpool) {
|
||||
printf("inpcb_init: ENOMEM\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
zeroin_addr.s_addr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int in_pcballoc(struct socket *so, struct inpcb *head)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
inp = (struct inpcb *)pool_get(pcbpool);
|
||||
|
||||
if (!inp) {
|
||||
printf("in_pcballoc: ENOMEM\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
memset(inp, 0, sizeof(*inp));
|
||||
|
||||
inp->inp_head = head;
|
||||
/* associate ourselves with the socket */
|
||||
inp->inp_socket = so;
|
||||
insque(inp, head);
|
||||
so->so_pcb = (caddr_t)inp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void in_pcbdetach(struct inpcb *inp)
|
||||
{
|
||||
struct socket *so = inp->inp_socket;
|
||||
|
||||
so->so_pcb = NULL;
|
||||
/* BSD sockets would call sofree here - we can't.
|
||||
* The first thing that sofree does in BSD is check whether
|
||||
* there are still file system references to the socket
|
||||
* (SS_NOFDREF) and if there are it doesn't free. We don't have
|
||||
* the same relationship to our sockets, as we use the socket for
|
||||
* the kernel cookie, and freeing it here would lead to real problems,
|
||||
* so we leave the socket until we call socket_close()
|
||||
* This may need to be reviewed and an extra layer of abstraction
|
||||
* added at some point if we find it's using too much system resource.
|
||||
*/
|
||||
|
||||
if (inp->inp_options)
|
||||
m_free(inp->inp_options);
|
||||
if (inp->inp_route.ro_rt)
|
||||
rtfree(inp->inp_route.ro_rt);
|
||||
|
||||
remque(inp);
|
||||
pool_put(pcbpool, inp);
|
||||
}
|
||||
|
||||
int in_pcbbind(struct inpcb *inp, struct mbuf *nam)
|
||||
{
|
||||
struct socket *so = inp->inp_socket;
|
||||
struct inpcb *head = inp->inp_head;
|
||||
struct sockaddr_in *sin;
|
||||
uint16 lport = 0;
|
||||
int wild = 0;
|
||||
int reuseport = (so->so_options & SO_REUSEPORT);
|
||||
|
||||
if (inp->lport || inp->laddr.s_addr != INADDR_ANY) {
|
||||
printf("in_pcbbind: EINVAL (%08lx:%d)\n", inp->laddr.s_addr, inp->lport);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* XXX - yuck! Try to format this better */
|
||||
/* This basically checks all the options that might be set that allow
|
||||
* us to use wildcard searches.
|
||||
*/
|
||||
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)) {
|
||||
printf("in_pcbind: EINVAL (m_len = %ld vs %ld)\n",
|
||||
nam->m_len, sizeof(*sin));
|
||||
/* whoops, too much data! */
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Apparently this may not be correctly
|
||||
* in older programs, so this may need
|
||||
* to be commented out...
|
||||
*/
|
||||
if (sin->sin_family != AF_INET) {
|
||||
printf("in_pcbbind: EAFNOSUPPORT\n");
|
||||
return EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
lport = sin->sin_port;
|
||||
|
||||
if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
|
||||
/* need special case for multicast. We'll
|
||||
* allow the complete binding to be duplicated if
|
||||
* SO_REUSEPORT is set, or if we have
|
||||
* SO_REUSEADDR set and both sockets have
|
||||
* a multicast address bound.
|
||||
* We'll exit with the reuseport variable set
|
||||
* correctly.
|
||||
*/
|
||||
if (so->so_options & SO_REUSEADDR)
|
||||
reuseport = SO_REUSEADDR | SO_REUSEPORT;
|
||||
} else if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||
sin->sin_port = 0; /* must be zero for next step */
|
||||
if (ifa_ifwithaddr((struct sockaddr*)sin) == NULL) {
|
||||
printf("in_pcbbind: EADDRNOTAVAIL\n");
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
}
|
||||
if (lport) {
|
||||
struct inpcb *t;
|
||||
/* we have something to work with... */
|
||||
/* XXX - reserved ports have no meaning for us */
|
||||
/* XXX - fix me if we ever have multi-user */
|
||||
t = in_pcblookup(head, zeroin_addr, 0,
|
||||
sin->sin_addr, lport, wild);
|
||||
if (t && (reuseport & t->inp_socket->so_options) == 0) {
|
||||
printf("in_pcbbind: EADDRINUSE\n");
|
||||
return EADDRINUSE;
|
||||
}
|
||||
}
|
||||
inp->laddr = sin->sin_addr;
|
||||
}
|
||||
/* if we have an ephemereal port, find a suitable port to use */
|
||||
if (lport == 0) {
|
||||
/* ephemereal port!! */
|
||||
do {
|
||||
if (head->lport++ < IPPORT_RESERVED ||
|
||||
head->lport > IPPORT_USERRESERVED) {
|
||||
head->lport = IPPORT_RESERVED;
|
||||
}
|
||||
lport = htons(head->lport);
|
||||
} while (in_pcblookup(head, zeroin_addr, 0,
|
||||
inp->laddr, lport, wild));
|
||||
}
|
||||
|
||||
inp->lport = lport;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct inpcb *in_pcblookup(struct inpcb *head, struct in_addr faddr,
|
||||
uint16 fport_a, struct in_addr laddr,
|
||||
uint16 lport_a, int flags)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
struct inpcb *match = NULL;
|
||||
int matchwild = 3;
|
||||
int wildcard;
|
||||
uint16 fport = fport_a;
|
||||
uint16 lport = lport_a;
|
||||
|
||||
for (inp = head->inp_next; inp != head; inp = inp->inp_next) {
|
||||
if (inp->lport != lport)
|
||||
continue; /* local ports don't match */
|
||||
wildcard = 0;
|
||||
/* Here we try to find the best match. wildcard is set to 0
|
||||
* and bumped by one every time we find something that doesn't match
|
||||
* so we can have a suitable match at the end
|
||||
*/
|
||||
if (inp->laddr.s_addr != INADDR_ANY) {
|
||||
if (laddr.s_addr == INADDR_ANY)
|
||||
wildcard++;
|
||||
else if (inp->laddr.s_addr != laddr.s_addr)
|
||||
continue;
|
||||
} else {
|
||||
if (laddr.s_addr != INADDR_ANY)
|
||||
wildcard++;
|
||||
}
|
||||
|
||||
if (inp->faddr.s_addr != INADDR_ANY) {
|
||||
if (faddr.s_addr == INADDR_ANY)
|
||||
wildcard++;
|
||||
else if (inp->faddr.s_addr != faddr.s_addr ||
|
||||
inp->fport != fport)
|
||||
continue;
|
||||
} else {
|
||||
if (faddr.s_addr != INADDR_ANY)
|
||||
wildcard++;
|
||||
}
|
||||
if (wildcard && ((flags & INPLOOKUP_WILDCARD) == 0)) {
|
||||
continue; /* wildcard match is not allowed!! */
|
||||
}
|
||||
|
||||
if (wildcard < matchwild) {
|
||||
match = inp;
|
||||
matchwild = wildcard;
|
||||
if (matchwild == 0)
|
||||
break; /* exact match!! */
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
int in_pcbconnect(struct inpcb *inp, struct mbuf *nam)
|
||||
{
|
||||
struct in_ifaddr *ia = NULL;
|
||||
struct sockaddr_in *ifaddr = NULL;
|
||||
struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
|
||||
|
||||
if (nam->m_len != sizeof(*sin)) {
|
||||
printf("in_pcbconnect: EINVAL: is %ld should be %ld\n", nam->m_len,
|
||||
sizeof(*sin));
|
||||
return EINVAL;
|
||||
}
|
||||
if (sin->sin_family != AF_INET) {
|
||||
printf("in_pcbconnect: EAFNOSUPPORT (sin_family = %d, not %d)\n",
|
||||
sin->sin_family, AF_INET);
|
||||
return EAFNOSUPPORT;
|
||||
}
|
||||
if (sin->sin_port == 0) {
|
||||
printf("in_pcbconnect: EADDRNOTAVAIL\n");
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
if (in_ifaddr) {
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY)
|
||||
sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr;
|
||||
|
||||
/* we need to handle INADDR_BROADCAST here as well */
|
||||
|
||||
}
|
||||
|
||||
if (inp->laddr.s_addr == INADDR_ANY) {
|
||||
struct route *ro;
|
||||
|
||||
ro = &inp->inp_route;
|
||||
|
||||
if (ro && 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 = NULL;
|
||||
}
|
||||
if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0
|
||||
&& (ro->ro_rt == NULL
|
||||
|| ro->ro_rt->rt_ifp == NULL)) {
|
||||
/* we don't have a route, try to get one */
|
||||
memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
|
||||
ro->ro_dst.sa_family = AF_INET;
|
||||
ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
|
||||
((struct sockaddr_in*)&ro->ro_dst)->sin_addr = sin->sin_addr;
|
||||
rtalloc(ro);
|
||||
}
|
||||
/* did we find a route?? */
|
||||
if (ro->ro_rt && (ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
|
||||
ia = ifatoia(ro->ro_rt->rt_ifa);
|
||||
|
||||
if (ia == NULL) {
|
||||
uint16 fport = sin->sin_port;
|
||||
|
||||
sin->sin_port = 0;
|
||||
ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin)));
|
||||
if (ia == NULL)
|
||||
ia = ifatoia(ifa_ifwithnet(sintosa(sin)));
|
||||
sin->sin_port = fport;
|
||||
if (ia == NULL)
|
||||
ia = in_ifaddr;
|
||||
if (ia == NULL) {
|
||||
printf("in_pcbconnect: EADDRNOTAVAIL\n");
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
/* XXX - handle multicast */
|
||||
ifaddr = (struct sockaddr_in*) &ia->ia_addr;
|
||||
}
|
||||
|
||||
if (in_pcblookup(inp->inp_head, sin->sin_addr, sin->sin_port,
|
||||
inp->laddr.s_addr ? inp->laddr : ifaddr->sin_addr,
|
||||
inp->lport, 0)) {
|
||||
printf("in_pcbconnect: EADDRINUSE\n");
|
||||
return EADDRINUSE;
|
||||
}
|
||||
|
||||
if (inp->laddr.s_addr == INADDR_ANY) {
|
||||
if (inp->lport == 0)
|
||||
in_pcbbind(inp, NULL);
|
||||
inp->laddr = ifaddr->sin_addr;
|
||||
}
|
||||
inp->faddr = sin->sin_addr;
|
||||
inp->fport = sin->sin_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX - why is this an int? */
|
||||
int in_pcbdisconnect(struct inpcb *inp)
|
||||
{
|
||||
inp->faddr.s_addr = INADDR_ANY;
|
||||
inp->fport = 0;
|
||||
if (inp->inp_socket->so_state & SS_NOFDREF)
|
||||
in_pcbdetach(inp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void in_losing(struct inpcb *inp)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct rt_addrinfo info;
|
||||
|
||||
if ((rt = inp->inp_route.ro_rt)) {
|
||||
inp->inp_route.ro_rt = NULL;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.rti_info[RTAX_DST] = (struct sockaddr*)&inp->inp_route.ro_dst;
|
||||
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
|
||||
info.rti_info[RTAX_NETMASK] = rt_mask(rt);
|
||||
//rt_missmsg
|
||||
|
||||
if (rt->rt_flags & RTF_DYNAMIC)
|
||||
rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
|
||||
rt->rt_flags, NULL);
|
||||
else
|
||||
rtfree(rt);
|
||||
}
|
||||
}
|
||||
|
||||
struct rtentry *in_pcbrtentry(struct inpcb *inp)
|
||||
{
|
||||
struct route *ro;
|
||||
|
||||
ro = &inp->inp_route;
|
||||
|
||||
/*
|
||||
* No route yet, so try to acquire one.
|
||||
*/
|
||||
if (ro->ro_rt == NULL) {
|
||||
memset(ro, 0, sizeof(struct route));
|
||||
|
||||
if (inp->faddr.s_addr != INADDR_ANY) {
|
||||
/* this probably isn't needed, but better safe than sorry */
|
||||
memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
|
||||
ro->ro_dst.sa_family = AF_INET;
|
||||
ro->ro_dst.sa_len = sizeof(ro->ro_dst);
|
||||
satosin(&ro->ro_dst)->sin_addr = inp->faddr;
|
||||
rtalloc(ro);
|
||||
}
|
||||
}
|
||||
return (ro->ro_rt);
|
||||
}
|
||||
|
||||
int inetctlerr(int cmd)
|
||||
{
|
||||
return inetctlerrmap[cmd];
|
||||
}
|
||||
|
||||
/* remove the route associated with a control block (if there is one)
|
||||
* forcing the route to be allocated next time it's used
|
||||
*/
|
||||
static void in_rtchange(struct inpcb *inp, int err)
|
||||
{
|
||||
if (inp->inp_route.ro_rt) {
|
||||
rtfree(inp->inp_route.ro_rt);
|
||||
inp->inp_route.ro_rt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void in_pcbnotify(struct inpcb *head, struct sockaddr *dst,
|
||||
uint16 fport_arg, struct in_addr laddr,
|
||||
uint16 lport_arg, int cmd,
|
||||
void (*notify)(struct inpcb *, int))
|
||||
{
|
||||
struct inpcb *inp, *oinp;
|
||||
struct in_addr faddr;
|
||||
uint16 fport = fport_arg, lport = lport_arg;
|
||||
int err = 0;
|
||||
|
||||
if ((uint)cmd > PRC_NCMDS || dst->sa_family != AF_INET)
|
||||
return;
|
||||
faddr = satosin(dst)->sin_addr;
|
||||
if (faddr.s_addr == INADDR_ANY)
|
||||
return;
|
||||
|
||||
if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
|
||||
fport = lport = 0;
|
||||
laddr.s_addr = 0;
|
||||
if (cmd != PRC_HOSTDEAD)
|
||||
notify = in_rtchange;
|
||||
}
|
||||
err = inetctlerrmap[cmd];
|
||||
for (inp = head->inp_next; inp != head;) {
|
||||
if (inp->faddr.s_addr != faddr.s_addr ||
|
||||
inp->inp_socket == NULL ||
|
||||
inp->fport != fport ||
|
||||
inp->lport != lport ||
|
||||
(laddr.s_addr && inp->laddr.s_addr != laddr.s_addr)) {
|
||||
inp = inp->inp_next;
|
||||
continue;
|
||||
}
|
||||
oinp = inp;
|
||||
inp = inp->inp_next;
|
||||
if (notify)
|
||||
(*notify)(oinp, err);
|
||||
}
|
||||
}
|
||||
|
||||
void in_setsockaddr(struct inpcb *inp, struct mbuf *nam)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
nam->m_len = sizeof(*sin);
|
||||
sin = mtod(nam, struct sockaddr_in *);
|
||||
memset(sin, 0, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_port = inp->lport;
|
||||
sin->sin_addr = inp->laddr;
|
||||
}
|
||||
|
||||
void in_setpeeraddr(struct inpcb *inp, struct mbuf *nam)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
nam->m_len = sizeof(*sin);
|
||||
sin = mtod(nam, struct sockaddr_in *);
|
||||
memset(sin, 0, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_port = inp->fport;
|
||||
sin->sin_addr = inp->faddr;
|
||||
}
|
||||
|
@ -1,530 +0,0 @@
|
||||
/* mbuf.c
|
||||
* network buffer implementation
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <kernel/OS.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "net_misc.h"
|
||||
#include "pools.h"
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#endif
|
||||
|
||||
#define MBUF_ALLOCSIZE 4096
|
||||
|
||||
|
||||
struct pool_ctl *mbpool;
|
||||
struct pool_ctl *clpool;
|
||||
|
||||
int max_hdr = 0; /* largest link+protocol header */
|
||||
int max_linkhdr = 0; /* largest link level header */
|
||||
int max_protohdr = 0; /* largest protocol header */
|
||||
|
||||
|
||||
void dump_freelist(void)
|
||||
{
|
||||
pool_debug_walk(mbpool);
|
||||
}
|
||||
|
||||
/* init the mbuf data structures */
|
||||
void mbinit(void)
|
||||
{
|
||||
if (!mbpool)
|
||||
pool_init(&mbpool, sizeof(struct mbuf));
|
||||
if (!clpool)
|
||||
pool_init(&clpool, MCLBYTES);
|
||||
max_linkhdr = 14;
|
||||
max_protohdr = 40;
|
||||
max_hdr = max_linkhdr + max_protohdr;
|
||||
}
|
||||
|
||||
struct mbuf *m_get(int type)
|
||||
{
|
||||
struct mbuf *mnew;
|
||||
MGET(mnew, type);
|
||||
return mnew;
|
||||
}
|
||||
|
||||
struct mbuf *m_getclr(int type)
|
||||
{
|
||||
struct mbuf *mnew;
|
||||
MGET(mnew, type);
|
||||
if (!mnew)
|
||||
return NULL;
|
||||
memset(mtod(mnew, char *), 0, MLEN);
|
||||
return mnew;
|
||||
}
|
||||
|
||||
struct mbuf *m_gethdr(int type)
|
||||
{
|
||||
struct mbuf *mnew;
|
||||
MGETHDR(mnew, type);
|
||||
return mnew;
|
||||
}
|
||||
|
||||
struct mbuf *m_free(struct mbuf *mfree)
|
||||
{
|
||||
struct mbuf *succ; /* successor if there is one! */
|
||||
MFREE(mfree, succ);
|
||||
return succ;
|
||||
}
|
||||
|
||||
/* Free the entire chain */
|
||||
void m_freem(struct mbuf *m)
|
||||
{
|
||||
struct mbuf *n = NULL;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
do {
|
||||
MFREE(m, n);
|
||||
//printf("m_freem(%p, %p)\n", m, n);
|
||||
} while ((m = n) != NULL);
|
||||
}
|
||||
|
||||
struct mbuf *m_prepend(struct mbuf *m, int len)
|
||||
{
|
||||
struct mbuf *mnew;
|
||||
|
||||
if (M_LEADINGSPACE(m) >= len) {
|
||||
m->m_data -= len;
|
||||
m->m_len += len;
|
||||
} else {
|
||||
MGET(mnew, m->m_type);
|
||||
if (!mnew) {
|
||||
/* free chain */
|
||||
return NULL;
|
||||
}
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
M_MOVE_PKTHDR(mnew, m);
|
||||
mnew->m_next = m;
|
||||
m = mnew;
|
||||
if (len < (int) MHLEN)
|
||||
MH_ALIGN(m, len);
|
||||
m->m_len = len;
|
||||
}
|
||||
if (m && m->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len += len;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
struct mbuf *m_devget(char *buf, int totlen, int off0,
|
||||
struct ifnet *ifp,
|
||||
void (*copy)(const void *, void *, size_t))
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct mbuf *top = NULL, **mp = ⊤
|
||||
int off = off0, len;
|
||||
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(uint16);
|
||||
totlen -= 2 * sizeof(uint16);
|
||||
}
|
||||
MGETHDR(m, 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, MT_DATA);
|
||||
if (m == NULL) {
|
||||
m_freem(top);
|
||||
return (NULL);
|
||||
}
|
||||
m->m_len = MLEN;
|
||||
}
|
||||
len = min(totlen, epkt - cp);
|
||||
if (len >= (int) MINCLSIZE) {
|
||||
MCLGET(m);
|
||||
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 < (int) m->m_len) {
|
||||
if (top == NULL &&
|
||||
len + max_linkhdr <= (int) m->m_len)
|
||||
m->m_data += max_linkhdr;
|
||||
m->m_len = len;
|
||||
} else
|
||||
len = m->m_len;
|
||||
}
|
||||
if (copy)
|
||||
copy(cp, mtod(m, void *), (size_t)len);
|
||||
else
|
||||
memmove(mtod(m, void *), cp, (size_t)len);
|
||||
cp += len;
|
||||
*mp = m;
|
||||
mp = &m->m_next;
|
||||
totlen -= len;
|
||||
if (cp == epkt)
|
||||
cp = buf;
|
||||
}
|
||||
return (top);
|
||||
}
|
||||
|
||||
void m_reserve(struct mbuf *mp, int len)
|
||||
{
|
||||
if (mp->m_len == 0) {
|
||||
/* empty buffer! */
|
||||
if (mp->m_flags & M_PKTHDR) {
|
||||
if (len < (int) MHLEN) {
|
||||
mp->m_data += len;
|
||||
mp->m_len -= len;
|
||||
mp->m_pkthdr.len -= len;
|
||||
return;
|
||||
}
|
||||
/* ?? */
|
||||
} else {
|
||||
if (len <= (int) MLEN) {
|
||||
mp->m_data += len;
|
||||
mp->m_len -= len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if (len <= (int) mp->m_len) {
|
||||
mp->m_data += len;
|
||||
mp->m_len -= len;
|
||||
}
|
||||
}
|
||||
if (mp->m_flags & M_PKTHDR)
|
||||
mp->m_pkthdr.len -= len;
|
||||
}
|
||||
|
||||
void m_cat(struct mbuf *m, struct mbuf *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 them :) */
|
||||
m->m_next = n;
|
||||
return;
|
||||
}
|
||||
memcpy((void*)(mtod(m, char *) + m->m_len), mtod(n, void*), n->m_len);
|
||||
m->m_len += n->m_len;
|
||||
n = m_free(n);
|
||||
}
|
||||
}
|
||||
|
||||
void m_adj(struct mbuf *mp, int req_len)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int len = req_len, count = 0;
|
||||
|
||||
if ((m = mp) == NULL)
|
||||
return;
|
||||
|
||||
if (len >= 0) {
|
||||
/* trim from the head */
|
||||
while (m!= NULL && len > 0) {
|
||||
if ((int) m->m_len <= len) {
|
||||
/* this whole mbuf isn't enough... */
|
||||
len -= m->m_len;
|
||||
m->m_len = 0;
|
||||
m = m->m_next;
|
||||
} else {
|
||||
/* this mbuf just needs trimming */
|
||||
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... */
|
||||
len = -len;
|
||||
count = 0;
|
||||
for (;;) {
|
||||
count += m->m_len;
|
||||
if (m->m_next == NULL)
|
||||
break;
|
||||
m = m->m_next;
|
||||
}
|
||||
if ((int) 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;
|
||||
/* The correct length for the chain is now "count".
|
||||
* find the last mbuf, adjust it's length and toss
|
||||
* remaining mbufs...
|
||||
*/
|
||||
m = mp; /* first mbuf */
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len = count;
|
||||
for (; m; m= m->m_next) {
|
||||
if ((int) m->m_len >= count) {
|
||||
m->m_len = count;
|
||||
break;
|
||||
}
|
||||
count -= m->m_len;
|
||||
}
|
||||
while (m->m_next)
|
||||
(m = m->m_next)->m_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void m_copydata(struct mbuf *m, int off, int len, caddr_t cp)
|
||||
{
|
||||
uint count = 0;
|
||||
|
||||
if (off < 0) {
|
||||
printf("m_copydata: off %d < 0\n", off);
|
||||
return;
|
||||
}
|
||||
if (len < 0) {
|
||||
printf("m_copydata: len %d < 0\n", len);
|
||||
return;
|
||||
}
|
||||
while (off > 0) {
|
||||
if (m == NULL) {
|
||||
printf("m_copydata: null mbuf in skip\n");
|
||||
return;
|
||||
}
|
||||
if (off < (int) m->m_len)
|
||||
break;
|
||||
off -= m->m_len;
|
||||
m = m->m_next;
|
||||
}
|
||||
while (len > 0) {
|
||||
if (m == NULL) {
|
||||
printf("m_copydata: null mbuf\n");
|
||||
return;
|
||||
}
|
||||
count = min((int) m->m_len - off, len);
|
||||
memcpy(cp, (void*)(mtod(m, char *) + off), count);
|
||||
len -= count;
|
||||
cp += count;
|
||||
off = 0;
|
||||
m = m->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
struct mbuf *m_copym(struct mbuf *m, int off0, int len)
|
||||
{
|
||||
struct mbuf *n, **np;
|
||||
int off = off0;
|
||||
struct mbuf *top;
|
||||
int copyhdr = 0;
|
||||
|
||||
if (off < 0 || len < 0) {
|
||||
printf("PANIC: m_copym: m: off %d, len %d\n", off, len);
|
||||
return NULL;
|
||||
}
|
||||
if (off == 0 && m->m_flags & M_PKTHDR)
|
||||
copyhdr = 1;
|
||||
while (off > 0) {
|
||||
if (!m) {
|
||||
printf("PANIC: m_copym: null mbuf\n");
|
||||
return NULL;
|
||||
}
|
||||
if (off < (int) m->m_len)
|
||||
break;
|
||||
off -= m->m_len;
|
||||
m = m->m_next;
|
||||
}
|
||||
np = ⊤
|
||||
top = NULL;
|
||||
while (len > 0) {
|
||||
if (!m) {
|
||||
if (len != M_COPYALL) {
|
||||
printf("PANIC: m_copym: m == NULL and not COPYALL\n");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
MGET(n, m->m_type);
|
||||
*np = n;
|
||||
if (!n)
|
||||
goto nospace;
|
||||
if (copyhdr) {
|
||||
M_DUP_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, (int) m->m_len - off);
|
||||
if (m->m_flags & M_EXT) {
|
||||
/*
|
||||
* we are unsure about the way m was allocated.
|
||||
* copy into multiple MCLBYTES cluster mbufs.
|
||||
*/
|
||||
MCLGET(n);
|
||||
n->m_len = 0;
|
||||
n->m_len = M_TRAILINGSPACE(n);
|
||||
n->m_len = min((int) n->m_len, len);
|
||||
n->m_len = min(n->m_len, m->m_len - off);
|
||||
memcpy(mtod(n, caddr_t), (void *)(mtod(m, char *) + off),
|
||||
(unsigned)n->m_len);
|
||||
} else
|
||||
memcpy(mtod(n, caddr_t), (void*)(mtod(m, char *)+off),
|
||||
(unsigned)n->m_len);
|
||||
if (len != M_COPYALL)
|
||||
len -= n->m_len;
|
||||
off += n->m_len;
|
||||
if (off == (int) m->m_len) {
|
||||
m = m->m_next;
|
||||
off = 0;
|
||||
}
|
||||
np = &n->m_next;
|
||||
}
|
||||
return (top);
|
||||
nospace:
|
||||
m_freem(top);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Rearrange 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 = 0;
|
||||
struct mbuf *m_pullup(struct mbuf *n, int len)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int count;
|
||||
int space;
|
||||
|
||||
if ((int) n->m_len <= len)
|
||||
return n;
|
||||
|
||||
/*
|
||||
* 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 ((int) n->m_len >= len)
|
||||
return (n);
|
||||
m = n;
|
||||
n = n->m_next;
|
||||
len -= m->m_len;
|
||||
} else {
|
||||
if (len > (int) MHLEN)
|
||||
goto bad;
|
||||
MGET(m, n->m_type);
|
||||
if (m == NULL)
|
||||
goto bad;
|
||||
m->m_len = 0;
|
||||
if (n->m_flags & M_PKTHDR) {
|
||||
M_MOVE_PKTHDR(m, n);
|
||||
}
|
||||
}
|
||||
space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
|
||||
do {
|
||||
count = min(min(max(len, max_protohdr), space), (int) n->m_len);
|
||||
memcpy((void *)(mtod(m, caddr_t) + m->m_len), mtod(n, void *), (uint)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) {
|
||||
printf("m_pullup: failed: len = %d\n", len);
|
||||
(void)m_free(m);
|
||||
goto bad;
|
||||
}
|
||||
m->m_next = n;
|
||||
return (m);
|
||||
bad:
|
||||
m_freem(n);
|
||||
MPFail++;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(struct mbuf *m0, int off, int len, caddr_t cp)
|
||||
{
|
||||
int mlen;
|
||||
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->m_type);
|
||||
if (n == 0)
|
||||
goto out;
|
||||
n->m_len = min((int) MLEN, len + off);
|
||||
m->m_next = n;
|
||||
}
|
||||
m = m->m_next;
|
||||
}
|
||||
while (len > 0) {
|
||||
mlen = min ((int) m->m_len - off, len);
|
||||
memcpy(off + mtod(m, caddr_t), cp, (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->m_type);
|
||||
if (n == 0)
|
||||
break;
|
||||
n->m_len = min((int) 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;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
/* some misc functions... */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#endif
|
||||
|
||||
#include "net_misc.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Basically use dump_ to see the address plus message on a line,
|
||||
* print_ to simply have the address printed with nothing else...
|
||||
*/
|
||||
|
||||
void dump_ipv4_addr(char *msg, void *ad)
|
||||
{
|
||||
uint8 *b = (uint8*)ad;
|
||||
printf("%s %d.%d.%d.%d\n", msg, b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
void print_ipv4_addr(void *ad)
|
||||
{
|
||||
uint8 *b = (uint8*)ad;
|
||||
printf("%d.%d.%d.%d", b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
void dump_ether_addr(char *msg, void *ea)
|
||||
{
|
||||
uint8 *b = (uint8*)ea;
|
||||
printf("%s %02x:%02x:%02x:%02x:%02x:%02x\n", msg,
|
||||
b[0], b[1], b[2],
|
||||
b[3], b[4], b[5]);
|
||||
}
|
||||
|
||||
void print_ether_addr(void *ea)
|
||||
{
|
||||
uint8 *b = (uint8*)ea;
|
||||
printf("%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
b[0], b[1], b[2],
|
||||
b[3], b[4], b[5]);
|
||||
}
|
||||
|
||||
void dump_buffer(char *buffer, int len)
|
||||
{
|
||||
uint8 *b = (uint8 *)buffer;
|
||||
int i;
|
||||
|
||||
printf (" ");
|
||||
for (i=0;i<len;i++) {
|
||||
if (i%16 == 0)
|
||||
printf("\n ");
|
||||
if (i%2 == 0)
|
||||
printf(" %02x", b[i]);
|
||||
else
|
||||
printf("%02x ", b[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
/* net_timer.h - a small and more or less inaccurate timer for net modules.
|
||||
** The registered hooks will be called in the thread of the timer.
|
||||
**
|
||||
** Initial version by Axel Dörfler, axeld@pinc-software.de
|
||||
**
|
||||
** This file may be used under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
#include <malloc.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include "net_timer.h"
|
||||
|
||||
|
||||
|
||||
struct timer_entry {
|
||||
struct timer_entry *te_next;
|
||||
net_timer_hook te_hook;
|
||||
void *te_data;
|
||||
bigtime_t te_interval;
|
||||
bigtime_t te_until;
|
||||
net_timer_id te_id;
|
||||
};
|
||||
|
||||
struct timer_info {
|
||||
struct timer_entry *ti_first;
|
||||
|
||||
sem_id ti_lock;
|
||||
sem_id ti_wait;
|
||||
int32 ti_counter;
|
||||
volatile int32 ti_inUse;
|
||||
};
|
||||
|
||||
int32 net_timer(void *_data);
|
||||
|
||||
struct timer_info gTimerInfo;
|
||||
|
||||
status_t
|
||||
net_init_timer(void)
|
||||
{
|
||||
thread_id thread;
|
||||
|
||||
memset(&gTimerInfo,0,sizeof(struct timer_info));
|
||||
|
||||
gTimerInfo.ti_lock = create_sem(1,"net timer lock");
|
||||
if (gTimerInfo.ti_lock < B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
gTimerInfo.ti_wait = create_sem(0,"net timer wait");
|
||||
if (gTimerInfo.ti_wait < B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
set_sem_owner(gTimerInfo.ti_lock, B_SYSTEM_TEAM);
|
||||
set_sem_owner(gTimerInfo.ti_wait, B_SYSTEM_TEAM);
|
||||
#endif
|
||||
|
||||
thread = spawn_kernel_thread(net_timer, "net timer", B_NORMAL_PRIORITY, &gTimerInfo);
|
||||
if (thread < B_OK)
|
||||
return thread;
|
||||
|
||||
return resume_thread(thread);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
net_shutdown_timer(void)
|
||||
{
|
||||
struct timer_entry *te,*next;
|
||||
int32 tries = 20;
|
||||
|
||||
delete_sem(gTimerInfo.ti_wait);
|
||||
delete_sem(gTimerInfo.ti_lock);
|
||||
gTimerInfo.ti_wait = -1;
|
||||
gTimerInfo.ti_lock = -1;
|
||||
|
||||
// make sure the structure isn't used anymore
|
||||
while (gTimerInfo.ti_inUse != 0 && tries-- > 0)
|
||||
snooze(1000);
|
||||
|
||||
// free the remaining timer entries
|
||||
for (te = gTimerInfo.ti_first;te;te = next) {
|
||||
next = te->te_next;
|
||||
free(te);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
net_timer(void *_data)
|
||||
{
|
||||
struct timer_info *timer = (struct timer_info *)_data;
|
||||
status_t status = B_OK;
|
||||
|
||||
do {
|
||||
bigtime_t timeout = B_INFINITE_TIMEOUT;
|
||||
struct timer_entry *te;
|
||||
|
||||
// get access to the info structure
|
||||
if (status == B_TIMED_OUT || status == B_OK) {
|
||||
if (acquire_sem(timer->ti_lock) == B_OK) {
|
||||
for (te = timer->ti_first;te;te = te->te_next) {
|
||||
// new entry?
|
||||
if (te->te_until == -1)
|
||||
te->te_until = system_time() + te->te_interval;
|
||||
|
||||
// execute timer?
|
||||
if (te->te_until < system_time()) {
|
||||
te->te_until += te->te_interval;
|
||||
te->te_hook(te->te_data);
|
||||
}
|
||||
|
||||
// calculate new timeout
|
||||
if (te->te_until < timeout)
|
||||
timeout = te->te_until;
|
||||
}
|
||||
|
||||
release_sem(timer->ti_lock);
|
||||
}
|
||||
}
|
||||
|
||||
status = acquire_sem_etc(timer->ti_wait,1,B_ABSOLUTE_TIMEOUT,timeout);
|
||||
// the wait sem normally can't be acquired, so we
|
||||
// have to look at the status value the call returns:
|
||||
//
|
||||
// B_OK - someone wanted to notify us
|
||||
// B_TIMED_OUT - look for timers to be executed
|
||||
// B_BAD_SEM_ID - our sem got deleted
|
||||
|
||||
} while (status != B_BAD_SEM_ID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
net_timer_id
|
||||
net_add_timer(net_timer_hook hook,void *data,bigtime_t interval)
|
||||
{
|
||||
struct timer_entry *te;
|
||||
status_t status;
|
||||
|
||||
if (interval < 100)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
atomic_add(&gTimerInfo.ti_inUse,1);
|
||||
|
||||
// get access to the timer info structure
|
||||
status = acquire_sem(gTimerInfo.ti_lock);
|
||||
if (status < B_OK) {
|
||||
atomic_add(&gTimerInfo.ti_inUse,-1);
|
||||
return status;
|
||||
}
|
||||
|
||||
te = (struct timer_entry *)malloc(sizeof(struct timer_entry));
|
||||
if (te == NULL) {
|
||||
atomic_add(&gTimerInfo.ti_inUse,-1);
|
||||
release_sem(gTimerInfo.ti_lock);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
te->te_hook = hook;
|
||||
te->te_data = data;
|
||||
te->te_interval = interval;
|
||||
te->te_until = -1;
|
||||
te->te_id = ++gTimerInfo.ti_counter;
|
||||
|
||||
// add the new entry
|
||||
te->te_next = gTimerInfo.ti_first;
|
||||
gTimerInfo.ti_first = te;
|
||||
|
||||
atomic_add(&gTimerInfo.ti_inUse,-1);
|
||||
release_sem(gTimerInfo.ti_lock);
|
||||
|
||||
// notify timer about the change
|
||||
release_sem(gTimerInfo.ti_wait);
|
||||
|
||||
return te->te_id;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
net_remove_timer(net_timer_id id)
|
||||
{
|
||||
struct timer_entry *te,*last;
|
||||
status_t status;
|
||||
|
||||
if (id <= B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
atomic_add(&gTimerInfo.ti_inUse,1);
|
||||
|
||||
// get access to the timer info structure
|
||||
status = acquire_sem(gTimerInfo.ti_lock);
|
||||
if (status < B_OK) {
|
||||
atomic_add(&gTimerInfo.ti_inUse,-1);
|
||||
return status;
|
||||
}
|
||||
|
||||
// search the list for the right timer
|
||||
|
||||
// little hack that relies on ti_first being on the same position
|
||||
// in the structure as te_next
|
||||
last = (struct timer_entry *)&gTimerInfo;
|
||||
for (te = gTimerInfo.ti_first;te;te = te->te_next) {
|
||||
if (te->te_id == id) {
|
||||
last->te_next = te->te_next;
|
||||
free(te);
|
||||
break;
|
||||
}
|
||||
last = te;
|
||||
}
|
||||
atomic_add(&gTimerInfo.ti_inUse,-1);
|
||||
release_sem(gTimerInfo.ti_lock);
|
||||
|
||||
if (te == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// notify timer about the change
|
||||
release_sem(gTimerInfo.ti_wait);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1,157 +0,0 @@
|
||||
/* nhash.c
|
||||
* net hash
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "net_malloc.h"
|
||||
#include "nhash.h"
|
||||
|
||||
#define MAX_INITIAL 15;
|
||||
|
||||
|
||||
net_hash_index *nhash_next(net_hash_index *hi);
|
||||
net_hash_index *nhash_first(net_hash *nh);
|
||||
void nhash_this(net_hash_index *hi, const void **key, ssize_t *klen,
|
||||
void **val);
|
||||
|
||||
|
||||
net_hash *nhash_make(void)
|
||||
{
|
||||
net_hash *nn;
|
||||
|
||||
nn = (net_hash *)malloc(sizeof(net_hash));
|
||||
|
||||
if (!nn)
|
||||
return NULL;
|
||||
|
||||
nn->count = 0;
|
||||
nn->max = MAX_INITIAL;
|
||||
|
||||
nn->array = (net_hash_entry **)malloc(sizeof(net_hash_entry) * (nn->max + 1));
|
||||
memset(nn->array, 0, sizeof(net_hash_entry) * (nn->max +1));
|
||||
pool_init(&nn->pool, sizeof(net_hash_entry));
|
||||
if (!nn->pool)
|
||||
return NULL;
|
||||
return nn;
|
||||
}
|
||||
|
||||
net_hash_index *nhash_next(net_hash_index *hi)
|
||||
{
|
||||
hi->this = hi->next;
|
||||
while (!hi->this) {
|
||||
if (hi->index > hi->nh->max)
|
||||
return NULL;
|
||||
hi->this = hi->nh->array[hi->index++];
|
||||
}
|
||||
hi->next = hi->this->next;
|
||||
return hi;
|
||||
}
|
||||
|
||||
net_hash_index *nhash_first(net_hash *nh)
|
||||
{
|
||||
net_hash_index *hi = &nh->iterator;
|
||||
hi->nh = nh;
|
||||
hi->index = 0;
|
||||
hi->this = hi->next = NULL;
|
||||
return nhash_next(hi);
|
||||
}
|
||||
|
||||
static void expand_array(net_hash *nh)
|
||||
{
|
||||
net_hash_index *hi;
|
||||
net_hash_entry **new_array;
|
||||
int new_max = nh->max * 2 +1;
|
||||
int i;
|
||||
|
||||
new_array = (net_hash_entry **)malloc(sizeof(net_hash_entry) * new_max);
|
||||
memset(new_array, 0, sizeof(net_hash_entry) * new_max);
|
||||
for (hi = nhash_first(nh); hi; hi = nhash_next(hi)) {
|
||||
i = hi->this->hash & new_max;
|
||||
hi->this->next = new_array[i];
|
||||
new_array[i] = hi->this;
|
||||
}
|
||||
free(nh->array);
|
||||
nh->array = new_array;
|
||||
nh->max = new_max;
|
||||
}
|
||||
|
||||
void nhash_this(net_hash_index *hi, const void **key, ssize_t *klen,
|
||||
void **val)
|
||||
{
|
||||
if (key) *key = hi->this->key;
|
||||
if (klen) *klen = hi->this->klen;
|
||||
if (val) *val = (void*)hi->this->val;
|
||||
}
|
||||
|
||||
static net_hash_entry **find_entry(net_hash *nh, const void *key,
|
||||
ssize_t klen, const void *val)
|
||||
{
|
||||
net_hash_entry **hep;
|
||||
net_hash_entry *he;
|
||||
const unsigned char *p;
|
||||
int hash = 0;
|
||||
ssize_t i;
|
||||
|
||||
if (!nh)
|
||||
return NULL;
|
||||
|
||||
for (p=key, i=klen; i; i--, p++)
|
||||
hash = hash * 33 + *p;
|
||||
|
||||
for (hep = &nh->array[hash & nh->max], he = *hep; he;
|
||||
hep = &he->next, he = *hep) {
|
||||
if (he->hash == hash && he->klen == klen
|
||||
&& memcmp(he->key, key, klen) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (he || !val)
|
||||
return hep;
|
||||
|
||||
/* add a new linked-list entry */
|
||||
he = (net_hash_entry *)pool_get(nh->pool);
|
||||
he->next = NULL;
|
||||
he->hash = hash;
|
||||
he->key = key;
|
||||
he->klen = klen;
|
||||
he->val = val;
|
||||
*hep = he;
|
||||
nh->count++;
|
||||
return hep;
|
||||
}
|
||||
|
||||
void *nhash_get(net_hash *nh, const void *key, ssize_t klen)
|
||||
{
|
||||
net_hash_entry *he;
|
||||
he = *find_entry(nh, key, klen, NULL);
|
||||
if (he)
|
||||
return (void*)he->val;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nhash_set(net_hash *nh, const void *key, ssize_t klen, const void *val)
|
||||
{
|
||||
net_hash_entry **hep;
|
||||
net_hash_entry *old;
|
||||
hep = find_entry(nh, key, klen, val);
|
||||
|
||||
if (*hep) {
|
||||
if (!val) {
|
||||
/* delete it */
|
||||
old = *hep;
|
||||
*hep = (*hep)->next;
|
||||
--nh->count;
|
||||
pool_put(nh->pool, old);
|
||||
} else {
|
||||
/* replace it */
|
||||
(*hep)->val = val;
|
||||
if (nh->count > nh->max)
|
||||
expand_array(nh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,324 +0,0 @@
|
||||
/* pools.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "pools.h"
|
||||
#include "net_misc.h"
|
||||
#include "net_malloc.h"
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#define AREA_ADDR_FLAG B_ANY_KERNEL_ADDRESS
|
||||
#define AREA_FLAGS B_NO_LOCK
|
||||
#else
|
||||
#define AREA_ADDR_FLAG B_ANY_ADDRESS
|
||||
#define AREA_FLAGS B_FULL_LOCK
|
||||
#endif
|
||||
|
||||
static sem_id init_sem = -1;
|
||||
|
||||
#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1))
|
||||
|
||||
#ifdef WALK_POOL_LIST
|
||||
void walk_pool_list(struct pool_ctl *p)
|
||||
{
|
||||
struct pool_mem *pb = p->list;
|
||||
|
||||
printf("Pool: %p\n", p);
|
||||
printf(" -> list = %p\n", pb);
|
||||
while (pb) {
|
||||
printf(" -> mem_block %p, %p\n", pb, pb->next);
|
||||
pb = pb->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void pool_debug_walk(struct pool_ctl *p)
|
||||
{
|
||||
char *ptr;
|
||||
int i = 1;
|
||||
|
||||
printf("%ld byte blocks allocated, but now free:\n\n", p->alloc_size);
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
ACQUIRE_BENAPHORE(p->lock);
|
||||
#else
|
||||
ACQUIRE_READ_LOCK(p->lock);
|
||||
#endif
|
||||
ptr = p->freelist;
|
||||
while (ptr) {
|
||||
printf(" %02d: %p\n", i++, ptr);
|
||||
ptr = ((struct free_blk*)ptr)->next;
|
||||
}
|
||||
#if POOL_USES_BENAPHORES
|
||||
RELEASE_BENAPHORE(p->lock);
|
||||
#else
|
||||
RELEASE_READ_LOCK(p->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void pool_debug(struct pool_ctl *p, char *name)
|
||||
{
|
||||
p->debug = 1;
|
||||
if (strlen(name) < POOL_DEBUG_NAME_SZ)
|
||||
strncpy(p->name, name, strlen(name));
|
||||
else
|
||||
strncpy(p->name, name, POOL_DEBUG_NAME_SZ);
|
||||
}
|
||||
|
||||
static struct pool_mem *get_mem_block(struct pool_ctl *pool)
|
||||
{
|
||||
struct pool_mem *block;
|
||||
|
||||
block = (struct pool_mem *)malloc(sizeof(struct pool_mem));
|
||||
if (block == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(block, 0, sizeof(*block));
|
||||
|
||||
block->aid = create_area("net_stack_pools_block",
|
||||
(void**)&block->base_addr,
|
||||
AREA_ADDR_FLAG, pool->block_size,
|
||||
AREA_FLAGS,
|
||||
B_READ_AREA|B_WRITE_AREA);
|
||||
if (block->aid < B_OK) {
|
||||
free(block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block->mem_size = block->avail = pool->block_size;
|
||||
block->ptr = block->base_addr;
|
||||
INIT_BENAPHORE(block->lock, "pool_mem_lock");
|
||||
|
||||
if (CHECK_BENAPHORE(block->lock) >= B_OK) {
|
||||
#if POOL_USES_BENAPHORES
|
||||
ACQUIRE_BENAPHORE(pool->lock);
|
||||
#else
|
||||
ACQUIRE_WRITE_LOCK(pool->lock);
|
||||
#endif
|
||||
|
||||
// insert block at the beginning of the pools
|
||||
if (pool->list)
|
||||
block->next = pool->list;
|
||||
|
||||
pool->list = block;
|
||||
|
||||
#ifdef WALK_POOL_LIST
|
||||
walk_pool_list(pool);
|
||||
#endif
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
RELEASE_BENAPHORE(pool->lock);
|
||||
#else
|
||||
RELEASE_WRITE_LOCK(pool->lock);
|
||||
#endif
|
||||
|
||||
return block;
|
||||
}
|
||||
UNINIT_BENAPHORE(block->lock);
|
||||
|
||||
delete_area(block->aid);
|
||||
free(block);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t pool_init(struct pool_ctl **_newPool, size_t size)
|
||||
{
|
||||
struct pool_ctl *pool = NULL;
|
||||
|
||||
if (init_sem == -1)
|
||||
create_sem(1, "pool_init_sem");
|
||||
|
||||
/* minimum block size is sizeof the free_blk structure */
|
||||
if (size < sizeof(struct free_blk))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// acquire_sem_etc(init_sem, 1, B_CAN_INTERRUPT, 0);
|
||||
|
||||
pool = (struct pool_ctl*)malloc(sizeof(struct pool_ctl));
|
||||
if (pool == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(pool, 0, sizeof(*pool));
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
INIT_BENAPHORE(pool->lock, "pool_lock");
|
||||
if (CHECK_BENAPHORE(pool->lock) < B_OK) {
|
||||
free(pool);
|
||||
return B_ERROR;
|
||||
}
|
||||
#else
|
||||
INIT_RW_LOCK(pool->lock, "pool_lock");
|
||||
if (CHECK_RW_LOCK(pool->lock) < B_OK) {
|
||||
free(pool);
|
||||
return B_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 4 puddles will always fit in one pool
|
||||
pool->block_size = ROUND_TO_PAGE_SIZE(size * 8);
|
||||
pool->alloc_size = size;
|
||||
pool->list = NULL;
|
||||
pool->freelist = NULL;
|
||||
|
||||
/* now add a first block */
|
||||
get_mem_block(pool);
|
||||
if (!pool->list) {
|
||||
#if POOL_USES_BENAPHORES
|
||||
UNINIT_BENAPHORE(pool->lock);
|
||||
#else
|
||||
UNINIT_RW_LOCK(pool->lock);
|
||||
#endif
|
||||
free(pool);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
*_newPool = pool;
|
||||
|
||||
// release_sem_etc(init_sem, 1, B_CAN_INTERRUPT);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
char *pool_get(struct pool_ctl *p)
|
||||
{
|
||||
/* ok, so now we look for a suitable block... */
|
||||
struct pool_mem *mp = p->list;
|
||||
char *rv = NULL;
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
ACQUIRE_BENAPHORE(p->lock);
|
||||
#else
|
||||
ACQUIRE_WRITE_LOCK(p->lock);
|
||||
#endif
|
||||
|
||||
if (p->freelist) {
|
||||
/* woohoo, just grab a block! */
|
||||
|
||||
rv = p->freelist;
|
||||
|
||||
if (p->debug)
|
||||
printf("%s: allocating %p, setting freelist to %p\n",
|
||||
p->name, p->freelist,
|
||||
((struct free_blk*)rv)->next);
|
||||
|
||||
p->freelist = ((struct free_blk*)rv)->next;
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
RELEASE_BENAPHORE(p->lock);
|
||||
#else
|
||||
RELEASE_WRITE_LOCK(p->lock);
|
||||
#endif
|
||||
|
||||
memset(rv, 0, p->alloc_size);
|
||||
return rv;
|
||||
}
|
||||
#if !POOL_USES_BENAPHORES
|
||||
RELEASE_WRITE_LOCK(p->lock);
|
||||
ACQUIRE_READ_LOCK(p->lock);
|
||||
#endif
|
||||
|
||||
/* no free blocks, try to allocate of the top of the memory blocks
|
||||
** we must hold the global pool lock while iterating through the list!
|
||||
*/
|
||||
|
||||
do {
|
||||
ACQUIRE_BENAPHORE(mp->lock);
|
||||
|
||||
if (mp->avail >= p->alloc_size) {
|
||||
rv = mp->ptr;
|
||||
mp->ptr += p->alloc_size;
|
||||
mp->avail -= p->alloc_size;
|
||||
RELEASE_BENAPHORE(mp->lock);
|
||||
break;
|
||||
}
|
||||
RELEASE_BENAPHORE(mp->lock);
|
||||
} while ((mp = mp->next) != NULL);
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
RELEASE_BENAPHORE(p->lock);
|
||||
#else
|
||||
RELEASE_READ_LOCK(p->lock);
|
||||
#endif
|
||||
|
||||
if (rv) {
|
||||
memset(rv, 0, p->alloc_size);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mp = get_mem_block(p);
|
||||
if (mp == NULL)
|
||||
return NULL;
|
||||
|
||||
ACQUIRE_BENAPHORE(mp->lock);
|
||||
|
||||
if (mp->avail >= p->alloc_size) {
|
||||
rv = mp->ptr;
|
||||
mp->ptr += p->alloc_size;
|
||||
mp->avail -= p->alloc_size;
|
||||
}
|
||||
RELEASE_BENAPHORE(mp->lock);
|
||||
|
||||
memset(rv, 0, p->alloc_size);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void pool_put(struct pool_ctl *p, void *ptr)
|
||||
{
|
||||
#if POOL_USES_BENAPHORES
|
||||
ACQUIRE_BENAPHORE(p->lock);
|
||||
#else
|
||||
ACQUIRE_WRITE_LOCK(p->lock);
|
||||
#endif
|
||||
|
||||
memset(ptr, 0, p->alloc_size);
|
||||
((struct free_blk*)ptr)->next = p->freelist;
|
||||
|
||||
if (p->debug) {
|
||||
printf("%s: adding %p, setting next = %p\n",
|
||||
p->name, ptr, p->freelist);
|
||||
}
|
||||
|
||||
p->freelist = ptr;
|
||||
|
||||
if (p->debug)
|
||||
printf("%s: freelist = %p\n", p->name, p->freelist);
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
RELEASE_BENAPHORE(p->lock);
|
||||
#else
|
||||
RELEASE_WRITE_LOCK(p->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void pool_destroy(struct pool_ctl *p)
|
||||
{
|
||||
struct pool_mem *mp,*temp;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
/* the semaphore will be deleted, so we don't have to unlock */
|
||||
ACQUIRE_WRITE_LOCK(p->lock);
|
||||
|
||||
mp = p->list;
|
||||
while (mp != NULL) {
|
||||
delete_area(mp->aid);
|
||||
temp = mp;
|
||||
mp = mp->next;
|
||||
UNINIT_BENAPHORE(mp->lock);
|
||||
free(temp);
|
||||
}
|
||||
|
||||
#if POOL_USES_BENAPHORES
|
||||
UNINIT_BENAPHORE(p->lock);
|
||||
#else
|
||||
UNINIT_RW_LOCK(p->lock);
|
||||
#endif
|
||||
free(p);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,430 +0,0 @@
|
||||
/* route.c */
|
||||
|
||||
#ifndef _KERNEL_MODE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#endif
|
||||
|
||||
#include "net_malloc.h"
|
||||
|
||||
#include "sys/domain.h"
|
||||
#include "net/route.h" /* includes net/radix.h */
|
||||
#include "protocols.h"
|
||||
#include "net/if.h"
|
||||
|
||||
int rttrash = 0; /* routes in table that should have been freed but hevn't been */
|
||||
|
||||
#define SA(p) ((struct sockaddr *)(p))
|
||||
#define ROUNDUP(a) (a >0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
|
||||
struct rtstat rtstat;
|
||||
struct radix_node_head *rt_tables[AF_MAX+1];
|
||||
|
||||
struct radix_node_head **get_rt_tables(void)
|
||||
{
|
||||
return (struct radix_node_head**)rt_tables;
|
||||
}
|
||||
|
||||
struct rtentry *rtalloc1(struct sockaddr *dst, int report)
|
||||
{
|
||||
struct radix_node_head *rnh = rt_tables[dst->sa_family];
|
||||
struct rtentry *rt;
|
||||
struct radix_node *rn;
|
||||
struct rtentry *newrt = NULL;
|
||||
struct rt_addrinfo info;
|
||||
int msgtype = RTM_MISS;
|
||||
int err;
|
||||
|
||||
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, NULL,
|
||||
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++;
|
||||
}
|
||||
/* XXX - stats? */
|
||||
|
||||
miss:
|
||||
if (report) {
|
||||
memset((caddr_t)&info, 0, sizeof(info));
|
||||
info.rti_info[RTAX_DST] = dst;
|
||||
//rt_missmsg(msgtype, &info, 0, err);
|
||||
}
|
||||
return (newrt);
|
||||
}
|
||||
|
||||
void rtalloc(struct route *ro)
|
||||
{
|
||||
/* can we use what we have?? */
|
||||
if (ro && ro->ro_rt && ro->ro_rt->rt_ifp &&
|
||||
(ro->ro_rt->rt_flags & RTF_UP)) {
|
||||
/* yes */
|
||||
return;
|
||||
}
|
||||
/* no, get a new route */
|
||||
ro->ro_rt = rtalloc1(&ro->ro_dst, 1);
|
||||
}
|
||||
|
||||
void rtfree(struct rtentry *rt)
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
|
||||
if (!rt) {
|
||||
printf("rtfree on a NULL pointer!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rt->rt_refcnt--;
|
||||
if (rt->rt_refcnt <= 0 && (rt->rt_flags && RTF_UP) == 0) {
|
||||
if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) {
|
||||
printf("Trying to free nodes we shouldn't be!\n");
|
||||
return;
|
||||
}
|
||||
rttrash--;
|
||||
if (rt->rt_refcnt < 0) {
|
||||
printf("rtfree: %p not freed as the refcnt is negative!\n", rt);
|
||||
return;
|
||||
}
|
||||
ifa = rt->rt_ifa;
|
||||
IFAFREE(ifa);
|
||||
Free(rt_key(rt));
|
||||
Free(rt);
|
||||
}
|
||||
}
|
||||
|
||||
int rtrequest(int req, struct sockaddr *dst,
|
||||
struct sockaddr *gateway,
|
||||
struct sockaddr *netmask,
|
||||
int flags,
|
||||
struct rtentry **ret_nrt)
|
||||
{
|
||||
int error = 0;
|
||||
struct rtentry *rt;
|
||||
struct radix_node *rn = NULL;
|
||||
struct radix_node_head *rnh;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr *ndst;
|
||||
|
||||
#define snderr(x) {error = x; goto bad; }
|
||||
|
||||
if ((rnh = rt_tables[dst->sa_family]) == NULL)
|
||||
snderr(ESRCH);
|
||||
if (flags & RTF_HOST)
|
||||
netmask = NULL;
|
||||
|
||||
switch(req) {
|
||||
case RTM_DELETE:
|
||||
if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)
|
||||
snderr(ESRCH);
|
||||
if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) {
|
||||
/* XXX - should be panic */
|
||||
printf("rtrequest: delete: cannot delete route!\n");
|
||||
return -1;
|
||||
}
|
||||
rt = (struct rtentry *)rn;
|
||||
rt->rt_flags &= ~RTF_UP; /* mark route as down */
|
||||
if (rt->rt_gwroute) {
|
||||
rt = rt->rt_gwroute;
|
||||
RTFREE(rt);
|
||||
(rt = (struct rtentry*)rn)->rt_gwroute = NULL;
|
||||
}
|
||||
if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
|
||||
ifa->ifa_rtrequest(RTM_DELETE, rt, 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)
|
||||
snderr(EINVAL);
|
||||
ifa = rt->rt_ifa;
|
||||
flags = rt->rt_flags & ~RTF_CLONING;
|
||||
gateway = rt->rt_gateway;
|
||||
if ((netmask = rt->rt_genmask) == NULL)
|
||||
flags |= RTF_HOST;
|
||||
/* fall through */
|
||||
goto makeroute;
|
||||
case RTM_ADD:
|
||||
/* can we find a route to it? */
|
||||
if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == NULL) {
|
||||
printf("ENETUNREACH!\n");
|
||||
snderr(ENETUNREACH);
|
||||
}
|
||||
makeroute:
|
||||
R_Malloc(rt, struct rtentry *, sizeof(*rt));
|
||||
if (!rt)
|
||||
snderr(ENOMEM);
|
||||
Bzero(rt, sizeof(*rt));
|
||||
rt->rt_flags = RTF_UP | flags;
|
||||
if (rt_setgate(rt, dst, gateway)) {
|
||||
Free(rt);
|
||||
snderr(ENOMEM);
|
||||
}
|
||||
|
||||
ndst = rt_key(rt);
|
||||
if (netmask)
|
||||
rt_maskedcopy(dst, ndst, netmask);
|
||||
else
|
||||
Bcopy(dst, ndst, dst->sa_len);
|
||||
|
||||
rn = rnh->rnh_addaddr((caddr_t) ndst, (caddr_t) netmask,
|
||||
rnh, rt->rt_nodes);
|
||||
|
||||
if (!rn) {
|
||||
if (rt->rt_gwroute)
|
||||
rtfree(rt->rt_gwroute);
|
||||
Free(rt_key(rt));
|
||||
Free(rt);
|
||||
snderr(EEXIST);
|
||||
}
|
||||
ifa->ifa_refcnt++;
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = ifa->ifa_ifp;
|
||||
/* if we've fallen through - copy metrics */
|
||||
if (req == RTM_RESOLVE)
|
||||
rt->rt_rmx = (*ret_nrt)->rt_rmx;
|
||||
if (ifa->ifa_rtrequest)
|
||||
ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0));
|
||||
if (ret_nrt) {
|
||||
*ret_nrt = rt;
|
||||
rt->rt_refcnt++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
bad:
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct ifaddr *ifa_ifwithroute(int flags,
|
||||
struct sockaddr *dst,
|
||||
struct sockaddr *gateway)
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
|
||||
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 ((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);
|
||||
}
|
||||
|
||||
int rt_setgate(struct rtentry *rt0,
|
||||
struct sockaddr *dst,
|
||||
struct sockaddr *gate)
|
||||
{
|
||||
caddr_t new, old = NULL;
|
||||
int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len);
|
||||
struct rtentry *rt = rt0;
|
||||
|
||||
|
||||
if (rt->rt_gateway == NULL || glen > (int) 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);
|
||||
/*
|
||||
* If we switched gateways, grab the MTU from the new
|
||||
* gateway route if the current MTU is 0 or greater
|
||||
* than the MTU of gateway.
|
||||
*/
|
||||
if (rt->rt_gwroute && !(rt->rt_rmx.rmx_locks & RTV_MTU) &&
|
||||
(rt->rt_rmx.rmx_mtu == 0 ||
|
||||
rt->rt_rmx.rmx_mtu > rt->rt_gwroute->rt_rmx.rmx_mtu)) {
|
||||
rt->rt_rmx.rmx_mtu = rt->rt_gwroute->rt_rmx.rmx_mtu;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rt_maskedcopy(struct sockaddr *src,
|
||||
struct sockaddr *dst,
|
||||
struct sockaddr *netmask)
|
||||
{
|
||||
uchar *cp1 = (uchar *)src;
|
||||
uchar *cp2 = (uchar *)dst;
|
||||
uchar *cp3 = (uchar *)netmask;
|
||||
uchar *cplim = cp2 + *cp3;
|
||||
uchar *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)
|
||||
memset((caddr_t)cp2, 0, (unsigned)(cplim2 - cp2));
|
||||
}
|
||||
|
||||
void ifafree(struct ifaddr *ifa)
|
||||
{
|
||||
if (ifa == NULL) {
|
||||
printf("ifafree");
|
||||
return;
|
||||
}
|
||||
if (ifa->ifa_refcnt == 0)
|
||||
free(ifa);
|
||||
else
|
||||
ifa->ifa_refcnt--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a routing table entry, normally
|
||||
* for an interface.
|
||||
*/
|
||||
int rtinit(struct ifaddr *ifa, int cmd, int flags)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct sockaddr *dst;
|
||||
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(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 (cmd == RTM_DELETE && error == 0 && (rt = nrt) != NULL) {
|
||||
/* XXX - add this when we have routing sockets!
|
||||
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--;
|
||||
if (rt->rt_ifa != ifa) {
|
||||
printf("rtinit: wrong ifa (%p) was (%p)\n", ifa, rt->rt_ifa);
|
||||
|
||||
if (rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, 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;
|
||||
ifa->ifa_refcnt++;
|
||||
if (ifa->ifa_rtrequest)
|
||||
ifa->ifa_rtrequest(RTM_ADD, rt, NULL);
|
||||
}
|
||||
/* XXX - add this when we have routing sockets!
|
||||
rt_newaddrmsg(cmd, ifa, error, nrt);
|
||||
*/
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void rtable_init(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(void)
|
||||
{
|
||||
rn_init();
|
||||
|
||||
rtable_init((void**)rt_tables);
|
||||
}
|
@ -1,308 +0,0 @@
|
||||
/* socket "server" */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
#include <KernelExport.h>
|
||||
#endif
|
||||
|
||||
#include "core_private.h"
|
||||
#include <sys/socket.h>
|
||||
#include <net_socket.h>
|
||||
#include <pools.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <net_misc.h>
|
||||
#include <protocols.h>
|
||||
|
||||
uint32 sb_max = SB_MAX; /* hard value, recompile needed to alter :( */
|
||||
|
||||
/*
|
||||
* 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 sockbuf_reserve(struct sockbuf *sb, uint32 cc)
|
||||
{
|
||||
uint64 dd = (uint64)cc;
|
||||
uint64 ee = (sb_max * MCLBYTES) / ((MSIZE) + (MCLBYTES));
|
||||
|
||||
if (cc == 0)
|
||||
return 0;
|
||||
if (dd > ee)
|
||||
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);
|
||||
}
|
||||
|
||||
void sockbuf_drop(struct sockbuf *sb, int len)
|
||||
{
|
||||
struct mbuf *m, *mn;
|
||||
struct mbuf *next;
|
||||
|
||||
next = (m = sb->sb_mb) ? m->m_nextpkt : NULL;
|
||||
while (len > 0) {
|
||||
if (m == NULL) {
|
||||
if (next == NULL)
|
||||
return;
|
||||
|
||||
m = next;
|
||||
next = m->m_nextpkt;
|
||||
continue;
|
||||
}
|
||||
if ((int) 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free all mbufs in a sockbuf.
|
||||
* Check that all resources are reclaimed.
|
||||
*/
|
||||
void sockbuf_flush(struct sockbuf *sb)
|
||||
{
|
||||
if (sb->sb_flags & SB_LOCK) {
|
||||
return;
|
||||
}
|
||||
while (sb->sb_mbcnt)
|
||||
sockbuf_drop(sb, (int)sb->sb_cc);
|
||||
if (sb->sb_cc || sb->sb_mb)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free mbufs held by a socket, and reserved mbuf space.
|
||||
*/
|
||||
void sockbuf_release(struct sockbuf *sb)
|
||||
{
|
||||
sockbuf_flush(sb);
|
||||
sb->sb_hiwat = sb->sb_mbmax = 0;
|
||||
}
|
||||
|
||||
void sockbuf_append(struct sockbuf *sb, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *n;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
if ((n = sb->sb_mb) != NULL) {
|
||||
while (n->m_nextpkt)
|
||||
n = n->m_nextpkt;
|
||||
do {
|
||||
if (n->m_flags & M_EOR) {
|
||||
sockbuf_appendrecord(sb, m); /* XXXXXX!!!! */
|
||||
return;
|
||||
}
|
||||
} while (n->m_next && (n = n->m_next));
|
||||
}
|
||||
sockbuf_compress(sb, m, n);
|
||||
}
|
||||
|
||||
void sockbuf_appendrecord(struct sockbuf *sb, struct mbuf *m0)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
if (!m0)
|
||||
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;
|
||||
}
|
||||
sockbuf_compress(sb, m, m0);
|
||||
}
|
||||
|
||||
int sockbuf_appendaddr(struct sockbuf *sb, struct sockaddr *asa,
|
||||
struct mbuf *m0, struct mbuf *control)
|
||||
{
|
||||
struct mbuf *m, *n;
|
||||
int space = asa->sa_len;
|
||||
|
||||
if (m0 && (m0->m_flags & M_PKTHDR) == 0)
|
||||
return(-1);
|
||||
|
||||
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 > (int) sbspace(sb))
|
||||
return (0);
|
||||
if (asa->sa_len > MLEN)
|
||||
return (0);
|
||||
MGET(m, MT_SONAME);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = asa->sa_len;
|
||||
memcpy(mtod(m, caddr_t), (caddr_t)asa, 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);
|
||||
}
|
||||
|
||||
void sockbuf_compress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n)
|
||||
{
|
||||
int eor = 0;
|
||||
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) {
|
||||
memcpy(mtod(n, caddr_t) + n->m_len, mtod(m, caddr_t),
|
||||
(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
|
||||
printf("semi-panic: sockbuf_compress\n");
|
||||
}
|
||||
}
|
||||
|
||||
void sockbuf_droprecord(struct sockbuf *sb)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int sockbuf_wait(struct sockbuf *sb)
|
||||
{
|
||||
if (sb->sb_cc > 0)
|
||||
return 0;
|
||||
sb->sb_flags |= SB_WAIT;
|
||||
return nsleep(sb->sb_pop, "sockbuf_wait", sb->sb_timeo);
|
||||
}
|
||||
|
||||
void sockbuf_insertoob(struct sockbuf *sb, struct mbuf *m0)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct mbuf **mp;
|
||||
|
||||
if (m0 == NULL)
|
||||
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;
|
||||
}
|
||||
sockbuf_compress(sb, m, m0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock a sockbuf already known to be locked;
|
||||
* return any error returned from sleep (EINTR).
|
||||
*/
|
||||
int sockbuf_lock(struct sockbuf *sb) // XXX never called at all
|
||||
{
|
||||
int error;
|
||||
|
||||
while (sb->sb_flags & SB_LOCK) {
|
||||
sb->sb_flags |= SB_WANT;
|
||||
error = nsleep(sb->sb_sleep, "sockbuf_lock", 0);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
sb->sb_flags |= SB_LOCK;
|
||||
return (0);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network interfaces ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel network interfaces ethernet ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network interfaces loopback ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network interfaces ppp ;
|
@ -1,24 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network interfaces ethernet ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
KernelAddon ethernet : kernel obos_network interfaces :
|
||||
ethernet.c
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/interfaces
|
||||
: ethernet ;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
ethernet :
|
||||
boot home config add-ons kernel obos_network interfaces ;
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network interfaces loopback ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
KernelAddon loopback : kernel obos_network interfaces :
|
||||
loopback.c
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/interfaces
|
||||
: loopback ;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
loopback :
|
||||
boot home config add-ons kernel obos_network interfaces ;
|
@ -1,176 +0,0 @@
|
||||
/* loopback.c - loopback device
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include "sys/socket.h"
|
||||
#include "protocols.h"
|
||||
#include "netinet/in.h"
|
||||
#include "netinet/ip.h"
|
||||
#include "sys/socketvar.h"
|
||||
#include "sys/protosw.h"
|
||||
#include "sys/domain.h"
|
||||
#include "sys/sockio.h"
|
||||
|
||||
#include "net_malloc.h"
|
||||
#include "core_module.h"
|
||||
#include "net_module.h"
|
||||
#include "core_funcs.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
#define printf dprintf
|
||||
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
static struct core_module_info *core = NULL;
|
||||
|
||||
static struct protosw *proto[IPPROTO_MAX];
|
||||
static struct ifnet *me = NULL;
|
||||
|
||||
static int loopback_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
|
||||
struct rtentry *rt)
|
||||
{
|
||||
/* turn it straight back... */
|
||||
/* This is lame as we should be detecting the protocol, but it gets
|
||||
* us working.
|
||||
* XXX - fix me!
|
||||
*/
|
||||
struct ip *ip = mtod(m, struct ip *);
|
||||
|
||||
ip->ip_dst = ip->ip_src;
|
||||
ip->ip_src.s_addr = INADDR_LOOPBACK;
|
||||
|
||||
IFQ_ENQUEUE(ifp->rxq, m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void loopback_input(struct mbuf *buf)
|
||||
{
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
buf->m_pkthdr.rcvif = me;
|
||||
|
||||
if (proto[IPPROTO_IP] && proto[IPPROTO_IP]->pr_input) {
|
||||
proto[IPPROTO_IP]->pr_input(buf, 0);
|
||||
return;
|
||||
} else
|
||||
printf("No input tourtine found for IP\n");
|
||||
|
||||
m_freem(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
static int loopback_dev_stop(struct ifnet *dev)
|
||||
{
|
||||
if (!dev || dev->if_type != IFT_LOOP)
|
||||
return EINVAL;
|
||||
|
||||
dev->if_flags &= ~IFF_UP;
|
||||
|
||||
if (dev->rx_thread > 0)
|
||||
kill_thread(dev->rx_thread);
|
||||
if (dev->tx_thread > 0)
|
||||
kill_thread(dev->tx_thread);
|
||||
|
||||
dev->if_flags &= ~IFF_RUNNING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loopback_ioctl(struct ifnet *ifp, ulong cmd, caddr_t data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch(cmd) {
|
||||
case SIOCSIFADDR:
|
||||
ifp->if_flags |= (IFF_UP | IFF_RUNNING);
|
||||
if (ifp->rx_thread < 0)
|
||||
start_rx_thread(ifp);
|
||||
if (ifp->tx_thread < 0)
|
||||
start_tx_thread(ifp);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int loopback_init(void)
|
||||
{
|
||||
me = (struct ifnet*)malloc(sizeof(struct ifnet));
|
||||
if (!me)
|
||||
return -1;
|
||||
|
||||
memset(me, 0, sizeof(*me));
|
||||
|
||||
memset(proto, 0, sizeof(struct protosw *) * IPPROTO_MAX);
|
||||
|
||||
me->devid = -1;
|
||||
me->name = "loop";
|
||||
me->if_unit = 0;
|
||||
me->if_type = IFT_LOOP;
|
||||
me->rx_thread = -1;
|
||||
me->tx_thread = -1;
|
||||
me->if_addrlen = 0;
|
||||
me->if_hdrlen = 0;
|
||||
me->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
|
||||
me->if_mtu = 16384; /* can be as large as we want */
|
||||
me->input = &loopback_input;
|
||||
me->output = &loopback_output;
|
||||
me->stop = &loopback_dev_stop;
|
||||
me->ioctl = &loopback_ioctl;
|
||||
|
||||
add_protosw(proto, NET_LAYER1);
|
||||
if_attach(me);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loopback_module_init(void *cpp)
|
||||
{
|
||||
if (cpp)
|
||||
core = cpp;
|
||||
|
||||
loopback_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct kernel_net_module_info device_info = {
|
||||
{
|
||||
NETWORK_MODULES_ROOT "interfaces/loopback",
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
loopback_module_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
_EXPORT status_t std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
case B_MODULE_INIT:
|
||||
get_module(NET_CORE_MODULE_NAME, (module_info **)&core);
|
||||
if (!core)
|
||||
return B_ERROR;
|
||||
return B_OK;
|
||||
case B_MODULE_UNINIT:
|
||||
break;
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
_EXPORT module_info *modules[] = {
|
||||
(module_info*) &device_info,
|
||||
NULL
|
||||
};
|
||||
|
@ -1,39 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network interfaces ppp ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
|
||||
KernelAddon ppp : kernel obos_network interfaces :
|
||||
ppp.cpp
|
||||
PPPManager.cpp
|
||||
;
|
||||
|
||||
LinkAgainst ppp : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/interfaces
|
||||
: ppp ;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
ppp :
|
||||
boot home config add-ons kernel obos_network interfaces ;
|
@ -1,862 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Waldemar Kornewald <wkornew@gmx.net>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "PPPManager.h"
|
||||
#include <PPPControl.h>
|
||||
#include <KPPPModule.h>
|
||||
#include <KPPPUtils.h>
|
||||
#include <settings_tools.h>
|
||||
|
||||
#include <net_stack_driver.h>
|
||||
|
||||
#include <LockerHelper.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
|
||||
static const char sKPPPIfNameBase[] = "ppp";
|
||||
|
||||
|
||||
static
|
||||
status_t
|
||||
deleter_thread(void *data)
|
||||
{
|
||||
PPPManager *manager = (PPPManager*) data;
|
||||
thread_id sender;
|
||||
int32 code;
|
||||
|
||||
while(true) {
|
||||
manager->DeleterThreadEvent();
|
||||
|
||||
// check if the manager is being destroyed
|
||||
if(receive_data_with_timeout(&sender, &code, NULL, 0, 500) == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
pulse_timer(void *data)
|
||||
{
|
||||
((PPPManager*)data)->Pulse();
|
||||
}
|
||||
|
||||
|
||||
PPPManager::PPPManager()
|
||||
: fLock("PPPManager"),
|
||||
fReportLock("PPPManagerReportLock"),
|
||||
fDefaultInterface(NULL),
|
||||
fReportManager(fReportLock),
|
||||
fNextID(1)
|
||||
{
|
||||
TRACE("PPPManager: Constructor\n");
|
||||
|
||||
fDeleterThread = spawn_kernel_thread(deleter_thread, "PPPManager: deleter_thread",
|
||||
B_NORMAL_PRIORITY, this);
|
||||
resume_thread(fDeleterThread);
|
||||
fPulseTimer = net_add_timer(pulse_timer, this, PPP_PULSE_RATE);
|
||||
}
|
||||
|
||||
|
||||
PPPManager::~PPPManager()
|
||||
{
|
||||
TRACE("PPPManager: Destructor\n");
|
||||
|
||||
int32 tmp;
|
||||
send_data(fDeleterThread, 0, NULL, 0);
|
||||
// notify deleter_thread that we are being destroyed
|
||||
wait_for_thread(fDeleterThread, &tmp);
|
||||
net_remove_timer(fPulseTimer);
|
||||
|
||||
// now really delete the interfaces (the deleter_thread is not running)
|
||||
ppp_interface_entry *entry = NULL;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry) {
|
||||
delete entry->interface;
|
||||
free(entry->name);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
free(fDefaultInterface);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PPPManager::Stop(ifnet *ifp)
|
||||
{
|
||||
TRACE("PPPManager: Stop(%s)\n", ifp ? ifp->if_name : "Unknown");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(ifp);
|
||||
if(!entry) {
|
||||
ERROR("PPPManager: Stop(): Could not find interface!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
DeleteInterface(entry->interface->ID());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
|
||||
struct rtentry *rt0)
|
||||
{
|
||||
TRACE("PPPManager: Output(%s)\n", ifp ? ifp->if_name : "Unknown");
|
||||
|
||||
if(dst->sa_family == AF_UNSPEC)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
ppp_interface_entry *entry = EntryFor(ifp);
|
||||
if(!entry) {
|
||||
ERROR("PPPManager: Output(): Could not find interface!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
atomic_add(&entry->accessing, 1);
|
||||
locker.UnlockNow();
|
||||
|
||||
if(!entry->interface->DoesConnectOnDemand()
|
||||
&& ifp->if_flags & (IFF_UP | IFF_RUNNING) != (IFF_UP | IFF_RUNNING)) {
|
||||
m_freem(buf);
|
||||
atomic_add(&entry->accessing, -1);
|
||||
return ENETDOWN;
|
||||
}
|
||||
|
||||
int32 result = B_ERROR;
|
||||
KPPPProtocol *protocol = entry->interface->FirstProtocol();
|
||||
for(; protocol; protocol = protocol->NextProtocol()) {
|
||||
if(!protocol->IsEnabled() || protocol->AddressFamily() != dst->sa_family)
|
||||
continue;
|
||||
|
||||
if(protocol->Flags() & PPP_INCLUDES_NCP)
|
||||
result = protocol->Send(buf, protocol->ProtocolNumber() & 0x7FFF);
|
||||
else
|
||||
result = protocol->Send(buf, protocol->ProtocolNumber());
|
||||
if(result == PPP_UNHANDLED)
|
||||
continue;
|
||||
|
||||
atomic_add(&entry->accessing, -1);
|
||||
return result;
|
||||
}
|
||||
|
||||
m_freem(buf);
|
||||
atomic_add(&entry->accessing, -1);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
|
||||
{
|
||||
TRACE("PPPManager: Control(%s)\n", ifp ? ifp->if_name : "Unknown");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
ppp_interface_entry *entry = EntryFor(ifp);
|
||||
if(!entry || entry->deleting) {
|
||||
ERROR("PPPManager: Control(): Could not find interface!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
int32 status = B_OK;
|
||||
atomic_add(&entry->accessing, 1);
|
||||
locker.UnlockNow();
|
||||
|
||||
switch(cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
if(((ifreq*)data)->ifr_flags & IFF_DOWN) {
|
||||
if(entry->interface->DoesConnectOnDemand()
|
||||
&& entry->interface->Phase() == PPP_DOWN_PHASE)
|
||||
DeleteInterface(entry->interface->ID());
|
||||
else
|
||||
entry->interface->Down();
|
||||
} else if(((ifreq*)data)->ifr_flags & IFF_UP)
|
||||
entry->interface->Up();
|
||||
break;
|
||||
|
||||
default:
|
||||
status = entry->interface->StackControl(cmd, data);
|
||||
}
|
||||
|
||||
atomic_add(&entry->accessing, -1);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_id
|
||||
PPPManager::CreateInterface(const driver_settings *settings,
|
||||
ppp_interface_id parentID)
|
||||
{
|
||||
return _CreateInterface(NULL, settings, parentID);
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_id
|
||||
PPPManager::CreateInterfaceWithName(const char *name,
|
||||
ppp_interface_id parentID)
|
||||
{
|
||||
if(!name)
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
|
||||
ppp_interface_id result = _CreateInterface(name, NULL, parentID);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPManager::DeleteInterface(ppp_interface_id ID)
|
||||
{
|
||||
TRACE("PPPManager: DeleteInterface(%ld)\n", ID);
|
||||
|
||||
// This only marks the interface for deletion.
|
||||
// Our deleter_thread does the real work.
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(ID);
|
||||
if(!entry)
|
||||
return false;
|
||||
|
||||
if(entry->deleting)
|
||||
return true;
|
||||
// this prevents an endless loop between Delete() and interface->Down()
|
||||
|
||||
entry->deleting = true;
|
||||
atomic_add(&entry->accessing, 1);
|
||||
locker.UnlockNow();
|
||||
|
||||
// bring interface down if needed
|
||||
if(entry->interface->State() != PPP_INITIAL_STATE
|
||||
|| entry->interface->Phase() != PPP_DOWN_PHASE)
|
||||
entry->interface->Down();
|
||||
|
||||
atomic_add(&entry->accessing, -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPManager::RemoveInterface(ppp_interface_id ID)
|
||||
{
|
||||
TRACE("PPPManager: RemoveInterface(%ld)\n", ID);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
int32 index;
|
||||
ppp_interface_entry *entry = EntryFor(ID, &index);
|
||||
if(!entry || entry->deleting)
|
||||
return false;
|
||||
|
||||
UnregisterInterface(ID);
|
||||
|
||||
delete entry;
|
||||
fEntries.RemoveItem(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ifnet*
|
||||
PPPManager::RegisterInterface(ppp_interface_id ID)
|
||||
{
|
||||
TRACE("PPPManager: RegisterInterface(%ld)\n", ID);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(ID);
|
||||
if(!entry || entry->deleting)
|
||||
return NULL;
|
||||
|
||||
// maybe the interface is already registered
|
||||
if(entry->interface->Ifnet())
|
||||
return entry->interface->Ifnet();
|
||||
|
||||
// TODO: allocate struct around ifnet with pointer to entry so we can optimize
|
||||
// ifnet->ppp_interface_entry translation (speeds-up Output()/Input())
|
||||
ifnet *ifp = (ifnet*) malloc(sizeof(ifnet));
|
||||
memset(ifp, 0, sizeof(ifnet));
|
||||
ifp->devid = -1;
|
||||
ifp->if_type = IFT_PPP;
|
||||
ifp->name = (char*)sKPPPIfNameBase;
|
||||
ifp->if_unit = FindUnit();
|
||||
ifp->if_flags = IFF_POINTOPOINT;
|
||||
ifp->rx_thread = ifp->tx_thread = -1;
|
||||
ifp->start = NULL;
|
||||
ifp->stop = ppp_ifnet_stop;
|
||||
ifp->output = ppp_ifnet_output;
|
||||
ifp->ioctl = ppp_ifnet_ioctl;
|
||||
|
||||
TRACE("PPPManager::RegisterInterface(): Created new ifnet: %s%d\n",
|
||||
ifp->name, ifp->if_unit);
|
||||
|
||||
if_attach(ifp);
|
||||
return ifp;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPManager::UnregisterInterface(ppp_interface_id ID)
|
||||
{
|
||||
TRACE("PPPManager: UnregisterInterface(%ld)\n", ID);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(ID);
|
||||
if(!entry)
|
||||
return false;
|
||||
|
||||
if(entry->interface->Ifnet()) {
|
||||
if_detach(entry->interface->Ifnet());
|
||||
free(entry->interface->Ifnet());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPManager::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
TRACE("PPPManager: Control(%ld)\n", op);
|
||||
|
||||
// this method is intended for use by userland applications
|
||||
|
||||
switch(op) {
|
||||
case PPPC_CONTROL_MODULE: {
|
||||
if(length < sizeof(control_net_module_args) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
control_net_module_args *args = (control_net_module_args*) data;
|
||||
if(!args->name)
|
||||
return B_ERROR;
|
||||
|
||||
char name[B_PATH_NAME_LENGTH];
|
||||
sprintf(name, "%s/%s", PPP_MODULES_PATH, args->name);
|
||||
ppp_module_info *module;
|
||||
if(get_module(name, (module_info**) &module) != B_OK
|
||||
|| !module->control)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
return module->control(args->op, args->data, args->length);
|
||||
} break;
|
||||
|
||||
case PPPC_CREATE_INTERFACE: {
|
||||
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_interface_description_info *info
|
||||
= (ppp_interface_description_info*) data;
|
||||
if(!info->u.settings)
|
||||
return B_ERROR;
|
||||
|
||||
info->interface = CreateInterface(info->u.settings);
|
||||
// parents cannot be set from userland
|
||||
return info->interface != PPP_UNDEFINED_INTERFACE_ID ? B_OK : B_ERROR;
|
||||
} break;
|
||||
|
||||
case PPPC_CREATE_INTERFACE_WITH_NAME: {
|
||||
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_interface_description_info *info
|
||||
= (ppp_interface_description_info*) data;
|
||||
if(!info->u.name)
|
||||
return B_ERROR;
|
||||
|
||||
info->interface = CreateInterfaceWithName(info->u.name);
|
||||
// parents cannot be set from userland
|
||||
return info->interface != PPP_UNDEFINED_INTERFACE_ID ? B_OK : B_ERROR;
|
||||
} break;
|
||||
|
||||
case PPPC_DELETE_INTERFACE:
|
||||
if(length != sizeof(ppp_interface_id) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
if(!DeleteInterface(*(ppp_interface_id*)data))
|
||||
return B_ERROR;
|
||||
break;
|
||||
|
||||
case PPPC_BRING_INTERFACE_UP: {
|
||||
if(length != sizeof(ppp_interface_id) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(*(ppp_interface_id*)data);
|
||||
if(!entry || entry->deleting)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
atomic_add(&entry->accessing, 1);
|
||||
locker.UnlockNow();
|
||||
|
||||
entry->interface->Up();
|
||||
atomic_add(&entry->accessing, -1);
|
||||
} break;
|
||||
|
||||
case PPPC_BRING_INTERFACE_DOWN: {
|
||||
if(length != sizeof(ppp_interface_id) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(*(ppp_interface_id*)data);
|
||||
if(!entry || entry->deleting)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
atomic_add(&entry->accessing, 1);
|
||||
locker.UnlockNow();
|
||||
|
||||
entry->interface->Down();
|
||||
atomic_add(&entry->accessing, -1);
|
||||
} break;
|
||||
|
||||
case PPPC_CONTROL_INTERFACE: {
|
||||
if(length < sizeof(ppp_control_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_control_info *control = (ppp_control_info*) data;
|
||||
|
||||
return ControlInterface(control->index, control->op, control->data,
|
||||
control->length);
|
||||
} break;
|
||||
|
||||
case PPPC_GET_INTERFACES: {
|
||||
if(length < sizeof(ppp_get_interfaces_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_get_interfaces_info *info = (ppp_get_interfaces_info*) data;
|
||||
if(!info->interfaces)
|
||||
return B_ERROR;
|
||||
|
||||
info->resultCount = GetInterfaces(info->interfaces, info->count,
|
||||
info->filter);
|
||||
return info->resultCount >= 0 ? B_OK : B_ERROR;
|
||||
} break;
|
||||
|
||||
case PPPC_COUNT_INTERFACES:
|
||||
if(length != sizeof(ppp_interface_filter) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
return CountInterfaces(*(ppp_interface_filter*)data);
|
||||
break;
|
||||
|
||||
case PPPC_FIND_INTERFACE_WITH_SETTINGS: {
|
||||
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_interface_description_info *info
|
||||
= (ppp_interface_description_info*) data;
|
||||
if(!info->u.settings)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(info->u.settings);
|
||||
if(entry)
|
||||
info->interface = entry->interface->ID();
|
||||
else {
|
||||
info->interface = PPP_UNDEFINED_INTERFACE_ID;
|
||||
return B_ERROR;
|
||||
}
|
||||
} break;
|
||||
|
||||
case PPPC_ENABLE_REPORTS: {
|
||||
if(length < sizeof(ppp_report_request) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_report_request *request = (ppp_report_request*) data;
|
||||
ReportManager().EnableReports(request->type, request->thread,
|
||||
request->flags);
|
||||
} break;
|
||||
|
||||
case PPPC_DISABLE_REPORTS: {
|
||||
if(length < sizeof(ppp_report_request) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_report_request *request = (ppp_report_request*) data;
|
||||
ReportManager().DisableReports(request->type, request->thread);
|
||||
} break;
|
||||
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPManager::ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
|
||||
{
|
||||
TRACE("PPPManager: ControlInterface(%ld)\n", ID);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
status_t result = B_BAD_INDEX;
|
||||
ppp_interface_entry *entry = EntryFor(ID);
|
||||
if(entry && !entry->deleting) {
|
||||
atomic_add(&entry->accessing, 1);
|
||||
locker.UnlockNow();
|
||||
result = entry->interface->Control(op, data, length);
|
||||
atomic_add(&entry->accessing, -1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PPPManager::GetInterfaces(ppp_interface_id *interfaces, int32 count,
|
||||
ppp_interface_filter filter)
|
||||
{
|
||||
TRACE("PPPManager: GetInterfaces()\n");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
int32 item = 0;
|
||||
// the current item in 'interfaces' (also the number of ids copied)
|
||||
ppp_interface_entry *entry;
|
||||
|
||||
for(int32 index = 0; item < count && index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(!entry || entry->deleting)
|
||||
continue;
|
||||
|
||||
switch(filter) {
|
||||
case PPP_ALL_INTERFACES:
|
||||
interfaces[item++] = entry->interface->ID();
|
||||
break;
|
||||
|
||||
case PPP_REGISTERED_INTERFACES:
|
||||
if(entry->interface->Ifnet())
|
||||
interfaces[item++] = entry->interface->ID();
|
||||
break;
|
||||
|
||||
case PPP_UNREGISTERED_INTERFACES:
|
||||
if(!entry->interface->Ifnet())
|
||||
interfaces[item++] = entry->interface->ID();
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
// the filter is unknown
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PPPManager::CountInterfaces(ppp_interface_filter filter)
|
||||
{
|
||||
TRACE("PPPManager: CountInterfaces()\n");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
if(filter == PPP_ALL_INTERFACES)
|
||||
return fEntries.CountItems();
|
||||
|
||||
int32 count = 0;
|
||||
ppp_interface_entry *entry;
|
||||
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(!entry || entry->deleting)
|
||||
continue;
|
||||
|
||||
switch(filter) {
|
||||
case PPP_REGISTERED_INTERFACES:
|
||||
if(entry->interface->Ifnet())
|
||||
++count;
|
||||
break;
|
||||
|
||||
case PPP_UNREGISTERED_INTERFACES:
|
||||
if(!entry->interface->Ifnet())
|
||||
++count;
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
// the filter is unknown
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_entry*
|
||||
PPPManager::EntryFor(ppp_interface_id ID, int32 *saveIndex) const
|
||||
{
|
||||
TRACE("PPPManager: EntryFor(%ld)\n", ID);
|
||||
|
||||
if(ID == PPP_UNDEFINED_INTERFACE_ID)
|
||||
return NULL;
|
||||
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry && entry->interface->ID() == ID) {
|
||||
if(saveIndex)
|
||||
*saveIndex = index;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_entry*
|
||||
PPPManager::EntryFor(ifnet *ifp, int32 *saveIndex) const
|
||||
{
|
||||
if(!ifp)
|
||||
return NULL;
|
||||
|
||||
TRACE("PPPManager: EntryFor(%s%d)\n", ifp->name, ifp->if_unit);
|
||||
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry && entry->interface->Ifnet() == ifp) {
|
||||
if(saveIndex)
|
||||
*saveIndex = index;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_entry*
|
||||
PPPManager::EntryFor(const char *name, int32 *saveIndex) const
|
||||
{
|
||||
if(!name)
|
||||
return NULL;
|
||||
|
||||
TRACE("PPPManager: EntryFor(%s)\n", name);
|
||||
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry && entry->name && !strcmp(entry->name, name)) {
|
||||
if(saveIndex)
|
||||
*saveIndex = index;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_entry*
|
||||
PPPManager::EntryFor(const driver_settings *settings) const
|
||||
{
|
||||
if(!settings)
|
||||
return NULL;
|
||||
|
||||
TRACE("PPPManager: EntryFor(settings)\n");
|
||||
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry && equal_interface_settings(entry->interface->Settings(), settings))
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPManager::SettingsChanged()
|
||||
{
|
||||
// get default interface name and update interfaces if it changed
|
||||
void *handle = load_driver_settings("ptpnet.settings");
|
||||
const char *name = get_driver_parameter(handle, "default", NULL, NULL);
|
||||
|
||||
if((!fDefaultInterface && !name) || (fDefaultInterface && name
|
||||
&& !strcmp(name, fDefaultInterface))) {
|
||||
unload_driver_settings(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
ppp_interface_entry *entry = EntryFor(fDefaultInterface);
|
||||
if(entry && entry->interface->StateMachine().Phase() == PPP_DOWN_PHASE)
|
||||
DeleteInterface(entry->interface->ID());
|
||||
|
||||
free(fDefaultInterface);
|
||||
if(!name) {
|
||||
fDefaultInterface = NULL;
|
||||
unload_driver_settings(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
fDefaultInterface = strdup(name);
|
||||
unload_driver_settings(handle);
|
||||
ppp_interface_id id = CreateInterfaceWithName(fDefaultInterface);
|
||||
entry = EntryFor(id);
|
||||
if(entry)
|
||||
entry->interface->SetConnectOnDemand(true);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int
|
||||
greater(const void *a, const void *b)
|
||||
{
|
||||
return (*(const int*)a - *(const int*)b);
|
||||
}
|
||||
|
||||
|
||||
// used by the public CreateInterface() methods
|
||||
ppp_interface_id
|
||||
PPPManager::_CreateInterface(const char *name,
|
||||
const driver_settings *settings, ppp_interface_id parentID)
|
||||
{
|
||||
TRACE("PPPManager: CreateInterface(%s)\n", name ? name : "Unnamed");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *parentEntry = EntryFor(parentID);
|
||||
if(parentID != PPP_UNDEFINED_INTERFACE_ID && !parentEntry)
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
|
||||
// the day when NextID() returns 0 will come, be prepared! ;)
|
||||
ppp_interface_id id = NextID();
|
||||
if(id == PPP_UNDEFINED_INTERFACE_ID)
|
||||
id = NextID();
|
||||
|
||||
// check if we already have an entry for the named interface
|
||||
ppp_interface_entry *entry = EntryFor(name);
|
||||
if(entry)
|
||||
return entry->interface->ID();
|
||||
|
||||
entry = new ppp_interface_entry;
|
||||
entry->name = name ? strdup(name) : NULL;
|
||||
entry->accessing = 1;
|
||||
entry->deleting = false;
|
||||
fEntries.AddItem(entry);
|
||||
// nothing bad can happen because we are in a locked section
|
||||
|
||||
new KPPPInterface(name, entry, id, settings,
|
||||
parentEntry ? parentEntry->interface : NULL);
|
||||
// KPPPInterface will add itself to the entry (no need to do it here)
|
||||
if(entry->interface->InitCheck() != B_OK) {
|
||||
delete entry->interface;
|
||||
free(entry->name);
|
||||
fEntries.RemoveItem(entry);
|
||||
delete entry;
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
}
|
||||
|
||||
// hidden/child interfaces should never bother the user
|
||||
if(!entry->name)
|
||||
entry->interface->SetAskBeforeConnecting(false);
|
||||
|
||||
locker.UnlockNow();
|
||||
// it is safe to access the manager from userland now
|
||||
|
||||
Report(PPP_MANAGER_REPORT, PPP_REPORT_INTERFACE_CREATED, &id,
|
||||
sizeof(ppp_interface_id));
|
||||
|
||||
// notify handlers that interface has been created and they can initialize it now
|
||||
entry->interface->StateMachine().DownProtocols();
|
||||
entry->interface->StateMachine().ResetLCPHandlers();
|
||||
|
||||
atomic_add(&entry->accessing, -1);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PPPManager::FindUnit() const
|
||||
{
|
||||
// Find the smallest unused unit.
|
||||
int32 *units = new int32[fEntries.CountItems()];
|
||||
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry && entry->interface->Ifnet())
|
||||
units[index] = entry->interface->Ifnet()->if_unit;
|
||||
else
|
||||
units[index] = -1;
|
||||
}
|
||||
|
||||
qsort(units, fEntries.CountItems(), sizeof(int32), greater);
|
||||
|
||||
int32 unit = 0;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
if(units[index] > unit)
|
||||
return unit;
|
||||
else if(units[index] == unit)
|
||||
++unit;
|
||||
}
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPManager::DeleterThreadEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
SettingsChanged();
|
||||
// TODO: Use Haiku's kernel node monitoring capabilities
|
||||
|
||||
// delete and remove marked interfaces
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry && entry->deleting && entry->accessing <= 0) {
|
||||
delete entry->interface;
|
||||
fEntries.RemoveItem(index);
|
||||
--index;
|
||||
|
||||
// recreate default interface
|
||||
if(entry->name && fDefaultInterface &&
|
||||
!strcmp(entry->name, fDefaultInterface)) {
|
||||
free(fDefaultInterface);
|
||||
fDefaultInterface = NULL;
|
||||
SettingsChanged();
|
||||
}
|
||||
|
||||
free(entry->name);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPManager::Pulse()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
ppp_interface_entry *entry;
|
||||
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||
entry = fEntries.ItemAt(index);
|
||||
if(entry)
|
||||
entry->interface->Pulse();
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Waldemar Kornewald <wkornew@gmx.net>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _PPP_MANAGER__H
|
||||
#define _PPP_MANAGER__H
|
||||
|
||||
#include <KPPPInterface.h>
|
||||
#include <KPPPManager.h>
|
||||
#include <core_funcs.h>
|
||||
|
||||
|
||||
// these functions are defined in ppp.cpp
|
||||
extern int ppp_ifnet_stop(ifnet *ifp);
|
||||
extern int ppp_ifnet_output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
|
||||
struct rtentry *rt0);
|
||||
extern int ppp_ifnet_ioctl(ifnet *ifp, ulong cmd, caddr_t data);
|
||||
|
||||
|
||||
class PPPManager {
|
||||
public:
|
||||
PPPManager();
|
||||
~PPPManager();
|
||||
|
||||
int32 Stop(ifnet *ifp);
|
||||
int32 Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
|
||||
struct rtentry *rt0);
|
||||
int32 Control(ifnet *ifp, ulong cmd, caddr_t data);
|
||||
|
||||
ppp_interface_id CreateInterface(const driver_settings *settings,
|
||||
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
|
||||
ppp_interface_id CreateInterfaceWithName(const char *name,
|
||||
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
|
||||
bool DeleteInterface(ppp_interface_id ID);
|
||||
bool RemoveInterface(ppp_interface_id ID);
|
||||
|
||||
ifnet *RegisterInterface(ppp_interface_id ID);
|
||||
bool UnregisterInterface(ppp_interface_id ID);
|
||||
|
||||
status_t Control(uint32 op, void *data, size_t length);
|
||||
status_t ControlInterface(ppp_interface_id ID, uint32 op, void *data,
|
||||
size_t length);
|
||||
|
||||
int32 GetInterfaces(ppp_interface_id *interfaces, int32 count,
|
||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
|
||||
int32 CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
|
||||
|
||||
KPPPReportManager& ReportManager()
|
||||
{ return fReportManager; }
|
||||
bool Report(ppp_report_type type, int32 code, void *data, int32 length)
|
||||
{ return ReportManager().Report(type, code, data, length); }
|
||||
// returns false if reply was bad (or an error occured)
|
||||
|
||||
// these methods must be called from a locked section
|
||||
ppp_interface_entry *EntryFor(ppp_interface_id ID,
|
||||
int32 *saveIndex = NULL) const;
|
||||
ppp_interface_entry *EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const;
|
||||
ppp_interface_entry *EntryFor(const char *name, int32 *saveIndex = NULL) const;
|
||||
ppp_interface_entry *EntryFor(const driver_settings *settings) const;
|
||||
|
||||
void SettingsChanged();
|
||||
|
||||
ppp_interface_id NextID()
|
||||
{ return (ppp_interface_id) atomic_add((int32*) &fNextID, 1); }
|
||||
|
||||
void DeleterThreadEvent();
|
||||
void Pulse();
|
||||
|
||||
private:
|
||||
ppp_interface_id _CreateInterface(const char *name,
|
||||
const driver_settings *settings, ppp_interface_id parentID);
|
||||
int32 FindUnit() const;
|
||||
|
||||
private:
|
||||
BLocker fLock, fReportLock;
|
||||
char *fDefaultInterface;
|
||||
KPPPReportManager fReportManager;
|
||||
TemplateList<ppp_interface_entry*> fEntries;
|
||||
ppp_interface_id fNextID;
|
||||
thread_id fDeleterThread, fPulseTimer;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Waldemar Kornewald <wkornew@gmx.net>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <core_funcs.h>
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <PPPDefs.h>
|
||||
#include "PPPManager.h"
|
||||
|
||||
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
struct core_module_info *core = NULL;
|
||||
static PPPManager *sManager = NULL;
|
||||
|
||||
|
||||
int
|
||||
ppp_ifnet_stop(ifnet *ifp)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->Stop(ifp);
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ppp_ifnet_output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
|
||||
struct rtentry *rt0)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->Output(ifp, buf, dst, rt0);
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ppp_ifnet_ioctl(ifnet *ifp, ulong cmd, caddr_t data)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->Control(ifp, cmd, data);
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int
|
||||
ppp_start(void *cpp)
|
||||
{
|
||||
if(cpp)
|
||||
core = (core_module_info*) cpp;
|
||||
|
||||
sManager = new PPPManager;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int
|
||||
ppp_stop()
|
||||
{
|
||||
delete sManager;
|
||||
sManager = NULL;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// PPPManager wrappers
|
||||
static
|
||||
status_t
|
||||
ppp_control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->Control(op, data, length);
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
ppp_interface_id
|
||||
CreateInterface(const driver_settings *settings, ppp_interface_id parent)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->CreateInterface(settings, parent);
|
||||
else
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
ppp_interface_id
|
||||
CreateInterfaceWithName(const char *name, ppp_interface_id parent)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->CreateInterfaceWithName(name, parent);
|
||||
else
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool
|
||||
DeleteInterface(ppp_interface_id ID)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->DeleteInterface(ID);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool
|
||||
RemoveInterface(ppp_interface_id ID)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->RemoveInterface(ID);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
ifnet*
|
||||
RegisterInterface(ppp_interface_id ID)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->RegisterInterface(ID);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool
|
||||
UnregisterInterface(ppp_interface_id ID)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->UnregisterInterface(ID);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
status_t
|
||||
ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->ControlInterface(ID, op, data, length);
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int32
|
||||
GetInterfaces(ppp_interface_id *interfaces, int32 count,
|
||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->GetInterfaces(interfaces, count, filter);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int32
|
||||
CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->CountInterfaces(filter);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
EnableReports(ppp_report_type type, thread_id thread, int32 flags = PPP_NO_FLAGS)
|
||||
{
|
||||
if(sManager)
|
||||
sManager->ReportManager().EnableReports(type, thread, flags);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
DisableReports(ppp_report_type type, thread_id thread)
|
||||
{
|
||||
if(sManager)
|
||||
sManager->ReportManager().DisableReports(type, thread);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool
|
||||
DoesReport(ppp_report_type type, thread_id thread)
|
||||
{
|
||||
if(sManager)
|
||||
return sManager->ReportManager().DoesReport(type, thread);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ppp_interface_module_info ppp_interface_module = {
|
||||
{
|
||||
{
|
||||
PPP_INTERFACE_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
ppp_start,
|
||||
ppp_stop,
|
||||
ppp_control
|
||||
},
|
||||
CreateInterface,
|
||||
CreateInterfaceWithName,
|
||||
DeleteInterface,
|
||||
RemoveInterface,
|
||||
RegisterInterface,
|
||||
UnregisterInterface,
|
||||
ControlInterface,
|
||||
GetInterfaces,
|
||||
CountInterfaces,
|
||||
EnableReports,
|
||||
DisableReports,
|
||||
DoesReport
|
||||
};
|
||||
|
||||
|
||||
_EXPORT
|
||||
status_t
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
case B_MODULE_INIT:
|
||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**)&core) != B_OK)
|
||||
return B_ERROR;
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
_EXPORT
|
||||
module_info *modules[] = {
|
||||
(module_info*) &ppp_interface_module,
|
||||
NULL
|
||||
};
|
@ -1,9 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network protocols ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols icmp ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols ipv4 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols tcp ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols udp ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols raw ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols route ;
|
||||
|
@ -1,24 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network protocols icmp ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
KernelAddon icmp : kernel obos_network protocols :
|
||||
icmp.c
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/protocols
|
||||
: icmp ;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
icmp :
|
||||
boot home config add-ons kernel obos_network protocols ;
|
@ -1,466 +0,0 @@
|
||||
/* icmp.c
|
||||
*/
|
||||
#ifndef _KERNEL_MODE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "net_misc.h"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include "protocols.h"
|
||||
#include "sys/protosw.h"
|
||||
#include "sys/domain.h"
|
||||
#include <netinet/icmp_var.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "core_module.h"
|
||||
#include "net_module.h"
|
||||
#include "core_funcs.h"
|
||||
#include "raw_module.h"
|
||||
#include "icmp_module.h"
|
||||
#include "ipv4_module.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
/* private variables */
|
||||
static struct core_module_info *core = NULL;
|
||||
static struct raw_module_info *raw = NULL;
|
||||
static struct protosw* proto[IPPROTO_MAX];
|
||||
static struct in_ifaddr *ic_ifaddr = NULL;
|
||||
static struct ipv4_module_info *ipm = NULL;
|
||||
|
||||
struct icmpstat icmpstat;
|
||||
|
||||
static struct route icmprt;
|
||||
|
||||
#if SHOW_DEBUG
|
||||
static void dump_icmp(struct mbuf *buf)
|
||||
{
|
||||
struct ip *ip = mtod(buf, struct ip *);
|
||||
struct icmp *ic = (struct icmp*)((caddr_t)ip + (ip->ip_hl * 4));
|
||||
|
||||
printf("ICMP: ");
|
||||
switch (ic->icmp_type) {
|
||||
case ICMP_ECHO:
|
||||
printf ("Echo request\n");
|
||||
break;
|
||||
case ICMP_ECHOREPLY:
|
||||
printf("echo reply\n");
|
||||
break;
|
||||
default:
|
||||
printf("?? type = %d\n", ic->icmp_type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void icmp_send(struct mbuf *m, struct mbuf *opts)
|
||||
{
|
||||
struct ip *ip = mtod(m, struct ip*);
|
||||
int hlen;
|
||||
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, 0);
|
||||
m->m_data -= hlen;
|
||||
m->m_len += hlen;
|
||||
proto[IPPROTO_IP]->pr_output(m, opts, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static void icmp_reflect(struct mbuf *m)
|
||||
{
|
||||
struct ip *ip = mtod(m, struct ip*);
|
||||
struct in_ifaddr *ia;
|
||||
struct in_addr t;
|
||||
struct mbuf *opts = NULL;
|
||||
int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
|
||||
struct sockaddr_in icmpdst;
|
||||
|
||||
if (!ic_ifaddr) {
|
||||
ic_ifaddr = get_primary_addr();
|
||||
if (!ic_ifaddr) {
|
||||
printf("icmp_reflect: no interfaces available (ic_ifaddr == NULL)\n");
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_canforward(ip->ip_src) &&
|
||||
((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=
|
||||
(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
|
||||
printf("icmp_reflect: can't forward packet!\n");
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
t = ip->ip_dst;
|
||||
ip->ip_dst = ip->ip_src;
|
||||
for (ia = ic_ifaddr; ia; ia = ia->ia_next) {
|
||||
if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr)
|
||||
break;
|
||||
if ((ia->ia_ifp->if_flags & IFF_BROADCAST) &&
|
||||
t.s_addr == satosin(&ia->ia_broadaddr)->sin_addr.s_addr)
|
||||
break;
|
||||
}
|
||||
icmpdst.sin_addr = t;
|
||||
if (ia == NULL)
|
||||
ia = (struct in_ifaddr*)ifaof_ifpforaddr((struct sockaddr*)&icmpdst,
|
||||
m->m_pkthdr.rcvif);
|
||||
if (ia == NULL)
|
||||
ia = get_primary_addr(); //XXX is this right?
|
||||
t = IA_SIN(ia)->sin_addr;
|
||||
ip->ip_src = t;
|
||||
ip->ip_ttl = MAXTTL;
|
||||
if (optlen > 0) {
|
||||
uint8 *cp;
|
||||
int opt, cnt, len;
|
||||
|
||||
cp = (uint8*)(ip + 1);
|
||||
if ((opts = ipm->srcroute()) == 0 &&
|
||||
(opts = m_gethdr(MT_HEADER))) {
|
||||
opts->m_len = sizeof(struct in_addr);
|
||||
mtod(opts, struct in_addr*)->s_addr = 0;
|
||||
}
|
||||
if (opts) {
|
||||
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;
|
||||
}
|
||||
if (opt == IPOPT_RR || opt == IPOPT_TS ||
|
||||
opt == IPOPT_SECURITY) {
|
||||
memcpy((void*)(mtod(opts, char*) + opts->m_len),
|
||||
(void*)cp, len);
|
||||
opts->m_len += len;
|
||||
}
|
||||
}
|
||||
if ((cnt = opts->m_len % 4)) {
|
||||
for (; cnt < 4; cnt++) {
|
||||
*(mtod(opts, char*) + opts->m_len) = IPOPT_EOL;
|
||||
opts->m_len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
memcpy((void*)(ip + 1), (void*)(ip + optlen),
|
||||
(uint)(m->m_len - sizeof(struct ip)));
|
||||
}
|
||||
m->m_flags &= ~(M_BCAST | M_MCAST);
|
||||
icmp_send(m, opts);
|
||||
done:
|
||||
if (opts)
|
||||
m_free(opts);
|
||||
}
|
||||
|
||||
static void icmp_input(struct mbuf *buf, int hdrlen)
|
||||
{
|
||||
struct ip *ip = mtod(buf, struct ip *);
|
||||
struct icmp *ic;
|
||||
int icl = ip->ip_len;
|
||||
int i;
|
||||
uint16 rv;
|
||||
int code;
|
||||
struct sockaddr_in icmpsrc = {sizeof(struct sockaddr_in), AF_INET};
|
||||
|
||||
if (icl < ICMP_MINLEN) {
|
||||
icmpstat.icps_tooshort++;
|
||||
goto freeit;
|
||||
}
|
||||
#if SHOW_DEBUG
|
||||
dump_icmp(buf);
|
||||
#endif
|
||||
i = hdrlen + min(icl, (int) ICMP_ADVLENMIN);
|
||||
if ((int) buf->m_len < i && (buf = m_pullup(buf, i)) == NULL) {
|
||||
icmpstat.icps_tooshort++;
|
||||
return;
|
||||
}
|
||||
ip = mtod(buf, struct ip*);
|
||||
buf->m_len -= hdrlen;
|
||||
buf->m_data += hdrlen;
|
||||
ic = mtod(buf, struct icmp*);
|
||||
|
||||
if ((rv = in_cksum(buf, icl, 0)) != 0) {
|
||||
printf("icmp_input: checksum failed over %d bytes (%d)!\n", icl, rv);
|
||||
icmpstat.icps_checksum++;
|
||||
goto freeit;
|
||||
}
|
||||
buf->m_len += hdrlen;
|
||||
buf->m_data -= hdrlen;
|
||||
if (ic->icmp_type > ICMP_MAXTYPE)
|
||||
goto raw;
|
||||
|
||||
icmpstat.icps_inhist[ic->icmp_type]++;
|
||||
code = ic->icmp_code;
|
||||
switch (ic->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:
|
||||
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:
|
||||
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:
|
||||
if (icl < (int) ICMP_ADVLENMIN || icl < ICMP_ADVLEN(ic) ||
|
||||
(ic->icmp_ip.ip_hl < sizeof(struct ip) >> 2)) {
|
||||
icmpstat.icps_badlen++;
|
||||
goto freeit;
|
||||
}
|
||||
ic->icmp_ip.ip_len = htons(ic->icmp_ip.ip_len);
|
||||
icmpsrc.sin_addr = ic->icmp_ip.ip_dst;
|
||||
if (proto[ic->icmp_ip.ip_p]->pr_ctlinput)
|
||||
proto[ic->icmp_ip.ip_p]->pr_ctlinput(code,
|
||||
(struct sockaddr*)&icmpsrc, (void*)&ic->icmp_ip);
|
||||
break;
|
||||
badcode:
|
||||
icmpstat.icps_badcode++;
|
||||
break;
|
||||
case ICMP_ECHO: {
|
||||
ic->icmp_type = ICMP_ECHOREPLY;
|
||||
ip->ip_len += hdrlen;
|
||||
icmpstat.icps_reflect++;
|
||||
icmpstat.icps_outhist[ic->icmp_type]++;
|
||||
icmp_reflect(buf);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
case ICMP_ECHOREPLY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
raw:
|
||||
if (raw)
|
||||
raw->input(buf, 0);
|
||||
|
||||
return;
|
||||
|
||||
freeit:
|
||||
m_freem(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void icmp_error(struct mbuf *n, int type, int code, n_long dest,
|
||||
struct ifnet *destifp)
|
||||
{
|
||||
struct ip *oip = mtod(n, struct ip*), *nip;
|
||||
uint oiplen = oip->ip_hl << 2;
|
||||
struct icmp *icp;
|
||||
struct mbuf *m;
|
||||
uint icmplen;
|
||||
|
||||
if (type != ICMP_REDIRECT)
|
||||
icmpstat.icps_error++;
|
||||
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*)((void*)(oip + oiplen)))->icmp_type)) {
|
||||
icmpstat.icps_oldicmp++;
|
||||
goto freeit;
|
||||
}
|
||||
/* don't send icmp errors in response to multi or broad cast */
|
||||
if (n->m_flags & (M_BCAST | M_MCAST))
|
||||
goto freeit;
|
||||
|
||||
m = m_gethdr(MT_HEADER);
|
||||
if (!m)
|
||||
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 ((uint)type > ICMP_MAXTYPE) {
|
||||
/* PANIC */
|
||||
printf("PANIC: icmp_error! type outside of range\n");
|
||||
return;
|
||||
}
|
||||
icmpstat.icps_outhist[type]++;
|
||||
icp->icmp_type = type;
|
||||
if (type == ICMP_REDIRECT)
|
||||
icp->icmp_gwaddr.s_addr = dest;
|
||||
else {
|
||||
icp->icmp_void = 0;
|
||||
if (type == ICMP_PARAMPROB) {
|
||||
icp->icmp_pptr = code;
|
||||
} else if (type == ICMP_UNREACH &&
|
||||
code == ICMP_UNREACH_NEEDFRAG &&
|
||||
destifp) {
|
||||
icp->icmp_nextmtu = htons(destifp->if_mtu);
|
||||
}
|
||||
}
|
||||
icp->icmp_code = code;
|
||||
memcpy((void*)&icp->icmp_ip, (void*)oip, icmplen);
|
||||
nip = &icp->icmp_ip;
|
||||
nip->ip_len = htons((nip->ip_len + oiplen));
|
||||
if (m->m_data - sizeof(struct ip) < m->m_pktdat) {
|
||||
/* PANIC */
|
||||
printf("PANIC: icmp_error: icmp len\n");
|
||||
return;
|
||||
}
|
||||
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*);
|
||||
memcpy((void*)nip, (void*)oip, sizeof(struct ip));
|
||||
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 void icmp_init(void)
|
||||
{
|
||||
memset(&icmprt, 0, sizeof(icmprt));
|
||||
|
||||
memset(proto, 0, sizeof(struct protosw *) * IPPROTO_MAX);
|
||||
add_protosw(proto, NET_LAYER2);
|
||||
if (!raw)
|
||||
get_module(NET_RAW_MODULE_NAME, (module_info**)&raw);
|
||||
ic_ifaddr = get_primary_addr();
|
||||
}
|
||||
|
||||
struct protosw my_proto = {
|
||||
"ICMP (v4)",
|
||||
NET_ICMP_MODULE_NAME,
|
||||
0,
|
||||
NULL,
|
||||
IPPROTO_ICMP,
|
||||
PR_ATOMIC | PR_ADDR,
|
||||
NET_LAYER2,
|
||||
|
||||
&icmp_init,
|
||||
&icmp_input,
|
||||
NULL, /* pr_output, */
|
||||
NULL,
|
||||
NULL, /* pr_sysctl */
|
||||
NULL,
|
||||
NULL, /* pr_ctloutput */
|
||||
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int icmp_protocol_init(void *cpp)
|
||||
{
|
||||
/* we will never call this with anything but NULL when in kernel,
|
||||
* so this should be safe.
|
||||
*/
|
||||
if (cpp)
|
||||
core = (struct core_module_info *)cpp;
|
||||
add_domain(NULL, AF_INET);
|
||||
add_protocol(&my_proto, AF_INET);
|
||||
|
||||
if (!ipm)
|
||||
get_module(NET_IPV4_MODULE_NAME, (module_info**)&ipm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icmp_protocol_stop(void)
|
||||
{
|
||||
remove_protocol(&my_proto);
|
||||
remove_domain(AF_INET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct icmp_module_info protocol_info = {
|
||||
{
|
||||
{
|
||||
NET_ICMP_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
icmp_protocol_init,
|
||||
icmp_protocol_stop,
|
||||
NULL
|
||||
},
|
||||
|
||||
icmp_error
|
||||
};
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
_EXPORT status_t std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
case B_MODULE_INIT:
|
||||
if (!core)
|
||||
get_module(NET_CORE_MODULE_NAME, (module_info **) &core);
|
||||
if (!core)
|
||||
return B_ERROR;
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
_EXPORT module_info *modules[] = {
|
||||
(module_info *) &protocol_info,
|
||||
NULL
|
||||
};
|
||||
|
@ -1,24 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network protocols ipv4 ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
KernelAddon ipv4 : kernel obos_network protocols :
|
||||
ipv4.c
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/protocols
|
||||
: ipv4 ;
|
||||
|
||||
Package haiku-networkingkit-cvs :
|
||||
ipv4 :
|
||||
boot home config add-ons kernel obos_network protocols ;
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user