2 * Copyright (c) 1990,1993 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
10 #include <sys/types.h>
11 #include <sys/param.h>
12 #include <sys/socket.h>
13 #if defined( sun ) && defined( __svr4__ )
14 #include </usr/ucbinclude/sys/file.h>
19 #include <sys/resource.h>
20 #include <sys/ioctl.h>
24 #include <net/route.h>
35 #include <netatalk/endian.h>
36 #include <netatalk/at.h>
37 #include <atalk/compat.h>
38 #include <atalk/zip.h>
39 #include <atalk/rtmp.h>
40 #include <atalk/ddp.h>
41 #include <atalk/atp.h>
42 #include <atalk/paths.h>
43 #include <atalk/util.h>
46 #include <sys/sockio.h>
50 #include "interface.h"
57 /* FIXME/SOCKLEN_T: socklen_t is a unix98 feature */
59 #define SOCKLEN_T unsigned int
63 #define WEXITSTATUS(x) ((x).w_retcode)
66 /* linux has a special ioctl for appletalk device destruction. as of
67 * 2.1.57, SIOCDIFADDR works w/ linux. okay, we need to deal with the
68 * fact that SIOCDIFADDR may be defined on linux despite the fact that
70 #if !defined(SIOCDIFADDR) && defined(SIOCATALKDIFADDR)
71 #define SIOCDIFADDR SIOCATALKDIFADDR
74 #define elements(a) (sizeof(a)/sizeof((a)[0]))
78 extern int rtmp_packet();
79 extern int nbp_packet();
80 extern int aep_packet();
81 extern int zip_packet();
85 struct atserv atserv[] = {
86 { "rtmp", 1, rtmp_packet }, /* 0 */
87 { "nbp", 2, nbp_packet }, /* 1 */
88 { "echo", 4, aep_packet }, /* 2 */
89 { "zip", 6, zip_packet }, /* 3 */
91 int atservNATSERV = elements( atserv );
93 struct interface *interfaces = NULL, *ciface = NULL;
95 int debug = 0, quiet = 0, chatty = 0;
96 char *configfile = NULL;
97 int ziptimeout = 0, transition = 0;
98 int stabletimer, stable = 0, newrtmpdata = 0, noparent = 0;
99 static int ninterfaces;
100 int defphase = IFACE_PHASE2;
103 char Packet[ PKTSZ ];
104 char *version = VERSION;
105 static char *pidfile = _PATH_ATALKDLOCK;
108 /* this is the messiest of the bunch as atalkd can exit pretty much
109 * everywhere. we delete interfaces here instead of in as_down. */
110 static void atalkd_exit(const int i)
113 struct interface *iface;
115 for (iface = interfaces; iface; iface = iface->i_next) {
116 if (ifconfig( iface->i_name, SIOCDIFADDR, &iface->i_addr)) {
117 #ifdef SIOCATALKDIFADDR
118 #if (SIOCDIFADDR != SIOCATALKDIFADDR)
119 if (!ifconfig(iface->i_name, SIOCATALKDIFADDR, &iface->i_addr))
123 syslog( LOG_ERR, "difaddr(%u.%u): %m",
124 ntohs(iface->i_addr.sat_addr.s_net),
125 iface->i_addr.sat_addr.s_node);
130 server_unlock(pidfile);
135 #if !defined( ibm032 ) && !defined( _IBMR2 )
140 struct sockaddr_at sat;
143 struct rtmp_tuple rt;
144 struct atport *ap, *zap, *rap;
145 struct interface *iface, *iface2;
146 struct gate *gate, *fgate = NULL;
147 struct rtmptab *rtmp, *frtmp;
149 char *data, *end, packet[ ATP_BUFSIZ ];
153 memset(&sat, 0, sizeof( struct sockaddr_at ));
154 for ( iface = interfaces; iface; iface = iface->i_next ) {
155 if ( iface->i_flags & IFACE_LOOPBACK ) {
158 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
159 if ( ap->ap_packet == zip_packet ) {
162 if ( ap->ap_packet == rtmp_packet ) {
167 if (( iface->i_flags & ( IFACE_ADDR|IFACE_CONFIG|IFACE_NOROUTER )) ==
169 if ( iface->i_time < 3 ) {
170 if ( iface->i_flags & IFACE_PHASE1 ) {
171 if (rtmp_request( iface ) < 0) {
172 syslog(LOG_ERR, "rtmp_request: %m");
177 if (zip_getnetinfo( iface ) < 0) {
178 syslog(LOG_ERR, "zip_getnetinfo: %m");
185 iface->i_flags |= IFACE_NOROUTER;
186 if ((iface->i_flags & IFACE_ISROUTER)) {
187 if (( iface->i_flags & IFACE_SEED ) == 0 ) {
189 * No seed info, and we've got multiple interfaces.
193 "as_timer multiple interfaces, no seed" );
194 syslog( LOG_INFO, "as_timer can't configure %s",
196 syslog( LOG_INFO, "as_timer waiting for router" );
201 * Complete configuration for iface, and boot next
204 iface->i_flags |= IFACE_CONFIG;
205 for ( zt = iface->i_czt; zt; zt = zt->zt_next ) {
206 if (addzone( iface->i_rt, zt->zt_len,
208 syslog(LOG_ERR, "addzone: %m");
212 if ( iface->i_rt->rt_zt ) {
213 iface->i_rt->rt_flags &= ~RTMPTAB_ZIPQUERY;
214 iface->i_rt->rt_flags |= RTMPTAB_HASZONES;
216 if ( iface->i_flags & IFACE_PHASE1 ) {
218 "as_timer configured %s phase 1 from seed",
220 setaddr( iface, IFACE_PHASE1,
221 iface->i_caddr.sat_addr.s_net,
222 iface->i_addr.sat_addr.s_node,
223 iface->i_caddr.sat_addr.s_net,
224 iface->i_caddr.sat_addr.s_net );
227 "as_timer configured %s phase 2 from seed",
231 if ( looproute( iface, RTMP_ADD )) { /* -1 or 1 */
233 "as_timer: can't route %u.%u to loop: %m",
234 ntohs( iface->i_addr.sat_addr.s_net ),
235 iface->i_addr.sat_addr.s_node );
238 if ( iface == ciface ) {
239 ciface = ciface->i_next;
245 * Configure for no router operation. Wait for a route
246 * to become available in rtmp_packet().
248 syslog( LOG_INFO, "config for no router" );
250 if ( iface->i_flags & IFACE_PHASE2 ) {
251 iface->i_rt->rt_firstnet = 0;
252 iface->i_rt->rt_lastnet = htons( STARTUP_LASTNET );
253 setaddr( iface, IFACE_PHASE2,
254 iface->i_addr.sat_addr.s_net,
255 iface->i_addr.sat_addr.s_node,
256 0, htons( STARTUP_LASTNET ));
258 if ( looproute( iface, RTMP_ADD ) ) { /* -1 or 1 */
260 "as_timer: can't route %u.%u to loopback: %m",
261 ntohs( iface->i_addr.sat_addr.s_net ),
262 iface->i_addr.sat_addr.s_node );
266 if ( iface == ciface ) {
267 ciface = ciface->i_next;
274 for ( gate = iface->i_gate; gate; gate = gate->g_next ) {
276 free( (caddr_t)fgate );
281 data = packet + 1 + sizeof( struct ziphdr );
282 end = packet + sizeof( packet );
285 sat.sat_port = zap->ap_port;
288 * Perform timeouts on routers. If we've only got one
289 * interface, we'll use these timeouts to decide that
290 * our zone has gone away.
292 if ( ++gate->g_state >= RTMPTAB_BAD ) {
293 syslog( LOG_INFO, "as_timer gateway %u.%u down",
294 ntohs( gate->g_sat.sat_addr.s_net ),
295 gate->g_sat.sat_addr.s_node );
298 frtmp = rtmp->rt_next;
299 if ( rtmp->rt_hops == RTMPHOPS_POISON ||
300 rtmp->rt_iprev == 0 ) {
303 rtmp->rt_hops = RTMPHOPS_POISON;
304 if ((cc = rtmp_replace( rtmp )) < 0) {
305 syslog(LOG_ERR, "rtmp_replace: %m");
309 gate->g_state = rtmp->rt_state = RTMPTAB_GOOD;
314 if ( gate->g_rt == 0 ) {
315 if ( gate->g_prev == 0 ) {
316 gate->g_iface->i_gate = gate->g_next;
318 gate->g_prev->g_next = gate->g_next;
320 if ( gate->g_next != 0 ) {
321 gate->g_next->g_prev = gate->g_prev;
323 fgate = gate; /* can't free here, just mark it */
326 * If this is the last router on the only interface,
327 * reconfigure our netrange. By marking the interface
328 * as having no router, we will notice when a router
331 * XXX: actually, we always reconfigure an interface
332 * if we're not a seed router.
335 if ( gate->g_iface->i_gate == 0 &&
336 ((iface->i_flags & IFACE_SEED) == 0)) {
337 gate->g_iface->i_flags |= IFACE_NOROUTER;
338 gate->g_iface->i_flags &= ~IFACE_CONFIG;
340 /* get rid of any zones associated with this iface */
341 if (gate->g_iface->i_rt->rt_zt) {
342 rtmp_delzonemap(gate->g_iface->i_rt);
343 gate->g_iface->i_rt->rt_flags &= ~RTMPTAB_HASZONES;
346 syslog( LOG_INFO, "as_timer last gateway down" );
348 /* Set netrange to 0-fffe. */
349 if ( gate->g_iface->i_flags & IFACE_PHASE2 ) {
350 gate->g_iface->i_rt->rt_firstnet = 0;
351 gate->g_iface->i_rt->rt_lastnet =
352 htons( STARTUP_LASTNET );
353 setaddr( iface, IFACE_PHASE2,
354 iface->i_addr.sat_addr.s_net,
355 iface->i_addr.sat_addr.s_node,
356 0, htons( STARTUP_LASTNET ));
363 * If we don't have a zone for our interface yet, ask for
364 * it from any router (all routers) on the interface.
366 if (( iface->i_rt->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
367 iface->i_rt->rt_flags |= RTMPTAB_ZIPQUERY;
368 memcpy( data, &iface->i_rt->rt_firstnet, sizeof( u_short ));
369 data += sizeof( u_short );
376 * Delete old routing tuples.
378 if ( rtmp->rt_state != RTMPTAB_PERM ) {
383 * We've not been updated for this route in a while. If
384 * it's not in use, go ahead and remove it. If it is in
385 * use, mark the route as down (POISON), and look for a
386 * better route. If one is found, delete this route and use
387 * the new one. If it's not found, mark the route as GOOD
388 * (so we'll propogate our poison) and delete it the next
389 * time it becomes BAD.
391 if ( rtmp->rt_state >= RTMPTAB_BAD ) {
392 frtmp = rtmp->rt_next;
393 if ( rtmp->rt_iprev == 0 ) { /* not in use */
395 } else { /* in use */
396 if ( rtmp->rt_hops == RTMPHOPS_POISON ) {
399 rtmp->rt_hops = RTMPHOPS_POISON;
400 if ((cc = rtmp_replace( rtmp )) < 0) {
401 syslog(LOG_ERR, "rtmp_replace: %m");
405 rtmp->rt_state = RTMPTAB_GOOD;
415 if ( rtmp->rt_iprev &&
416 ( rtmp->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
417 if ( data + sizeof( u_short ) > end || n == 255 ) {
418 /* send what we've got */
419 zh.zh_op = ZIPOP_QUERY;
423 *data++ = DDPTYPE_ZIP;
424 memcpy( data, &zh, sizeof( struct ziphdr ));
426 if ( sendto( zap->ap_fd, packet, cc, 0,
427 (struct sockaddr *)&sat,
428 sizeof( struct sockaddr_at )) < 0 ) {
429 syslog( LOG_ERR, "as_timer sendto: %m" );
434 data = packet + 1 + sizeof( struct ziphdr );
435 end = packet + sizeof( packet );
439 * rt_nzq is number of ZIP Queries we've issued for a
440 * given netrange. If we've got ziptimeout on, we
441 * will only ask 3 times for any given netrange.
442 * Interestingly enough, since rt_nzq is a u_char,
443 * it will overflow after a while. This means we will
444 * periodically ask for nets that we've decided not to
445 * ask about, and warn that we can't get it's zone.
447 if ( rtmp->rt_nzq++ == 3 ) {
448 syslog( LOG_INFO, "as_timer can't get zone for %u",
449 ntohs( rtmp->rt_firstnet ));
451 if ( rtmp->rt_nzq > 3 ) {
453 rtmp = rtmp->rt_next;
459 rtmp->rt_flags |= RTMPTAB_ZIPQUERY;
460 memcpy( data, &rtmp->rt_firstnet, sizeof( u_short ));
461 data += sizeof( u_short );
464 rtmp = rtmp->rt_next;
467 /* send what we've got */
469 zh.zh_op = ZIPOP_QUERY;
473 *data++ = DDPTYPE_ZIP;
474 memcpy( data, &zh, sizeof( struct ziphdr ));
476 if ( sendto( zap->ap_fd, packet, cc, 0, (struct sockaddr *)&sat,
477 sizeof( struct sockaddr_at )) < 0 ) {
478 syslog( LOG_ERR, "as_timer sendto: %m" );
483 free( (caddr_t)fgate );
488 * Send RTMP broadcasts if we have multiple interfaces or our
489 * interface is configured as a router.
491 if ((iface->i_flags & IFACE_ISROUTER)) {
493 sat.sat_len = sizeof( struct sockaddr_at );
495 sat.sat_family = AF_APPLETALK;
496 sat.sat_addr.s_net = ATADDR_ANYNET;
497 sat.sat_addr.s_node = ATADDR_BCAST;
498 sat.sat_port = rap->ap_port;
501 end = data + sizeof( packet );
502 *data++ = DDPTYPE_RTMPRD;
503 rh.rh_net = iface->i_addr.sat_addr.s_net;
505 rh.rh_node = iface->i_addr.sat_addr.s_node;
506 memcpy( data, &rh, sizeof( struct rtmp_head ));
507 data += sizeof( struct rtmp_head );
511 if ( iface->i_flags & IFACE_PHASE1 ) {
514 memcpy( data, &rt, SZ_RTMPTUPLE );
515 data += SZ_RTMPTUPLE;
517 rt.rt_net = iface->i_rt->rt_firstnet;
519 memcpy( data, &rt, SZ_RTMPTUPLE );
520 data += SZ_RTMPTUPLE;
522 rt.rt_net = iface->i_rt->rt_lastnet;
524 memcpy( data, &rt, SZ_RTMPTUPLE );
525 data += SZ_RTMPTUPLE;
528 for ( iface2 = interfaces; iface2; iface2 = iface2->i_next ) {
530 /* XXX: there used to be a bit checking against iface ==
531 iface2. also, we don't want to send an rtmp broadcast
532 to an interface that doesn't want it. */
533 if ((( iface2->i_flags & IFACE_CONFIG ) == 0) ||
534 ((iface2->i_flags & IFACE_ISROUTER) == 0)) {
538 * Fill in tuples. Always send the same thing, regardless
539 * of the phase of the destination. Routers who don't
540 * understand extended rtmp packets will toss extended
541 * tuples because their distance will have the high bit set.
543 for ( rtmp = iface2->i_rt; rtmp; rtmp = rtmp->rt_inext ) {
544 /* don't broadcast routes we have no zone for */
545 if ( rtmp->rt_zt == 0 ||
546 ( rtmp->rt_flags & RTMPTAB_ZIPQUERY ) ||
547 ( rtmp->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
551 if ((( rtmp->rt_flags & RTMPTAB_EXTENDED ) &&
552 data + 2 * SZ_RTMPTUPLE > end ) ||
553 data + SZ_RTMPTUPLE > end ) {
554 if ( sendto( rap->ap_fd, packet, data - packet, 0,
555 (struct sockaddr *)&sat,
556 sizeof( struct sockaddr_at )) < 0 ) {
557 syslog( LOG_ERR, "as_timer sendto %u.%u (%u): %m",
558 ntohs( sat.sat_addr.s_net ),
560 ntohs( iface->i_rt->rt_firstnet ));
563 if ( iface->i_flags & IFACE_PHASE2 ) {
564 data = packet + 1 + sizeof( struct rtmp_head ) +
567 data = packet + 1 + sizeof( struct rtmp_head ) +
573 rt.rt_net = rtmp->rt_firstnet;
574 rt.rt_dist = rtmp->rt_hops;
575 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
578 memcpy( data, &rt, SZ_RTMPTUPLE );
579 data += SZ_RTMPTUPLE;
581 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
582 rt.rt_net = rtmp->rt_lastnet;
584 memcpy( data, &rt, SZ_RTMPTUPLE );
585 data += SZ_RTMPTUPLE;
593 if ( sendto( rap->ap_fd, packet, data - packet, 0,
594 (struct sockaddr *)&sat,
595 sizeof( struct sockaddr_at )) < 0 ) {
596 syslog( LOG_ERR, "as_timer sendto %u.%u (%u): %m",
597 ntohs( sat.sat_addr.s_net ),
599 ntohs( iface->i_rt->rt_firstnet ));
606 * Check if we're stable. Each time we configure an interface, we
607 * sent stabletimer to UNSTABLE. If stabletimer ever gets to
608 * STABLEANYWAY, we give up and decide to "be" stable anyway.
609 * Normally, we wait for stabletimer get <= STABLE with no new rtmp
610 * data and all zip data complete.
613 if ( stabletimer <= STABLE && !newrtmpdata && !sentzipq ) {
614 /* write out config file */
616 writeconf( configfile );
618 if ( stabletimer-- <= STABLEANYWAY ) {
624 if ( stable && !noparent ) {
626 syslog( LOG_INFO, "ready %d/%d/%d", stabletimer, newrtmpdata,
630 * Seems like we could get here more than once...
632 if ( kill( getpid(), SIGSTOP ) < 0 ) {
633 syslog( LOG_ERR, "as_timer: kill-self failed!" );
647 * Consistency check...
651 struct rtmptab *rtmp;
652 struct list *lr, *lz;
655 for ( zt = ziptab; zt; zt = zt->zt_next ) {
656 for ( lr = zt->zt_rt; lr; lr = lr->l_next ) {
657 rtmp = (struct rtmptab *)lr->l_data;
658 if ( rtmp->rt_iprev == 0 && rtmp->rt_gate != 0 ) {
659 syslog( LOG_ERR, "%.*s has %u-%u (unused)\n",
660 zt->zt_len, zt->zt_name, ntohs( rtmp->rt_firstnet ),
661 ntohs( rtmp->rt_lastnet ));
664 for ( lz = rtmp->rt_zt; lz; lz = lz->l_next ) {
665 if ( zt == (struct ziptab *)lz->l_data ) {
670 syslog( LOG_ERR, "no map from %u-%u to %.*s\n",
671 ntohs( rtmp->rt_firstnet ),
672 ntohs( rtmp->rt_lastnet ),
673 zt->zt_len, zt->zt_name );
681 #if !defined( ibm032 ) && !defined( _IBMR2 )
686 struct interface *iface;
693 if (( rtmpdebug = fopen( _PATH_ATALKDEBUG, "w" )) == NULL ) {
694 syslog( LOG_ERR, "rtmp: %m" );
697 for ( iface = interfaces; iface; iface = iface->i_next ) {
698 fprintf( rtmpdebug, "interface %s %u.%u ", iface->i_name,
699 ntohs( iface->i_addr.sat_addr.s_net ),
700 iface->i_addr.sat_addr.s_node );
701 if ( iface->i_flags & IFACE_PHASE1 ) {
702 putc( '1', rtmpdebug );
704 if ( iface->i_flags & IFACE_PHASE2 ) {
705 putc( '2', rtmpdebug );
707 if ( iface->i_flags & IFACE_RSEED ) {
708 putc( 'R', rtmpdebug );
710 if ( iface->i_flags & IFACE_SEED ) {
711 putc( 'S', rtmpdebug );
713 if ( iface->i_flags & IFACE_DONTROUTE ) {
714 putc( 'D', rtmpdebug );
716 if ( iface->i_flags & IFACE_ADDR ) {
717 putc( 'A', rtmpdebug );
719 if ( iface->i_flags & IFACE_CONFIG ) {
720 putc( 'C', rtmpdebug );
722 if ( iface->i_flags & IFACE_NOROUTER ) {
723 putc( 'N', rtmpdebug );
725 if ( iface->i_flags & IFACE_LOOP ) {
726 putc( 'L', rtmpdebug );
728 putc( '\n', rtmpdebug );
731 fprintf( rtmpdebug, "\t%u-%u ",
732 ntohs( iface->i_rt->rt_firstnet ),
733 ntohs( iface->i_rt->rt_lastnet ));
734 if ( iface->i_rt->rt_flags & RTMPTAB_ZIPQUERY ) {
735 putc( 'q', rtmpdebug );
737 if ( iface->i_rt->rt_flags & RTMPTAB_HASZONES ) {
738 putc( 'z', rtmpdebug );
740 if ( iface->i_rt->rt_flags & RTMPTAB_EXTENDED ) {
741 putc( 'x', rtmpdebug );
743 putc( 'i', rtmpdebug );
744 for ( l = iface->i_rt->rt_zt; l; l = l->l_next ) {
745 zt = (struct ziptab *)l->l_data;
746 fprintf( rtmpdebug, " '%.*s'", zt->zt_len, zt->zt_name );
748 fprintf( rtmpdebug, "\n" );
751 for ( gate = iface->i_gate; gate; gate = gate->g_next ) {
752 fprintf( rtmpdebug, "gate %u.%u %X\n",
753 ntohs( gate->g_sat.sat_addr.s_net ),
754 gate->g_sat.sat_addr.s_node, gate->g_state );
755 for ( rt = gate->g_rt; rt; rt = rt->rt_next ) {
756 fprintf( rtmpdebug, "\t%u-%u ", ntohs( rt->rt_firstnet ),
757 ntohs( rt->rt_lastnet ));
758 if ( rt->rt_flags & RTMPTAB_ZIPQUERY ) {
759 putc( 'q', rtmpdebug );
761 if ( rt->rt_flags & RTMPTAB_HASZONES ) {
762 putc( 'z', rtmpdebug );
764 if ( rt->rt_flags & RTMPTAB_EXTENDED ) {
765 putc( 'x', rtmpdebug );
767 if ( rt->rt_iprev ) {
768 putc( 'i', rtmpdebug );
770 for ( l = rt->rt_zt; l; l = l->l_next ) {
771 zt = (struct ziptab *)l->l_data;
772 fprintf( rtmpdebug, " '%.*s'", zt->zt_len, zt->zt_name );
774 fprintf( rtmpdebug, "\n" );
783 * Called when SIGTERM is recieved. Remove all routes and then exit.
785 #if !defined( ibm032 ) && !defined( _IBMR2 )
790 struct interface *iface;
794 for ( iface = interfaces; iface; iface = iface->i_next ) {
795 for ( gate = iface->i_gate; gate; gate = gate->g_next ) {
796 for ( rt = gate->g_rt; rt; rt = rt->rt_next ) {
797 if ( rt->rt_iprev ) {
798 if ( gateroute( RTMP_DEL, rt ) < 0 ) {
799 syslog( LOG_ERR, "as_down remove %u-%u failed: %m",
800 ntohs( rt->rt_firstnet ),
801 ntohs( rt->rt_lastnet ));
806 if ( iface->i_flags & IFACE_LOOP ) {
807 if (looproute( iface, RTMP_DEL )) {
808 syslog( LOG_ERR, "as_down remove %s %u.%u failed: %m",
809 iface->i_name, ntohs( iface->i_addr.sat_addr.s_net ),
810 iface->i_addr.sat_addr.s_node );
815 syslog( LOG_INFO, "done" );
826 struct sockaddr_at sat;
829 struct interface *iface;
838 while (( c = getopt( ac, av, "12qsdtf:P:" )) != EOF ) {
841 defphase = IFACE_PHASE1;
845 defphase = IFACE_PHASE2;
856 case 'q' : /* don't seed */
860 case 's' : /* seed */
864 case 't' : /* transition */
868 case 'P' : /* pid file */
873 fprintf( stderr, "Unknown option -- '%c'\n", c );
877 if ( optind != ac ) {
878 fprintf( stderr, "Too many arguments.\n" );
882 if (( prog = strrchr( av[ 0 ], '/' )) == NULL ) {
889 * Configure loop back address first, so appearances of "lo0" in
890 * the config file fail. Also insures that lo0 gets configured,
891 * even if there's some hangup during configuration of some
894 if (( interfaces = newiface( LOOPIFACE )) == NULL ) {
895 perror( "newiface" );
898 interfaces->i_flags |= IFACE_PHASE2 | IFACE_LOOPBACK;
901 * Check our initial configuration before we fork. This way we can
902 * complain about syntax errors on stdout.
904 * Basically, if we're going to read our config file, we should read
905 * it and initialize our data structures. If we're not going to read
906 * our config file, use GIFCONF to initialize our data structures.
908 if ( readconf( configfile ) < 0 && getifconf() < 0 ) {
909 fprintf( stderr, "%s: can't get interfaces, exiting.\n", prog );
913 /* we need to count up our interfaces so that we can simplify things
914 * later. we also need to figure out if we have more than one interface
915 * that is routing. */
916 for (i = 0, ninterfaces = 0, iface = interfaces; iface;
917 iface=iface->i_next) {
918 if (iface->i_flags & IFACE_DONTROUTE)
922 i = ninterfaces - i; /* number of routable interfaces */
925 * At this point, we have (at least partially) initialized data
926 * structures. Fill in what we can and verify that nothing is obviously
929 for (iface = interfaces; iface; iface = iface->i_next) {
930 /* Apply the default phase */
931 if (( iface->i_flags & IFACE_PHASE1 ) == 0 &&
932 ( iface->i_flags & IFACE_PHASE2 ) == 0 ) {
933 iface->i_flags |= defphase;
936 /* set up router flag information. if we have multiple interfaces
937 * and DONTROUTE isn't set, set up ROUTER. i is the number of
938 * interfaces that don't have the DONTROUTE flag set. */
939 if ((i > IFBASE) && ((iface->i_flags & IFACE_DONTROUTE) == 0)) {
940 iface->i_flags |= IFACE_ISROUTER;
943 /* Set default addresses */
944 if ( iface->i_rt == NULL ) {
945 if (( iface->i_rt = newrt(iface)) == NULL ) {
950 if ( iface->i_flags & IFACE_PHASE1 ) {
951 iface->i_rt->rt_firstnet = iface->i_rt->rt_lastnet =
952 iface->i_caddr.sat_addr.s_net;
954 if ( iface->i_caddr.sat_addr.s_net != ATADDR_ANYNET ||
955 ( iface->i_flags & IFACE_LOOPBACK )) {
956 iface->i_rt->rt_firstnet = iface->i_rt->rt_lastnet =
957 iface->i_caddr.sat_addr.s_net;
959 iface->i_rt->rt_firstnet = htons( STARTUP_FIRSTNET );
960 iface->i_rt->rt_lastnet = htons( STARTUP_LASTNET );
965 if (( iface->i_flags & IFACE_PHASE1 ) == 0 ) {
966 iface->i_rt->rt_flags |= RTMPTAB_EXTENDED;
969 if ( iface->i_caddr.sat_addr.s_net == ATADDR_ANYNET ) {
970 iface->i_caddr.sat_addr.s_net = iface->i_rt->rt_firstnet;
974 dumpconfig( iface ); /* probably needs args */
979 * A little consistency check...
981 if ( ninterfaces < IFBASE ) {
982 fprintf( stderr, "%s: zero interfaces, exiting.\n", prog );
986 /* do this here so that we can use ifconfig */
989 fprintf(stderr, "can't establish STREAMS plumbing, exiting.\n" );
994 /* delete pre-existing interface addresses. */
996 for (iface = interfaces; iface; iface = iface->i_next) {
997 if (ifconfig(iface->i_name, SIOCDIFADDR, &iface->i_addr)) {
998 #ifdef SIOCATALKDIFADDR
999 #if (SIOCDIFADDR != SIOCATALKDIFADDR)
1000 ifconfig(iface->i_name, SIOCATALKDIFADDR, &iface->i_addr);
1008 * Disassociate. The child will send itself a signal when it is
1009 * stable. This indicates that other processes may begin using
1012 switch (i = server_lock("atalkd", pidfile, debug)) {
1017 default: /* parent */
1019 * Wait for the child to send itself a SIGSTOP, after which
1020 * we send it a SIGCONT and exit ourself.
1022 if ( wait3( &status, WUNTRACED, (struct rusage *)0 ) != i) {
1023 perror( "wait3" ); /* Child died? */
1026 if ( !WIFSTOPPED( status )) {
1027 fprintf( stderr, "AppleTalk not up! Check your syslog for the reason." );
1028 if ( WIFEXITED( status )) {
1029 fprintf( stderr, " Child exited with %d.\n",
1030 WEXITSTATUS( status ));
1032 fprintf( stderr, " Child died.\n" );
1036 if ( kill(i, SIGCONT ) < 0 ) {
1044 openlog( prog, LOG_PID );
1046 openlog( prog, LOG_PID, LOG_DAEMON );
1049 syslog( LOG_INFO, "restart (%s)", version );
1052 * Socket for use in routing ioctl()s. Can't add routes to our
1053 * interfaces until we have our routing socket.
1056 if (( rtfd = socket( PF_ROUTE, SOCK_RAW, AF_APPLETALK )) < 0 ) {
1057 syslog( LOG_ERR, "route socket: %m" );
1060 if ( shutdown( rtfd, 0 ) < 0 ) {
1061 syslog( LOG_ERR, "route shutdown: %m" );
1065 if (( rtfd = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
1066 syslog( LOG_ERR, "route socket: %m" );
1071 memset(&sv, 0, sizeof(sv));
1072 sv.sa_handler = as_down;
1073 sigemptyset( &sv.sa_mask );
1074 sigaddset( &sv.sa_mask, SIGUSR1 );
1075 sigaddset( &sv.sa_mask, SIGALRM );
1076 sigaddset( &sv.sa_mask, SIGTERM );
1077 sv.sa_flags = SA_RESTART;
1078 if ( sigaction( SIGTERM, &sv, NULL) < 0 ) {
1079 syslog( LOG_ERR, "sigterm: %m" );
1083 sv.sa_handler = as_debug;
1084 sigemptyset( &sv.sa_mask );
1085 sigaddset( &sv.sa_mask, SIGUSR1 );
1086 sigaddset( &sv.sa_mask, SIGALRM );
1087 sigaddset( &sv.sa_mask, SIGTERM );
1088 sv.sa_flags = SA_RESTART;
1089 if ( sigaction( SIGUSR1, &sv, NULL) < 0 ) {
1090 syslog( LOG_ERR, "sigusr1: %m" );
1094 sv.sa_handler = as_timer;
1095 sigemptyset( &sv.sa_mask );
1096 sigaddset( &sv.sa_mask, SIGUSR1 );
1097 sigaddset( &sv.sa_mask, SIGALRM );
1098 sigaddset( &sv.sa_mask, SIGTERM );
1099 sv.sa_flags = SA_RESTART;
1100 if ( sigaction( SIGALRM, &sv, NULL) < 0 ) {
1101 syslog( LOG_ERR, "sigalrm: %m" );
1105 it.it_interval.tv_sec = 10L;
1106 it.it_interval.tv_usec = 0L;
1107 it.it_value.tv_sec = 10L;
1108 it.it_value.tv_usec = 0L;
1109 if ( setitimer( ITIMER_REAL, &it, NULL) < 0 ) {
1110 syslog( LOG_ERR, "setitimer: %m" );
1114 ciface = interfaces;
1118 if ( select( nfds, &readfds, NULL, NULL, NULL) < 0 ) {
1119 if ( errno == EINTR ) {
1123 syslog( LOG_ERR, "select: %m" );
1128 for ( iface = interfaces; iface; iface = iface->i_next ) {
1129 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1130 if ( FD_ISSET( ap->ap_fd, &readfds )) {
1131 if ( ap->ap_packet ) {
1132 fromlen = sizeof( struct sockaddr_at );
1133 if (( c = recvfrom( ap->ap_fd, Packet, sizeof( Packet ),
1134 0, (struct sockaddr *)&sat, &fromlen )) < 0 ) {
1135 syslog( LOG_ERR, "recvfrom: %m" );
1140 printf( "packet from %u.%u on %s (%x) %d (%d)\n",
1141 ntohs( sat.sat_addr.s_net ),
1142 sat.sat_addr.s_node, iface->i_name,
1143 iface->i_flags, ap->ap_port, ap->ap_fd );
1144 bprint( Packet, c );
1148 if ( sighold( SIGALRM ) || sighold( SIGUSR1 )) {
1149 syslog( LOG_ERR, "sighold: %m" );
1153 mask = sigsetmask( sigmask( SIGALRM ) |
1154 sigmask( SIGUSR1 ));
1156 if (( *ap->ap_packet )( ap, &sat, Packet, c ) < 0) {
1157 syslog(LOG_ERR, "ap->ap_packet: %m");
1165 if ( sigrelse( SIGUSR1 ) || sigrelse( SIGALRM )) {
1166 syslog( LOG_ERR, "sigrelse: %m" );
1180 * This code is called (from main(), as_timer(), zip_packet(),
1181 * and rtmp_packet()) to set the initial "bootstrapping" address
1185 struct interface *iface;
1192 if ( iface->i_flags & IFACE_ADDR ) {
1193 syslog( LOG_ERR, "bootaddr OOPS!" );
1197 if ( iface->i_flags & IFACE_PHASE1 ) {
1198 setaddr( iface, IFACE_PHASE1, 0,
1199 iface->i_caddr.sat_addr.s_node, 0, 0 );
1201 if ( iface->i_flags & IFACE_LOOPBACK ) {
1202 iface->i_flags |= IFACE_CONFIG | IFACE_ADDR;
1203 if ( ciface == iface ) {
1204 ciface = ciface->i_next;
1208 } else if (rtmp_request( iface ) < 0) {
1209 syslog(LOG_ERR, "bootaddr (rtmp_request): %m");
1214 setaddr( iface, IFACE_PHASE2, iface->i_caddr.sat_addr.s_net,
1215 iface->i_caddr.sat_addr.s_node,
1216 iface->i_rt->rt_firstnet, iface->i_rt->rt_lastnet );
1218 if ( iface->i_flags & IFACE_LOOPBACK ) {
1219 iface->i_flags |= IFACE_CONFIG | IFACE_ADDR;
1220 if ( ciface == iface ) {
1221 ciface = ciface->i_next;
1225 } else if (zip_getnetinfo( iface ) < 0) {
1226 syslog(LOG_ERR, "bootaddr (zip_getnetinfo): %m");
1231 iface->i_flags |= IFACE_ADDR;
1232 stabletimer = UNSTABLE;
1238 * to manage the i_ports field and the fds for select().
1240 setaddr( iface, phase, net, node, first, last )
1241 struct interface *iface;
1245 u_int16_t first, last;
1251 struct sockaddr_at sat;
1254 if ( iface->i_ports == NULL ) { /* allocate port structures */
1255 for ( i = 0, as = atserv; i < atservNATSERV; i++, as++ ) {
1256 if (( se = getservbyname( as->as_name, "ddp" )) == NULL ) {
1257 syslog( LOG_INFO, "%s: service unknown", as->as_name );
1259 as->as_port = ntohs( se->s_port );
1261 if (( ap = (struct atport *)malloc( sizeof( struct atport ))) ==
1263 syslog( LOG_ERR, "malloc: %m" );
1267 ap->ap_next = iface->i_ports;
1268 ap->ap_iface = iface;
1269 ap->ap_port = as->as_port;
1270 ap->ap_packet = as->as_packet;
1272 iface->i_ports = ap;
1274 } else { /* close ports */
1275 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1276 (void)close( ap->ap_fd );
1281 iface->i_addr.sat_len = sizeof( struct sockaddr_at );
1283 iface->i_addr.sat_family = AF_APPLETALK;
1284 iface->i_addr.sat_addr.s_net = net;
1285 iface->i_addr.sat_addr.s_node = node;
1287 nr.nr_phase = phase;
1288 nr.nr_firstnet = first;
1289 nr.nr_lastnet = last;
1290 memcpy( iface->i_addr.sat_zero, &nr, sizeof( struct netrange ));
1292 if ( ifconfig( iface->i_name, SIOCSIFADDR, &iface->i_addr )) {
1293 syslog( LOG_ERR, "setifaddr: %s (%u-%u): %m. try specifying a \
1294 smaller net range.", iface->i_name, ntohs(first), ntohs(last));
1297 if ( ifconfig( iface->i_name, SIOCGIFADDR, &iface->i_addr )) {
1298 syslog( LOG_ERR, "getifaddr: %s: %m", iface->i_name );
1303 i = 1; /* enable broadcasts */
1304 #if defined(__svr4__)
1305 syslog(LOG_INFO, "setsockopt incompatible w/ Solaris STREAMS module.");
1307 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1308 if (( ap->ap_fd = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
1309 syslog( LOG_ERR, "socket: %m" );
1312 #if !defined(__svr4__)
1313 setsockopt(ap->ap_fd, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i));
1316 memset( &sat, 0, sizeof( struct sockaddr_at ));
1318 sat.sat_len = sizeof( struct sockaddr_at );
1320 sat.sat_family = AF_APPLETALK;
1321 sat.sat_addr.s_net = iface->i_addr.sat_addr.s_net;
1322 sat.sat_addr.s_node = iface->i_addr.sat_addr.s_node;
1323 sat.sat_port = ap->ap_port;
1325 if ( bind( ap->ap_fd, (struct sockaddr *)&sat,
1326 sizeof( struct sockaddr_at )) < 0 ) {
1327 syslog( LOG_ERR, "bind %u.%u:%u: %m",
1328 ntohs( sat.sat_addr.s_net ),
1329 sat.sat_addr.s_node, sat.sat_port );
1331 /* remove all interfaces if we have a problem with bind */
1332 for (iface = interfaces; iface; iface = iface->i_next) {
1333 if (ifconfig( iface->i_name, SIOCDIFADDR, &iface->i_addr )) {
1334 #ifdef SIOCATALKDIFADDR
1335 #if (SIOCDIFADDR != SIOCATALKDIFADDR)
1336 ifconfig( iface->i_name, SIOCATALKDIFADDR, &iface->i_addr );
1346 /* recalculate nfds and fds */
1348 for ( nfds = 0, iface = interfaces; iface; iface = iface->i_next ) {
1349 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1350 FD_SET( ap->ap_fd, &fds );
1351 if ( ap->ap_fd > nfds ) {
1359 ifconfig( iname, cmd, sa )
1362 struct sockaddr_at *sa;
1367 memset(&ifr, 0, sizeof(ifr));
1368 strcpy( ifr.ifr_name, iname );
1369 ifr.ifr_addr = *(struct sockaddr *)sa;
1371 if (( s = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
1374 if ( ioctl( s, cmd, &ifr ) < 0 ) {
1379 if ( cmd == SIOCGIFADDR ) {
1380 *(struct sockaddr *)sa = ifr.ifr_addr;
1386 struct interface *iface;
1390 printf( "%s", iface->i_name );
1391 if ( iface->i_flags & IFACE_RSEED ) {
1392 printf( " -router" );
1393 } else if ( iface->i_flags & IFACE_SEED ) {
1397 if ( iface->i_flags & IFACE_DONTROUTE)
1398 printf( " -dontroute");
1400 printf( " -phase" );
1401 if ( iface->i_flags & IFACE_PHASE1 ) {
1406 printf( " -net %d", ntohs( iface->i_rt->rt_firstnet ));
1407 if ( iface->i_rt->rt_lastnet != iface->i_rt->rt_firstnet ) {
1408 printf( "-%d", ntohs( iface->i_rt->rt_lastnet ));
1410 printf( " -addr %u.%u", ntohs( iface->i_addr.sat_addr.s_net ),
1411 iface->i_addr.sat_addr.s_node );
1412 printf( " -caddr %u.%u", ntohs( iface->i_caddr.sat_addr.s_net ),
1413 iface->i_caddr.sat_addr.s_node );
1414 for ( l = iface->i_rt->rt_zt; l; l = l->l_next ) {
1415 printf( " -zone %.*s", ((struct ziptab *)l->l_data)->zt_len,
1416 ((struct ziptab *)l->l_data)->zt_name );
1424 struct interface *iface;
1425 struct rtmptab *rtmp;
1429 for ( iface = interfaces; iface; iface = iface->i_next ) {
1430 for ( rtmp = iface->i_rt; rtmp; rtmp = rtmp->rt_inext ) {
1431 if ( rtmp->rt_gate == 0 ) {
1432 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
1433 printf( "%u-%u", ntohs( rtmp->rt_firstnet ),
1434 ntohs( rtmp->rt_lastnet ));
1436 printf( "%u", ntohs( rtmp->rt_firstnet ));
1439 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
1440 printf( "%u.%u for %u-%u",
1441 ntohs( rtmp->rt_gate->g_sat.sat_addr.s_net ),
1442 rtmp->rt_gate->g_sat.sat_addr.s_node,
1443 ntohs( rtmp->rt_firstnet ),
1444 ntohs( rtmp->rt_lastnet ));
1446 printf( "%u.%u for %u",
1447 ntohs( rtmp->rt_gate->g_sat.sat_addr.s_net ),
1448 rtmp->rt_gate->g_sat.sat_addr.s_node,
1449 ntohs( rtmp->rt_firstnet ));
1453 if ( rtmp->rt_iprev == 0 && rtmp != iface->i_rt ) {
1457 for ( l = rtmp->rt_zt; l; l = l->l_next ) {
1458 zt = (struct ziptab *)l->l_data;
1459 printf( " %.*s", zt->zt_len, zt->zt_name );
1472 struct interface *iface;
1473 struct rtmptab *rtmp;
1477 for ( zt = ziptab; zt; zt = zt->zt_next ) {
1478 printf( "%.*s", zt->zt_len, zt->zt_name );
1479 for ( l = zt->zt_rt; l; l = l->l_next ) {
1480 rtmp = (struct rtmptab *)l->l_data;
1481 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
1482 printf( " %u-%u", ntohs( rtmp->rt_firstnet ),
1483 ntohs( rtmp->rt_lastnet ));
1485 printf( " %u", ntohs( rtmp->rt_firstnet ));
1487 if ( rtmp->rt_iprev == 0 && rtmp->rt_gate != 0 ) {