Deleted Added
full compact
at_control.c (15885) at_control.c (17254)
1/*
2 * Copyright (c) 1990,1991 Regents of The University of Michigan.
3 * All Rights Reserved.
4 */
5
6#include <sys/param.h>
7#include <sys/systm.h>
1/*
2 * Copyright (c) 1990,1991 Regents of The University of Michigan.
3 * All Rights Reserved.
4 */
5
6#include <sys/param.h>
7#include <sys/systm.h>
8#ifdef ibm032
9#include <sys/dir.h>
10#endif ibm032
11#include <sys/proc.h>
8#include <sys/proc.h>
12#ifndef BSD4_4
13#include <sys/user.h>
14#endif
15#include <sys/types.h>
16#include <sys/errno.h>
17#include <sys/ioctl.h>
18#include <sys/mbuf.h>
9#include <sys/types.h>
10#include <sys/errno.h>
11#include <sys/ioctl.h>
12#include <sys/mbuf.h>
19#ifndef _IBMR2
20#include <sys/kernel.h>
13#include <sys/kernel.h>
21#endif _IBMR2
22#include <sys/socket.h>
23#include <sys/socketvar.h>
24#include <net/if.h>
14#include <sys/socket.h>
15#include <sys/socketvar.h>
16#include <net/if.h>
25/* #include <net/af.h> */
26#include <net/route.h>
27#include <netinet/in.h>
28#undef s_net
29#include <netinet/if_ether.h>
17#include <net/route.h>
18#include <netinet/in.h>
19#undef s_net
20#include <netinet/if_ether.h>
30#ifdef _IBMR2
31#include <net/spl.h>
32#endif _IBMR2
33
34#include "at.h"
35#include "at_var.h"
36#include "aarp.h"
37#include "phase2.h"
38#include <netatalk/at_extern.h>
39
21
22#include "at.h"
23#include "at_var.h"
24#include "aarp.h"
25#include "phase2.h"
26#include <netatalk/at_extern.h>
27
28static int aa_addrangeroute(struct ifaddr *ifa, int first, int last);
29static int aa_addsingleroute(struct ifaddr *ifa,
30 struct at_addr *addr, struct at_addr *mask);
31static int aa_delsingleroute(struct ifaddr *ifa,
32 struct at_addr *addr, struct at_addr *mask);
33static int aa_dosingleroute(struct ifaddr *ifa, struct at_addr *addr,
34 struct at_addr *mask, int cmd, int flags);
40static int at_scrub( struct ifnet *ifp, struct at_ifaddr *aa );
41static int at_ifinit( struct ifnet *ifp, struct at_ifaddr *aa,
42 struct sockaddr_at *sat );
43
35static int at_scrub( struct ifnet *ifp, struct at_ifaddr *aa );
36static int at_ifinit( struct ifnet *ifp, struct at_ifaddr *aa,
37 struct sockaddr_at *sat );
38
44#ifdef BSD4_4
45# define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \
46 (a)->sat_family == (b)->sat_family && \
47 (a)->sat_addr.s_net == (b)->sat_addr.s_net && \
48 (a)->sat_addr.s_node == (b)->sat_addr.s_node )
39# define sateqaddr(a,b) ((a)->sat_len == (b)->sat_len && \
40 (a)->sat_family == (b)->sat_family && \
41 (a)->sat_addr.s_net == (b)->sat_addr.s_net && \
42 (a)->sat_addr.s_node == (b)->sat_addr.s_node )
49#else BSD4_4
50atalk_hash( sat, hp )
51 struct sockaddr_at *sat;
52 struct afhash *hp;
53{
54 hp->afh_nethash = sat->sat_addr.s_net;
55 hp->afh_hosthash = ( sat->sat_addr.s_net << 8 ) +
56 sat->sat_addr.s_node;
57}
58
43
59/*
60 * Note the magic to get ifa_ifwithnet() to work without adding an
61 * ifaddr entry for each net in our local range.
62 */
63int
44int
64atalk_netmatch( sat1, sat2 )
65 struct sockaddr_at *sat1, *sat2;
66{
67 struct at_ifaddr *aa;
68
69 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
70 if ( AA_SAT( aa ) == sat1 ) {
71 break;
72 }
73 }
74 if ( aa ) {
75 return( ntohs( aa->aa_firstnet ) <= ntohs( sat2->sat_addr.s_net ) &&
76 ntohs( aa->aa_lastnet ) >= ntohs( sat2->sat_addr.s_net ));
77 }
78 return( sat1->sat_addr.s_net == sat2->sat_addr.s_net );
79}
80#endif BSD4_4
81
82int
83at_control( int cmd, caddr_t data, struct ifnet *ifp, struct proc *p )
84{
85 struct ifreq *ifr = (struct ifreq *)data;
86 struct sockaddr_at *sat;
87 struct netrange *nr;
45at_control( int cmd, caddr_t data, struct ifnet *ifp, struct proc *p )
46{
47 struct ifreq *ifr = (struct ifreq *)data;
48 struct sockaddr_at *sat;
49 struct netrange *nr;
88#ifdef BSD4_4
89 struct at_aliasreq *ifra = (struct at_aliasreq *)data;
90 struct at_ifaddr *aa0;
50 struct at_aliasreq *ifra = (struct at_aliasreq *)data;
51 struct at_ifaddr *aa0;
91#endif BSD4_4
92 struct at_ifaddr *aa = 0;
93 struct mbuf *m;
94 struct ifaddr *ifa;
95
96 if ( ifp ) {
97 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
98 if ( aa->aa_ifp == ifp ) break;
99 }
100 }
101
102 switch ( cmd ) {
52 struct at_ifaddr *aa = 0;
53 struct mbuf *m;
54 struct ifaddr *ifa;
55
56 if ( ifp ) {
57 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
58 if ( aa->aa_ifp == ifp ) break;
59 }
60 }
61
62 switch ( cmd ) {
103#ifdef BSD4_4
104 case SIOCAIFADDR:
105 case SIOCDIFADDR:
106 if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) {
107 for ( ; aa; aa = aa->aa_next ) {
108 if ( aa->aa_ifp == ifp &&
109 sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) {
110 break;
111 }
112 }
113 }
114 if ( cmd == SIOCDIFADDR && aa == 0 ) {
115 return( EADDRNOTAVAIL );
116 }
117 /*FALLTHROUGH*/
63 case SIOCAIFADDR:
64 case SIOCDIFADDR:
65 if ( ifra->ifra_addr.sat_family == AF_APPLETALK ) {
66 for ( ; aa; aa = aa->aa_next ) {
67 if ( aa->aa_ifp == ifp &&
68 sateqaddr( &aa->aa_addr, &ifra->ifra_addr )) {
69 break;
70 }
71 }
72 }
73 if ( cmd == SIOCDIFADDR && aa == 0 ) {
74 return( EADDRNOTAVAIL );
75 }
76 /*FALLTHROUGH*/
118#endif BSD4_4
119
120 case SIOCSIFADDR:
77
78 case SIOCSIFADDR:
121#ifdef BSD4_4
122 /*
123 * What a great idea this is: Let's reverse the meaning of
124 * the return...
125 */
126#if defined( __FreeBSD__ )
127 if ( suser(p->p_ucred, &p->p_acflag) ) {
79 if ( suser(p->p_ucred, &p->p_acflag) ) {
128#else
129 if ( suser( u.u_cred, &u.u_acflag )) {
130#endif
131 return( EPERM );
132 }
80 return( EPERM );
81 }
133#else BSD4_4
134 if ( !suser()) {
135 return( EPERM );
136 }
137#endif BSD4_4
138
139 sat = satosat( &ifr->ifr_addr );
140 nr = (struct netrange *)sat->sat_zero;
141 if ( nr->nr_phase == 1 ) {
142 for ( ; aa; aa = aa->aa_next ) {
143 if ( aa->aa_ifp == ifp &&
144 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
145 break;

--- 40 unchanged lines hidden (view full) ---

186 if (( ifa = ifp->if_addrlist ) != NULL ) {
187 for ( ; ifa->ifa_next; ifa = ifa->ifa_next )
188 ;
189 ifa->ifa_next = (struct ifaddr *)aa;
190 } else {
191 ifp->if_addrlist = (struct ifaddr *)aa;
192 }
193
82
83 sat = satosat( &ifr->ifr_addr );
84 nr = (struct netrange *)sat->sat_zero;
85 if ( nr->nr_phase == 1 ) {
86 for ( ; aa; aa = aa->aa_next ) {
87 if ( aa->aa_ifp == ifp &&
88 ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
89 break;

--- 40 unchanged lines hidden (view full) ---

130 if (( ifa = ifp->if_addrlist ) != NULL ) {
131 for ( ; ifa->ifa_next; ifa = ifa->ifa_next )
132 ;
133 ifa->ifa_next = (struct ifaddr *)aa;
134 } else {
135 ifp->if_addrlist = (struct ifaddr *)aa;
136 }
137
194#ifdef BSD4_4
195 aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr;
196 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr;
197 aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask;
138 aa->aa_ifa.ifa_addr = (struct sockaddr *)&aa->aa_addr;
139 aa->aa_ifa.ifa_dstaddr = (struct sockaddr *)&aa->aa_addr;
140 aa->aa_ifa.ifa_netmask = (struct sockaddr *)&aa->aa_netmask;
198#endif BSD4_4
199
200 /*
201 * Set/clear the phase 2 bit.
202 */
203 if ( nr->nr_phase == 1 ) {
204 aa->aa_flags &= ~AFA_PHASE2;
205 } else {
206 aa->aa_flags |= AFA_PHASE2;

--- 24 unchanged lines hidden (view full) ---

231
232 if ( aa == (struct at_ifaddr *) 0 )
233 return( EADDRNOTAVAIL );
234 break;
235 }
236
237 switch ( cmd ) {
238 case SIOCGIFADDR:
141
142 /*
143 * Set/clear the phase 2 bit.
144 */
145 if ( nr->nr_phase == 1 ) {
146 aa->aa_flags &= ~AFA_PHASE2;
147 } else {
148 aa->aa_flags |= AFA_PHASE2;

--- 24 unchanged lines hidden (view full) ---

173
174 if ( aa == (struct at_ifaddr *) 0 )
175 return( EADDRNOTAVAIL );
176 break;
177 }
178
179 switch ( cmd ) {
180 case SIOCGIFADDR:
239#ifdef BSD4_4
240 *(struct sockaddr_at *)&ifr->ifr_addr = aa->aa_addr;
241#else BSD4_4
242 ifr->ifr_addr = aa->aa_addr;
243#endif BSD4_4
181 sat = (struct sockaddr_at *)&ifr->ifr_addr;
182 *sat = aa->aa_addr;
183 ((struct netrange *)&sat->sat_zero)->nr_phase
184 = (aa->aa_flags & AFA_PHASE2) ? 2 : 1;
185 ((struct netrange *)&sat->sat_zero)->nr_firstnet = aa->aa_firstnet;
186 ((struct netrange *)&sat->sat_zero)->nr_lastnet = aa->aa_lastnet;
244 break;
245
246 case SIOCSIFADDR:
247 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
248
187 break;
188
189 case SIOCSIFADDR:
190 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
191
249#ifdef BSD4_4
250 case SIOCAIFADDR:
251 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) {
252 return( 0 );
253 }
254 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
255
256 case SIOCDIFADDR:
257 at_scrub( ifp, aa );

--- 20 unchanged lines hidden (view full) ---

278 if ( aa->aa_next ) {
279 aa->aa_next = aa0->aa_next;
280 } else {
281 panic( "at_control" );
282 }
283 }
284 m_free( dtom( aa0 ));
285 break;
192 case SIOCAIFADDR:
193 if ( sateqaddr( &ifra->ifra_addr, &aa->aa_addr )) {
194 return( 0 );
195 }
196 return( at_ifinit( ifp, aa, (struct sockaddr_at *)&ifr->ifr_addr ));
197
198 case SIOCDIFADDR:
199 at_scrub( ifp, aa );

--- 20 unchanged lines hidden (view full) ---

220 if ( aa->aa_next ) {
221 aa->aa_next = aa0->aa_next;
222 } else {
223 panic( "at_control" );
224 }
225 }
226 m_free( dtom( aa0 ));
227 break;
286#endif BSD4_4
287
288 default:
289 if ( ifp == 0 || ifp->if_ioctl == 0 )
290 return( EOPNOTSUPP );
291 return( (*ifp->if_ioctl)( ifp, cmd, data ));
292 }
293 return( 0 );
294}
228
229 default:
230 if ( ifp == 0 || ifp->if_ioctl == 0 )
231 return( EOPNOTSUPP );
232 return( (*ifp->if_ioctl)( ifp, cmd, data ));
233 }
234 return( 0 );
235}
236
295static int
296at_scrub( ifp, aa )
297 struct ifnet *ifp;
298 struct at_ifaddr *aa;
299{
237static int
238at_scrub( ifp, aa )
239 struct ifnet *ifp;
240 struct at_ifaddr *aa;
241{
300#ifndef BSD4_4
301 struct sockaddr_at netsat;
302 u_short net;
303#endif BSD4_4
304 int error;
305
306 if ( aa->aa_flags & AFA_ROUTE ) {
242 int error;
243
244 if ( aa->aa_flags & AFA_ROUTE ) {
307#ifdef BSD4_4
308 if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE,
309 ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) {
310 return( error );
311 }
312 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
245 if (( error = rtinit( &(aa->aa_ifa), RTM_DELETE,
246 ( ifp->if_flags & IFF_LOOPBACK ) ? RTF_HOST : 0 )) != 0 ) {
247 return( error );
248 }
249 aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
313#else BSD4_4
314 if ( ifp->if_flags & IFF_LOOPBACK ) {
315 rtinit( &aa->aa_addr, &aa->aa_addr, SIOCDELRT, RTF_HOST );
316 } else {
317 bzero( &netsat, sizeof( struct sockaddr_at ));
318 netsat.sat_family = AF_APPLETALK;
319 netsat.sat_addr.s_node = ATADDR_ANYNODE;
320
321 /*
322 * If the range is the full 0-fffe range, just use
323 * the default route.
324 */
325 if ( aa->aa_firstnet == htons( 0x0000 ) &&
326 aa->aa_lastnet == htons( 0xfffe )) {
327 netsat.sat_addr.s_net = 0;
328 rtinit((struct sockaddr *)&netsat, &aa->aa_addr,
329 (int)SIOCDELRT, 0 );
330 } else {
331 for ( net = ntohs( aa->aa_firstnet );
332 net <= ntohs( aa->aa_lastnet ); net++ ) {
333 netsat.sat_addr.s_net = htons( net );
334 rtinit((struct sockaddr *)&netsat, &aa->aa_addr,
335 (int)SIOCDELRT, 0 );
336 }
337 }
338 }
339#endif BSD4_4
340 aa->aa_flags &= ~AFA_ROUTE;
341 }
342 return( 0 );
343}
344
250 aa->aa_flags &= ~AFA_ROUTE;
251 }
252 return( 0 );
253}
254
345#if !defined( __FreeBSD__ )
346extern struct timeval time;
347#endif __FreeBSD__
348
349static int
350at_ifinit( ifp, aa, sat )
351 struct ifnet *ifp;
352 struct at_ifaddr *aa;
353 struct sockaddr_at *sat;
354{
355 struct netrange nr, onr;
255static int
256at_ifinit( ifp, aa, sat )
257 struct ifnet *ifp;
258 struct at_ifaddr *aa;
259 struct sockaddr_at *sat;
260{
261 struct netrange nr, onr;
356#ifdef BSD4_4
357 struct sockaddr_at oldaddr;
262 struct sockaddr_at oldaddr;
358#else BSD4_4
359 struct sockaddr oldaddr;
360#endif BSD4_4
361 struct sockaddr_at netaddr;
362 int s = splimp(), error = 0, i, j, netinc, nodeinc, nnets;
263 int s = splimp(), error = 0, i, j;
264 int flags = RTF_UP, netinc, nodeinc, nnets;
363 u_short net;
364
365 oldaddr = aa->aa_addr;
366 bzero( AA_SAT( aa ), sizeof( struct sockaddr_at ));
367 bcopy( sat->sat_zero, &nr, sizeof( struct netrange ));
265 u_short net;
266
267 oldaddr = aa->aa_addr;
268 bzero( AA_SAT( aa ), sizeof( struct sockaddr_at ));
269 bcopy( sat->sat_zero, &nr, sizeof( struct netrange ));
270 bcopy( sat->sat_zero, AA_SAT( aa )->sat_zero, sizeof( struct netrange ));
368 nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1;
369
370 onr.nr_firstnet = aa->aa_firstnet;
371 onr.nr_lastnet = aa->aa_lastnet;
372 aa->aa_firstnet = nr.nr_firstnet;
373 aa->aa_lastnet = nr.nr_lastnet;
374
271 nnets = ntohs( nr.nr_lastnet ) - ntohs( nr.nr_firstnet ) + 1;
272
273 onr.nr_firstnet = aa->aa_firstnet;
274 onr.nr_lastnet = aa->aa_lastnet;
275 aa->aa_firstnet = nr.nr_firstnet;
276 aa->aa_lastnet = nr.nr_lastnet;
277
278/* XXX ALC */
279 printf("at_ifinit: %s: %u.%u range %u-%u phase %d\n",
280 ifp->if_name,
281 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
282 ntohs(aa->aa_firstnet), ntohs(aa->aa_lastnet),
283 (aa->aa_flags & AFA_PHASE2) ? 2 : 1);
284
375 /*
376 * We could eliminate the need for a second phase 1 probe (post
377 * autoconf) if we check whether we're resetting the node. Note
378 * that phase 1 probes use only nodes, not net.node pairs. Under
379 * phase 2, both the net and node must be the same.
380 */
381 if ( ifp->if_flags & IFF_LOOPBACK ) {
285 /*
286 * We could eliminate the need for a second phase 1 probe (post
287 * autoconf) if we check whether we're resetting the node. Note
288 * that phase 1 probes use only nodes, not net.node pairs. Under
289 * phase 2, both the net and node must be the same.
290 */
291 if ( ifp->if_flags & IFF_LOOPBACK ) {
382#ifdef BSD4_4
383 AA_SAT( aa )->sat_len = sat->sat_len;
292 AA_SAT( aa )->sat_len = sat->sat_len;
384#endif BSD4_4
385 AA_SAT( aa )->sat_family = AF_APPLETALK;
386 AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net;
387 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
293 AA_SAT( aa )->sat_family = AF_APPLETALK;
294 AA_SAT( aa )->sat_addr.s_net = sat->sat_addr.s_net;
295 AA_SAT( aa )->sat_addr.s_node = sat->sat_addr.s_node;
296#if 0
297 } else if ( fp->if_flags & IFF_POINTOPOINT) {
298 /* unimplemented */
299#endif
388 } else {
389 aa->aa_flags |= AFA_PROBING;
300 } else {
301 aa->aa_flags |= AFA_PROBING;
390#ifdef BSD4_4
391 AA_SAT( aa )->sat_len = sizeof(struct sockaddr_at);
302 AA_SAT( aa )->sat_len = sizeof(struct sockaddr_at);
392#endif BSD4_4
393 AA_SAT( aa )->sat_family = AF_APPLETALK;
394 if ( aa->aa_flags & AFA_PHASE2 ) {
395 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) {
396 if ( nnets != 1 ) {
397 net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 );
398 } else {
399 net = ntohs( nr.nr_firstnet );
400 }

--- 25 unchanged lines hidden (view full) ---

426 j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) {
427 if ( AA_SAT( aa )->sat_addr.s_node > 253 ||
428 AA_SAT( aa )->sat_addr.s_node < 1 ) {
429 continue;
430 }
431 aa->aa_probcnt = 10;
432 timeout( (timeout_func_t)aarpprobe, (caddr_t)ifp, hz / 5 );
433 splx( s );
303 AA_SAT( aa )->sat_family = AF_APPLETALK;
304 if ( aa->aa_flags & AFA_PHASE2 ) {
305 if ( sat->sat_addr.s_net == ATADDR_ANYNET ) {
306 if ( nnets != 1 ) {
307 net = ntohs( nr.nr_firstnet ) + time.tv_sec % ( nnets - 1 );
308 } else {
309 net = ntohs( nr.nr_firstnet );
310 }

--- 25 unchanged lines hidden (view full) ---

336 j++, AA_SAT( aa )->sat_addr.s_node += nodeinc ) {
337 if ( AA_SAT( aa )->sat_addr.s_node > 253 ||
338 AA_SAT( aa )->sat_addr.s_node < 1 ) {
339 continue;
340 }
341 aa->aa_probcnt = 10;
342 timeout( (timeout_func_t)aarpprobe, (caddr_t)ifp, hz / 5 );
343 splx( s );
434 if (
435#if defined( __FreeBSD__ )
436 tsleep( aa, PPAUSE|PCATCH, "at_ifinit", 0 )
437#else
438 sleep( aa, PSLEP|PCATCH )
439#endif
440 ) {
441 printf( "at_ifinit why did this happen?!\n" );
344 if ( tsleep( aa, PPAUSE|PCATCH, "at_ifinit", 0 )) {
345 printf( "at_ifinit: why did this happen?!\n" );
442 aa->aa_addr = oldaddr;
443 aa->aa_firstnet = onr.nr_firstnet;
444 aa->aa_lastnet = onr.nr_lastnet;
445 return( EINTR );
446 }
447 s = splimp();
448 if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
449 break;

--- 12 unchanged lines hidden (view full) ---

462 aa->aa_lastnet = onr.nr_lastnet;
463 splx( s );
464 return( EADDRINUSE );
465 }
466 }
467
468 if ( ifp->if_ioctl &&
469 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, (caddr_t)aa ))) {
346 aa->aa_addr = oldaddr;
347 aa->aa_firstnet = onr.nr_firstnet;
348 aa->aa_lastnet = onr.nr_lastnet;
349 return( EINTR );
350 }
351 s = splimp();
352 if (( aa->aa_flags & AFA_PROBING ) == 0 ) {
353 break;

--- 12 unchanged lines hidden (view full) ---

366 aa->aa_lastnet = onr.nr_lastnet;
367 splx( s );
368 return( EADDRINUSE );
369 }
370 }
371
372 if ( ifp->if_ioctl &&
373 ( error = (*ifp->if_ioctl)( ifp, SIOCSIFADDR, (caddr_t)aa ))) {
470 splx( s );
471 aa->aa_addr = oldaddr;
472 aa->aa_firstnet = onr.nr_firstnet;
473 aa->aa_lastnet = onr.nr_lastnet;
374 aa->aa_addr = oldaddr;
375 aa->aa_firstnet = onr.nr_firstnet;
376 aa->aa_lastnet = onr.nr_lastnet;
377 splx( s );
474 return( error );
475 }
476
378 return( error );
379 }
380
477#ifdef BSD4_4
478 aa->aa_netmask.sat_len = 6/*sizeof(struct sockaddr_at)*/;
381 /* Initialize interface netmask, which is silly for us */
382
383 bzero(&aa->aa_netmask, sizeof(aa->aa_netmask));
384 aa->aa_netmask.sat_len = sizeof(struct sockaddr_at);
479 aa->aa_netmask.sat_family = AF_APPLETALK;
385 aa->aa_netmask.sat_family = AF_APPLETALK;
480 aa->aa_netmask.sat_addr.s_net = 0xffff;
481 aa->aa_netmask.sat_addr.s_node = 0;
482#if defined( __FreeBSD__ )
483 aa->aa_ifa.ifa_netmask =(struct sockaddr *) &(aa->aa_netmask); /* XXX */
484#endif __FreeBSD__
485#endif BSD4_4
386 aa->aa_ifa.ifa_netmask = (struct sockaddr *) &aa->aa_netmask;
486
387
388 /* "Add a route to the network" */
389
390 aa->aa_ifa.ifa_metric = ifp->if_metric;
391 if (ifp->if_flags & IFF_BROADCAST) {
392 bzero(&aa->aa_broadaddr, sizeof(aa->aa_broadaddr));
393 aa->aa_broadaddr.sat_len = sat->sat_len;
394 aa->aa_broadaddr.sat_family = AF_APPLETALK;
395 aa->aa_broadaddr.sat_addr.s_net = htons(0);
396 aa->aa_broadaddr.sat_addr.s_node = 0xff;
397 aa->aa_ifa.ifa_broadaddr = (struct sockaddr *) &aa->aa_broadaddr;
398 aa->aa_netmask.sat_addr.s_net = htons(0xffff); /* XXX */
399 aa->aa_netmask.sat_addr.s_node = htons(0); /* XXX */
400 } else if (ifp->if_flags & IFF_LOOPBACK) {
401 aa->aa_ifa.ifa_dstaddr = aa->aa_ifa.ifa_addr;
402 aa->aa_netmask.sat_addr.s_net = htons(0xffff); /* XXX */
403 aa->aa_netmask.sat_addr.s_node = htons(0xffff); /* XXX */
404 flags |= RTF_HOST;
405 } else if (ifp->if_flags & IFF_POINTOPOINT) {
406 aa->aa_ifa.ifa_dstaddr = aa->aa_ifa.ifa_addr;
407 aa->aa_netmask.sat_addr.s_net = htons(0xffff);
408 aa->aa_netmask.sat_addr.s_node = htons(0xffff);
409 flags |= RTF_HOST;
410 }
411 error = rtinit(&(aa->aa_ifa), (int)RTM_ADD, flags);
412
413#if 0
487 if ( ifp->if_flags & IFF_LOOPBACK ) {
414 if ( ifp->if_flags & IFF_LOOPBACK ) {
488#ifndef BSD4_4
489 rtinit( &aa->aa_addr, &aa->aa_addr, (int)SIOCADDRT,
490 RTF_HOST|RTF_UP );
491#else BSD4_4
492 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD,
493#if !defined( __FreeBSD__ )
494 RTF_HOST |
495#else
496 /* XXX not a host route? */
497#endif __FreeBSD__
498 RTF_UP );
499#endif BSD4_4
415 struct at_addr rtaddr, rtmask;
416
417 bzero(&rtaddr, sizeof(rtaddr));
418 bzero(&rtmask, sizeof(rtmask));
419 rtaddr.s_net = AA_SAT( aa )->sat_addr.s_net;
420 rtaddr.s_node = AA_SAT( aa )->sat_addr.s_node;
421 rtmask.s_net = 0xffff;
422 rtmask.s_node = 0xff;
423
424 error = aa_addsingleroute(&aa->aa_ifa, &rtaddr, &rtmask);
425
500 } else {
426 } else {
501#ifndef BSD4_4
502 /*
503 * rtrequest looks for point-to-point links first. The
504 * broadaddr is in the same spot as the destaddr. So, if
505 * ATADDR_ANYNET is 0, and we don't fill in the broadaddr, we
506 * get 0.0 routed out the ether interface. So, initialize the
507 * broadaddr, even tho we don't use it.
508 *
509 * We *could* use the broadaddr field to reduce some of the
510 * sockaddr_at overloading that we've done. E.g. Just send
511 * to INTERFACE-NET.255, and have the kernel reroute that
512 * to broadaddr, which would be 0.255 for phase 2 interfaces,
513 * and IFACE-NET.255 for phase 1 interfaces.
514 */
515 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_net =
516 sat->sat_addr.s_net;
517 ((struct sockaddr_at *)&aa->aa_broadaddr)->sat_addr.s_node =
518 ATADDR_BCAST;
519
427
520 bzero( &netaddr, sizeof( struct sockaddr_at ));
521 netaddr.sat_family = AF_APPLETALK;
522 netaddr.sat_addr.s_node = ATADDR_ANYNODE;
523 if (( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
524 netaddr.sat_addr.s_net = AA_SAT( aa )->sat_addr.s_net;
525 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
526 (int)SIOCADDRT, RTF_UP );
527 } else {
528 /*
529 * If the range is the full 0-fffe range, just use
530 * the default route.
531 */
532 if ( aa->aa_firstnet == htons( 0x0000 ) &&
533 aa->aa_lastnet == htons( 0xfffe )) {
534 netaddr.sat_addr.s_net = 0;
535 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
536 (int)SIOCADDRT, RTF_UP );
537 } else {
538 for ( net = ntohs( aa->aa_firstnet );
539 net <= ntohs( aa->aa_lastnet ); net++ ) {
540 netaddr.sat_addr.s_net = htons( net );
541 rtinit((struct sockaddr *)&netaddr, &aa->aa_addr,
542 (int)SIOCADDRT, RTF_UP );
543 }
544 }
545 }
546#else BSD4_4
547 error = rtinit( &(aa->aa_ifa), (int)RTM_ADD, RTF_UP );
548#endif BSD4_4
428 /* Install routes for our own network, and then also for
429 all networks above and below it in the network range */
430
431 error = aa_addrangeroute(&aa->aa_ifa,
432 ntohs(aa->aa_addr.sat_addr.s_net),
433 ntohs(aa->aa_addr.sat_addr.s_net) + 1);
434 if (!error
435 && ntohs(aa->aa_firstnet) < ntohs(aa->aa_addr.sat_addr.s_net))
436 error = aa_addrangeroute(&aa->aa_ifa,
437 ntohs(aa->aa_firstnet), ntohs(aa->aa_addr.sat_addr.s_net));
438 if (!error
439 && ntohs(aa->aa_addr.sat_addr.s_net) < ntohs(aa->aa_lastnet))
440 error = aa_addrangeroute(&aa->aa_ifa,
441 ntohs(aa->aa_addr.sat_addr.s_net) + 1,
442 ntohs(aa->aa_lastnet) + 1);
549 }
443 }
444#endif
445
446
550 if ( error ) {
551 aa->aa_addr = oldaddr;
552 aa->aa_firstnet = onr.nr_firstnet;
553 aa->aa_lastnet = onr.nr_lastnet;
554 splx( s );
555 return( error );
556 }
557
447 if ( error ) {
448 aa->aa_addr = oldaddr;
449 aa->aa_firstnet = onr.nr_firstnet;
450 aa->aa_lastnet = onr.nr_lastnet;
451 splx( s );
452 return( error );
453 }
454
558#ifdef BSD4_4
559 aa->aa_ifa.ifa_flags |= IFA_ROUTE;
455 aa->aa_ifa.ifa_flags |= IFA_ROUTE;
560#endif BSD4_4
561 aa->aa_flags |= AFA_ROUTE;
562 splx( s );
563 return( 0 );
564}
565
566int
567at_broadcast( sat )
568 struct sockaddr_at *sat;

--- 12 unchanged lines hidden (view full) ---

581 ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) {
582 return( 1 );
583 }
584 }
585 }
586 return( 0 );
587}
588
456 aa->aa_flags |= AFA_ROUTE;
457 splx( s );
458 return( 0 );
459}
460
461int
462at_broadcast( sat )
463 struct sockaddr_at *sat;

--- 12 unchanged lines hidden (view full) ---

476 ntohs( sat->sat_addr.s_net ) <= ntohs( aa->aa_lastnet ))) {
477 return( 1 );
478 }
479 }
480 }
481 return( 0 );
482}
483
484/*
485 * aa_addrangeroute()
486 *
487 * Add a route for a range of networks from bot to top - 1.
488 * Algorithm:
489 *
490 * Split the range into three subranges such that the middle
491 * subrange is from (base + 2^N) to (base + 2^N + 2^(N-1)) for
492 * some N. Then add a route for the middle range and recurse on
493 * the upper and lower sub-ranges. As a degenerate case, it may
494 * be that the middle subrange is empty.
495 */
496
497static int
498aa_addrangeroute(struct ifaddr *ifa, int bot, int top)
499{
500 int base, mask, mbot, mtop;
501 int a, b, abit, bbit, error;
502 struct at_addr rtaddr, rtmask;
503
504/* Special case the whole range */
505
506 if (bot == 0 && top == 0xffff)
507 {
508 bzero(&rtaddr, sizeof(rtaddr));
509 bzero(&rtmask, sizeof(rtmask));
510 return(aa_addsingleroute(ifa, &rtaddr, &rtmask));
511 }
512
513 if (top <= bot)
514 panic("aa_addrangeroute");
515
516/* Mask out the high order bits on which both bounds agree */
517
518 for (mask = 0xffff; (bot & mask) != (top & mask); mask <<= 1);
519 base = bot & mask;
520 a = bot & ~mask;
521 b = top & ~mask;
522
523/* Find suitable powers of two between a and b we can make a route with */
524
525 for (bbit = 0x8000; bbit > b; bbit >>= 1);
526 if (a == 0)
527 abit = 0;
528 else
529 {
530 for (abit = 0x0001; a > abit; abit <<= 1);
531 if ((abit << 1) > bbit)
532 bbit = abit;
533 else
534 bbit = abit << 1;
535 }
536
537/* Now we have a "square" middle chunk from abit to bbit, possibly empty */
538
539 mbot = base + abit;
540 mtop = base + bbit;
541 mask = ~(bbit - 1);
542
543/* Route to the middle chunk */
544
545 if (mbot < mtop)
546 {
547 bzero(&rtaddr, sizeof(rtaddr));
548 bzero(&rtmask, sizeof(rtmask));
549 rtaddr.s_net = htons((u_short) mbot);
550 rtmask.s_net = htons((u_short) mask);
551 if ((error = aa_addsingleroute(ifa, &rtaddr, &rtmask)))
552 return(error);
553 }
554
555/* Recurse on the upper and lower chunks we didn't get to */
556
557 if (bot < mbot)
558 if ((error = aa_addrangeroute(ifa, bot, mbot)))
559 {
560 if (mbot < mtop)
561 aa_delsingleroute(ifa, &rtaddr, &rtmask);
562 return(error);
563 }
564 if (mtop < top)
565 if ((error = aa_addrangeroute(ifa, mtop, top)))
566 {
567 if (mbot < mtop)
568 aa_delsingleroute(ifa, &rtaddr, &rtmask);
569 return(error);
570 }
571 return(0);
572}
573
574static int
575aa_addsingleroute(struct ifaddr *ifa,
576 struct at_addr *addr, struct at_addr *mask)
577{
578 int error;
579
580 printf("aa_addsingleroute: %x.%x mask %x.%x ...\n",
581 ntohs(addr->s_net), addr->s_node,
582 ntohs(mask->s_net), mask->s_node);
583
584 error = aa_dosingleroute(ifa, addr, mask, RTM_ADD, RTF_UP);
585 if (error)
586 printf("error %d\n", error);
587 return(error);
588}
589
590static int
591aa_delsingleroute(struct ifaddr *ifa,
592 struct at_addr *addr, struct at_addr *mask)
593{
594 int error;
595
596 error = aa_dosingleroute(ifa, addr, mask, RTM_DELETE, 0);
597 if (error)
598 printf("aa_delsingleroute: error %d\n", error);
599 return(error);
600}
601
602static int
603aa_dosingleroute(struct ifaddr *ifa,
604 struct at_addr *at_addr, struct at_addr *at_mask, int cmd, int flags)
605{
606 struct sockaddr_at addr, mask;
607
608 bzero(&addr, sizeof(addr));
609 bzero(&mask, sizeof(mask));
610 addr.sat_family = AF_APPLETALK;
611 addr.sat_len = sizeof(struct sockaddr_at);
612 addr.sat_addr.s_net = at_addr->s_net;
613 addr.sat_addr.s_node = at_addr->s_node;
614 mask.sat_addr.s_net = at_mask->s_net;
615 mask.sat_addr.s_node = at_mask->s_node;
616 if (at_mask->s_node)
617 flags |= RTF_HOST;
618 return(rtrequest(cmd, (struct sockaddr *) &addr, ifa->ifa_addr,
619 (struct sockaddr *) &mask, flags, NULL));
620}
621
622#if 0
623
589static void
590aa_clean(void)
591{
592 struct at_ifaddr *aa;
593 struct ifaddr *ifa;
594 struct ifnet *ifp;
595
596 while ( aa = at_ifaddr ) {

--- 10 unchanged lines hidden (view full) ---

607 if ( ifa->ifa_next ) {
608 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;
609 } else {
610 panic( "at_entry" );
611 }
612 }
613 }
614}
624static void
625aa_clean(void)
626{
627 struct at_ifaddr *aa;
628 struct ifaddr *ifa;
629 struct ifnet *ifp;
630
631 while ( aa = at_ifaddr ) {

--- 10 unchanged lines hidden (view full) ---

642 if ( ifa->ifa_next ) {
643 ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;
644 } else {
645 panic( "at_entry" );
646 }
647 }
648 }
649}
650
651#endif
652