]> git.saurik.com Git - apple/network_cmds.git/blame - identd.tproj/netbsd.c
network_cmds-115.2.tar.gz
[apple/network_cmds.git] / identd.tproj / netbsd.c
CommitLineData
b7080c8e
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25** $Id: netbsd.c,v 1.1.1.2 2000/01/11 01:48:48 wsanchez Exp $
26**
27** netbsd.c Low level kernel access functions for NetBSD
28**
29** This program is in the public domain and may be used freely by anyone
30** who wants to.
31**
32** Last update: 17 March 1993
33**
34** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
35*/
36
37#include <stdio.h>
38#include <errno.h>
39#include <ctype.h>
40#include <nlist.h>
41#include <pwd.h>
42#include <signal.h>
43#include <syslog.h>
44
45#include "kvm.h"
46
47#include <sys/types.h>
48#include <sys/stat.h>
49#include <sys/param.h>
50#include <sys/ioctl.h>
51#include <sys/socket.h>
52
53#include <sys/socketvar.h>
54
55#define KERNEL
56
57#include <sys/file.h>
58
59#undef KERNEL
60#include <sys/sysctl.h>
61
62#include <fcntl.h>
63
64#include <sys/user.h>
65
66#include <sys/wait.h>
67
68#include <net/if.h>
69#include <net/route.h>
70#include <netinet/in.h>
71
72#include <netinet/in_systm.h>
73#include <netinet/ip.h>
74
75#include <netinet/in_pcb.h>
76
77#include <netinet/tcp.h>
78#include <netinet/ip_var.h>
79#include <netinet/tcp_timer.h>
80#include <netinet/tcp_var.h>
81
82#include <arpa/inet.h>
83
84#include "identd.h"
85#include "error.h"
86
87
88extern void *calloc();
89extern void *malloc();
90
91
92struct nlist nl[] =
93{
94#define N_FILE 0
95#define N_NFILE 1
96#define N_TCB 2
97
98 { "_filehead" },
99 { "_nfiles" },
100 { "_tcb" },
101 { "" }
102};
103
104static kvm_t *kd;
105
106static struct file *xfile;
107static int nfile;
108
109static struct inpcbhead tcb;
110
111
112int k_open()
113{
114 /*
115 ** Open the kernel memory device
116 */
117 if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, "identd")) ==
118 NULL)
119 ERROR("main: kvm_open");
120
121 /*
122 ** Extract offsets to the needed variables in the kernel
123 */
124 if (kvm_nlist(kd, nl) < 0)
125 ERROR("main: kvm_nlist");
126
127 return 0;
128}
129
130
131/*
132** Get a piece of kernel memory with error handling.
133** Returns 1 if call succeeded, else 0 (zero).
134*/
135static int getbuf(addr, buf, len, what)
136 long addr;
137 char *buf;
138 int len;
139 char *what;
140{
141 if (kvm_read(kd, addr, buf, len) < 0)
142 {
143 if (syslog_flag)
144 syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
145 addr, len, what);
146
147 return 0;
148 }
149
150 return 1;
151}
152
153
154
155/*
156** Traverse the inpcb list until a match is found.
157** Returns NULL if no match.
158*/
159static struct socket *
160 getlist(pcbp_head, faddr, fport, laddr, lport)
161 struct inpcbhead *pcbp_head;
162 struct in_addr *faddr;
163 int fport;
164 struct in_addr *laddr;
165 int lport;
166{
167 struct inpcb *pcbp;
168 struct inpcb pcb;
169
170 pcbp = pcbp_head->lh_first;
171 while (pcbp &&
172 getbuf((long) pcbp,
173 &pcb,
174 sizeof(struct inpcb),
175 "tcblist"))
176 {
177 if ( pcb.inp_faddr.s_addr == faddr->s_addr &&
178 pcb.inp_laddr.s_addr == laddr->s_addr &&
179 pcb.inp_fport == fport &&
180 pcb.inp_lport == lport )
181 return pcb.inp_socket;
182
183 pcbp = pcb.inp_list.le_next;
184 }
185
186 return NULL;
187}
188
189
190
191/*
192** Return the user number for the connection owner
193*/
194int k_getuid(faddr, fport, laddr, lport, uid)
195 struct in_addr *faddr;
196 int fport;
197 struct in_addr *laddr;
198 int lport;
199 int *uid;
200{
201 long addr;
202 struct socket *sockp;
203 int i, mib[2];
204 struct ucred ucb;
205
206 /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
207 if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
208 return -1;
209
210 if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
211 return -1;
212
213 {
214 int siz, rv;
215
216 mib[0] = CTL_KERN;
217 mib[1] = KERN_FILE;
218 if ((rv = sysctl(mib, 2, NULL, &siz, NULL, 0)) == -1)
219 {
220 ERROR1("k_getuid: sysctl 1 (%d)", rv);
221 return -1;
222 }
223 xfile = malloc(siz);
224 if (!xfile)
225 ERROR1("k_getuid: malloc(%d)", siz);
226 if ((rv = sysctl(mib, 2, xfile, &siz, NULL, 0)) == -1)
227 {
228 ERROR1("k_getuid: sysctl 2 (%d)", rv);
229 return -1;
230 }
231 xfile = (struct file *)((char *)xfile + sizeof(filehead));
232 }
233
234 /* -------------------- TCP PCB LIST -------------------- */
235 if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
236 return -1;
237
238 sockp = getlist(&tcb, faddr, fport, laddr, lport);
239
240 if (!sockp)
241 return -1;
242
243 /*
244 ** Locate the file descriptor that has the socket in question
245 ** open so that we can get the 'ucred' information
246 */
247 for (i = 0; i < nfile; i++)
248 {
249 if (xfile[i].f_count == 0)
250 continue;
251
252 if (xfile[i].f_type == DTYPE_SOCKET &&
253 (struct socket *) xfile[i].f_data == sockp)
254 {
255 if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
256 return -1;
257
258 *uid = ucb.cr_uid;
259 return 0;
260 }
261 }
262
263 return -1;
264}
265