1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
/*
* routines below for saving IP headers to buffer
*/
int iplopen(struct inode * inode, struct file * filp)
{
u_int min = MINOR(inode->i_rdev);
if (flags & FWRITE)
return ENXIO;
if (min)
return ENXIO;
iplbusy++;
return 0;
}
int iplclose(struct inode * inode, struct file * filp)
{
u_int min = MINOR(inode->i_rdev);
if (min)
return ENXIO;
iplbusy--;
return 0;
}
/*
* iplread/ipllog
* all three of these must operate with at least splnet() lest they be
* called during packet processing and cause an inconsistancy to appear in
* the filter lists.
*/
int iplread(struct inode *inode, struct file *file, char *buf, int count)
{
register int ret, s;
register size_t sz, sx;
int error;
if (!uio->uio_resid)
return 0;
while (!iplused) {
error = SLEEP(iplbuf, "ipl sleep");
if (error)
return error;
}
SPLNET(s);
ret = sx = sz = MIN(count, iplused);
if (iplh < iplt)
sz = MIN(sz, LOGSIZE - (iplt - iplbuf));
sx -= sz;
memcpy_tofs(buf, iplt, sz);
buf += sz;
iplt += sz;
iplused -= sz;
if ((iplh < iplt) && (iplt == iplbuf + LOGSIZE))
iplt = iplbuf;
if (sx) {
memcpy_tofs(buf, iplt, sx);
ret += sx;
iplt += sx;
iplused -= sx;
if ((iplh < iplt) && (iplt == iplbuf + LOGSIZE))
iplt = iplbuf;
}
if (!iplused) /* minimise wrapping around the end */
iplh = iplt = iplbuf;
SPLX(s);
return ret;
}
|