typedef struct label_t { long val[8]; } label_t; typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef short __int16_t; typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; typedef long long __int64_t; typedef unsigned long long __uint64_t; typedef __int8_t __int_least8_t; typedef __uint8_t __uint_least8_t; typedef __int16_t __int_least16_t; typedef __uint16_t __uint_least16_t; typedef __int32_t __int_least32_t; typedef __uint32_t __uint_least32_t; typedef __int64_t __int_least64_t; typedef __uint64_t __uint_least64_t; typedef __int32_t __int_fast8_t; typedef __uint32_t __uint_fast8_t; typedef __int32_t __int_fast16_t; typedef __uint32_t __uint_fast16_t; typedef __int32_t __int_fast32_t; typedef __uint32_t __uint_fast32_t; typedef __int64_t __int_fast64_t; typedef __uint64_t __uint_fast64_t; typedef long __intptr_t; typedef unsigned long __uintptr_t; typedef __int64_t __intmax_t; typedef __uint64_t __uintmax_t; typedef long __register_t; typedef unsigned long __vaddr_t; typedef unsigned long __paddr_t; typedef unsigned long __vsize_t; typedef unsigned long __psize_t; typedef double __double_t; typedef float __float_t; typedef long __ptrdiff_t; typedef unsigned long __size_t; typedef long __ssize_t; typedef __builtin_va_list __va_list; typedef int __wchar_t; typedef int __wint_t; typedef int __rune_t; typedef void * __wctrans_t; typedef void * __wctype_t; typedef __int64_t __blkcnt_t; typedef __int32_t __blksize_t; typedef __int64_t __clock_t; typedef __int32_t __clockid_t; typedef unsigned long __cpuid_t; typedef __int32_t __dev_t; typedef __uint32_t __fixpt_t; typedef __uint64_t __fsblkcnt_t; typedef __uint64_t __fsfilcnt_t; typedef __uint32_t __gid_t; typedef __uint32_t __id_t; typedef __uint32_t __in_addr_t; typedef __uint16_t __in_port_t; typedef __uint64_t __ino_t; typedef long __key_t; typedef __uint32_t __mode_t; typedef __uint32_t __nlink_t; typedef __int64_t __off_t; typedef __int32_t __pid_t; typedef __uint64_t __rlim_t; typedef __uint8_t __sa_family_t; typedef __int32_t __segsz_t; typedef __uint32_t __socklen_t; typedef long __suseconds_t; typedef __int32_t __swblk_t; typedef __int64_t __time_t; typedef __int32_t __timer_t; typedef __uint32_t __uid_t; typedef __uint32_t __useconds_t; typedef union { char __mbstate8[128]; __int64_t __mbstateL; } __mbstate_t; typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; typedef unsigned char unchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef __cpuid_t cpuid_t; typedef __register_t register_t; typedef __int8_t int8_t; typedef __uint8_t uint8_t; typedef __int16_t int16_t; typedef __uint16_t uint16_t; typedef __int32_t int32_t; typedef __uint32_t uint32_t; typedef __int64_t int64_t; typedef __uint64_t uint64_t; typedef __uint8_t u_int8_t; typedef __uint16_t u_int16_t; typedef __uint32_t u_int32_t; typedef __uint64_t u_int64_t; typedef __int64_t quad_t; typedef __uint64_t u_quad_t; typedef __vaddr_t vaddr_t; typedef __paddr_t paddr_t; typedef __vsize_t vsize_t; typedef __psize_t psize_t; typedef __blkcnt_t blkcnt_t; typedef __blksize_t blksize_t; typedef char * caddr_t; typedef __int32_t daddr32_t; typedef __int64_t daddr_t; typedef __dev_t dev_t; typedef __fixpt_t fixpt_t; typedef __gid_t gid_t; typedef __id_t id_t; typedef __ino_t ino_t; typedef __key_t key_t; typedef __mode_t mode_t; typedef __nlink_t nlink_t; typedef __rlim_t rlim_t; typedef __segsz_t segsz_t; typedef __swblk_t swblk_t; typedef __uid_t uid_t; typedef __useconds_t useconds_t; typedef __suseconds_t suseconds_t; typedef __fsblkcnt_t fsblkcnt_t; typedef __fsfilcnt_t fsfilcnt_t; typedef __clock_t clock_t; typedef __clockid_t clockid_t; typedef __pid_t pid_t; typedef __size_t size_t; typedef __ssize_t ssize_t; typedef __time_t time_t; typedef __timer_t timer_t; typedef __off_t off_t; struct proc; struct pgrp; struct ucred; struct rusage; struct file; struct buf; struct tty; struct uio; struct timeval { time_t tv_sec; suseconds_t tv_usec; }; struct timespec { time_t tv_sec; long tv_nsec; }; typedef uint32_t __fd_mask; typedef struct fd_set { __fd_mask fds_bits[(((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof(__fd_mask) * 8))))]; } fd_set; static __inline void __fd_set(int fd, fd_set *p) { p->fds_bits[fd / ((unsigned)(sizeof(__fd_mask) * 8))] |= (1U << (fd % ((unsigned)(sizeof(__fd_mask) * 8)))); } static __inline void __fd_clr(int fd, fd_set *p) { p->fds_bits[fd / ((unsigned)(sizeof(__fd_mask) * 8))] &= ~(1U << (fd % ((unsigned)(sizeof(__fd_mask) * 8)))); } static __inline int __fd_isset(int fd, const fd_set *p) { return (p->fds_bits[fd / ((unsigned)(sizeof(__fd_mask) * 8))] & (1U << (fd % ((unsigned)(sizeof(__fd_mask) * 8))))); } struct timezone { int tz_minuteswest; int tz_dsttime; }; struct itimerval { struct timeval it_interval; struct timeval it_value; }; struct clockinfo { int hz; int tick; int tickadj; int stathz; int profhz; }; struct itimerspec { struct timespec it_interval; struct timespec it_value; }; struct bintime { time_t sec; uint64_t frac; }; static __inline void bintime_addx(struct bintime *bt, uint64_t x) { uint64_t u; u = bt->frac; bt->frac += x; if (u > bt->frac) bt->sec++; } static __inline void bintime_add(struct bintime *bt, struct bintime *bt2) { uint64_t u; u = bt->frac; bt->frac += bt2->frac; if (u > bt->frac) bt->sec++; bt->sec += bt2->sec; } static __inline void bintime_sub(struct bintime *bt, struct bintime *bt2) { uint64_t u; u = bt->frac; bt->frac -= bt2->frac; if (u < bt->frac) bt->sec--; bt->sec -= bt2->sec; } static __inline void bintime2timespec(struct bintime *bt, struct timespec *ts) { ts->tv_sec = bt->sec; ts->tv_nsec = (long)(((uint64_t)1000000000 * (uint32_t)(bt->frac >> 32)) >> 32); } static __inline void timespec2bintime(struct timespec *ts, struct bintime *bt) { bt->sec = ts->tv_sec; bt->frac = (uint64_t)ts->tv_nsec * (uint64_t)18446744073ULL; } static __inline void bintime2timeval(struct bintime *bt, struct timeval *tv) { tv->tv_sec = bt->sec; tv->tv_usec = (long)(((uint64_t)1000000 * (uint32_t)(bt->frac >> 32)) >> 32); } static __inline void timeval2bintime(struct timeval *tv, struct bintime *bt) { bt->sec = (time_t)tv->tv_sec; bt->frac = (uint64_t)tv->tv_usec * (uint64_t)18446744073709ULL; } extern volatile time_t time_second; extern volatile time_t time_uptime; void bintime(struct bintime *); void nanotime(struct timespec *); void microtime(struct timeval *); void getnanotime(struct timespec *); void getmicrotime(struct timeval *); void binuptime(struct bintime *); void nanouptime(struct timespec *); void microuptime(struct timeval *); void getnanouptime(struct timespec *); void getmicrouptime(struct timeval *); struct proc; int clock_gettime(struct proc *, clockid_t, struct timespec *); int timespecfix(struct timespec *); int itimerfix(struct timeval *); int itimerdecr(struct itimerval *itp, int usec); void itimerround(struct timeval *); int settime(struct timespec *); int ratecheck(struct timeval *, const struct timeval *); int ppsratecheck(struct timeval *, int *, int); struct clock_ymdhms { u_short dt_year; u_char dt_mon; u_char dt_day; u_char dt_wday; u_char dt_hour; u_char dt_min; u_char dt_sec; }; time_t clock_ymdhms_to_secs(struct clock_ymdhms *); void clock_secs_to_ymdhms(time_t, struct clock_ymdhms *); struct rusage { struct timeval ru_utime; struct timeval ru_stime; long ru_maxrss; long ru_ixrss; long ru_idrss; long ru_isrss; long ru_minflt; long ru_majflt; long ru_nswap; long ru_inblock; long ru_oublock; long ru_msgsnd; long ru_msgrcv; long ru_nsignals; long ru_nvcsw; long ru_nivcsw; }; struct rlimit { rlim_t rlim_cur; rlim_t rlim_max; }; struct loadavg { fixpt_t ldavg[3]; long fscale; }; extern struct loadavg averunnable; struct process; int dosetrlimit(struct proc *, u_int, struct rlimit *); int donice(struct proc *, struct process *, int); int dogetrusage(struct proc *, int, struct rusage *); struct ucred { u_int cr_ref; uid_t cr_uid; uid_t cr_ruid; uid_t cr_svuid; gid_t cr_gid; gid_t cr_rgid; gid_t cr_svgid; short cr_ngroups; gid_t cr_groups[16]; }; struct xucred { uid_t cr_uid; gid_t cr_gid; short cr_ngroups; gid_t cr_groups[16]; }; int crfromxucred(struct ucred *, const struct xucred *); void crset(struct ucred *, const struct ucred *); struct ucred *crcopy(struct ucred *cr); struct ucred *crdup(struct ucred *cr); void crfree(struct ucred *cr); struct ucred *crget(void); int suser(struct proc *p, u_int flags); int suser_ucred(struct ucred *cred); struct iovec { void *iov_base; size_t iov_len; }; enum uio_rw { UIO_READ, UIO_WRITE }; enum uio_seg { UIO_USERSPACE, UIO_SYSSPACE }; struct uio { struct iovec *uio_iov; int uio_iovcnt; off_t uio_offset; size_t uio_resid; enum uio_seg uio_segflg; enum uio_rw uio_rw; struct proc *uio_procp; }; int ureadc(int c, struct uio *); struct file; int dofilereadv(struct proc *, int, struct file *, const struct iovec *, int, int, off_t *, register_t *); int dofilewritev(struct proc *, int, struct file *, const struct iovec *, int, int, off_t *, register_t *); struct refcnt { unsigned int refs; }; void refcnt_init(struct refcnt *); void refcnt_take(struct refcnt *); int refcnt_rele(struct refcnt *); void refcnt_rele_wake(struct refcnt *); void refcnt_finalize(struct refcnt *, const char *); struct srp { void *ref; }; struct srp_hazard { struct srp *sh_p; void *sh_v; }; struct srp_ref { struct srp_hazard *hz; } ; struct srp_gc { void (*srp_gc_dtor)(void *, void *); void *srp_gc_cookie; struct refcnt srp_gc_refcnt; }; struct srpl_rc { void (*srpl_ref)(void *, void *); struct srp_gc srpl_gc; }; struct srpl { struct srp sl_head; }; void srp_startup(void); void srp_gc_init(struct srp_gc *, void (*)(void *, void *), void *); void *srp_swap_locked(struct srp *, void *); void srp_update_locked(struct srp_gc *, struct srp *, void *); void *srp_get_locked(struct srp *); void srp_gc_finalize(struct srp_gc *); void srp_init(struct srp *); void *srp_swap(struct srp *, void *); void srp_update(struct srp_gc *, struct srp *, void *); void srp_finalize(void *, const char *); void *srp_enter(struct srp_ref *, struct srp *); void *srp_follow(struct srp_ref *, struct srp *); void srp_leave(struct srp_ref *); void srpl_rc_init(struct srpl_rc *, void (*)(void *, void *), void (*)(void *, void *), void *); typedef int sig_atomic_t; struct sigcontext { long sc_rdi; long sc_rsi; long sc_rdx; long sc_rcx; long sc_r8; long sc_r9; long sc_r10; long sc_r11; long sc_r12; long sc_r13; long sc_r14; long sc_r15; long sc_rbp; long sc_rbx; long sc_rax; long sc_gs; long sc_fs; long sc_es; long sc_ds; long sc_trapno; long sc_err; long sc_rip; long sc_cs; long sc_rflags; long sc_rsp; long sc_ss; struct fxsave64 *sc_fpstate; int __sc_unused; int sc_mask; long sc_cookie; }; typedef unsigned int sigset_t; union sigval { int sival_int; void *sival_ptr; }; typedef struct { int si_signo; int si_code; int si_errno; union { int _pad[((128 / sizeof (int)) - 3)]; struct { pid_t _pid; union { struct { uid_t _uid; union sigval _value; } _kill; struct { clock_t _utime; clock_t _stime; int _status; } _cld; } _pdata; } _proc; struct { void *_addr; int _trapno; } _fault; } _data; } siginfo_t; void initsiginfo(siginfo_t *, int, u_long, int, union sigval); struct sigaction { union { void (*__sa_handler)(int); void (*__sa_sigaction)(int, siginfo_t *, void *); } __sigaction_u; sigset_t sa_mask; int sa_flags; }; typedef void (*sig_t)(int); struct sigvec { void (*sv_handler)(int); int sv_mask; int sv_flags; }; typedef struct sigaltstack { void *ss_sp; size_t ss_size; int ss_flags; } stack_t; typedef struct sigcontext ucontext_t; struct fxsave64 { u_int16_t fx_fcw; u_int16_t fx_fsw; u_int8_t fx_ftw; u_int8_t fx_unused1; u_int16_t fx_fop; u_int64_t fx_rip; u_int64_t fx_rdp; u_int32_t fx_mxcsr; u_int32_t fx_mxcsr_mask; u_int64_t fx_st[8][2]; u_int64_t fx_xmm[16][2]; u_int8_t fx_unused3[96]; } __attribute__((__packed__)); struct xstate_hdr { uint64_t xstate_bv; uint64_t xstate_xcomp_bv; uint8_t xstate_rsrv0[0]; uint8_t xstate_rsrv[40]; } __attribute__((__packed__)); struct savefpu { struct fxsave64 fp_fxsave; struct xstate_hdr fp_xstate; u_int64_t fp_ymm[16][2]; u_int16_t fp_ex_sw; u_int16_t fp_ex_tw; }; struct trapframe; struct cpu_info; extern size_t fpu_save_len; extern uint32_t fpu_mxcsr_mask; extern uint64_t xsave_mask; void fpuinit(struct cpu_info *); void fpudrop(void); void fpudiscard(struct proc *); void fputrap(struct trapframe *); void fpusave_proc(struct proc *, int); void fpusave_cpu(struct cpu_info *, int); void fpu_kernel_enter(void); void fpu_kernel_exit(void); static inline void xsave(struct savefpu *addr, uint64_t mask) { uint32_t lo, hi; lo = mask; hi = mask >> 32; __asm volatile("xsave %0" : "=m" (*addr) : "a" (lo), "d" (hi) : "memory"); } static inline void xrstor(struct savefpu *addr, uint64_t mask) { uint32_t lo, hi; lo = mask; hi = mask >> 32; __asm volatile("xrstor %0" : : "m" (*addr), "a" (lo), "d" (hi)); } struct trapframe { int64_t tf_rdi; int64_t tf_rsi; int64_t tf_rdx; int64_t tf_rcx; int64_t tf_r8; int64_t tf_r9; int64_t tf_r10; int64_t tf_r11; int64_t tf_r12; int64_t tf_r13; int64_t tf_r14; int64_t tf_r15; int64_t tf_rbp; int64_t tf_rbx; int64_t tf_rax; int64_t tf_gs; int64_t tf_fs; int64_t tf_es; int64_t tf_ds; int64_t tf_trapno; int64_t tf_err; int64_t tf_rip; int64_t tf_cs; int64_t tf_rflags; int64_t tf_rsp; int64_t tf_ss; }; struct intrframe { int64_t if_ppl; int64_t if_rdi; int64_t if_rsi; int64_t if_rdx; int64_t if_rcx; int64_t if_r8; int64_t if_r9; int64_t if_r10; int64_t if_r11; int64_t if_r12; int64_t if_r13; int64_t if_r14; int64_t if_r15; int64_t if_rbp; int64_t if_rbx; int64_t if_rax; int64_t tf_gs; int64_t tf_fs; int64_t tf_es; int64_t tf_ds; u_int64_t __if_trapno; u_int64_t __if_err; int64_t if_rip; int64_t if_cs; int64_t if_rflags; int64_t if_rsp; int64_t if_ss; }; struct switchframe { int64_t sf_r15; int64_t sf_r14; int64_t sf_r13; int64_t sf_r12; int64_t sf_rbp; int64_t sf_rbx; int64_t sf_rip; }; struct callframe { struct callframe *f_frame; long f_retaddr; long f_arg0; }; struct sys_segment_descriptor { u_int64_t sd_lolimit:16; u_int64_t sd_lobase:24; u_int64_t sd_type:5; u_int64_t sd_dpl:2; u_int64_t sd_p:1; u_int64_t sd_hilimit:4; u_int64_t sd_xx1:3; u_int64_t sd_gran:1; u_int64_t sd_hibase:40; u_int64_t sd_xx2:8; u_int64_t sd_zero:5; u_int64_t sd_xx3:19; } __attribute__((__packed__)); struct mem_segment_descriptor { unsigned int sd_lolimit:16; unsigned int sd_lobase:24; unsigned int sd_type:5; unsigned int sd_dpl:2; unsigned int sd_p:1; unsigned int sd_hilimit:4; unsigned int sd_avl:1; unsigned int sd_long:1; unsigned int sd_def32:1; unsigned int sd_gran:1; unsigned int sd_hibase:8; } __attribute__((__packed__)); struct gate_descriptor { u_int64_t gd_looffset:16; u_int64_t gd_selector:16; u_int64_t gd_ist:3; u_int64_t gd_xx1:5; u_int64_t gd_type:5; u_int64_t gd_dpl:2; u_int64_t gd_p:1; u_int64_t gd_hioffset:48; u_int64_t gd_xx2:8; u_int64_t gd_zero:5; u_int64_t gd_xx3:19; } __attribute__((__packed__)); struct region_descriptor { u_int16_t rd_limit; u_int64_t rd_base; } __attribute__((__packed__)); extern struct gate_descriptor *idt; void setgate(struct gate_descriptor *, void *, int, int, int, int); void unsetgate(struct gate_descriptor *); void setregion(struct region_descriptor *, void *, u_int16_t); void set_sys_segment(struct sys_segment_descriptor *, void *, size_t, int, int, int); void set_mem_segment(struct mem_segment_descriptor *, void *, size_t, int, int, int, int, int); int idt_vec_alloc(int, int); void idt_vec_set(int, void (*)(void)); void idt_vec_free(int); void cpu_init_idt(void); struct x86_cache_info { uint8_t cai_index; uint8_t cai_desc; uint8_t cai_associativity; u_int cai_totalsize; u_int cai_linesize; const char *cai_string; }; struct cpu_info; const struct x86_cache_info *cache_info_lookup(const struct x86_cache_info *, u_int8_t); void amd_cpu_cacheinfo(struct cpu_info *); void x86_print_cacheinfo(struct cpu_info *); enum devclass { DV_DULL, DV_CPU, DV_DISK, DV_IFNET, DV_TAPE, DV_TTY }; struct device { enum devclass dv_class; struct { struct device *tqe_next; struct device **tqe_prev; } dv_list; struct cfdata *dv_cfdata; int dv_unit; char dv_xname[16]; struct device *dv_parent; int dv_flags; int dv_ref; }; struct devicelist { struct device *tqh_first; struct device **tqh_last; }; struct cfdata { struct cfattach *cf_attach; struct cfdriver *cf_driver; short cf_unit; short cf_fstate; long *cf_loc; int cf_flags; short *cf_parents; int cf_locnames; short cf_starunit1; }; extern struct cfdata cfdata[]; typedef int (*cfmatch_t)(struct device *, void *, void *); typedef void (*cfscan_t)(struct device *, void *); struct cfattach { size_t ca_devsize; cfmatch_t ca_match; void (*ca_attach)(struct device *, struct device *, void *); int (*ca_detach)(struct device *, int); int (*ca_activate)(struct device *, int); }; struct cfdriver { void **cd_devs; char *cd_name; enum devclass cd_class; int cd_indirect; int cd_ndevs; }; typedef int (*cfprint_t)(void *, const char *); struct pdevinit { void (*pdev_attach)(int); int pdev_count; }; extern struct devicelist alldevs; extern int autoconf_verbose; extern volatile int config_pending; void config_init(void); void *config_search(cfmatch_t, struct device *, void *); struct device *config_found_sm(struct device *, void *, cfprint_t, cfmatch_t); struct device *config_rootfound(char *, void *); void config_scan(cfscan_t, struct device *); struct device *config_attach(struct device *, void *, void *, cfprint_t); int config_detach(struct device *, int); int config_detach_children(struct device *, int); int config_deactivate(struct device *); int config_suspend(struct device *, int); int config_suspend_all(int); int config_activate_children(struct device *, int); struct device *config_make_softc(struct device *parent, struct cfdata *cf); void config_defer(struct device *, void (*)(struct device *)); void config_pending_incr(void); void config_pending_decr(void); void config_mountroot(struct device *, void (*)(struct device *)); void config_process_deferred_mountroot(void); struct device *device_mainbus(void); struct device *device_mpath(void); struct device *device_lookup(struct cfdriver *, int unit); void device_ref(struct device *); void device_unref(struct device *); struct nam2blk { char *name; int maj; }; int findblkmajor(struct device *dv); char *findblkname(int); void setroot(struct device *, int, int); struct device *getdisk(char *str, int len, int defpart, dev_t *devp); struct device *parsedisk(char *str, int len, int defpart, dev_t *devp); void device_register(struct device *, void *); int loadfirmware(const char *name, u_char **bufp, size_t *buflen); struct schedstate_percpu { struct timespec spc_runtime; volatile int spc_schedflags; u_int spc_schedticks; u_int64_t spc_cp_time[5]; u_char spc_curpriority; int spc_rrticks; int spc_pscnt; int spc_psdiv; struct proc *spc_idleproc; u_int spc_nrun; fixpt_t spc_ldavg; struct prochead { struct proc *tqh_first; struct proc **tqh_last; } spc_qs[32]; volatile uint32_t spc_whichqs; struct { struct proc *lh_first; } spc_deadproc; }; extern int schedhz; extern int rrticks_init; struct proc; void schedclock(struct proc *); struct cpu_info; void roundrobin(struct cpu_info *); void scheduler_start(void); void userret(struct proc *p); void sched_init_cpu(struct cpu_info *); void sched_idle(void *); void sched_exit(struct proc *); void mi_switch(void); void cpu_switchto(struct proc *, struct proc *); struct proc *sched_chooseproc(void); struct cpu_info *sched_choosecpu(struct proc *); struct cpu_info *sched_choosecpu_fork(struct proc *parent, int); void cpu_idle_enter(void); void cpu_idle_cycle(void); void cpu_idle_leave(void); void sched_peg_curproc(struct cpu_info *ci); void sched_barrier(struct cpu_info *ci); int sysctl_hwsetperf(void *, size_t *, void *, size_t); int sysctl_hwperfpolicy(void *, size_t *, void *, size_t); void sched_start_secondary_cpus(void); void sched_stop_secondary_cpus(void); void sched_init_runqueues(void); void setrunqueue(struct proc *); void remrunqueue(struct proc *); enum lock_class_index { LO_CLASS_KERNEL_LOCK, LO_CLASS_SCHED_LOCK, LO_CLASS_MUTEX, LO_CLASS_RWLOCK, LO_CLASS_RRWLOCK }; struct lock_object { struct lock_type *lo_type; const char *lo_name; struct witness *lo_witness; uint32_t lo_flags; }; struct lock_type { const char *lt_name; }; struct proc; struct rwlock { volatile unsigned long rwl_owner; const char *rwl_name; }; struct rrwlock { struct rwlock rrwl_lock; uint32_t rrwl_wcnt; }; void _rw_init_flags(struct rwlock *, const char *, int, struct lock_type *); void _rw_enter_read(struct rwlock * ); void _rw_enter_write(struct rwlock * ); void _rw_exit_read(struct rwlock * ); void _rw_exit_write(struct rwlock * ); void rw_assert_wrlock(struct rwlock *); void rw_assert_rdlock(struct rwlock *); void rw_assert_anylock(struct rwlock *); void rw_assert_unlocked(struct rwlock *); int _rw_enter(struct rwlock *, int ); void _rw_exit(struct rwlock * ); int rw_status(struct rwlock *); void _rrw_init_flags(struct rrwlock *, char *, int, struct lock_type *); int _rrw_enter(struct rrwlock *, int ); void _rrw_exit(struct rrwlock * ); int rrw_status(struct rrwlock *); extern struct __mp_lock sched_lock; enum sensor_type { SENSOR_TEMP, SENSOR_FANRPM, SENSOR_VOLTS_DC, SENSOR_VOLTS_AC, SENSOR_OHMS, SENSOR_WATTS, SENSOR_AMPS, SENSOR_WATTHOUR, SENSOR_AMPHOUR, SENSOR_INDICATOR, SENSOR_INTEGER, SENSOR_PERCENT, SENSOR_LUX, SENSOR_DRIVE, SENSOR_TIMEDELTA, SENSOR_HUMIDITY, SENSOR_FREQ, SENSOR_ANGLE, SENSOR_DISTANCE, SENSOR_PRESSURE, SENSOR_ACCEL, SENSOR_MAX_TYPES }; enum sensor_status { SENSOR_S_UNSPEC, SENSOR_S_OK, SENSOR_S_WARN, SENSOR_S_CRIT, SENSOR_S_UNKNOWN }; struct sensor { char desc[32]; struct timeval tv; int64_t value; enum sensor_type type; enum sensor_status status; int numt; int flags; }; struct sensordev { int num; char xname[16]; int maxnumt[SENSOR_MAX_TYPES]; int sensors_count; }; struct ksensor { struct { struct ksensor *sle_next; } list; char desc[32]; struct timeval tv; int64_t value; enum sensor_type type; enum sensor_status status; int numt; int flags; }; struct ksensors_head { struct ksensor *slh_first; }; struct ksensordev { struct { struct ksensordev *sle_next; } list; int num; char xname[16]; int maxnumt[SENSOR_MAX_TYPES]; int sensors_count; struct ksensors_head sensors_list; }; void sensordev_install(struct ksensordev *); void sensordev_deinstall(struct ksensordev *); int sensordev_get(int, struct ksensordev **); void sensor_attach(struct ksensordev *, struct ksensor *); void sensor_detach(struct ksensordev *, struct ksensor *); int sensor_find(int, enum sensor_type, int, struct ksensor **); struct sensor_task; struct sensor_task *sensor_task_register(void *, void (*)(void *), unsigned int); void sensor_task_unregister(struct sensor_task *); void sensor_quiesce(void); void sensor_restart(void); struct vmxon_region { uint32_t vr_revision; }; struct vmx { uint64_t vmx_cr0_fixed0; uint64_t vmx_cr0_fixed1; uint64_t vmx_cr4_fixed0; uint64_t vmx_cr4_fixed1; uint32_t vmx_vmxon_revision; uint32_t vmx_msr_table_size; uint32_t vmx_cr3_tgt_count; uint64_t vmx_vm_func; }; struct svm { uint32_t svm_max_asid; uint8_t svm_flush_by_asid; uint8_t svm_vmcb_clean; }; union vmm_cpu_cap { struct vmx vcc_vmx; struct svm vcc_svm; }; struct x86_64_tss; struct cpu_info { struct device *ci_dev; struct cpu_info *ci_self; struct schedstate_percpu ci_schedstate; struct cpu_info *ci_next; struct proc *ci_curproc; u_int ci_cpuid; u_int ci_apicid; u_int ci_acpi_proc_id; u_int32_t ci_randseed; u_int64_t ci_scratch; struct proc *ci_fpcurproc; struct proc *ci_fpsaveproc; int ci_fpsaving; struct pcb *ci_curpcb; struct pcb *ci_idle_pcb; struct intrsource *ci_isources[64]; u_int64_t ci_ipending; int ci_ilevel; int ci_idepth; int ci_handled_intr_level; u_int64_t ci_imask[16]; u_int64_t ci_iunmask[16]; int ci_mutex_level; volatile u_int ci_flags; u_int32_t ci_ipis; u_int32_t ci_feature_flags; u_int32_t ci_feature_eflags; u_int32_t ci_feature_sefflags_ebx; u_int32_t ci_feature_sefflags_ecx; u_int32_t ci_feature_sefflags_edx; u_int32_t ci_feature_amdspec_ebx; u_int32_t ci_feature_tpmflags; u_int32_t ci_pnfeatset; u_int32_t ci_efeature_eax; u_int32_t ci_efeature_ecx; u_int32_t ci_brand[12]; u_int32_t ci_amdcacheinfo[4]; u_int32_t ci_extcacheinfo[4]; u_int32_t ci_signature; u_int32_t ci_family; u_int32_t ci_model; u_int32_t ci_cflushsz; int ci_inatomic; u_int32_t ci_smt_id; u_int32_t ci_core_id; u_int32_t ci_pkg_id; struct cpu_functions *ci_func; void (*cpu_setup)(struct cpu_info *); void (*ci_info)(struct cpu_info *); struct device *ci_acpicpudev; volatile u_int ci_mwait; int ci_want_resched; struct x86_cache_info ci_cinfo[8]; struct x86_64_tss *ci_tss; char *ci_gdt; volatile int ci_ddb_paused; struct srp_hazard ci_srp_hazards[16]; struct ksensordev ci_sensordev; struct ksensor ci_sensor; u_int32_t ci_vmm_flags; union vmm_cpu_cap ci_vmm_cap; paddr_t ci_vmxon_region_pa; struct vmxon_region *ci_vmxon_region; }; extern struct cpu_info cpu_info_primary; extern struct cpu_info *cpu_info_list; extern void need_resched(struct cpu_info *); extern struct cpu_info *cpu_info[64]; void cpu_boot_secondary_processors(void); void cpu_init_idle_pcbs(void); void cpu_kick(struct cpu_info *); void cpu_unidle(struct cpu_info *); extern int cpu_feature; static __inline void invlpg(u_int64_t addr) { __asm volatile("invlpg (%0)" : : "r" (addr) : "memory"); } static __inline void lidt(void *p) { __asm volatile("lidt (%0)" : : "r" (p) : "memory"); } static __inline void lldt(u_short sel) { __asm volatile("lldt %0" : : "r" (sel)); } static __inline void ltr(u_short sel) { __asm volatile("ltr %0" : : "r" (sel)); } static __inline void lcr8(u_int val) { u_int64_t val64 = val; __asm volatile("movq %0,%%cr8" : : "r" (val64)); } static __inline void lcr0(u_int val) { u_int64_t val64 = val; __asm volatile("movq %0,%%cr0" : : "r" (val64)); } static __inline u_int rcr0(void) { u_int64_t val64; u_int val; __asm volatile("movq %%cr0,%0" : "=r" (val64)); val = val64; return val; } static __inline u_int64_t rcr2(void) { u_int64_t val; __asm volatile("movq %%cr2,%0" : "=r" (val)); return val; } static __inline void lcr3(u_int64_t val) { __asm volatile("movq %0,%%cr3" : : "r" (val)); } static __inline u_int64_t rcr3(void) { u_int64_t val; __asm volatile("movq %%cr3,%0" : "=r" (val)); return val; } static __inline void lcr4(u_int val) { u_int64_t val64 = val; __asm volatile("movq %0,%%cr4" : : "r" (val64)); } static __inline u_int rcr4(void) { u_int64_t val64; __asm volatile("movq %%cr4,%0" : "=r" (val64)); return (u_int) val64; } static __inline void tlbflush(void) { u_int64_t val; __asm volatile("movq %%cr3,%0" : "=r" (val)); __asm volatile("movq %0,%%cr3" : : "r" (val)); } static __inline void disable_intr(void) { __asm volatile("cli"); } static __inline void enable_intr(void) { __asm volatile("sti"); } static __inline u_long read_rflags(void) { u_long ef; __asm volatile("pushfq; popq %0" : "=r" (ef)); return (ef); } static __inline void write_rflags(u_long ef) { __asm volatile("pushq %0; popfq" : : "r" (ef)); } static __inline u_long intr_disable(void) { u_long ef; ef = read_rflags(); disable_intr(); return (ef); } static __inline void intr_restore(u_long ef) { write_rflags(ef); } static __inline u_int64_t rdmsr(u_int msr) { uint32_t hi, lo; __asm volatile("rdmsr" : "=d" (hi), "=a" (lo) : "c" (msr)); return (((uint64_t)hi << 32) | (uint64_t) lo); } static __inline void wrmsr(u_int msr, u_int64_t newval) { __asm volatile("wrmsr" : : "a" (newval & 0xffffffff), "d" (newval >> 32), "c" (msr)); } static __inline u_int64_t rdmsr_locked(u_int msr, u_int code) { uint32_t hi, lo; __asm volatile("rdmsr" : "=d" (hi), "=a" (lo) : "c" (msr), "D" (code)); return (((uint64_t)hi << 32) | (uint64_t) lo); } static __inline void wrmsr_locked(u_int msr, u_int code, u_int64_t newval) { __asm volatile("wrmsr" : : "a" (newval & 0xffffffff), "d" (newval >> 32), "c" (msr), "D" (code)); } static __inline void wbinvd(void) { __asm volatile("wbinvd"); } static __inline void clflush(u_int64_t addr) { __asm volatile("clflush %0" : "+m" (*(volatile char *)addr)); } static __inline void mfence(void) { __asm volatile("mfence" : : : "memory"); } static __inline u_int64_t rdtsc(void) { uint32_t hi, lo; __asm volatile("rdtsc" : "=d" (hi), "=a" (lo)); return (((uint64_t)hi << 32) | (uint64_t) lo); } static __inline u_int64_t rdpmc(u_int pmc) { uint32_t hi, lo; __asm volatile("rdpmc" : "=d" (hi), "=a" (lo) : "c" (pmc)); return (((uint64_t)hi << 32) | (uint64_t) lo); } static __inline void monitor(const volatile void *addr, u_long extensions, u_int hints) { __asm volatile("monitor" : : "a" (addr), "c" (extensions), "d" (hints)); } static __inline void mwait(u_long extensions, u_int hints) { __asm volatile("mwait" : : "a" (hints), "c" (extensions)); } static __inline void xsetbv(uint32_t reg, uint64_t mask) { uint32_t lo, hi; lo = mask; hi = mask >> 32; __asm volatile("xsetbv" :: "c" (reg), "a" (lo), "d" (hi) : "memory"); } static __inline uint64_t xgetbv(uint32_t reg) { uint32_t lo, hi; __asm volatile("xgetbv" : "=a" (lo), "=d" (hi) : "c" (reg)); return (((uint64_t)hi << 32) | (uint64_t)lo); } static __inline void breakpoint(void) { __asm volatile("int $3"); } void amd64_errata(struct cpu_info *); void cpu_flags_update(struct cpu_info *); void cpu_ucode_apply(struct cpu_info *); void cpu_ucode_attachhook(struct device *); struct evcount { u_int64_t ec_count; int ec_id; const char *ec_name; void *ec_data; struct { struct evcount *tqe_next; struct evcount **tqe_prev; } next; }; void evcount_attach(struct evcount *, const char *, void *); void evcount_detach(struct evcount *); int evcount_sysctl(int *, u_int, void *, size_t *, void *, size_t); struct intrstub { void *ist_entry; void *ist_recurse; void *ist_resume; }; struct intrsource { int is_maxlevel; int is_pin; struct intrhand *is_handlers; struct pic *is_pic; void *is_recurse; void *is_resume; char is_evname[32]; int is_flags; int is_type; int is_idtvec; int is_minlevel; }; struct intrhand { int (*ih_fun)(void *); void *ih_arg; int ih_level; int ih_flags; struct intrhand *ih_next; int ih_pin; int ih_slot; struct cpu_info *ih_cpu; int ih_irq; struct evcount ih_count; }; extern void Xspllower(int); int splraise(int); int spllower(int); void softintr(int); void splassert_fail(int, int, const char *); extern int splassert_ctl; void splassert_check(int, const char *); struct mutex { volatile void *mtx_owner; int mtx_wantipl; int mtx_oldipl; }; void __mtx_init(struct mutex *, int); void __mtx_enter(struct mutex *); int __mtx_enter_try(struct mutex *); void __mtx_leave(struct mutex *); struct cpu_info; struct pic { struct device pic_dev; int pic_type; struct mutex pic_mutex; void (*pic_hwmask)(struct pic *, int); void (*pic_hwunmask)(struct pic *, int); void (*pic_addroute)(struct pic *, struct cpu_info *, int, int, int); void (*pic_delroute)(struct pic *, struct cpu_info *, int, int, int); struct intrstub *pic_level_stubs; struct intrstub *pic_edge_stubs; }; extern struct pic i8259_pic; extern struct pic local_pic; extern struct pic msi_pic; extern struct pic softintr_pic; extern void Xsoftclock(void); extern void Xsoftnet(void); extern void Xsofttty(void); extern struct intrstub i8259_stubs[]; extern struct intrstub ioapic_edge_stubs[]; extern struct intrstub ioapic_level_stubs[]; struct cpu_info; extern int intr_shared_edge; extern char idt_allocmap[]; void intr_default_setup(void); int x86_nmi(void); void intr_calculatemasks(struct cpu_info *); int intr_allocate_slot_cpu(struct cpu_info *, struct pic *, int, int *); int intr_allocate_slot(struct pic *, int, int, int, struct cpu_info **, int *, int *); void *intr_establish(int, struct pic *, int, int, int, int (*)(void *), void *, const char *); void intr_disestablish(struct intrhand *); int intr_handler(struct intrframe *, struct intrhand *); void cpu_intr_init(struct cpu_info *); int intr_find_mpmapping(int bus, int pin, int *handle); void intr_printconfig(void); void intr_barrier(void *); void x86_send_ipi(struct cpu_info *, int); int x86_fast_ipi(struct cpu_info *, int); void x86_broadcast_ipi(int); void x86_ipi_handler(void); void x86_setperf_ipi(struct cpu_info *); extern void (*ipifunc[10])(struct cpu_info *); struct x86_soft_intrhand { struct { struct x86_soft_intrhand *tqe_next; struct x86_soft_intrhand **tqe_prev; } sih_q; struct x86_soft_intr *sih_intrhead; void (*sih_fn)(void *); void *sih_arg; int sih_pending; }; struct x86_soft_intr { struct { struct x86_soft_intrhand *tqh_first; struct x86_soft_intrhand **tqh_last; } softintr_q; int softintr_ssir; struct mutex softintr_lock; }; void *softintr_establish(int, void (*)(void *), void *); void softintr_disestablish(void *); void softintr_init(void); void softintr_dispatch(int); struct __mp_lock_cpu { u_int mplc_ticket; u_int mplc_depth; }; struct __mp_lock { struct __mp_lock_cpu mpl_cpus[64]; volatile u_int mpl_ticket; u_int mpl_users; }; void ___mp_lock_init(struct __mp_lock *, struct lock_type *); void ___mp_lock(struct __mp_lock * ); void ___mp_unlock(struct __mp_lock * ); int ___mp_release_all(struct __mp_lock * ); int ___mp_release_all_but_one(struct __mp_lock * ); void ___mp_acquire_count(struct __mp_lock *, int ); int __mp_lock_held(struct __mp_lock *, struct cpu_info *); extern struct __mp_lock kernel_lock; void signotify(struct proc *); extern void (*delay_func)(int); struct timeval; extern int biosbasemem; extern int biosextmem; extern int cpu; extern int cpu_feature; extern int cpu_ebxfeature; extern int cpu_ecxfeature; extern int cpu_perf_eax; extern int cpu_perf_ebx; extern int cpu_perf_edx; extern int cpu_apmi_edx; extern int ecpu_ecxfeature; extern int cpu_id; extern char cpu_vendor[]; extern int cpuid_level; extern int cpuspeed; extern u_int cpu_mwait_size; extern u_int cpu_mwait_states; void identifycpu(struct cpu_info *); int cpu_amd64speed(int *); void dumpconf(void); void cpu_reset(void); void x86_64_proc0_tss_ldt_init(void); void x86_64_bufinit(void); void x86_64_init_pcb_tss_ldt(struct cpu_info *); void cpu_proc_fork(struct proc *, struct proc *); int amd64_pa_used(paddr_t); extern void (*cpu_idle_enter_fcn)(void); extern void (*cpu_idle_cycle_fcn)(void); extern void (*cpu_idle_leave_fcn)(void); struct region_descriptor; void lgdt(struct region_descriptor *); struct pcb; void savectx(struct pcb *); void switch_exit(struct proc *, void (*)(struct proc *)); void proc_trampoline(void); extern void (*initclock_func)(void); void startclocks(void); void rtcstart(void); void rtcstop(void); void i8254_delay(int); void i8254_initclocks(void); void i8254_startclock(void); void i8254_inittimecounter(void); void i8254_inittimecounter_simple(void); void i8259_default_setup(void); void cpu_init_msrs(struct cpu_info *); void dkcsumattach(void); void x86_bus_space_init(void); void x86_bus_space_mallocok(void); void k8_powernow_init(struct cpu_info *); void k8_powernow_setperf(int); void k1x_init(struct cpu_info *); void k1x_setperf(int); void est_init(struct cpu_info *); void est_setperf(int); void mp_setperf_init(void); typedef __builtin_va_list __gnuc_va_list; typedef __gnuc_va_list va_list; extern int securelevel; extern const char *panicstr; extern const char *faultstr; extern const char version[]; extern const char copyright[]; extern const char ostype[]; extern const char osversion[]; extern const char osrelease[]; extern int cold; extern int ncpus; extern int ncpusfound; extern int nblkdev; extern int nchrdev; extern int selwait; extern int maxmem; extern int physmem; extern dev_t dumpdev; extern long dumplo; extern dev_t rootdev; extern u_char bootduid[8]; extern u_char rootduid[8]; extern struct vnode *rootvp; extern dev_t swapdev; extern struct vnode *swapdev_vp; struct proc; struct process; typedef int sy_call_t(struct proc *, void *, register_t *); extern struct sysent { short sy_narg; short sy_argsize; int sy_flags; sy_call_t *sy_call; } sysent[]; extern int boothowto; extern void (*v_putc)(int); int nullop(void *); int enodev(void); int enosys(void); int enoioctl(void); int enxio(void); int eopnotsupp(void *); struct vnodeopv_desc; void vfs_opv_init_explicit(struct vnodeopv_desc *); void vfs_opv_init_default(struct vnodeopv_desc *); void vfs_op_init(void); int seltrue(dev_t dev, int which, struct proc *); int selfalse(dev_t dev, int which, struct proc *); void *hashinit(int, int, int, u_long *); void hashfree(void *, int, int); int sys_nosys(struct proc *, void *, register_t *); void panic(const char *, ...) __attribute__((__noreturn__,__format__(__kprintf__,1,2))); void __assert(const char *, const char *, int, const char *) __attribute__((__noreturn__)); int printf(const char *, ...) __attribute__((__format__(__kprintf__,1,2))); void uprintf(const char *, ...) __attribute__((__format__(__kprintf__,1,2))); int vprintf(const char *, va_list) __attribute__((__format__(__kprintf__,1,0))); int vsnprintf(char *, size_t, const char *, va_list) __attribute__((__format__(__kprintf__,3,0))); int snprintf(char *buf, size_t, const char *, ...) __attribute__((__format__(__kprintf__,3,4))); struct tty; void ttyprintf(struct tty *, const char *, ...) __attribute__((__format__(__kprintf__,2,3))); void splassert_fail(int, int, const char *); extern int splassert_ctl; void assertwaitok(void); void tablefull(const char *); int kcopy(const void *, void *, size_t) __attribute__ ((__bounded__(__buffer__,1,3))) __attribute__ ((__bounded__(__buffer__,2,3))); void bcopy(const void *, void *, size_t) __attribute__ ((__bounded__(__buffer__,1,3))) __attribute__ ((__bounded__(__buffer__,2,3))); void bzero(void *, size_t) __attribute__ ((__bounded__(__buffer__,1,2))); void explicit_bzero(void *, size_t) __attribute__ ((__bounded__(__buffer__,1,2))); int bcmp(const void *, const void *, size_t); void *memcpy(void *, const void *, size_t) __attribute__ ((__bounded__(__buffer__,1,3))) __attribute__ ((__bounded__(__buffer__,2,3))); void *memmove(void *, const void *, size_t) __attribute__ ((__bounded__(__buffer__,1,3))) __attribute__ ((__bounded__(__buffer__,2,3))); void *memset(void *, int, size_t) __attribute__ ((__bounded__(__buffer__,1,3))); int copystr(const void *, void *, size_t, size_t *) __attribute__ ((__bounded__(__string__,2,3))); int copyinstr(const void *, void *, size_t, size_t *) __attribute__ ((__bounded__(__string__,2,3))); int copyoutstr(const void *, void *, size_t, size_t *); int copyin(const void *, void *, size_t) __attribute__ ((__bounded__(__buffer__,2,3))); int copyout(const void *, void *, size_t); int copyin32(const uint32_t *, uint32_t *); void arc4random_buf(void *, size_t) __attribute__ ((__bounded__(__buffer__,1,2))); u_int32_t arc4random(void); u_int32_t arc4random_uniform(u_int32_t); struct timeval; struct timespec; int tvtohz(const struct timeval *); int tstohz(const struct timespec *); void realitexpire(void *); struct intrframe; void hardclock(struct intrframe *); void softclock(void *); void statclock(struct intrframe *); void initclocks(void); void inittodr(time_t); void resettodr(void); void cpu_initclocks(void); void startprofclock(struct process *); void stopprofclock(struct process *); void setstatclockrate(int); void start_periodic_resettodr(void); void stop_periodic_resettodr(void); struct sleep_state; void sleep_setup(struct sleep_state *, const volatile void *, int, const char *); void sleep_setup_timeout(struct sleep_state *, int); void sleep_setup_signal(struct sleep_state *, int); void sleep_finish(struct sleep_state *, int); int sleep_finish_timeout(struct sleep_state *); int sleep_finish_signal(struct sleep_state *); void sleep_queue_init(void); struct cond; void cond_init(struct cond *); void cond_wait(struct cond *, const char *); void cond_signal(struct cond *); struct mutex; struct rwlock; void wakeup_n(const volatile void *, int); void wakeup(const volatile void *); int tsleep(const volatile void *, int, const char *, int); int msleep(const volatile void *, struct mutex *, int, const char*, int); int rwsleep(const volatile void *, struct rwlock *, int, const char *, int); void yield(void); void wdog_register(int (*)(void *, int), void *); void wdog_shutdown(void *); struct hook_desc { struct { struct hook_desc *tqe_next; struct hook_desc **tqe_prev; } hd_list; void (*hd_fn)(void *); void *hd_arg; }; struct hook_desc_head { struct hook_desc *tqh_first; struct hook_desc **tqh_last; }; extern struct hook_desc_head startuphook_list; void *hook_establish(struct hook_desc_head *, int, void (*)(void *), void *); void hook_disestablish(struct hook_desc_head *, void *); void dohooks(struct hook_desc_head *, int); struct uio; int uiomove(void *, size_t, struct uio *); extern struct rwlock netlock; __attribute__((returns_twice)) int setjmp(label_t *); __attribute__((__noreturn__)) void longjmp(label_t *); void consinit(void); void cpu_startup(void); void cpu_configure(void); void diskconf(void); int nfs_mountroot(void); int dk_mountroot(void); extern int (*mountroot)(void); static __inline int imax(int, int); static __inline int imin(int, int); static __inline u_int max(u_int, u_int); static __inline u_int min(u_int, u_int); static __inline long lmax(long, long); static __inline long lmin(long, long); static __inline u_long ulmax(u_long, u_long); static __inline u_long ulmin(u_long, u_long); static __inline int abs(int); static __inline int imax(int a, int b) { return (a > b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline long lmax(long a, long b) { return (a > b ? a : b); } static __inline long lmin(long a, long b) { return (a < b ? a : b); } static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); } static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); } static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); } static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); } static __inline int abs(int j) { return(j < 0 ? -j : j); } void __assert(const char *, const char *, int, const char *) __attribute__ ((__noreturn__)); int bcmp(const void *, const void *, size_t); void bzero(void *, size_t); void explicit_bzero(void *, size_t); int ffs(int); int fls(int); int flsl(long); void *memchr(const void *, int, size_t); int memcmp(const void *, const void *, size_t); void *memset(void *, int c, size_t len); u_int32_t random(void); int scanc(u_int, const u_char *, const u_char [], int); int skpc(int, size_t, u_char *); size_t strlen(const char *); char *strncpy(char *, const char *, size_t) __attribute__ ((__bounded__(__string__,1,3))); size_t strnlen(const char *, size_t); size_t strlcpy(char *, const char *, size_t) __attribute__ ((__bounded__(__string__,1,3))); size_t strlcat(char *, const char *, size_t) __attribute__ ((__bounded__(__string__,1,3))); int strcmp(const char *, const char *); int strncmp(const char *, const char *, size_t); int strncasecmp(const char *, const char *, size_t); int getsn(char *, int); char *strchr(const char *, int); char *strrchr(const char *, int); int timingsafe_bcmp(const void *, const void *, size_t); void user_config(void); void _kernel_lock_init(void); void _kernel_lock(const char *, int); void _kernel_unlock(void); int _kernel_lock_held(void); struct kmemstats { long ks_inuse; long ks_calls; long ks_memuse; u_short ks_limblocks; u_short ks_mapblocks; long ks_maxused; long ks_limit; long ks_size; long ks_spare; }; struct kmemusage { short ku_indx; union { u_short freecnt; u_short pagecnt; } ku_un; }; struct kmem_freelist; struct kmembuckets { struct { struct kmem_freelist *sqx_first; struct kmem_freelist **sqx_last; unsigned long sqx_cookie; } kb_freelist; u_int64_t kb_calls; u_int64_t kb_total; u_int64_t kb_totalfree; u_int64_t kb_elmpercl; u_int64_t kb_highwat; u_int64_t kb_couldfree; }; extern struct kmemstats kmemstats[]; extern struct kmemusage *kmemusage; extern char *kmembase; extern struct kmembuckets bucket[]; void *malloc(size_t, int, int); void *mallocarray(size_t, size_t, int, int); void free(void *, int, size_t); int sysctl_malloc(int *, u_int, void *, size_t *, void *, size_t, struct proc *); size_t malloc_roundup(size_t); void malloc_printit(int (*)(const char *, ...)); void poison_mem(void *, size_t); int poison_check(void *, size_t, size_t *, uint32_t *); uint32_t poison_value(void *); struct m_tag { struct { struct m_tag *sle_next; } m_tag_link; u_int16_t m_tag_id; u_int16_t m_tag_len; }; struct m_hdr { struct mbuf *mh_next; struct mbuf *mh_nextpkt; caddr_t mh_data; u_int mh_len; short mh_type; u_short mh_flags; }; struct pf_state_key; struct inpcb; struct pkthdr_pf { struct pf_state_key *statekey; struct inpcb *inp; u_int32_t qid; u_int16_t tag; u_int8_t flags; u_int8_t routed; u_int8_t prio; u_int8_t pad[3]; }; struct pkthdr { void *ph_cookie; struct { struct m_tag *slh_first; } ph_tags; int64_t ph_timestamp; int len; u_int16_t ph_tagsset; u_int16_t ph_flowid; u_int16_t csum_flags; u_int16_t ether_vtag; u_int ph_rtableid; u_int ph_ifidx; u_int8_t ph_loopcnt; u_int8_t ph_family; struct pkthdr_pf pf; }; struct mbuf_ext { caddr_t ext_buf; void *ext_arg; u_int ext_free_fn; u_int ext_size; struct mbuf *ext_nextref; struct mbuf *ext_prevref; }; struct mbuf { struct m_hdr m_hdr; union { struct { struct pkthdr MH_pkthdr; union { struct mbuf_ext MH_ext; char MH_databuf[((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))]; } MH_dat; } MH; char M_databuf[(256 - sizeof(struct m_hdr))]; } M_dat; }; u_int mextfree_register(void (*)(caddr_t, u_int, void *)); struct mbstat { u_long m_drops; u_long m_wait; u_long m_drain; u_short m_mtypes[256]; }; struct mbuf_list { struct mbuf *ml_head; struct mbuf *ml_tail; u_int ml_len; }; struct mbuf_queue { struct mutex mq_mtx; struct mbuf_list mq_list; u_int mq_maxlen; u_int mq_drops; }; struct pool; extern int nmbclust; extern int mblowat; extern int mcllowat; extern int max_linkhdr; extern int max_protohdr; extern int max_hdr; void mbinit(void); void mbcpuinit(void); struct mbuf *m_copym(struct mbuf *, int, int, int); struct mbuf *m_free(struct mbuf *); struct mbuf *m_get(int, int); struct mbuf *m_getclr(int, int); struct mbuf *m_gethdr(int, int); struct mbuf *m_inithdr(struct mbuf *); void m_resethdr(struct mbuf *); int m_defrag(struct mbuf *, int); struct mbuf *m_prepend(struct mbuf *, int, int); struct mbuf *m_pulldown(struct mbuf *, int, int, int *); struct mbuf *m_pullup(struct mbuf *, int); struct mbuf *m_split(struct mbuf *, int, int); struct mbuf *m_makespace(struct mbuf *, int, int, int *); struct mbuf *m_getptr(struct mbuf *, int, int *); int m_leadingspace(struct mbuf *); int m_trailingspace(struct mbuf *); struct mbuf *m_clget(struct mbuf *, int, u_int); void m_extref(struct mbuf *, struct mbuf *); void m_pool_init(struct pool *, u_int, u_int, const char *); void m_extfree_pool(caddr_t, u_int, void *); void m_adj(struct mbuf *, int); int m_copyback(struct mbuf *, int, int, const void *, int); struct mbuf *m_freem(struct mbuf *); void m_purge(struct mbuf *); void m_reclaim(void *, int); void m_copydata(struct mbuf *, int, int, caddr_t); void m_cat(struct mbuf *, struct mbuf *); struct mbuf *m_devget(char *, int, int); int m_apply(struct mbuf *, int, int, int (*)(caddr_t, caddr_t, unsigned int), caddr_t); struct mbuf *m_dup_pkt(struct mbuf *, unsigned int, int); int m_dup_pkthdr(struct mbuf *, struct mbuf *, int); static inline struct mbuf * m_freemp(struct mbuf **mp) { struct mbuf *m = *mp; *mp = ((void *)0); return m_freem(m); } struct m_tag *m_tag_get(int, int, int); void m_tag_prepend(struct mbuf *, struct m_tag *); void m_tag_delete(struct mbuf *, struct m_tag *); void m_tag_delete_chain(struct mbuf *); struct m_tag *m_tag_find(struct mbuf *, int, struct m_tag *); struct m_tag *m_tag_copy(struct m_tag *, int); int m_tag_copy_chain(struct mbuf *, struct mbuf *, int); void m_tag_init(struct mbuf *); struct m_tag *m_tag_first(struct mbuf *); struct m_tag *m_tag_next(struct mbuf *, struct m_tag *); void ml_init(struct mbuf_list *); void ml_enqueue(struct mbuf_list *, struct mbuf *); struct mbuf * ml_dequeue(struct mbuf_list *); void ml_enlist(struct mbuf_list *, struct mbuf_list *); struct mbuf * ml_dechain(struct mbuf_list *); unsigned int ml_purge(struct mbuf_list *); void mq_init(struct mbuf_queue *, u_int, int); int mq_enqueue(struct mbuf_queue *, struct mbuf *); struct mbuf * mq_dequeue(struct mbuf_queue *); int mq_enlist(struct mbuf_queue *, struct mbuf_list *); void mq_delist(struct mbuf_queue *, struct mbuf_list *); struct mbuf * mq_dechain(struct mbuf_queue *); unsigned int mq_purge(struct mbuf_queue *); extern long hostid; extern char hostname[256]; extern int hostnamelen; extern char domainname[256]; extern int domainnamelen; extern struct timespec boottime; extern struct timezone tz; extern int tick; extern int tickfix; extern int tickfixinterval; extern int tickadj; extern int ticks; extern int hz; extern int stathz; extern int profhz; extern int lbolt; extern int tickdelta; extern long timedelta; extern int64_t adjtimedelta; extern struct bintime naptime; struct syslog_data { int log_stat; const char *log_tag; int log_fac; int log_mask; }; void logpri(int); void log(int, const char *, ...) __attribute__((__format__(__kprintf__,2,3))); int addlog(const char *, ...) __attribute__((__format__(__kprintf__,1,2))); void logwakeup(void); typedef __socklen_t socklen_t; struct mbuf; struct ifnet; struct domain { int dom_family; char *dom_name; void (*dom_init)(void); int (*dom_externalize)(struct mbuf *, socklen_t, int); void (*dom_dispose)(struct mbuf *); const struct protosw *dom_protosw, *dom_protoswNPROTOSW; unsigned int dom_rtkeylen; unsigned int dom_rtoffset; unsigned int dom_maxplen; void *(*dom_ifattach)(struct ifnet *); void (*dom_ifdetach)(struct ifnet *, void *); }; extern struct domain *domains[]; void domaininit(void); extern struct domain inetdomain; extern struct domain inet6domain; struct mbuf; struct sockaddr; struct socket; struct domain; struct proc; struct protosw { short pr_type; struct domain *pr_domain; short pr_protocol; short pr_flags; int (*pr_input)(struct mbuf **, int *, int, int); int (*pr_output)(struct mbuf *, struct socket *, struct sockaddr *, struct mbuf *); void (*pr_ctlinput)(int, struct sockaddr *, u_int, void *); int (*pr_ctloutput)(int, struct socket *, int, int, struct mbuf *); int (*pr_usrreq)(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int (*pr_attach)(struct socket *, int); int (*pr_detach)(struct socket *); void (*pr_init)(void); void (*pr_fasttimo)(void); void (*pr_slowtimo)(void); int (*pr_sysctl)(int *, u_int, void *, size_t *, void *, size_t); }; struct sockaddr; const struct protosw *pffindproto(int, int, int); const struct protosw *pffindtype(int, int); void pfctlinput(int, struct sockaddr *); extern u_char ip_protox[]; extern const struct protosw inetsw[]; struct kinfo_pool { unsigned int pr_size; unsigned int pr_pgsize; unsigned int pr_itemsperpage; unsigned int pr_minpages; unsigned int pr_maxpages; unsigned int pr_hardlimit; unsigned int pr_npages; unsigned int pr_nout; unsigned int pr_nitems; unsigned long pr_nget; unsigned long pr_nput; unsigned long pr_nfail; unsigned long pr_npagealloc; unsigned long pr_npagefree; unsigned int pr_hiwat; unsigned long pr_nidle; }; struct kinfo_pool_cache { uint64_t pr_ngc; unsigned int pr_len; unsigned int pr_nitems; unsigned int pr_contention; }; struct kinfo_pool_cache_cpu { unsigned int pr_cpu; uint64_t pr_nget; uint64_t pr_nfail; uint64_t pr_nput; uint64_t pr_nlget; uint64_t pr_nlfail; uint64_t pr_nlput; }; struct rb_type { int (*t_compare)(const void *, const void *); void (*t_augment)(void *); unsigned int t_offset; }; struct rb_tree { struct rb_entry *rbt_root; }; struct rb_entry { struct rb_entry *rbt_parent; struct rb_entry *rbt_left; struct rb_entry *rbt_right; unsigned int rbt_color; }; static inline void _rb_init(struct rb_tree *rbt) { rbt->rbt_root = ((void *)0); } static inline int _rb_empty(struct rb_tree *rbt) { return (rbt->rbt_root == ((void *)0)); } void *_rb_insert(const struct rb_type *, struct rb_tree *, void *); void *_rb_remove(const struct rb_type *, struct rb_tree *, void *); void *_rb_find(const struct rb_type *, struct rb_tree *, const void *); void *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *); void *_rb_root(const struct rb_type *, struct rb_tree *); void *_rb_min(const struct rb_type *, struct rb_tree *); void *_rb_max(const struct rb_type *, struct rb_tree *); void *_rb_next(const struct rb_type *, void *); void *_rb_prev(const struct rb_type *, void *); void *_rb_left(const struct rb_type *, void *); void *_rb_right(const struct rb_type *, void *); void *_rb_parent(const struct rb_type *, void *); void _rb_set_left(const struct rb_type *, void *, void *); void _rb_set_right(const struct rb_type *, void *, void *); void _rb_set_parent(const struct rb_type *, void *, void *); void _rb_poison(const struct rb_type *, void *, unsigned long); int _rb_check(const struct rb_type *, void *, unsigned long); struct pool; struct pool_request; struct pool_lock_ops; struct pool_requests { struct pool_request *tqh_first; struct pool_request **tqh_last; }; struct pool_allocator { void *(*pa_alloc)(struct pool *, int, int *); void (*pa_free)(struct pool *, void *); size_t pa_pagesz; }; struct pool_pagelist { struct pool_page_header *tqh_first; struct pool_page_header **tqh_last; }; struct pool_cache_item; struct pool_cache_lists { struct pool_cache_item *tqh_first; struct pool_cache_item **tqh_last; }; struct cpumem; union pool_lock { struct mutex prl_mtx; struct rwlock prl_rwlock; }; struct pool { union pool_lock pr_lock; const struct pool_lock_ops * pr_lock_ops; struct { struct pool *sqe_next; } pr_poollist; struct pool_pagelist pr_emptypages; struct pool_pagelist pr_fullpages; struct pool_pagelist pr_partpages; struct pool_page_header * pr_curpage; unsigned int pr_size; unsigned int pr_minitems; unsigned int pr_minpages; unsigned int pr_maxpages; unsigned int pr_npages; unsigned int pr_itemsperpage; unsigned int pr_slack; unsigned int pr_nitems; unsigned int pr_nout; unsigned int pr_hardlimit; unsigned int pr_serial; unsigned int pr_pgsize; vaddr_t pr_pgmask; struct pool_allocator * pr_alloc; const char * pr_wchan; int pr_flags; int pr_ipl; struct phtree { struct rb_tree rbh_root; } pr_phtree; struct cpumem * pr_cache; unsigned long pr_cache_magic[2]; union pool_lock pr_cache_lock; struct pool_cache_lists pr_cache_lists; u_int pr_cache_nitems; u_int pr_cache_items; u_int pr_cache_contention; u_int pr_cache_contention_prev; int pr_cache_tick; int pr_cache_nout; uint64_t pr_cache_ngc; u_int pr_align; u_int pr_maxcolors; int pr_phoffset; const char *pr_hardlimit_warning; struct timeval pr_hardlimit_ratecap; struct timeval pr_hardlimit_warning_last; union pool_lock pr_requests_lock; struct pool_requests pr_requests; unsigned int pr_requesting; unsigned long pr_nget; unsigned long pr_nfail; unsigned long pr_nput; unsigned long pr_npagealloc; unsigned long pr_npagefree; unsigned int pr_hiwat; unsigned long pr_nidle; const struct kmem_pa_mode * pr_crange; }; extern struct pool_allocator pool_allocator_single; extern struct pool_allocator pool_allocator_multi; struct pool_request { struct { struct pool_request *tqe_next; struct pool_request **tqe_prev; } pr_entry; void (*pr_handler)(struct pool *, void *, void *); void *pr_cookie; void *pr_item; }; void pool_init(struct pool *, size_t, u_int, int, int, const char *, struct pool_allocator *); void pool_cache_init(struct pool *); void pool_destroy(struct pool *); void pool_setlowat(struct pool *, int); void pool_sethiwat(struct pool *, int); int pool_sethardlimit(struct pool *, u_int, const char *, int); struct uvm_constraint_range; void pool_set_constraints(struct pool *, const struct kmem_pa_mode *mode); void *pool_get(struct pool *, int) __attribute__((__malloc__)); void pool_request_init(struct pool_request *, void (*)(struct pool *, void *, void *), void *); void pool_request(struct pool *, struct pool_request *); void pool_put(struct pool *, void *); int pool_reclaim(struct pool *); void pool_reclaim_all(void); int pool_prime(struct pool *, int); void dma_alloc_init(void); void *dma_alloc(size_t size, int flags); void dma_free(void *m, size_t size); struct uvmexp { int pagesize; int pagemask; int pageshift; int npages; int free; int active; int inactive; int paging; int wired; int zeropages; int reserve_pagedaemon; int reserve_kernel; int anonpages; int vnodepages; int vtextpages; int freemin; int freetarg; int inactarg; int wiredmax; int anonmin; int vtextmin; int vnodemin; int anonminpct; int vtextminpct; int vnodeminpct; int nswapdev; int swpages; int swpginuse; int swpgonly; int nswget; int nanon; int nanonneeded; int nfreeanon; int faults; int traps; int intrs; int swtch; int softs; int syscalls; int pageins; int obsolete_swapins; int obsolete_swapouts; int pgswapin; int pgswapout; int forks; int forks_ppwait; int forks_sharevm; int pga_zerohit; int pga_zeromiss; int zeroaborts; int fltnoram; int fltnoanon; int fltnoamap; int fltpgwait; int fltpgrele; int fltrelck; int fltrelckok; int fltanget; int fltanretry; int fltamcopy; int fltnamap; int fltnomap; int fltlget; int fltget; int flt_anon; int flt_acow; int flt_obj; int flt_prcopy; int flt_przero; int pdwoke; int pdrevs; int pdswout; int pdfreed; int pdscans; int pdanscan; int pdobscan; int pdreact; int pdbusy; int pdpageouts; int pdpending; int pddeact; int pdreanon; int pdrevnode; int pdrevtext; int fpswtch; int kmapent; }; struct _ps_strings { void *val; }; struct ctlname { char *ctl_name; int ctl_type; }; struct kinfo_proc { u_int64_t p_forw; u_int64_t p_back; u_int64_t p_paddr; u_int64_t p_addr; u_int64_t p_fd; u_int64_t p_stats; u_int64_t p_limit; u_int64_t p_vmspace; u_int64_t p_sigacts; u_int64_t p_sess; u_int64_t p_tsess; u_int64_t p_ru; int32_t p_eflag; int32_t p_exitsig; int32_t p_flag; int32_t p_pid; int32_t p_ppid; int32_t p_sid; int32_t p__pgid; int32_t p_tpgid; u_int32_t p_uid; u_int32_t p_ruid; u_int32_t p_gid; u_int32_t p_rgid; u_int32_t p_groups[16]; int16_t p_ngroups; int16_t p_jobc; u_int32_t p_tdev; u_int32_t p_estcpu; u_int32_t p_rtime_sec; u_int32_t p_rtime_usec; int32_t p_cpticks; u_int32_t p_pctcpu; u_int32_t p_swtime; u_int32_t p_slptime; int32_t p_schedflags; u_int64_t p_uticks; u_int64_t p_sticks; u_int64_t p_iticks; u_int64_t p_tracep; int32_t p_traceflag; int32_t p_holdcnt; int32_t p_siglist; u_int32_t p_sigmask; u_int32_t p_sigignore; u_int32_t p_sigcatch; int8_t p_stat; u_int8_t p_priority; u_int8_t p_usrpri; u_int8_t p_nice; u_int16_t p_xstat; u_int16_t p_acflag; char p_comm[24]; char p_wmesg[8]; u_int64_t p_wchan; char p_login[32]; int32_t p_vm_rssize; int32_t p_vm_tsize; int32_t p_vm_dsize; int32_t p_vm_ssize; int64_t p_uvalid; u_int64_t p_ustart_sec; u_int32_t p_ustart_usec; u_int32_t p_uutime_sec; u_int32_t p_uutime_usec; u_int32_t p_ustime_sec; u_int32_t p_ustime_usec; u_int64_t p_uru_maxrss; u_int64_t p_uru_ixrss; u_int64_t p_uru_idrss; u_int64_t p_uru_isrss; u_int64_t p_uru_minflt; u_int64_t p_uru_majflt; u_int64_t p_uru_nswap; u_int64_t p_uru_inblock; u_int64_t p_uru_oublock; u_int64_t p_uru_msgsnd; u_int64_t p_uru_msgrcv; u_int64_t p_uru_nsignals; u_int64_t p_uru_nvcsw; u_int64_t p_uru_nivcsw; u_int32_t p_uctime_sec; u_int32_t p_uctime_usec; int32_t p_psflags; int32_t p_spare; u_int32_t p_svuid; u_int32_t p_svgid; char p_emul[8]; u_int64_t p_rlim_rss_cur; u_int64_t p_cpuid; u_int64_t p_vm_map_size; int32_t p_tid; u_int32_t p_rtableid; }; struct kinfo_vmentry { u_long kve_start; u_long kve_end; u_long kve_guard; u_long kve_fspace; u_long kve_fspace_augment; u_int64_t kve_offset; int kve_wired_count; int kve_etype; int kve_protection; int kve_max_protection; int kve_advice; int kve_inheritance; u_int8_t kve_flags; }; struct kinfo_file { uint64_t f_fileaddr; uint32_t f_flag; uint32_t f_iflags; uint32_t f_type; uint32_t f_count; uint32_t f_msgcount; uint32_t f_usecount; uint64_t f_ucred; uint32_t f_uid; uint32_t f_gid; uint64_t f_ops; uint64_t f_offset; uint64_t f_data; uint64_t f_rxfer; uint64_t f_rwfer; uint64_t f_seek; uint64_t f_rbytes; uint64_t f_wbytes; uint64_t v_un; uint32_t v_type; uint32_t v_tag; uint32_t v_flag; uint32_t va_rdev; uint64_t v_data; uint64_t v_mount; uint64_t va_fileid; uint64_t va_size; uint32_t va_mode; uint32_t va_fsid; char f_mntonname[96]; uint32_t so_type; uint32_t so_state; uint64_t so_pcb; uint32_t so_protocol; uint32_t so_family; uint64_t inp_ppcb; uint32_t inp_lport; uint32_t inp_laddru[4]; uint32_t inp_fport; uint32_t inp_faddru[4]; uint64_t unp_conn; uint64_t pipe_peer; uint32_t pipe_state; uint32_t kq_count; uint32_t kq_state; uint32_t __unused1; uint32_t p_pid; int32_t fd_fd; uint32_t fd_ofileflags; uint32_t p_uid; uint32_t p_gid; uint32_t p_tid; char p_comm[24]; uint32_t inp_rtableid; uint64_t so_splice; int64_t so_splicelen; uint64_t so_rcv_cc; uint64_t so_snd_cc; uint64_t unp_refs; uint64_t unp_nextref; uint64_t unp_addr; char unp_path[104]; uint32_t inp_proto; uint32_t t_state; uint64_t t_rcv_wnd; uint64_t t_snd_wnd; uint64_t t_snd_cwnd; uint32_t va_nlink; }; typedef int (sysctlfn)(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int sysctl_int(void *, size_t *, void *, size_t, int *); int sysctl_int_lower(void *, size_t *, void *, size_t, int *); int sysctl_rdint(void *, size_t *, void *, int); int sysctl_int_arr(int **, int *, u_int, void *, size_t *, void *, size_t); int sysctl_quad(void *, size_t *, void *, size_t, int64_t *); int sysctl_rdquad(void *, size_t *, void *, int64_t); int sysctl_string(void *, size_t *, void *, size_t, char *, size_t); int sysctl_tstring(void *, size_t *, void *, size_t, char *, size_t); int sysctl__string(void *, size_t *, void *, size_t, char *, size_t, int); int sysctl_rdstring(void *, size_t *, void *, const char *); int sysctl_rdstruct(void *, size_t *, void *, const void *, size_t); int sysctl_struct(void *, size_t *, void *, size_t, void *, size_t); int sysctl_file(int *, u_int, char *, size_t *, struct proc *); int sysctl_doproc(int *, u_int, char *, size_t *); struct mbuf_queue; int sysctl_mq(int *, u_int, void *, size_t *, void *, size_t, struct mbuf_queue *); struct rtentry; struct walkarg; int sysctl_dumpentry(struct rtentry *, void *, unsigned int); int sysctl_rtable(int *, u_int, void *, size_t *, void *, size_t); int sysctl_clockrate(char *, size_t *, void *); int sysctl_vnode(char *, size_t *, struct proc *); int sysctl_dopool(int *, u_int, char *, size_t *); int kern_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int hw_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int vm_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int fs_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int fs_posix_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int net_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int cpu_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int vfs_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); int sysctl_sysvipc(int *, u_int, void *, size_t *); int sysctl_wdog(int *, u_int, void *, size_t *, void *, size_t); extern int (*cpu_cpuspeed)(int *); extern void (*cpu_setperf)(int); int bpf_sysctl(int *, u_int, void *, size_t *, void *, size_t); int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t); int pipex_sysctl(int *, u_int, void *, size_t *, void *, size_t); int mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t); typedef __sa_family_t sa_family_t; struct linger { int l_onoff; int l_linger; }; struct splice { int sp_fd; off_t sp_max; struct timeval sp_idle; }; struct sockaddr { __uint8_t sa_len; sa_family_t sa_family; char sa_data[14]; }; struct sockaddr_storage { __uint8_t ss_len; sa_family_t ss_family; unsigned char __ss_pad1[6]; __uint64_t __ss_pad2; unsigned char __ss_pad3[240]; }; struct sockproto { unsigned short sp_family; unsigned short sp_protocol; }; struct sockpeercred { uid_t uid; gid_t gid; pid_t pid; }; struct msghdr { void *msg_name; socklen_t msg_namelen; struct iovec *msg_iov; unsigned int msg_iovlen; void *msg_control; socklen_t msg_controllen; int msg_flags; }; struct cmsghdr { socklen_t cmsg_len; int cmsg_level; int cmsg_type; }; void pfctlinput(int, struct sockaddr *); static inline struct sockaddr * sstosa(struct sockaddr_storage *ss) { return ((struct sockaddr *)(ss)); } struct kevent { __uintptr_t ident; short filter; unsigned short flags; unsigned int fflags; __int64_t data; void *udata; }; struct knote; struct klist { struct knote *slh_first; }; struct filterops { int f_isfd; int (*f_attach)(struct knote *kn); void (*f_detach)(struct knote *kn); int (*f_event)(struct knote *kn, long hint); }; struct knote { struct { struct knote *sle_next; } kn_link; struct { struct knote *sle_next; } kn_selnext; struct { struct knote *tqe_next; struct knote **tqe_prev; } kn_tqe; struct kqueue *kn_kq; struct kevent kn_kevent; int kn_status; int kn_sfflags; __int64_t kn_sdata; union { struct file *p_fp; struct process *p_process; } kn_ptr; const struct filterops *kn_fop; void *kn_hook; }; struct proc; extern void knote(struct klist *list, long hint); extern void knote_activate(struct knote *); extern void knote_remove(struct proc *p, struct klist *list); extern void knote_fdclose(struct proc *p, int fd); extern void knote_processexit(struct proc *); extern int kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p); extern int filt_seltrue(struct knote *kn, long hint); extern int seltrue_kqfilter(dev_t, struct knote *); extern void klist_invalidate(struct klist *); struct selinfo { struct klist si_note; pid_t si_seltid; short si_flags; }; struct proc; void selrecord(struct proc *selector, struct selinfo *); void selwakeup(struct selinfo *); struct taskq; struct task { struct { struct task *tqe_next; struct task **tqe_prev; } t_entry; void (*t_func)(void *); void *t_arg; unsigned int t_flags; }; struct task_list { struct task *tqh_first; struct task **tqh_last; }; extern struct taskq *const systq; extern struct taskq *const systqmp; struct taskq *taskq_create(const char *, unsigned int, int, unsigned int); void taskq_destroy(struct taskq *); void taskq_barrier(struct taskq *); void task_set(struct task *, void (*)(void *), void *); int task_add(struct taskq *, struct task *); int task_del(struct taskq *, struct task *); struct circq { struct circq *next; struct circq *prev; }; struct timeout { struct circq to_list; void (*to_func)(void *); void *to_arg; int to_time; int to_flags; }; struct bintime; void timeout_set(struct timeout *, void (*)(void *), void *); void timeout_set_proc(struct timeout *, void (*)(void *), void *); int timeout_add(struct timeout *, int); int timeout_add_tv(struct timeout *, const struct timeval *); int timeout_add_ts(struct timeout *, const struct timespec *); int timeout_add_bt(struct timeout *, const struct bintime *); int timeout_add_sec(struct timeout *, int); int timeout_add_msec(struct timeout *, int); int timeout_add_usec(struct timeout *, int); int timeout_add_nsec(struct timeout *, int); int timeout_del(struct timeout *); void timeout_barrier(struct timeout *); void timeout_startup(void); void timeout_adjust_ticks(int); int timeout_hardclock_update(void); struct soqhead { struct socket *tqh_first; struct socket **tqh_last; }; struct socket { const struct protosw *so_proto; void *so_pcb; u_int so_state; short so_type; short so_options; short so_linger; struct socket *so_head; struct soqhead *so_onq; struct soqhead so_q0; struct soqhead so_q; struct { struct socket *tqe_next; struct socket **tqe_prev; } so_qe; short so_q0len; short so_qlen; short so_qlimit; short so_timeo; u_int so_error; pid_t so_pgid; uid_t so_siguid; uid_t so_sigeuid; u_long so_oobmark; struct sosplice { struct socket *ssp_socket; struct socket *ssp_soback; off_t ssp_len; off_t ssp_max; struct timeval ssp_idletv; struct timeout ssp_idleto; struct task ssp_task; } *so_sp; struct sockbuf { u_long sb_cc; u_long sb_datacc; u_long sb_hiwat; u_long sb_wat; u_long sb_mbcnt; u_long sb_mbmax; long sb_lowat; struct mbuf *sb_mb; struct mbuf *sb_mbtail; struct mbuf *sb_lastrecord; u_short sb_timeo; short sb_flags; int sb_flagsintr; struct selinfo sb_sel; } so_rcv, so_snd; void (*so_upcall)(struct socket *so, caddr_t arg, int waitf); caddr_t so_upcallarg; uid_t so_euid, so_ruid; gid_t so_egid, so_rgid; pid_t so_cpid; }; void soassertlocked(struct socket *); static inline int sb_notify(struct socket *so, struct sockbuf *sb) { int flags = (sb->sb_flags | sb->sb_flagsintr); ((sb == &so->so_rcv || sb == &so->so_snd) ? (void)0 : __assert("diagnostic ", "/home/src/sys/sys/socketvar.h", 178, "sb == &so->so_rcv || sb == &so->so_snd")); soassertlocked(so); return ((flags & (0x04|0x08|0x10|0x20|0x80)) != 0); } static inline long sbspace(struct socket *so, struct sockbuf *sb) { ((sb == &so->so_rcv || sb == &so->so_snd) ? (void)0 : __assert("diagnostic ", "/home/src/sys/sys/socketvar.h", 192, "sb == &so->so_rcv || sb == &so->so_snd")); return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt); } static inline int soreadable(struct socket *so) { soassertlocked(so); if (((so)->so_sp && (so)->so_sp->ssp_socket)) return 0; return (so->so_state & 0x020) || so->so_qlen || so->so_error || so->so_rcv.sb_cc >= so->so_rcv.sb_lowat; } int sblock(struct socket *, struct sockbuf *, int); void sbunlock(struct socket *, struct sockbuf *); extern u_long sb_max; extern struct pool socket_pool; struct mbuf; struct sockaddr; struct proc; struct msghdr; struct stat; struct knote; int soo_read(struct file *fp, off_t *, struct uio *uio, struct ucred *cred); int soo_write(struct file *fp, off_t *, struct uio *uio, struct ucred *cred); int soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p); int soo_poll(struct file *fp, int events, struct proc *p); int soo_kqfilter(struct file *fp, struct knote *kn); int soo_close(struct file *fp, struct proc *p); int soo_stat(struct file *, struct stat *, struct proc *); void sbappend(struct socket *, struct sockbuf *, struct mbuf *); void sbappendstream(struct socket *, struct sockbuf *, struct mbuf *); int sbappendaddr(struct socket *, struct sockbuf *, struct sockaddr *, struct mbuf *, struct mbuf *); int sbappendcontrol(struct socket *, struct sockbuf *, struct mbuf *, struct mbuf *); void sbappendrecord(struct socket *, struct sockbuf *, struct mbuf *); void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n); struct mbuf * sbcreatecontrol(caddr_t p, int size, int type, int level); void sbdrop(struct socket *, struct sockbuf *, int); void sbdroprecord(struct sockbuf *sb); void sbflush(struct socket *, struct sockbuf *); void sbinsertoob(struct sockbuf *sb, struct mbuf *m0); void sbrelease(struct socket *, struct sockbuf *); int sbcheckreserve(u_long cnt, u_long defcnt); int sbchecklowmem(void); int sbreserve(struct socket *, struct sockbuf *, u_long); int sbwait(struct socket *, struct sockbuf *sb); int sb_lock(struct sockbuf *sb); void soinit(void); int soabort(struct socket *so); int soaccept(struct socket *so, struct mbuf *nam); int sobind(struct socket *so, struct mbuf *nam, struct proc *p); void socantrcvmore(struct socket *so); void socantsendmore(struct socket *so); int soclose(struct socket *so); int soconnect(struct socket *so, struct mbuf *nam); int soconnect2(struct socket *so1, struct socket *so2); int socreate(int dom, struct socket **aso, int type, int proto); int sodisconnect(struct socket *so); void sofree(struct socket *so); int sogetopt(struct socket *so, int level, int optname, struct mbuf *m); void sohasoutofband(struct socket *so); void soisconnected(struct socket *so); void soisconnecting(struct socket *so); void soisdisconnected(struct socket *so); void soisdisconnecting(struct socket *so); int solisten(struct socket *so, int backlog); struct socket *sonewconn(struct socket *head, int connstatus); void soqinsque(struct socket *head, struct socket *so, int q); int soqremque(struct socket *so, int q); int soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp, socklen_t controllen); int soreserve(struct socket *so, u_long sndcc, u_long rcvcc); void sorflush(struct socket *so); int sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags); int sosetopt(struct socket *so, int level, int optname, struct mbuf *m); int soshutdown(struct socket *so, int how); void sowakeup(struct socket *so, struct sockbuf *sb); void sorwakeup(struct socket *); void sowwakeup(struct socket *); int sockargs(struct mbuf **, const void *, size_t, int); int sosleep(struct socket *, void *, int, const char *, int); int solock(struct socket *); void sounlock(int); int sendit(struct proc *, int, struct msghdr *, int, register_t *); int recvit(struct proc *, int, struct msghdr *, caddr_t, register_t *); int doaccept(struct proc *, int, struct sockaddr *, socklen_t *, int, register_t *); struct if_nameindex { unsigned int if_index; char *if_name; }; struct if_clonereq { int ifcr_total; int ifcr_count; char *ifcr_buffer; }; struct if_rxring { int rxr_adjusted; u_int rxr_alive; u_int rxr_cwm; u_int rxr_lwm; u_int rxr_hwm; }; struct if_rxring_info { char ifr_name[16]; u_int ifr_size; struct if_rxring ifr_info; }; struct if_rxrinfo { u_int ifri_total; struct if_rxring_info *ifri_entries; }; struct if_data { u_char ifi_type; u_char ifi_addrlen; u_char ifi_hdrlen; u_char ifi_link_state; u_int32_t ifi_mtu; u_int32_t ifi_metric; u_int32_t ifi_rdomain; u_int64_t ifi_baudrate; u_int64_t ifi_ipackets; u_int64_t ifi_ierrors; u_int64_t ifi_opackets; u_int64_t ifi_oerrors; u_int64_t ifi_collisions; u_int64_t ifi_ibytes; u_int64_t ifi_obytes; u_int64_t ifi_imcasts; u_int64_t ifi_omcasts; u_int64_t ifi_iqdrops; u_int64_t ifi_oqdrops; u_int64_t ifi_noproto; u_int32_t ifi_capabilities; struct timeval ifi_lastchange; }; struct if_status_description { u_char ifs_type; u_char ifs_state; const char *ifs_string; }; struct if_msghdr { u_short ifm_msglen; u_char ifm_version; u_char ifm_type; u_short ifm_hdrlen; u_short ifm_index; u_short ifm_tableid; u_char ifm_pad1; u_char ifm_pad2; int ifm_addrs; int ifm_flags; int ifm_xflags; struct if_data ifm_data; }; struct ifa_msghdr { u_short ifam_msglen; u_char ifam_version; u_char ifam_type; u_short ifam_hdrlen; u_short ifam_index; u_short ifam_tableid; u_char ifam_pad1; u_char ifam_pad2; int ifam_addrs; int ifam_flags; int ifam_metric; }; struct if_announcemsghdr { u_short ifan_msglen; u_char ifan_version; u_char ifan_type; u_short ifan_hdrlen; u_short ifan_index; u_short ifan_what; char ifan_name[16]; }; struct if_nameindex_msg { unsigned int if_index; char if_name[16]; }; struct ifg_req { union { char ifgrqu_group[16]; char ifgrqu_member[16]; } ifgrq_ifgrqu; }; struct ifg_attrib { int ifg_carp_demoted; }; struct ifgroupreq { char ifgr_name[16]; u_int ifgr_len; union { char ifgru_group[16]; struct ifg_req *ifgru_groups; struct ifg_attrib ifgru_attrib; } ifgr_ifgru; }; struct ifreq { char ifr_name[16]; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; short ifru_flags; int ifru_metric; int64_t ifru_vnetid; uint64_t ifru_media; caddr_t ifru_data; unsigned int ifru_index; } ifr_ifru; }; struct ifaliasreq { char ifra_name[16]; union { struct sockaddr ifrau_addr; int ifrau_align; } ifra_ifrau; struct sockaddr ifra_dstaddr; struct sockaddr ifra_mask; }; struct ifmediareq { char ifm_name[16]; uint64_t ifm_current; uint64_t ifm_mask; uint64_t ifm_status; uint64_t ifm_active; int ifm_count; uint64_t *ifm_ulist; }; struct ifkalivereq { char ikar_name[16]; int ikar_timeo; int ikar_cnt; }; struct ifconf { int ifc_len; union { caddr_t ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu; }; struct if_laddrreq { char iflr_name[16]; unsigned int flags; unsigned int prefixlen; struct sockaddr_storage addr; struct sockaddr_storage dstaddr; }; struct if_afreq { char ifar_name[16]; sa_family_t ifar_af; }; struct if_parent { char ifp_name[16]; char ifp_parent[16]; }; struct arphdr { u_int16_t ar_hrd; u_int16_t ar_pro; u_int8_t ar_hln; u_int8_t ar_pln; u_int16_t ar_op; }; struct arpreq { struct sockaddr arp_pa; struct sockaddr arp_ha; int arp_flags; }; struct socket; struct ifnet; struct ifq_ops; void if_alloc_sadl(struct ifnet *); void if_free_sadl(struct ifnet *); void if_attach(struct ifnet *); void if_attach_queues(struct ifnet *, unsigned int); void if_attach_iqueues(struct ifnet *, unsigned int); void if_attach_ifq(struct ifnet *, const struct ifq_ops *, void *); void if_attachtail(struct ifnet *); void if_attachhead(struct ifnet *); void if_deactivate(struct ifnet *); void if_detach(struct ifnet *); void if_down(struct ifnet *); void if_downall(void); void if_link_state_change(struct ifnet *); void if_up(struct ifnet *); void if_getdata(struct ifnet *, struct if_data *); void ifinit(void); int ifioctl(struct socket *, u_long, caddr_t, struct proc *); int ifpromisc(struct ifnet *, int); struct ifg_group *if_creategroup(const char *); int if_addgroup(struct ifnet *, const char *); int if_delgroup(struct ifnet *, const char *); void if_group_routechange(struct sockaddr *, struct sockaddr *); struct ifnet *ifunit(const char *); struct ifnet *if_get(unsigned int); void if_put(struct ifnet *); void ifnewlladdr(struct ifnet *); void if_congestion(void); int if_congested(void); __attribute__((__noreturn__)) void unhandled_af(int); int if_setlladdr(struct ifnet *, const uint8_t *); struct taskq * net_tq(unsigned int); typedef int vm_fault_t; typedef int vm_inherit_t; typedef off_t voff_t; union vm_map_object; typedef union vm_map_object vm_map_object_t; struct vm_map_entry; typedef struct vm_map_entry *vm_map_entry_t; struct vm_map; typedef struct vm_map *vm_map_t; struct vm_page; typedef struct vm_page *vm_page_t; typedef int vm_prot_t; struct buf; struct mount; struct pglist; struct vmspace; struct pmap; typedef int boolean_t; struct proc; struct pmap_statistics { long resident_count; long wired_count; }; typedef struct pmap_statistics *pmap_statistics_t; struct uvm_object { struct uvm_pagerops *pgops; struct uvm_objtree { struct rb_tree rbh_root; } memt; int uo_npages; int uo_refs; }; extern struct uvm_pagerops uvm_vnodeops; extern struct uvm_pagerops uvm_deviceops; int uvm_pagecmp(const struct vm_page *, const struct vm_page *); extern const struct rb_type *const uvm_objtree_RBT_TYPE; __attribute__((__unused__)) static inline void uvm_objtree_RBT_INIT(struct uvm_objtree *head) { _rb_init(&head->rbh_root); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_INSERT(struct uvm_objtree *head, struct vm_page *elm) { return _rb_insert(uvm_objtree_RBT_TYPE, &head->rbh_root, elm); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_REMOVE(struct uvm_objtree *head, struct vm_page *elm) { return _rb_remove(uvm_objtree_RBT_TYPE, &head->rbh_root, elm); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_FIND(struct uvm_objtree *head, const struct vm_page *key) { return _rb_find(uvm_objtree_RBT_TYPE, &head->rbh_root, key); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_NFIND(struct uvm_objtree *head, const struct vm_page *key) { return _rb_nfind(uvm_objtree_RBT_TYPE, &head->rbh_root, key); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_ROOT(struct uvm_objtree *head) { return _rb_root(uvm_objtree_RBT_TYPE, &head->rbh_root); } __attribute__((__unused__)) static inline int uvm_objtree_RBT_EMPTY(struct uvm_objtree *head) { return _rb_empty(&head->rbh_root); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_MIN(struct uvm_objtree *head) { return _rb_min(uvm_objtree_RBT_TYPE, &head->rbh_root); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_MAX(struct uvm_objtree *head) { return _rb_max(uvm_objtree_RBT_TYPE, &head->rbh_root); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_NEXT(struct vm_page *elm) { return _rb_next(uvm_objtree_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_PREV(struct vm_page *elm) { return _rb_prev(uvm_objtree_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_LEFT(struct vm_page *elm) { return _rb_left(uvm_objtree_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_RIGHT(struct vm_page *elm) { return _rb_right(uvm_objtree_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_page * uvm_objtree_RBT_PARENT(struct vm_page *elm) { return _rb_parent(uvm_objtree_RBT_TYPE, elm); } __attribute__((__unused__)) static inline void uvm_objtree_RBT_SET_LEFT(struct vm_page *elm, struct vm_page *left) { return _rb_set_left(uvm_objtree_RBT_TYPE, elm, left); } __attribute__((__unused__)) static inline void uvm_objtree_RBT_SET_RIGHT(struct vm_page *elm, struct vm_page *right) { return _rb_set_right(uvm_objtree_RBT_TYPE, elm, right); } __attribute__((__unused__)) static inline void uvm_objtree_RBT_SET_PARENT(struct vm_page *elm, struct vm_page *parent) { return _rb_set_parent(uvm_objtree_RBT_TYPE, elm, parent); } __attribute__((__unused__)) static inline void uvm_objtree_RBT_POISON(struct vm_page *elm, unsigned long poison) { return _rb_poison(uvm_objtree_RBT_TYPE, elm, poison); } __attribute__((__unused__)) static inline int uvm_objtree_RBT_CHECK(struct vm_page *elm, unsigned long poison) { return _rb_check(uvm_objtree_RBT_TYPE, elm, poison); } void uvm_objinit(struct uvm_object *, struct uvm_pagerops *, int); int uvm_objwire(struct uvm_object *, voff_t, voff_t, struct pglist *); void uvm_objunwire(struct uvm_object *, voff_t, voff_t); typedef u_int64_t pd_entry_t; typedef u_int64_t pt_entry_t; extern pt_entry_t pg_nx; extern pt_entry_t pg_g_kern; struct pmap; typedef struct pmap *pmap_t; struct pmap_head { struct pmap *lh_first; }; struct pmap { struct mutex pm_mtx; struct uvm_object pm_obj[4 -1]; struct { struct pmap *le_next; struct pmap **le_prev; } pm_list; pd_entry_t *pm_pdir; paddr_t pm_pdirpa; struct vm_page *pm_ptphint[4 -1]; struct pmap_statistics pm_stats; u_int64_t pm_cpus; int pm_type; }; struct pv_entry { struct pv_entry *pv_next; struct pmap *pv_pmap; vaddr_t pv_va; struct vm_page *pv_ptp; }; extern u_long PTDpaddr; extern struct pmap kernel_pmap_store; extern paddr_t ptp_masks[]; extern int ptp_shifts[]; extern long nkptp[], nbpd[], nkptpmax[]; paddr_t pmap_bootstrap(paddr_t, paddr_t); boolean_t pmap_clear_attrs(struct vm_page *, unsigned long); static void pmap_page_protect(struct vm_page *, vm_prot_t); void pmap_page_remove (struct vm_page *); static void pmap_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t); void pmap_remove(struct pmap *, vaddr_t, vaddr_t); boolean_t pmap_test_attrs(struct vm_page *, unsigned); static void pmap_update_pg(vaddr_t); static void pmap_update_2pg(vaddr_t,vaddr_t); void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t); void pmap_fix_ept(struct pmap *, vaddr_t); vaddr_t reserve_dumppages(vaddr_t); paddr_t pmap_prealloc_lowmem_ptps(paddr_t); void pagezero(vaddr_t); int pmap_convert(struct pmap *, int); void pmap_flush_cache(vaddr_t, vsize_t); static __inline void pmap_remove_all(struct pmap *pmap) { } __inline static void pmap_update_pg(vaddr_t va) { invlpg(va); } __inline static void pmap_update_2pg(vaddr_t va, vaddr_t vb) { invlpg(va); invlpg(vb); } __inline static void pmap_page_protect(struct vm_page *pg, vm_prot_t prot) { if ((prot & 0x02) == 0) { if (prot & (0x01 | 0x04)) { (void) pmap_clear_attrs(pg, 0x0000000000000002UL); } else { pmap_page_remove(pg); } } } __inline static void pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) { if ((prot & 0x02) == 0) { if (prot & (0x01| 0x04)) { pmap_write_protect(pmap, sva, eva, prot); } else { pmap_remove(pmap, sva, eva); } } } static __inline pt_entry_t * vtopte(vaddr_t va) { return (((pt_entry_t *) (255 * (1ULL << 39))) + (((((va) & ~0xffff000000000000)) & (((0x0000ff8000000000UL|0x0000007fc0000000UL)|0x000000003fe00000UL)|0x00000000001ff000UL)) >> 12)); } static __inline pt_entry_t * kvtopte(vaddr_t va) { return (((pt_entry_t *) (255 * (1ULL << 39))) + (((((va) & ~0xffff000000000000)) & (((0x0000ff8000000000UL|0x0000007fc0000000UL)|0x000000003fe00000UL)|0x00000000001ff000UL)) >> 12)); } struct pv_entry; struct vm_page_md { struct mutex pv_mtx; struct pv_entry *pv_list; }; void pmap_activate(struct proc *); void pmap_deactivate(struct proc *); void pmap_unwire(pmap_t, vaddr_t); void pmap_collect(pmap_t); void pmap_copy_page(struct vm_page *, struct vm_page *); struct pmap *pmap_create(void); void pmap_destroy(pmap_t); int pmap_enter(pmap_t, vaddr_t, paddr_t, vm_prot_t, int); boolean_t pmap_extract(pmap_t, vaddr_t, paddr_t *); vaddr_t pmap_growkernel(vaddr_t); void pmap_init(void); void pmap_kenter_pa(vaddr_t, paddr_t, vm_prot_t); void pmap_kremove(vaddr_t, vsize_t); void pmap_page_protect(struct vm_page *, vm_prot_t); void pmap_protect(pmap_t, vaddr_t, vaddr_t, vm_prot_t); void pmap_reference(pmap_t); void pmap_remove(pmap_t, vaddr_t, vaddr_t); void pmap_zero_page(struct vm_page *); void pmap_virtual_space(vaddr_t *, vaddr_t *); vaddr_t pmap_steal_memory(vsize_t, vaddr_t *, vaddr_t *); struct pglist { struct vm_page *tqh_first; struct vm_page **tqh_last; }; struct vm_page { struct { struct vm_page *tqe_next; struct vm_page **tqe_prev; } pageq; struct rb_entry objt; struct vm_anon *uanon; struct uvm_object *uobject; voff_t offset; u_int pg_flags; u_int pg_version; u_int wire_count; paddr_t phys_addr; psize_t fpgsz; struct vm_page_md mdpage; }; struct vm_physseg { paddr_t start; paddr_t end; paddr_t avail_start; paddr_t avail_end; struct vm_page *pgs; struct vm_page *lastpg; }; extern boolean_t vm_page_zero_enable; extern struct vm_physseg vm_physmem[16]; extern int vm_nphysseg; void uvm_page_init(vaddr_t *, vaddr_t *); void uvm_pageactivate(struct vm_page *); vaddr_t uvm_pageboot_alloc(vsize_t); void uvm_pagecopy(struct vm_page *, struct vm_page *); void uvm_pagedeactivate(struct vm_page *); void uvm_pagefree(struct vm_page *); void uvm_page_unbusy(struct vm_page **, int); struct vm_page *uvm_pagelookup(struct uvm_object *, voff_t); void uvm_pageunwire(struct vm_page *); void uvm_pagewait(struct vm_page *, int); void uvm_pagewake(struct vm_page *); void uvm_pagewire(struct vm_page *); void uvm_pagezero(struct vm_page *); void uvm_pagealloc_pg(struct vm_page *, struct uvm_object *, voff_t, struct vm_anon *); struct uvm_constraint_range; psize_t uvm_pagecount(struct uvm_constraint_range*); struct vm_page *PHYS_TO_VM_PAGE(paddr_t); int vm_physseg_find(paddr_t, int *); void uvm_map_clip_end(struct vm_map*, struct vm_map_entry*, vaddr_t); void uvm_map_clip_start(struct vm_map*, struct vm_map_entry*, vaddr_t); struct vm_anon { struct vm_page *an_page; int an_ref; int an_swslot; }; struct vm_aref { int ar_pageoff; struct vm_amap *ar_amap; }; struct vm_anon *uvm_analloc(void); void uvm_anfree(struct vm_anon *); void uvm_anwait(void); void uvm_anon_init(void); void uvm_anon_dropswap(struct vm_anon *); boolean_t uvm_anon_pagein(struct vm_anon *); union vm_map_object { struct uvm_object *uvm_obj; struct vm_map *sub_map; }; struct vm_map_entry { union { struct rb_entry addr_entry; struct { struct vm_map_entry *sle_next; } addr_kentry; } daddrs; union { struct rb_entry rbtree; struct { struct vm_map_entry *tqe_next; struct vm_map_entry **tqe_prev; } tailq; struct { struct vm_map_entry *tqe_next; struct vm_map_entry **tqe_prev; } deadq; } dfree; vaddr_t start; vaddr_t end; vsize_t guard; vsize_t fspace; union vm_map_object object; voff_t offset; struct vm_aref aref; int etype; vm_prot_t protection; vm_prot_t max_protection; vm_inherit_t inheritance; int wired_count; int advice; u_int8_t flags; vsize_t fspace_augment; }; struct uvm_map_deadq { struct vm_map_entry *tqh_first; struct vm_map_entry **tqh_last; }; struct uvm_map_addr { struct rb_tree rbh_root; }; extern const struct rb_type *const uvm_map_addr_RBT_TYPE; __attribute__((__unused__)) static inline void uvm_map_addr_RBT_INIT(struct uvm_map_addr *head) { _rb_init(&head->rbh_root); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_INSERT(struct uvm_map_addr *head, struct vm_map_entry *elm) { return _rb_insert(uvm_map_addr_RBT_TYPE, &head->rbh_root, elm); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_REMOVE(struct uvm_map_addr *head, struct vm_map_entry *elm) { return _rb_remove(uvm_map_addr_RBT_TYPE, &head->rbh_root, elm); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_FIND(struct uvm_map_addr *head, const struct vm_map_entry *key) { return _rb_find(uvm_map_addr_RBT_TYPE, &head->rbh_root, key); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_NFIND(struct uvm_map_addr *head, const struct vm_map_entry *key) { return _rb_nfind(uvm_map_addr_RBT_TYPE, &head->rbh_root, key); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_ROOT(struct uvm_map_addr *head) { return _rb_root(uvm_map_addr_RBT_TYPE, &head->rbh_root); } __attribute__((__unused__)) static inline int uvm_map_addr_RBT_EMPTY(struct uvm_map_addr *head) { return _rb_empty(&head->rbh_root); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_MIN(struct uvm_map_addr *head) { return _rb_min(uvm_map_addr_RBT_TYPE, &head->rbh_root); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_MAX(struct uvm_map_addr *head) { return _rb_max(uvm_map_addr_RBT_TYPE, &head->rbh_root); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_NEXT(struct vm_map_entry *elm) { return _rb_next(uvm_map_addr_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_PREV(struct vm_map_entry *elm) { return _rb_prev(uvm_map_addr_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_LEFT(struct vm_map_entry *elm) { return _rb_left(uvm_map_addr_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_RIGHT(struct vm_map_entry *elm) { return _rb_right(uvm_map_addr_RBT_TYPE, elm); } __attribute__((__unused__)) static inline struct vm_map_entry * uvm_map_addr_RBT_PARENT(struct vm_map_entry *elm) { return _rb_parent(uvm_map_addr_RBT_TYPE, elm); } __attribute__((__unused__)) static inline void uvm_map_addr_RBT_SET_LEFT(struct vm_map_entry *elm, struct vm_map_entry *left) { return _rb_set_left(uvm_map_addr_RBT_TYPE, elm, left); } __attribute__((__unused__)) static inline void uvm_map_addr_RBT_SET_RIGHT(struct vm_map_entry *elm, struct vm_map_entry *right) { return _rb_set_right(uvm_map_addr_RBT_TYPE, elm, right); } __attribute__((__unused__)) static inline void uvm_map_addr_RBT_SET_PARENT(struct vm_map_entry *elm, struct vm_map_entry *parent) { return _rb_set_parent(uvm_map_addr_RBT_TYPE, elm, parent); } __attribute__((__unused__)) static inline void uvm_map_addr_RBT_POISON(struct vm_map_entry *elm, unsigned long poison) { return _rb_poison(uvm_map_addr_RBT_TYPE, elm, poison); } __attribute__((__unused__)) static inline int uvm_map_addr_RBT_CHECK(struct vm_map_entry *elm, unsigned long poison) { return _rb_check(uvm_map_addr_RBT_TYPE, elm, poison); }; struct vm_map { struct pmap * pmap; struct rwlock lock; struct mutex mtx; struct uvm_map_addr addr; vsize_t size; int ref_count; int flags; struct mutex flags_lock; unsigned int timestamp; vaddr_t min_offset; vaddr_t max_offset; vaddr_t b_start; vaddr_t b_end; vaddr_t s_start; vaddr_t s_end; struct uvm_addr_state *uaddr_exe; struct uvm_addr_state *uaddr_any[4]; struct uvm_addr_state *uaddr_brk_stack; }; struct vm_map_intrsafe { struct vm_map vmi_map; struct { struct vm_map_intrsafe *le_next; struct vm_map_intrsafe **le_prev; } vmi_list; }; extern vaddr_t uvm_maxkaddr; void uvm_map_deallocate(vm_map_t); int uvm_map_clean(vm_map_t, vaddr_t, vaddr_t, int); vm_map_t uvm_map_create(pmap_t, vaddr_t, vaddr_t, int); int uvm_map_extract(struct vm_map*, vaddr_t, vsize_t, vaddr_t*, int); vaddr_t uvm_map_pie(vaddr_t); vaddr_t uvm_map_hint(struct vmspace *, vm_prot_t, vaddr_t, vaddr_t); int uvm_map_inherit(vm_map_t, vaddr_t, vaddr_t, vm_inherit_t); int uvm_map_advice(vm_map_t, vaddr_t, vaddr_t, int); void uvm_map_init(void); boolean_t uvm_map_lookup_entry(vm_map_t, vaddr_t, vm_map_entry_t *); int uvm_map_replace(vm_map_t, vaddr_t, vaddr_t, vm_map_entry_t, int); int uvm_map_reserve(vm_map_t, vsize_t, vaddr_t, vsize_t, vaddr_t *); void uvm_map_setup(vm_map_t, vaddr_t, vaddr_t, int); int uvm_map_submap(vm_map_t, vaddr_t, vaddr_t, vm_map_t); void uvm_unmap(vm_map_t, vaddr_t, vaddr_t); void uvm_map_set_uaddr(struct vm_map*, struct uvm_addr_state**, struct uvm_addr_state*); int uvm_map_mquery(struct vm_map*, vaddr_t*, vsize_t, voff_t, int); void uvm_unmap_detach(struct uvm_map_deadq*, int); void uvm_unmap_remove(struct vm_map*, vaddr_t, vaddr_t, struct uvm_map_deadq*, boolean_t, boolean_t); struct kinfo_vmentry; int uvm_map_fill_vmmap(struct vm_map *, struct kinfo_vmentry *, size_t *); boolean_t vm_map_lock_try_ln(struct vm_map*, char*, int); void vm_map_lock_ln(struct vm_map*, char*, int); void vm_map_lock_read_ln(struct vm_map*, char*, int); void vm_map_unlock_ln(struct vm_map*, char*, int); void vm_map_unlock_read_ln(struct vm_map*, char*, int); void vm_map_downgrade_ln(struct vm_map*, char*, int); void vm_map_upgrade_ln(struct vm_map*, char*, int); void vm_map_busy_ln(struct vm_map*, char*, int); void vm_map_unbusy_ln(struct vm_map*, char*, int); struct uvm_faultinfo { vm_map_t orig_map; vaddr_t orig_rvaddr; vsize_t orig_size; vm_map_t map; unsigned int mapv; vm_map_entry_t entry; vsize_t size; }; void uvmfault_init(void); boolean_t uvmfault_lookup(struct uvm_faultinfo *, boolean_t); boolean_t uvmfault_relock(struct uvm_faultinfo *); void uvmfault_unlockall(struct uvm_faultinfo *, struct vm_amap *, struct uvm_object *, struct vm_anon *); int uvmfault_anonget(struct uvm_faultinfo *, struct vm_amap *, struct vm_anon *); int uvm_fault_wire(vm_map_t, vaddr_t, vaddr_t, vm_prot_t); void uvm_fault_unwire(vm_map_t, vaddr_t, vaddr_t); void uvm_fault_unwire_locked(vm_map_t, vaddr_t, vaddr_t); struct uvm_pagerops { void (*pgo_init)(void); void (*pgo_reference)(struct uvm_object *); void (*pgo_detach)(struct uvm_object *); int (*pgo_fault)(struct uvm_faultinfo *, vaddr_t, vm_page_t *, int, int, vm_fault_t, vm_prot_t, int); boolean_t (*pgo_flush)(struct uvm_object *, voff_t, voff_t, int); int (*pgo_get)(struct uvm_object *, voff_t, vm_page_t *, int *, int, vm_prot_t, int, int); int (*pgo_put)(struct uvm_object *, vm_page_t *, int, boolean_t); void (*pgo_cluster)(struct uvm_object *, voff_t, voff_t *, voff_t *); struct vm_page ** (*pgo_mk_pcluster)(struct uvm_object *, struct vm_page **, int *, struct vm_page *, int, voff_t, voff_t); }; void uvm_pager_dropcluster(struct uvm_object *, struct vm_page *, struct vm_page **, int *, int); void uvm_pager_init(void); int uvm_pager_put(struct uvm_object *, struct vm_page *, struct vm_page ***, int *, int, voff_t, voff_t); vaddr_t uvm_pagermapin(struct vm_page **, int, int); void uvm_pagermapout(vaddr_t, int); struct vm_page **uvm_mk_pcluster(struct uvm_object *, struct vm_page **, int *, struct vm_page *, int, voff_t, voff_t); struct vmspace { struct vm_map vm_map; int vm_refcnt; caddr_t vm_shm; segsz_t vm_rssize; segsz_t vm_swrss; segsz_t vm_tsize; segsz_t vm_dsize; segsz_t vm_dused; segsz_t vm_ssize; caddr_t vm_taddr; caddr_t vm_daddr; caddr_t vm_maxsaddr; caddr_t vm_minsaddr; }; struct uvm_constraint_range { paddr_t ucr_low; paddr_t ucr_high; }; extern struct uvmexp uvmexp; extern struct uvm_constraint_range isa_constraint; extern struct uvm_constraint_range dma_constraint; extern struct uvm_constraint_range no_constraint; extern struct uvm_constraint_range *uvm_md_constraints[]; extern struct pool *uvm_aiobuf_pool; extern struct vm_map *exec_map; extern struct vm_map *kernel_map; extern struct vm_map *kmem_map; extern struct vm_map *phys_map; extern vaddr_t vm_min_kernel_address; void vmapbuf(struct buf *, vsize_t); void vunmapbuf(struct buf *, vsize_t); struct uvm_object *uao_create(vsize_t, int); void uao_detach(struct uvm_object *); void uao_detach_locked(struct uvm_object *); void uao_reference(struct uvm_object *); void uao_reference_locked(struct uvm_object *); int uvm_fault(vm_map_t, vaddr_t, vm_fault_t, vm_prot_t); vaddr_t uvm_uarea_alloc(void); void uvm_uarea_free(struct proc *); void uvm_exit(struct process *); void uvm_init_limits(struct proc *); boolean_t uvm_kernacc(caddr_t, size_t, int); int uvm_vslock(struct proc *, caddr_t, size_t, vm_prot_t); void uvm_vsunlock(struct proc *, caddr_t, size_t); int uvm_vslock_device(struct proc *, void *, size_t, vm_prot_t, void **); void uvm_vsunlock_device(struct proc *, void *, size_t, void *); void uvm_pause(void); void uvm_init(void); int uvm_io(vm_map_t, struct uio *, int); vaddr_t uvm_km_alloc1(vm_map_t, vsize_t, vsize_t, boolean_t); void uvm_km_free(vm_map_t, vaddr_t, vsize_t); void uvm_km_free_wakeup(vm_map_t, vaddr_t, vsize_t); vaddr_t uvm_km_kmemalloc_pla(struct vm_map *, struct uvm_object *, vsize_t, vsize_t, int, paddr_t, paddr_t, paddr_t, paddr_t, int); vaddr_t uvm_km_valloc(vm_map_t, vsize_t); vaddr_t uvm_km_valloc_try(vm_map_t, vsize_t); vaddr_t uvm_km_valloc_wait(vm_map_t, vsize_t); vaddr_t uvm_km_valloc_align(struct vm_map *, vsize_t, vsize_t, int); vaddr_t uvm_km_valloc_prefer_wait(vm_map_t, vsize_t, voff_t); struct vm_map *uvm_km_suballoc(vm_map_t, vaddr_t *, vaddr_t *, vsize_t, int, boolean_t, vm_map_t); struct kmem_va_mode { struct vm_map **kv_map; vsize_t kv_align; char kv_wait; char kv_singlepage; }; struct kmem_pa_mode { struct uvm_constraint_range *kp_constraint; struct uvm_object **kp_object; paddr_t kp_align; paddr_t kp_boundary; int kp_maxseg; char kp_nomem; char kp_zero; char kp_pageable; }; struct kmem_dyn_mode { voff_t kd_prefer; int *kd_slowdown; char kd_waitok; char kd_trylock; }; extern const struct kmem_va_mode kv_any; extern const struct kmem_va_mode kv_intrsafe; extern const struct kmem_va_mode kv_page; extern const struct kmem_pa_mode kp_dirty; extern const struct kmem_pa_mode kp_zero; extern const struct kmem_pa_mode kp_dma; extern const struct kmem_pa_mode kp_dma_contig; extern const struct kmem_pa_mode kp_dma_zero; extern const struct kmem_pa_mode kp_pageable; extern const struct kmem_pa_mode kp_none; extern const struct kmem_dyn_mode kd_waitok; extern const struct kmem_dyn_mode kd_nowait; extern const struct kmem_dyn_mode kd_trylock; void *km_alloc(size_t, const struct kmem_va_mode *, const struct kmem_pa_mode *, const struct kmem_dyn_mode *); void km_free(void *, size_t, const struct kmem_va_mode *, const struct kmem_pa_mode *); int uvm_map(vm_map_t, vaddr_t *, vsize_t, struct uvm_object *, voff_t, vsize_t, unsigned int); int uvm_mapanon(vm_map_t, vaddr_t *, vsize_t, vsize_t, unsigned int); int uvm_map_pageable(vm_map_t, vaddr_t, vaddr_t, boolean_t, int); int uvm_map_pageable_all(vm_map_t, int, vsize_t); boolean_t uvm_map_checkprot(vm_map_t, vaddr_t, vaddr_t, vm_prot_t); int uvm_map_protect(vm_map_t, vaddr_t, vaddr_t, vm_prot_t, boolean_t); struct vmspace *uvmspace_alloc(vaddr_t, vaddr_t, boolean_t, boolean_t); void uvmspace_init(struct vmspace *, struct pmap *, vaddr_t, vaddr_t, boolean_t, boolean_t); void uvmspace_exec(struct proc *, vaddr_t, vaddr_t); struct vmspace *uvmspace_fork(struct process *); void uvmspace_free(struct vmspace *); struct vmspace *uvmspace_share(struct process *); int uvm_share(vm_map_t, vaddr_t, vm_prot_t, vm_map_t, vaddr_t, vsize_t); void uvm_meter(void); int uvm_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *); struct vm_page *uvm_pagealloc(struct uvm_object *, voff_t, struct vm_anon *, int); vaddr_t uvm_pagealloc_contig(vaddr_t, vaddr_t, vaddr_t, vaddr_t); int uvm_pagealloc_multi(struct uvm_object *, voff_t, vsize_t, int); void uvm_pagerealloc(struct vm_page *, struct uvm_object *, voff_t); int uvm_pagerealloc_multi(struct uvm_object *, voff_t, vsize_t, int, struct uvm_constraint_range *); void uvm_page_physload(paddr_t, paddr_t, paddr_t, paddr_t, int); void uvm_setpagesize(void); void uvm_shutdown(void); void uvm_aio_biodone(struct buf *); void uvm_aio_aiodone(struct buf *); void uvm_pageout(void *); void uvm_aiodone_daemon(void *); void uvm_wait(const char *); int uvm_pglistalloc(psize_t, paddr_t, paddr_t, paddr_t, paddr_t, struct pglist *, int, int); void uvm_pglistfree(struct pglist *); void uvm_pmr_use_inc(paddr_t, paddr_t); void uvm_swap_init(void); typedef int uvm_coredump_setup_cb(int _nsegment, void *_cookie); typedef int uvm_coredump_walk_cb(vaddr_t _start, vaddr_t _realend, vaddr_t _end, vm_prot_t _prot, int _nsegment, void *_cookie); int uvm_coredump_walkmap(struct proc *_p, uvm_coredump_setup_cb *_setup, uvm_coredump_walk_cb *_walk, void *_cookie); void uvm_grow(struct proc *, vaddr_t); void uvm_deallocate(vm_map_t, vaddr_t, vsize_t); struct uvm_object *uvn_attach(struct vnode *, vm_prot_t); void uvm_pagezero_thread(void *); void kmeminit_nkmempages(void); void kmeminit(void); extern u_int nkmempages; struct process; struct kinfo_vmentry; int fill_vmmap(struct process *, struct kinfo_vmentry *, size_t *); typedef __in_addr_t in_addr_t; typedef __in_port_t in_port_t; struct in_addr { in_addr_t s_addr; }; struct sockaddr_in { u_int8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; int8_t sin_zero[8]; }; struct ip_opts { struct in_addr ip_dst; int8_t ip_opts[40]; }; struct ip_mreq { struct in_addr imr_multiaddr; struct in_addr imr_interface; }; struct in6_addr { union { u_int8_t __u6_addr8[16]; u_int16_t __u6_addr16[8]; u_int32_t __u6_addr32[4]; } __u6_addr; }; struct sockaddr_in6 { u_int8_t sin6_len; sa_family_t sin6_family; in_port_t sin6_port; u_int32_t sin6_flowinfo; struct in6_addr sin6_addr; u_int32_t sin6_scope_id; }; extern const struct sockaddr_in6 sa6_any; extern const struct in6_addr in6mask0; extern const struct in6_addr in6mask32; extern const struct in6_addr in6mask64; extern const struct in6_addr in6mask96; extern const struct in6_addr in6mask128; extern const struct in6_addr in6addr_any; extern const struct in6_addr in6addr_loopback; extern const struct in6_addr in6addr_intfacelocal_allnodes; extern const struct in6_addr in6addr_linklocal_allnodes; extern const struct in6_addr in6addr_linklocal_allrouters; struct route_in6 { struct rtentry *ro_rt; u_long ro_tableid; struct sockaddr_in6 ro_dst; }; struct ipv6_mreq { struct in6_addr ipv6mr_multiaddr; unsigned int ipv6mr_interface; }; struct in6_pktinfo { struct in6_addr ipi6_addr; unsigned int ipi6_ifindex; }; struct ip6_mtuinfo { struct sockaddr_in6 ip6m_addr; u_int32_t ip6m_mtu; }; extern const u_char inet6ctlerrmap[]; extern struct in6_addr zeroin6_addr; struct mbuf; struct ifnet; struct cmsghdr; void ipv6_input(struct ifnet *, struct mbuf *); int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t); void in6_proto_cksum_out(struct mbuf *, struct ifnet *); int in6_localaddr(struct in6_addr *); int in6_addrscope(struct in6_addr *); struct in6_ifaddr *in6_ifawithscope(struct ifnet *, struct in6_addr *, u_int); int in6_mask2len(struct in6_addr *, u_char *); int in6_nam2sin6(const struct mbuf *, struct sockaddr_in6 **); struct inpcb; int in6_embedscope(struct in6_addr *, const struct sockaddr_in6 *, struct inpcb *); void in6_recoverscope(struct sockaddr_in6 *, const struct in6_addr *); void in6_clearscope(struct in6_addr *); struct sockaddr; struct sockaddr_in6; struct ifaddr; struct in6_ifaddr; static inline struct sockaddr_in6 * satosin6(struct sockaddr *sa) { return ((struct sockaddr_in6 *)(sa)); } static inline struct sockaddr * sin6tosa(struct sockaddr_in6 *sin6) { return ((struct sockaddr *)(sin6)); } static inline struct in6_ifaddr * ifatoia6(struct ifaddr *ifa) { return ((struct in6_ifaddr *)(ifa)); } struct cmsghdr; extern int inet6_opt_init(void *, socklen_t); extern int inet6_opt_append(void *, socklen_t, int, u_int8_t, socklen_t, u_int8_t, void **); extern int inet6_opt_finish(void *, socklen_t, int); extern int inet6_opt_set_val(void *, int, void *, socklen_t); extern int inet6_opt_next(void *, socklen_t, int, u_int8_t *, socklen_t *, void **); extern int inet6_opt_find(void *, socklen_t, int, u_int8_t, socklen_t *, void **); extern int inet6_opt_get_val(void *, int, void *, socklen_t); extern socklen_t inet6_rth_space(int, int); extern void *inet6_rth_init(void *, socklen_t, int, int); extern int inet6_rth_add(void *, const struct in6_addr *); extern int inet6_rth_reverse(const void *, void *); extern int inet6_rth_segments(const void *); extern struct in6_addr *inet6_rth_getaddr(const void *, int); extern const int inetctlerrmap[]; extern struct in_addr zeroin_addr; struct mbuf; struct sockaddr; struct sockaddr_in; struct ifaddr; struct in_ifaddr; void ipv4_input(struct ifnet *, struct mbuf *); int in_broadcast(struct in_addr, u_int); int in_canforward(struct in_addr); int in_cksum(struct mbuf *, int); int in4_cksum(struct mbuf *, u_int8_t, int, int); void in_proto_cksum_out(struct mbuf *, struct ifnet *); void in_ifdetach(struct ifnet *); int in_mask2len(struct in_addr *); void in_len2mask(struct in_addr *, int); int in_nam2sin(const struct mbuf *, struct sockaddr_in **); char *inet_ntoa(struct in_addr); int inet_nat64(int, const void *, void *, const void *, u_int8_t); int inet_nat46(int, const void *, void *, const void *, u_int8_t); const char *inet_ntop(int, const void *, char *, socklen_t); const char *sockaddr_ntop(struct sockaddr *, char *, size_t); static inline struct sockaddr_in * satosin(struct sockaddr *sa) { return ((struct sockaddr_in *)(sa)); } static inline struct sockaddr * sintosa(struct sockaddr_in *sin) { return ((struct sockaddr *)(sin)); } static inline struct in_ifaddr * ifatoia(struct ifaddr *ifa) { return ((struct in_ifaddr *)(ifa)); } struct radix_node { struct radix_mask *rn_mklist; struct radix_node *rn_p; short rn_b; char rn_bmask; u_char rn_flags; union { struct { caddr_t rn_Key; caddr_t rn_Mask; struct radix_node *rn_Dupedkey; } rn_leaf; struct { int rn_Off; struct radix_node *rn_L; struct radix_node *rn_R; } rn_node; } rn_u; }; struct radix_mask { short rm_b; char rm_unused; u_char rm_flags; struct radix_mask *rm_mklist; union { caddr_t rmu_mask; struct radix_node *rmu_leaf; } rm_rmu; int rm_refs; }; struct radix_node_head { struct radix_node *rnh_treetop; int rnh_addrsize; int rnh_pktsize; struct radix_node rnh_nodes[3]; u_int rnh_rtableid; }; void rn_init(unsigned int); int rn_inithead(void **, int); int rn_walktree(struct radix_node_head *, int (*)(struct radix_node *, void *, u_int), void *); struct radix_node *rn_addroute(void *, void *, struct radix_node_head *, struct radix_node [2], u_int8_t); struct radix_node *rn_delete(void *, void *, struct radix_node_head *, struct radix_node *); struct radix_node *rn_lookup(void *, void *, struct radix_node_head *); struct radix_node *rn_match(void *, struct radix_node_head *); struct rt_kmetrics { u_int64_t rmx_pksent; int64_t rmx_expire; u_int rmx_locks; u_int rmx_mtu; }; struct rt_metrics { u_int64_t rmx_pksent; int64_t rmx_expire; u_int rmx_locks; u_int rmx_mtu; u_int rmx_refcnt; u_int rmx_hopcount; u_int rmx_recvpipe; u_int rmx_sendpipe; u_int rmx_ssthresh; u_int rmx_rtt; u_int rmx_rttvar; u_int rmx_pad; }; struct art_root { struct srp ar_root; struct rwlock ar_lock; uint8_t ar_bits[32]; uint8_t ar_nlvl; uint8_t ar_alen; uint8_t ar_off; unsigned int ar_rtableid; }; struct rtentry; struct art_node { union { struct srpl an__rtlist; struct art_node *an__gc; } an_pointer; uint8_t an_plen; }; void art_init(void); struct art_root *art_alloc(unsigned int, unsigned int, unsigned int); struct art_node *art_insert(struct art_root *, struct art_node *, void *, int); struct art_node *art_delete(struct art_root *, struct art_node *, void *, int); struct art_node *art_match(struct art_root *, void *, struct srp_ref *); struct art_node *art_lookup(struct art_root *, void *, int, struct srp_ref *); int art_walk(struct art_root *, int (*)(struct art_node *, void *), void *); struct art_node *art_get(void *, uint8_t); void art_put(struct art_node *); int rtable_satoplen(sa_family_t, struct sockaddr *); void rtable_init(void); int rtable_exists(unsigned int); int rtable_add(unsigned int); unsigned int rtable_l2(unsigned int); unsigned int rtable_loindex(unsigned int); void rtable_l2set(unsigned int, unsigned int, unsigned int); struct rtentry *rtable_lookup(unsigned int, struct sockaddr *, struct sockaddr *, struct sockaddr *, uint8_t); struct rtentry *rtable_match(unsigned int, struct sockaddr *, uint32_t *); struct rtentry *rtable_iterate(struct rtentry *); int rtable_insert(unsigned int, struct sockaddr *, struct sockaddr *, struct sockaddr *, uint8_t, struct rtentry *); int rtable_delete(unsigned int, struct sockaddr *, struct sockaddr *, struct rtentry *); int rtable_walk(unsigned int, sa_family_t, int (*)(struct rtentry *, void *, unsigned int), void *); int rtable_mpath_capable(unsigned int, sa_family_t); struct rtentry *rtable_mpath_match(unsigned int, struct rtentry *, struct sockaddr *, uint8_t); int rtable_mpath_reprio(unsigned int, struct sockaddr *, struct sockaddr *, uint8_t, struct rtentry *); struct rtentry { struct sockaddr *rt_dest; struct { struct srp se_next; } rt_next; struct sockaddr *rt_gateway; struct ifaddr *rt_ifa; caddr_t rt_llinfo; union { struct rtentry *_nh; unsigned int _ref; } RT_gw; struct rtentry *rt_parent; struct { struct rttimer *lh_first; } rt_timer; struct rt_kmetrics rt_rmx; unsigned int rt_ifidx; unsigned int rt_flags; int rt_refcnt; int rt_plen; uint16_t rt_labelid; uint8_t rt_priority; }; struct rtstat { u_int32_t rts_badredirect; u_int32_t rts_dynamic; u_int32_t rts_newgateway; u_int32_t rts_unreach; u_int32_t rts_wildcard; }; struct rt_tableinfo { u_short rti_tableid; u_short rti_domainid; }; struct rt_msghdr { u_short rtm_msglen; u_char rtm_version; u_char rtm_type; u_short rtm_hdrlen; u_short rtm_index; u_short rtm_tableid; u_char rtm_priority; u_char rtm_mpls; int rtm_addrs; int rtm_flags; int rtm_fmask; pid_t rtm_pid; int rtm_seq; int rtm_errno; u_int rtm_inits; struct rt_metrics rtm_rmx; }; struct sockaddr_rtlabel { u_int8_t sr_len; sa_family_t sr_family; char sr_label[32]; }; struct sockaddr_rtdns { u_int8_t sr_len; sa_family_t sr_family; char sr_dns[128]; }; struct sockaddr_rtstatic { u_int8_t sr_len; sa_family_t sr_family; char sr_static[128]; }; struct sockaddr_rtsearch { u_int8_t sr_len; sa_family_t sr_family; char sr_search[128]; }; struct route { struct rtentry *ro_rt; u_long ro_tableid; struct sockaddr ro_dst; }; struct rt_addrinfo { int rti_addrs; struct sockaddr *rti_info[15]; int rti_flags; struct ifaddr *rti_ifa; struct rt_msghdr *rti_rtm; u_char rti_mpls; }; enum rtstat_counters { rts_badredirect, rts_dynamic, rts_newgateway, rts_unreach, rts_wildcard, rts_ncounters }; static inline void rtstat_inc(enum rtstat_counters c) { extern struct cpumem *rtcounters; counters_inc(rtcounters, c); } struct rttimer { struct { struct rttimer *tqe_next; struct rttimer **tqe_prev; } rtt_next; struct { struct rttimer *le_next; struct rttimer **le_prev; } rtt_link; struct rttimer_queue *rtt_queue; struct rtentry *rtt_rt; void (*rtt_func)(struct rtentry *, struct rttimer *); time_t rtt_time; u_int rtt_tableid; }; struct rttimer_queue { long rtq_timeout; unsigned long rtq_count; struct { struct rttimer *tqh_first; struct rttimer **tqh_last; } rtq_head; struct { struct rttimer_queue *le_next; struct rttimer_queue **le_prev; } rtq_link; }; const char *rtlabel_id2name(u_int16_t); u_int16_t rtlabel_name2id(char *); struct sockaddr *rtlabel_id2sa(u_int16_t, struct sockaddr_rtlabel *); void rtlabel_unref(u_int16_t); extern struct rtstat rtstat; struct mbuf; struct socket; struct ifnet; struct sockaddr_in6; struct bfd_config; void route_init(void); void rtm_ifchg(struct ifnet *); void rtm_ifannounce(struct ifnet *, int); void rtm_bfd(struct bfd_config *); void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *); struct sockaddr *rt_plen2mask(struct rtentry *, struct sockaddr_in6 *); void rtm_send(struct rtentry *, int, int, unsigned int); void rtm_addr(struct rtentry *, int, struct ifaddr *); void rtm_miss(int, struct rt_addrinfo *, int, uint8_t, u_int, int, u_int); int rt_setgate(struct rtentry *, struct sockaddr *, u_int); struct rtentry *rt_getll(struct rtentry *); int rt_timer_add(struct rtentry *, void(*)(struct rtentry *, struct rttimer *), struct rttimer_queue *, u_int); void rt_timer_remove_all(struct rtentry *); struct rttimer_queue *rt_timer_queue_create(u_int); void rt_timer_queue_change(struct rttimer_queue *, long); void rt_timer_queue_destroy(struct rttimer_queue *); unsigned long rt_timer_queue_count(struct rttimer_queue *); void rt_timer_timer(void *); int rtisvalid(struct rtentry *); int rt_hash(struct rtentry *, struct sockaddr *, uint32_t *); struct rtentry *rtalloc_mpath(struct sockaddr *, uint32_t *, u_int); struct rtentry *rtalloc(struct sockaddr *, int, unsigned int); void rtref(struct rtentry *); void rtfree(struct rtentry *); int rt_ifa_add(struct ifaddr *, int, struct sockaddr *); int rt_ifa_del(struct ifaddr *, int, struct sockaddr *); void rt_ifa_purge(struct ifaddr *); int rt_ifa_addlocal(struct ifaddr *); int rt_ifa_dellocal(struct ifaddr *); void rtredirect(struct sockaddr *, struct sockaddr *, struct sockaddr *, struct rtentry **, unsigned int); int rtrequest(int, struct rt_addrinfo *, u_int8_t, struct rtentry **, u_int); int rtrequest_delete(struct rt_addrinfo *, u_int8_t, struct ifnet *, struct rtentry **, u_int); void rt_if_track(struct ifnet *); int rt_if_linkstate_change(struct rtentry *, void *, u_int); int rtdeletemsg(struct rtentry *, struct ifnet *, u_int); struct ip; struct ip6_hdr; struct mbuf_list; typedef struct refcnt pf_refcnt_t; enum { PF_INOUT, PF_IN, PF_OUT, PF_FWD }; enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT, PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER, PF_MATCH, PF_DIVERT, PF_RT, PF_AFRT }; enum { PF_TRANS_RULESET, PF_TRANS_ALTQ, PF_TRANS_TABLE }; enum { PF_OP_NONE, PF_OP_IRG, PF_OP_EQ, PF_OP_NE, PF_OP_LT, PF_OP_LE, PF_OP_GT, PF_OP_GE, PF_OP_XRG, PF_OP_RRG }; enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL, PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER, PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET }; enum { PF_GET_NONE, PF_GET_CLR_CNTR }; enum { PF_SK_WIRE, PF_SK_STACK, PF_SK_BOTH }; enum { PF_PEER_SRC, PF_PEER_DST, PF_PEER_BOTH }; enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED, PFTM_TCP_CLOSING, PFTM_TCP_FIN_WAIT, PFTM_TCP_CLOSED, PFTM_UDP_FIRST_PACKET, PFTM_UDP_SINGLE, PFTM_UDP_MULTIPLE, PFTM_ICMP_FIRST_PACKET, PFTM_ICMP_ERROR_REPLY, PFTM_OTHER_FIRST_PACKET, PFTM_OTHER_SINGLE, PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL, PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE, PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNLINKED }; enum { PF_NOPFROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO }; enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, PF_LIMIT_TABLES, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX }; enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM, PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN, PF_POOL_LEASTSTATES }; enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL, PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED, PF_ADDR_RANGE, PF_ADDR_NONE }; struct pf_addr { union { struct in_addr v4; struct in6_addr v6; u_int8_t addr8[16]; u_int16_t addr16[8]; u_int32_t addr32[4]; } pfa; }; struct pf_addr_wrap { union { struct { struct pf_addr addr; struct pf_addr mask; } a; char ifname[16]; char tblname[32]; char rtlabelname[32]; u_int32_t rtlabel; } v; union { struct pfi_dynaddr *dyn; struct pfr_ktable *tbl; int dyncnt; int tblcnt; } p; u_int8_t type; u_int8_t iflags; }; struct pfi_dynaddr { struct { struct pfi_dynaddr *tqe_next; struct pfi_dynaddr **tqe_prev; } entry; struct pf_addr pfid_addr4; struct pf_addr pfid_mask4; struct pf_addr pfid_addr6; struct pf_addr pfid_mask6; struct pfr_ktable *pfid_kt; struct pfi_kif *pfid_kif; void *pfid_hook_cookie; int pfid_net; int pfid_acnt4; int pfid_acnt6; sa_family_t pfid_af; u_int8_t pfid_iflags; }; struct pf_rule_uid { uid_t uid[2]; u_int8_t op; }; struct pf_rule_gid { uid_t gid[2]; u_int8_t op; }; struct pf_rule_addr { struct pf_addr_wrap addr; u_int16_t port[2]; u_int8_t neg; u_int8_t port_op; u_int16_t weight; }; struct pf_threshold { u_int32_t limit; u_int32_t seconds; u_int32_t count; u_int32_t last; }; struct pf_poolhashkey { union { u_int8_t key8[16]; u_int16_t key16[8]; u_int32_t key32[4]; } pfk; }; struct pf_pool { struct pf_addr_wrap addr; struct pf_poolhashkey key; struct pf_addr counter; char ifname[16]; struct pfi_kif *kif; int tblidx; u_int64_t states; int curweight; u_int16_t weight; u_int16_t proxy_port[2]; u_int8_t port_op; u_int8_t opts; }; typedef u_int32_t pf_osfp_t; struct pf_osfp_entry { struct { struct pf_osfp_entry *sle_next; } fp_entry; pf_osfp_t fp_os; int fp_enflags; u_char fp_class_nm[32]; u_char fp_version_nm[32]; u_char fp_subtype_nm[32]; }; typedef u_int64_t pf_tcpopts_t; struct pf_os_fingerprint { struct pf_osfp_enlist { struct pf_osfp_entry *slh_first; } fp_oses; pf_tcpopts_t fp_tcpopts; u_int16_t fp_wsize; u_int16_t fp_psize; u_int16_t fp_mss; u_int16_t fp_flags; u_int8_t fp_optcnt; u_int8_t fp_wscale; u_int8_t fp_ttl; struct { struct pf_os_fingerprint *sle_next; } fp_next; }; struct pf_osfp_ioctl { struct pf_osfp_entry fp_os; pf_tcpopts_t fp_tcpopts; u_int16_t fp_wsize; u_int16_t fp_psize; u_int16_t fp_mss; u_int16_t fp_flags; u_int8_t fp_optcnt; u_int8_t fp_wscale; u_int8_t fp_ttl; int fp_getnum; }; struct pf_rule_actions { int rtableid; u_int16_t qid; u_int16_t pqid; u_int16_t max_mss; u_int16_t flags; u_int8_t log; u_int8_t set_tos; u_int8_t min_ttl; u_int8_t set_prio[2]; u_int8_t pad[3]; }; union pf_rule_ptr { struct pf_rule *ptr; u_int32_t nr; }; struct pf_rule { struct pf_rule_addr src; struct pf_rule_addr dst; union pf_rule_ptr skip[9]; char label[64]; char ifname[16]; char rcv_ifname[16]; char qname[64]; char pqname[64]; char tagname[64]; char match_tagname[64]; char overload_tblname[32]; struct { struct pf_rule *tqe_next; struct pf_rule **tqe_prev; } entries; struct pf_pool nat; struct pf_pool rdr; struct pf_pool route; struct pf_threshold pktrate; u_int64_t evaluations; u_int64_t packets[2]; u_int64_t bytes[2]; struct pfi_kif *kif; struct pfi_kif *rcv_kif; struct pf_anchor *anchor; struct pfr_ktable *overload_tbl; pf_osfp_t os_fingerprint; int rtableid; int onrdomain; u_int32_t timeout[PFTM_MAX]; u_int32_t states_cur; u_int32_t states_tot; u_int32_t max_states; u_int32_t src_nodes; u_int32_t max_src_nodes; u_int32_t max_src_states; u_int32_t max_src_conn; struct { u_int32_t limit; u_int32_t seconds; } max_src_conn_rate; u_int32_t qid; u_int32_t pqid; u_int32_t rt_listid; u_int32_t nr; u_int32_t prob; uid_t cuid; pid_t cpid; u_int16_t return_icmp; u_int16_t return_icmp6; u_int16_t max_mss; u_int16_t tag; u_int16_t match_tag; u_int16_t scrub_flags; struct pf_rule_uid uid; struct pf_rule_gid gid; u_int32_t rule_flag; u_int8_t action; u_int8_t direction; u_int8_t log; u_int8_t logif; u_int8_t quick; u_int8_t ifnot; u_int8_t match_tag_not; u_int8_t keep_state; sa_family_t af; u_int8_t proto; u_int8_t type; u_int8_t code; u_int8_t flags; u_int8_t flagset; u_int8_t min_ttl; u_int8_t allow_opts; u_int8_t rt; u_int8_t return_ttl; u_int8_t tos; u_int8_t set_tos; u_int8_t anchor_relative; u_int8_t anchor_wildcard; u_int8_t flush; u_int8_t prio; u_int8_t set_prio[2]; sa_family_t naf; u_int8_t rcvifnot; u_int8_t pad[2]; struct { struct pf_addr addr; u_int16_t port; u_int8_t type; } divert; struct { struct pf_rule *sle_next; } gcle; struct pf_ruleset *ruleset; time_t exptime; }; struct pf_rule_item { struct { struct pf_rule_item *sle_next; } entry; struct pf_rule *r; }; struct pf_rule_slist { struct pf_rule_item *slh_first; }; enum pf_sn_types { PF_SN_NONE, PF_SN_NAT, PF_SN_RDR, PF_SN_ROUTE, PF_SN_MAX }; struct pf_src_node { struct { struct pf_src_node *rbe_left; struct pf_src_node *rbe_right; struct pf_src_node *rbe_parent; int rbe_color; } entry; struct pf_addr addr; struct pf_addr raddr; union pf_rule_ptr rule; struct pfi_kif *kif; u_int64_t bytes[2]; u_int64_t packets[2]; u_int32_t states; u_int32_t conn; struct pf_threshold conn_rate; int32_t creation; int32_t expire; sa_family_t af; sa_family_t naf; u_int8_t type; }; struct pf_sn_item { struct { struct pf_sn_item *sle_next; } next; struct pf_src_node *sn; }; struct pf_sn_head { struct pf_sn_item *slh_first; }; struct pf_state_scrub { struct timeval pfss_last; u_int32_t pfss_tsecr; u_int32_t pfss_tsval; u_int32_t pfss_tsval0; u_int16_t pfss_flags; u_int8_t pfss_ttl; u_int8_t pad; u_int32_t pfss_ts_mod; }; struct pf_state_host { struct pf_addr addr; u_int16_t port; u_int16_t pad; }; struct pf_state_peer { struct pf_state_scrub *scrub; u_int32_t seqlo; u_int32_t seqhi; u_int32_t seqdiff; u_int16_t max_win; u_int16_t mss; u_int8_t state; u_int8_t wscale; u_int8_t tcp_est; u_int8_t pad[1]; }; struct pf_state_queue { struct pf_state *tqh_first; struct pf_state **tqh_last; }; struct pf_state_key_cmp { struct pf_addr addr[2]; u_int16_t port[2]; u_int16_t rdomain; sa_family_t af; u_int8_t proto; }; struct pf_state_item { struct { struct pf_state_item *tqe_next; struct pf_state_item **tqe_prev; } entry; struct pf_state *s; }; struct pf_statelisthead { struct pf_state_item *tqh_first; struct pf_state_item **tqh_last; }; struct pf_state_key { struct pf_addr addr[2]; u_int16_t port[2]; u_int16_t rdomain; sa_family_t af; u_int8_t proto; struct { struct pf_state_key *rbe_left; struct pf_state_key *rbe_right; struct pf_state_key *rbe_parent; int rbe_color; } entry; struct pf_statelisthead states; struct pf_state_key *reverse; struct inpcb *inp; pf_refcnt_t refcnt; u_int8_t removed; }; struct pf_state_cmp { u_int64_t id; u_int32_t creatorid; u_int8_t direction; u_int8_t pad[3]; }; struct pf_state { u_int64_t id; u_int32_t creatorid; u_int8_t direction; u_int8_t pad[3]; struct { struct pf_state *tqe_next; struct pf_state **tqe_prev; } sync_list; struct { struct pf_state *tqe_next; struct pf_state **tqe_prev; } entry_list; struct { struct pf_state *rbe_left; struct pf_state *rbe_right; struct pf_state *rbe_parent; int rbe_color; } entry_id; struct pf_state_peer src; struct pf_state_peer dst; struct pf_rule_slist match_rules; union pf_rule_ptr rule; union pf_rule_ptr anchor; union pf_rule_ptr natrule; struct pf_addr rt_addr; struct pf_sn_head src_nodes; struct pf_state_key *key[2]; struct pfi_kif *kif; struct pfi_kif *rt_kif; u_int64_t packets[2]; u_int64_t bytes[2]; int32_t creation; int32_t expire; int32_t pfsync_time; u_int16_t qid; u_int16_t pqid; u_int16_t tag; u_int16_t state_flags; u_int8_t log; u_int8_t timeout; u_int8_t sync_state; u_int8_t sync_updates; int rtableid[2]; u_int8_t min_ttl; u_int8_t set_tos; u_int8_t set_prio[2]; u_int16_t max_mss; u_int16_t if_index_in; u_int16_t if_index_out; u_int8_t pad2[2]; }; struct pfsync_state_scrub { u_int16_t pfss_flags; u_int8_t pfss_ttl; u_int8_t scrub_flag; u_int32_t pfss_ts_mod; } __attribute__((__packed__)); struct pfsync_state_peer { struct pfsync_state_scrub scrub; u_int32_t seqlo; u_int32_t seqhi; u_int32_t seqdiff; u_int16_t max_win; u_int16_t mss; u_int8_t state; u_int8_t wscale; u_int8_t pad[6]; } __attribute__((__packed__)); struct pfsync_state_key { struct pf_addr addr[2]; u_int16_t port[2]; u_int16_t rdomain; sa_family_t af; u_int8_t pad; }; struct pfsync_state { u_int64_t id; char ifname[16]; struct pfsync_state_key key[2]; struct pfsync_state_peer src; struct pfsync_state_peer dst; struct pf_addr rt_addr; u_int32_t rule; u_int32_t anchor; u_int32_t nat_rule; u_int32_t creation; u_int32_t expire; u_int32_t packets[2][2]; u_int32_t bytes[2][2]; u_int32_t creatorid; int32_t rtableid[2]; u_int16_t max_mss; sa_family_t af; u_int8_t proto; u_int8_t direction; u_int8_t log; u_int8_t pad0; u_int8_t timeout; u_int8_t sync_flags; u_int8_t updates; u_int8_t min_ttl; u_int8_t set_tos; u_int16_t state_flags; u_int8_t set_prio[2]; } __attribute__((__packed__)); struct pf_rulequeue { struct pf_rule *tqh_first; struct pf_rule **tqh_last; }; struct pf_anchor; struct pf_ruleset { struct { struct pf_rulequeue queues[2]; struct { struct pf_rulequeue *ptr; struct pf_rule **ptr_array; u_int32_t rcount; u_int32_t ticket; int open; } active, inactive; } rules; struct pf_anchor *anchor; u_int32_t tticket; int tables; int topen; }; struct pf_anchor_global { struct pf_anchor *rbh_root; }; struct pf_anchor_node { struct pf_anchor *rbh_root; }; struct pf_anchor { struct { struct pf_anchor *rbe_left; struct pf_anchor *rbe_right; struct pf_anchor *rbe_parent; int rbe_color; } entry_global; struct { struct pf_anchor *rbe_left; struct pf_anchor *rbe_right; struct pf_anchor *rbe_parent; int rbe_color; } entry_node; struct pf_anchor *parent; struct pf_anchor_node children; char name[64]; char path[1024]; struct pf_ruleset ruleset; int refcnt; int match; }; void pf_anchor_global_RB_INSERT_COLOR(struct pf_anchor_global *, struct pf_anchor *); void pf_anchor_global_RB_REMOVE_COLOR(struct pf_anchor_global *, struct pf_anchor *, struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_REMOVE(struct pf_anchor_global *, struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_INSERT(struct pf_anchor_global *, struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_FIND(struct pf_anchor_global *, struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_NFIND(struct pf_anchor_global *, struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_NEXT(struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_PREV(struct pf_anchor *); struct pf_anchor *pf_anchor_global_RB_MINMAX(struct pf_anchor_global *, int); void pf_anchor_node_RB_INSERT_COLOR(struct pf_anchor_node *, struct pf_anchor *); void pf_anchor_node_RB_REMOVE_COLOR(struct pf_anchor_node *, struct pf_anchor *, struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_REMOVE(struct pf_anchor_node *, struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_INSERT(struct pf_anchor_node *, struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_FIND(struct pf_anchor_node *, struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_NFIND(struct pf_anchor_node *, struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_NEXT(struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_PREV(struct pf_anchor *); struct pf_anchor *pf_anchor_node_RB_MINMAX(struct pf_anchor_node *, int); struct pfr_table { char pfrt_anchor[1024]; char pfrt_name[32]; u_int32_t pfrt_flags; u_int8_t pfrt_fback; }; enum { PFR_FB_NONE, PFR_FB_MATCH, PFR_FB_ADDED, PFR_FB_DELETED, PFR_FB_CHANGED, PFR_FB_CLEARED, PFR_FB_DUPLICATE, PFR_FB_NOTMATCH, PFR_FB_CONFLICT, PFR_FB_NOCOUNT, PFR_FB_MAX }; struct pfr_addr { union { struct in_addr _pfra_ip4addr; struct in6_addr _pfra_ip6addr; } pfra_u; char pfra_ifname[16]; u_int32_t pfra_states; u_int16_t pfra_weight; u_int8_t pfra_af; u_int8_t pfra_net; u_int8_t pfra_not; u_int8_t pfra_fback; u_int8_t pfra_type; u_int8_t pad[7]; }; enum { PFR_DIR_IN, PFR_DIR_OUT, PFR_DIR_MAX }; enum { PFR_OP_BLOCK, PFR_OP_MATCH, PFR_OP_PASS, PFR_OP_ADDR_MAX, PFR_OP_TABLE_MAX }; struct pfr_astats { struct pfr_addr pfras_a; u_int64_t pfras_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX]; u_int64_t pfras_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX]; time_t pfras_tzero; }; enum { PFR_REFCNT_RULE, PFR_REFCNT_ANCHOR, PFR_REFCNT_MAX }; struct pfr_tstats { struct pfr_table pfrts_t; u_int64_t pfrts_packets[PFR_DIR_MAX][PFR_OP_TABLE_MAX]; u_int64_t pfrts_bytes[PFR_DIR_MAX][PFR_OP_TABLE_MAX]; u_int64_t pfrts_match; u_int64_t pfrts_nomatch; time_t pfrts_tzero; int pfrts_cnt; int pfrts_refcnt[PFR_REFCNT_MAX]; }; struct pfr_kcounters { u_int64_t pfrkc_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX]; u_int64_t pfrkc_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX]; u_int64_t states; }; union pfsockaddr_union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; }; struct pfr_kentryworkq { struct pfr_kentry *slh_first; }; struct _pfr_kentry { struct radix_node _pfrke_node[2]; union pfsockaddr_union _pfrke_sa; struct { struct pfr_kentry *sle_next; } _pfrke_workq; struct pfr_kcounters *_pfrke_counters; time_t _pfrke_tzero; u_int8_t _pfrke_af; u_int8_t _pfrke_net; u_int8_t _pfrke_flags; u_int8_t _pfrke_type; }; enum { PFRKE_PLAIN, PFRKE_ROUTE, PFRKE_COST, PFRKE_MAX }; struct pfr_kentry { union { struct _pfr_kentry _ke; } u; }; struct pfr_kentry_route { union { struct _pfr_kentry _ke; } u; struct pfi_kif *kif; }; struct pfr_kentry_cost { union { struct _pfr_kentry _ke; } u; struct pfi_kif *kif; u_int16_t weight; }; struct pfr_kentry_all { union { struct _pfr_kentry _ke; struct pfr_kentry_route kr; struct pfr_kentry_cost kc; } u; }; struct pfr_ktableworkq { struct pfr_ktable *slh_first; }; struct pfr_ktablehead { struct pfr_ktable *rbh_root; }; struct pfr_ktable { struct pfr_tstats pfrkt_ts; struct { struct pfr_ktable *rbe_left; struct pfr_ktable *rbe_right; struct pfr_ktable *rbe_parent; int rbe_color; } pfrkt_tree; struct { struct pfr_ktable *sle_next; } pfrkt_workq; struct radix_node_head *pfrkt_ip4; struct radix_node_head *pfrkt_ip6; struct pfr_ktable *pfrkt_shadow; struct pfr_ktable *pfrkt_root; struct pf_ruleset *pfrkt_rs; long pfrkt_larg; int pfrkt_nflags; u_int64_t pfrkt_refcntcost; u_int16_t pfrkt_gcdweight; u_int16_t pfrkt_maxweight; }; struct pf_state_tree { struct pf_state_key *rbh_root; }; void pf_state_tree_RB_INSERT_COLOR(struct pf_state_tree *, struct pf_state_key *); void pf_state_tree_RB_REMOVE_COLOR(struct pf_state_tree *, struct pf_state_key *, struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_REMOVE(struct pf_state_tree *, struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_INSERT(struct pf_state_tree *, struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_FIND(struct pf_state_tree *, struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_NFIND(struct pf_state_tree *, struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_NEXT(struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_PREV(struct pf_state_key *); struct pf_state_key *pf_state_tree_RB_MINMAX(struct pf_state_tree *, int); struct pf_state_tree_ext_gwy { struct pf_state_key *rbh_root; }; void pf_state_tree_ext_gwy_RB_INSERT_COLOR(struct pf_state_tree_ext_gwy *, struct pf_state_key *); void pf_state_tree_ext_gwy_RB_REMOVE_COLOR(struct pf_state_tree_ext_gwy *, struct pf_state_key *, struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_REMOVE(struct pf_state_tree_ext_gwy *, struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_INSERT(struct pf_state_tree_ext_gwy *, struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_FIND(struct pf_state_tree_ext_gwy *, struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_NFIND(struct pf_state_tree_ext_gwy *, struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_NEXT(struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_PREV(struct pf_state_key *); struct pf_state_key *pf_state_tree_ext_gwy_RB_MINMAX(struct pf_state_tree_ext_gwy *, int); struct pfi_ifhead { struct pfi_kif *rbh_root; }; extern struct pf_state_tree pf_statetbl; struct pfi_kif_cmp { char pfik_name[16]; }; struct ifnet; struct ifg_group; struct pfi_kif { char pfik_name[16]; struct { struct pfi_kif *rbe_left; struct pfi_kif *rbe_right; struct pfi_kif *rbe_parent; int rbe_color; } pfik_tree; u_int64_t pfik_packets[2][2][2]; u_int64_t pfik_bytes[2][2][2]; time_t pfik_tzero; int pfik_flags; int pfik_flags_new; void *pfik_ah_cookie; struct ifnet *pfik_ifp; struct ifg_group *pfik_group; int pfik_states; int pfik_rules; int pfik_routes; struct { struct pfi_dynaddr *tqh_first; struct pfi_dynaddr **tqh_last; } pfik_dynaddrs; }; enum pfi_kif_refs { PFI_KIF_REF_NONE, PFI_KIF_REF_STATE, PFI_KIF_REF_RULE, PFI_KIF_REF_ROUTE }; struct pf_status { u_int64_t counters[17]; u_int64_t lcounters[7]; u_int64_t fcounters[3]; u_int64_t scounters[3]; u_int64_t pcounters[2][2][3]; u_int64_t bcounters[2][2]; u_int64_t stateid; time_t since; u_int32_t running; u_int32_t states; u_int32_t states_halfopen; u_int32_t src_nodes; u_int32_t debug; u_int32_t hostid; u_int32_t reass; char ifname[16]; u_int8_t pf_chksum[16]; }; struct pf_queue_bwspec { u_int absolute; u_int percent; }; struct pf_queue_scspec { struct pf_queue_bwspec m1; struct pf_queue_bwspec m2; u_int d; }; struct pf_queue_fqspec { u_int flows; u_int quantum; u_int target; u_int interval; }; struct pf_queuespec { struct { struct pf_queuespec *tqe_next; struct pf_queuespec **tqe_prev; } entries; char qname[64]; char parent[64]; char ifname[16]; struct pf_queue_scspec realtime; struct pf_queue_scspec linkshare; struct pf_queue_scspec upperlimit; struct pf_queue_fqspec flowqueue; struct pfi_kif *kif; u_int flags; u_int qlimit; u_int32_t qid; u_int32_t parent_qid; }; struct priq_opts { int flags; }; struct hfsc_opts { u_int rtsc_m1; u_int rtsc_d; u_int rtsc_m2; u_int lssc_m1; u_int lssc_d; u_int lssc_m2; u_int ulsc_m1; u_int ulsc_d; u_int ulsc_m2; int flags; }; struct pfq_ops { void * (*pfq_alloc)(struct ifnet *); int (*pfq_addqueue)(void *, struct pf_queuespec *); void (*pfq_free)(void *); int (*pfq_qstats)(struct pf_queuespec *, void *, int *); unsigned int (*pfq_qlength)(void *); struct mbuf * (*pfq_enqueue)(void *, struct mbuf *); struct mbuf * (*pfq_deq_begin)(void *, void **, struct mbuf_list *); void (*pfq_deq_commit)(void *, struct mbuf *, void *); void (*pfq_purge)(void *, struct mbuf_list *); }; struct pf_tagname { struct { struct pf_tagname *tqe_next; struct pf_tagname **tqe_prev; } entries; char name[64]; u_int16_t tag; int ref; }; struct pf_divert { struct pf_addr addr; u_int16_t port; u_int16_t rdomain; u_int8_t type; }; enum pf_divert_types { PF_DIVERT_NONE, PF_DIVERT_TO, PF_DIVERT_REPLY, PF_DIVERT_PACKET }; struct pfioc_rule { u_int32_t action; u_int32_t ticket; u_int32_t nr; char anchor[1024]; char anchor_call[1024]; struct pf_rule rule; }; struct pfioc_natlook { struct pf_addr saddr; struct pf_addr daddr; struct pf_addr rsaddr; struct pf_addr rdaddr; u_int16_t rdomain; u_int16_t rrdomain; u_int16_t sport; u_int16_t dport; u_int16_t rsport; u_int16_t rdport; sa_family_t af; u_int8_t proto; u_int8_t direction; }; struct pfioc_state { struct pfsync_state state; }; struct pfioc_src_node_kill { sa_family_t psnk_af; struct pf_rule_addr psnk_src; struct pf_rule_addr psnk_dst; u_int psnk_killed; }; struct pfioc_state_kill { struct pf_state_cmp psk_pfcmp; sa_family_t psk_af; int psk_proto; struct pf_rule_addr psk_src; struct pf_rule_addr psk_dst; char psk_ifname[16]; char psk_label[64]; u_int psk_killed; u_int16_t psk_rdomain; }; struct pfioc_states { int ps_len; union { caddr_t psu_buf; struct pfsync_state *psu_states; } ps_u; }; struct pfioc_src_nodes { int psn_len; union { caddr_t psu_buf; struct pf_src_node *psu_src_nodes; } psn_u; }; struct pfioc_tm { int timeout; int seconds; }; struct pfioc_limit { int index; unsigned limit; }; struct pfioc_ruleset { u_int32_t nr; char path[1024]; char name[64]; }; struct pfioc_trans { int size; int esize; struct pfioc_trans_e { int type; char anchor[1024]; u_int32_t ticket; } *array; }; struct pfioc_queue { u_int32_t ticket; u_int nr; struct pf_queuespec queue; }; struct pfioc_qstats { u_int32_t ticket; u_int32_t nr; struct pf_queuespec queue; void *buf; int nbytes; }; struct pfioc_table { struct pfr_table pfrio_table; void *pfrio_buffer; int pfrio_esize; int pfrio_size; int pfrio_size2; int pfrio_nadd; int pfrio_ndel; int pfrio_nchange; int pfrio_flags; u_int32_t pfrio_ticket; }; struct pfioc_iface { char pfiio_name[16]; void *pfiio_buffer; int pfiio_esize; int pfiio_size; int pfiio_nzero; int pfiio_flags; }; struct pf_pdesc; struct pf_src_tree { struct pf_src_node *rbh_root; }; void pf_src_tree_RB_INSERT_COLOR(struct pf_src_tree *, struct pf_src_node *); void pf_src_tree_RB_REMOVE_COLOR(struct pf_src_tree *, struct pf_src_node *, struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_REMOVE(struct pf_src_tree *, struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_INSERT(struct pf_src_tree *, struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_FIND(struct pf_src_tree *, struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_NFIND(struct pf_src_tree *, struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_NEXT(struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_PREV(struct pf_src_node *); struct pf_src_node *pf_src_tree_RB_MINMAX(struct pf_src_tree *, int);; extern struct pf_src_tree tree_src_tracking; struct pf_state_tree_id { struct pf_state *rbh_root; }; void pf_state_tree_id_RB_INSERT_COLOR(struct pf_state_tree_id *, struct pf_state *); void pf_state_tree_id_RB_REMOVE_COLOR(struct pf_state_tree_id *, struct pf_state *, struct pf_state *); struct pf_state *pf_state_tree_id_RB_REMOVE(struct pf_state_tree_id *, struct pf_state *); struct pf_state *pf_state_tree_id_RB_INSERT(struct pf_state_tree_id *, struct pf_state *); struct pf_state *pf_state_tree_id_RB_FIND(struct pf_state_tree_id *, struct pf_state *); struct pf_state *pf_state_tree_id_RB_NFIND(struct pf_state_tree_id *, struct pf_state *); struct pf_state *pf_state_tree_id_RB_NEXT(struct pf_state *); struct pf_state *pf_state_tree_id_RB_PREV(struct pf_state *); struct pf_state *pf_state_tree_id_RB_MINMAX(struct pf_state_tree_id *, int);; extern struct pf_state_tree_id tree_id; extern struct pf_state_queue state_list; struct pf_queuehead { struct pf_queuespec *tqh_first; struct pf_queuespec **tqh_last; }; extern struct pf_queuehead pf_queues[2]; extern struct pf_queuehead *pf_queues_active, *pf_queues_inactive; extern u_int32_t ticket_pabuf; extern struct pool pf_src_tree_pl, pf_sn_item_pl, pf_rule_pl; extern struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl, pf_rule_item_pl, pf_queue_pl; extern struct pool pf_state_scrub_pl; extern struct ifnet *sync_ifp; extern struct pf_rule pf_default_rule; extern int pf_tbladdr_setup(struct pf_ruleset *, struct pf_addr_wrap *); extern void pf_tbladdr_remove(struct pf_addr_wrap *); extern void pf_tbladdr_copyout(struct pf_addr_wrap *); extern void pf_calc_skip_steps(struct pf_rulequeue *); extern void pf_purge_expired_src_nodes(); extern void pf_purge_expired_states(u_int32_t); extern void pf_purge_expired_rules(); extern void pf_remove_state(struct pf_state *); extern void pf_remove_divert_state(struct pf_state_key *); extern void pf_free_state(struct pf_state *); extern int pf_state_insert(struct pfi_kif *, struct pf_state_key **, struct pf_state_key **, struct pf_state *); int pf_insert_src_node(struct pf_src_node **, struct pf_rule *, enum pf_sn_types, sa_family_t, struct pf_addr *, struct pf_addr *); void pf_remove_src_node(struct pf_src_node *); struct pf_src_node *pf_get_src_node(struct pf_state *, enum pf_sn_types); void pf_src_tree_remove_state(struct pf_state *); void pf_state_rm_src_node(struct pf_state *, struct pf_src_node *); extern struct pf_state *pf_find_state_byid(struct pf_state_cmp *); extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *, u_int, int *); extern void pf_state_export(struct pfsync_state *, struct pf_state *); extern void pf_print_state(struct pf_state *); extern void pf_print_flags(u_int8_t); extern void pf_addrcpy(struct pf_addr *, struct pf_addr *, sa_family_t); void pf_rm_rule(struct pf_rulequeue *, struct pf_rule *); void pf_purge_rule(struct pf_rule *); struct pf_divert *pf_find_divert(struct mbuf *); int pf_setup_pdesc(struct pf_pdesc *, sa_family_t, int, struct pfi_kif *, struct mbuf *, u_short *); int pf_test(sa_family_t, int, struct ifnet *, struct mbuf **); void pf_poolmask(struct pf_addr *, struct pf_addr*, struct pf_addr *, struct pf_addr *, sa_family_t); void pf_addr_inc(struct pf_addr *, sa_family_t); void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *, sa_family_t); int pf_patch_8(struct pf_pdesc *, u_int8_t *, u_int8_t, _Bool); int pf_patch_16(struct pf_pdesc *, u_int16_t *, u_int16_t); int pf_patch_16_unaligned(struct pf_pdesc *, void *, u_int16_t, _Bool); int pf_patch_32(struct pf_pdesc *, u_int32_t *, u_int32_t); int pf_patch_32_unaligned(struct pf_pdesc *, void *, u_int32_t, _Bool); int pflog_packet(struct pf_pdesc *, u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *, struct pf_rule *); void pf_send_deferred_syn(struct pf_state *); int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *, struct pf_addr *, sa_family_t); int pf_match_addr_range(struct pf_addr *, struct pf_addr *, struct pf_addr *, sa_family_t); int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t); int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t); int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t); int pf_match_gid(u_int8_t, gid_t, gid_t, gid_t); int pf_refragment6(struct mbuf **, struct m_tag *mtag, struct sockaddr_in6 *, struct ifnet *, struct rtentry *); void pf_normalize_init(void); int pf_normalize_ip(struct pf_pdesc *, u_short *); int pf_normalize_ip6(struct pf_pdesc *, u_short *); int pf_normalize_tcp(struct pf_pdesc *); void pf_normalize_tcp_cleanup(struct pf_state *); int pf_normalize_tcp_init(struct pf_pdesc *, struct pf_state_peer *); int pf_normalize_tcp_stateful(struct pf_pdesc *, u_short *, struct pf_state *, struct pf_state_peer *, struct pf_state_peer *, int *); int pf_normalize_mss(struct pf_pdesc *, u_int16_t); void pf_scrub(struct mbuf *, u_int16_t, sa_family_t, u_int8_t, u_int8_t); int32_t pf_state_expires(const struct pf_state *); void pf_purge_expired_fragments(void); int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *, int); int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *, int); int pf_socket_lookup(struct pf_pdesc *); struct pf_state_key *pf_alloc_state_key(int); int pf_ouraddr(struct mbuf *); void pf_pkt_addr_changed(struct mbuf *); struct inpcb *pf_inp_lookup(struct mbuf *); void pf_inp_link(struct mbuf *, struct inpcb *); void pf_inp_unlink(struct inpcb *); int pf_state_key_attach(struct pf_state_key *, struct pf_state *, int); int pf_translate(struct pf_pdesc *, struct pf_addr *, u_int16_t, struct pf_addr *, u_int16_t, u_int16_t, int); int pf_translate_af(struct pf_pdesc *); void pf_route(struct pf_pdesc *, struct pf_rule *, struct pf_state *); void pf_route6(struct pf_pdesc *, struct pf_rule *, struct pf_state *); void pf_init_threshold(struct pf_threshold *, u_int32_t, u_int32_t); void pfr_initialize(void); int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t); void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, struct pf_pdesc *, int, int); int pfr_pool_get(struct pf_pool *, struct pf_addr **, struct pf_addr **, sa_family_t); int pfr_states_increase(struct pfr_ktable *, struct pf_addr *, int); int pfr_states_decrease(struct pfr_ktable *, struct pf_addr *, int); struct pfr_kentry * pfr_kentry_byaddr(struct pfr_ktable *, struct pf_addr *, sa_family_t, int); void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *); struct pfr_ktable * pfr_attach_table(struct pf_ruleset *, char *, int); void pfr_detach_table(struct pfr_ktable *); int pfr_clr_tables(struct pfr_table *, int *, int); int pfr_add_tables(struct pfr_table *, int, int *, int); int pfr_del_tables(struct pfr_table *, int, int *, int); int pfr_get_tables(struct pfr_table *, struct pfr_table *, int *, int); int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int); int pfr_clr_tstats(struct pfr_table *, int, int *, int); int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int); int pfr_clr_addrs(struct pfr_table *, int *, int); int pfr_insert_kentry(struct pfr_ktable *, struct pfr_addr *, time_t); int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int *, int *, int *, int, u_int32_t); int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int); int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int); int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_ina_begin(struct pfr_table *, u_int32_t *, int *, int); int pfr_ina_rollback(struct pfr_table *, u_int32_t, int *, int); int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int); int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *, int *, u_int32_t, int); extern struct pfi_kif *pfi_all; void pfi_initialize(void); struct pfi_kif *pfi_kif_find(const char *); struct pfi_kif *pfi_kif_get(const char *); void pfi_kif_ref(struct pfi_kif *, enum pfi_kif_refs); void pfi_kif_unref(struct pfi_kif *, enum pfi_kif_refs); int pfi_kif_match(struct pfi_kif *, struct pfi_kif *); void pfi_attach_ifnet(struct ifnet *); void pfi_detach_ifnet(struct ifnet *); void pfi_attach_ifgroup(struct ifg_group *); void pfi_detach_ifgroup(struct ifg_group *); void pfi_group_change(const char *); int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *, sa_family_t); int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t); void pfi_dynaddr_remove(struct pf_addr_wrap *); void pfi_dynaddr_copyout(struct pf_addr_wrap *); void pfi_update_status(const char *, struct pf_status *); int pfi_get_ifaces(const char *, struct pfi_kif *, int *); int pfi_set_flags(const char *, int); int pfi_clear_flags(const char *, int); void pfi_xcommit(void); int pf_match_tag(struct mbuf *, struct pf_rule *, int *); u_int16_t pf_tagname2tag(char *, int); void pf_tag2tagname(u_int16_t, char *); void pf_tag_ref(u_int16_t); void pf_tag_unref(u_int16_t); void pf_tag_packet(struct mbuf *, int, int); int pf_addr_compare(struct pf_addr *, struct pf_addr *, sa_family_t); const struct pfq_ops *pf_queue_manager(struct pf_queuespec *); extern struct pf_status pf_status; extern struct pool pf_frent_pl, pf_frag_pl; struct pf_pool_limit { void *pp; unsigned limit; unsigned limit_new; }; extern struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; extern struct pf_anchor_global pf_anchors; extern struct pf_anchor pf_main_anchor; struct tcphdr; void pf_init_ruleset(struct pf_ruleset *); int pf_anchor_setup(struct pf_rule *, const struct pf_ruleset *, const char *); int pf_anchor_copyout(const struct pf_ruleset *, const struct pf_rule *, struct pfioc_rule *); void pf_anchor_remove(struct pf_rule *); void pf_remove_if_empty_ruleset(struct pf_ruleset *); struct pf_anchor *pf_find_anchor(const char *); struct pf_ruleset *pf_find_ruleset(const char *); struct pf_ruleset *pf_get_leaf_ruleset(char *, char **); struct pf_anchor *pf_create_anchor(struct pf_anchor *, const char *); struct pf_ruleset *pf_find_or_create_ruleset(const char *); void pf_rs_initialize(void); int pf_anchor_copyout(const struct pf_ruleset *, const struct pf_rule *, struct pfioc_rule *); void pf_anchor_remove(struct pf_rule *); int pf_osfp_add(struct pf_osfp_ioctl *); struct pf_osfp_enlist * pf_osfp_fingerprint(struct pf_pdesc *); struct pf_osfp_enlist * pf_osfp_fingerprint_hdr(const struct ip *, const struct ip6_hdr *, const struct tcphdr *); void pf_osfp_flush(void); int pf_osfp_get(struct pf_osfp_ioctl *); void pf_osfp_initialize(void); int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t); struct pf_os_fingerprint * pf_osfp_validate(void); void pf_print_host(struct pf_addr *, u_int16_t, sa_family_t); int pf_get_transaddr(struct pf_rule *, struct pf_pdesc *, struct pf_src_node **, struct pf_rule **); int pf_map_addr(sa_family_t, struct pf_rule *, struct pf_addr *, struct pf_addr *, struct pf_addr *, struct pf_src_node **, struct pf_pool *, enum pf_sn_types); int pf_postprocess_addr(struct pf_state *); void pf_mbuf_link_state_key(struct mbuf *, struct pf_state_key *); void pf_mbuf_unlink_state_key(struct mbuf *); u_int8_t pf_get_wscale(struct pf_pdesc *); u_int16_t pf_get_mss(struct pf_pdesc *); struct mbuf * pf_build_tcp(const struct pf_rule *, sa_family_t, const struct pf_addr *, const struct pf_addr *, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, u_int16_t, u_int, u_int); void pf_send_tcp(const struct pf_rule *, sa_family_t, const struct pf_addr *, const struct pf_addr *, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, u_int16_t, u_int); ; struct cpumem *mbstat = ((void *)0); static char mclnames[8][8]; int max_linkhdr; int max_protohdr; int max_hdr; struct mutex m_extref_mtx = { ((void *)0), ((((0x7)) > 0x0 && ((0x7)) < 0x9) ? 0x9 : ((0x7))), 0x0 }; void m_extfree(struct mbuf *); void nmbclust_update(void); void m_zero(struct mbuf *); unsigned int mbuf_mem_limit; unsigned int mbuf_mem_alloc; static void (*mextfree_fns[4])(caddr_t, u_int, void *); static u_int num_extfree_fns; int __VERIFIER_nondet_bool(void); void mbinit(void) { } void mbcpuinit() { } void nmbclust_update(void) { } struct mbuf * m_get(int nowait, int type) { struct mbuf *m; if (nowait == 0x0002 && __VERIFIER_nondet_bool()) { return (((void *)0)); } m = malloc(sizeof(struct mbuf), 0, 0); m->m_hdr.mh_type = type; m->m_hdr.mh_next = ((void *)0); m->m_hdr.mh_nextpkt = ((void *)0); m->m_hdr.mh_data = m->M_dat.M_databuf; m->m_hdr.mh_flags = 0; return (m); } struct mbuf * m_gethdr(int nowait, int type) { ((void)0); struct mbuf *m; if (nowait == 0x0002 && __VERIFIER_nondet_bool()) { return (((void *)0)); } m = malloc(sizeof(struct mbuf), 0, 0); m->m_hdr.mh_type = type; return (m_inithdr(m)); } struct mbuf * m_inithdr(struct mbuf *m) { m->m_hdr.mh_next = ((void *)0); m->m_hdr.mh_nextpkt = ((void *)0); m->m_hdr.mh_data = m->M_dat.MH.MH_dat.MH_databuf; m->m_hdr.mh_flags = 0x0002; __builtin_memset((&m->M_dat.MH.MH_pkthdr), (0), (sizeof(m->M_dat.MH.MH_pkthdr))); m->M_dat.MH.MH_pkthdr.pf.prio = 3; return (m); } void m_resethdr(struct mbuf *m) { int len = m->M_dat.MH.MH_pkthdr.len; u_int8_t loopcnt = m->M_dat.MH.MH_pkthdr.ph_loopcnt; ((m->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic ", "module.c", 192, "m->m_flags & M_PKTHDR")); m->m_hdr.mh_flags &= (0x0001|0x0002|0x0004|0x0008|0x2000); m_tag_delete_chain(m); pf_mbuf_unlink_state_key(m); __builtin_memset((&m->M_dat.MH.MH_pkthdr), (0), (sizeof(m->M_dat.MH.MH_pkthdr))); m->M_dat.MH.MH_pkthdr.pf.prio = 3; m->M_dat.MH.MH_pkthdr.len = len; m->M_dat.MH.MH_pkthdr.ph_loopcnt = loopcnt; } struct mbuf * m_getclr(int nowait, int type) { struct mbuf *m; m = m_get((nowait), (type)); if (m == ((void *)0)) return (((void *)0)); __builtin_memset((((caddr_t)((m)->m_hdr.mh_data))), (0), ((256 - sizeof(struct m_hdr)))); return (m); } struct mbuf * m_clget(struct mbuf *m, int how, u_int pktlen) { struct mbuf *m0 = ((void *)0); caddr_t buf; if (pktlen > (64 * 1024)) panic("m_clget: request for %u byte cluster", pktlen); if (m == ((void *)0)) { m0 = m_gethdr(how, 1); if (m0 == ((void *)0)) return (((void *)0)); m = m0; } if (how == 0x0002 && __VERIFIER_nondet_bool()) { m_freem(m0); return (((void *)0)); } buf = malloc(sizeof(struct mbuf), 0, m); (m)->m_hdr.mh_data = (m)->M_dat.MH.MH_dat.MH_ext.ext_buf = (caddr_t)(buf); (m)->m_hdr.mh_flags |= 0x0001 | (0x0008 & 0x0008); (m)->M_dat.MH.MH_dat.MH_ext.ext_size = (64 * 1024); (m)->M_dat.MH.MH_dat.MH_ext.ext_free_fn = (0); (m)->M_dat.MH.MH_dat.MH_ext.ext_arg = (((void *)0)); (m)->M_dat.MH.MH_dat.MH_ext.ext_prevref = (m); (m)->M_dat.MH.MH_dat.MH_ext.ext_nextref = (m); return (m); } void m_extfree_pool(caddr_t buf, u_int size, void *pp) { free(buf, 127, size); } struct mbuf * m_free(struct mbuf *m) { struct mbuf *n; if (m == ((void *)0)) return (((void *)0)); n = m->m_hdr.mh_next; if (m->m_hdr.mh_flags & 0x2000) { m_zero(m); if (n) n->m_hdr.mh_flags |= 0x2000; } if (m->m_hdr.mh_flags & 0x0002) { m_tag_delete_chain(m); pf_mbuf_unlink_state_key(m); } if (m->m_hdr.mh_flags & 0x0001) m_extfree(m); free(m, 127, sizeof(struct mbuf)); return (n); } void m_extref(struct mbuf *o, struct mbuf *n) { int refs = ((o)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (o)); n->m_hdr.mh_flags |= o->m_hdr.mh_flags & (0x0001|0x0008); if (refs) __mtx_enter(&m_extref_mtx); n->M_dat.MH.MH_dat.MH_ext.ext_nextref = o->M_dat.MH.MH_dat.MH_ext.ext_nextref; n->M_dat.MH.MH_dat.MH_ext.ext_prevref = o; o->M_dat.MH.MH_dat.MH_ext.ext_nextref = n; n->M_dat.MH.MH_dat.MH_ext.ext_nextref->M_dat.MH.MH_dat.MH_ext.ext_prevref = n; if (refs) __mtx_leave(&m_extref_mtx); ; } static inline u_int m_extunref(struct mbuf *m) { int refs = 1; if (!((m)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (m))) return (0); __mtx_enter(&m_extref_mtx); if (((m)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (m))) { m->M_dat.MH.MH_dat.MH_ext.ext_nextref->M_dat.MH.MH_dat.MH_ext.ext_prevref = m->M_dat.MH.MH_dat.MH_ext.ext_prevref; m->M_dat.MH.MH_dat.MH_ext.ext_prevref->M_dat.MH.MH_dat.MH_ext.ext_nextref = m->M_dat.MH.MH_dat.MH_ext.ext_nextref; } else refs = 0; __mtx_leave(&m_extref_mtx); return (refs); } u_int mextfree_register(void (*fn)(caddr_t, u_int, void *)) { ((num_extfree_fns < (sizeof((mextfree_fns)) / sizeof((mextfree_fns)[0]))) ? (void)0 : __assert("diagnostic ", "module.c", 335, "num_extfree_fns < nitems(mextfree_fns)")); mextfree_fns[num_extfree_fns] = fn; return num_extfree_fns++; } void m_extfree(struct mbuf *m) { if (m_extunref(m) == 0) { ((m->M_dat.MH.MH_dat.MH_ext.ext_free_fn < num_extfree_fns) ? (void)0 : __assert("diagnostic ", "module.c", 344, "m->m_ext.ext_free_fn < num_extfree_fns")); mextfree_fns[m->M_dat.MH.MH_dat.MH_ext.ext_free_fn](m->M_dat.MH.MH_dat.MH_ext.ext_buf, m->M_dat.MH.MH_dat.MH_ext.ext_size, m->M_dat.MH.MH_dat.MH_ext.ext_arg); } m->m_hdr.mh_flags &= ~(0x0001|0x0008); } struct mbuf * m_freem(struct mbuf *m) { struct mbuf *n; if (m == ((void *)0)) return (((void *)0)); n = m->m_hdr.mh_nextpkt; do m = m_free(m); while (m != ((void *)0)); return (n); } void m_purge(struct mbuf *m) { while (m != ((void *)0)) m = m_freem(m); } int m_defrag(struct mbuf *m, int how) { struct mbuf *m0; if (m->m_hdr.mh_next == ((void *)0)) return (0); ((m->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic ", "module.c", 389, "m->m_flags & M_PKTHDR")); if ((m0 = m_gethdr(how, m->m_hdr.mh_type)) == ((void *)0)) return (55); if (m->M_dat.MH.MH_pkthdr.len > ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) { m_clget((m0), (how), (m->M_dat.MH.MH_pkthdr.len)); if (!(m0->m_hdr.mh_flags & 0x0001)) { m_free(m0); return (55); } } m_copydata(m, 0, m->M_dat.MH.MH_pkthdr.len, ((caddr_t)((m0)->m_hdr.mh_data))); m0->M_dat.MH.MH_pkthdr.len = m0->m_hdr.mh_len = m->M_dat.MH.MH_pkthdr.len; m_freem(m->m_hdr.mh_next); m->m_hdr.mh_next = ((void *)0); if (m->m_hdr.mh_flags & 0x0001) m_extfree(m); if (m0->m_hdr.mh_flags & 0x0001) { __builtin_memcpy((&m->M_dat.MH.MH_dat.MH_ext), (&m0->M_dat.MH.MH_dat.MH_ext), (sizeof(struct mbuf_ext))); do { (m)->M_dat.MH.MH_dat.MH_ext.ext_prevref = (m); (m)->M_dat.MH.MH_dat.MH_ext.ext_nextref = (m); ; ; } while ( 0); m->m_hdr.mh_flags |= m0->m_hdr.mh_flags & (0x0001|0x0008); m->m_hdr.mh_data = m->M_dat.MH.MH_dat.MH_ext.ext_buf; } else { m->m_hdr.mh_data = m->M_dat.MH.MH_dat.MH_databuf; __builtin_memcpy((m->m_hdr.mh_data), (m0->m_hdr.mh_data), (m0->m_hdr.mh_len)); } m->M_dat.MH.MH_pkthdr.len = m->m_hdr.mh_len = m0->m_hdr.mh_len; m0->m_hdr.mh_flags &= ~(0x0001|0x0008); m_free(m0); return (0); } struct mbuf * m_prepend(struct mbuf *m, int len, int how) { struct mbuf *mn; if (len > ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) panic("mbuf prepend length too big"); if (m_leadingspace(m) >= len) { m->m_hdr.mh_data -= len; m->m_hdr.mh_len += len; } else { mn = m_get((how), (m->m_hdr.mh_type)); if (mn == ((void *)0)) { m_freem(m); return (((void *)0)); } if (m->m_hdr.mh_flags & 0x0002) do { (mn)->m_hdr.mh_flags = ((mn)->m_hdr.mh_flags & (0x0001 | 0x0008)); (mn)->m_hdr.mh_flags |= (m)->m_hdr.mh_flags & (0x0002|0x0004|0x0010|0x0100|0x0200|0x0400|0x4000| 0x0800|0x0040|0x1000|0x8000|0x0020|0x0080| 0x2000); do { ((mn))->M_dat.MH.MH_pkthdr = ((m))->M_dat.MH.MH_pkthdr; ((m))->m_hdr.mh_flags &= ~0x0002; { ((&((m))->M_dat.MH.MH_pkthdr.ph_tags)->slh_first) = ((void *)0); }; ((m))->M_dat.MH.MH_pkthdr.pf.statekey = ((void *)0); } while ( 0); if (((mn)->m_hdr.mh_flags & 0x0001) == 0) (mn)->m_hdr.mh_data = (mn)->M_dat.MH.MH_dat.MH_databuf; } while ( 0); mn->m_hdr.mh_next = m; m = mn; (m)->m_hdr.mh_data += (((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)) - (len)) &~ (sizeof(long) - 1); m->m_hdr.mh_len = len; } if (m->m_hdr.mh_flags & 0x0002) m->M_dat.MH.MH_pkthdr.len += len; return (m); } struct mbuf * m_copym(struct mbuf *m0, int off, int len, int wait) { struct mbuf *m, *n, **np; struct mbuf *top; int copyhdr = 0; if (off < 0 || len < 0) panic("m_copym0: off %d, len %d", off, len); if (off == 0 && m0->m_hdr.mh_flags & 0x0002) copyhdr = 1; if ((m = m_getptr(m0, off, &off)) == ((void *)0)) panic("m_copym0: short mbuf chain"); np = ⊤ top = ((void *)0); while (len > 0) { if (m == ((void *)0)) { if (len != 1000000000) panic("m_copym0: m == NULL and not COPYALL"); break; } n = m_get((wait), (m->m_hdr.mh_type)); *np = n; if (n == ((void *)0)) goto nospace; if (copyhdr) { if (m_dup_pkthdr(n, m0, wait)) goto nospace; if (len != 1000000000) n->M_dat.MH.MH_pkthdr.len = len; copyhdr = 0; } n->m_hdr.mh_len = min(len, m->m_hdr.mh_len - off); if (m->m_hdr.mh_flags & 0x0001) { n->m_hdr.mh_data = m->m_hdr.mh_data + off; n->M_dat.MH.MH_dat.MH_ext = m->M_dat.MH.MH_dat.MH_ext; m_extref((m), (n)); } else { n->m_hdr.mh_data += m->m_hdr.mh_data - (m->m_hdr.mh_flags & 0x0002 ? m->M_dat.MH.MH_dat.MH_databuf : m->M_dat.M_databuf); n->m_hdr.mh_data += off; __builtin_memcpy((((caddr_t)((n)->m_hdr.mh_data))), (((caddr_t)((m)->m_hdr.mh_data)) + off), (n->m_hdr.mh_len)); } if (len != 1000000000) len -= n->m_hdr.mh_len; off += n->m_hdr.mh_len; if (off > m->m_hdr.mh_len) panic("m_copym0 overrun"); if (off == m->m_hdr.mh_len) { m = m->m_hdr.mh_next; off = 0; } np = &n->m_hdr.mh_next; } return (top); nospace: m_freem(top); return (((void *)0)); } void m_copydata(struct mbuf *m, int off, int len, caddr_t cp) { unsigned count; if (off < 0) panic("m_copydata: off %d < 0", off); if (len < 0) panic("m_copydata: len %d < 0", len); if ((m = m_getptr(m, off, &off)) == ((void *)0)) panic("m_copydata: short mbuf chain"); while (len > 0) { if (m == ((void *)0)) panic("m_copydata: null mbuf"); count = min(m->m_hdr.mh_len - off, len); __builtin_memmove((cp), (((caddr_t)((m)->m_hdr.mh_data)) + off), (count)); len -= count; cp += count; off = 0; m = m->m_hdr.mh_next; } } int m_copyback(struct mbuf *m0, int off, int len, const void *_cp, int wait) { int mlen, totlen = 0; struct mbuf *m = m0, *n; caddr_t cp = (caddr_t)_cp; int error = 0; if (m0 == ((void *)0)) return (0); while (off > (mlen = m->m_hdr.mh_len)) { off -= mlen; totlen += mlen; if (m->m_hdr.mh_next == ((void *)0)) { if ((n = m_get(wait, m->m_hdr.mh_type)) == ((void *)0)) { error = 55; goto out; } if (off + len > (256 - sizeof(struct m_hdr))) { m_clget((n), (wait), (off + len)); if (!(n->m_hdr.mh_flags & 0x0001)) { m_free(n); error = 55; goto out; } } __builtin_memset((((caddr_t)((n)->m_hdr.mh_data))), (0), (off)); n->m_hdr.mh_len = len + off; m->m_hdr.mh_next = n; } m = m->m_hdr.mh_next; } while (len > 0) { if (m->m_hdr.mh_next == ((void *)0) && (len > m->m_hdr.mh_len - off)) m->m_hdr.mh_len += min(len - (m->m_hdr.mh_len - off), m_trailingspace(m)); mlen = min(m->m_hdr.mh_len - off, len); __builtin_memmove((((caddr_t)((m)->m_hdr.mh_data)) + off), (cp), (mlen)); cp += mlen; len -= mlen; totlen += mlen + off; if (len == 0) break; off = 0; if (m->m_hdr.mh_next == ((void *)0)) { if ((n = m_get(wait, m->m_hdr.mh_type)) == ((void *)0)) { error = 55; goto out; } if (len > (256 - sizeof(struct m_hdr))) { m_clget((n), (wait), (len)); if (!(n->m_hdr.mh_flags & 0x0001)) { m_free(n); error = 55; goto out; } } n->m_hdr.mh_len = len; m->m_hdr.mh_next = n; } m = m->m_hdr.mh_next; } out: if (((m = m0)->m_hdr.mh_flags & 0x0002) && (m->M_dat.MH.MH_pkthdr.len < totlen)) m->M_dat.MH.MH_pkthdr.len = totlen; return (error); } void m_cat(struct mbuf *m, struct mbuf *n) { while (m->m_hdr.mh_next) m = m->m_hdr.mh_next; while (n) { if ((((m)->m_hdr.mh_flags & 0x0001) != 0 && (((m)->m_hdr.mh_flags & 0x0008) == 0 || ((m)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (m)))) || n->m_hdr.mh_len > m_trailingspace(m)) { m->m_hdr.mh_next = n; return; } __builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data)) + m->m_hdr.mh_len), (((caddr_t)((n)->m_hdr.mh_data))), (n->m_hdr.mh_len)); m->m_hdr.mh_len += n->m_hdr.mh_len; n = m_free(n); } } void m_adj(struct mbuf *mp, int req_len) { int len = req_len; struct mbuf *m; int count; if (mp == ((void *)0)) return; if (len >= 0) { m = mp; while (m != ((void *)0) && len > 0) { if (m->m_hdr.mh_len <= len) { len -= m->m_hdr.mh_len; m->m_hdr.mh_data += m->m_hdr.mh_len; m->m_hdr.mh_len = 0; m = m->m_hdr.mh_next; } else { m->m_hdr.mh_data += len; m->m_hdr.mh_len -= len; len = 0; } } if (mp->m_hdr.mh_flags & 0x0002) mp->M_dat.MH.MH_pkthdr.len -= (req_len - len); } else { len = -len; count = 0; m = mp; for (;;) { count += m->m_hdr.mh_len; if (m->m_hdr.mh_next == ((void *)0)) break; m = m->m_hdr.mh_next; } if (m->m_hdr.mh_len >= len) { m->m_hdr.mh_len -= len; if (mp->m_hdr.mh_flags & 0x0002) mp->M_dat.MH.MH_pkthdr.len -= len; return; } count -= len; if (count < 0) count = 0; if (mp->m_hdr.mh_flags & 0x0002) mp->M_dat.MH.MH_pkthdr.len = count; m = mp; for (;;) { if (m->m_hdr.mh_len >= count) { m->m_hdr.mh_len = count; break; } count -= m->m_hdr.mh_len; m = m->m_hdr.mh_next; } while ((m = m->m_hdr.mh_next) != ((void *)0)) m->m_hdr.mh_len = 0; } } struct mbuf * m_pullup(struct mbuf *n, int len) { struct mbuf *m; unsigned int adj; caddr_t head, tail; unsigned int space; if (len <= n->m_hdr.mh_len) return (n); adj = (unsigned long)n->m_hdr.mh_data & (sizeof(long) - 1); head = (caddr_t)(((unsigned long)(((caddr_t)((n)->m_hdr.mh_data)) - m_leadingspace(n)) + (sizeof(long) - 1)) &~(sizeof(long) - 1)) + adj; tail = ((caddr_t)((n)->m_hdr.mh_data)) + n->m_hdr.mh_len + m_trailingspace(n); if (head < tail && len <= tail - head) { if (len > tail - ((caddr_t)((n)->m_hdr.mh_data))) { __builtin_memmove((head), (((caddr_t)((n)->m_hdr.mh_data))), (n->m_hdr.mh_len)); n->m_hdr.mh_data = head; } len -= n->m_hdr.mh_len; m = n; n = m->m_hdr.mh_next; } else { space = adj + len; if (space > (64 * 1024)) goto bad; m = m_get((0x0002), (n->m_hdr.mh_type)); if (m == ((void *)0)) goto bad; if (space > ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) { m_clget((m), (0x0002), (space)); if ((m->m_hdr.mh_flags & 0x0001) == 0) { m_free(m); goto bad; } } if (n->m_hdr.mh_flags & 0x0002) do { (m)->m_hdr.mh_flags = ((m)->m_hdr.mh_flags & (0x0001 | 0x0008)); (m)->m_hdr.mh_flags |= (n)->m_hdr.mh_flags & (0x0002|0x0004|0x0010|0x0100|0x0200|0x0400|0x4000| 0x0800|0x0040|0x1000|0x8000|0x0020|0x0080| 0x2000); do { ((m))->M_dat.MH.MH_pkthdr = ((n))->M_dat.MH.MH_pkthdr; ((n))->m_hdr.mh_flags &= ~0x0002; { ((&((n))->M_dat.MH.MH_pkthdr.ph_tags)->slh_first) = ((void *)0); }; ((n))->M_dat.MH.MH_pkthdr.pf.statekey = ((void *)0); } while ( 0); if (((m)->m_hdr.mh_flags & 0x0001) == 0) (m)->m_hdr.mh_data = (m)->M_dat.MH.MH_dat.MH_databuf; } while ( 0); m->m_hdr.mh_len = 0; m->m_hdr.mh_data += adj; } ((m_trailingspace(m) >= len) ? (void)0 : __assert("diagnostic ", "module.c", 801, "M_TRAILINGSPACE(m) >= len")); do { if (n == ((void *)0)) { (void)m_free(m); goto bad; } space = min(len, n->m_hdr.mh_len); __builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data)) + m->m_hdr.mh_len), (((caddr_t)((n)->m_hdr.mh_data))), (space)); len -= space; m->m_hdr.mh_len += space; n->m_hdr.mh_len -= space; if (n->m_hdr.mh_len > 0) n->m_hdr.mh_data += space; else n = m_free(n); } while (len > 0); m->m_hdr.mh_next = n; return (m); bad: m_freem(n); return (((void *)0)); } struct mbuf * m_getptr(struct mbuf *m, int loc, int *off) { while (loc >= 0) { if (m->m_hdr.mh_len > loc) { *off = loc; return (m); } else { loc -= m->m_hdr.mh_len; if (m->m_hdr.mh_next == ((void *)0)) { if (loc == 0) { *off = m->m_hdr.mh_len; return (m); } else { return (((void *)0)); } } else { m = m->m_hdr.mh_next; } } } return (((void *)0)); } struct mbuf * m_split(struct mbuf *m0, int len0, int wait) { struct mbuf *m, *n; unsigned len = len0, remain, olen; for (m = m0; m && len > m->m_hdr.mh_len; m = m->m_hdr.mh_next) len -= m->m_hdr.mh_len; if (m == ((void *)0)) return (((void *)0)); remain = m->m_hdr.mh_len - len; if (m0->m_hdr.mh_flags & 0x0002) { n = m_gethdr((wait), (m0->m_hdr.mh_type)); if (n == ((void *)0)) return (((void *)0)); if (m_dup_pkthdr(n, m0, wait)) { m_freem(n); return (((void *)0)); } n->M_dat.MH.MH_pkthdr.len -= len0; olen = m0->M_dat.MH.MH_pkthdr.len; m0->M_dat.MH.MH_pkthdr.len = len0; if (remain == 0) { n->m_hdr.mh_next = m->m_hdr.mh_next; m->m_hdr.mh_next = ((void *)0); n->m_hdr.mh_len = 0; return (n); } if (m->m_hdr.mh_flags & 0x0001) goto extpacket; if (remain > ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) { (n)->m_hdr.mh_data += (((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)) - (0)) &~ (sizeof(long) - 1); n->m_hdr.mh_next = m_split(m, len, wait); if (n->m_hdr.mh_next == ((void *)0)) { (void) m_free(n); m0->M_dat.MH.MH_pkthdr.len = olen; return (((void *)0)); } else { n->m_hdr.mh_len = 0; return (n); } } else (n)->m_hdr.mh_data += (((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)) - (remain)) &~ (sizeof(long) - 1); } else if (remain == 0) { n = m->m_hdr.mh_next; m->m_hdr.mh_next = ((void *)0); return (n); } else { n = m_get((wait), (m->m_hdr.mh_type)); if (n == ((void *)0)) return (((void *)0)); (n)->m_hdr.mh_data += ((256 - sizeof(struct m_hdr)) - (remain)) &~ (sizeof(long) - 1); } extpacket: if (m->m_hdr.mh_flags & 0x0001) { n->M_dat.MH.MH_dat.MH_ext = m->M_dat.MH.MH_dat.MH_ext; m_extref((m), (n)); n->m_hdr.mh_data = m->m_hdr.mh_data + len; } else { __builtin_memcpy((((caddr_t)((n)->m_hdr.mh_data))), (((caddr_t)((m)->m_hdr.mh_data)) + len), (remain)); } n->m_hdr.mh_len = remain; m->m_hdr.mh_len = len; n->m_hdr.mh_next = m->m_hdr.mh_next; m->m_hdr.mh_next = ((void *)0); return (n); } struct mbuf * m_makespace(struct mbuf *m0, int skip, int hlen, int *off) { struct mbuf *m; unsigned remain; ((m0->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic ", "module.c", 949, "m0->m_flags & M_PKTHDR")); ((hlen < ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) ? (void)0 : __assert("diagnostic ", "module.c", 956, "hlen < MHLEN")); for (m = m0; m && skip > m->m_hdr.mh_len; m = m->m_hdr.mh_next) skip -= m->m_hdr.mh_len; if (m == ((void *)0)) return (((void *)0)); remain = m->m_hdr.mh_len - skip; if (skip < remain && hlen <= m_leadingspace(m)) { if (skip) __builtin_memmove((m->m_hdr.mh_data-hlen), (m->m_hdr.mh_data), (skip)); m->m_hdr.mh_data -= hlen; m->m_hdr.mh_len += hlen; *off = skip; } else if (hlen > m_trailingspace(m)) { struct mbuf *n; if (remain > 0) { n = m_get((0x0002), (m->m_hdr.mh_type)); if (n && remain > (256 - sizeof(struct m_hdr))) { m_clget((n), (0x0002), (remain)); if ((n->m_hdr.mh_flags & 0x0001) == 0) { m_free(n); n = ((void *)0); } } if (n == ((void *)0)) return (((void *)0)); __builtin_memcpy((n->m_hdr.mh_data), (((char *)((m)->m_hdr.mh_data)) + skip), (remain)); n->m_hdr.mh_len = remain; m->m_hdr.mh_len -= remain; n->m_hdr.mh_next = m->m_hdr.mh_next; m->m_hdr.mh_next = n; } if (hlen <= m_trailingspace(m)) { m->m_hdr.mh_len += hlen; *off = skip; } else { n = m_get(0x0002, m->m_hdr.mh_type); if (n == ((void *)0)) return ((void *)0); n->m_hdr.mh_len = hlen; n->m_hdr.mh_next = m->m_hdr.mh_next; m->m_hdr.mh_next = n; *off = 0; m = n; } } else { if (remain > 0) __builtin_memmove((((caddr_t)((m)->m_hdr.mh_data)) + skip + hlen), (((caddr_t)((m)->m_hdr.mh_data)) + skip), (remain)); m->m_hdr.mh_len += hlen; *off = skip; } m0->M_dat.MH.MH_pkthdr.len += hlen; return m; } struct mbuf * m_devget(char *buf, int totlen, int off) { struct mbuf *m; struct mbuf *top, **mp; int len; top = ((void *)0); mp = ⊤ if (off < 0 || off > ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) return (((void *)0)); m = m_gethdr((0x0002), (1)); if (m == ((void *)0)) return (((void *)0)); m->M_dat.MH.MH_pkthdr.len = totlen; len = ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)); while (totlen > 0) { if (top != ((void *)0)) { m = m_get((0x0002), (1)); if (m == ((void *)0)) { top->m_hdr.mh_flags |= 0x2000; m_freem(top); return (((void *)0)); } len = (256 - sizeof(struct m_hdr)); } if (totlen + off >= (((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)) + (256 - sizeof(struct m_hdr)) + 1)) { (void) m_clget((m), (0x0002), (1 << 11)); if (m->m_hdr.mh_flags & 0x0001) len = (1 << 11); } else { if (top == ((void *)0) && totlen + off + max_linkhdr <= len) { m->m_hdr.mh_data += max_linkhdr; len -= max_linkhdr; } } if (off) { m->m_hdr.mh_data += off; len -= off; off = 0; } m->m_hdr.mh_len = len = min(totlen, len); __builtin_memcpy((((void *)((m)->m_hdr.mh_data))), (buf), ((size_t)len)); buf += len; *mp = m; mp = &m->m_hdr.mh_next; totlen -= len; } return (top); } void m_zero(struct mbuf *m) { if ((((m)->m_hdr.mh_flags & 0x0001) != 0 && (((m)->m_hdr.mh_flags & 0x0008) == 0 || ((m)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (m))))) panic("m_zero: M_READONLY"); if (m->m_hdr.mh_flags & 0x0001) explicit_bzero(m->M_dat.MH.MH_dat.MH_ext.ext_buf, m->M_dat.MH.MH_dat.MH_ext.ext_size); else { if (m->m_hdr.mh_flags & 0x0002) explicit_bzero(m->M_dat.MH.MH_dat.MH_databuf, ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))); else explicit_bzero(m->M_dat.M_databuf, (256 - sizeof(struct m_hdr))); } } int m_apply(struct mbuf *m, int off, int len, int (*f)(caddr_t, caddr_t, unsigned int), caddr_t fstate) { int rval; unsigned int count; if (len < 0) panic("m_apply: len %d < 0", len); if (off < 0) panic("m_apply: off %d < 0", off); while (off > 0) { if (m == ((void *)0)) panic("m_apply: null mbuf in skip"); if (off < m->m_hdr.mh_len) break; off -= m->m_hdr.mh_len; m = m->m_hdr.mh_next; } while (len > 0) { if (m == ((void *)0)) panic("m_apply: null mbuf"); count = min(m->m_hdr.mh_len - off, len); rval = f(fstate, ((caddr_t)((m)->m_hdr.mh_data)) + off, count); if (rval) return (rval); len -= count; off = 0; m = m->m_hdr.mh_next; } return (0); } int m_leadingspace(struct mbuf *m) { if ((((m)->m_hdr.mh_flags & 0x0001) != 0 && (((m)->m_hdr.mh_flags & 0x0008) == 0 || ((m)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (m))))) return 0; return (m->m_hdr.mh_flags & 0x0001 ? m->m_hdr.mh_data - m->M_dat.MH.MH_dat.MH_ext.ext_buf : m->m_hdr.mh_flags & 0x0002 ? m->m_hdr.mh_data - m->M_dat.MH.MH_dat.MH_databuf : m->m_hdr.mh_data - m->M_dat.M_databuf); } int m_trailingspace(struct mbuf *m) { if ((((m)->m_hdr.mh_flags & 0x0001) != 0 && (((m)->m_hdr.mh_flags & 0x0008) == 0 || ((m)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (m))))) return 0; return (m->m_hdr.mh_flags & 0x0001 ? m->M_dat.MH.MH_dat.MH_ext.ext_buf + m->M_dat.MH.MH_dat.MH_ext.ext_size - (m->m_hdr.mh_data + m->m_hdr.mh_len) : &m->M_dat.M_databuf[(256 - sizeof(struct m_hdr))] - (m->m_hdr.mh_data + m->m_hdr.mh_len)); } int m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int wait) { int error; ((from->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic ", "module.c", 1188, "from->m_flags & M_PKTHDR")); to->m_hdr.mh_flags = (to->m_hdr.mh_flags & (0x0001 | 0x0008)); to->m_hdr.mh_flags |= (from->m_hdr.mh_flags & (0x0002|0x0004|0x0010|0x0100|0x0200|0x0400|0x4000| 0x0800|0x0040|0x1000|0x8000|0x0020|0x0080| 0x2000)); to->M_dat.MH.MH_pkthdr = from->M_dat.MH.MH_pkthdr; to->M_dat.MH.MH_pkthdr.pf.statekey = ((void *)0); pf_mbuf_link_state_key(to, from->M_dat.MH.MH_pkthdr.pf.statekey); { ((&to->M_dat.MH.MH_pkthdr.ph_tags)->slh_first) = ((void *)0); }; if ((error = m_tag_copy_chain(to, from, wait)) != 0) return (error); if ((to->m_hdr.mh_flags & 0x0001) == 0) to->m_hdr.mh_data = to->M_dat.MH.MH_dat.MH_databuf; return (0); } struct mbuf * m_dup_pkt(struct mbuf *m0, unsigned int adj, int wait) { struct mbuf *m; int len; ((m0->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic ", "module.c", 1216, "m0->m_flags & M_PKTHDR")); len = m0->M_dat.MH.MH_pkthdr.len + adj; if (len > (64 * 1024)) return (((void *)0)); m = m_get(wait, m0->m_hdr.mh_type); if (m == ((void *)0)) return (((void *)0)); if (m_dup_pkthdr(m, m0, wait) != 0) goto fail; if (len > ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) { m_clget((m), (wait), (len)); if (!((m->m_hdr.mh_flags) & (0x0001))) goto fail; } m->m_hdr.mh_len = m->M_dat.MH.MH_pkthdr.len = len; m_adj(m, adj); m_copydata(m0, 0, m0->M_dat.MH.MH_pkthdr.len, ((caddr_t)((m)->m_hdr.mh_data))); return (m); fail: m_freem(m); return (((void *)0)); } void ml_init(struct mbuf_list *ml) { ml->ml_head = ml->ml_tail = ((void *)0); ml->ml_len = 0; } void ml_enqueue(struct mbuf_list *ml, struct mbuf *m) { if (ml->ml_tail == ((void *)0)) ml->ml_head = ml->ml_tail = m; else { ml->ml_tail->m_hdr.mh_nextpkt = m; ml->ml_tail = m; } m->m_hdr.mh_nextpkt = ((void *)0); ml->ml_len++; } void ml_enlist(struct mbuf_list *mla, struct mbuf_list *mlb) { if (!((mlb)->ml_len == 0)) { if (((mla)->ml_len == 0)) mla->ml_head = mlb->ml_head; else mla->ml_tail->m_hdr.mh_nextpkt = mlb->ml_head; mla->ml_tail = mlb->ml_tail; mla->ml_len += mlb->ml_len; ml_init(mlb); } } struct mbuf * ml_dequeue(struct mbuf_list *ml) { struct mbuf *m; m = ml->ml_head; if (m != ((void *)0)) { ml->ml_head = m->m_hdr.mh_nextpkt; if (ml->ml_head == ((void *)0)) ml->ml_tail = ((void *)0); m->m_hdr.mh_nextpkt = ((void *)0); ml->ml_len--; } return (m); } struct mbuf * ml_dechain(struct mbuf_list *ml) { struct mbuf *m0; m0 = ml->ml_head; ml_init(ml); return (m0); } unsigned int ml_purge(struct mbuf_list *ml) { struct mbuf *m, *n; unsigned int len; for (m = ml->ml_head; m != ((void *)0); m = n) { n = m->m_hdr.mh_nextpkt; m_freem(m); } len = ml->ml_len; ml_init(ml); return (len); } void mq_init(struct mbuf_queue *mq, u_int maxlen, int ipl) { do { (void)(((void *)0)); (void)(0); __mtx_init((&mq->mq_mtx), ((((ipl)) > 0x0 && ((ipl)) < 0x9) ? 0x9 : ((ipl)))); } while (0); ml_init(&mq->mq_list); mq->mq_maxlen = maxlen; } int mq_enqueue(struct mbuf_queue *mq, struct mbuf *m) { int dropped = 0; __mtx_enter(&mq->mq_mtx); if (((&(mq)->mq_list)->ml_len) < mq->mq_maxlen) ml_enqueue(&mq->mq_list, m); else { mq->mq_drops++; dropped = 1; } __mtx_leave(&mq->mq_mtx); if (dropped) m_freem(m); return (dropped); } struct mbuf * mq_dequeue(struct mbuf_queue *mq) { struct mbuf *m; __mtx_enter(&mq->mq_mtx); m = ml_dequeue(&mq->mq_list); __mtx_leave(&mq->mq_mtx); return (m); } int mq_enlist(struct mbuf_queue *mq, struct mbuf_list *ml) { struct mbuf *m; int dropped = 0; __mtx_enter(&mq->mq_mtx); if (((&(mq)->mq_list)->ml_len) < mq->mq_maxlen) ml_enlist(&mq->mq_list, ml); else { dropped = ((ml)->ml_len); mq->mq_drops += dropped; } __mtx_leave(&mq->mq_mtx); if (dropped) { while ((m = ml_dequeue(ml)) != ((void *)0)) m_freem(m); } return (dropped); } void mq_delist(struct mbuf_queue *mq, struct mbuf_list *ml) { __mtx_enter(&mq->mq_mtx); *ml = mq->mq_list; ml_init(&mq->mq_list); __mtx_leave(&mq->mq_mtx); } struct mbuf * mq_dechain(struct mbuf_queue *mq) { struct mbuf *m0; __mtx_enter(&mq->mq_mtx); m0 = ml_dechain(&mq->mq_list); __mtx_leave(&mq->mq_mtx); return (m0); } unsigned int mq_purge(struct mbuf_queue *mq) { struct mbuf_list ml; mq_delist(mq, &ml); return (ml_purge(&ml)); } int sysctl_mq(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct mbuf_queue *mq) { unsigned int maxlen; int error; if (namelen != 1) return (20); switch (name[0]) { case 1: return (sysctl_rdint(oldp, oldlenp, newp, ((&(mq)->mq_list)->ml_len))); case 2: maxlen = mq->mq_maxlen; error = sysctl_int(oldp, oldlenp, newp, newlen, &maxlen); if (!error && maxlen != mq->mq_maxlen) { __mtx_enter(&mq->mq_mtx); mq->mq_maxlen = maxlen; __mtx_leave(&mq->mq_mtx); } return (error); case 3: return (sysctl_rdint(oldp, oldlenp, newp, ((mq)->mq_drops))); default: return (45); } } static struct mbuf *m_dup1(struct mbuf *, int, int, int); int __VERIFIER_nondet_bool(void); struct mbuf * m_pulldown(struct mbuf *m, int off, int len, int *offp) { struct mbuf *n, *o; int hlen, tlen, olen; int sharedcluster; if (m == ((void *)0)) panic("m == NULL in m_pulldown()"); if ((n = m_getptr(m, off, &off)) == ((void *)0)) { m_freem(m); return (((void *)0)); } sharedcluster = (((n)->m_hdr.mh_flags & 0x0001) != 0 && (((n)->m_hdr.mh_flags & 0x0008) == 0 || ((n)->M_dat.MH.MH_dat.MH_ext.ext_nextref != (n)))); if ((off == 0 || offp) && len <= n->m_hdr.mh_len - off && !sharedcluster) goto ok; if (len <= n->m_hdr.mh_len - off) { struct mbuf *mlast; o = m_dup1(n, off, n->m_hdr.mh_len - off, 0x0002); if (o == ((void *)0)) { m_freem(m); return (((void *)0)); } for (mlast = o; mlast->m_hdr.mh_next != ((void *)0); mlast = mlast->m_hdr.mh_next) ; n->m_hdr.mh_len = off; mlast->m_hdr.mh_next = n->m_hdr.mh_next; n->m_hdr.mh_next = o; n = o; off = 0; goto ok; } hlen = n->m_hdr.mh_len - off; tlen = len - hlen; olen = 0; for (o = n->m_hdr.mh_next; o != ((void *)0); o = o->m_hdr.mh_next) olen += o->m_hdr.mh_len; if (hlen + olen < len) { m_freem(m); return (((void *)0)); } if ((off == 0 || offp) && m_trailingspace(n) >= tlen && !sharedcluster) { m_copydata(n->m_hdr.mh_next, 0, tlen, ((caddr_t)((n)->m_hdr.mh_data)) + n->m_hdr.mh_len); n->m_hdr.mh_len += tlen; m_adj(n->m_hdr.mh_next, tlen); goto ok; } if ((off == 0 || offp) && m_leadingspace(n->m_hdr.mh_next) >= hlen && !sharedcluster && n->m_hdr.mh_next->m_hdr.mh_len >= tlen) { n->m_hdr.mh_next->m_hdr.mh_data -= hlen; n->m_hdr.mh_next->m_hdr.mh_len += hlen; __builtin_memmove((((caddr_t)((n->m_hdr.mh_next)->m_hdr.mh_data))), (((caddr_t)((n)->m_hdr.mh_data)) + off), (hlen)); n->m_hdr.mh_len -= hlen; n = n->m_hdr.mh_next; off = 0; goto ok; } if (len > (64 * 1024)) { m_freem(m); return (((void *)0)); } o = m_get((0x0002), (m->m_hdr.mh_type)); if (o && len > (256 - sizeof(struct m_hdr))) { m_clget((o), (0x0002), (len)); if ((o->m_hdr.mh_flags & 0x0001) == 0) { m_free(o); o = ((void *)0); } } if (!o) { m_freem(m); return (((void *)0)); } o->m_hdr.mh_len = hlen; __builtin_memmove((((caddr_t)((o)->m_hdr.mh_data))), (((caddr_t)((n)->m_hdr.mh_data)) + off), (hlen)); n->m_hdr.mh_len -= hlen; m_copydata(n->m_hdr.mh_next, 0, tlen, ((caddr_t)((o)->m_hdr.mh_data)) + o->m_hdr.mh_len); o->m_hdr.mh_len += tlen; m_adj(n->m_hdr.mh_next, tlen); o->m_hdr.mh_next = n->m_hdr.mh_next; n->m_hdr.mh_next = o; n = o; off = 0; ok: if (offp) *offp = off; return (n); } static struct mbuf * m_dup1(struct mbuf *m, int off, int len, int wait) { struct mbuf *n; int l; if (len > (64 * 1024)) return (((void *)0)); if (off == 0 && (m->m_hdr.mh_flags & 0x0002) != 0) { n = m_gethdr((wait), (m->m_hdr.mh_type)); if (n == ((void *)0)) return (((void *)0)); if (m_dup_pkthdr(n, m, wait)) { m_free(n); return (((void *)0)); } l = ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)); } else { n = m_get((wait), (m->m_hdr.mh_type)); l = (256 - sizeof(struct m_hdr)); } if (n && len > l) { m_clget((n), (wait), (len)); if ((n->m_hdr.mh_flags & 0x0001) == 0) { m_free(n); n = ((void *)0); } } if (!n) return (((void *)0)); m_copydata(m, off, len, ((caddr_t)((n)->m_hdr.mh_data))); n->m_hdr.mh_len = len; return (n); } struct m_tag * m_tag_get(int type, int len, int wait) { struct m_tag *t; if (len < 0) return (((void *)0)); if (len > 60) panic("requested tag size for pool %#x is too big", type); if (wait == 0x0002 && __VERIFIER_nondet_bool()) { return (((void *)0)); } t = malloc(sizeof(struct m_tag), 0, 0); t->m_tag_id = type; t->m_tag_len = len; return (t); } void m_tag_prepend(struct mbuf *m, struct m_tag *t) { do { (t)->m_tag_link.sle_next = (&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first; (&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first = (t); } while (0); m->M_dat.MH.MH_pkthdr.ph_tagsset |= t->m_tag_id; } void m_tag_delete(struct mbuf *m, struct m_tag *t) { u_int32_t ph_tagsset = 0; struct m_tag *p; do { if ((&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first == (t)) { do { ((&m->M_dat.MH.MH_pkthdr.ph_tags))->slh_first = ((&m->M_dat.MH.MH_pkthdr.ph_tags))->slh_first->m_tag_link.sle_next; } while (0); } else { struct m_tag *curelm = (&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first; while (curelm->m_tag_link.sle_next != (t)) curelm = curelm->m_tag_link.sle_next; curelm->m_tag_link.sle_next = curelm->m_tag_link.sle_next->m_tag_link.sle_next; } ((t)->m_tag_link.sle_next) = ((void *)-1); } while (0); free(t, 127, sizeof(struct m_tag)); for((p) = ((&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first); (p) != ((void *)0); (p) = ((p)->m_tag_link.sle_next)) ph_tagsset |= p->m_tag_id; m->M_dat.MH.MH_pkthdr.ph_tagsset = ph_tagsset; } void m_tag_delete_chain(struct mbuf *m) { struct m_tag *p; while ((p = ((&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first)) != ((void *)0)) { do { (&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first = (&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first->m_tag_link.sle_next; } while (0); free(p, 127, sizeof(struct m_tag)); } m->M_dat.MH.MH_pkthdr.ph_tagsset = 0; } struct m_tag * m_tag_find(struct mbuf *m, int type, struct m_tag *t) { struct m_tag *p; if (!(m->M_dat.MH.MH_pkthdr.ph_tagsset & type)) return (((void *)0)); if (t == ((void *)0)) p = ((&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first); else p = ((t)->m_tag_link.sle_next); while (p != ((void *)0)) { if (p->m_tag_id == type) return (p); p = ((p)->m_tag_link.sle_next); } return (((void *)0)); } struct m_tag * m_tag_copy(struct m_tag *t, int wait) { struct m_tag *p; p = m_tag_get(t->m_tag_id, t->m_tag_len, wait); if (p == ((void *)0)) return (((void *)0)); __builtin_memcpy((p + 1), (t + 1), (t->m_tag_len)); return (p); } int m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int wait) { struct m_tag *p, *t, *tprev = ((void *)0); m_tag_delete_chain(to); for((p) = ((&from->M_dat.MH.MH_pkthdr.ph_tags)->slh_first); (p) != ((void *)0); (p) = ((p)->m_tag_link.sle_next)) { t = m_tag_copy(p, wait); if (t == ((void *)0)) { m_tag_delete_chain(to); return (55); } if (tprev == ((void *)0)) do { (t)->m_tag_link.sle_next = (&to->M_dat.MH.MH_pkthdr.ph_tags)->slh_first; (&to->M_dat.MH.MH_pkthdr.ph_tags)->slh_first = (t); } while (0); else do { (t)->m_tag_link.sle_next = (tprev)->m_tag_link.sle_next; (tprev)->m_tag_link.sle_next = (t); } while (0); tprev = t; to->M_dat.MH.MH_pkthdr.ph_tagsset |= t->m_tag_id; } return (0); } void m_tag_init(struct mbuf *m) { { ((&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first) = ((void *)0); }; } struct m_tag * m_tag_first(struct mbuf *m) { return (((&m->M_dat.MH.MH_pkthdr.ph_tags)->slh_first)); } struct m_tag * m_tag_next(struct mbuf *m, struct m_tag *t) { return (((t)->m_tag_link.sle_next)); } void pool_init(struct pool *, size_t, u_int, int, int, const char *, struct pool_allocator *); void pool_destroy(struct pool *); void * pool_get(struct pool *, int); void pool_put(struct pool *, void *); int pool_prime(struct pool *, int); void pool_sethiwat(struct pool *, int); void pool_setlowat(struct pool *, int); int pool_sethardlimit(struct pool *, unsigned, const char *, int); void *pool_page_alloc(struct pool *, int, int *); void pool_page_free(struct pool *, void *); struct pool_allocator pool_allocator_single = { pool_page_alloc, pool_page_free, (((1 << 12)) | (1UL)) }; struct pool_allocator pool_allocator_multi = { pool_page_alloc, pool_page_free, (((1 << 12)) | (1UL)) }; struct pool_allocator pool_allocator_multi_ni = { pool_page_alloc, pool_page_free, (((1 << 12)) | (1UL)) }; void pool_init(struct pool *pool, size_t size, u_int align, int ipl, int flags, const char *wmesg, struct pool_allocator *palloc) { pool->pr_size = size; } void pool_destroy(struct pool *pp) { } void * pool_get(struct pool *pp, int flags) { void *v = ((void *)0); v = malloc(pp->pr_size,0,0); return (v); } void pool_put(struct pool *pp, void *item) { free(item); } int pool_prime(struct pool *pp, int nitems) { } void pool_sethiwat(struct pool *pp, int n) { } void pool_setlowat(struct pool *pp, int n) { } int pool_sethardlimit(struct pool *pp, unsigned n, const char *warnmess, int ratecap) { } void *pool_page_alloc(struct pool *pp, int a, int *b) {} void pool_page_free(struct pool *, void *a) {} struct winsize { unsigned short ws_row; unsigned short ws_col; unsigned short ws_xpixel; unsigned short ws_ypixel; }; struct tstamps { int ts_set; int ts_clr; }; struct ifnet; struct ifq_ops; struct ifqueue { struct ifnet *ifq_if; union { void *_ifq_softc; struct ifqueue *_ifq_ifqs[1]; } _ifq_ptr; struct mutex ifq_mtx; const struct ifq_ops *ifq_ops; void *ifq_q; struct mbuf_list ifq_free; unsigned int ifq_len; unsigned int ifq_oactive; uint64_t ifq_packets; uint64_t ifq_bytes; uint64_t ifq_qdrops; uint64_t ifq_errors; uint64_t ifq_mcasts; struct mutex ifq_task_mtx; struct task_list ifq_task_list; void *ifq_serializer; struct task ifq_start; struct task ifq_restart; unsigned int ifq_maxlen; unsigned int ifq_idx; }; struct ifiqueue { struct ifnet *ifiq_if; struct taskq *ifiq_softnet; union { void *_ifiq_softc; struct ifiqueue *_ifiq_ifiqs[1]; } _ifiq_ptr; struct mutex ifiq_mtx; struct mbuf_list ifiq_ml; struct task ifiq_task; uint64_t ifiq_packets; uint64_t ifiq_bytes; uint64_t ifiq_qdrops; uint64_t ifiq_errors; uint64_t ifiq_mcasts; uint64_t ifiq_noproto; unsigned int ifiq_idx; }; struct ifq_ops { unsigned int (*ifqop_idx)(unsigned int, const struct mbuf *); struct mbuf *(*ifqop_enq)(struct ifqueue *, struct mbuf *); struct mbuf *(*ifqop_deq_begin)(struct ifqueue *, void **); void (*ifqop_deq_commit)(struct ifqueue *, struct mbuf *, void *); void (*ifqop_purge)(struct ifqueue *, struct mbuf_list *); void *(*ifqop_alloc)(unsigned int, void *); void (*ifqop_free)(unsigned int, void *); }; void ifq_init(struct ifqueue *, struct ifnet *, unsigned int); void ifq_attach(struct ifqueue *, const struct ifq_ops *, void *); void ifq_destroy(struct ifqueue *); void ifq_add_data(struct ifqueue *, struct if_data *); int ifq_enqueue(struct ifqueue *, struct mbuf *); struct mbuf *ifq_deq_begin(struct ifqueue *); void ifq_deq_commit(struct ifqueue *, struct mbuf *); void ifq_deq_rollback(struct ifqueue *, struct mbuf *); struct mbuf *ifq_dequeue(struct ifqueue *); void ifq_mfreem(struct ifqueue *, struct mbuf *); void ifq_mfreeml(struct ifqueue *, struct mbuf_list *); unsigned int ifq_purge(struct ifqueue *); void *ifq_q_enter(struct ifqueue *, const struct ifq_ops *); void ifq_q_leave(struct ifqueue *, void *); void ifq_serialize(struct ifqueue *, struct task *); int ifq_is_serialized(struct ifqueue *); void ifq_barrier(struct ifqueue *); static inline void ifq_set_oactive(struct ifqueue *ifq) { ifq->ifq_oactive = 1; } static inline void ifq_clr_oactive(struct ifqueue *ifq) { ifq->ifq_oactive = 0; } static inline unsigned int ifq_is_oactive(struct ifqueue *ifq) { return (ifq->ifq_oactive); } static inline void ifq_start(struct ifqueue *ifq) { ifq_serialize(ifq, &ifq->ifq_start); } static inline void ifq_restart(struct ifqueue *ifq) { ifq_serialize(ifq, &ifq->ifq_restart); } static inline unsigned int ifq_idx(struct ifqueue *ifq, unsigned int nifqs, const struct mbuf *m) { return ((*ifq->ifq_ops->ifqop_idx)(nifqs, m)); } extern const struct ifq_ops * const ifq_priq_ops; void ifiq_init(struct ifiqueue *, struct ifnet *, unsigned int); void ifiq_destroy(struct ifiqueue *); int ifiq_input(struct ifiqueue *, struct mbuf_list *, unsigned int); int ifiq_enqueue(struct ifiqueue *, struct mbuf *); void ifiq_add_data(struct ifiqueue *, struct if_data *); void ifiq_barrier(struct ifiqueue *); struct rtentry; struct ifnet; struct task; struct if_clone { struct { struct if_clone *le_next; struct if_clone **le_prev; } ifc_list; const char *ifc_name; size_t ifc_namelen; int (*ifc_create)(struct if_clone *, int); int (*ifc_destroy)(struct ifnet *); }; struct ifnet_head { struct ifnet *tqh_first; struct ifnet **tqh_last; }; struct ifnet { void *if_softc; struct refcnt if_refcnt; struct { struct ifnet *tqe_next; struct ifnet **tqe_prev; } if_list; struct { struct ifaddr *tqh_first; struct ifaddr **tqh_last; } if_addrlist; struct { struct ifmaddr *tqh_first; struct ifmaddr **tqh_last; } if_maddrlist; struct { struct ifg_list *tqh_first; struct ifg_list **tqh_last; } if_groups; struct hook_desc_head *if_addrhooks; struct hook_desc_head *if_linkstatehooks; struct hook_desc_head *if_detachhooks; void (*if_rtrequest)(struct ifnet *, int, struct rtentry *); char if_xname[16]; int if_pcount; caddr_t if_bpf; caddr_t if_bridgeport; caddr_t if_switchport; caddr_t if_mcast; caddr_t if_mcast6; caddr_t if_pf_kif; union { struct srpl carp_s; struct ifnet *carp_d; } if_carp_ptr; unsigned int if_index; short if_timer; unsigned short if_flags; int if_xflags; struct if_data if_data; uint32_t if_hardmtu; char if_description[64]; u_short if_rtlabelid; uint8_t if_priority; uint8_t if_llprio; struct timeout if_slowtimo; struct task if_watchdogtask; struct task if_linkstatetask; struct srpl if_inputs; int (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int (*if_ll_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); void (*if_start)(struct ifnet *); int (*if_ioctl)(struct ifnet *, u_long, caddr_t); void (*if_watchdog)(struct ifnet *); int (*if_wol)(struct ifnet *, int); struct ifqueue if_snd; struct ifqueue **if_ifqs; void (*if_qstart)(struct ifqueue *); unsigned int if_nifqs; struct ifiqueue if_rcv; struct ifiqueue **if_iqs; unsigned int if_niqs; struct sockaddr_dl *if_sadl; void *if_afdata[36]; }; struct ifaddr { struct sockaddr *ifa_addr; struct sockaddr *ifa_dstaddr; struct sockaddr *ifa_netmask; struct ifnet *ifa_ifp; struct { struct ifaddr *tqe_next; struct ifaddr **tqe_prev; } ifa_list; u_int ifa_flags; u_int ifa_refcnt; int ifa_metric; }; struct ifmaddr { struct sockaddr *ifma_addr; unsigned int ifma_ifidx; unsigned int ifma_refcnt; struct { struct ifmaddr *tqe_next; struct ifmaddr **tqe_prev; } ifma_list; }; struct ifg_group { char ifg_group[16]; u_int ifg_refcnt; caddr_t ifg_pf_kif; int ifg_carp_demoted; struct { struct ifg_member *tqh_first; struct ifg_member **tqh_last; } ifg_members; struct { struct ifg_group *tqe_next; struct ifg_group **tqe_prev; } ifg_next; }; struct ifg_member { struct { struct ifg_member *tqe_next; struct ifg_member **tqe_prev; } ifgm_next; struct ifnet *ifgm_ifp; }; struct ifg_list { struct ifg_group *ifgl_group; struct { struct ifg_list *tqe_next; struct ifg_list **tqe_prev; } ifgl_next; }; struct niqueue { struct mbuf_queue ni_q; u_int ni_isr; }; void niq_init(struct niqueue *, u_int, u_int); int niq_enqueue(struct niqueue *, struct mbuf *); int niq_enlist(struct niqueue *, struct mbuf_list *); extern struct ifnet_head ifnet; void if_start(struct ifnet *); int if_enqueue_try(struct ifnet *, struct mbuf *); int if_enqueue(struct ifnet *, struct mbuf *); void if_input(struct ifnet *, struct mbuf_list *); void if_input_process(struct ifnet *, struct mbuf_list *); int if_input_local(struct ifnet *, struct mbuf *, sa_family_t); int if_output_local(struct ifnet *, struct mbuf *, sa_family_t); void if_rtrequest_dummy(struct ifnet *, int, struct rtentry *); void p2p_rtrequest(struct ifnet *, int, struct rtentry *); struct ifaddr *ifa_ifwithaddr(struct sockaddr *, u_int); struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *, u_int); struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); void ifafree(struct ifaddr *); int if_isconnected(const struct ifnet *, unsigned int); void if_clone_attach(struct if_clone *); void if_clone_detach(struct if_clone *); int if_clone_create(const char *, int); int if_clone_destroy(const char *); struct if_clone * if_clone_lookup(const char *, int *); void ifa_add(struct ifnet *, struct ifaddr *); void ifa_del(struct ifnet *, struct ifaddr *); void ifa_update_broadaddr(struct ifnet *, struct ifaddr *, struct sockaddr *); void if_ih_insert(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, void *), void *); void if_ih_remove(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, void *), void *); void if_rxr_livelocked(struct if_rxring *); void if_rxr_init(struct if_rxring *, u_int, u_int); u_int if_rxr_get(struct if_rxring *, u_int); int if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *); int if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int, struct if_rxring *); struct sockaddr_dl { u_char sdl_len; u_char sdl_family; u_int16_t sdl_index; u_char sdl_type; u_char sdl_nlen; u_char sdl_alen; u_char sdl_slen; char sdl_data[24]; }; static inline struct sockaddr_dl * satosdl(struct sockaddr *sa) { return ((struct sockaddr_dl *)(sa)); } static inline struct sockaddr * sdltosa(struct sockaddr_dl *sdl) { return ((struct sockaddr *)(sdl)); } struct ifnet; typedef int (*ifm_change_cb_t)(struct ifnet *); typedef void (*ifm_stat_cb_t)(struct ifnet *, struct ifmediareq *); struct ifmedia_entry { struct { struct ifmedia_entry *tqe_next; struct ifmedia_entry **tqe_prev; } ifm_list; uint64_t ifm_media; u_int ifm_data; void *ifm_aux; }; struct ifmedia { uint64_t ifm_mask; uint64_t ifm_media; struct ifmedia_entry *ifm_cur; struct { struct ifmedia_entry *tqh_first; struct ifmedia_entry **tqh_last; } ifm_list; ifm_change_cb_t ifm_change; ifm_stat_cb_t ifm_status; }; void ifmedia_init(struct ifmedia *, uint64_t, ifm_change_cb_t, ifm_stat_cb_t); void ifmedia_add(struct ifmedia *, uint64_t, int, void *); void ifmedia_list_add(struct ifmedia *, struct ifmedia_entry *, int); void ifmedia_set(struct ifmedia *, uint64_t); int ifmedia_ioctl(struct ifnet *, struct ifreq *, struct ifmedia *, u_long); struct ifmedia_entry *ifmedia_match(struct ifmedia *, uint64_t, uint64_t); void ifmedia_delete_instance(struct ifmedia *, uint64_t); uint64_t ifmedia_baudrate(uint64_t); struct ifmedia_description { uint64_t ifmt_word; const char *ifmt_string; }; struct ifmedia_baudrate { uint64_t ifmb_word; uint64_t ifmb_baudrate; }; struct ifmedia_status_description { uint64_t ifms_type; uint64_t ifms_valid; uint64_t ifms_bit; const char *ifms_string[2]; }; struct ip { u_int ip_hl:4, ip_v:4; u_int8_t ip_tos; u_int16_t ip_len; u_int16_t ip_id; u_int16_t ip_off; u_int8_t ip_ttl; u_int8_t ip_p; u_int16_t ip_sum; struct in_addr ip_src, ip_dst; }; struct ip_timestamp { u_int8_t ipt_code; u_int8_t ipt_len; u_int8_t ipt_ptr; u_int ipt_flg:4, ipt_oflw:4; union ipt_timestamp { u_int32_t ipt_time[1]; struct ipt_ta { struct in_addr ipt_addr; u_int32_t ipt_time; } ipt_ta[1]; } ipt_timestamp; }; struct ippseudo { struct in_addr ippseudo_src; struct in_addr ippseudo_dst; u_int8_t ippseudo_pad; u_int8_t ippseudo_p; u_int16_t ippseudo_len; }; struct ipovly { u_int8_t ih_x1[9]; u_int8_t ih_pr; u_int16_t ih_len; struct in_addr ih_src; struct in_addr ih_dst; }; struct ipstat { u_long ips_total; u_long ips_badsum; u_long ips_tooshort; u_long ips_toosmall; u_long ips_badhlen; u_long ips_badlen; u_long ips_fragments; u_long ips_fragdropped; u_long ips_fragtimeout; u_long ips_forward; u_long ips_cantforward; u_long ips_redirectsent; u_long ips_noproto; u_long ips_delivered; u_long ips_localout; u_long ips_odropped; u_long ips_reassembled; u_long ips_fragmented; u_long ips_ofragments; u_long ips_cantfrag; u_long ips_badoptions; u_long ips_noroute; u_long ips_badvers; u_long ips_rawout; u_long ips_badfrags; u_long ips_rcvmemdrop; u_long ips_toolong; u_long ips_nogif; u_long ips_badaddr; u_long ips_inswcsum; u_long ips_outswcsum; u_long ips_notmember; }; struct ipoption { struct in_addr ipopt_dst; int8_t ipopt_list[40]; }; enum ipstat_counters { ips_total, ips_badsum, ips_tooshort, ips_toosmall, ips_badhlen, ips_badlen, ips_fragments, ips_fragdropped, ips_fragtimeout, ips_forward, ips_cantforward, ips_redirectsent, ips_noproto, ips_delivered, ips_localout, ips_odropped, ips_reassembled, ips_fragmented, ips_ofragments, ips_cantfrag, ips_badoptions, ips_noroute, ips_badvers, ips_rawout, ips_badfrags, ips_rcvmemdrop, ips_toolong, ips_nogif, ips_badaddr, ips_inswcsum, ips_outswcsum, ips_notmember, ips_ncounters }; extern struct cpumem *ipcounters; static inline void ipstat_inc(enum ipstat_counters c) { counters_inc(ipcounters, c); } struct ip_moptions { struct in_multi **imo_membership; unsigned short imo_ifidx; u_int8_t imo_ttl; u_int8_t imo_loop; u_int16_t imo_num_memberships; u_int16_t imo_max_memberships; }; struct ipqehead { struct ipqent *lh_first; }; struct ipqent { struct { struct ipqent *le_next; struct ipqent **le_prev; } ipqe_q; struct ip *ipqe_ip; struct mbuf *ipqe_m; u_int8_t ipqe_mff; }; struct ipq { struct { struct ipq *le_next; struct ipq **le_prev; } ipq_q; u_int8_t ipq_ttl; u_int8_t ipq_p; u_int16_t ipq_id; struct ipqehead ipq_fragq; struct in_addr ipq_src, ipq_dst; }; extern struct ipstat ipstat; extern int ip_defttl; extern int ip_mtudisc; extern u_int ip_mtudisc_timeout; extern int ipport_firstauto; extern int ipport_lastauto; extern int ipport_hifirstauto; extern int ipport_hilastauto; extern int ipforwarding; extern int ipmforwarding; extern int ipmultipath; extern int la_hold_total; extern struct rttimer_queue *ip_mtudisc_timeout_q; extern struct pool ipqent_pool; struct route; struct inpcb; int ip_ctloutput(int, struct socket *, int, int, struct mbuf *); void ip_flush(void); int ip_fragment(struct mbuf *, struct ifnet *, u_long); void ip_freef(struct ipq *); void ip_freemoptions(struct ip_moptions *); int ip_getmoptions(int, struct ip_moptions *, struct mbuf *); void ip_init(void); struct mbuf* ip_insertoptions(struct mbuf *, struct mbuf *, int *); int ip_mforward(struct mbuf *, struct ifnet *); int ip_optcopy(struct ip *, struct ip *); int ip_output(struct mbuf *, struct mbuf *, struct route *, int, struct ip_moptions *, struct inpcb *, u_int32_t); struct mbuf * ip_reass(struct ipqent *, struct ipq *); u_int16_t ip_randomid(void); void ip_send(struct mbuf *); void ip_slowtimo(void); struct mbuf * ip_srcroute(struct mbuf *); void ip_stripoptions(struct mbuf *); int ip_sysctl(int *, u_int, void *, size_t *, void *, size_t); void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *, struct mbuf *); void ipintr(void); int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *); int ip_deliver(struct mbuf **, int *, int, int); void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int); int rip_ctloutput(int, struct socket *, int, int, struct mbuf *); void rip_init(void); int rip_input(struct mbuf **, int *, int, int); int rip_output(struct mbuf *, struct socket *, struct sockaddr *, struct mbuf *); int rip_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int rip_attach(struct socket *, int); int rip_detach(struct socket *); extern struct socket *ip_mrouter[]; struct ether_addr { u_int8_t ether_addr_octet[6]; }; struct ether_header { u_int8_t ether_dhost[6]; u_int8_t ether_shost[6]; u_int16_t ether_type; }; struct ether_vlan_header { u_char evl_dhost[6]; u_char evl_shost[6]; u_int16_t evl_encap_proto; u_int16_t evl_tag; u_int16_t evl_proto; }; struct ether_arp { struct arphdr ea_hdr; u_int8_t arp_sha[6]; u_int8_t arp_spa[4]; u_int8_t arp_tha[6]; u_int8_t arp_tpa[4]; }; struct sockaddr_inarp { u_int8_t sin_len; u_int8_t sin_family; u_int16_t sin_port; struct in_addr sin_addr; struct in_addr sin_srcaddr; u_int16_t sin_tos; u_int16_t sin_other; }; struct arpcom { struct ifnet ac_if; u_int8_t ac_enaddr[6]; char ac__pad[2]; struct { struct ether_multi *lh_first; } ac_multiaddrs; int ac_multicnt; int ac_multirangecnt; }; extern int arpt_keep; extern int arpt_down; extern u_int8_t etherbroadcastaddr[6]; extern u_int8_t etheranyaddr[6]; extern u_int8_t ether_ipmulticast_min[6]; extern u_int8_t ether_ipmulticast_max[6]; extern unsigned int revarp_ifidx; void revarpinput(struct ifnet *, struct mbuf *); void revarprequest(struct ifnet *); int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *); int revarpwhoami(struct in_addr *, struct ifnet *); void arpinput(struct ifnet *, struct mbuf *); void arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *); void arpwhohas(struct arpcom *, struct in_addr *); int arpproxy(struct in_addr, unsigned int); int arpresolve(struct ifnet *, struct rtentry *, struct mbuf *, struct sockaddr *, u_char *); void arp_rtrequest(struct ifnet *, int, struct rtentry *); void ether_fakeaddr(struct ifnet *); int ether_addmulti(struct ifreq *, struct arpcom *); int ether_delmulti(struct ifreq *, struct arpcom *); int ether_multiaddr(struct sockaddr *, u_int8_t[], u_int8_t[]); void ether_ifattach(struct ifnet *); void ether_ifdetach(struct ifnet *); int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t); int ether_input(struct ifnet *, struct mbuf *, void *); int ether_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); void ether_rtrequest(struct ifnet *, int, struct rtentry *); char *ether_sprintf(u_char *); struct ether_multi { u_int8_t enm_addrlo[6]; u_int8_t enm_addrhi[6]; u_int enm_refcount; struct { struct ether_multi *le_next; struct ether_multi **le_prev; } enm_list; }; struct ether_multistep { struct ether_multi *e_enm; }; u_int32_t ether_crc32_le_update(u_int32_t crc, const u_int8_t *, size_t); u_int32_t ether_crc32_be_update(u_int32_t crc, const u_int8_t *, size_t); u_int32_t ether_crc32_le(const u_int8_t *, size_t); u_int32_t ether_crc32_be(const u_int8_t *, size_t); struct etheripstat { u_int64_t etherips_hdrops; u_int64_t etherips_qfull; u_int64_t etherips_noifdrops; u_int64_t etherips_pdrops; u_int64_t etherips_adrops; u_int64_t etherips_ipackets; u_int64_t etherips_opackets; u_int64_t etherips_ibytes; u_int64_t etherips_obytes; }; struct etherip_header { u_int eip_res:4; u_int eip_ver:4; u_int8_t eip_pad; } __attribute__((__packed__)); enum etheripstat_counters { etherips_hdrops, etherips_qfull, etherips_noifdrops, etherips_pdrops, etherips_adrops, etherips_ipackets, etherips_opackets, etherips_ibytes, etherips_obytes, etherips_ncounters }; extern struct cpumem *etheripcounters; static inline void etheripstat_inc(enum etheripstat_counters c) { counters_inc(etheripcounters, c); } static inline void etheripstat_add(enum etheripstat_counters c, uint64_t v) { counters_add(etheripcounters, c, v); } static inline void etheripstat_pkt(enum etheripstat_counters pcounter, enum etheripstat_counters bcounter, uint64_t v) { counters_pkt(etheripcounters, pcounter, bcounter, v); } struct tdb; struct ip6_hdr { union { struct ip6_hdrctl { u_int32_t ip6_un1_flow; u_int16_t ip6_un1_plen; u_int8_t ip6_un1_nxt; u_int8_t ip6_un1_hlim; } ip6_un1; u_int8_t ip6_un2_vfc; } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; } __attribute__((__packed__)); struct ip6_hdr_pseudo { struct in6_addr ip6ph_src; struct in6_addr ip6ph_dst; u_int32_t ip6ph_len; u_int8_t ip6ph_zero[3]; u_int8_t ip6ph_nxt; } __attribute__((__packed__)); struct ip6_ext { u_int8_t ip6e_nxt; u_int8_t ip6e_len; } __attribute__((__packed__)); struct ip6_hbh { u_int8_t ip6h_nxt; u_int8_t ip6h_len; } __attribute__((__packed__)); struct ip6_dest { u_int8_t ip6d_nxt; u_int8_t ip6d_len; } __attribute__((__packed__)); struct ip6_opt { u_int8_t ip6o_type; u_int8_t ip6o_len; } __attribute__((__packed__)); struct ip6_opt_jumbo { u_int8_t ip6oj_type; u_int8_t ip6oj_len; u_int8_t ip6oj_jumbo_len[4]; } __attribute__((__packed__)); struct ip6_opt_nsap { u_int8_t ip6on_type; u_int8_t ip6on_len; u_int8_t ip6on_src_nsap_len; u_int8_t ip6on_dst_nsap_len; } __attribute__((__packed__)); struct ip6_opt_tunnel { u_int8_t ip6ot_type; u_int8_t ip6ot_len; u_int8_t ip6ot_encap_limit; } __attribute__((__packed__)); struct ip6_opt_router { u_int8_t ip6or_type; u_int8_t ip6or_len; u_int8_t ip6or_value[2]; } __attribute__((__packed__)); struct ip6_rthdr { u_int8_t ip6r_nxt; u_int8_t ip6r_len; u_int8_t ip6r_type; u_int8_t ip6r_segleft; } __attribute__((__packed__)); struct ip6_rthdr0 { u_int8_t ip6r0_nxt; u_int8_t ip6r0_len; u_int8_t ip6r0_type; u_int8_t ip6r0_segleft; u_int32_t ip6r0_reserved; } __attribute__((__packed__)); struct ip6_frag { u_int8_t ip6f_nxt; u_int8_t ip6f_reserved; u_int16_t ip6f_offlg; u_int32_t ip6f_ident; } __attribute__((__packed__)); struct ip6q { struct { struct ip6q *tqe_next; struct ip6q **tqe_prev; } ip6q_queue; struct ip6asfrag_list { struct ip6asfrag *lh_first; } ip6q_asfrag; struct in6_addr ip6q_src, ip6q_dst; int ip6q_unfrglen; int ip6q_nfrag; u_int32_t ip6q_ident; u_int8_t ip6q_nxt; u_int8_t ip6q_ttl; }; struct ip6asfrag { struct { struct ip6asfrag *le_next; struct ip6asfrag **le_prev; } ip6af_list; struct mbuf *ip6af_m; int ip6af_offset; int ip6af_frglen; int ip6af_off; u_int32_t ip6af_flow; u_int16_t ip6af_mff; }; struct ip6_moptions { struct { struct in6_multi_mship *lh_first; } im6o_memberships; unsigned short im6o_ifidx; u_char im6o_hlim; u_char im6o_loop; }; struct ip6po_rhinfo { struct ip6_rthdr *ip6po_rhi_rthdr; struct route_in6 ip6po_rhi_route; }; struct ip6_pktopts { int ip6po_hlim; struct in6_pktinfo *ip6po_pktinfo; struct ip6_hbh *ip6po_hbh; struct ip6_dest *ip6po_dest1; struct ip6po_rhinfo ip6po_rhinfo; struct ip6_dest *ip6po_dest2; int ip6po_tclass; int ip6po_minmtu; int ip6po_flags; }; struct ip6stat { u_int64_t ip6s_total; u_int64_t ip6s_tooshort; u_int64_t ip6s_toosmall; u_int64_t ip6s_fragments; u_int64_t ip6s_fragdropped; u_int64_t ip6s_fragtimeout; u_int64_t ip6s_fragoverflow; u_int64_t ip6s_forward; u_int64_t ip6s_cantforward; u_int64_t ip6s_redirectsent; u_int64_t ip6s_delivered; u_int64_t ip6s_localout; u_int64_t ip6s_odropped; u_int64_t ip6s_reassembled; u_int64_t ip6s_fragmented; u_int64_t ip6s_ofragments; u_int64_t ip6s_cantfrag; u_int64_t ip6s_badoptions; u_int64_t ip6s_noroute; u_int64_t ip6s_badvers; u_int64_t ip6s_rawout; u_int64_t ip6s_badscope; u_int64_t ip6s_notmember; u_int64_t ip6s_nxthist[256]; u_int64_t ip6s_m1; u_int64_t ip6s_m2m[32]; u_int64_t ip6s_mext1; u_int64_t ip6s_mext2m; u_int64_t ip6s_nogif; u_int64_t ip6s_toomanyhdr; u_int64_t ip6s_sources_none; u_int64_t ip6s_sources_sameif[16]; u_int64_t ip6s_sources_otherif[16]; u_int64_t ip6s_sources_samescope[16]; u_int64_t ip6s_sources_otherscope[16]; u_int64_t ip6s_sources_deprecated[16]; u_int64_t ip6s_forward_cachehit; u_int64_t ip6s_forward_cachemiss; }; enum ip6stat_counters { ip6s_total, ip6s_tooshort, ip6s_toosmall, ip6s_fragments, ip6s_fragdropped, ip6s_fragtimeout, ip6s_fragoverflow, ip6s_forward, ip6s_cantforward, ip6s_redirectsent, ip6s_delivered, ip6s_localout, ip6s_odropped, ip6s_reassembled, ip6s_fragmented, ip6s_ofragments, ip6s_cantfrag, ip6s_badoptions, ip6s_noroute, ip6s_badvers, ip6s_rawout, ip6s_badscope, ip6s_notmember, ip6s_nxthist, ip6s_m1 = ip6s_nxthist + 256, ip6s_m2m, ip6s_mext1 = ip6s_m2m + 32, ip6s_mext2m, ip6s_nogif, ip6s_toomanyhdr, ip6s_sources_none, ip6s_sources_sameif, ip6s_sources_otherif = ip6s_sources_sameif + 16, ip6s_sources_samescope = ip6s_sources_otherif + 16, ip6s_sources_otherscope = ip6s_sources_samescope + 16, ip6s_sources_deprecated = ip6s_sources_otherscope + 16, ip6s_forward_cachehit = ip6s_sources_deprecated + 16, ip6s_forward_cachemiss, ip6s_ncounters, }; extern struct cpumem *ip6counters; static inline void ip6stat_inc(enum ip6stat_counters c) { counters_inc(ip6counters, c); } static inline void ip6stat_add(enum ip6stat_counters c, uint64_t v) { counters_add(ip6counters, c, v); } extern int ip6_mtudisc_timeout; extern struct rttimer_queue *icmp6_mtudisc_timeout_q; extern int ip6_defhlim; extern int ip6_defmcasthlim; extern int ip6_forwarding; extern int ip6_mforwarding; extern int ip6_multipath; extern int ip6_sendredirect; extern int ip6_use_deprecated; extern int ip6_mcast_pmtu; extern int ip6_neighborgcthresh; extern int ip6_maxdynroutes; extern struct socket *ip6_mrouter[255]; extern int ip6_sendredirects; extern int ip6_maxfragpackets; extern int ip6_maxfrags; extern int ip6_log_interval; extern time_t ip6_log_time; extern int ip6_hdrnestlimit; extern int ip6_dad_count; extern int ip6_dad_pending; extern int ip6_auto_flowlabel; extern int ip6_auto_linklocal; struct in6pcb; struct inpcb; int icmp6_ctloutput(int, struct socket *, int, int, struct mbuf *); void ip6_init(void); void ip6intr(void); int ip6_input_if(struct mbuf **, int *, int, int, struct ifnet *); void ip6_freepcbopts(struct ip6_pktopts *); void ip6_freemoptions(struct ip6_moptions *); int ip6_unknown_opt(u_int8_t *, struct mbuf *, int); int ip6_get_prevhdr(struct mbuf *, int); int ip6_nexthdr(struct mbuf *, int, int, int *); int ip6_lasthdr(struct mbuf *, int, int, int *); int ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *); int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, u_int32_t *); void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); void ip6_forward(struct mbuf *, struct rtentry *, int); void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route_in6 *, int, struct ip6_moptions *, struct inpcb *); int ip6_fragment(struct mbuf *, int, u_char, u_long); int ip6_ctloutput(int, struct socket *, int, int, struct mbuf *); int ip6_raw_ctloutput(int, struct socket *, int, int, struct mbuf *); void ip6_initpktopts(struct ip6_pktopts *); int ip6_setpktopts(struct mbuf *, struct ip6_pktopts *, struct ip6_pktopts *, int, int); void ip6_clearpktopts(struct ip6_pktopts *, int); void ip6_randomid_init(void); u_int32_t ip6_randomid(void); void ip6_send(struct mbuf *); int route6_input(struct mbuf **, int *, int, int); void frag6_init(void); int frag6_input(struct mbuf **, int *, int, int); int frag6_deletefraghdr(struct mbuf *, int); void frag6_slowtimo(void); void rip6_init(void); int rip6_input(struct mbuf **, int *, int, int); void rip6_ctlinput(int, struct sockaddr *, u_int, void *); int rip6_ctloutput(int, struct socket *, int, int, struct mbuf *); int rip6_output(struct mbuf *, struct socket *, struct sockaddr *, struct mbuf *); int rip6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int rip6_attach(struct socket *, int); int rip6_detach(struct socket *); int rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); int dest6_input(struct mbuf **, int *, int, int); int none_input(struct mbuf **, int *, int); int in6_pcbselsrc(struct in6_addr **, struct sockaddr_in6 *, struct inpcb *, struct ip6_pktopts *); int in6_selectsrc(struct in6_addr **, struct sockaddr_in6 *, struct ip6_moptions *, unsigned int); struct rtentry *in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct route_in6 *, unsigned int rtableid); u_int32_t ip6_randomflowlabel(void); typedef int32_t bpf_int32; typedef u_int32_t bpf_u_int32; struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; struct bpf_stat { u_int bs_recv; u_int bs_drop; }; struct bpf_version { u_short bv_major; u_short bv_minor; }; struct bpf_timeval { u_int32_t tv_sec; u_int32_t tv_usec; }; struct bpf_hdr { struct bpf_timeval bh_tstamp; u_int32_t bh_caplen; u_int32_t bh_datalen; u_int16_t bh_hdrlen; }; struct bpf_insn { u_int16_t code; u_char jt; u_char jf; u_int32_t k; }; struct bpf_dltlist { u_int bfl_len; u_int *bfl_list; }; struct bpf_ops { u_int32_t (*ldw)(const void *, u_int32_t, int *); u_int32_t (*ldh)(const void *, u_int32_t, int *); u_int32_t (*ldb)(const void *, u_int32_t, int *); }; u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int) ; u_int _bpf_filter(const struct bpf_insn *, const struct bpf_ops *, const void *, u_int); struct ifnet; struct mbuf; int bpf_validate(struct bpf_insn *, int); int bpf_mtap(caddr_t, const struct mbuf *, u_int); int bpf_mtap_hdr(caddr_t, caddr_t, u_int, const struct mbuf *, u_int, void (*)(const void *, void *, size_t)); int bpf_mtap_af(caddr_t, u_int32_t, const struct mbuf *, u_int); int bpf_mtap_ether(caddr_t, const struct mbuf *, u_int); int bpf_tap_hdr(caddr_t, const void *, u_int, const void *, u_int, u_int); void bpfattach(caddr_t *, struct ifnet *, u_int, u_int); void bpfdetach(struct ifnet *); void *bpfsattach(caddr_t *, const char *, u_int, u_int); void bpfsdetach(void *); void bpfilterattach(int); u_int bpf_mfilter(const struct bpf_insn *, const struct mbuf *, u_int); int etherip_sysctl(int *, uint, void *, size_t *, void *, size_t); int ip_etherip_output(struct ifnet *, struct mbuf *); int ip_etherip_input(struct mbuf **, int *, int, int); int ip6_etherip_output(struct ifnet *, struct mbuf *); int ip6_etherip_input(struct mbuf **, int *, int, int); struct etherip_softc { struct arpcom sc_ac; struct ifmedia sc_media; unsigned int sc_rdomain; struct sockaddr_storage sc_src; struct sockaddr_storage sc_dst; struct { struct etherip_softc *le_next; struct etherip_softc **le_prev; } sc_entry; }; struct { struct etherip_softc *lh_first; } etherip_softc_list; int etherip_allow = 0; struct cpumem *etheripcounters; void etheripattach(int); int etherip_clone_create(struct if_clone *, int); int etherip_clone_destroy(struct ifnet *); int etherip_ioctl(struct ifnet *, u_long, caddr_t); void etherip_start(struct ifnet *); int etherip_media_change(struct ifnet *); void etherip_media_status(struct ifnet *, struct ifmediareq *); int etherip_set_tunnel_addr(struct ifnet *, struct sockaddr_storage *, struct sockaddr_storage *); struct if_clone etherip_cloner = { .ifc_list = { ((void *)0), ((void *)0) }, .ifc_name = "etherip", .ifc_namelen = sizeof("etherip") - 1, .ifc_create = etherip_clone_create, .ifc_destroy = etherip_clone_destroy, }; void etheripattach(int count) { if_clone_attach(ðerip_cloner); etheripcounters = counters_alloc(etherips_ncounters); } int etherip_clone_create(struct if_clone *ifc, int unit) { struct ifnet *ifp; struct etherip_softc *sc; sc = malloc(sizeof(*sc), 2, 0x0001|0x0008); ifp = &sc->sc_ac.ac_if; snprintf(ifp->if_xname, sizeof ifp->if_xname, "etherip%d", unit); ifp->if_flags = 0x2 | 0x800 | 0x8000; ether_fakeaddr(ifp); ifp->if_softc = sc; ifp->if_ioctl = etherip_ioctl; ifp->if_start = etherip_start; ifp->if_xflags = 0x2; ((&ifp->if_snd)->ifq_maxlen = (256)); ifp->if_data.ifi_capabilities = 0x00000010; ifmedia_init(&sc->sc_media, 0, etherip_media_change, etherip_media_status); ifmedia_add(&sc->sc_media, 0x0000000000000100ULL | 0ULL, 0, ((void *)0)); ifmedia_set(&sc->sc_media, 0x0000000000000100ULL | 0ULL); if_attach(ifp); ether_ifattach(ifp); do { if (((sc)->sc_entry.le_next = (ðerip_softc_list)->lh_first) != ((void *)0)) (ðerip_softc_list)->lh_first->sc_entry.le_prev = &(sc)->sc_entry.le_next; (ðerip_softc_list)->lh_first = (sc); (sc)->sc_entry.le_prev = &(ðerip_softc_list)->lh_first; } while (0); return 0; } int etherip_clone_destroy(struct ifnet *ifp) { struct etherip_softc *sc = ifp->if_softc; do { if ((sc)->sc_entry.le_next != ((void *)0)) (sc)->sc_entry.le_next->sc_entry.le_prev = (sc)->sc_entry.le_prev; *(sc)->sc_entry.le_prev = (sc)->sc_entry.le_next; ((sc)->sc_entry.le_prev) = ((void *)-1); ((sc)->sc_entry.le_next) = ((void *)-1); } while (0); ifmedia_delete_instance(&sc->sc_media, ((uint64_t) -1)); ether_ifdetach(ifp); if_detach(ifp); free(sc, 2, sizeof(*sc)); return 0; } int etherip_media_change(struct ifnet *ifp) { return 0; } void etherip_media_status(struct ifnet *ifp, struct ifmediareq *imr) { imr->ifm_active = 0x0000000000000100ULL | 0ULL; imr->ifm_status = 0x0000000000000001ULL | 0x0000000000000002ULL; } void etherip_start(struct ifnet *ifp) { struct etherip_softc *sc = ifp->if_softc; struct mbuf *m; int error; for (;;) { do { (m) = ifq_dequeue(&ifp->if_snd); } while ( 0); if (m == ((void *)0)) break; if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, m, (1<<1)); if (sc->sc_src.ss_family == 0 || sc->sc_dst.ss_family == 0) { m_freem(m); continue; } switch (sc->sc_src.ss_family) { case 2: error = ip_etherip_output(ifp, m); break; case 24: error = ip6_etherip_output(ifp, m); break; default: unhandled_af(sc->sc_src.ss_family); } if (error) ifp->if_data.ifi_oerrors++; } } int etherip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct etherip_softc *sc = ifp->if_softc; struct if_laddrreq *lifr = (struct if_laddrreq *)data; struct ifreq *ifr = (struct ifreq *)data; struct sockaddr_storage *src, *dst; struct proc *p = ({struct cpu_info *__ci; asm volatile("movq %%gs:8,%0" : "=r" (__ci)); __ci;})->ci_curproc; int error = 0; switch (cmd) { case ((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((12))): ifp->if_flags |= 0x1; case ((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((16))): if (ifp->if_flags & 0x1) ifp->if_flags |= 0x40; else ifp->if_flags &= ~0x40; break; case ((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((161))): if ((error = suser(p, 0)) != 0) break; if (ifr->ifr_ifru.ifru_metric < 0 || ifr->ifr_ifru.ifru_metric > 255 || !rtable_exists(ifr->ifr_ifru.ifru_metric)) { error = 22; break; } sc->sc_rdomain = ifr->ifr_ifru.ifru_metric; break; case (((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof(struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((162))): ifr->ifr_ifru.ifru_metric = sc->sc_rdomain; break; case ((unsigned long)0x80000000 | ((sizeof(struct if_laddrreq) & 0x1fff) << 16) | ((('i')) << 8) | ((74))): if ((error = suser(p, 0)) != 0) break; src = &lifr->addr; dst = &lifr->dstaddr; if (src->ss_family == 0 || dst->ss_family == 0) return 49; switch (src->ss_family) { case 2: if (src->ss_len != sizeof(struct sockaddr_in) || dst->ss_len != sizeof(struct sockaddr_in)) return 22; break; case 24: if (src->ss_len != sizeof(struct sockaddr_in6) || dst->ss_len != sizeof(struct sockaddr_in6)) return 22; break; default: return 47; } error = etherip_set_tunnel_addr(ifp, src, dst); break; case ((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((73))): if ((error = suser(p, 0)) != 0) break; ifp->if_flags &= ~0x40; __builtin_memset((&sc->sc_src), (0), (sizeof(sc->sc_src))); __builtin_memset((&sc->sc_dst), (0), (sizeof(sc->sc_dst))); break; case (((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof(struct if_laddrreq) & 0x1fff) << 16) | ((('i')) << 8) | ((75))): if (sc->sc_dst.ss_family == 0) return 49; __builtin_memset((&lifr->addr), (0), (sizeof(lifr->addr))); __builtin_memset((&lifr->dstaddr), (0), (sizeof(lifr->dstaddr))); __builtin_memcpy((&lifr->addr), (&sc->sc_src), (sc->sc_src.ss_len)); __builtin_memcpy((&lifr->dstaddr), (&sc->sc_dst), (sc->sc_dst.ss_len)); break; case (((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof(struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((55))): case (((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof(struct ifmediareq) & 0x1fff) << 16) | ((('i')) << 8) | ((56))): error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); break; default: error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); break; } return error; } int etherip_set_tunnel_addr(struct ifnet *ifp, struct sockaddr_storage *src, struct sockaddr_storage *dst) { struct etherip_softc *sc, *tsc; int error = 0; sc = ifp->if_softc; for((tsc) = ((ðerip_softc_list)->lh_first); (tsc)!= ((void *)0); (tsc) = ((tsc)->sc_entry.le_next)) { if (tsc == sc) continue; if (tsc->sc_src.ss_family != src->ss_family || tsc->sc_dst.ss_family != dst->ss_family || tsc->sc_src.ss_len != src->ss_len || tsc->sc_dst.ss_len != dst->ss_len) continue; if (tsc->sc_rdomain == sc->sc_rdomain && __builtin_memcmp((&tsc->sc_dst), (dst), (dst->ss_len)) == 0 && __builtin_memcmp((&tsc->sc_src), (src), (src->ss_len)) == 0) { error = 49; goto out; } } __builtin_memcpy((&sc->sc_src), (src), (src->ss_len)); __builtin_memcpy((&sc->sc_dst), (dst), (dst->ss_len)); out: return error; } int ip_etherip_output(struct ifnet *ifp, struct mbuf *m) { struct etherip_softc *sc = (struct etherip_softc *)ifp->if_softc; struct sockaddr_in *src, *dst; struct etherip_header *eip; struct ip *ip; src = (struct sockaddr_in *)&sc->sc_src; dst = (struct sockaddr_in *)&sc->sc_dst; if (src == ((void *)0) || dst == ((void *)0) || src->sin_family != 2 || dst->sin_family != 2) { m_freem(m); return 47; } if (dst->sin_addr.s_addr == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x00000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) { m_freem(m); return 51; } m->m_hdr.mh_flags &= ~(0x0100|0x0200); (m) = m_prepend((m), (sizeof(struct etherip_header)), (0x0002)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 55; } eip = ((struct etherip_header *)((m)->m_hdr.mh_data)); eip->eip_ver = 0x03; eip->eip_res = 0; eip->eip_pad = 0; (m) = m_prepend((m), (sizeof(struct ip)), (0x0002)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 55; } ip = ((struct ip *)((m)->m_hdr.mh_data)); __builtin_memset((ip), (0), (sizeof(struct ip))); ip->ip_v = 4; ip->ip_hl = sizeof(struct ip) >> 2; ip->ip_id = (__uint16_t)(__builtin_constant_p(ip_randomid()) ? (__uint16_t)(((__uint16_t)(ip_randomid()) & 0xffU) << 8 | ((__uint16_t)(ip_randomid()) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip_randomid()); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); ip->ip_tos = 0x10; ip->ip_p = 97; ip->ip_len = (__uint16_t)(__builtin_constant_p(m->M_dat.MH.MH_pkthdr.len) ? (__uint16_t)(((__uint16_t)(m->M_dat.MH.MH_pkthdr.len) & 0xffU) << 8 | ((__uint16_t)(m->M_dat.MH.MH_pkthdr.len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (m->M_dat.MH.MH_pkthdr.len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); ip->ip_ttl = 64; ip->ip_src = src->sin_addr; ip->ip_dst = dst->sin_addr; m->M_dat.MH.MH_pkthdr.ph_rtableid = sc->sc_rdomain; pf_pkt_addr_changed(m); etheripstat_pkt(etherips_opackets, etherips_obytes, m->M_dat.MH.MH_pkthdr.len - (sizeof(struct ip) + sizeof(struct etherip_header))); ip_send(m); return (0); } int ip_etherip_input(struct mbuf **mp, int *offp, int proto, int af) { struct mbuf *m = *mp; struct mbuf_list ml = { ((void *)0), ((void *)0), 0 }; struct etherip_softc *sc; const struct ip *ip; struct etherip_header *eip; struct sockaddr_in *src, *dst; struct ifnet *ifp = ((void *)0); ip = ((struct ip *)((m)->m_hdr.mh_data)); if (ip->ip_p != 97) { m_freem(m); ipstat_inc(ips_noproto); return 257; } if (!etherip_allow && (m->m_hdr.mh_flags & (0x0800|0x0400)) == 0) { m_freem(m); etheripstat_inc(etherips_pdrops); return 257; } do { int _s = rw_status(&netlock); if ((splassert_ctl > 0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while (0); for((sc) = ((ðerip_softc_list)->lh_first); (sc)!= ((void *)0); (sc) = ((sc)->sc_entry.le_next)) { if (sc->sc_src.ss_family != 2 || sc->sc_dst.ss_family != 2) continue; src = (struct sockaddr_in *)&sc->sc_src; dst = (struct sockaddr_in *)&sc->sc_dst; if (sc->sc_rdomain != rtable_l2(m->M_dat.MH.MH_pkthdr.ph_rtableid) || src->sin_addr.s_addr != ip->ip_dst.s_addr || dst->sin_addr.s_addr != ip->ip_src.s_addr) continue; ifp = &sc->sc_ac.ac_if; break; } if (ifp == ((void *)0)) { etheripstat_inc(etherips_noifdrops); m_freem(m); return 257; } m_adj(m, *offp); m = *mp = m_pullup(m, sizeof(struct etherip_header)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 257; } eip = ((struct etherip_header *)((m)->m_hdr.mh_data)); if (eip->eip_ver != 0x03 || eip->eip_pad) { etheripstat_inc(etherips_adrops); m_freem(m); return 257; } etheripstat_pkt(etherips_ipackets, etherips_ibytes, m->M_dat.MH.MH_pkthdr.len - sizeof(struct etherip_header)); m_adj(m, sizeof(struct etherip_header)); m = *mp = m_pullup(m, sizeof(struct ether_header)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 257; } m->m_hdr.mh_flags &= ~(0x0100|0x0200); pf_pkt_addr_changed(m); ml_enqueue(&ml, m); if_input(ifp, &ml); return 257; } int ip6_etherip_output(struct ifnet *ifp, struct mbuf *m) { struct etherip_softc *sc = (struct etherip_softc *)ifp->if_softc; struct sockaddr_in6 *src, *dst; struct etherip_header *eip; struct ip6_hdr *ip6; int error; src = (struct sockaddr_in6 *)&sc->sc_src; dst = (struct sockaddr_in6 *)&sc->sc_dst; if (src == ((void *)0) || dst == ((void *)0) || src->sin6_family != 24 || dst->sin6_family != 24) { error = 47; goto drop; } if (((*(const u_int32_t *)(const void *)(&(&dst->sin6_addr)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t *)(const void *)(&(&dst->sin6_addr)->__u6_addr.__u6_addr8[4]) == 0) && (*(const u_int32_t *)(const void *)(&(&dst->sin6_addr)->__u6_addr.__u6_addr8[8]) == 0) && (*(const u_int32_t *)(const void *)(&(&dst->sin6_addr)->__u6_addr.__u6_addr8[12]) == 0))) { error = 51; goto drop; } m->m_hdr.mh_flags &= ~(0x0100|0x0200); (m) = m_prepend((m), (sizeof(struct etherip_header)), (0x0002)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 55; } eip = ((struct etherip_header *)((m)->m_hdr.mh_data)); eip->eip_ver = 0x03; eip->eip_res = 0; eip->eip_pad = 0; (m) = m_prepend((m), (sizeof(struct ip6_hdr)), (0x0002)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 55; } ip6 = ((struct ip6_hdr *)((m)->m_hdr.mh_data)); ip6->ip6_ctlun.ip6_un1.ip6_un1_flow = 0; ip6->ip6_ctlun.ip6_un2_vfc &= ~0xf0; ip6->ip6_ctlun.ip6_un2_vfc |= 0x60; ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt = 97; ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim = ip6_defhlim; ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = (__uint16_t)(__builtin_constant_p(m->M_dat.MH.MH_pkthdr.len - sizeof(struct ip6_hdr)) ? (__uint16_t)(((__uint16_t)(m->M_dat.MH.MH_pkthdr.len - sizeof(struct ip6_hdr)) & 0xffU) << 8 | ((__uint16_t)(m->M_dat.MH.MH_pkthdr.len - sizeof(struct ip6_hdr)) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (m->M_dat.MH.MH_pkthdr.len - sizeof(struct ip6_hdr)); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); error = in6_embedscope(&ip6->ip6_src, src, ((void *)0)); if (error != 0) goto drop; error = in6_embedscope(&ip6->ip6_dst, dst, ((void *)0)); if (error != 0) goto drop; m->M_dat.MH.MH_pkthdr.ph_rtableid = sc->sc_rdomain; pf_pkt_addr_changed(m); etheripstat_pkt(etherips_opackets, etherips_obytes, m->M_dat.MH.MH_pkthdr.len - (sizeof(struct ip6_hdr) + sizeof(struct etherip_header))); ip6_send(m); return (0); drop: m_freem(m); return (error); } int ip6_etherip_input(struct mbuf **mp, int *offp, int proto, int af) { struct mbuf *m = *mp; struct mbuf_list ml = { ((void *)0), ((void *)0), 0 }; struct etherip_softc *sc; const struct ip6_hdr *ip6; struct etherip_header *eip; struct sockaddr_in6 ipsrc, ipdst; struct sockaddr_in6 *src6, *dst6; struct ifnet *ifp = ((void *)0); if (!etherip_allow && (m->m_hdr.mh_flags & (0x0800|0x0400)) == 0) { m_freem(m); etheripstat_inc(etherips_pdrops); return 59; } ip6 = ((const struct ip6_hdr *)((m)->m_hdr.mh_data)); in6_recoverscope(&ipsrc, &ip6->ip6_src); in6_recoverscope(&ipdst, &ip6->ip6_dst); do { int _s = rw_status(&netlock); if ((splassert_ctl > 0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while (0); for((sc) = ((ðerip_softc_list)->lh_first); (sc)!= ((void *)0); (sc) = ((sc)->sc_entry.le_next)) { if (sc->sc_src.ss_family != 24 || sc->sc_dst.ss_family != 24) continue; src6 = (struct sockaddr_in6 *)&sc->sc_src; dst6 = (struct sockaddr_in6 *)&sc->sc_dst; if ((__builtin_memcmp((&(&src6->sin6_addr)->__u6_addr.__u6_addr8[0]), (&(&ipdst.sin6_addr)->__u6_addr.__u6_addr8[0]), (sizeof(struct in6_addr))) == 0) && src6->sin6_scope_id == ipdst.sin6_scope_id && (__builtin_memcmp((&(&dst6->sin6_addr)->__u6_addr.__u6_addr8[0]), (&(&ipsrc.sin6_addr)->__u6_addr.__u6_addr8[0]), (sizeof(struct in6_addr))) == 0) && dst6->sin6_scope_id == ipsrc.sin6_scope_id) { ifp = &sc->sc_ac.ac_if; break; } } if (ifp == ((void *)0)) { etheripstat_inc(etherips_noifdrops); m_freem(m); return 257; } m_adj(m, *offp); m = *mp = m_pullup(m, sizeof(struct etherip_header)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 257; } eip = ((struct etherip_header *)((m)->m_hdr.mh_data)); if ((eip->eip_ver != 0x03) || eip->eip_pad) { etheripstat_inc(etherips_adrops); m_freem(m); return 257; } etheripstat_pkt(etherips_ipackets, etherips_ibytes, m->M_dat.MH.MH_pkthdr.len - sizeof(struct etherip_header)); m_adj(m, sizeof(struct etherip_header)); m = *mp = m_pullup(m, sizeof(struct ether_header)); if (m == ((void *)0)) { etheripstat_inc(etherips_adrops); return 257; } m->m_hdr.mh_flags &= ~(0x0100|0x0200); pf_pkt_addr_changed(m); ml_enqueue(&ml, m); if_input(ifp, &ml); return 257; } int etherip_sysctl_etheripstat(void *oldp, size_t *oldlenp, void *newp) { struct etheripstat etheripstat; extern char _ctassert[(sizeof(etheripstat) == (etherips_ncounters * sizeof(uint64_t))) ? 1 : -1 ] __attribute__((__unused__)); __builtin_memset((ðeripstat), (0), (sizeof etheripstat)); counters_read(etheripcounters, (uint64_t *)ðeripstat, etherips_ncounters); return (sysctl_rdstruct(oldp, oldlenp, newp, ðeripstat, sizeof(etheripstat))); } int etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int error; if (namelen != 1) return 20; switch (name[0]) { case 1: do { _rw_enter_write(&netlock ); } while (0); error = sysctl_int(oldp, oldlenp, newp, newlen, ðerip_allow); do { _rw_exit_write(&netlock ); } while (0); return (error); case 2: return (etherip_sysctl_etheripstat(oldp, oldlenp, newp)); default: break; } return 42; } struct icmp6_hdr { u_int8_t icmp6_type; u_int8_t icmp6_code; u_int16_t icmp6_cksum; union { u_int32_t icmp6_un_data32[1]; u_int16_t icmp6_un_data16[2]; u_int8_t icmp6_un_data8[4]; } icmp6_dataun; } __attribute__((__packed__)); struct mld_hdr { struct icmp6_hdr mld_icmp6_hdr; struct in6_addr mld_addr; } __attribute__((__packed__)); struct nd_router_solicit { struct icmp6_hdr nd_rs_hdr; } __attribute__((__packed__)); struct nd_router_advert { struct icmp6_hdr nd_ra_hdr; u_int32_t nd_ra_reachable; u_int32_t nd_ra_retransmit; } __attribute__((__packed__)); struct nd_neighbor_solicit { struct icmp6_hdr nd_ns_hdr; struct in6_addr nd_ns_target; } __attribute__((__packed__)); struct nd_neighbor_advert { struct icmp6_hdr nd_na_hdr; struct in6_addr nd_na_target; } __attribute__((__packed__)); struct nd_redirect { struct icmp6_hdr nd_rd_hdr; struct in6_addr nd_rd_target; struct in6_addr nd_rd_dst; } __attribute__((__packed__)); struct nd_opt_hdr { u_int8_t nd_opt_type; u_int8_t nd_opt_len; } __attribute__((__packed__)); struct nd_opt_prefix_info { u_int8_t nd_opt_pi_type; u_int8_t nd_opt_pi_len; u_int8_t nd_opt_pi_prefix_len; u_int8_t nd_opt_pi_flags_reserved; u_int32_t nd_opt_pi_valid_time; u_int32_t nd_opt_pi_preferred_time; u_int32_t nd_opt_pi_reserved2; struct in6_addr nd_opt_pi_prefix; } __attribute__((__packed__)); struct nd_opt_rd_hdr { u_int8_t nd_opt_rh_type; u_int8_t nd_opt_rh_len; u_int16_t nd_opt_rh_reserved1; u_int32_t nd_opt_rh_reserved2; } __attribute__((__packed__)); struct nd_opt_mtu { u_int8_t nd_opt_mtu_type; u_int8_t nd_opt_mtu_len; u_int16_t nd_opt_mtu_reserved; u_int32_t nd_opt_mtu_mtu; } __attribute__((__packed__)); struct nd_opt_route_info { u_int8_t nd_opt_rti_type; u_int8_t nd_opt_rti_len; u_int8_t nd_opt_rti_prefixlen; u_int8_t nd_opt_rti_flags; u_int32_t nd_opt_rti_lifetime; } __attribute__((__packed__)); struct nd_opt_rdnss { u_int8_t nd_opt_rdnss_type; u_int8_t nd_opt_rdnss_len; u_int16_t nd_opt_rdnss_reserved; u_int32_t nd_opt_rdnss_lifetime; } __attribute__((__packed__)); struct nd_opt_dnssl { u_int8_t nd_opt_dnssl_type; u_int8_t nd_opt_dnssl_len; u_int16_t nd_opt_dnssl_reserved; u_int32_t nd_opt_dnssl_lifetime; } __attribute__((__packed__)); struct icmp6_namelookup { struct icmp6_hdr icmp6_nl_hdr; u_int8_t icmp6_nl_nonce[8]; int32_t icmp6_nl_ttl; } __attribute__((__packed__)); struct icmp6_nodeinfo { struct icmp6_hdr icmp6_ni_hdr; u_int8_t icmp6_ni_nonce[8]; } __attribute__((__packed__)); struct ni_reply_fqdn { u_int32_t ni_fqdn_ttl; u_int8_t ni_fqdn_namelen; u_int8_t ni_fqdn_name[3]; } __attribute__((__packed__)); struct icmp6_router_renum { struct icmp6_hdr rr_hdr; u_int8_t rr_segnum; u_int8_t rr_flags; u_int16_t rr_maxdelay; u_int32_t rr_reserved; } __attribute__((__packed__)); struct rr_pco_match { u_int8_t rpm_code; u_int8_t rpm_len; u_int8_t rpm_ordinal; u_int8_t rpm_matchlen; u_int8_t rpm_minlen; u_int8_t rpm_maxlen; u_int16_t rpm_reserved; struct in6_addr rpm_prefix; } __attribute__((__packed__)); struct rr_pco_use { u_int8_t rpu_uselen; u_int8_t rpu_keeplen; u_int8_t rpu_ramask; u_int8_t rpu_raflags; u_int32_t rpu_vltime; u_int32_t rpu_pltime; u_int32_t rpu_flags; struct in6_addr rpu_prefix; } __attribute__((__packed__)); struct rr_result { u_int16_t rrr_flags; u_int8_t rrr_ordinal; u_int8_t rrr_matchedlen; u_int32_t rrr_ifid; struct in6_addr rrr_prefix; } __attribute__((__packed__)); struct icmp6_filter { u_int32_t icmp6_filt[8]; }; struct icmp6stat { u_int64_t icp6s_error; u_int64_t icp6s_canterror; u_int64_t icp6s_toofreq; u_int64_t icp6s_outhist[256]; u_int64_t icp6s_badcode; u_int64_t icp6s_tooshort; u_int64_t icp6s_checksum; u_int64_t icp6s_badlen; u_int64_t icp6s_reflect; u_int64_t icp6s_inhist[256]; u_int64_t icp6s_nd_toomanyopt; u_int64_t icp6s_odst_unreach_noroute; u_int64_t icp6s_odst_unreach_admin; u_int64_t icp6s_odst_unreach_beyondscope; u_int64_t icp6s_odst_unreach_addr; u_int64_t icp6s_odst_unreach_noport; u_int64_t icp6s_opacket_too_big; u_int64_t icp6s_otime_exceed_transit; u_int64_t icp6s_otime_exceed_reassembly; u_int64_t icp6s_oparamprob_header; u_int64_t icp6s_oparamprob_nextheader; u_int64_t icp6s_oparamprob_option; u_int64_t icp6s_oredirect; u_int64_t icp6s_ounknown; u_int64_t icp6s_pmtuchg; u_int64_t icp6s_nd_badopt; u_int64_t icp6s_badns; u_int64_t icp6s_badna; u_int64_t icp6s_badrs; u_int64_t icp6s_badra; u_int64_t icp6s_badredirect; }; enum icmp6stat_counters { icp6s_error, icp6s_canterror, icp6s_toofreq, icp6s_outhist, icp6s_badcode = icp6s_outhist + 256, icp6s_tooshort, icp6s_checksum, icp6s_badlen, icp6s_reflect, icp6s_inhist, icp6s_nd_toomanyopt = icp6s_inhist + 256, icp6s_odst_unreach_noroute, icp6s_odst_unreach_admin, icp6s_odst_unreach_beyondscope, icp6s_odst_unreach_addr, icp6s_odst_unreach_noport, icp6s_opacket_too_big, icp6s_otime_exceed_transit, icp6s_otime_exceed_reassembly, icp6s_oparamprob_header, icp6s_oparamprob_nextheader, icp6s_oparamprob_option, icp6s_oredirect, icp6s_ounknown, icp6s_pmtuchg, icp6s_nd_badopt, icp6s_badns, icp6s_badna, icp6s_badrs, icp6s_badra, icp6s_badredirect, icp6s_ncounters, }; extern struct cpumem *icmp6counters; static inline void icmp6stat_inc(enum icmp6stat_counters c) { counters_inc(icmp6counters, c); } struct rtentry; struct rttimer; struct in6_multi; void icmp6_init(void); void icmp6_paramerror(struct mbuf *, int); void icmp6_error(struct mbuf *, int, int, int); int icmp6_input(struct mbuf **, int *, int, int); void icmp6_fasttimo(void); void icmp6_reflect(struct mbuf *, size_t); void icmp6_prepare(struct mbuf *); void icmp6_redirect_input(struct mbuf *, int); void icmp6_redirect_output(struct mbuf *, struct rtentry *); int icmp6_sysctl(int *, u_int, void *, size_t *, void *, size_t); struct ip6ctlparam; void icmp6_mtudisc_update(struct ip6ctlparam *, int); void icmp6_mtudisc_callback_register(void (*)(struct sockaddr_in6 *, u_int)); extern int icmp6_redirtimeout; struct m_tag; union sockaddr_union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; }; struct sockaddr_encap { u_int8_t sen_len; u_int8_t sen_family; u_int16_t sen_type; union { struct { u_int8_t Direction; struct in_addr Src; struct in_addr Dst; u_int8_t Proto; u_int16_t Sport; u_int16_t Dport; } Sip4; struct { u_int8_t Direction; struct in6_addr Src; struct in6_addr Dst; u_int8_t Proto; u_int16_t Sport; u_int16_t Dport; } Sip6; struct ipsec_policy *PolicyHead; } Sen; }; struct ipsec_id { u_int16_t type; int16_t len; }; struct ipsec_ids { struct rb_entry id_node_id; struct rb_entry id_node_flow; struct ipsec_id *id_local; struct ipsec_id *id_remote; u_int32_t id_flow; int id_refcount; struct timeout id_timeout; }; struct ipsec_ids_flows { struct rb_tree rbh_root; }; struct ipsec_ids_tree { struct rb_tree rbh_root; }; struct ipsec_acquire { union sockaddr_union ipa_addr; u_int32_t ipa_seq; struct sockaddr_encap ipa_info; struct sockaddr_encap ipa_mask; struct timeout ipa_timeout; struct ipsec_policy *ipa_policy; struct inpcb *ipa_pcb; struct { struct ipsec_acquire *tqe_next; struct ipsec_acquire **tqe_prev; } ipa_ipo_next; struct { struct ipsec_acquire *tqe_next; struct ipsec_acquire **tqe_prev; } ipa_next; }; struct ipsec_policy { struct radix_node ipo_nodes[2]; struct sockaddr_encap ipo_addr; struct sockaddr_encap ipo_mask; union sockaddr_union ipo_src; union sockaddr_union ipo_dst; u_int64_t ipo_last_searched; u_int8_t ipo_flags; u_int8_t ipo_type; u_int8_t ipo_sproto; u_int ipo_rdomain; int ipo_ref_count; struct tdb *ipo_tdb; struct ipsec_ids *ipo_ids; struct ipo_acquires_head { struct ipsec_acquire *tqh_first; struct ipsec_acquire **tqh_last; } ipo_acquires; struct { struct ipsec_policy *tqe_next; struct ipsec_policy **tqe_prev; } ipo_tdb_next; struct { struct ipsec_policy *tqe_next; struct ipsec_policy **tqe_prev; } ipo_list; }; struct tdb { struct tdb *tdb_hnext; struct tdb *tdb_dnext; struct tdb *tdb_snext; struct tdb *tdb_inext; struct tdb *tdb_onext; struct xformsw *tdb_xform; struct enc_xform *tdb_encalgxform; struct auth_hash *tdb_authalgxform; struct comp_algo *tdb_compalgxform; u_int32_t tdb_flags; struct timeout tdb_timer_tmo; struct timeout tdb_first_tmo; struct timeout tdb_stimer_tmo; struct timeout tdb_sfirst_tmo; u_int32_t tdb_seq; u_int32_t tdb_exp_allocations; u_int32_t tdb_soft_allocations; u_int32_t tdb_cur_allocations; u_int64_t tdb_exp_bytes; u_int64_t tdb_soft_bytes; u_int64_t tdb_cur_bytes; u_int64_t tdb_exp_timeout; u_int64_t tdb_soft_timeout; u_int64_t tdb_established; u_int64_t tdb_first_use; u_int64_t tdb_soft_first_use; u_int64_t tdb_exp_first_use; u_int64_t tdb_last_used; u_int64_t tdb_last_marked; u_int64_t tdb_cryptoid; u_int32_t tdb_spi; u_int16_t tdb_amxkeylen; u_int16_t tdb_emxkeylen; u_int16_t tdb_ivlen; u_int8_t tdb_sproto; u_int8_t tdb_wnd; u_int8_t tdb_satype; u_int8_t tdb_updates; union sockaddr_union tdb_dst; union sockaddr_union tdb_src; u_int8_t *tdb_amxkey; u_int8_t *tdb_emxkey; u_int64_t tdb_rpl; u_int32_t tdb_seen[((((2100+32)) + ((32) - 1)) / (32))]; u_int8_t tdb_iv[4]; struct ipsec_ids *tdb_ids; int tdb_ids_swapped; u_int32_t tdb_mtu; u_int64_t tdb_mtutimeout; u_int16_t tdb_udpencap_port; u_int16_t tdb_tag; u_int32_t tdb_tap; u_int tdb_rdomain; struct sockaddr_encap tdb_filter; struct sockaddr_encap tdb_filtermask; struct tdb_policy_head { struct ipsec_policy *tqh_first; struct ipsec_policy **tqh_last; } tdb_policy_head; struct { struct tdb *tqe_next; struct tdb **tqe_prev; } tdb_sync_entry; }; struct tdb_ident { u_int32_t spi; union sockaddr_union dst; u_int8_t proto; u_int rdomain; }; struct tdb_crypto { u_int32_t tc_spi; union sockaddr_union tc_dst; u_int8_t tc_proto; int tc_protoff; int tc_skip; u_int tc_rdomain; }; struct ipsecinit { u_int8_t *ii_enckey; u_int8_t *ii_authkey; u_int16_t ii_enckeylen; u_int16_t ii_authkeylen; u_int8_t ii_encalg; u_int8_t ii_authalg; u_int8_t ii_compalg; }; struct xformsw { u_short xf_type; u_short xf_flags; char *xf_name; int (*xf_attach)(void); int (*xf_init)(struct tdb *, struct xformsw *, struct ipsecinit *); int (*xf_zeroize)(struct tdb *); int (*xf_input)(struct mbuf *, struct tdb *, int, int); int (*xf_output)(struct mbuf *, struct tdb *, struct mbuf **, int, int); }; extern int ipsec_in_use; extern u_int64_t ipsec_last_added; extern int ipsec_policy_pool_initialized; extern int encdebug; extern int ipsec_keep_invalid; extern int ipsec_require_pfs; extern int ipsec_expire_acquire; extern int ipsec_soft_allocations; extern int ipsec_exp_allocations; extern int ipsec_soft_bytes; extern int ipsec_exp_bytes; extern int ipsec_soft_timeout; extern int ipsec_exp_timeout; extern int ipsec_soft_first_use; extern int ipsec_exp_first_use; extern char ipsec_def_enc[]; extern char ipsec_def_auth[]; extern char ipsec_def_comp[]; extern struct enc_xform enc_xform_des; extern struct enc_xform enc_xform_3des; extern struct enc_xform enc_xform_blf; extern struct enc_xform enc_xform_cast5; extern struct auth_hash auth_hash_hmac_md5_96; extern struct auth_hash auth_hash_hmac_sha1_96; extern struct auth_hash auth_hash_hmac_ripemd_160_96; extern struct comp_algo comp_algo_deflate; extern struct ipsec_policy_head { struct ipsec_policy *tqh_first; struct ipsec_policy **tqh_last; } ipsec_policy_head; struct radix_node_head *spd_table_add(unsigned int); struct radix_node_head *spd_table_get(unsigned int); int spd_table_walk(unsigned int, int (*walker)(struct ipsec_policy *, void *, unsigned int), void *); uint32_t reserve_spi(u_int, u_int32_t, u_int32_t, union sockaddr_union *, union sockaddr_union *, u_int8_t, int *); struct tdb *gettdb(u_int, u_int32_t, union sockaddr_union *, u_int8_t); struct tdb *gettdbbydst(u_int, union sockaddr_union *, u_int8_t, struct ipsec_ids *, struct sockaddr_encap *, struct sockaddr_encap *); struct tdb *gettdbbysrc(u_int, union sockaddr_union *, u_int8_t, struct ipsec_ids *, struct sockaddr_encap *, struct sockaddr_encap *); struct tdb *gettdbbysrcdst(u_int, u_int32_t, union sockaddr_union *, union sockaddr_union *, u_int8_t); void puttdb(struct tdb *); void tdb_delete(struct tdb *); struct tdb *tdb_alloc(u_int); void tdb_free(struct tdb *); int tdb_init(struct tdb *, u_int16_t, struct ipsecinit *); void tdb_unlink(struct tdb *); int tdb_walk(u_int, int (*)(struct tdb *, void *, int), void *); int ipe4_attach(void); int ipe4_init(struct tdb *, struct xformsw *, struct ipsecinit *); int ipe4_zeroize(struct tdb *); int ipe4_input(struct mbuf *, struct tdb *, int, int); int ah_attach(void); int ah_init(struct tdb *, struct xformsw *, struct ipsecinit *); int ah_zeroize(struct tdb *); int ah_input(struct mbuf *, struct tdb *, int, int); int ah_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int ah_sysctl(int *, u_int, void *, size_t *, void *, size_t); int ah4_input(struct mbuf **, int *, int, int); void ah4_ctlinput(int, struct sockaddr *, u_int, void *); void udpencap_ctlinput(int, struct sockaddr *, u_int, void *); int ah6_input(struct mbuf **, int *, int, int); int esp_attach(void); int esp_init(struct tdb *, struct xformsw *, struct ipsecinit *); int esp_zeroize(struct tdb *); int esp_input(struct mbuf *, struct tdb *, int, int); int esp_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int esp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int esp4_input(struct mbuf **, int *, int, int); void esp4_ctlinput(int, struct sockaddr *, u_int, void *); int esp6_input(struct mbuf **, int *, int, int); int ipcomp_attach(void); int ipcomp_init(struct tdb *, struct xformsw *, struct ipsecinit *); int ipcomp_zeroize(struct tdb *); int ipcomp_input(struct mbuf *, struct tdb *, int, int); int ipcomp_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int ipcomp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int ipcomp4_input(struct mbuf **, int *, int, int); int ipcomp6_input(struct mbuf **, int *, int, int); int tcp_signature_tdb_attach(void); int tcp_signature_tdb_init(struct tdb *, struct xformsw *, struct ipsecinit *); int tcp_signature_tdb_zeroize(struct tdb *); int tcp_signature_tdb_input(struct mbuf *, struct tdb *, int, int); int tcp_signature_tdb_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int checkreplaywindow(struct tdb *, u_int32_t, u_int32_t *, int); int ipsp_process_packet(struct mbuf *, struct tdb *, int, int); int ipsp_process_done(struct mbuf *, struct tdb *); struct tdb *ipsp_spd_lookup(struct mbuf *, int, int, int *, int, struct tdb *, struct inpcb *, u_int32_t); struct tdb *ipsp_spd_inp(struct mbuf *, int, int, int *, int, struct tdb *, struct inpcb *, struct ipsec_policy *); int ipsp_is_unspecified(union sockaddr_union); int ipsp_aux_match(struct tdb *, struct ipsec_ids *, struct sockaddr_encap *, struct sockaddr_encap *); int ipsp_ids_match(struct ipsec_ids *, struct ipsec_ids *); struct ipsec_ids *ipsp_ids_insert(struct ipsec_ids *); struct ipsec_ids *ipsp_ids_lookup(u_int32_t); void ipsp_ids_free(struct ipsec_ids *); void ipsec_init(void); int ipsec_sysctl(int *, u_int, void *, size_t *, void *, size_t); int ipsec_common_input(struct mbuf *, int, int, int, int, int); void ipsec_common_input_cb(struct mbuf *, struct tdb *, int, int); int ipsec_delete_policy(struct ipsec_policy *); ssize_t ipsec_hdrsz(struct tdb *); void ipsec_adjust_mtu(struct mbuf *, u_int32_t); struct ipsec_acquire *ipsec_get_acquire(u_int32_t); int ipsec_forward_check(struct mbuf *, int, int); int ipsec_local_check(struct mbuf *, int, int, int); typedef struct _SIPHASH_CTX { uint64_t v[4]; uint8_t buf[8]; uint32_t bytes; } SIPHASH_CTX; typedef struct { uint64_t k0; uint64_t k1; } SIPHASH_KEY; void SipHash_Init(SIPHASH_CTX *, const SIPHASH_KEY *); void SipHash_Update(SIPHASH_CTX *, int, int, const void *, size_t) ; uint64_t SipHash_End(SIPHASH_CTX *, int, int); void SipHash_Final(void *, SIPHASH_CTX *, int, int) ; uint64_t SipHash(const SIPHASH_KEY *, int, int, const void *, size_t) ; struct pf_state_key; union inpaddru { struct in6_addr iau_addr6; struct { uint8_t pad[12]; struct in_addr inaddr; } iau_a4u; }; struct inpcb { struct { struct inpcb *le_next; struct inpcb **le_prev; } inp_hash; struct { struct inpcb *le_next; struct inpcb **le_prev; } inp_lhash; struct { struct inpcb *tqe_next; struct inpcb **tqe_prev; } inp_queue; struct inpcbtable *inp_table; union inpaddru inp_faddru; union inpaddru inp_laddru; u_int16_t inp_fport; u_int16_t inp_lport; struct socket *inp_socket; caddr_t inp_ppcb; union { struct route ru_route; struct route_in6 ru_route6; } inp_ru; int inp_flags; union { struct ip hu_ip; struct ip6_hdr hu_ipv6; } inp_hu; struct mbuf *inp_options; struct ip6_pktopts *inp_outputopts6; int inp_hops; union { struct ip_moptions *mou_mo; struct ip6_moptions *mou_mo6; } inp_mou; u_char inp_seclevel[4]; u_char inp_ip_minttl; int inp_cksum6; struct icmp6_filter *inp_icmp6filt; struct pf_state_key *inp_pf_sk; u_int inp_rtableid; int inp_pipex; }; struct inpcbhead { struct inpcb *lh_first; }; struct inpcbtable { struct inpthead { struct inpcb *tqh_first; struct inpcb **tqh_last; } inpt_queue; struct inpcbhead *inpt_hashtbl, *inpt_lhashtbl; SIPHASH_KEY inpt_key; u_long inpt_hash, inpt_lhash; int inpt_count; }; struct baddynamicports { u_int32_t tcp[((((65536) + (((sizeof(u_int32_t) * 8)) - 1)) / ((sizeof(u_int32_t) * 8))))]; u_int32_t udp[((((65536) + (((sizeof(u_int32_t) * 8)) - 1)) / ((sizeof(u_int32_t) * 8))))]; }; extern struct baddynamicports baddynamicports; extern struct baddynamicports rootonlyports; void in_losing(struct inpcb *); int in_pcballoc(struct socket *, struct inpcbtable *); int in_pcbbind(struct inpcb *, struct mbuf *, struct proc *); int in_pcbaddrisavail(struct inpcb *, struct sockaddr_in *, int, struct proc *); int in_pcbconnect(struct inpcb *, struct mbuf *); void in_pcbdetach(struct inpcb *); void in_pcbdisconnect(struct inpcb *); struct inpcb * in_pcbhashlookup(struct inpcbtable *, struct in_addr, u_int, struct in_addr, u_int, u_int); struct inpcb * in_pcblookup_listen(struct inpcbtable *, struct in_addr, u_int, struct mbuf *, u_int); struct inpcb * in6_pcbhashlookup(struct inpcbtable *, const struct in6_addr *, u_int, const struct in6_addr *, u_int, u_int); struct inpcb * in6_pcblookup_listen(struct inpcbtable *, struct in6_addr *, u_int, struct mbuf *, u_int); int in6_pcbaddrisavail(struct inpcb *, struct sockaddr_in6 *, int, struct proc *); int in6_pcbconnect(struct inpcb *, struct mbuf *); int in6_setsockaddr(struct inpcb *, struct mbuf *); int in6_setpeeraddr(struct inpcb *, struct mbuf *); void in_pcbinit(struct inpcbtable *, int); struct inpcb * in_pcblookup_local(struct inpcbtable *, void *, u_int, int, u_int); void in_pcbnotifyall(struct inpcbtable *, struct sockaddr *, u_int, int, void (*)(struct inpcb *, int)); void in_pcbrehash(struct inpcb *); void in_rtchange(struct inpcb *, int); void in_setpeeraddr(struct inpcb *, struct mbuf *); void in_setsockaddr(struct inpcb *, struct mbuf *); int in_baddynamic(u_int16_t, u_int16_t); int in_rootonly(u_int16_t, u_int16_t); int in_pcbselsrc(struct in_addr **, struct sockaddr_in *, struct inpcb *); struct rtentry * in_pcbrtentry(struct inpcb *); int in6_pcbnotify(struct inpcbtable *, struct sockaddr_in6 *, u_int, const struct sockaddr_in6 *, u_int, u_int, int, void *, void (*)(struct inpcb *, int)); int in6_selecthlim(struct inpcb *); int in_pcbpickport(u_int16_t *, void *, int, struct inpcb *, struct proc *); typedef u_int32_t tcp_seq; struct tcphdr { u_int16_t th_sport; u_int16_t th_dport; tcp_seq th_seq; tcp_seq th_ack; u_int32_t th_x2:4, th_off:4; u_int8_t th_flags; u_int16_t th_win; u_int16_t th_sum; u_int16_t th_urp; }; typedef void (*tcp_timer_func_t)(void *); extern const tcp_timer_func_t tcp_timer_funcs[5]; extern int tcptv_keep_init; extern int tcp_always_keepalive; extern int tcp_keepidle; extern int tcp_keepintvl; extern int tcp_maxidle; extern int tcp_ttl; extern int tcp_backoff[]; void tcp_timer_init(void); struct sackblk { tcp_seq start; tcp_seq end; }; struct sackhole { tcp_seq start; tcp_seq end; int dups; tcp_seq rxmit; struct sackhole *next; }; struct tcpqehead { struct tcpqent *tqh_first; struct tcpqent **tqh_last; }; struct tcpqent { struct { struct tcpqent *tqe_next; struct tcpqent **tqe_prev; } tcpqe_q; struct tcphdr *tcpqe_tcp; struct mbuf *tcpqe_m; }; struct tcpcb { struct tcpqehead t_segq; struct timeout t_timer[5]; short t_state; short t_rxtshift; short t_rxtcur; short t_dupacks; u_short t_maxseg; char t_force; u_int t_flags; struct mbuf *t_template; struct inpcb *t_inpcb; struct timeout t_delack_to; tcp_seq snd_una; tcp_seq snd_nxt; tcp_seq snd_up; tcp_seq snd_wl1; tcp_seq snd_wl2; tcp_seq iss; u_long snd_wnd; int sack_enable; int snd_numholes; struct sackhole *snd_holes; tcp_seq snd_last; u_long rcv_wnd; tcp_seq rcv_nxt; tcp_seq rcv_up; tcp_seq irs; tcp_seq rcv_lastsack; int rcv_numsacks; struct sackblk sackblks[6]; tcp_seq rcv_adv; tcp_seq snd_max; u_long snd_cwnd; u_long snd_ssthresh; u_int rfbuf_cnt; u_int32_t rfbuf_ts; u_short t_maxopd; u_short t_peermss; uint32_t t_rcvtime; uint32_t t_rtttime; tcp_seq t_rtseq; short t_srtt; short t_rttvar; u_short t_rttmin; u_long max_sndwnd; char t_oobflags; char t_iobc; short t_softerror; u_char snd_scale; u_char rcv_scale; u_char request_r_scale; u_char requested_s_scale; u_int32_t ts_recent; u_int32_t ts_modulate; u_int32_t ts_recent_age; tcp_seq last_ack_sent; struct { struct syn_cache *lh_first; } t_sc; u_int t_pmtud_mss_acked; u_int t_pmtud_mtu_sent; tcp_seq t_pmtud_th_seq; u_int t_pmtud_nextmtu; u_short t_pmtud_ip_len; u_short t_pmtud_ip_hl; int pf; }; extern int tcp_delack_ticks; void tcp_delack(void *); struct tcp_opt_info { int ts_present; u_int32_t ts_val; u_int32_t ts_ecr; u_int16_t maxseg; }; union syn_cache_sa { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; }; struct syn_cache { struct { struct syn_cache *tqe_next; struct syn_cache **tqe_prev; } sc_bucketq; struct timeout sc_timer; union { struct route route4; struct route_in6 route6; } sc_route_u; long sc_win; struct syn_cache_head *sc_buckethead; struct syn_cache_set *sc_set; u_int32_t sc_hash; u_int32_t sc_timestamp; u_int32_t sc_modulate; union syn_cache_sa sc_src; union syn_cache_sa sc_dst; tcp_seq sc_irs; tcp_seq sc_iss; u_int sc_rtableid; u_int sc_rxtcur; u_int sc_rxttot; u_short sc_rxtshift; u_short sc_flags; struct mbuf *sc_ipopts; u_int16_t sc_peermaxseg; u_int16_t sc_ourmaxseg; u_int sc_request_r_scale : 4, sc_requested_s_scale : 4; struct tcpcb *sc_tp; struct { struct syn_cache *le_next; struct syn_cache **le_prev; } sc_tpq; }; struct syn_cache_head { struct { struct syn_cache *tqh_first; struct syn_cache **tqh_last; } sch_bucket; u_short sch_length; }; struct syn_cache_set { struct syn_cache_head *scs_buckethead; int scs_size; int scs_count; int scs_use; u_int32_t scs_random[5]; }; struct tcpstat { u_int32_t tcps_connattempt; u_int32_t tcps_accepts; u_int32_t tcps_connects; u_int32_t tcps_drops; u_int32_t tcps_conndrops; u_int32_t tcps_closed; u_int32_t tcps_segstimed; u_int32_t tcps_rttupdated; u_int32_t tcps_delack; u_int32_t tcps_timeoutdrop; u_int32_t tcps_rexmttimeo; u_int32_t tcps_persisttimeo; u_int32_t tcps_persistdrop; u_int32_t tcps_keeptimeo; u_int32_t tcps_keepprobe; u_int32_t tcps_keepdrops; u_int32_t tcps_sndtotal; u_int32_t tcps_sndpack; u_int64_t tcps_sndbyte; u_int32_t tcps_sndrexmitpack; u_int64_t tcps_sndrexmitbyte; u_int64_t tcps_sndrexmitfast; u_int32_t tcps_sndacks; u_int32_t tcps_sndprobe; u_int32_t tcps_sndurg; u_int32_t tcps_sndwinup; u_int32_t tcps_sndctrl; u_int32_t tcps_rcvtotal; u_int32_t tcps_rcvpack; u_int64_t tcps_rcvbyte; u_int32_t tcps_rcvbadsum; u_int32_t tcps_rcvbadoff; u_int32_t tcps_rcvmemdrop; u_int32_t tcps_rcvnosec; u_int32_t tcps_rcvshort; u_int32_t tcps_rcvduppack; u_int64_t tcps_rcvdupbyte; u_int32_t tcps_rcvpartduppack; u_int64_t tcps_rcvpartdupbyte; u_int32_t tcps_rcvoopack; u_int64_t tcps_rcvoobyte; u_int32_t tcps_rcvpackafterwin; u_int64_t tcps_rcvbyteafterwin; u_int32_t tcps_rcvafterclose; u_int32_t tcps_rcvwinprobe; u_int32_t tcps_rcvdupack; u_int32_t tcps_rcvacktoomuch; u_int32_t tcps_rcvacktooold; u_int32_t tcps_rcvackpack; u_int64_t tcps_rcvackbyte; u_int32_t tcps_rcvwinupd; u_int32_t tcps_pawsdrop; u_int32_t tcps_predack; u_int32_t tcps_preddat; u_int32_t tcps_pcbhashmiss; u_int32_t tcps_noport; u_int32_t tcps_badsyn; u_int32_t tcps_dropsyn; u_int32_t tcps_rcvbadsig; u_int64_t tcps_rcvgoodsig; u_int32_t tcps_inswcsum; u_int32_t tcps_outswcsum; u_int32_t tcps_ecn_accepts; u_int32_t tcps_ecn_rcvece; u_int32_t tcps_ecn_rcvcwr; u_int32_t tcps_ecn_rcvce; u_int32_t tcps_ecn_sndect; u_int32_t tcps_ecn_sndece; u_int32_t tcps_ecn_sndcwr; u_int32_t tcps_cwr_ecn; u_int32_t tcps_cwr_frecovery; u_int32_t tcps_cwr_timeout; u_int64_t tcps_sc_added; u_int64_t tcps_sc_completed; u_int64_t tcps_sc_timed_out; u_int64_t tcps_sc_overflowed; u_int64_t tcps_sc_reset; u_int64_t tcps_sc_unreach; u_int64_t tcps_sc_bucketoverflow; u_int64_t tcps_sc_aborted; u_int64_t tcps_sc_dupesyn; u_int64_t tcps_sc_dropped; u_int64_t tcps_sc_collisions; u_int64_t tcps_sc_retransmitted; u_int64_t tcps_sc_seedrandom; u_int64_t tcps_sc_hash_size; u_int64_t tcps_sc_entry_count; u_int64_t tcps_sc_entry_limit; u_int64_t tcps_sc_bucket_maxlen; u_int64_t tcps_sc_bucket_limit; u_int64_t tcps_sc_uses_left; u_int64_t tcps_conndrained; u_int64_t tcps_sack_recovery_episode; u_int64_t tcps_sack_rexmits; u_int64_t tcps_sack_rexmit_bytes; u_int64_t tcps_sack_rcv_opts; u_int64_t tcps_sack_snd_opts; }; struct tcp_ident_mapping { struct sockaddr_storage faddr, laddr; int euid, ruid; u_int rdomain; }; enum tcpstat_counters { tcps_connattempt, tcps_accepts, tcps_connects, tcps_drops, tcps_conndrops, tcps_closed, tcps_segstimed, tcps_rttupdated, tcps_delack, tcps_timeoutdrop, tcps_rexmttimeo, tcps_persisttimeo, tcps_persistdrop, tcps_keeptimeo, tcps_keepprobe, tcps_keepdrops, tcps_sndtotal, tcps_sndpack, tcps_sndbyte, tcps_sndrexmitpack, tcps_sndrexmitbyte, tcps_sndrexmitfast, tcps_sndacks, tcps_sndprobe, tcps_sndurg, tcps_sndwinup, tcps_sndctrl, tcps_rcvtotal, tcps_rcvpack, tcps_rcvbyte, tcps_rcvbadsum, tcps_rcvbadoff, tcps_rcvmemdrop, tcps_rcvnosec, tcps_rcvshort, tcps_rcvduppack, tcps_rcvdupbyte, tcps_rcvpartduppack, tcps_rcvpartdupbyte, tcps_rcvoopack, tcps_rcvoobyte, tcps_rcvpackafterwin, tcps_rcvbyteafterwin, tcps_rcvafterclose, tcps_rcvwinprobe, tcps_rcvdupack, tcps_rcvacktoomuch, tcps_rcvacktooold, tcps_rcvackpack, tcps_rcvackbyte, tcps_rcvwinupd, tcps_pawsdrop, tcps_predack, tcps_preddat, tcps_pcbhashmiss, tcps_noport, tcps_badsyn, tcps_dropsyn, tcps_rcvbadsig, tcps_rcvgoodsig, tcps_inswcsum, tcps_outswcsum, tcps_ecn_accepts, tcps_ecn_rcvece, tcps_ecn_rcvcwr, tcps_ecn_rcvce, tcps_ecn_sndect, tcps_ecn_sndece, tcps_ecn_sndcwr, tcps_cwr_ecn, tcps_cwr_frecovery, tcps_cwr_timeout, tcps_sc_added, tcps_sc_completed, tcps_sc_timed_out, tcps_sc_overflowed, tcps_sc_reset, tcps_sc_unreach, tcps_sc_bucketoverflow, tcps_sc_aborted, tcps_sc_dupesyn, tcps_sc_dropped, tcps_sc_collisions, tcps_sc_retransmitted, tcps_sc_seedrandom, tcps_sc_hash_size, tcps_sc_entry_count, tcps_sc_entry_limit, tcps_sc_bucket_maxlen, tcps_sc_bucket_limit, tcps_sc_uses_left, tcps_conndrained, tcps_sack_recovery_episode, tcps_sack_rexmits, tcps_sack_rexmit_bytes, tcps_sack_rcv_opts, tcps_sack_snd_opts, tcps_ncounters, }; extern struct cpumem *tcpcounters; static inline void tcpstat_inc(enum tcpstat_counters c) { counters_inc(tcpcounters, c); } static inline void tcpstat_add(enum tcpstat_counters c, uint64_t v) { counters_add(tcpcounters, c, v); } static inline void tcpstat_pkt(enum tcpstat_counters pcounter, enum tcpstat_counters bcounter, uint64_t v) { counters_pkt(tcpcounters, pcounter, bcounter, v); } extern struct pool tcpcb_pool; extern struct inpcbtable tcbtable; extern u_int32_t tcp_now; extern int tcp_do_rfc1323; extern int tcptv_keep_init; extern int tcp_mssdflt; extern int tcp_rst_ppslim; extern int tcp_ack_on_push; extern int tcp_do_sack; extern struct pool sackhl_pool; extern int tcp_sackhole_limit; extern int tcp_do_ecn; extern int tcp_do_rfc3390; extern struct pool tcpqe_pool; extern int tcp_reass_limit; extern int tcp_syn_hash_size; extern int tcp_syn_cache_limit; extern int tcp_syn_bucket_limit; extern int tcp_syn_use_limit; extern struct syn_cache_set tcp_syn_cache[]; extern int tcp_syn_cache_active; void tcp_canceltimers(struct tcpcb *); struct tcpcb * tcp_close(struct tcpcb *); int tcp_freeq(struct tcpcb *); void tcp6_ctlinput(int, struct sockaddr *, u_int, void *); void tcp_ctlinput(int, struct sockaddr *, u_int, void *); int tcp_ctloutput(int, struct socket *, int, int, struct mbuf *); struct tcpcb * tcp_disconnect(struct tcpcb *); struct tcpcb * tcp_drop(struct tcpcb *, int); int tcp_dooptions(struct tcpcb *, u_char *, int, struct tcphdr *, struct mbuf *, int, struct tcp_opt_info *, u_int); void tcp_init(void); int tcp_input(struct mbuf **, int *, int, int); int tcp_mss(struct tcpcb *, int); void tcp_mss_update(struct tcpcb *); u_int tcp_hdrsz(struct tcpcb *); void tcp_mtudisc(struct inpcb *, int); void tcp_mtudisc_increase(struct inpcb *, int); void tcp6_mtudisc(struct inpcb *, int); void tcp6_mtudisc_callback(struct sockaddr_in6 *, u_int); struct tcpcb * tcp_newtcpcb(struct inpcb *); void tcp_notify(struct inpcb *, int); int tcp_output(struct tcpcb *); void tcp_pulloutofband(struct socket *, u_int, struct mbuf *, int); int tcp_reass(struct tcpcb *, struct tcphdr *, struct mbuf *, int *); void tcp_rscale(struct tcpcb *, u_long); void tcp_respond(struct tcpcb *, caddr_t, struct tcphdr *, tcp_seq, tcp_seq, int, u_int); void tcp_setpersist(struct tcpcb *); void tcp_update_sndspace(struct tcpcb *); void tcp_update_rcvspace(struct tcpcb *); void tcp_slowtimo(void); struct mbuf * tcp_template(struct tcpcb *); void tcp_trace(short, short, struct tcpcb *, caddr_t, int, int); struct tcpcb * tcp_usrclosed(struct tcpcb *); int tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int tcp_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int tcp_attach(struct socket *, int); int tcp_detach(struct socket *); void tcp_xmit_timer(struct tcpcb *, int); void tcpdropoldhalfopen(struct tcpcb *, u_int16_t); void tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int); void tcp_update_sack_list(struct tcpcb *tp, tcp_seq, tcp_seq); void tcp_del_sackholes(struct tcpcb *, struct tcphdr *); void tcp_clean_sackreport(struct tcpcb *tp); void tcp_sack_adjust(struct tcpcb *tp); struct sackhole * tcp_sack_output(struct tcpcb *tp); u_long tcp_seq_subtract(u_long, u_long ); void tcp_set_iss_tsm(struct tcpcb *); void syn_cache_unreach(struct sockaddr *, struct sockaddr *, struct tcphdr *, u_int); void syn_cache_init(void); void syn_cache_cleanup(struct tcpcb *); struct udphdr { u_int16_t uh_sport; u_int16_t uh_dport; u_int16_t uh_ulen; u_int16_t uh_sum; }; struct udpiphdr { struct ipovly ui_i; struct udphdr ui_u; }; struct udpstat { u_long udps_ipackets; u_long udps_hdrops; u_long udps_badsum; u_long udps_nosum; u_long udps_badlen; u_long udps_noport; u_long udps_noportbcast; u_long udps_nosec; u_long udps_fullsock; u_long udps_pcbhashmiss; u_long udps_inswcsum; u_long udps_opackets; u_long udps_outswcsum; }; enum udpstat_counters { udps_ipackets, udps_hdrops, udps_badsum, udps_nosum, udps_badlen, udps_noport, udps_noportbcast, udps_nosec, udps_fullsock, udps_pcbhashmiss, udps_inswcsum, udps_opackets, udps_outswcsum, udps_ncounters }; extern struct cpumem *udpcounters; static inline void udpstat_inc(enum udpstat_counters c) { counters_inc(udpcounters, c); } extern struct inpcbtable udbtable; extern struct udpstat udpstat; void udp6_ctlinput(int, struct sockaddr *, u_int, void *); void udp_ctlinput(int, struct sockaddr *, u_int, void *); void udp_init(void); int udp_input(struct mbuf **, int *, int, int); int udp6_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *); int udp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int udp_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int udp_attach(struct socket *, int); int udp_detach(struct socket *); struct ahstat { uint64_t ahs_hdrops; uint64_t ahs_nopf; uint64_t ahs_notdb; uint64_t ahs_badkcr; uint64_t ahs_badauth; uint64_t ahs_noxform; uint64_t ahs_qfull; uint64_t ahs_wrap; uint64_t ahs_replay; uint64_t ahs_badauthl; uint64_t ahs_input; uint64_t ahs_output; uint64_t ahs_invalid; uint64_t ahs_ibytes; uint64_t ahs_obytes; uint64_t ahs_toobig; uint64_t ahs_pdrops; uint64_t ahs_crypto; uint64_t ahs_outfail; }; struct ah { u_int8_t ah_nh; u_int8_t ah_hl; u_int16_t ah_rv; u_int32_t ah_spi; u_int32_t ah_rpl; }; enum ahstat_counters { ahs_hdrops, ahs_nopf, ahs_notdb, ahs_badkcr, ahs_badauth, ahs_noxform, ahs_qfull, ahs_wrap, ahs_replay, ahs_badauthl, ahs_input, ahs_output, ahs_invalid, ahs_ibytes, ahs_obytes, ahs_toobig, ahs_pdrops, ahs_crypto, ahs_outfail, ahs_ncounters }; extern struct cpumem *ahcounters; static inline void ahstat_inc(enum ahstat_counters c) { counters_inc(ahcounters, c); } static inline void ahstat_add(enum ahstat_counters c, uint64_t v) { counters_add(ahcounters, c, v); } extern int ah_enable; struct espstat { uint64_t esps_hdrops; uint64_t esps_nopf; uint64_t esps_notdb; uint64_t esps_badkcr; uint64_t esps_qfull; uint64_t esps_noxform; uint64_t esps_badilen; uint64_t esps_wrap; uint64_t esps_badenc; uint64_t esps_badauth; uint64_t esps_replay; uint64_t esps_input; uint64_t esps_output; uint64_t esps_invalid; uint64_t esps_ibytes; uint64_t esps_obytes; uint64_t esps_toobig; uint64_t esps_pdrops; uint64_t esps_crypto; uint64_t esps_udpencin; uint64_t esps_udpencout; uint64_t esps_udpinval; uint64_t esps_udpneeded; uint64_t esps_outfail; }; enum espstat_counters { esps_hdrops, esps_nopf, esps_notdb, esps_badkcr, esps_qfull, esps_noxform, esps_badilen, esps_wrap, esps_badenc, esps_badauth, esps_replay, esps_input, esps_output, esps_invalid, esps_ibytes, esps_obytes, esps_toobig, esps_pdrops, esps_crypto, esps_udpencin, esps_udpencout, esps_udpinval, esps_udpneeded, esps_outfail, esps_ncounters }; extern struct cpumem *espcounters; static inline void espstat_inc(enum espstat_counters c) { counters_inc(espcounters, c); } static inline void espstat_add(enum espstat_counters c, uint64_t v) { counters_add(espcounters, c, v); } extern int esp_enable; extern int udpencap_enable; extern int udpencap_port; struct ipipstat { u_int64_t ipips_ipackets; u_int64_t ipips_opackets; u_int64_t ipips_hdrops; u_int64_t ipips_qfull; u_int64_t ipips_ibytes; u_int64_t ipips_obytes; u_int64_t ipips_pdrops; u_int64_t ipips_spoof; u_int64_t ipips_family; u_int64_t ipips_unspec; }; enum ipipstat_counters { ipips_ipackets, ipips_opackets, ipips_hdrops, ipips_qfull, ipips_ibytes, ipips_obytes, ipips_pdrops, ipips_spoof, ipips_family, ipips_unspec, ipips_ncounters }; extern struct cpumem *ipipcounters; static inline void ipipstat_inc(enum ipipstat_counters c) { counters_inc(ipipcounters, c); } static inline void ipipstat_add(enum ipipstat_counters c, uint64_t v) { counters_add(ipipcounters, c, v); } void ipip_init(void); int ipip_input(struct mbuf **, int *, int, int); int ipip_input_if(struct mbuf **, int *, int, int, struct ifnet *); int ipip_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int ipip_sysctl(int *, u_int, void *, size_t *, void *, size_t); extern int ipip_allow; struct in6_addrlifetime { time_t ia6t_expire; time_t ia6t_preferred; u_int32_t ia6t_vltime; u_int32_t ia6t_pltime; }; struct nd_ifinfo; struct in6_ifextra { struct nd_ifinfo *nd_ifinfo; void *rs_lhcookie; int nprefixes; int ndefrouters; }; struct in6_ifaddr { struct ifaddr ia_ifa; struct sockaddr_in6 ia_addr; struct sockaddr_in6 ia_dstaddr; struct sockaddr_in6 ia_prefixmask; struct { struct in6_ifaddr *tqe_next; struct in6_ifaddr **tqe_prev; } ia_list; int ia6_flags; struct in6_addrlifetime ia6_lifetime; time_t ia6_createtime; time_t ia6_updatetime; struct { struct in6_multi_mship *lh_first; } ia6_memberships; }; struct in6_ifstat { u_int64_t ifs6_in_receive; u_int64_t ifs6_in_hdrerr; u_int64_t ifs6_in_toobig; u_int64_t ifs6_in_noroute; u_int64_t ifs6_in_addrerr; u_int64_t ifs6_in_protounknown; u_int64_t ifs6_in_truncated; u_int64_t ifs6_in_discard; u_int64_t ifs6_in_deliver; u_int64_t ifs6_out_forward; u_int64_t ifs6_out_request; u_int64_t ifs6_out_discard; u_int64_t ifs6_out_fragok; u_int64_t ifs6_out_fragfail; u_int64_t ifs6_out_fragcreat; u_int64_t ifs6_reass_reqd; u_int64_t ifs6_reass_ok; u_int64_t ifs6_reass_fail; u_int64_t ifs6_in_mcast; u_int64_t ifs6_out_mcast; }; struct icmp6_ifstat { u_int64_t ifs6_in_msg; u_int64_t ifs6_in_error; u_int64_t ifs6_in_dstunreach; u_int64_t ifs6_in_adminprohib; u_int64_t ifs6_in_timeexceed; u_int64_t ifs6_in_paramprob; u_int64_t ifs6_in_pkttoobig; u_int64_t ifs6_in_echo; u_int64_t ifs6_in_echoreply; u_int64_t ifs6_in_routersolicit; u_int64_t ifs6_in_routeradvert; u_int64_t ifs6_in_neighborsolicit; u_int64_t ifs6_in_neighboradvert; u_int64_t ifs6_in_redirect; u_int64_t ifs6_in_mldquery; u_int64_t ifs6_in_mldreport; u_int64_t ifs6_in_mlddone; u_int64_t ifs6_out_msg; u_int64_t ifs6_out_error; u_int64_t ifs6_out_dstunreach; u_int64_t ifs6_out_adminprohib; u_int64_t ifs6_out_timeexceed; u_int64_t ifs6_out_paramprob; u_int64_t ifs6_out_pkttoobig; u_int64_t ifs6_out_echo; u_int64_t ifs6_out_echoreply; u_int64_t ifs6_out_routersolicit; u_int64_t ifs6_out_routeradvert; u_int64_t ifs6_out_neighborsolicit; u_int64_t ifs6_out_neighboradvert; u_int64_t ifs6_out_redirect; u_int64_t ifs6_out_mldquery; u_int64_t ifs6_out_mldreport; u_int64_t ifs6_out_mlddone; }; struct in6_ifreq { char ifr_name[16]; union { struct sockaddr_in6 ifru_addr; struct sockaddr_in6 ifru_dstaddr; short ifru_flags; int ifru_flags6; int ifru_metric; caddr_t ifru_data; struct in6_addrlifetime ifru_lifetime; struct in6_ifstat ifru_stat; struct icmp6_ifstat ifru_icmp6stat; } ifr_ifru; }; struct in6_aliasreq { char ifra_name[16]; union { struct sockaddr_in6 ifrau_addr; int ifrau_align; } ifra_ifrau; struct sockaddr_in6 ifra_dstaddr; struct sockaddr_in6 ifra_prefixmask; int ifra_flags; struct in6_addrlifetime ifra_lifetime; }; struct in6_multi_mship { struct in6_multi *i6mm_maddr; struct { struct in6_multi_mship *le_next; struct in6_multi_mship **le_prev; } i6mm_chain; }; struct in6_multi { struct ifmaddr in6m_ifma; struct sockaddr_in6 in6m_sin; u_int in6m_state; u_int in6m_timer; }; static __inline struct in6_multi * ifmatoin6m(struct ifmaddr *ifma) { return ((struct in6_multi *)(ifma)); } struct in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *, int *); void in6_delmulti(struct in6_multi *); int in6_hasmulti(struct in6_addr *, struct ifnet *); struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *, int *); void in6_leavegroup(struct in6_multi_mship *); int in6_control(struct socket *, u_long, caddr_t, struct ifnet *); int in6_ioctl(u_long, caddr_t, struct ifnet *, int); int in6_update_ifa(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *); void in6_purgeaddr(struct ifaddr *); int in6if_do_dad(struct ifnet *); void *in6_domifattach(struct ifnet *); void in6_domifdetach(struct ifnet *, void *); struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int); struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, struct in6_addr *); int in6_addr2scopeid(unsigned int, struct in6_addr *); int in6_matchlen(struct in6_addr *, struct in6_addr *); void in6_prefixlen2mask(struct in6_addr *, int); void in6_purgeprefix(struct ifnet *); struct nd_ifinfo { u_int32_t basereachable; u_int32_t reachable; u_int32_t retrans; int recalctm; u_int8_t initialized; }; struct in6_nbrinfo { char ifname[16]; struct in6_addr addr; time_t expire; long asked; int isrouter; int state; }; struct prf_ra { u_int onlink : 1; u_int autonomous : 1; u_int router : 1; u_int reserved : 5; }; struct in6_ndireq { char ifname[16]; struct nd_ifinfo ndi; }; struct in6_ndifreq { char ifname[16]; u_long ifindex; }; struct llinfo_nd6 { struct { struct llinfo_nd6 *tqe_next; struct llinfo_nd6 **tqe_prev; } ln_list; struct rtentry *ln_rt; struct mbuf *ln_hold; long ln_asked; int ln_byhint; short ln_state; short ln_router; }; extern int nd6_delay; extern int nd6_umaxtries; extern int nd6_mmaxtries; extern int nd6_maxnudhint; extern int nd6_gctimer; extern int nd6_debug; union nd_opts { struct nd_opt_hdr *nd_opt_array[9]; struct { struct nd_opt_hdr *zero; struct nd_opt_hdr *src_lladdr; struct nd_opt_hdr *tgt_lladdr; struct nd_opt_prefix_info *pi_beg; struct nd_opt_rd_hdr *rh; struct nd_opt_mtu *mtu; struct nd_opt_hdr *search; struct nd_opt_hdr *last; int done; struct nd_opt_prefix_info *pi_end; } nd_opt_each; }; void nd6_init(void); struct nd_ifinfo *nd6_ifattach(struct ifnet *); void nd6_ifdetach(struct nd_ifinfo *); int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *); void nd6_option_init(void *, int, union nd_opts *); struct nd_opt_hdr *nd6_option(union nd_opts *); int nd6_options(union nd_opts *); struct rtentry *nd6_lookup(struct in6_addr *, int, struct ifnet *, u_int); void nd6_setmtu(struct ifnet *); void nd6_llinfo_settimer(struct llinfo_nd6 *, unsigned int); void nd6_purge(struct ifnet *); void nd6_nud_hint(struct rtentry *); void nd6_rtrequest(struct ifnet *, int, struct rtentry *); int nd6_ioctl(u_long, caddr_t, struct ifnet *); void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, char *, int, int, int); int nd6_resolve(struct ifnet *, struct rtentry *, struct mbuf *, struct sockaddr *, u_char *); int nd6_need_cache(struct ifnet *); void nd6_na_input(struct mbuf *, int, int); void nd6_na_output(struct ifnet *, struct in6_addr *, struct in6_addr *, u_long, int, struct sockaddr *); void nd6_ns_input(struct mbuf *, int, int); void nd6_ns_output(struct ifnet *, struct in6_addr *, struct in6_addr *, struct llinfo_nd6 *, int); caddr_t nd6_ifptomac(struct ifnet *); void nd6_dad_start(struct ifaddr *); void nd6_dad_stop(struct ifaddr *); void nd6_rtr_cache(struct mbuf *, int, int, int); int in6_ifdel(struct ifnet *, struct in6_addr *); void rt6_flush(struct in6_addr *, struct ifnet *); void nd6_expire_timer_update(struct in6_ifaddr *); struct mbuf; struct sockaddr; struct socket; struct domain; struct proc; struct ip6_hdr; struct icmp6_hdr; struct in6_addr; struct ip6ctlparam { struct mbuf *ip6c_m; struct icmp6_hdr *ip6c_icmp6; struct ip6_hdr *ip6c_ip6; int ip6c_off; struct sockaddr_in6 *ip6c_src; struct sockaddr_in6 *ip6c_dst; struct in6_addr *ip6c_finaldst; void *ip6c_cmdarg; u_int8_t ip6c_nxt; }; extern u_char ip6_protox[]; extern const struct protosw inet6sw[]; struct gif_softc { struct ifnet gif_if; struct sockaddr *gif_psrc; struct sockaddr *gif_pdst; u_int gif_rtableid; struct { struct gif_softc *le_next; struct gif_softc **le_prev; } gif_list; }; extern struct gif_softc_head { struct gif_softc *lh_first; } gif_softc_list; int gif_encap(struct ifnet *, struct mbuf **, sa_family_t); int in_gif_input(struct mbuf **, int *, int, int); int in6_gif_input(struct mbuf **, int *, int, int); struct carp_header { u_int carp_type:4, carp_version:4; u_int8_t carp_vhid; u_int8_t carp_advskew; u_int8_t carp_authlen; u_int8_t carp_demote; u_int8_t carp_advbase; u_int16_t carp_cksum; u_int32_t carp_counter[2]; unsigned char carp_md[20]; } __attribute__((__packed__)); struct carpstats { u_int64_t carps_ipackets; u_int64_t carps_ipackets6; u_int64_t carps_badif; u_int64_t carps_badttl; u_int64_t carps_hdrops; u_int64_t carps_badsum; u_int64_t carps_badver; u_int64_t carps_badlen; u_int64_t carps_badauth; u_int64_t carps_badvhid; u_int64_t carps_badaddrs; u_int64_t carps_opackets; u_int64_t carps_opackets6; u_int64_t carps_onomem; u_int64_t carps_ostates; u_int64_t carps_preempt; }; struct carpreq { int carpr_state; char carpr_carpdev[16]; u_int8_t carpr_vhids[32]; u_int8_t carpr_advskews[32]; u_int8_t carpr_states[32]; u_int8_t carpr_balancing; int carpr_advbase; unsigned char carpr_key[20]; struct in_addr carpr_peer; }; enum carpstat_counters { carps_ipackets, carps_ipackets6, carps_badif, carps_badttl, carps_hdrops, carps_badsum, carps_badver, carps_badlen, carps_badauth, carps_badvhid, carps_badaddrs, carps_opackets, carps_opackets6, carps_onomem, carps_ostates, carps_preempt, carps_ncounters, }; extern struct cpumem *carpcounters; static inline void carpstat_inc(enum carpstat_counters c) { counters_inc(carpcounters, c); } int carp_proto_input(struct mbuf **, int *, int, int); void carp_carpdev_state(void *); void carp_group_demote_adj(struct ifnet *, int, char *); int carp6_proto_input(struct mbuf **, int *, int, int); int carp_iamatch(struct ifnet *); int carp_ourether(struct ifnet *, u_int8_t *); int carp_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int carp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int carp_lsdrop(struct mbuf *, sa_family_t, u_int32_t *, u_int32_t *, int); struct div6stat { u_long divs_ipackets; u_long divs_noport; u_long divs_fullsock; u_long divs_opackets; u_long divs_errors; }; enum div6stat_counters { div6s_ipackets, div6s_noport, div6s_fullsock, div6s_opackets, div6s_errors, div6s_ncounters, }; extern struct cpumem *div6counters; static inline void div6stat_inc(enum div6stat_counters c) { counters_inc(div6counters, c); } extern struct inpcbtable divb6table; void divert6_init(void); int divert6_packet(struct mbuf *, int, u_int16_t); int divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t); int divert6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int divert6_attach(struct socket *, int); int divert6_detach(struct socket *); u_char ip6_protox[256]; const struct protosw inet6sw[] = { { .pr_domain = &inet6domain, .pr_protocol = 41, .pr_init = ip6_init, .pr_slowtimo = frag6_slowtimo, .pr_sysctl = ip6_sysctl }, { .pr_type = 2, .pr_domain = &inet6domain, .pr_protocol = 17, .pr_flags = 0x01|0x02|0x40, .pr_input = udp_input, .pr_ctlinput = udp6_ctlinput, .pr_ctloutput = ip6_ctloutput, .pr_usrreq = udp_usrreq, .pr_attach = udp_attach, .pr_detach = udp_detach, .pr_sysctl = udp_sysctl }, { .pr_type = 1, .pr_domain = &inet6domain, .pr_protocol = 6, .pr_flags = 0x04|0x08|0x20|0x40, .pr_input = tcp_input, .pr_ctlinput = tcp6_ctlinput, .pr_ctloutput = tcp_ctloutput, .pr_usrreq = tcp_usrreq, .pr_attach = tcp_attach, .pr_detach = tcp_detach, .pr_sysctl = tcp_sysctl }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 255, .pr_flags = 0x01|0x02, .pr_input = rip6_input, .pr_ctlinput = rip6_ctlinput, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, .pr_sysctl = rip6_sysctl }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 58, .pr_flags = 0x01|0x02, .pr_input = icmp6_input, .pr_ctlinput = rip6_ctlinput, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, .pr_init = icmp6_init, .pr_fasttimo = icmp6_fasttimo, .pr_sysctl = icmp6_sysctl }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 60, .pr_flags = 0x01|0x02, .pr_input = dest6_input }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 43, .pr_flags = 0x01|0x02, .pr_input = route6_input }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 44, .pr_flags = 0x01|0x02, .pr_input = frag6_input }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 4, .pr_flags = 0x01|0x02, .pr_input = in6_gif_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 41, .pr_flags = 0x01|0x02, .pr_input = in6_gif_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 112, .pr_flags = 0x01|0x02, .pr_input = carp6_proto_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, .pr_sysctl = carp_sysctl }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 258, .pr_flags = 0x01|0x02, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = divert6_usrreq, .pr_attach = divert6_attach, .pr_detach = divert6_detach, .pr_init = divert6_init, .pr_sysctl = divert6_sysctl }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_protocol = 97, .pr_flags = 0x01|0x02, .pr_input = ip6_etherip_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, }, { .pr_type = 3, .pr_domain = &inet6domain, .pr_flags = 0x01|0x02, .pr_input = rip6_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreq = rip6_usrreq, .pr_attach = rip6_attach, .pr_detach = rip6_detach, .pr_init = rip6_init } }; struct domain inet6domain = { .dom_family = 24, .dom_name = "internet6", .dom_protosw = inet6sw, .dom_protoswNPROTOSW = &inet6sw[(sizeof((inet6sw)) / sizeof((inet6sw)[0]))], .dom_rtkeylen = sizeof(struct sockaddr_in6), .dom_rtoffset = __builtin_offsetof(struct sockaddr_in6, sin6_addr), .dom_maxplen = 128, .dom_ifattach = in6_domifattach, .dom_ifdetach = in6_domifdetach }; int ip6_forwarding = 0; int ip6_mforwarding = 0; int ip6_multipath = 0; int ip6_sendredirects = 1; int ip6_defhlim = 64; int ip6_defmcasthlim = 1; int ip6_maxfragpackets = 200; int ip6_maxfrags = 200; int ip6_log_interval = 5; int ip6_hdrnestlimit = 10; int ip6_dad_count = 1; int ip6_dad_pending; int ip6_auto_flowlabel = 1; int ip6_use_deprecated = 1; int ip6_mcast_pmtu = 0; int ip6_neighborgcthresh = 2048; int ip6_maxdynroutes = 4096; time_t ip6_log_time = (time_t)0L; u_long rip6_sendspace = 8192; u_long rip6_recvspace = 8192; int icmp6_redirtimeout = 10 * 60; int icmp6errppslim = 100; int ip6_mtudisc_timeout = (10 * 60); struct icmp_ra_addr { u_int32_t ira_addr; u_int32_t ira_preference; }; struct icmp { u_int8_t icmp_type; u_int8_t icmp_code; u_int16_t icmp_cksum; union { u_int8_t ih_pptr; struct ih_exthdr { u_int8_t iex_pad; u_int8_t iex_length; } ih_exthdr; struct in_addr ih_gwaddr; struct ih_idseq { u_int16_t icd_id; u_int16_t icd_seq; } ih_idseq; int32_t ih_void; struct ih_pmtu { u_int16_t ipm_void; u_int16_t ipm_nextmtu; } ih_pmtu; struct ih_rtradv { u_int8_t irt_num_addrs; u_int8_t irt_wpa; u_int16_t irt_lifetime; } ih_rtradv; } icmp_hun; union { struct id_ts { u_int32_t its_otime; u_int32_t its_rtime; u_int32_t its_ttime; } id_ts; struct id_ip { struct ip idi_ip; } id_ip; u_int32_t id_mask; int8_t id_data[1]; } icmp_dun; }; struct icmp_ext_hdr { u_int8_t ieh_version; u_int8_t ieh_res; u_int16_t ieh_cksum; }; struct icmp_ext_obj_hdr { u_int16_t ieo_length; u_int8_t ieo_cnum; u_int8_t ieo_ctype; }; struct mbuf * icmp_do_error(struct mbuf *, int, int, u_int32_t, int); void icmp_error(struct mbuf *, int, int, u_int32_t, int); int icmp_input(struct mbuf **, int *, int, int); void icmp_init(void); int icmp_reflect(struct mbuf *, struct mbuf **, struct in_ifaddr *); void icmp_send(struct mbuf *, struct mbuf *); int icmp_sysctl(int *, u_int, void *, size_t *, void *, size_t); struct rtentry * icmp_mtudisc_clone(struct in_addr, u_int); void icmp_mtudisc(struct icmp *, u_int); int icmp_do_exthdr(struct mbuf *, u_int16_t, u_int8_t, void *, size_t); struct igmpstat { u_long igps_rcv_total; u_long igps_rcv_tooshort; u_long igps_rcv_badsum; u_long igps_rcv_queries; u_long igps_rcv_badqueries; u_long igps_rcv_reports; u_long igps_rcv_badreports; u_long igps_rcv_ourreports; u_long igps_snd_reports; }; enum igmpstat_counters { igps_rcv_total, igps_rcv_tooshort, igps_rcv_badsum, igps_rcv_queries, igps_rcv_badqueries, igps_rcv_reports, igps_rcv_badreports, igps_rcv_ourreports, igps_snd_reports, igps_ncounters }; extern struct cpumem *igmpcounters; static inline void igmpstat_inc(enum igmpstat_counters c) { counters_inc(igmpcounters, c); } void igmp_init(void); int igmp_input(struct mbuf **, int *, int, int); void igmp_joingroup(struct in_multi *); void igmp_leavegroup(struct in_multi *); void igmp_fasttimo(void); void igmp_slowtimo(void); int igmp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int gre_input(struct mbuf **, int *, int, int); int gre_mobile_input(struct mbuf **, int *, int, int); int ipmobile_sysctl(int *, u_int, void *, size_t *, void *, size_t); int gre_sysctl(int *, u_int, void *, size_t *, void *, size_t); int gre_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); struct gre_softc { struct ifnet sc_if; struct { struct gre_softc *le_next; struct gre_softc **le_prev; } sc_list; struct timeout sc_ka_hold; struct timeout sc_ka_snd; struct in_addr g_src; struct in_addr g_dst; struct route route; u_int g_rtableid; int gre_unit; int gre_flags; int sc_ka_timout; int sc_ka_holdmax; int sc_ka_holdcnt; int sc_ka_cnt; u_char g_proto; u_char sc_ka_state; }; struct gre_h { u_int16_t flags; u_int16_t ptype; } __attribute__((__packed__)); struct greip { struct ip gi_i; struct gre_h gi_g; } __attribute__((__packed__)); struct gre_sre { u_int16_t sre_family; u_char sre_offset; u_char sre_length; u_char *sre_rtinfo; }; struct greioctl { int unit; struct in_addr addr; }; struct mobile_h { u_int16_t proto; u_int16_t hcrc; u_int32_t odst; u_int32_t osrc; } __attribute__((__packed__)); struct mobip_h { struct ip mi; struct mobile_h mh; } __attribute__((__packed__)); extern struct gre_softc_head { struct gre_softc *lh_first; } gre_softc_list; extern int gre_allow; extern int gre_wccp; extern int ip_mobile_allow; void greattach(int); int gre_ioctl(struct ifnet *, u_long, caddr_t); int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); u_int16_t gre_in_cksum(u_int16_t *, u_int); void gre_recv_keepalive(struct gre_softc *); struct pfsync_header { u_int8_t version; u_int8_t _pad; u_int16_t len; u_int8_t pfcksum[16]; } __attribute__((__packed__)); struct pfsync_subheader { u_int8_t action; u_int8_t len; u_int16_t count; } __attribute__((__packed__)); struct pfsync_clr { char ifname[16]; u_int32_t creatorid; } __attribute__((__packed__)); struct pfsync_ins_ack { u_int64_t id; u_int32_t creatorid; } __attribute__((__packed__)); struct pfsync_upd_c { u_int64_t id; struct pfsync_state_peer src; struct pfsync_state_peer dst; u_int32_t creatorid; u_int32_t expire; u_int8_t timeout; u_int8_t state_flags; u_int8_t _pad[2]; } __attribute__((__packed__)); struct pfsync_upd_req { u_int64_t id; u_int32_t creatorid; } __attribute__((__packed__)); struct pfsync_del_c { u_int64_t id; u_int32_t creatorid; } __attribute__((__packed__)); struct pfsync_bus { u_int32_t creatorid; u_int32_t endtime; u_int8_t status; u_int8_t _pad[3]; } __attribute__((__packed__)); struct pfsync_tdb { u_int32_t spi; union sockaddr_union dst; u_int64_t rpl; u_int64_t cur_bytes; u_int8_t sproto; u_int8_t updates; u_int16_t rdomain; } __attribute__((__packed__)); struct pfsyncstats { u_int64_t pfsyncs_ipackets; u_int64_t pfsyncs_ipackets6; u_int64_t pfsyncs_badif; u_int64_t pfsyncs_badttl; u_int64_t pfsyncs_hdrops; u_int64_t pfsyncs_badver; u_int64_t pfsyncs_badact; u_int64_t pfsyncs_badlen; u_int64_t pfsyncs_badauth; u_int64_t pfsyncs_stale; u_int64_t pfsyncs_badval; u_int64_t pfsyncs_badstate; u_int64_t pfsyncs_opackets; u_int64_t pfsyncs_opackets6; u_int64_t pfsyncs_onomem; u_int64_t pfsyncs_oerrors; }; struct pfsyncreq { char pfsyncr_syncdev[16]; struct in_addr pfsyncr_syncpeer; int pfsyncr_maxupdates; int pfsyncr_defer; }; enum pfsync_counters { pfsyncs_ipackets, pfsyncs_ipackets6, pfsyncs_badif, pfsyncs_badttl, pfsyncs_hdrops, pfsyncs_badver, pfsyncs_badact, pfsyncs_badlen, pfsyncs_badauth, pfsyncs_stale, pfsyncs_badval, pfsyncs_badstate, pfsyncs_opackets, pfsyncs_opackets6, pfsyncs_onomem, pfsyncs_oerrors, pfsyncs_ncounters, }; extern struct cpumem *pfsynccounters; static inline void pfsyncstat_inc(enum pfsync_counters c) { counters_inc(pfsynccounters, c); } int pfsync_input(struct mbuf **, int *, int, int); int pfsync_sysctl(int *, u_int, void *, size_t *, void *, size_t); int pfsync_state_import(struct pfsync_state *, int); void pfsync_state_export(struct pfsync_state *, struct pf_state *); void pfsync_insert_state(struct pf_state *); void pfsync_update_state(struct pf_state *); void pfsync_delete_state(struct pf_state *); void pfsync_clear_states(u_int32_t, const char *); void pfsync_update_tdb(struct tdb *, int); void pfsync_delete_tdb(struct tdb *); int pfsync_defer(struct pf_state *, struct mbuf *); int pfsync_up(void); int pfsync_state_in_use(struct pf_state *); struct divstat { u_long divs_ipackets; u_long divs_noport; u_long divs_fullsock; u_long divs_opackets; u_long divs_errors; }; enum divstat_counters { divs_ipackets, divs_noport, divs_fullsock, divs_opackets, divs_errors, divs_ncounters, }; extern struct cpumem *divcounters; static inline void divstat_inc(enum divstat_counters c) { counters_inc(divcounters, c); } extern struct inpcbtable divbtable; void divert_init(void); int divert_packet(struct mbuf *, int, u_int16_t); int divert_sysctl(int *, u_int, void *, size_t *, void *, size_t); int divert_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int divert_attach(struct socket *, int); int divert_detach(struct socket *); u_char ip_protox[256]; const struct protosw inetsw[] = { { .pr_domain = &inetdomain, .pr_init = ip_init, .pr_slowtimo = ip_slowtimo, .pr_sysctl = ip_sysctl }, { .pr_type = 2, .pr_domain = &inetdomain, .pr_protocol = 17, .pr_flags = 0x01|0x02|0x40, .pr_input = udp_input, .pr_ctlinput = udp_ctlinput, .pr_ctloutput = ip_ctloutput, .pr_usrreq = udp_usrreq, .pr_attach = udp_attach, .pr_detach = udp_detach, .pr_init = udp_init, .pr_sysctl = udp_sysctl }, { .pr_type = 1, .pr_domain = &inetdomain, .pr_protocol = 6, .pr_flags = 0x04|0x08|0x20|0x40, .pr_input = tcp_input, .pr_ctlinput = tcp_ctlinput, .pr_ctloutput = tcp_ctloutput, .pr_usrreq = tcp_usrreq, .pr_attach = tcp_attach, .pr_detach = tcp_detach, .pr_init = tcp_init, .pr_slowtimo = tcp_slowtimo, .pr_sysctl = tcp_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 255, .pr_flags = 0x01|0x02, .pr_input = rip_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 1, .pr_flags = 0x01|0x02, .pr_input = icmp_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_init = icmp_init, .pr_sysctl = icmp_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 4, .pr_flags = 0x01|0x02, .pr_input = in_gif_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_sysctl = ipip_sysctl, .pr_init = ipip_init }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 41, .pr_flags = 0x01|0x02, .pr_input = in_gif_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 2, .pr_flags = 0x01|0x02, .pr_input = igmp_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_init = igmp_init, .pr_fasttimo = igmp_fasttimo, .pr_slowtimo = igmp_slowtimo, .pr_sysctl = igmp_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 47, .pr_flags = 0x01|0x02, .pr_input = gre_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = gre_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_sysctl = gre_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 55, .pr_flags = 0x01|0x02, .pr_input = gre_mobile_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_sysctl = ipmobile_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 112, .pr_flags = 0x01|0x02, .pr_input = carp_proto_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_sysctl = carp_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 240, .pr_flags = 0x01|0x02, .pr_input = pfsync_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_sysctl = pfsync_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 258, .pr_flags = 0x01|0x02, .pr_ctloutput = rip_ctloutput, .pr_usrreq = divert_usrreq, .pr_attach = divert_attach, .pr_detach = divert_detach, .pr_init = divert_init, .pr_sysctl = divert_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_protocol = 97, .pr_flags = 0x01|0x02, .pr_input = ip_etherip_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_sysctl = etherip_sysctl }, { .pr_type = 3, .pr_domain = &inetdomain, .pr_flags = 0x01|0x02, .pr_input = rip_input, .pr_ctloutput = rip_ctloutput, .pr_usrreq = rip_usrreq, .pr_attach = rip_attach, .pr_detach = rip_detach, .pr_init = rip_init } }; struct domain inetdomain = { .dom_family = 2, .dom_name = "internet", .dom_protosw = inetsw, .dom_protoswNPROTOSW = &inetsw[(sizeof((inetsw)) / sizeof((inetsw)[0]))], .dom_rtkeylen = sizeof(struct sockaddr_in), .dom_rtoffset = __builtin_offsetof(struct sockaddr_in, sin_addr), .dom_maxplen = 32 }; static inline unsigned int _atomic_cas_uint(volatile unsigned int *p, unsigned int e, unsigned int n) { __asm volatile("lock" " cmpxchgl %2, %1" : "=a" (n), "=m" (*p) : "r" (n), "a" (e), "m" (*p)); return (n); } static inline unsigned long _atomic_cas_ulong(volatile unsigned long *p, unsigned long e, unsigned long n) { __asm volatile("lock" " cmpxchgq %2, %1" : "=a" (n), "=m" (*p) : "r" (n), "a" (e), "m" (*p)); return (n); } static inline void * _atomic_cas_ptr(volatile void *p, void *e, void *n) { __asm volatile("lock" " cmpxchgq %2, %1" : "=a" (n), "=m" (*(unsigned long *)p) : "r" (n), "a" (e), "m" (*(unsigned long *)p)); return (n); } static inline unsigned int _atomic_swap_uint(volatile unsigned int *p, unsigned int n) { __asm volatile("xchgl %0, %1" : "=a" (n), "=m" (*p) : "0" (n), "m" (*p)); return (n); } static inline unsigned long _atomic_swap_ulong(volatile unsigned long *p, unsigned long n) { __asm volatile("xchgq %0, %1" : "=a" (n), "=m" (*p) : "0" (n), "m" (*p)); return (n); } static inline uint64_t _atomic_swap_64(volatile uint64_t *p, uint64_t n) { __asm volatile("xchgq %0, %1" : "=a" (n), "=m" (*p) : "0" (n), "m" (*p)); return (n); } static inline void * _atomic_swap_ptr(volatile void *p, void *n) { __asm volatile("xchgq %0, %1" : "=a" (n), "=m" (*(unsigned long *)p) : "0" (n), "m" (*(unsigned long *)p)); return (n); } static inline void _atomic_inc_int(volatile unsigned int *p) { __asm volatile("lock" " incl %0" : "+m" (*p)); } static inline void _atomic_inc_long(volatile unsigned long *p) { __asm volatile("lock" " incq %0" : "+m" (*p)); } static inline void _atomic_dec_int(volatile unsigned int *p) { __asm volatile("lock" " decl %0" : "+m" (*p)); } static inline void _atomic_dec_long(volatile unsigned long *p) { __asm volatile("lock" " decq %0" : "+m" (*p)); } static inline void _atomic_add_int(volatile unsigned int *p, unsigned int v) { __asm volatile("lock" " addl %1,%0" : "+m" (*p) : "a" (v)); } static inline void _atomic_add_long(volatile unsigned long *p, unsigned long v) { __asm volatile("lock" " addq %1,%0" : "+m" (*p) : "a" (v)); } static inline void _atomic_sub_int(volatile unsigned int *p, unsigned int v) { __asm volatile("lock" " subl %1,%0" : "+m" (*p) : "a" (v)); } static inline void _atomic_sub_long(volatile unsigned long *p, unsigned long v) { __asm volatile("lock" " subq %1,%0" : "+m" (*p) : "a" (v)); } static inline unsigned long _atomic_add_int_nv(volatile unsigned int *p, unsigned int v) { unsigned int rv = v; __asm volatile("lock" " xaddl %0,%1" : "+a" (rv), "+m" (*p)); return (rv + v); } static inline unsigned long _atomic_add_long_nv(volatile unsigned long *p, unsigned long v) { unsigned long rv = v; __asm volatile("lock" " xaddq %0,%1" : "+a" (rv), "+m" (*p)); return (rv + v); } static inline unsigned long _atomic_sub_int_nv(volatile unsigned int *p, unsigned int v) { unsigned int rv = 0 - v; __asm volatile("lock" " xaddl %0,%1" : "+a" (rv), "+m" (*p)); return (rv - v); } static inline unsigned long _atomic_sub_long_nv(volatile unsigned long *p, unsigned long v) { unsigned long rv = 0 - v; __asm volatile("lock" " xaddq %0,%1" : "+a" (rv), "+m" (*p)); return (rv - v); } static __inline void x86_atomic_setbits_u32(volatile u_int32_t *ptr, u_int32_t bits) { __asm volatile("lock" " orl %1,%0" : "=m" (*ptr) : "ir" (bits)); } static __inline void x86_atomic_clearbits_u32(volatile u_int32_t *ptr, u_int32_t bits) { __asm volatile("lock" " andl %1,%0" : "=m" (*ptr) : "ir" (~bits)); } static __inline void x86_atomic_setbits_u64(volatile u_int64_t *ptr, u_int64_t bits) { __asm volatile("lock" " orq %1,%0" : "=m" (*ptr) : "er" (bits)); } static __inline void x86_atomic_clearbits_u64(volatile u_int64_t *ptr, u_int64_t bits) { __asm volatile("lock" " andq %1,%0" : "=m" (*ptr) : "er" (~bits)); } extern int netisr; extern struct task if_input_task_locked; void arpintr(void); void ipintr(void); void ip6intr(void); void pppintr(void); void bridgeintr(void); void pppoeintr(void); void switchintr(void); void pfsyncintr(void); void pipexintr(void); typedef u_int16_t n_short; typedef u_int32_t n_long; typedef u_int32_t n_time; u_int32_t iptime(void); struct in_ifaddr { struct ifaddr ia_ifa; u_int32_t ia_net; u_int32_t ia_netmask; struct { struct in_ifaddr *tqe_next; struct in_ifaddr **tqe_prev; } ia_list; struct sockaddr_in ia_addr; struct sockaddr_in ia_dstaddr; struct sockaddr_in ia_sockmask; struct in_multi *ia_allhosts; }; struct in_aliasreq { char ifra_name[16]; union { struct sockaddr_in ifrau_addr; int ifrau_align; } ifra_ifrau; struct sockaddr_in ifra_dstaddr; struct sockaddr_in ifra_mask; }; struct router_info { unsigned int rti_ifidx; int rti_type; int rti_age; struct router_info *rti_next; }; struct in_multi { struct ifmaddr inm_ifma; struct sockaddr_in inm_sin; u_int inm_state; u_int inm_timer; struct router_info *inm_rti; }; static __inline struct in_multi * ifmatoinm(struct ifmaddr *ifma) { return ((struct in_multi *)(ifma)); } int in_ifinit(struct ifnet *, struct in_ifaddr *, struct sockaddr_in *, int); struct in_multi *in_addmulti(struct in_addr *, struct ifnet *); void in_delmulti(struct in_multi *); int in_hasmulti(struct in_addr *, struct ifnet *); void in_ifscrub(struct ifnet *, struct in_ifaddr *); int in_control(struct socket *, u_long, caddr_t, struct ifnet *); int in_ioctl(u_long, caddr_t, struct ifnet *, int); void in_prefixlen2mask(struct in_addr *, int); typedef u_int32_t vifbitmap_t; typedef u_int16_t vifi_t; struct vifctl { vifi_t vifc_vifi; u_int8_t vifc_flags; u_int8_t vifc_threshold; u_int32_t vifc_rate_limit; struct in_addr vifc_lcl_addr; struct in_addr vifc_rmt_addr; }; struct mfcctl { struct in_addr mfcc_origin; struct in_addr mfcc_mcastgrp; vifi_t mfcc_parent; u_int8_t mfcc_ttls[32]; }; struct mfcctl2 { struct in_addr mfcc_origin; struct in_addr mfcc_mcastgrp; vifi_t mfcc_parent; u_int8_t mfcc_ttls[32]; u_int8_t mfcc_flags[32]; struct in_addr mfcc_rp; }; struct mfcinfo { struct in_addr mfc_origin; struct in_addr mfc_mcastgrp; vifi_t mfc_parent; u_long mfc_pkt_cnt; u_long mfc_byte_cnt; u_int8_t mfc_ttls[32]; }; struct vifinfo { vifi_t v_vifi; u_int8_t v_flags; u_int8_t v_threshold; struct in_addr v_lcl_addr; struct in_addr v_rmt_addr; u_long v_pkt_in; u_long v_pkt_out; u_long v_bytes_in; u_long v_bytes_out; }; struct sioc_sg_req { struct in_addr src; struct in_addr grp; u_long pktcnt; u_long bytecnt; u_long wrong_if; }; struct sioc_vif_req { vifi_t vifi; u_long icount; u_long ocount; u_long ibytes; u_long obytes; }; struct mrtstat { u_long mrts_mfc_lookups; u_long mrts_mfc_misses; u_long mrts_upcalls; u_long mrts_no_route; u_long mrts_bad_tunnel; u_long mrts_cant_tunnel; u_long mrts_wrong_if; u_long mrts_upq_ovflw; u_long mrts_cache_cleanups; u_long mrts_drop_sel; u_long mrts_q_overflow; u_long mrts_pkt2large; u_long mrts_upq_sockfull; }; struct vif { vifi_t v_id; u_int8_t v_flags; u_int8_t v_threshold; struct in_addr v_lcl_addr; struct in_addr v_rmt_addr; u_long v_pkt_in; u_long v_pkt_out; u_long v_bytes_in; u_long v_bytes_out; }; struct mfc { vifi_t mfc_parent; u_long mfc_pkt_cnt; u_long mfc_byte_cnt; u_long mfc_wrong_if; uint8_t mfc_ttl; uint8_t mfc_flags; struct in_addr mfc_rp; u_long mfc_expire; }; struct igmpmsg { u_int32_t unused1; u_int32_t unused2; u_int8_t im_msgtype; u_int8_t im_mbz; u_int8_t im_vif; u_int8_t unused3; struct in_addr im_src, im_dst; }; int ip_mrouter_set(struct socket *, int, struct mbuf *); int ip_mrouter_get(struct socket *, int, struct mbuf *); int mrt_ioctl(struct socket *, u_long, caddr_t); int mrt_sysctl_vif(void *, size_t *); int mrt_sysctl_mfc(void *, size_t *); int ip_mrouter_done(struct socket *); void vif_delete(struct ifnet *); int ipforwarding = 0; int ipmforwarding = 0; int ipmultipath = 0; int ipsendredirects = 1; int ip_dosourceroute = 0; int ip_defttl = 64; int ip_mtudisc = 1; u_int ip_mtudisc_timeout = (10 * 60); int ip_directedbcast = 0; struct rttimer_queue *ip_mtudisc_timeout_q = ((void *)0); struct mutex ipq_mutex = { ((void *)0), ((((0x5)) > 0x0 && ((0x5)) < 0x9) ? 0x9 : ((0x5))), 0x0 }; struct { struct ipq *lh_first; } ipq; int ip_maxqueue = 300; int ip_frags = 0; int *ipctl_vars[41] = { ((void *)0), &ipforwarding, &ipsendredirects, &ip_defttl, ((void *)0), ((void *)0), &ip_directedbcast, &ipport_firstauto, &ipport_lastauto, &ipport_hifirstauto, &ipport_hilastauto, &ip_maxqueue, ((void *)0) , ((void *)0), ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0) , ((void *)0), ((void *)0), ((void *)0), ((void *)0), ((void *)0), ((void *)0), &ipmforwarding, &ipmultipath, ((void *)0), ((void *)0), ((void *)0), &la_hold_total, ((void *)0), ((void *)0), &arpt_keep, &arpt_down, }; struct niqueue ipintrq = { { { ((void *)0), ((((0x7)) > 0x0 && ((0x7)) < 0x9) ? 0x9 : ((0x7))), 0x0 }, { ((void *)0), ((void *)0), 0 }, ((2048)), 0 }, (2) }; struct pool ipqent_pool; struct pool ipq_pool; struct cpumem *ipcounters; int ip_sysctl_ipstat(void *, size_t *, void *); static struct mbuf_queue ipsend_mq; int ip_ours(struct mbuf **, int *, int, int); int ip_local(struct mbuf **, int *, int, int); int ip_dooptions(struct mbuf *, struct ifnet *); int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **); static void ip_send_dispatch(void *); static struct task ipsend_task = {{ ((void *)0), ((void *)0) }, (ip_send_dispatch), (&ipsend_mq), 0 }; struct ip_srcrt { int isr_nhops; struct in_addr isr_dst; char isr_nop; char isr_hdr[2 + 1]; struct in_addr isr_routes[40/sizeof(struct in_addr)]; }; void save_rte(struct mbuf *, u_char *, struct in_addr); void ip_init(void) { const struct protosw *pr; int i; const u_int16_t defbaddynamicports_tcp[] = { 587, 749, 750, 751, 871, 2049, 6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009, 6010, 0 }; const u_int16_t defbaddynamicports_udp[] = { 623, 664, 749, 750, 751, 2049, 3784, 3785, 7784, 0 }; const u_int16_t defrootonlyports_tcp[] = { 2049, 0 }; const u_int16_t defrootonlyports_udp[] = { 2049, 0 }; ipcounters = counters_alloc(ips_ncounters); pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0x5, 0, "ipqe", ((void *)0)); pool_init(&ipq_pool, sizeof(struct ipq), 0, 0x5, 0, "ipq", ((void *)0)); pr = pffindproto(2, 255, 3); if (pr == ((void *)0)) panic("ip_init"); for (i = 0; i < 256; i++) ip_protox[i] = pr - inetsw; for (pr = inetdomain.dom_protosw; pr < inetdomain.dom_protoswNPROTOSW; pr++) if (pr->pr_domain->dom_family == 2 && pr->pr_protocol && pr->pr_protocol != 255 && pr->pr_protocol < 256) ip_protox[pr->pr_protocol] = pr - inetsw; do { ((&ipq)->lh_first) = ((void *)0); } while (0); if (ip_mtudisc != 0) ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); __builtin_memset((&baddynamicports), (0), (sizeof(baddynamicports))); for (i = 0; defbaddynamicports_tcp[i] != 0; i++) ((baddynamicports.tcp)[(defbaddynamicports_tcp[i]) / (sizeof(u_int32_t) * 8)] |= (1 << ((defbaddynamicports_tcp[i]) % (sizeof(u_int32_t) * 8)))); for (i = 0; defbaddynamicports_udp[i] != 0; i++) ((baddynamicports.udp)[(defbaddynamicports_udp[i]) / (sizeof(u_int32_t) * 8)] |= (1 << ((defbaddynamicports_udp[i]) % (sizeof(u_int32_t) * 8)))); __builtin_memset((&rootonlyports), (0), (sizeof(rootonlyports))); for (i = 0; defrootonlyports_tcp[i] != 0; i++) ((rootonlyports.tcp)[(defrootonlyports_tcp[i]) / (sizeof(u_int32_t) * 8)] |= (1 << ((defrootonlyports_tcp[i]) % (sizeof(u_int32_t) * 8)))); for (i = 0; defrootonlyports_udp[i] != 0; i++) ((rootonlyports.udp)[(defrootonlyports_udp[i]) / (sizeof(u_int32_t) * 8)] |= (1 << ((defrootonlyports_udp[i]) % (sizeof(u_int32_t) * 8)))); mq_init(&ipsend_mq, 64, 0x5); } int ip_ours(struct mbuf **mp, int *offp, int nxt, int af) { if (af != 0) return ip_local(mp, offp, nxt, af); niq_enqueue(&ipintrq, *mp); *mp = ((void *)0); return 257; } void ipintr(void) { struct mbuf *m; int off, nxt; while ((m = mq_dequeue(&(&ipintrq)->ni_q)) != ((void *)0)) { if ((m->m_hdr.mh_flags & 0x0002) == 0) panic("ipintr no HDR"); off = 0; nxt = ip_local(&m, &off, 4, 0); ((nxt == 257) ? (void)0 : __assert("diagnostic ", "module.c", 4078, "nxt == IPPROTO_DONE")); } } void ipv4_input(struct ifnet *ifp, struct mbuf *m) { int off, nxt; off = 0; nxt = ip_input_if(&m, &off, 4, 0, ifp); ((nxt == 257) ? (void)0 : __assert("diagnostic ", "module.c", 4094, "nxt == IPPROTO_DONE")); } int ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) { struct mbuf *m = *mp; struct rtentry *rt = ((void *)0); struct ip *ip; int hlen, len; in_addr_t pfrdr = 0; ((*offp == 0) ? (void)0 : __assert("diagnostic ", "module.c", 4106, "*offp == 0")); ipstat_inc(ips_total); if (m->m_hdr.mh_len < sizeof (struct ip) && (m = *mp = m_pullup(m, sizeof (struct ip))) == ((void *)0)) { ipstat_inc(ips_toosmall); goto bad; } ip = ((struct ip *)((m)->m_hdr.mh_data)); if (ip->ip_v != 4) { ipstat_inc(ips_badvers); goto bad; } hlen = ip->ip_hl << 2; if (hlen < sizeof(struct ip)) { ipstat_inc(ips_badhlen); goto bad; } if (hlen > m->m_hdr.mh_len) { if ((m = *mp = m_pullup(m, hlen)) == ((void *)0)) { ipstat_inc(ips_badhlen); goto bad; } ip = ((struct ip *)((m)->m_hdr.mh_data)); } if (((__uint32_t)(__builtin_constant_p(ip->ip_dst.s_addr) ? (__uint32_t)(((__uint32_t)(ip->ip_dst.s_addr) & 0xff) << 24 | ((__uint32_t)(ip->ip_dst.s_addr) & 0xff00) << 8 | ((__uint32_t)(ip->ip_dst.s_addr) & 0xff0000) >> 8 | ((__uint32_t)(ip->ip_dst.s_addr) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = (ip->ip_dst.s_addr); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })) >> 24) == 127 || ((__uint32_t)(__builtin_constant_p(ip->ip_src.s_addr) ? (__uint32_t)(((__uint32_t)(ip->ip_src.s_addr) & 0xff) << 24 | ((__uint32_t)(ip->ip_src.s_addr) & 0xff00) << 8 | ((__uint32_t)(ip->ip_src.s_addr) & 0xff0000) >> 8 | ((__uint32_t)(ip->ip_src.s_addr) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = (ip->ip_src.s_addr); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })) >> 24) == 127) { if ((ifp->if_flags & 0x8) == 0) { ipstat_inc(ips_badaddr); goto bad; } } if ((m->M_dat.MH.MH_pkthdr.csum_flags & 0x0008) == 0) { if (m->M_dat.MH.MH_pkthdr.csum_flags & 0x0010) { ipstat_inc(ips_badsum); goto bad; } ipstat_inc(ips_inswcsum); if (in_cksum(m, hlen) != 0) { ipstat_inc(ips_badsum); goto bad; } } len = (__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); if (len < hlen) { ipstat_inc(ips_badlen); goto bad; } if (m->M_dat.MH.MH_pkthdr.len < len) { ipstat_inc(ips_tooshort); goto bad; } if (m->M_dat.MH.MH_pkthdr.len > len) { if (m->m_hdr.mh_len == m->M_dat.MH.MH_pkthdr.len) { m->m_hdr.mh_len = len; m->M_dat.MH.MH_pkthdr.len = len; } else m_adj(m, len - m->M_dat.MH.MH_pkthdr.len); } if (ifp->if_data.ifi_type == 0xf7 && carp_lsdrop(m, 2, &ip->ip_src.s_addr, &ip->ip_dst.s_addr, (ip->ip_p == 1 ? 0 : 1))) goto bad; pfrdr = ip->ip_dst.s_addr; if (pf_test(2, PF_IN, ifp, mp) != PF_PASS) goto bad; m = *mp; if (m == ((void *)0)) goto bad; ip = ((struct ip *)((m)->m_hdr.mh_data)); hlen = ip->ip_hl << 2; pfrdr = (pfrdr != ip->ip_dst.s_addr); if (hlen > sizeof (struct ip) && ip_dooptions(m, ifp)) { m = *mp = ((void *)0); goto bad; } if (ip->ip_dst.s_addr == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xffffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xffffffff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xffffffff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xffffffff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xffffffff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; }))) || ip->ip_dst.s_addr == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x00000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) { nxt = ip_ours(mp, offp, nxt, af); goto out; } if (in_ouraddr(m, ifp, &rt)) { nxt = ip_ours(mp, offp, nxt, af); goto out; } if ((((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xf0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xf0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xe0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; }))))) { m->m_hdr.mh_flags |= 0x0200; if (ipmforwarding && ip_mrouter[ifp->if_data.ifi_rdomain]) { int error; if (m->m_hdr.mh_flags & 0x0001) { if ((m = *mp = m_pullup(m, hlen)) == ((void *)0)) { ipstat_inc(ips_toosmall); goto bad; } ip = ((struct ip *)((m)->m_hdr.mh_data)); } _kernel_lock("module.c", 4259); error = ip_mforward(m, ifp); _kernel_unlock(); if (error) { ipstat_inc(ips_cantforward); goto bad; } if (ip->ip_p == 2) { nxt = ip_ours(mp, offp, nxt, af); goto out; } ipstat_inc(ips_forward); } if (!in_hasmulti(&ip->ip_dst, ifp)) { ipstat_inc(ips_notmember); if (!(((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xffffff00)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xffffff00)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xe0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; }))))) ipstat_inc(ips_cantforward); goto bad; } nxt = ip_ours(mp, offp, nxt, af); goto out; } if (ifp->if_data.ifi_type == 0xf7 && ip->ip_p == 1 && carp_lsdrop(m, 2, &ip->ip_src.s_addr, &ip->ip_dst.s_addr, 1)) goto bad; if (ipforwarding == 0) { ipstat_inc(ips_cantforward); goto bad; } ip_forward(m, ifp, rt, pfrdr); *mp = ((void *)0); return 257; bad: nxt = 257; m_freemp(mp); out: rtfree(rt); return nxt; } int ip_local(struct mbuf **mp, int *offp, int nxt, int af) { struct mbuf *m = *mp; struct ip *ip = ((struct ip *)((m)->m_hdr.mh_data)); struct ipq *fp; struct ipqent *ipqe; int mff, hlen; hlen = ip->ip_hl << 2; if (ip->ip_off &~ (__uint16_t)(__builtin_constant_p(0x4000 | 0x8000) ? (__uint16_t)(((__uint16_t)(0x4000 | 0x8000) & 0xffU) << 8 | ((__uint16_t)(0x4000 | 0x8000) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (0x4000 | 0x8000); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; }))) { if (m->m_hdr.mh_flags & 0x0001) { if ((m = *mp = m_pullup(m, hlen)) == ((void *)0)) { ipstat_inc(ips_toosmall); return 257; } ip = ((struct ip *)((m)->m_hdr.mh_data)); } __mtx_enter(&ipq_mutex); for((fp) = ((&ipq)->lh_first); (fp)!= ((void *)0); (fp) = ((fp)->ipq_q.le_next)) { if (ip->ip_id == fp->ipq_id && ip->ip_src.s_addr == fp->ipq_src.s_addr && ip->ip_dst.s_addr == fp->ipq_dst.s_addr && ip->ip_p == fp->ipq_p) break; } ip->ip_len = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - hlen) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - hlen) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - hlen) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - hlen); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); mff = (ip->ip_off & (__uint16_t)(__builtin_constant_p(0x2000) ? (__uint16_t)(((__uint16_t)(0x2000) & 0xffU) << 8 | ((__uint16_t)(0x2000) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (0x2000); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; }))) != 0; if (mff) { if ((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) == 0 || ((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) & 0x7) != 0) { ipstat_inc(ips_badfrags); goto bad; } } ip->ip_off = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(ip->ip_off) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) << 3) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_off) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) << 3) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_off) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) << 3) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(ip->ip_off) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) << 3); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); if (mff || ip->ip_off) { ipstat_inc(ips_fragments); if (ip_frags + 1 > ip_maxqueue) { ip_flush(); ipstat_inc(ips_rcvmemdrop); goto bad; } ipqe = pool_get(&ipqent_pool, 0x0002); if (ipqe == ((void *)0)) { ipstat_inc(ips_rcvmemdrop); goto bad; } ip_frags++; ipqe->ipqe_mff = mff; ipqe->ipqe_m = m; ipqe->ipqe_ip = ip; m = *mp = ip_reass(ipqe, fp); if (m == ((void *)0)) goto bad; ipstat_inc(ips_reassembled); ip = ((struct ip *)((m)->m_hdr.mh_data)); hlen = ip->ip_hl << 2; ip->ip_len = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + hlen) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + hlen) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + hlen) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + hlen); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); } else if (fp) ip_freef(fp); __mtx_leave(&ipq_mutex); } *offp = hlen; nxt = ip->ip_p; if (af == 0) nxt = ip_deliver(mp, offp, nxt, 2); return nxt; bad: __mtx_leave(&ipq_mutex); m_freemp(mp); return 257; } int ip_deliver(struct mbuf **mp, int *offp, int nxt, int af) { const struct protosw *psw; int naf = af; int nest = 0; switch (af) { case 2: in_proto_cksum_out(*mp, ((void *)0)); break; case 24: in6_proto_cksum_out(*mp, ((void *)0)); break; } (af == 2 ? ipstat_inc(ips_delivered) : ip6stat_inc(ip6s_delivered)); while (nxt != 257) { if (af == 24 && ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { ip6stat_inc(ip6s_toomanyhdr); goto bad; } if ((*mp)->M_dat.MH.MH_pkthdr.len < *offp) { (af == 2 ? ipstat_inc(ips_tooshort) : ip6stat_inc(ip6s_tooshort)); goto bad; } if (af == 24 && (((*mp)->m_hdr.mh_flags) & (0x0080)) && (nxt == 6)) { if ((*mp)->m_hdr.mh_len >= sizeof(struct ip6_hdr)) { icmp6_error(*mp, 1, 3, __builtin_offsetof(struct ip6_hdr, ip6_dst)); *mp = ((void *)0); } goto bad; } switch (nxt) { case 4: naf = 2; ipstat_inc(ips_delivered); break; case 41: naf = 24; ip6stat_inc(ip6s_delivered); break; } switch (af) { case 2: psw = &inetsw[ip_protox[nxt]]; break; case 24: psw = &inet6sw[ip6_protox[nxt]]; break; } nxt = ip6_etherip_input(mp, offp, nxt, af); af = naf; } return nxt; bad: m_freemp(mp); return 257; } int in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt) { struct rtentry *rt; struct ip *ip; struct sockaddr_in sin; int match = 0; switch (pf_ouraddr(m)) { case 0: return (0); case 1: return (1); default: break; } ip = ((struct ip *)((m)->m_hdr.mh_data)); __builtin_memset((&sin), (0), (sizeof(sin))); sin.sin_len = sizeof(sin); sin.sin_family = 2; sin.sin_addr = ip->ip_dst; rt = rtalloc_mpath(sintosa(&sin), &ip->ip_src.s_addr, m->M_dat.MH.MH_pkthdr.ph_rtableid); if (rtisvalid(rt)) { if (((rt->rt_flags) & (0x200000))) match = 1; if (((rt->rt_flags) & (0x400000)) && (!ip_directedbcast || rt->rt_ifidx == ifp->if_index)) { match = 1; m->m_hdr.mh_flags |= 0x0100; } } *prt = rt; if (!match) { struct ifaddr *ifa; if (!((m->m_hdr.mh_flags) & (0x0100)) || !(((((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xe0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xc0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) && (ip->ip_dst.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x000000ff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x000000ff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ip->ip_dst.s_addr) || ((((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xc0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x80000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) && (ip->ip_dst.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x0000ffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x0000ffff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ip->ip_dst.s_addr) || ((((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x80000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x00000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) && (ip->ip_dst.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00ffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x00ffffff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ip->ip_dst.s_addr))) return (0); if (ifp->if_data.ifi_rdomain != rtable_l2(m->M_dat.MH.MH_pkthdr.ph_rtableid)) return (0); do { int _s = rw_status(&netlock); if ((splassert_ctl > 0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while (0); for((ifa) = ((&ifp->if_addrlist)->tqh_first); (ifa) != ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next)) { if (ifa->ifa_addr->sa_family != 2) continue; if ((((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xe0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xc0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) && (ifatoia(ifa)->ia_addr.sin_addr.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x000000ff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x000000ff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ip->ip_dst.s_addr) || ((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xc0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x80000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) && (ifatoia(ifa)->ia_addr.sin_addr.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x0000ffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x0000ffff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ip->ip_dst.s_addr) || ((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x80000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x00000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) && (ifatoia(ifa)->ia_addr.sin_addr.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00ffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0x00ffffff)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ip->ip_dst.s_addr))) { match = 1; break; } } } return (match); } struct mbuf * ip_reass(struct ipqent *ipqe, struct ipq *fp) { struct mbuf *m = ipqe->ipqe_m; struct ipqent *nq, *p, *q; struct ip *ip; struct mbuf *t; int hlen = ipqe->ipqe_ip->ip_hl << 2; int i, next; u_int8_t ecn, ecn0; do { if ((&ipq_mutex)->mtx_owner != ({struct cpu_info *__ci; asm volatile("movq %%gs:8,%0" : "=r" (__ci)); __ci;})) panic("mutex %p not held in %s", (&ipq_mutex), __func__); } while (0); m->m_hdr.mh_data += hlen; m->m_hdr.mh_len -= hlen; if (fp == ((void *)0)) { fp = pool_get(&ipq_pool, 0x0002); if (fp == ((void *)0)) goto dropfrag; do { if (((fp)->ipq_q.le_next = (&ipq)->lh_first) != ((void *)0)) (&ipq)->lh_first->ipq_q.le_prev = &(fp)->ipq_q.le_next; (&ipq)->lh_first = (fp); (fp)->ipq_q.le_prev = &(&ipq)->lh_first; } while (0); fp->ipq_ttl = 60; fp->ipq_p = ipqe->ipqe_ip->ip_p; fp->ipq_id = ipqe->ipqe_ip->ip_id; do { ((&fp->ipq_fragq)->lh_first) = ((void *)0); } while (0); fp->ipq_src = ipqe->ipqe_ip->ip_src; fp->ipq_dst = ipqe->ipqe_ip->ip_dst; p = ((void *)0); goto insert; } ecn = ipqe->ipqe_ip->ip_tos & 0x03; ecn0 = ((&fp->ipq_fragq)->lh_first)->ipqe_ip->ip_tos & 0x03; if (ecn == 0x03) { if (ecn0 == 0x00) goto dropfrag; if (ecn0 != 0x03) ((&fp->ipq_fragq)->lh_first)->ipqe_ip->ip_tos |= 0x03; } if (ecn == 0x00 && ecn0 != 0x00) goto dropfrag; for (p = ((void *)0), q = ((&fp->ipq_fragq)->lh_first); q != ((void *)0); p = q, q = ((q)->ipqe_q.le_next)) if ((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) > (__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; }))) break; if (p != ((void *)0)) { i = (__uint16_t)(__builtin_constant_p(p->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(p->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(p->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (p->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + (__uint16_t)(__builtin_constant_p(p->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(p->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(p->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (p->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - (__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); if (i > 0) { if (i >= (__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; }))) goto dropfrag; m_adj(ipqe->ipqe_m, i); ipqe->ipqe_ip->ip_off = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); ipqe->ipqe_ip->ip_len = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); } } for (; q != ((void *)0) && (__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + (__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) > (__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); q = nq) { i = ((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + (__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ipqe->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; }))) - (__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); if (i < (__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; }))) { q->ipqe_ip->ip_len = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - i); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); q->ipqe_ip->ip_off = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) + i); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); m_adj(q->ipqe_m, i); break; } nq = ((q)->ipqe_q.le_next); m_freem(q->ipqe_m); do { if ((q)->ipqe_q.le_next != ((void *)0)) (q)->ipqe_q.le_next->ipqe_q.le_prev = (q)->ipqe_q.le_prev; *(q)->ipqe_q.le_prev = (q)->ipqe_q.le_next; ((q)->ipqe_q.le_prev) = ((void *)-1); ((q)->ipqe_q.le_next) = ((void *)-1); } while (0); pool_put(&ipqent_pool, q); ip_frags--; } insert: if (p == ((void *)0)) { do { if (((ipqe)->ipqe_q.le_next = (&fp->ipq_fragq)->lh_first) != ((void *)0)) (&fp->ipq_fragq)->lh_first->ipqe_q.le_prev = &(ipqe)->ipqe_q.le_next; (&fp->ipq_fragq)->lh_first = (ipqe); (ipqe)->ipqe_q.le_prev = &(&fp->ipq_fragq)->lh_first; } while (0); } else { do { if (((ipqe)->ipqe_q.le_next = (p)->ipqe_q.le_next) != ((void *)0)) (p)->ipqe_q.le_next->ipqe_q.le_prev = &(ipqe)->ipqe_q.le_next; (p)->ipqe_q.le_next = (ipqe); (ipqe)->ipqe_q.le_prev = &(p)->ipqe_q.le_next; } while (0); } next = 0; for (p = ((void *)0), q = ((&fp->ipq_fragq)->lh_first); q != ((void *)0); p = q, q = ((q)->ipqe_q.le_next)) { if ((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_off); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) != next) return (0); next += (__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (q->ipqe_ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); } if (p->ipqe_mff) return (0); q = ((&fp->ipq_fragq)->lh_first); ip = q->ipqe_ip; if ((next + (ip->ip_hl << 2)) > 65535) { ipstat_inc(ips_toolong); ip_freef(fp); return (0); } m = q->ipqe_m; t = m->m_hdr.mh_next; m->m_hdr.mh_next = 0; m_cat(m, t); nq = ((q)->ipqe_q.le_next); pool_put(&ipqent_pool, q); ip_frags--; for (q = nq; q != ((void *)0); q = nq) { t = q->ipqe_m; nq = ((q)->ipqe_q.le_next); pool_put(&ipqent_pool, q); ip_frags--; m_cat(m, t); } ip->ip_len = (__uint16_t)(__builtin_constant_p(next) ? (__uint16_t)(((__uint16_t)(next) & 0xffU) << 8 | ((__uint16_t)(next) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (next); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); ip->ip_src = fp->ipq_src; ip->ip_dst = fp->ipq_dst; do { if ((fp)->ipq_q.le_next != ((void *)0)) (fp)->ipq_q.le_next->ipq_q.le_prev = (fp)->ipq_q.le_prev; *(fp)->ipq_q.le_prev = (fp)->ipq_q.le_next; ((fp)->ipq_q.le_prev) = ((void *)-1); ((fp)->ipq_q.le_next) = ((void *)-1); } while (0); pool_put(&ipq_pool, fp); m->m_hdr.mh_len += (ip->ip_hl << 2); m->m_hdr.mh_data -= (ip->ip_hl << 2); if (m->m_hdr.mh_flags & 0x0002) { int plen = 0; for (t = m; t; t = t->m_hdr.mh_next) plen += t->m_hdr.mh_len; m->M_dat.MH.MH_pkthdr.len = plen; } return (m); dropfrag: ipstat_inc(ips_fragdropped); m_freem(m); pool_put(&ipqent_pool, ipqe); ip_frags--; return (((void *)0)); } void ip_freef(struct ipq *fp) { struct ipqent *q; do { if ((&ipq_mutex)->mtx_owner != ({struct cpu_info *__ci; asm volatile("movq %%gs:8,%0" : "=r" (__ci)); __ci;})) panic("mutex %p not held in %s", (&ipq_mutex), __func__); } while (0); while ((q = ((&fp->ipq_fragq)->lh_first)) != ((void *)0)) { do { if ((q)->ipqe_q.le_next != ((void *)0)) (q)->ipqe_q.le_next->ipqe_q.le_prev = (q)->ipqe_q.le_prev; *(q)->ipqe_q.le_prev = (q)->ipqe_q.le_next; ((q)->ipqe_q.le_prev) = ((void *)-1); ((q)->ipqe_q.le_next) = ((void *)-1); } while (0); m_freem(q->ipqe_m); pool_put(&ipqent_pool, q); ip_frags--; } do { if ((fp)->ipq_q.le_next != ((void *)0)) (fp)->ipq_q.le_next->ipq_q.le_prev = (fp)->ipq_q.le_prev; *(fp)->ipq_q.le_prev = (fp)->ipq_q.le_next; ((fp)->ipq_q.le_prev) = ((void *)-1); ((fp)->ipq_q.le_next) = ((void *)-1); } while (0); pool_put(&ipq_pool, fp); } void ip_slowtimo(void) { struct ipq *fp, *nfp; __mtx_enter(&ipq_mutex); for ((fp) = ((&ipq)->lh_first); (fp) && ((nfp) = ((fp)->ipq_q.le_next), 1); (fp) = (nfp)) { if (--fp->ipq_ttl == 0) { ipstat_inc(ips_fragtimeout); ip_freef(fp); } } __mtx_leave(&ipq_mutex); } void ip_flush(void) { int max = 50; do { if ((&ipq_mutex)->mtx_owner != ({struct cpu_info *__ci; asm volatile("movq %%gs:8,%0" : "=r" (__ci)); __ci;})) panic("mutex %p not held in %s", (&ipq_mutex), __func__); } while (0); while (!(((&ipq)->lh_first) == ((void *)0)) && ip_frags > ip_maxqueue * 3 / 4 && --max) { ipstat_inc(ips_fragdropped); ip_freef(((&ipq)->lh_first)); } } int ip_dooptions(struct mbuf *m, struct ifnet *ifp) { struct ip *ip = ((struct ip *)((m)->m_hdr.mh_data)); unsigned int rtableid = m->M_dat.MH.MH_pkthdr.ph_rtableid; struct rtentry *rt; struct sockaddr_in ipaddr; u_char *cp; struct ip_timestamp ipt; struct in_ifaddr *ia; int opt, optlen, cnt, off, code, type = 12, forward = 0; struct in_addr sin, dst; u_int32_t ntime; dst = ip->ip_dst; cp = (u_char *)(ip + 1); cnt = (ip->ip_hl << 2) - sizeof (struct ip); _kernel_lock("module.c", 4904); for (; cnt > 0; cnt -= optlen, cp += optlen) { opt = cp[0]; if (opt == 0) break; if (opt == 1) optlen = 1; else { if (cnt < 1 + sizeof(*cp)) { code = &cp[1] - (u_char *)ip; goto bad; } optlen = cp[1]; if (optlen < 1 + sizeof(*cp) || optlen > cnt) { code = &cp[1] - (u_char *)ip; goto bad; } } switch (opt) { default: break; case 131: case 137: if (!ip_dosourceroute) { type = 3; code = 5; goto bad; } if ((off = cp[2]) < 4) { code = &cp[2] - (u_char *)ip; goto bad; } __builtin_memset((&ipaddr), (0), (sizeof(ipaddr))); ipaddr.sin_family = 2; ipaddr.sin_len = sizeof(ipaddr); ipaddr.sin_addr = ip->ip_dst; ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr), m->M_dat.MH.MH_pkthdr.ph_rtableid)); if (ia == ((void *)0)) { if (opt == 137) { type = 3; code = 5; goto bad; } break; } off--; if ((off + sizeof(struct in_addr)) > optlen) { save_rte(m, cp, ip->ip_src); break; } __builtin_memset((&ipaddr), (0), (sizeof(ipaddr))); ipaddr.sin_family = 2; ipaddr.sin_len = sizeof(ipaddr); __builtin_memcpy((&ipaddr.sin_addr), (cp + off), (sizeof(ipaddr.sin_addr))); rt = rtalloc(sintosa(&ipaddr), 1, rtableid); if (!rtisvalid(rt) || ((opt == 137) && ((rt->rt_flags) & (0x2)))) { type = 3; code = 5; rtfree(rt); goto bad; } ia = ifatoia(rt->rt_ifa); __builtin_memcpy((cp + off), (&ia->ia_addr.sin_addr), (sizeof(struct in_addr))); rtfree(rt); cp[2] += sizeof(struct in_addr); ip->ip_dst = ipaddr.sin_addr; forward = !(((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xf0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xf0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000) >> 24) : __extension__({ __uint32_t __swap32md_x = ((u_int32_t)(0xe0000000)); __asm ("bswap %0" : "+r" (__swap32md_x)); __swap32md_x; })))); break; case 7: if (optlen < 2 + sizeof(*cp)) { code = &cp[1] - (u_char *)ip; goto bad; } if ((off = cp[2]) < 4) { code = &cp[2] - (u_char *)ip; goto bad; } off--; if ((off + sizeof(struct in_addr)) > optlen) break; __builtin_memset((&ipaddr), (0), (sizeof(ipaddr))); ipaddr.sin_family = 2; ipaddr.sin_len = sizeof(ipaddr); ipaddr.sin_addr = ip->ip_dst; rt = rtalloc(sintosa(&ipaddr), 1, rtableid); if (!rtisvalid(rt)) { type = 3; code = 1; rtfree(rt); goto bad; } ia = ifatoia(rt->rt_ifa); __builtin_memcpy((cp + off), (&ia->ia_addr.sin_addr), (sizeof(struct in_addr))); rtfree(rt); cp[2] += sizeof(struct in_addr); break; case 68: code = cp - (u_char *)ip; if (optlen < sizeof(struct ip_timestamp)) goto bad; __builtin_memcpy((&ipt), (cp), (sizeof(struct ip_timestamp))); if (ipt.ipt_ptr < 5 || ipt.ipt_len < 5) goto bad; if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) > ipt.ipt_len) { if (++ipt.ipt_oflw == 0) goto bad; break; } __builtin_memcpy((&sin), (cp + ipt.ipt_ptr - 1), (sizeof sin)); switch (ipt.ipt_flg) { case 0: break; case 1: if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) + sizeof(struct in_addr) > ipt.ipt_len) goto bad; __builtin_memset((&ipaddr), (0), (sizeof(ipaddr))); ipaddr.sin_family = 2; ipaddr.sin_len = sizeof(ipaddr); ipaddr.sin_addr = dst; ia = ifatoia(ifaof_ifpforaddr(sintosa(&ipaddr), ifp)); if (ia == ((void *)0)) continue; __builtin_memcpy((&sin), (&ia->ia_addr.sin_addr), (sizeof(struct in_addr))); ipt.ipt_ptr += sizeof(struct in_addr); break; case 3: if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) + sizeof(struct in_addr) > ipt.ipt_len) goto bad; __builtin_memset((&ipaddr), (0), (sizeof(ipaddr))); ipaddr.sin_family = 2; ipaddr.sin_len = sizeof(ipaddr); ipaddr.sin_addr = sin; if (ifa_ifwithaddr(sintosa(&ipaddr), m->M_dat.MH.MH_pkthdr.ph_rtableid) == ((void *)0)) continue; ipt.ipt_ptr += sizeof(struct in_addr); break; default: code = (u_char *)&ipt.ipt_ptr - (u_char *)ip + 1; goto bad; } ntime = iptime(); __builtin_memcpy((cp + ipt.ipt_ptr - 1), (&ntime), (sizeof(u_int32_t))); ipt.ipt_ptr += sizeof(u_int32_t); } } _kernel_unlock(); if (forward && ipforwarding) { ip_forward(m, ifp, ((void *)0), 1); return (1); } return (0); bad: _kernel_unlock(); icmp_error(m, type, code, 0, 0); ipstat_inc(ips_badoptions); return (1); } void save_rte(struct mbuf *m, u_char *option, struct in_addr dst) { struct ip_srcrt *isr; struct m_tag *mtag; unsigned olen; olen = option[1]; if (olen > sizeof(isr->isr_hdr) + sizeof(isr->isr_routes)) return; mtag = m_tag_get(0x1000, sizeof(*isr), 0x0002); if (mtag == ((void *)0)) return; isr = (struct ip_srcrt *)(mtag + 1); __builtin_memcpy((isr->isr_hdr), (option), (olen)); isr->isr_nhops = (olen - 2 - 1) / sizeof(struct in_addr); isr->isr_dst = dst; m_tag_prepend(m, mtag); } struct mbuf * ip_srcroute(struct mbuf *m0) { struct in_addr *p, *q; struct mbuf *m; struct ip_srcrt *isr; struct m_tag *mtag; if (!ip_dosourceroute) return (((void *)0)); mtag = m_tag_find(m0, 0x1000, ((void *)0)); if (mtag == ((void *)0)) return (((void *)0)); isr = (struct ip_srcrt *)(mtag + 1); if (isr->isr_nhops == 0) return (((void *)0)); m = m_get(0x0002, 4); if (m == ((void *)0)) return (((void *)0)); m->m_hdr.mh_len = (isr->isr_nhops + 1) * sizeof(struct in_addr) + (sizeof(isr->isr_nop) + sizeof(isr->isr_hdr)); p = &(isr->isr_routes[isr->isr_nhops - 1]); *(((struct in_addr *)((m)->m_hdr.mh_data))) = *p--; isr->isr_nop = 1; isr->isr_hdr[2] = 4; __builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data)) + sizeof(struct in_addr)), (&isr->isr_nop), ((sizeof(isr->isr_nop) + sizeof(isr->isr_hdr)))); q = (struct in_addr *)(((caddr_t)((m)->m_hdr.mh_data)) + sizeof(struct in_addr) + (sizeof(isr->isr_nop) + sizeof(isr->isr_hdr))); while (p >= isr->isr_routes) { *q++ = *p--; } *q = isr->isr_dst; m_tag_delete(m0, (struct m_tag *)isr); return (m); } void ip_stripoptions(struct mbuf *m) { int i; struct ip *ip = ((struct ip *)((m)->m_hdr.mh_data)); caddr_t opts; int olen; olen = (ip->ip_hl<<2) - sizeof (struct ip); opts = (caddr_t)(ip + 1); i = m->m_hdr.mh_len - (sizeof (struct ip) + olen); __builtin_memmove((opts), (opts + olen), (i)); m->m_hdr.mh_len -= olen; if (m->m_hdr.mh_flags & 0x0002) m->M_dat.MH.MH_pkthdr.len -= olen; ip->ip_hl = sizeof(struct ip) >> 2; ip->ip_len = (__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - olen) ? (__uint16_t)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - olen) & 0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - olen) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = ((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })) - olen); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })); } const int inetctlerrmap[21] = { 0, 0, 0, 0, 0, 40, 64, 65, 65, 65, 61, 61, 40, 65, 0, 0, 0, 0, 0, 0, 42 }; void ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) { struct mbuf mfake, *mcopy = ((void *)0); struct ip *ip = ((struct ip *)((m)->m_hdr.mh_data)); struct sockaddr_in *sin; struct route ro; int error, type = 0, code = 0, destmtu = 0, fake = 0, len; u_int32_t dest; dest = 0; if (m->m_hdr.mh_flags & (0x0100|0x0200) || in_canforward(ip->ip_dst) == 0) { ipstat_inc(ips_cantforward); m_freem(m); goto freecopy; } if (ip->ip_ttl <= 1) { icmp_error(m, 11, 0, dest, 0); goto freecopy; } sin = satosin(&ro.ro_dst); __builtin_memset((sin), (0), (sizeof(*sin))); sin->sin_family = 2; sin->sin_len = sizeof(*sin); sin->sin_addr = ip->ip_dst; if (!rtisvalid(rt)) { rtfree(rt); rt = rtalloc_mpath(sintosa(sin), &ip->ip_src.s_addr, m->M_dat.MH.MH_pkthdr.ph_rtableid); if (rt == ((void *)0)) { icmp_error(m, 3, 1, dest, 0); return; } } __builtin_memset((&mfake.m_hdr), (0), (sizeof(mfake.m_hdr))); mfake.m_hdr.mh_type = m->m_hdr.mh_type; if (m_dup_pkthdr(&mfake, m, 0x0002) == 0) { mfake.m_hdr.mh_data = mfake.M_dat.MH.MH_dat.MH_databuf; len = min((__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) : __extension__({ __uint16_t __swap16md_x = (ip->ip_len); __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); __swap16md_x; })), 68); m_copydata(m, 0, len, mfake.M_dat.MH.MH_dat.MH_databuf); mfake.M_dat.MH.MH_pkthdr.len = mfake.m_hdr.mh_len = len; pf_pkt_addr_changed(&mfake); fake = 1; } ip->ip_ttl -= 1; if ((rt->rt_ifidx == ifp->if_index) && (rt->rt_flags & (0x10|0x20)) == 0 && satosin(((rt)->rt_dest))->sin_addr.s_addr != 0 && ipsendredirects && !srcrt && !arpproxy(satosin(((rt)->rt_dest))->sin_addr, m->M_dat.MH.MH_pkthdr.ph_rtableid)) { if ((ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_netmask) == ifatoia(rt->rt_ifa)->ia_net) { if (rt->rt_flags & 0x2) dest = satosin(rt->rt_gateway)->sin_addr.s_addr; else dest = ip->ip_dst.s_addr; type = 5; code = 1; } } ro.ro_rt = rt; ro.ro_tableid = m->M_dat.MH.MH_pkthdr.ph_rtableid; error = ip_output(m, ((void *)0), &ro, (0x1 | (ip_directedbcast ? 0x0020 : 0)), ((void *)0), ((void *)0), 0); rt = ro.ro_rt; if (error) ipstat_inc(ips_cantforward); else { ipstat_inc(ips_forward); if (type) ipstat_inc(ips_redirectsent); else goto freecopy; } if (!fake) goto freecopy; switch (error) { case 0: break; case 51: case 65: case 50: case 64: default: type = 3; code = 1; break; case 40: type = 3; code = 4; ipstat_inc(ips_cantfrag); break; case 13: goto freecopy; case 55: goto freecopy; } mcopy = m_copym(&mfake, 0, len, 0x0002); if (mcopy) icmp_error(mcopy, type, code, dest, destmtu); freecopy: if (fake) m_tag_delete_chain(&mfake); rtfree(rt); } int ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int error; extern int ip_mrtproto; extern struct mrtstat mrtstat; if (namelen != 1 && name[0] != 30) return (20); switch (name[0]) { case 5: if (newp && securelevel > 0) return (1); do { _rw_enter_write(&netlock ); } while (0); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_dosourceroute); do { _rw_exit_write(&netlock ); } while (0); return (error); case 27: do { _rw_enter_write(&netlock ); } while (0); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc); if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == ((void *)0)) { ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != ((void *)0)) { rt_timer_queue_destroy(ip_mtudisc_timeout_q); ip_mtudisc_timeout_q = ((void *)0); } do { _rw_exit_write(&netlock ); } while (0); return error; case 28: do { _rw_enter_write(&netlock ); } while (0); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc_timeout); if (ip_mtudisc_timeout_q != ((void *)0)) rt_timer_queue_change(ip_mtudisc_timeout_q, ip_mtudisc_timeout); do { _rw_exit_write(&netlock ); } while (0); return (error); case 30: return (sysctl_mq((name + 1), (namelen - 1), (oldp), (oldlenp), (newp), (newlen), &(&ipintrq)->ni_q)); case 33: return (ip_sysctl_ipstat(oldp, oldlenp, newp)); case 35: return (sysctl_rdstruct(oldp, oldlenp, newp, &mrtstat, sizeof(mrtstat))); case 34: return (sysctl_rdint(oldp, oldlenp, newp, ip_mrtproto)); case 37: if (newp) return (1); do { _rw_enter_write(&netlock ); } while (0); error = mrt_sysctl_mfc(oldp, oldlenp); do { _rw_exit_write(&netlock ); } while (0); return (error); case 38: if (newp) return (1); do { _rw_enter_write(&netlock ); } while (0); error = mrt_sysctl_vif(oldp, oldlenp); do { _rw_exit_write(&netlock ); } while (0); return (error); default: if (name[0] < 41) { do { _rw_enter_write(&netlock ); } while (0); error = sysctl_int_arr(ipctl_vars, name, namelen, oldp, oldlenp, newp, newlen); do { _rw_exit_write(&netlock ); } while (0); return (error); } return (45); } } int ip_sysctl_ipstat(void *oldp, size_t *oldlenp, void *newp) { uint64_t counters[ips_ncounters]; struct ipstat ipstat; u_long *words = (u_long *)&ipstat; int i; extern char _ctassert[(sizeof(ipstat) == ((sizeof((counters)) / sizeof((counters)[0])) * sizeof(u_long))) ? 1 : -1 ] __attribute__((__unused__)); __builtin_memset((&ipstat), (0), (sizeof ipstat)); counters_read(ipcounters, counters, (sizeof((counters)) / sizeof((counters)[0]))); for (i = 0; i < (sizeof((counters)) / sizeof((counters)[0])); i++) words[i] = (u_long)counters[i]; return (sysctl_rdstruct(oldp, oldlenp, newp, &ipstat, sizeof(ipstat))); } void ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip, struct mbuf *m) { if (inp->inp_socket->so_options & 0x0800) { struct timeval tv; microtime(&tv); *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv), 0x04, 0xffff); if (*mp) mp = &(*mp)->m_hdr.mh_next; } if (inp->inp_flags & 0x004) { *mp = sbcreatecontrol((caddr_t) &ip->ip_dst, sizeof(struct in_addr), 7, 0); if (*mp) mp = &(*mp)->m_hdr.mh_next; } if (inp->inp_flags & 0x080) { struct sockaddr_dl sdl; struct ifnet *ifp; ifp = if_get(m->M_dat.MH.MH_pkthdr.ph_ifidx); if (ifp == ((void *)0) || ifp->if_sadl == ((void *)0)) { __builtin_memset((&sdl), (0), (sizeof(sdl))); sdl.sdl_len = __builtin_offsetof(struct sockaddr_dl, sdl_data[0]); sdl.sdl_family = 18; sdl.sdl_index = ifp != ((void *)0) ? ifp->if_index : 0; sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0; *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len, 30, 0); } else { *mp = sbcreatecontrol((caddr_t) ifp->if_sadl, ifp->if_sadl->sdl_len, 30, 0); } if (*mp) mp = &(*mp)->m_hdr.mh_next; if_put(ifp); } if (inp->inp_flags & 0x040) { *mp = sbcreatecontrol((caddr_t) &ip->ip_ttl, sizeof(u_int8_t), 31, 0); if (*mp) mp = &(*mp)->m_hdr.mh_next; } if (inp->inp_flags & 0x400) { u_int rtableid = inp->inp_rtableid; if (m && m->M_dat.MH.MH_pkthdr.pf.flags & 0x08) { struct pf_divert *divert; divert = pf_find_divert(m); ((divert != ((void *)0)) ? (void)0 : __assert("diagnostic ", "module.c", 5618, "divert != NULL")); rtableid = divert->rdomain; } *mp = sbcreatecontrol((caddr_t) &rtableid, sizeof(u_int), 35, 0); if (*mp) mp = &(*mp)->m_hdr.mh_next; } } void ip_send_dispatch(void *xmq) { struct mbuf_queue *mq = xmq; struct mbuf *m; struct mbuf_list ml; mq_delist(mq, &ml); if (((&ml)->ml_len == 0)) return; do { _rw_enter_read(&netlock ); } while (0); while ((m = ml_dequeue(&ml)) != ((void *)0)) { ip_output(m, ((void *)0), ((void *)0), 0, ((void *)0), ((void *)0), 0); } do { _rw_exit_read(&netlock ); } while (0); } void ip_send(struct mbuf *m) { mq_enqueue(&ipsend_mq, m); task_add(net_tq(0), &ipsend_task); } extern struct domain mplsdomain; extern struct domain pfkeydomain; extern struct domain inet6domain; extern struct domain inetdomain; extern struct domain unixdomain; extern struct domain routedomain; struct domain *domains[] = { &inet6domain, &inetdomain, &unixdomain, &routedomain, ((void *)0) }; void pffasttimo(void *); void pfslowtimo(void *); struct domain * pffinddomain(int); void domaininit(void) { struct domain *dp; const struct protosw *pr; static struct timeout pffast_timeout; static struct timeout pfslow_timeout; int i; for (i = 0; (dp = domains[i]) != ((void *)0); i++) { if (dp->dom_init) (*dp->dom_init)(); for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_init) (*pr->pr_init)(); } if (max_linkhdr < 64) max_linkhdr = 64; max_hdr = max_linkhdr + max_protohdr; timeout_set_proc(&pffast_timeout, pffasttimo, &pffast_timeout); timeout_set_proc(&pfslow_timeout, pfslowtimo, &pfslow_timeout); timeout_add(&pffast_timeout, 1); timeout_add(&pfslow_timeout, 1); } struct domain * pffinddomain(int family) { struct domain *dp; int i; for (i = 0; (dp = domains[i]) != ((void *)0); i++) { if (dp->dom_family == family) return (dp); } return (((void *)0)); } const struct protosw * pffindtype(int family, int type) { struct domain *dp; const struct protosw *pr; dp = pffinddomain(family); if (dp == ((void *)0)) return (((void *)0)); for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_type && pr->pr_type == type) return (pr); return (((void *)0)); } const struct protosw * pffindproto(int family, int protocol, int type) { struct domain *dp; const struct protosw *pr; const struct protosw *maybe = ((void *)0); if (family == 0) return (((void *)0)); dp = pffinddomain(family); if (dp == ((void *)0)) return (((void *)0)); for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) return (pr); if (type == 3 && pr->pr_type == 3 && pr->pr_protocol == 0 && maybe == ((void *)0)) maybe = pr; } return (maybe); } int net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct proc *p) { struct domain *dp; const struct protosw *pr; int error, family, protocol; if (namelen < 2) return (21); family = name[0]; if (family == 0) return (0); if (family == 31) return (bpf_sysctl(name + 1, namelen - 1, oldp, oldlenp, newp, newlen)); if (family == 34) return (pflow_sysctl(name + 1, namelen - 1, oldp, oldlenp, newp, newlen)); if (family == 35) return (pipex_sysctl(name + 1, namelen - 1, oldp, oldlenp, newp, newlen)); dp = pffinddomain(family); if (dp == ((void *)0)) return (42); if (namelen < 3) return (21); protocol = name[1]; for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_protocol == protocol && pr->pr_sysctl) { error = (*pr->pr_sysctl)(name + 2, namelen - 2, oldp, oldlenp, newp, newlen); return (error); } return (42); } void pfctlinput(int cmd, struct sockaddr *sa) { struct domain *dp; const struct protosw *pr; int i; do { int _s = rw_status(&netlock); if ((splassert_ctl > 0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while (0); for (i = 0; (dp = domains[i]) != ((void *)0); i++) { for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_ctlinput) (*pr->pr_ctlinput)(cmd, sa, 0, ((void *)0)); } } void pfslowtimo(void *arg) { struct timeout *to = (struct timeout *)arg; struct domain *dp; const struct protosw *pr; int i; for (i = 0; (dp = domains[i]) != ((void *)0); i++) { for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_slowtimo) (*pr->pr_slowtimo)(); } timeout_add_msec(to, 500); } void pffasttimo(void *arg) { struct timeout *to = (struct timeout *)arg; struct domain *dp; const struct protosw *pr; int i; for (i = 0; (dp = domains[i]) != ((void *)0); i++) { for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_fasttimo) (*pr->pr_fasttimo)(); } timeout_add_msec(to, 200); } void *__VERIFIER_nondet_pointer(void) ; void __VERIFIER_error(void) ; void __VERIFIER_assume(int expression) ; int __VERIFIER_nondet_int(void) ; void panic(const char *fmt, ...); void int main(void); void panic(const char *fmt, ...) { __VERIFIER_error(); } int main() { struct mbuf *m; int len, off; ip_init(); ip6_init(); m = m_gethdr(0, 2); m_tag_init(m); len = __VERIFIER_nondet_int(); __VERIFIER_assume(len > 0); __VERIFIER_assume(len <= ((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))); off = __VERIFIER_nondet_int(); __VERIFIER_assume(off > 0); __VERIFIER_assume(off <= len); m->m_hdr.mh_len = m->M_dat.MH.MH_pkthdr.len = len; ip_deliver(&m, &off, 0, 24); }