xref: /original-bsd/sys/netccitt/pk_acct.c (revision d5354517)
1 /*
2  * Copyright (c) University of British Columbia, 1984
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Laboratory for Computation Vision and the Computer Science Department
8  * of the University of British Columbia.
9  *
10  * %sccs.include.redist.c%
11  *
12  *	@(#)pk_acct.c	7.2 (Berkeley) 05/11/90
13  */
14 
15 #include "../h/param.h"
16 #ifdef NFS
17 #include "systm.h"
18 #include "dir.h"
19 #include "user.h"
20 #include "vnode.h"
21 #include "vfs.h"
22 #include "kernel.h"
23 #include "uio.h"
24 #else
25 #include "../h/systm.h"
26 #include "../h/dir.h"
27 #include "../h/user.h"
28 #include "../h/inode.h"
29 #include "../h/kernel.h"
30 #ifdef BSD4_3
31 #include "../h/namei.h"
32 #else
33 #include "../h/nami.h"
34 #endif
35 #include "../h/uio.h"
36 #endif
37 
38 #include "../netccitt/pk.h"
39 #include "../netccitt/pk_var.h"
40 #include "../netccitt/x25.h"
41 #include "../netccitt/x25acct.h"
42 
43 
44 #ifdef NFS
45 struct	vnode *pkacctp;
46 #else
47 struct	inode *pkacctp;
48 #endif
49 
50 /*
51  *  Turn on packet accounting
52  */
53 
54 pk_accton (path)
55 	char *path;
56 {
57 #ifdef NFS
58 	register int error;
59 	struct vnode *vp;
60 #else
61 #ifdef BSD4_3
62 	struct nameidata *ndp = &u.u_nd;
63 #endif
64 	register struct inode *ip;
65 #endif
66 
67 #ifdef NFS
68 	if (error = lookupname(path, UIO_USERSPACE, FOLLOW_LINK,
69 		(struct vnode **)0, &vp))
70 		return (error);
71 	if (vp->v_type != VREG) {
72 		VN_RELE(vp);
73 		return (EACCES);
74 	}
75 	if (vp->v_vfsp->vfs_flag & VFS_RDONLY) {
76 		VN_RELE(vp);
77 		return (EROFS);
78 	}
79 	pkacctp = vp;
80 #else
81 #ifdef BSD4_3
82 	ndp->ni_nameiop = LOOKUP | FOLLOW;
83 	ndp->ni_segflg = UIO_USERSPACE;
84 	ndp->ni_dirp = path;
85 	ip = namei(ndp);
86 #else
87 	u.u_dirp = path;
88 	ip = namei (schar, LOOKUP, 1);
89 #endif
90 	if (ip == NULL)
91 		return (u.u_error);
92 
93 	if ((ip -> i_mode & IFMT) != IFREG) {
94 		iput (ip);
95 		return (EACCES);
96 	}
97 	if (pkacctp)
98 		if (pkacctp->i_number != ip->i_number ||
99 		    pkacctp->i_dev != ip->i_dev)
100 			irele(pkacctp);
101 	pkacctp = ip;
102 	iunlock (ip);
103 #endif
104 	return (0);
105 }
106 
107 /*
108  *  Turn off packet accounting
109  */
110 
111 pk_acctoff ()
112 {
113 	if (pkacctp) {
114 #ifdef NFS
115 		VN_RELE(pkacctp);
116 #else
117 		irele (pkacctp);
118 #endif
119 		pkacctp = 0;
120 	}
121 }
122 
123 /*
124  *  Write a record on the accounting file.
125  */
126 
127 pk_acct (lcp)
128 register struct pklcd *lcp;
129 {
130 #ifdef NFS
131 	register struct vnode *vp;
132 #else
133 	register struct inode *ip;
134 	off_t siz;
135 #endif
136 	register struct sockaddr_x25 *sa;
137 	register char *src, *dst;
138 	register int len;
139 #ifndef WATERLOO
140 	register long etime;
141 #endif
142 	static struct x25acct acbuf;
143 
144 #ifdef NFS
145 	if ((vp = pkacctp) == 0)
146 #else
147 	if ((ip = pkacctp) == 0)
148 #endif
149 		return;
150 
151 	bzero ((caddr_t)&acbuf, sizeof (acbuf));
152 	if (lcp -> lcd_ceaddr != 0)
153 		sa = lcp -> lcd_ceaddr;
154 	else if (lcp -> lcd_craddr != 0) {
155 		sa = lcp -> lcd_craddr;
156 		acbuf.x25acct_callin = 1;
157 	} else
158 		return;
159 
160 	if (sa -> x25_opts.op_flags & X25_REVERSE_CHARGE)
161 		acbuf.x25acct_revcharge = 1;
162 	acbuf.x25acct_stime = lcp -> lcd_stime;
163 #ifdef WATERLOO
164 	acbuf.x25acct_etime = time.tv_sec - acbuf.x25acct_stime;
165 #else
166 	etime = time.tv_sec - acbuf.x25acct_stime;
167 	acbuf.x25acct_etime = etime > 0xffff ? 0xffff : etime;
168 #endif
169 	acbuf.x25acct_uid = u.u_uid;
170 	acbuf.x25acct_psize = sa -> x25_opts.op_psize;
171 	acbuf.x25acct_net = sa -> x25_net;
172 	/*
173 	 * Convert address to bcd
174 	 */
175 	src = sa -> x25_addr;
176 	dst = acbuf.x25acct_addr;
177 	for (len = 0; *src; len++)
178 		if (len & 01)
179 			*dst++ |= *src++ & 0xf;
180 		else
181 			*dst = *src++ << 4;
182 	acbuf.x25acct_addrlen = len;
183 
184 	bcopy (sa -> x25_udata, acbuf.x25acct_udata,
185 		sizeof (acbuf.x25acct_udata));
186 	acbuf.x25acct_txcnt = lcp -> lcd_txcnt;
187 	acbuf.x25acct_rxcnt = lcp -> lcd_rxcnt;
188 
189 #ifdef NFS
190 	(void) vn_rdwr(UIO_WRITE, vp, (caddr_t)&acbuf, sizeof (acbuf),
191 		(off_t)0, UIO_SYSSPACE, IO_UNIT|IO_APPEND, (int *)0);
192 #else
193 	ilock (ip);
194 	siz = ip -> i_size;
195 	if (rdwri (UIO_WRITE, ip, (caddr_t)&acbuf, sizeof (acbuf),
196 	    siz, 1, (int *) 0))
197 		itrunc (ip, (u_long) siz);
198 	iunlock (ip);
199 #endif
200 }
201