Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / sys / protosw.h @ 14

History | View | Annotate | Download (15.8 KB)

1
/*        $NetBSD: protosw.h,v 1.64 2015/05/02 17:18:04 rtr Exp $        */
2

    
3
/*-
4
 * Copyright (c) 1982, 1986, 1993
5
 *        The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 * 3. Neither the name of the University nor the names of its contributors
16
 *    may be used to endorse or promote products derived from this software
17
 *    without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
 * SUCH DAMAGE.
30
 *
31
 *        @(#)protosw.h        8.1 (Berkeley) 6/2/93
32
 */
33

    
34
#ifndef _SYS_PROTOSW_H_
35
#define _SYS_PROTOSW_H_
36

    
37
/*
38
 * Protocol switch table.
39
 *
40
 * Each protocol has a handle initializing one of these structures,
41
 * which is used for protocol-protocol and system-protocol communication.
42
 *
43
 * A protocol is called through the pr_init entry before any other.
44
 * Thereafter it is called every 200ms through the pr_fasttimo entry and
45
 * every 500ms through the pr_slowtimo for timer based actions.
46
 * The system will call the pr_drain entry if it is low on space and
47
 * this should throw away any non-critical data.
48
 *
49
 * Protocols pass data between themselves as chains of mbufs using
50
 * the pr_input and pr_output hooks.  Pr_input passes data up (towards
51
 * UNIX) and pr_output passes it down (towards the imps); control
52
 * information passes up and down on pr_ctlinput and pr_ctloutput.
53
 * The protocol is responsible for the space occupied by any the
54
 * arguments to these entries and must dispose it.
55
 *
56
 * The userreq routine interfaces protocols to the system and is
57
 * described below.
58
 */
59

    
60
struct mbuf;
61
struct ifnet;
62
struct sockaddr;
63
struct socket;
64
struct sockopt;
65
struct stat;
66
struct domain;
67
struct proc;
68
struct lwp;
69
struct pr_usrreqs;
70

    
71
struct protosw {
72
        int         pr_type;                /* socket type used for */
73
        struct        domain *pr_domain;        /* domain protocol a member of */
74
        short        pr_protocol;                /* protocol number */
75
        short        pr_flags;                /* see below */
76

    
77
/* protocol-protocol hooks */
78
        void        (*pr_input)                /* input to protocol (from below) */
79
                        (struct mbuf *, ...);
80
        int        (*pr_output)                /* output to protocol (from above) */
81
                        (struct mbuf *, ...);
82
        void        *(*pr_ctlinput)                /* control input (from below) */
83
                        (int, const struct sockaddr *, void *);
84
        int        (*pr_ctloutput)                /* control output (from above) */
85
                        (int, struct socket *, struct sockopt *);
86

    
87
/* user-protocol hooks */
88
        const struct pr_usrreqs *pr_usrreqs;
89

    
90
/* utility hooks */
91
        void        (*pr_init)                /* initialization hook */
92
                        (void);
93

    
94
        void        (*pr_fasttimo)                /* fast timeout (200ms) */
95
                        (void);
96
        void        (*pr_slowtimo)                /* slow timeout (500ms) */
97
                        (void);
98
        void        (*pr_drain)                /* flush any excess space possible */
99
                        (void);
100
};
101

    
102
#define        PR_SLOWHZ        2                /* 2 slow timeouts per second */
103
#define        PR_FASTHZ        5                /* 5 fast timeouts per second */
104

    
105
/*
106
 * Values for pr_flags.
107
 * PR_ADDR requires PR_ATOMIC;
108
 * PR_ADDR and PR_CONNREQUIRED are mutually exclusive.
109
 */
110
#define        PR_ATOMIC        0x01                /* exchange atomic messages only */
111
#define        PR_ADDR                0x02                /* addresses given with messages */
112
#define        PR_CONNREQUIRED        0x04                /* connection required by protocol */
113
#define        PR_WANTRCVD        0x08                /* want pr_rcvd() calls */
114
#define        PR_RIGHTS        0x10                /* passes capabilities */
115
#define        PR_LISTEN        0x20                /* supports listen(2) and accept(2) */
116
#define        PR_LASTHDR        0x40                /* enforce ipsec policy; last header */
117
#define        PR_ABRTACPTDIS        0x80                /* abort on accept(2) to disconnected
118
                                           socket */
119
#define PR_PURGEIF        0x100                /* might store struct ifnet pointer;
120
                                           pr_purgeif() must be called on ifnet
121
                                           deletion */
122

    
123
/*
124
 * The arguments to usrreq are:
125
 *        (*protosw[].pr_usrreq)(up, req, m, nam, opt, p);
126
 * where up is a (struct socket *), req is one of these requests,
127
 * m is a optional mbuf chain containing a message,
128
 * nam is an optional mbuf chain containing an address,
129
 * opt is an optional mbuf containing socket options,
130
 * and p is a pointer to the process requesting the action (if any).
131
 * The protocol is responsible for disposal of the mbuf chains m and opt,
132
 * the caller is responsible for any space held by nam.
133
 * A non-zero return from usrreq gives an
134
 * UNIX error number which should be passed to higher level software.
135
 */
136
#define        PRU_ATTACH                0        /* attach protocol to up */
137
#define        PRU_DETACH                1        /* detach protocol from up */
138
#define        PRU_BIND                2        /* bind socket to address */
139
#define        PRU_LISTEN                3        /* listen for connection */
140
#define        PRU_CONNECT                4        /* establish connection to peer */
141
#define        PRU_ACCEPT                5        /* accept connection from peer */
142
#define        PRU_DISCONNECT                6        /* disconnect from peer */
143
#define        PRU_SHUTDOWN                7        /* won't send any more data */
144
#define        PRU_RCVD                8        /* have taken data; more room now */
145
#define        PRU_SEND                9        /* send this data */
146
#define        PRU_ABORT                10        /* abort (fast DISCONNECT, DETACH) */
147
#define        PRU_CONTROL                11        /* control operations on protocol */
148
#define        PRU_SENSE                12        /* return status into m */
149
#define        PRU_RCVOOB                13        /* retrieve out of band data */
150
#define        PRU_SENDOOB                14        /* send out of band data */
151
#define        PRU_SOCKADDR                15        /* fetch socket's address */
152
#define        PRU_PEERADDR                16        /* fetch peer's address */
153
#define        PRU_CONNECT2                17        /* connect two sockets */
154
/* begin for protocols internal use */
155
#define        PRU_FASTTIMO                18        /* 200ms timeout */
156
#define        PRU_SLOWTIMO                19        /* 500ms timeout */
157
#define        PRU_PROTORCV                20        /* receive from below */
158
#define        PRU_PROTOSEND                21        /* send to below */
159
#define        PRU_PURGEIF                22        /* purge specified if */
160

    
161
#define        PRU_NREQ                23
162

    
163
#ifdef PRUREQUESTS
164
static const char * const prurequests[] = {
165
        "ATTACH",        "DETACH",        "BIND",                "LISTEN",
166
        "CONNECT",        "ACCEPT",        "DISCONNECT",        "SHUTDOWN",
167
        "RCVD",                "SEND",                "ABORT",        "CONTROL",
168
        "SENSE",        "RCVOOB",        "SENDOOB",        "SOCKADDR",
169
        "PEERADDR",        "CONNECT2",        "FASTTIMO",        "SLOWTIMO",
170
        "PROTORCV",        "PROTOSEND",        "PURGEIF",
171
};
172
#endif
173

    
174
/*
175
 * The arguments to the ctlinput routine are
176
 *        (*protosw[].pr_ctlinput)(cmd, sa, arg);
177
 * where cmd is one of the commands below, sa is a pointer to a sockaddr,
178
 * and arg is an optional void *argument used within a protocol family.
179
 */
180
#define        PRC_IFDOWN                0        /* interface transition */
181
#define        PRC_ROUTEDEAD                1        /* select new route if possible ??? */
182
#define        PRC_QUENCH2                3        /* DEC congestion bit says slow down */
183
#define        PRC_QUENCH                4        /* some one said to slow down */
184
#define        PRC_MSGSIZE                5        /* message size forced drop */
185
#define        PRC_HOSTDEAD                6        /* host appears to be down */
186
#define        PRC_HOSTUNREACH                7        /* deprecated (use PRC_UNREACH_HOST) */
187
#define        PRC_UNREACH_NET                8        /* no route to network */
188
#define        PRC_UNREACH_HOST        9        /* no route to host */
189
#define        PRC_UNREACH_PROTOCOL        10        /* dst says bad protocol */
190
#define        PRC_UNREACH_PORT        11        /* bad port # */
191
/* was        PRC_UNREACH_NEEDFRAG        12           (use PRC_MSGSIZE) */
192
#define        PRC_UNREACH_SRCFAIL        13        /* source route failed */
193
#define        PRC_REDIRECT_NET        14        /* net routing redirect */
194
#define        PRC_REDIRECT_HOST        15        /* host routing redirect */
195
#define        PRC_REDIRECT_TOSNET        16        /* redirect for type of service & net */
196
#define        PRC_REDIRECT_TOSHOST        17        /* redirect for tos & host */
197
#define        PRC_TIMXCEED_INTRANS        18        /* packet lifetime expired in transit */
198
#define        PRC_TIMXCEED_REASS        19        /* lifetime expired on reass q */
199
#define        PRC_PARAMPROB                20        /* header incorrect */
200

    
201
#define        PRC_NCMDS                21
202

    
203
#define        PRC_IS_REDIRECT(cmd)        \
204
        ((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
205

    
206
#ifdef PRCREQUESTS
207
static const char * const prcrequests[] = {
208
        "IFDOWN", "ROUTEDEAD", "#2", "DEC-BIT-QUENCH2",
209
        "QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
210
        "NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
211
        "#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
212
        "TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
213
        "PARAMPROB"
214
};
215
#endif
216

    
217
/*
218
 * The arguments to ctloutput are:
219
 *        (*protosw[].pr_ctloutput)(req, so, sopt);
220
 * req is one of the actions listed below, so is a (struct socket *),
221
 * sopt is a (struct sockopt *)
222
 * A non-zero return from usrreq gives an
223
 * UNIX error number which should be passed to higher level software.
224
 */
225
#define        PRCO_GETOPT        0
226
#define        PRCO_SETOPT        1
227

    
228
#define        PRCO_NCMDS        2
229

    
230
#ifdef PRCOREQUESTS
231
static const char * const prcorequests[] = {
232
        "GETOPT", "SETOPT",
233
};
234
#endif
235

    
236
#ifdef _KERNEL
237

    
238
struct pr_usrreqs {
239
        int        (*pr_attach)(struct socket *, int);
240
        void        (*pr_detach)(struct socket *);
241
        int        (*pr_accept)(struct socket *, struct sockaddr *);
242
        int        (*pr_connect)(struct socket *, struct sockaddr *, struct lwp *);
243
        int        (*pr_connect2)(struct socket *, struct socket *);
244
        int        (*pr_bind)(struct socket *, struct sockaddr *, struct lwp *);
245
        int        (*pr_listen)(struct socket *, struct lwp *);
246
        int        (*pr_disconnect)(struct socket *);
247
        int        (*pr_shutdown)(struct socket *);
248
        int        (*pr_abort)(struct socket *);
249
        int        (*pr_ioctl)(struct socket *, u_long, void *, struct ifnet *);
250
        int        (*pr_stat)(struct socket *, struct stat *);
251
        int        (*pr_peeraddr)(struct socket *, struct sockaddr *);
252
        int        (*pr_sockaddr)(struct socket *, struct sockaddr *);
253
        int        (*pr_rcvd)(struct socket *, int, struct lwp *);
254
        int        (*pr_recvoob)(struct socket *, struct mbuf *, int);
255
        int        (*pr_send)(struct socket *, struct mbuf *, struct sockaddr *,
256
            struct mbuf *, struct lwp *);
257
        int        (*pr_sendoob)(struct socket *, struct mbuf *, struct mbuf *);
258
        int        (*pr_purgeif)(struct socket *, struct ifnet *);
259
};
260

    
261
/*
262
 * Monotonically increasing time values for slow and fast timers.
263
 */
264
extern        u_int pfslowtimo_now;
265
extern        u_int pffasttimo_now;
266

    
267
#define        PRT_SLOW_ARM(t, nticks)        (t) = (pfslowtimo_now + (nticks))
268
#define        PRT_FAST_ARM(t, nticks)        (t) = (pffasttimo_now + (nticks))
269

    
270
#define        PRT_SLOW_DISARM(t)        (t) = 0
271
#define        PRT_FAST_DISARM(t)        (t) = 0
272

    
273
#define        PRT_SLOW_ISARMED(t)        ((t) != 0)
274
#define        PRT_FAST_ISARMED(t)        ((t) != 0)
275

    
276
#define        PRT_SLOW_ISEXPIRED(t)        (PRT_SLOW_ISARMED((t)) && (t) <= pfslowtimo_now)
277
#define        PRT_FAST_ISEXPIRED(t)        (PRT_FAST_ISARMED((t)) && (t) <= pffasttimo_now)
278

    
279
struct sockaddr;
280
const struct protosw *pffindproto(int, int, int);
281
const struct protosw *pffindtype(int, int);
282
struct domain *pffinddomain(int);
283
void pfctlinput(int, const struct sockaddr *);
284
void pfctlinput2(int, const struct sockaddr *, void *);
285

    
286
/*
287
 * Wrappers for non-MPSAFE protocols
288
 */
289
#include <sys/systm.h>        /* kernel_lock */
290

    
291
#define        PR_WRAP_USRREQS(name)                                \
292
static int                                                \
293
name##_attach_wrapper(struct socket *a, int b)                \
294
{                                                        \
295
        int rv;                                                \
296
        KERNEL_LOCK(1, NULL);                                \
297
        rv = name##_attach(a, b);                        \
298
        KERNEL_UNLOCK_ONE(NULL);                        \
299
        return rv;                                        \
300
}                                                        \
301
static void                                                \
302
name##_detach_wrapper(struct socket *a)                        \
303
{                                                        \
304
        KERNEL_LOCK(1, NULL);                                \
305
        name##_detach(a);                                \
306
        KERNEL_UNLOCK_ONE(NULL);                        \
307
}                                                        \
308
static int                                                \
309
name##_accept_wrapper(struct socket *a,                        \
310
    struct sockaddr *b)                                        \
311
{                                                        \
312
        int rv;                                                \
313
        KERNEL_LOCK(1, NULL);                                \
314
        rv = name##_accept(a, b);                        \
315
        KERNEL_UNLOCK_ONE(NULL);                        \
316
        return rv;                                        \
317
}                                                        \
318
static int                                                \
319
name##_bind_wrapper(struct socket *a,                        \
320
    struct sockaddr *b,        struct lwp *c)                        \
321
{                                                        \
322
        int rv;                                                \
323
        KERNEL_LOCK(1, NULL);                                \
324
        rv = name##_bind(a, b, c);                        \
325
        KERNEL_UNLOCK_ONE(NULL);                        \
326
        return rv;                                        \
327
}                                                        \
328
static int                                                \
329
name##_connect_wrapper(struct socket *a,                \
330
    struct sockaddr *b, struct lwp *c)                        \
331
{                                                        \
332
        int rv;                                                \
333
        KERNEL_LOCK(1, NULL);                                \
334
        rv = name##_connect(a, b, c);                        \
335
        KERNEL_UNLOCK_ONE(NULL);                        \
336
        return rv;                                        \
337
}                                                        \
338
static int                                                \
339
name##_connect2_wrapper(struct socket *a,                \
340
    struct socket *b)                                        \
341
{                                                        \
342
        int rv;                                                \
343
        KERNEL_LOCK(1, NULL);                                \
344
        rv = name##_connect2(a, b);                        \
345
        KERNEL_UNLOCK_ONE(NULL);                        \
346
        return rv;                                        \
347
}                                                        \
348
static int                                                \
349
name##_listen_wrapper(struct socket *a, struct lwp *b)        \
350
{                                                        \
351
        int rv;                                                \
352
        KERNEL_LOCK(1, NULL);                                \
353
        rv = name##_listen(a, b);                        \
354
        KERNEL_UNLOCK_ONE(NULL);                        \
355
        return rv;                                        \
356
}                                                        \
357
static int                                                \
358
name##_disconnect_wrapper(struct socket *a)                \
359
{                                                        \
360
        int rv;                                                \
361
        KERNEL_LOCK(1, NULL);                                \
362
        rv = name##_disconnect(a);                        \
363
        KERNEL_UNLOCK_ONE(NULL);                        \
364
        return rv;                                        \
365
}                                                        \
366
static int                                                \
367
name##_shutdown_wrapper(struct socket *a)                \
368
{                                                        \
369
        int rv;                                                \
370
        KERNEL_LOCK(1, NULL);                                \
371
        rv = name##_shutdown(a);                        \
372
        KERNEL_UNLOCK_ONE(NULL);                        \
373
        return rv;                                        \
374
}                                                        \
375
static int                                                \
376
name##_abort_wrapper(struct socket *a)                        \
377
{                                                        \
378
        int rv;                                                \
379
        KERNEL_LOCK(1, NULL);                                \
380
        rv = name##_abort(a);                                \
381
        KERNEL_UNLOCK_ONE(NULL);                        \
382
        return rv;                                        \
383
}                                                        \
384
static int                                                \
385
name##_ioctl_wrapper(struct socket *a, u_long b,        \
386
    void *c, struct ifnet *d)                                \
387
{                                                        \
388
        int rv;                                                \
389
        KERNEL_LOCK(1, NULL);                                \
390
        rv = name##_ioctl(a, b, c, d);                        \
391
        KERNEL_UNLOCK_ONE(NULL);                        \
392
        return rv;                                        \
393
}                                                        \
394
static int                                                \
395
name##_stat_wrapper(struct socket *a, struct stat *b)        \
396
{                                                        \
397
        int rv;                                                \
398
        KERNEL_LOCK(1, NULL);                                \
399
        rv = name##_stat(a, b);                                \
400
        KERNEL_UNLOCK_ONE(NULL);                        \
401
        return rv;                                        \
402
}                                                        \
403
static int                                                \
404
name##_peeraddr_wrapper(struct socket *a,                \
405
    struct sockaddr *b)                                        \
406
{                                                        \
407
        int rv;                                                \
408
        KERNEL_LOCK(1, NULL);                                \
409
        rv = name##_peeraddr(a, b);                        \
410
        KERNEL_UNLOCK_ONE(NULL);                        \
411
        return rv;                                        \
412
}                                                        \
413
static int                                                \
414
name##_sockaddr_wrapper(struct socket *a,                \
415
    struct sockaddr *b)                                        \
416
{                                                        \
417
        int rv;                                                \
418
        KERNEL_LOCK(1, NULL);                                \
419
        rv = name##_sockaddr(a, b);                        \
420
        KERNEL_UNLOCK_ONE(NULL);                        \
421
        return rv;                                        \
422
}                                                        \
423
static int                                                \
424
name##_rcvd_wrapper(struct socket *a, int b,                \
425
    struct lwp *c)                                        \
426
{                                                        \
427
        int rv;                                                \
428
        KERNEL_LOCK(1, NULL);                                \
429
        rv = name##_rcvd(a, b, c);                        \
430
        KERNEL_UNLOCK_ONE(NULL);                        \
431
        return rv;                                        \
432
}                                                        \
433
static int                                                \
434
name##_recvoob_wrapper(struct socket *a,                \
435
    struct mbuf *b, int c)                                \
436
{                                                        \
437
        int rv;                                                \
438
        KERNEL_LOCK(1, NULL);                                \
439
        rv = name##_recvoob(a, b, c);                        \
440
        KERNEL_UNLOCK_ONE(NULL);                        \
441
        return rv;                                        \
442
}                                                        \
443
static int                                                \
444
name##_send_wrapper(struct socket *a, struct mbuf *b,        \
445
    struct sockaddr *c, struct mbuf *d, struct lwp *e)        \
446
{                                                        \
447
        int rv;                                                \
448
        KERNEL_LOCK(1, NULL);                                \
449
        rv = name##_send(a, b, c, d, e);                \
450
        KERNEL_UNLOCK_ONE(NULL);                        \
451
        return rv;                                        \
452
}                                                        \
453
static int                                                \
454
name##_sendoob_wrapper(struct socket *a,                \
455
    struct mbuf *b, struct mbuf *c)                        \
456
{                                                        \
457
        int rv;                                                \
458
        KERNEL_LOCK(1, NULL);                                \
459
        rv = name##_sendoob(a, b, c);                        \
460
        KERNEL_UNLOCK_ONE(NULL);                        \
461
        return rv;                                        \
462
}                                                        \
463
static int                                                \
464
name##_purgeif_wrapper(struct socket *a,                \
465
    struct ifnet *b)                                        \
466
{                                                        \
467
        int rv;                                                \
468
        KERNEL_LOCK(1, NULL);                                \
469
        rv = name##_purgeif(a, b);                        \
470
        KERNEL_UNLOCK_ONE(NULL);                        \
471
        return rv;                                        \
472
}
473

    
474
#define        PR_WRAP_CTLOUTPUT(name)                                \
475
static int                                                \
476
name##_wrapper(int a, struct socket *b,                        \
477
    struct sockopt *c)                                        \
478
{                                                        \
479
        int rv;                                                \
480
        KERNEL_LOCK(1, NULL);                                \
481
        rv = name(a, b, c);                                \
482
        KERNEL_UNLOCK_ONE(NULL);                        \
483
        return rv;                                        \
484
}
485

    
486
#define        PR_WRAP_CTLINPUT(name)                                \
487
static void *                                                \
488
name##_wrapper(int a, const struct sockaddr *b, void *c)\
489
{                                                        \
490
        void *rv;                                        \
491
        KERNEL_LOCK(1, NULL);                                \
492
        rv = name(a, b, c);                                \
493
        KERNEL_UNLOCK_ONE(NULL);                        \
494
        return rv;                                        \
495
}
496

    
497
#endif /* _KERNEL */
498

    
499
#endif /* !_SYS_PROTOSW_H_ */