]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netccitt/pk_llcsubr.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (C) Dirk Husemann, Computer Science Department IV,
24 * University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
25 * Copyright (c) 1992, 1993
26 * The Regents of the University of California. All rights reserved.
28 * This code is derived from software contributed to Berkeley by
29 * Dirk Husemann and the Computer Science Department (IV) of
30 * the University of Erlangen-Nuremberg, Germany.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)pk_llcsubr.c 8.1 (Berkeley) 6/10/93
63 #include <sys/param.h>
64 #include <sys/systm.h>
66 #include <sys/domain.h>
67 #include <sys/socket.h>
68 #include <sys/socketvar.h>
69 #include <sys/protosw.h>
70 #include <sys/errno.h>
72 #include <sys/kernel.h>
73 #include <sys/malloc.h>
76 #include <net/if_dl.h>
77 #include <net/if_llc.h>
78 #include <net/if_types.h>
79 #include <net/route.h>
81 #include <netccitt/dll.h>
82 #include <netccitt/x25.h>
83 #include <netccitt/pk.h>
84 #include <netccitt/pk_var.h>
85 #include <netccitt/llc_var.h>
89 * Routing support for X.25
91 * We distinguish between two cases:
93 * rt_key(rt) X.25 address of host
94 * rt_gateway SNPA (MAC+DLSAP) address of host
95 * rt_llinfo pkcb for rt_key(rt)
98 * rt_key(rt) X.25 address of host or suitably masked network
99 * rt_gateway X.25 address of next X.25 gateway (switch)
100 * rt_llinfo rtentry for rt_gateway address
101 * ought to be of type RTF_HOST
104 * Mapping of X.121 to pkcbs:
106 * HDLC uses the DTE-DCE model of X.25, therefore we need a many-to-one
107 * relationship, i.e.:
109 * {X.121_a, X.121_b, X.121_c, ..., X.121_i} -> pkcb_0
111 * LLC2 utilizes the DTE-DTE model of X.25, resulting effectively in a
112 * one-to-one relationship, i.e.:
114 * {X.121_j} -> pkcb_1a
115 * {X.121_k} -> pkcb_1b
117 * {X.121_q} -> pkcb_1q
119 * It might make sense to allow a many-to-one relation for LLC2 also,
121 * {X.121_r, X.121_s, X.121_t, X.121_u} -> pkcb_2a
123 * This would make addresses X.121_[r-u] essentially aliases of one
124 * address ({X.121_[r-u]} would constitute a representative set).
126 * Each one-to-one relation must obviously be entered individually with
127 * a route add command, whereas a many-to-one relationship can be
128 * either entered individually or generated by using a netmask.
130 * To facilitate dealings the many-to-one case for LLC2 can only be
131 * established via a netmask.
135 #define XTRACTPKP(rt) ((rt)->rt_flags & RTF_GATEWAY ? \
137 (struct pkcb *) ((struct rtentry *)((rt)->rt_llinfo))->rt_llinfo : \
138 (struct pkcb *) NULL) : \
139 (struct pkcb *)((rt)->rt_llinfo))
141 #define equal(a1, a2) (bcmp((caddr_t)(a1), \
144 #define XIFA(rt) ((struct x25_ifaddr *)((rt)->rt_ifa))
145 #define SA(s) ((struct sockaddr *)s)
148 cons_rtrequest(int cmd
, struct rtentry
*rt
, struct sockaddr
*dst
)
150 register struct pkcb
*pkp
;
152 register char one_to_one
;
153 struct pkcb
*pk_newlink();
154 struct rtentry
*npaidb_enter();
164 if (rt
->rt_flags
& RTF_GATEWAY
) {
166 RTFREE((struct rtentry
*)rt
->rt_llinfo
);
167 rt
->rt_llinfo
= (caddr_t
) rtalloc1(rt
->rt_gateway
, 1);
171 * Assumptions: (1) ifnet structure is filled in
172 * (2) at least the pkcb created via
173 * x25config (ifconfig?) has been
175 * (3) HDLC interfaces have an if_type of
176 * IFT_X25{,DDN}, LLC2 interfaces
177 * anything else (any better way to
185 * We differentiate between dealing with a many-to-one
186 * (HDLC: DTE-DCE) and a one-to-one (LLC2: DTE-DTE)
187 * relationship (by looking at the if type).
189 * Only in case of the many-to-one relationship (HDLC)
190 * we set the ia->ia_pkcb pointer to the pkcb allocated
191 * via pk_newlink() as we will use just that one pkcb for
192 * future route additions (the rtentry->rt_llinfo pointer
193 * points to the pkcb allocated for that route).
195 * In case of the one-to-one relationship (LLC2) we
196 * create a new pkcb (via pk_newlink()) for each new rtentry.
198 * NOTE: Only in case of HDLC does ia->ia_pkcb point
199 * to a pkcb, in the LLC2 case it doesn't (as we don't
202 one_to_one
= ISISO8802(rt
->rt_ifp
);
204 if (!(pkp
= XIFA(rt
)->ia_pkcb
) && !one_to_one
)
205 XIFA(rt
)->ia_pkcb
= pkp
=
206 pk_newlink(XIFA(rt
), (caddr_t
) 0);
207 else if (one_to_one
&&
208 !equal(rt
->rt_gateway
, rt
->rt_ifa
->ifa_addr
)) {
209 pkp
= pk_newlink(XIFA(rt
), (caddr_t
) 0);
211 * We also need another route entry for mapping
212 * MAC+LSAP->X.25 address
214 pkp
->pk_llrt
= npaidb_enter(rt
->rt_gateway
, rt_key(rt
), rt
, 0);
221 rt
->rt_llinfo
= (caddr_t
) pkp
;
228 * The pkp might be empty if we are dealing
229 * with an interface route entry for LLC2, in this
230 * case we don't need to do anything ...
233 if ( rt
->rt_flags
& RTF_GATEWAY
) {
235 RTFREE((struct rtentry
*)rt
->rt_llinfo
);
240 npaidb_destroy(pkp
->pk_llrt
);
251 * Network Protocol Addressing Information DataBase (npaidb)
253 * To speed up locating the entity dealing with an LLC packet use is made
254 * of a routing tree. This npaidb routing tree is handled
255 * by the normal rn_*() routines just like (almost) any other routing tree.
257 * The mapping being done by the npaidb_*() routines is as follows:
259 * Key: MAC,LSAP (enhancing struct sockaddr_dl)
260 * Gateway: sockaddr_x25 (i.e. X.25 address - X.121 or NSAP)
261 * Llinfo: npaidbentry {
262 * struct llc_linkcb *npaidb_linkp;
263 * struct rtentry *npaidb_rt;
266 * Using the npaidbentry provided by llinfo we can then access
268 * o the pkcb by using (struct pkcb *) (npaidb_rt->rt_llinfo)
269 * o the linkcb via npaidb_linkp
271 * The following functions are provided
273 * o npaidb_enter(struct sockaddr_dl *sdl, struct sockaddr_x25 *sx25,
274 * struct struct llc_linkcb *link, struct rtentry *rt)
276 * o npaidb_enrich(short type, caddr_t info)
280 struct sockaddr_dl npdl_netmask
= {
281 sizeof(struct sockaddr_dl
), /* _len */
288 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* _data */
290 struct sockaddr npdl_dummy
;
292 int npdl_datasize
= sizeof(struct sockaddr_dl
)-
293 ((int)((caddr_t
)&((struct sockaddr_dl
*)0)->sdl_data
[0]));
296 npaidb_enter(struct sockaddr_dl
*key
, struct sockaddr
*value
,
297 struct rtentry
*rt
, struct llc_linkcb
*link
)
299 struct rtentry
*nprt
; register int i
;
303 if ((nprt
= rtalloc1(SA(key
), 0)) == 0) {
304 register u_int size
= sizeof(struct npaidbentry
);
305 register u_char saploc
= LLSAPLOC(key
, rt
->rt_ifp
);
308 * set up netmask: LLC2 packets have the lowest bit set in
309 * response packets (e.g. 0x7e for command packets, 0x7f for
310 * response packets), to facilitate the lookup we use a netmask
311 * of 11111110 for the SAP position. The remaining positions
314 npdl_netmask
.sdl_data
[saploc
] = NPDL_SAPNETMASK
;
315 bzero((caddr_t
)&npdl_netmask
.sdl_data
[saploc
+1],
316 npdl_datasize
-saploc
-1);
322 rtrequest(RTM_ADD
, SA(key
), SA(value
),
323 SA(&npdl_netmask
), 0, &nprt
);
325 /* and reset npdl_netmask */
326 for (i
= saploc
; i
< npdl_datasize
; i
++)
327 npdl_netmask
.sdl_data
[i
] = -1;
329 // nprt->rt_llinfo = malloc(size , M_PCB, M_WAITOK);
330 MALLOC(nprt
->rt_llinfo
, caddr_t
, size
, M_PCB
, M_WAITOK
);
331 if (nprt
->rt_llinfo
) {
332 bzero (nprt
->rt_llinfo
, size
);
333 ((struct npaidbentry
*) (nprt
->rt_llinfo
))->np_rt
= rt
;
335 } else nprt
->rt_refcnt
--;
340 npaidb_enrich(short type
, caddr_t info
, struct sockaddr_dl
*sdl
)
346 if (rt
= rtalloc1((struct sockaddr
*)sdl
, 0)) {
350 ((struct npaidbentry
*)(rt
->rt_llinfo
))->np_link
=
351 (struct llc_linkcb
*) info
;
357 return ((struct rtentry
*) 0);
361 npaidb_destroy(struct rtentry
*rt
)
366 FREE((caddr_t
) rt
->rt_llinfo
, M_PCB
);
367 return(rtrequest(RTM_DELETE
, rt_key(rt
), rt
->rt_gateway
, rt_mask(rt
),
374 * Glue between X.25 and LLC2
377 x25_llcglue(int prc
, struct sockaddr
*addr
)
379 register struct sockaddr_x25
*sx25
= (struct sockaddr_x25
*)addr
;
380 register struct x25_ifaddr
*x25ifa
;
381 struct dll_ctlinfo ctlinfo
;
383 if((x25ifa
= (struct x25_ifaddr
*)ifa_ifwithaddr(addr
)) == 0)
387 (struct dllconfig
*)(((struct sockaddr_x25
*)(&x25ifa
->ia_xc
))+1);
388 ctlinfo
.dlcti_lsap
= LLC_X25_LSAP
;
390 return ((int)llc_ctlinput(prc
, addr
, (caddr_t
)&ctlinfo
));