1255332Scy/* $FreeBSD$ */
2255332Scy
3255332Scy/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5255332Scy *
6255332Scy * See the IPFILTER.LICENCE file for details on licencing.
7255332Scy */
8255332Scy/*
9255332Scy * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate
10255332Scy * its own major char number! Way cool patch!
11255332Scy */
12255332Scy#include <sys/types.h>
13255332Scy#include <sys/stat.h>
14255332Scy#include <sys/time.h>
15255332Scy#include <sys/file.h>
16255332Scy#include <sys/conf.h>
17255332Scy#include <sys/syslog.h>
18255332Scy#include <sys/buf.h>
19255332Scy#include <sys/param.h>
20255332Scy#include <sys/errno.h>
21255332Scy#include <sys/uio.h>
22255332Scy#include <sys/vnode.h>
23255332Scy#include <sundev/mbvar.h>
24255332Scy#include <sun/autoconf.h>
25255332Scy#include <sun/vddrv.h>
26255332Scy#if defined(sun4c) || defined(sun4m)
27255332Scy#include <sun/openprom.h>
28255332Scy#endif
29255332Scy
30255332Scy#ifndef	IPL_NAME
31255332Scy#define	IPL_NAME	"/dev/ipf"
32255332Scy#endif
33255332Scy
34255332Scyextern	int	ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread();
35255332Scyextern	int	nulldev(), ipfidentify(), errno;
36255332Scy
37255332Scystruct	cdevsw	ipfdevsw =
38255332Scy{
39255332Scy	ipfopen, ipfclose, ipfread, nulldev,
40255332Scy	ipfioctl, nulldev, nulldev, nulldev,
41255332Scy	0, nulldev,
42255332Scy};
43255332Scy
44255332Scy
45255332Scystruct	dev_ops	ipf_ops =
46255332Scy{
47255332Scy	1,
48255332Scy	ipfidentify,
49255332Scy	ipfattach,
50255332Scy	ipfopen,
51255332Scy	ipfclose,
52255332Scy	ipfread,
53255332Scy	NULL,		/* write */
54255332Scy	NULL,		/* strategy */
55255332Scy	NULL,		/* dump */
56255332Scy	0,		/* psize */
57255332Scy        ipfioctl,
58255332Scy	NULL,		/* reset */
59255332Scy	NULL		/* mmap */
60255332Scy};
61255332Scy
62255332Scyint	ipf_major = 0;
63255332Scy
64255332Scy#ifdef sun4m
65255332Scystruct	vdldrv	vd =
66255332Scy{
67255332Scy	VDMAGIC_PSEUDO,
68255332Scy	"ipf",
69255332Scy	&ipf_ops,
70255332Scy	NULL,
71255332Scy	&ipfdevsw,
72255332Scy	0,
73255332Scy	0,
74255332Scy	NULL,
75255332Scy	NULL,
76255332Scy	NULL,
77255332Scy	0,
78255332Scy	1,
79255332Scy};
80255332Scy#else /* sun4m */
81255332Scystruct vdldrv vd =
82255332Scy{
83255332Scy	VDMAGIC_PSEUDO,	/* magic */
84255332Scy	"ipf",		/* name */
85255332Scy#ifdef sun4c
86255332Scy	&ipf_ops,	/* dev_ops */
87255332Scy#else
88255332Scy	NULL,		/* struct mb_ctlr *mb_ctlr */
89255332Scy	NULL,		/* struct mb_driver *mb_driver */
90255332Scy	NULL,		/* struct mb_device *mb_device */
91255332Scy	0,		/* num ctlrs */
92255332Scy	1,		/* numdevs */
93255332Scy#endif /* sun4c */
94255332Scy	NULL,		/* bdevsw */
95255332Scy	&ipfdevsw,	/* cdevsw */
96255332Scy	0,		/* block major */
97255332Scy	0,		/* char major */
98255332Scy};
99255332Scy#endif /* sun4m */
100255332Scy
101255332Scyextern int vd_unuseddev();
102255332Scyextern struct cdevsw cdevsw[];
103255332Scyextern int nchrdev;
104255332Scy
105255332Scyxxxinit(fc, vdp, vdi, vds)
106255332Scy	u_int	fc;
107255332Scy	struct	vddrv	*vdp;
108255332Scy	caddr_t	vdi;
109255332Scy	struct	vdstat	*vds;
110255332Scy{
111255332Scy	struct	vdlinkage *v;
112255332Scy	int	i;
113255332Scy
114255332Scy	switch (fc)
115255332Scy	{
116255332Scy	case VDLOAD:
117255332Scy		while (ipf_major < nchrdev &&
118255332Scy		       cdevsw[ipf_major].d_open != vd_unuseddev)
119255332Scy			ipf_major++;
120255332Scy		if (ipf_major == nchrdev)
121255332Scy			return ENODEV;
122255332Scy		vd.Drv_charmajor = ipf_major;
123255332Scy		vdp->vdd_vdtab = (struct vdlinkage *)&vd;
124255332Scy		return ipf_attach(vdi);
125255332Scy	case VDUNLOAD:
126255332Scy		return unload(vdp, vdi);
127255332Scy
128255332Scy	case VDSTAT:
129255332Scy		return 0;
130255332Scy
131255332Scy	default:
132255332Scy		return EIO;
133255332Scy	}
134255332Scy}
135255332Scy
136255332Scystatic unload(vdp, vdi)
137255332Scy	struct vddrv *vdp;
138255332Scy	struct vdioctl_unload  *vdi;
139255332Scy{
140255332Scy	int	i;
141255332Scy
142255332Scy	(void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE);
143255332Scy	return ipfdetach();
144255332Scy}
145255332Scy
146255332Scy
147255332Scystatic	int	ipf_attach(vdi)
148255332Scystruct	vdioctl_load	*vdi;
149255332Scy{
150255332Scy	struct	vnode	*vp;
151255332Scy	struct	vattr	vattr;
152255332Scy	int		error = 0, fmode = S_IFCHR|0600;
153255332Scy
154255332Scy	(void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE);
155255332Scy	vattr_null(&vattr);
156255332Scy	vattr.va_type = MFTOVT(fmode);
157255332Scy	vattr.va_mode = (fmode & 07777);
158255332Scy	vattr.va_rdev = ipf_major<<8;
159255332Scy
160255332Scy	error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp);
161255332Scy	if (error == 0)
162255332Scy		VN_RELE(vp);
163255332Scy	return ipfattach(0);
164255332Scy}
165