ml_ipl.c revision 259128
1/* $FreeBSD$ */
2
3/*
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8/*
9 * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate
10 * its own major char number! Way cool patch!
11 */
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <sys/time.h>
15#include <sys/file.h>
16#include <sys/conf.h>
17#include <sys/syslog.h>
18#include <sys/buf.h>
19#include <sys/param.h>
20#include <sys/errno.h>
21#include <sys/uio.h>
22#include <sys/vnode.h>
23#include <sundev/mbvar.h>
24#include <sun/autoconf.h>
25#include <sun/vddrv.h>
26#if defined(sun4c) || defined(sun4m)
27#include <sun/openprom.h>
28#endif
29
30#ifndef	IPL_NAME
31#define	IPL_NAME	"/dev/ipf"
32#endif
33
34extern	int	ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread();
35extern	int	nulldev(), ipfidentify(), errno;
36
37struct	cdevsw	ipfdevsw =
38{
39	ipfopen, ipfclose, ipfread, nulldev,
40	ipfioctl, nulldev, nulldev, nulldev,
41	0, nulldev,
42};
43
44
45struct	dev_ops	ipf_ops =
46{
47	1,
48	ipfidentify,
49	ipfattach,
50	ipfopen,
51	ipfclose,
52	ipfread,
53	NULL,		/* write */
54	NULL,		/* strategy */
55	NULL,		/* dump */
56	0,		/* psize */
57        ipfioctl,
58	NULL,		/* reset */
59	NULL		/* mmap */
60};
61
62int	ipf_major = 0;
63
64#ifdef sun4m
65struct	vdldrv	vd =
66{
67	VDMAGIC_PSEUDO,
68	"ipf",
69	&ipf_ops,
70	NULL,
71	&ipfdevsw,
72	0,
73	0,
74	NULL,
75	NULL,
76	NULL,
77	0,
78	1,
79};
80#else /* sun4m */
81struct vdldrv vd =
82{
83	VDMAGIC_PSEUDO,	/* magic */
84	"ipf",		/* name */
85#ifdef sun4c
86	&ipf_ops,	/* dev_ops */
87#else
88	NULL,		/* struct mb_ctlr *mb_ctlr */
89	NULL,		/* struct mb_driver *mb_driver */
90	NULL,		/* struct mb_device *mb_device */
91	0,		/* num ctlrs */
92	1,		/* numdevs */
93#endif /* sun4c */
94	NULL,		/* bdevsw */
95	&ipfdevsw,	/* cdevsw */
96	0,		/* block major */
97	0,		/* char major */
98};
99#endif /* sun4m */
100
101extern int vd_unuseddev();
102extern struct cdevsw cdevsw[];
103extern int nchrdev;
104
105xxxinit(fc, vdp, vdi, vds)
106	u_int	fc;
107	struct	vddrv	*vdp;
108	caddr_t	vdi;
109	struct	vdstat	*vds;
110{
111	struct	vdlinkage *v;
112	int	i;
113
114	switch (fc)
115	{
116	case VDLOAD:
117		while (ipf_major < nchrdev &&
118		       cdevsw[ipf_major].d_open != vd_unuseddev)
119			ipf_major++;
120		if (ipf_major == nchrdev)
121			return ENODEV;
122		vd.Drv_charmajor = ipf_major;
123		vdp->vdd_vdtab = (struct vdlinkage *)&vd;
124		return ipf_attach(vdi);
125	case VDUNLOAD:
126		return unload(vdp, vdi);
127
128	case VDSTAT:
129		return 0;
130
131	default:
132		return EIO;
133	}
134}
135
136static unload(vdp, vdi)
137	struct vddrv *vdp;
138	struct vdioctl_unload  *vdi;
139{
140	int	i;
141
142	(void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE);
143	return ipfdetach();
144}
145
146
147static	int	ipf_attach(vdi)
148struct	vdioctl_load	*vdi;
149{
150	struct	vnode	*vp;
151	struct	vattr	vattr;
152	int		error = 0, fmode = S_IFCHR|0600;
153
154	(void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE);
155	vattr_null(&vattr);
156	vattr.va_type = MFTOVT(fmode);
157	vattr.va_mode = (fmode & 07777);
158	vattr.va_rdev = ipf_major<<8;
159
160	error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp);
161	if (error == 0)
162		VN_RELE(vp);
163	return ipfattach(0);
164}
165