2 * Copyright (c) 1990,1993 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
8 #include <sys/socket.h>
9 #if defined( sun ) && defined( __svr4__ )
10 #include </usr/ucbinclude/sys/file.h>
15 #include <sys/resource.h>
16 #include <sys/ioctl.h>
20 #include <net/route.h>
31 #include <netatalk/endian.h>
32 #include <netatalk/at.h>
33 #include <atalk/compat.h>
34 #include <atalk/zip.h>
35 #include <atalk/rtmp.h>
36 #include <atalk/ddp.h>
37 #include <atalk/atp.h>
38 #include <atalk/paths.h>
39 #include <atalk/util.h>
42 #include <sys/sockio.h>
46 #include "interface.h"
53 /* FIXME/SOCKLEN_T: socklen_t is a unix98 feature */
55 #define SOCKLEN_T unsigned int
59 #define WEXITSTATUS(x) ((x).w_retcode)
62 /* linux has a special ioctl for appletalk device destruction. as of
63 * 2.1.57, SIOCDIFADDR works w/ linux. okay, we need to deal with the
64 * fact that SIOCDIFADDR may be defined on linux despite the fact that
66 #if !defined(SIOCDIFADDR) && defined(SIOCATALKDIFADDR)
67 #define SIOCDIFADDR SIOCATALKDIFADDR
70 #define elements(a) (sizeof(a)/sizeof((a)[0]))
74 extern int rtmp_packet();
75 extern int nbp_packet();
76 extern int aep_packet();
77 extern int zip_packet();
81 struct atserv atserv[] = {
82 { "rtmp", 1, rtmp_packet }, /* 0 */
83 { "nbp", 2, nbp_packet }, /* 1 */
84 { "echo", 4, aep_packet }, /* 2 */
85 { "zip", 6, zip_packet }, /* 3 */
87 int atservNATSERV = elements( atserv );
89 struct interface *interfaces = NULL, *ciface = NULL;
91 int debug = 0, quiet = 0, chatty = 0;
92 char *configfile = NULL;
93 int ziptimeout = 0, transition = 0;
94 int stabletimer, stable = 0, newrtmpdata = 0, noparent = 0;
95 static int ninterfaces;
96 int defphase = IFACE_PHASE2;
100 char *version = VERSION;
101 static char *pidfile = _PATH_ATALKDLOCK;
104 /* this is the messiest of the bunch as atalkd can exit pretty much
105 * everywhere. we delete interfaces here instead of in as_down. */
106 static void atalkd_exit(const int i)
109 struct interface *iface;
111 for (iface = interfaces; iface; iface = iface->i_next) {
112 if (ifconfig( iface->i_name, SIOCDIFADDR, &iface->i_addr)) {
113 #ifdef SIOCATALKDIFADDR
114 #if (SIOCDIFADDR != SIOCATALKDIFADDR)
115 if (!ifconfig(iface->i_name, SIOCATALKDIFADDR, &iface->i_addr))
119 syslog( LOG_ERR, "difaddr(%u.%u): %m",
120 ntohs(iface->i_addr.sat_addr.s_net),
121 iface->i_addr.sat_addr.s_node);
126 server_unlock(pidfile);
131 #if !defined( ibm032 ) && !defined( _IBMR2 )
136 struct sockaddr_at sat;
139 struct rtmp_tuple rt;
140 struct atport *ap, *zap, *rap;
141 struct interface *iface, *iface2;
142 struct gate *gate, *fgate = NULL;
143 struct rtmptab *rtmp, *frtmp;
145 char *data, *end, packet[ ATP_BUFSIZ ];
149 memset(&sat, 0, sizeof( struct sockaddr_at ));
150 for ( iface = interfaces; iface; iface = iface->i_next ) {
151 if ( iface->i_flags & IFACE_LOOPBACK ) {
154 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
155 if ( ap->ap_packet == zip_packet ) {
158 if ( ap->ap_packet == rtmp_packet ) {
163 if (( iface->i_flags & ( IFACE_ADDR|IFACE_CONFIG|IFACE_NOROUTER )) ==
165 if ( iface->i_time < 3 ) {
166 if ( iface->i_flags & IFACE_PHASE1 ) {
167 if (rtmp_request( iface ) < 0) {
168 syslog(LOG_ERR, "rtmp_request: %m");
173 if (zip_getnetinfo( iface ) < 0) {
174 syslog(LOG_ERR, "zip_getnetinfo: %m");
181 iface->i_flags |= IFACE_NOROUTER;
182 if ((iface->i_flags & IFACE_ISROUTER)) {
183 if (( iface->i_flags & IFACE_SEED ) == 0 ) {
185 * No seed info, and we've got multiple interfaces.
189 "as_timer multiple interfaces, no seed" );
190 syslog( LOG_INFO, "as_timer can't configure %s",
192 syslog( LOG_INFO, "as_timer waiting for router" );
197 * Complete configuration for iface, and boot next
200 iface->i_flags |= IFACE_CONFIG;
201 for ( zt = iface->i_czt; zt; zt = zt->zt_next ) {
202 if (addzone( iface->i_rt, zt->zt_len,
204 syslog(LOG_ERR, "addzone: %m");
208 if ( iface->i_rt->rt_zt ) {
209 iface->i_rt->rt_flags &= ~RTMPTAB_ZIPQUERY;
210 iface->i_rt->rt_flags |= RTMPTAB_HASZONES;
212 if ( iface->i_flags & IFACE_PHASE1 ) {
214 "as_timer configured %s phase 1 from seed",
216 setaddr( iface, IFACE_PHASE1,
217 iface->i_caddr.sat_addr.s_net,
218 iface->i_addr.sat_addr.s_node,
219 iface->i_caddr.sat_addr.s_net,
220 iface->i_caddr.sat_addr.s_net );
223 "as_timer configured %s phase 2 from seed",
227 if ( looproute( iface, RTMP_ADD )) { /* -1 or 1 */
229 "as_timer: can't route %u.%u to loop: %m",
230 ntohs( iface->i_addr.sat_addr.s_net ),
231 iface->i_addr.sat_addr.s_node );
234 if ( iface == ciface ) {
235 ciface = ciface->i_next;
241 * Configure for no router operation. Wait for a route
242 * to become available in rtmp_packet().
244 syslog( LOG_INFO, "config for no router" );
246 if ( iface->i_flags & IFACE_PHASE2 ) {
247 iface->i_rt->rt_firstnet = 0;
248 iface->i_rt->rt_lastnet = htons( STARTUP_LASTNET );
249 setaddr( iface, IFACE_PHASE2,
250 iface->i_addr.sat_addr.s_net,
251 iface->i_addr.sat_addr.s_node,
252 0, htons( STARTUP_LASTNET ));
254 if ( looproute( iface, RTMP_ADD ) ) { /* -1 or 1 */
256 "as_timer: can't route %u.%u to loopback: %m",
257 ntohs( iface->i_addr.sat_addr.s_net ),
258 iface->i_addr.sat_addr.s_node );
262 if ( iface == ciface ) {
263 ciface = ciface->i_next;
270 for ( gate = iface->i_gate; gate; gate = gate->g_next ) {
272 free( (caddr_t)fgate );
277 data = packet + 1 + sizeof( struct ziphdr );
278 end = packet + sizeof( packet );
281 sat.sat_port = zap->ap_port;
284 * Perform timeouts on routers. If we've only got one
285 * interface, we'll use these timeouts to decide that
286 * our zone has gone away.
288 if ( ++gate->g_state >= RTMPTAB_BAD ) {
289 syslog( LOG_INFO, "as_timer gateway %u.%u down",
290 ntohs( gate->g_sat.sat_addr.s_net ),
291 gate->g_sat.sat_addr.s_node );
294 frtmp = rtmp->rt_next;
295 if ( rtmp->rt_hops == RTMPHOPS_POISON ||
296 rtmp->rt_iprev == 0 ) {
299 rtmp->rt_hops = RTMPHOPS_POISON;
300 if ((cc = rtmp_replace( rtmp )) < 0) {
301 syslog(LOG_ERR, "rtmp_replace: %m");
305 gate->g_state = rtmp->rt_state = RTMPTAB_GOOD;
310 if ( gate->g_rt == 0 ) {
311 if ( gate->g_prev == 0 ) {
312 gate->g_iface->i_gate = gate->g_next;
314 gate->g_prev->g_next = gate->g_next;
316 if ( gate->g_next != 0 ) {
317 gate->g_next->g_prev = gate->g_prev;
319 fgate = gate; /* can't free here, just mark it */
322 * If this is the last router on the only interface,
323 * reconfigure our netrange. By marking the interface
324 * as having no router, we will notice when a router
327 * XXX: actually, we always reconfigure an interface
328 * if we're not a seed router.
331 if ( gate->g_iface->i_gate == 0 &&
332 ((iface->i_flags & IFACE_SEED) == 0)) {
333 gate->g_iface->i_flags |= IFACE_NOROUTER;
334 gate->g_iface->i_flags &= ~IFACE_CONFIG;
336 /* get rid of any zones associated with this iface */
337 if (gate->g_iface->i_rt->rt_zt) {
338 rtmp_delzonemap(gate->g_iface->i_rt);
339 gate->g_iface->i_rt->rt_flags &= ~RTMPTAB_HASZONES;
342 syslog( LOG_INFO, "as_timer last gateway down" );
344 /* Set netrange to 0-fffe. */
345 if ( gate->g_iface->i_flags & IFACE_PHASE2 ) {
346 gate->g_iface->i_rt->rt_firstnet = 0;
347 gate->g_iface->i_rt->rt_lastnet =
348 htons( STARTUP_LASTNET );
349 setaddr( iface, IFACE_PHASE2,
350 iface->i_addr.sat_addr.s_net,
351 iface->i_addr.sat_addr.s_node,
352 0, htons( STARTUP_LASTNET ));
359 * If we don't have a zone for our interface yet, ask for
360 * it from any router (all routers) on the interface.
362 if (( iface->i_rt->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
363 iface->i_rt->rt_flags |= RTMPTAB_ZIPQUERY;
364 memcpy( data, &iface->i_rt->rt_firstnet, sizeof( u_short ));
365 data += sizeof( u_short );
372 * Delete old routing tuples.
374 if ( rtmp->rt_state != RTMPTAB_PERM ) {
379 * We've not been updated for this route in a while. If
380 * it's not in use, go ahead and remove it. If it is in
381 * use, mark the route as down (POISON), and look for a
382 * better route. If one is found, delete this route and use
383 * the new one. If it's not found, mark the route as GOOD
384 * (so we'll propogate our poison) and delete it the next
385 * time it becomes BAD.
387 if ( rtmp->rt_state >= RTMPTAB_BAD ) {
388 frtmp = rtmp->rt_next;
389 if ( rtmp->rt_iprev == 0 ) { /* not in use */
391 } else { /* in use */
392 if ( rtmp->rt_hops == RTMPHOPS_POISON ) {
395 rtmp->rt_hops = RTMPHOPS_POISON;
396 if ((cc = rtmp_replace( rtmp )) < 0) {
397 syslog(LOG_ERR, "rtmp_replace: %m");
401 rtmp->rt_state = RTMPTAB_GOOD;
411 if ( rtmp->rt_iprev &&
412 ( rtmp->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
413 if ( data + sizeof( u_short ) > end || n == 255 ) {
414 /* send what we've got */
415 zh.zh_op = ZIPOP_QUERY;
419 *data++ = DDPTYPE_ZIP;
420 memcpy( data, &zh, sizeof( struct ziphdr ));
422 if ( sendto( zap->ap_fd, packet, cc, 0,
423 (struct sockaddr *)&sat,
424 sizeof( struct sockaddr_at )) < 0 ) {
425 syslog( LOG_ERR, "as_timer sendto: %m" );
430 data = packet + 1 + sizeof( struct ziphdr );
431 end = packet + sizeof( packet );
435 * rt_nzq is number of ZIP Queries we've issued for a
436 * given netrange. If we've got ziptimeout on, we
437 * will only ask 3 times for any given netrange.
438 * Interestingly enough, since rt_nzq is a u_char,
439 * it will overflow after a while. This means we will
440 * periodically ask for nets that we've decided not to
441 * ask about, and warn that we can't get it's zone.
443 if ( rtmp->rt_nzq++ == 3 ) {
444 syslog( LOG_INFO, "as_timer can't get zone for %u",
445 ntohs( rtmp->rt_firstnet ));
447 if ( rtmp->rt_nzq > 3 ) {
449 rtmp = rtmp->rt_next;
455 rtmp->rt_flags |= RTMPTAB_ZIPQUERY;
456 memcpy( data, &rtmp->rt_firstnet, sizeof( u_short ));
457 data += sizeof( u_short );
460 rtmp = rtmp->rt_next;
463 /* send what we've got */
465 zh.zh_op = ZIPOP_QUERY;
469 *data++ = DDPTYPE_ZIP;
470 memcpy( data, &zh, sizeof( struct ziphdr ));
472 if ( sendto( zap->ap_fd, packet, cc, 0, (struct sockaddr *)&sat,
473 sizeof( struct sockaddr_at )) < 0 ) {
474 syslog( LOG_ERR, "as_timer sendto: %m" );
479 free( (caddr_t)fgate );
484 * Send RTMP broadcasts if we have multiple interfaces or our
485 * interface is configured as a router.
487 if ((iface->i_flags & IFACE_ISROUTER)) {
489 sat.sat_len = sizeof( struct sockaddr_at );
491 sat.sat_family = AF_APPLETALK;
492 sat.sat_addr.s_net = ATADDR_ANYNET;
493 sat.sat_addr.s_node = ATADDR_BCAST;
494 sat.sat_port = rap->ap_port;
497 end = data + sizeof( packet );
498 *data++ = DDPTYPE_RTMPRD;
499 rh.rh_net = iface->i_addr.sat_addr.s_net;
501 rh.rh_node = iface->i_addr.sat_addr.s_node;
502 memcpy( data, &rh, sizeof( struct rtmp_head ));
503 data += sizeof( struct rtmp_head );
507 if ( iface->i_flags & IFACE_PHASE1 ) {
510 memcpy( data, &rt, SZ_RTMPTUPLE );
511 data += SZ_RTMPTUPLE;
513 rt.rt_net = iface->i_rt->rt_firstnet;
515 memcpy( data, &rt, SZ_RTMPTUPLE );
516 data += SZ_RTMPTUPLE;
518 rt.rt_net = iface->i_rt->rt_lastnet;
520 memcpy( data, &rt, SZ_RTMPTUPLE );
521 data += SZ_RTMPTUPLE;
524 for ( iface2 = interfaces; iface2; iface2 = iface2->i_next ) {
526 /* XXX: there used to be a bit checking against iface ==
527 iface2. also, we don't want to send an rtmp broadcast
528 to an interface that doesn't want it. */
529 if ((( iface2->i_flags & IFACE_CONFIG ) == 0) ||
530 ((iface2->i_flags & IFACE_ISROUTER) == 0)) {
534 * Fill in tuples. Always send the same thing, regardless
535 * of the phase of the destination. Routers who don't
536 * understand extended rtmp packets will toss extended
537 * tuples because their distance will have the high bit set.
539 for ( rtmp = iface2->i_rt; rtmp; rtmp = rtmp->rt_inext ) {
540 /* don't broadcast routes we have no zone for */
541 if ( rtmp->rt_zt == 0 ||
542 ( rtmp->rt_flags & RTMPTAB_ZIPQUERY ) ||
543 ( rtmp->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
547 if ((( rtmp->rt_flags & RTMPTAB_EXTENDED ) &&
548 data + 2 * SZ_RTMPTUPLE > end ) ||
549 data + SZ_RTMPTUPLE > end ) {
550 if ( sendto( rap->ap_fd, packet, data - packet, 0,
551 (struct sockaddr *)&sat,
552 sizeof( struct sockaddr_at )) < 0 ) {
553 syslog( LOG_ERR, "as_timer sendto %u.%u (%u): %m",
554 ntohs( sat.sat_addr.s_net ),
556 ntohs( iface->i_rt->rt_firstnet ));
559 if ( iface->i_flags & IFACE_PHASE2 ) {
560 data = packet + 1 + sizeof( struct rtmp_head ) +
563 data = packet + 1 + sizeof( struct rtmp_head ) +
569 rt.rt_net = rtmp->rt_firstnet;
570 rt.rt_dist = rtmp->rt_hops;
571 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
574 memcpy( data, &rt, SZ_RTMPTUPLE );
575 data += SZ_RTMPTUPLE;
577 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
578 rt.rt_net = rtmp->rt_lastnet;
580 memcpy( data, &rt, SZ_RTMPTUPLE );
581 data += SZ_RTMPTUPLE;
589 if ( sendto( rap->ap_fd, packet, data - packet, 0,
590 (struct sockaddr *)&sat,
591 sizeof( struct sockaddr_at )) < 0 ) {
592 syslog( LOG_ERR, "as_timer sendto %u.%u (%u): %m",
593 ntohs( sat.sat_addr.s_net ),
595 ntohs( iface->i_rt->rt_firstnet ));
602 * Check if we're stable. Each time we configure an interface, we
603 * sent stabletimer to UNSTABLE. If stabletimer ever gets to
604 * STABLEANYWAY, we give up and decide to "be" stable anyway.
605 * Normally, we wait for stabletimer get <= STABLE with no new rtmp
606 * data and all zip data complete.
609 if ( stabletimer <= STABLE && !newrtmpdata && !sentzipq ) {
610 /* write out config file */
612 writeconf( configfile );
614 if ( stabletimer-- <= STABLEANYWAY ) {
620 if ( stable && !noparent ) {
622 syslog( LOG_INFO, "ready %d/%d/%d", stabletimer, newrtmpdata,
626 * Seems like we could get here more than once...
628 if ( kill( getpid(), SIGSTOP ) < 0 ) {
629 syslog( LOG_ERR, "as_timer: kill-self failed!" );
643 * Consistency check...
647 struct rtmptab *rtmp;
648 struct list *lr, *lz;
651 for ( zt = ziptab; zt; zt = zt->zt_next ) {
652 for ( lr = zt->zt_rt; lr; lr = lr->l_next ) {
653 rtmp = (struct rtmptab *)lr->l_data;
654 if ( rtmp->rt_iprev == 0 && rtmp->rt_gate != 0 ) {
655 syslog( LOG_ERR, "%.*s has %u-%u (unused)\n",
656 zt->zt_len, zt->zt_name, ntohs( rtmp->rt_firstnet ),
657 ntohs( rtmp->rt_lastnet ));
660 for ( lz = rtmp->rt_zt; lz; lz = lz->l_next ) {
661 if ( zt == (struct ziptab *)lz->l_data ) {
666 syslog( LOG_ERR, "no map from %u-%u to %.*s\n",
667 ntohs( rtmp->rt_firstnet ),
668 ntohs( rtmp->rt_lastnet ),
669 zt->zt_len, zt->zt_name );
677 #if !defined( ibm032 ) && !defined( _IBMR2 )
682 struct interface *iface;
689 if (( rtmpdebug = fopen( _PATH_ATALKDEBUG, "w" )) == NULL ) {
690 syslog( LOG_ERR, "rtmp: %m" );
693 for ( iface = interfaces; iface; iface = iface->i_next ) {
694 fprintf( rtmpdebug, "interface %s %u.%u ", iface->i_name,
695 ntohs( iface->i_addr.sat_addr.s_net ),
696 iface->i_addr.sat_addr.s_node );
697 if ( iface->i_flags & IFACE_PHASE1 ) {
698 putc( '1', rtmpdebug );
700 if ( iface->i_flags & IFACE_PHASE2 ) {
701 putc( '2', rtmpdebug );
703 if ( iface->i_flags & IFACE_RSEED ) {
704 putc( 'R', rtmpdebug );
706 if ( iface->i_flags & IFACE_SEED ) {
707 putc( 'S', rtmpdebug );
709 if ( iface->i_flags & IFACE_DONTROUTE ) {
710 putc( 'D', rtmpdebug );
712 if ( iface->i_flags & IFACE_ADDR ) {
713 putc( 'A', rtmpdebug );
715 if ( iface->i_flags & IFACE_CONFIG ) {
716 putc( 'C', rtmpdebug );
718 if ( iface->i_flags & IFACE_NOROUTER ) {
719 putc( 'N', rtmpdebug );
721 if ( iface->i_flags & IFACE_LOOP ) {
722 putc( 'L', rtmpdebug );
724 putc( '\n', rtmpdebug );
727 fprintf( rtmpdebug, "\t%u-%u ",
728 ntohs( iface->i_rt->rt_firstnet ),
729 ntohs( iface->i_rt->rt_lastnet ));
730 if ( iface->i_rt->rt_flags & RTMPTAB_ZIPQUERY ) {
731 putc( 'q', rtmpdebug );
733 if ( iface->i_rt->rt_flags & RTMPTAB_HASZONES ) {
734 putc( 'z', rtmpdebug );
736 if ( iface->i_rt->rt_flags & RTMPTAB_EXTENDED ) {
737 putc( 'x', rtmpdebug );
739 putc( 'i', rtmpdebug );
740 for ( l = iface->i_rt->rt_zt; l; l = l->l_next ) {
741 zt = (struct ziptab *)l->l_data;
742 fprintf( rtmpdebug, " '%.*s'", zt->zt_len, zt->zt_name );
744 fprintf( rtmpdebug, "\n" );
747 for ( gate = iface->i_gate; gate; gate = gate->g_next ) {
748 fprintf( rtmpdebug, "gate %u.%u %X\n",
749 ntohs( gate->g_sat.sat_addr.s_net ),
750 gate->g_sat.sat_addr.s_node, gate->g_state );
751 for ( rt = gate->g_rt; rt; rt = rt->rt_next ) {
752 fprintf( rtmpdebug, "\t%u-%u ", ntohs( rt->rt_firstnet ),
753 ntohs( rt->rt_lastnet ));
754 if ( rt->rt_flags & RTMPTAB_ZIPQUERY ) {
755 putc( 'q', rtmpdebug );
757 if ( rt->rt_flags & RTMPTAB_HASZONES ) {
758 putc( 'z', rtmpdebug );
760 if ( rt->rt_flags & RTMPTAB_EXTENDED ) {
761 putc( 'x', rtmpdebug );
763 if ( rt->rt_iprev ) {
764 putc( 'i', rtmpdebug );
766 for ( l = rt->rt_zt; l; l = l->l_next ) {
767 zt = (struct ziptab *)l->l_data;
768 fprintf( rtmpdebug, " '%.*s'", zt->zt_len, zt->zt_name );
770 fprintf( rtmpdebug, "\n" );
779 * Called when SIGTERM is recieved. Remove all routes and then exit.
781 #if !defined( ibm032 ) && !defined( _IBMR2 )
786 struct interface *iface;
790 for ( iface = interfaces; iface; iface = iface->i_next ) {
791 for ( gate = iface->i_gate; gate; gate = gate->g_next ) {
792 for ( rt = gate->g_rt; rt; rt = rt->rt_next ) {
793 if ( rt->rt_iprev ) {
794 if ( gateroute( RTMP_DEL, rt ) < 0 ) {
795 syslog( LOG_ERR, "as_down remove %u-%u failed: %m",
796 ntohs( rt->rt_firstnet ),
797 ntohs( rt->rt_lastnet ));
802 if ( iface->i_flags & IFACE_LOOP ) {
803 if (looproute( iface, RTMP_DEL )) {
804 syslog( LOG_ERR, "as_down remove %s %u.%u failed: %m",
805 iface->i_name, ntohs( iface->i_addr.sat_addr.s_net ),
806 iface->i_addr.sat_addr.s_node );
811 syslog( LOG_INFO, "done" );
822 struct sockaddr_at sat;
825 struct interface *iface;
834 while (( c = getopt( ac, av, "12qsdtf:P:" )) != EOF ) {
837 defphase = IFACE_PHASE1;
841 defphase = IFACE_PHASE2;
852 case 'q' : /* don't seed */
856 case 's' : /* seed */
860 case 't' : /* transition */
864 case 'P' : /* pid file */
869 fprintf( stderr, "Unknown option -- '%c'\n", c );
873 if ( optind != ac ) {
874 fprintf( stderr, "Too many arguments.\n" );
878 if (( prog = strrchr( av[ 0 ], '/' )) == NULL ) {
885 * Configure loop back address first, so appearances of "lo0" in
886 * the config file fail. Also insures that lo0 gets configured,
887 * even if there's some hangup during configuration of some
890 if (( interfaces = newiface( LOOPIFACE )) == NULL ) {
891 perror( "newiface" );
894 interfaces->i_flags |= IFACE_PHASE2 | IFACE_LOOPBACK;
897 * Check our initial configuration before we fork. This way we can
898 * complain about syntax errors on stdout.
900 * Basically, if we're going to read our config file, we should read
901 * it and initialize our data structures. If we're not going to read
902 * our config file, use GIFCONF to initialize our data structures.
904 if ( readconf( configfile ) < 0 && getifconf() < 0 ) {
905 fprintf( stderr, "%s: can't get interfaces, exiting.\n", prog );
909 /* we need to count up our interfaces so that we can simplify things
910 * later. we also need to figure out if we have more than one interface
911 * that is routing. */
912 for (i = 0, ninterfaces = 0, iface = interfaces; iface;
913 iface=iface->i_next) {
914 if (iface->i_flags & IFACE_DONTROUTE)
918 i = ninterfaces - i; /* number of routable interfaces */
921 * At this point, we have (at least partially) initialized data
922 * structures. Fill in what we can and verify that nothing is obviously
925 for (iface = interfaces; iface; iface = iface->i_next) {
926 /* Apply the default phase */
927 if (( iface->i_flags & IFACE_PHASE1 ) == 0 &&
928 ( iface->i_flags & IFACE_PHASE2 ) == 0 ) {
929 iface->i_flags |= defphase;
932 /* set up router flag information. if we have multiple interfaces
933 * and DONTROUTE isn't set, set up ROUTER. i is the number of
934 * interfaces that don't have the DONTROUTE flag set. */
935 if ((i > IFBASE) && ((iface->i_flags & IFACE_DONTROUTE) == 0)) {
936 iface->i_flags |= IFACE_ISROUTER;
939 /* Set default addresses */
940 if ( iface->i_rt == NULL ) {
941 if (( iface->i_rt = newrt(iface)) == NULL ) {
946 if ( iface->i_flags & IFACE_PHASE1 ) {
947 iface->i_rt->rt_firstnet = iface->i_rt->rt_lastnet =
948 iface->i_caddr.sat_addr.s_net;
950 if ( iface->i_caddr.sat_addr.s_net != ATADDR_ANYNET ||
951 ( iface->i_flags & IFACE_LOOPBACK )) {
952 iface->i_rt->rt_firstnet = iface->i_rt->rt_lastnet =
953 iface->i_caddr.sat_addr.s_net;
955 iface->i_rt->rt_firstnet = htons( STARTUP_FIRSTNET );
956 iface->i_rt->rt_lastnet = htons( STARTUP_LASTNET );
961 if (( iface->i_flags & IFACE_PHASE1 ) == 0 ) {
962 iface->i_rt->rt_flags |= RTMPTAB_EXTENDED;
965 if ( iface->i_caddr.sat_addr.s_net == ATADDR_ANYNET ) {
966 iface->i_caddr.sat_addr.s_net = iface->i_rt->rt_firstnet;
970 dumpconfig( iface ); /* probably needs args */
975 * A little consistency check...
977 if ( ninterfaces < IFBASE ) {
978 fprintf( stderr, "%s: zero interfaces, exiting.\n", prog );
982 /* do this here so that we can use ifconfig */
985 fprintf(stderr, "can't establish STREAMS plumbing, exiting.\n" );
990 /* delete pre-existing interface addresses. */
992 for (iface = interfaces; iface; iface = iface->i_next) {
993 if (ifconfig(iface->i_name, SIOCDIFADDR, &iface->i_addr)) {
994 #ifdef SIOCATALKDIFADDR
995 #if (SIOCDIFADDR != SIOCATALKDIFADDR)
996 ifconfig(iface->i_name, SIOCATALKDIFADDR, &iface->i_addr);
1004 * Disassociate. The child will send itself a signal when it is
1005 * stable. This indicates that other processes may begin using
1008 switch (i = server_lock("atalkd", pidfile, debug)) {
1013 default: /* parent */
1015 * Wait for the child to send itself a SIGSTOP, after which
1016 * we send it a SIGCONT and exit ourself.
1018 if ( wait3( &status, WUNTRACED, (struct rusage *)0 ) != i) {
1019 perror( "wait3" ); /* Child died? */
1022 if ( !WIFSTOPPED( status )) {
1023 fprintf( stderr, "AppleTalk not up! Check your syslog for the reason." );
1024 if ( WIFEXITED( status )) {
1025 fprintf( stderr, " Child exited with %d.\n",
1026 WEXITSTATUS( status ));
1028 fprintf( stderr, " Child died.\n" );
1032 if ( kill(i, SIGCONT ) < 0 ) {
1040 openlog( prog, LOG_PID );
1042 openlog( prog, LOG_PID, LOG_DAEMON );
1045 syslog( LOG_INFO, "restart (%s)", version );
1048 * Socket for use in routing ioctl()s. Can't add routes to our
1049 * interfaces until we have our routing socket.
1052 if (( rtfd = socket( PF_ROUTE, SOCK_RAW, AF_APPLETALK )) < 0 ) {
1053 syslog( LOG_ERR, "route socket: %m" );
1056 if ( shutdown( rtfd, 0 ) < 0 ) {
1057 syslog( LOG_ERR, "route shutdown: %m" );
1061 if (( rtfd = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
1062 syslog( LOG_ERR, "route socket: %m" );
1067 memset(&sv, 0, sizeof(sv));
1068 sv.sa_handler = as_down;
1069 sigemptyset( &sv.sa_mask );
1070 sigaddset( &sv.sa_mask, SIGUSR1 );
1071 sigaddset( &sv.sa_mask, SIGALRM );
1072 sigaddset( &sv.sa_mask, SIGTERM );
1073 sv.sa_flags = SA_RESTART;
1074 if ( sigaction( SIGTERM, &sv, NULL) < 0 ) {
1075 syslog( LOG_ERR, "sigterm: %m" );
1079 sv.sa_handler = as_debug;
1080 sigemptyset( &sv.sa_mask );
1081 sigaddset( &sv.sa_mask, SIGUSR1 );
1082 sigaddset( &sv.sa_mask, SIGALRM );
1083 sigaddset( &sv.sa_mask, SIGTERM );
1084 sv.sa_flags = SA_RESTART;
1085 if ( sigaction( SIGUSR1, &sv, NULL) < 0 ) {
1086 syslog( LOG_ERR, "sigusr1: %m" );
1090 sv.sa_handler = as_timer;
1091 sigemptyset( &sv.sa_mask );
1092 sigaddset( &sv.sa_mask, SIGUSR1 );
1093 sigaddset( &sv.sa_mask, SIGALRM );
1094 sigaddset( &sv.sa_mask, SIGTERM );
1095 sv.sa_flags = SA_RESTART;
1096 if ( sigaction( SIGALRM, &sv, NULL) < 0 ) {
1097 syslog( LOG_ERR, "sigalrm: %m" );
1101 it.it_interval.tv_sec = 10L;
1102 it.it_interval.tv_usec = 0L;
1103 it.it_value.tv_sec = 10L;
1104 it.it_value.tv_usec = 0L;
1105 if ( setitimer( ITIMER_REAL, &it, NULL) < 0 ) {
1106 syslog( LOG_ERR, "setitimer: %m" );
1110 ciface = interfaces;
1114 if ( select( nfds, &readfds, NULL, NULL, NULL) < 0 ) {
1115 if ( errno == EINTR ) {
1119 syslog( LOG_ERR, "select: %m" );
1124 for ( iface = interfaces; iface; iface = iface->i_next ) {
1125 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1126 if ( FD_ISSET( ap->ap_fd, &readfds )) {
1127 if ( ap->ap_packet ) {
1128 fromlen = sizeof( struct sockaddr_at );
1129 if (( c = recvfrom( ap->ap_fd, Packet, sizeof( Packet ),
1130 0, (struct sockaddr *)&sat, &fromlen )) < 0 ) {
1131 syslog( LOG_ERR, "recvfrom: %m" );
1136 printf( "packet from %u.%u on %s (%x) %d (%d)\n",
1137 ntohs( sat.sat_addr.s_net ),
1138 sat.sat_addr.s_node, iface->i_name,
1139 iface->i_flags, ap->ap_port, ap->ap_fd );
1140 bprint( Packet, c );
1144 if ( sighold( SIGALRM ) || sighold( SIGUSR1 )) {
1145 syslog( LOG_ERR, "sighold: %m" );
1149 mask = sigsetmask( sigmask( SIGALRM ) |
1150 sigmask( SIGUSR1 ));
1152 if (( *ap->ap_packet )( ap, &sat, Packet, c ) < 0) {
1153 syslog(LOG_ERR, "ap->ap_packet: %m");
1161 if ( sigrelse( SIGUSR1 ) || sigrelse( SIGALRM )) {
1162 syslog( LOG_ERR, "sigrelse: %m" );
1176 * This code is called (from main(), as_timer(), zip_packet(),
1177 * and rtmp_packet()) to set the initial "bootstrapping" address
1181 struct interface *iface;
1188 if ( iface->i_flags & IFACE_ADDR ) {
1189 syslog( LOG_ERR, "bootaddr OOPS!" );
1193 if ( iface->i_flags & IFACE_PHASE1 ) {
1194 setaddr( iface, IFACE_PHASE1, 0,
1195 iface->i_caddr.sat_addr.s_node, 0, 0 );
1197 if ( iface->i_flags & IFACE_LOOPBACK ) {
1198 iface->i_flags |= IFACE_CONFIG | IFACE_ADDR;
1199 if ( ciface == iface ) {
1200 ciface = ciface->i_next;
1204 } else if (rtmp_request( iface ) < 0) {
1205 syslog(LOG_ERR, "bootaddr (rtmp_request): %m");
1210 setaddr( iface, IFACE_PHASE2, iface->i_caddr.sat_addr.s_net,
1211 iface->i_caddr.sat_addr.s_node,
1212 iface->i_rt->rt_firstnet, iface->i_rt->rt_lastnet );
1214 if ( iface->i_flags & IFACE_LOOPBACK ) {
1215 iface->i_flags |= IFACE_CONFIG | IFACE_ADDR;
1216 if ( ciface == iface ) {
1217 ciface = ciface->i_next;
1221 } else if (zip_getnetinfo( iface ) < 0) {
1222 syslog(LOG_ERR, "bootaddr (zip_getnetinfo): %m");
1227 iface->i_flags |= IFACE_ADDR;
1228 stabletimer = UNSTABLE;
1234 * to manage the i_ports field and the fds for select().
1236 setaddr( iface, phase, net, node, first, last )
1237 struct interface *iface;
1241 u_int16_t first, last;
1247 struct sockaddr_at sat;
1250 if ( iface->i_ports == NULL ) { /* allocate port structures */
1251 for ( i = 0, as = atserv; i < atservNATSERV; i++, as++ ) {
1252 if (( se = getservbyname( as->as_name, "ddp" )) == NULL ) {
1253 syslog( LOG_INFO, "%s: service unknown", as->as_name );
1255 as->as_port = ntohs( se->s_port );
1257 if (( ap = (struct atport *)malloc( sizeof( struct atport ))) ==
1259 syslog( LOG_ERR, "malloc: %m" );
1263 ap->ap_next = iface->i_ports;
1264 ap->ap_iface = iface;
1265 ap->ap_port = as->as_port;
1266 ap->ap_packet = as->as_packet;
1268 iface->i_ports = ap;
1270 } else { /* close ports */
1271 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1272 (void)close( ap->ap_fd );
1277 iface->i_addr.sat_len = sizeof( struct sockaddr_at );
1279 iface->i_addr.sat_family = AF_APPLETALK;
1280 iface->i_addr.sat_addr.s_net = net;
1281 iface->i_addr.sat_addr.s_node = node;
1283 nr.nr_phase = phase;
1284 nr.nr_firstnet = first;
1285 nr.nr_lastnet = last;
1286 memcpy( iface->i_addr.sat_zero, &nr, sizeof( struct netrange ));
1288 if ( ifconfig( iface->i_name, SIOCSIFADDR, &iface->i_addr )) {
1289 syslog( LOG_ERR, "setifaddr: %s (%u-%u): %m. try specifying a \
1290 smaller net range.", iface->i_name, ntohs(first), ntohs(last));
1293 if ( ifconfig( iface->i_name, SIOCGIFADDR, &iface->i_addr )) {
1294 syslog( LOG_ERR, "getifaddr: %s: %m", iface->i_name );
1299 i = 1; /* enable broadcasts */
1300 #if defined(__svr4__)
1301 syslog(LOG_INFO, "setsockopt incompatible w/ Solaris STREAMS module.");
1303 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1304 if (( ap->ap_fd = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
1305 syslog( LOG_ERR, "socket: %m" );
1308 #if !defined(__svr4__)
1309 setsockopt(ap->ap_fd, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i));
1312 memset( &sat, 0, sizeof( struct sockaddr_at ));
1314 sat.sat_len = sizeof( struct sockaddr_at );
1316 sat.sat_family = AF_APPLETALK;
1317 sat.sat_addr.s_net = iface->i_addr.sat_addr.s_net;
1318 sat.sat_addr.s_node = iface->i_addr.sat_addr.s_node;
1319 sat.sat_port = ap->ap_port;
1321 if ( bind( ap->ap_fd, (struct sockaddr *)&sat,
1322 sizeof( struct sockaddr_at )) < 0 ) {
1323 syslog( LOG_ERR, "bind %u.%u:%u: %m",
1324 ntohs( sat.sat_addr.s_net ),
1325 sat.sat_addr.s_node, sat.sat_port );
1327 /* remove all interfaces if we have a problem with bind */
1328 for (iface = interfaces; iface; iface = iface->i_next) {
1329 if (ifconfig( iface->i_name, SIOCDIFADDR, &iface->i_addr )) {
1330 #ifdef SIOCATALKDIFADDR
1331 #if (SIOCDIFADDR != SIOCATALKDIFADDR)
1332 ifconfig( iface->i_name, SIOCATALKDIFADDR, &iface->i_addr );
1342 /* recalculate nfds and fds */
1344 for ( nfds = 0, iface = interfaces; iface; iface = iface->i_next ) {
1345 for ( ap = iface->i_ports; ap; ap = ap->ap_next ) {
1346 FD_SET( ap->ap_fd, &fds );
1347 if ( ap->ap_fd > nfds ) {
1355 ifconfig( iname, cmd, sa )
1358 struct sockaddr_at *sa;
1363 memset(&ifr, 0, sizeof(ifr));
1364 strcpy( ifr.ifr_name, iname );
1365 ifr.ifr_addr = *(struct sockaddr *)sa;
1367 if (( s = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
1370 if ( ioctl( s, cmd, &ifr ) < 0 ) {
1375 if ( cmd == SIOCGIFADDR ) {
1376 *(struct sockaddr *)sa = ifr.ifr_addr;
1382 struct interface *iface;
1386 printf( "%s", iface->i_name );
1387 if ( iface->i_flags & IFACE_RSEED ) {
1388 printf( " -router" );
1389 } else if ( iface->i_flags & IFACE_SEED ) {
1393 if ( iface->i_flags & IFACE_DONTROUTE)
1394 printf( " -dontroute");
1396 printf( " -phase" );
1397 if ( iface->i_flags & IFACE_PHASE1 ) {
1402 printf( " -net %d", ntohs( iface->i_rt->rt_firstnet ));
1403 if ( iface->i_rt->rt_lastnet != iface->i_rt->rt_firstnet ) {
1404 printf( "-%d", ntohs( iface->i_rt->rt_lastnet ));
1406 printf( " -addr %u.%u", ntohs( iface->i_addr.sat_addr.s_net ),
1407 iface->i_addr.sat_addr.s_node );
1408 printf( " -caddr %u.%u", ntohs( iface->i_caddr.sat_addr.s_net ),
1409 iface->i_caddr.sat_addr.s_node );
1410 for ( l = iface->i_rt->rt_zt; l; l = l->l_next ) {
1411 printf( " -zone %.*s", ((struct ziptab *)l->l_data)->zt_len,
1412 ((struct ziptab *)l->l_data)->zt_name );
1420 struct interface *iface;
1421 struct rtmptab *rtmp;
1425 for ( iface = interfaces; iface; iface = iface->i_next ) {
1426 for ( rtmp = iface->i_rt; rtmp; rtmp = rtmp->rt_inext ) {
1427 if ( rtmp->rt_gate == 0 ) {
1428 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
1429 printf( "%u-%u", ntohs( rtmp->rt_firstnet ),
1430 ntohs( rtmp->rt_lastnet ));
1432 printf( "%u", ntohs( rtmp->rt_firstnet ));
1435 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
1436 printf( "%u.%u for %u-%u",
1437 ntohs( rtmp->rt_gate->g_sat.sat_addr.s_net ),
1438 rtmp->rt_gate->g_sat.sat_addr.s_node,
1439 ntohs( rtmp->rt_firstnet ),
1440 ntohs( rtmp->rt_lastnet ));
1442 printf( "%u.%u for %u",
1443 ntohs( rtmp->rt_gate->g_sat.sat_addr.s_net ),
1444 rtmp->rt_gate->g_sat.sat_addr.s_node,
1445 ntohs( rtmp->rt_firstnet ));
1449 if ( rtmp->rt_iprev == 0 && rtmp != iface->i_rt ) {
1453 for ( l = rtmp->rt_zt; l; l = l->l_next ) {
1454 zt = (struct ziptab *)l->l_data;
1455 printf( " %.*s", zt->zt_len, zt->zt_name );
1468 struct interface *iface;
1469 struct rtmptab *rtmp;
1473 for ( zt = ziptab; zt; zt = zt->zt_next ) {
1474 printf( "%.*s", zt->zt_len, zt->zt_name );
1475 for ( l = zt->zt_rt; l; l = l->l_next ) {
1476 rtmp = (struct rtmptab *)l->l_data;
1477 if ( rtmp->rt_flags & RTMPTAB_EXTENDED ) {
1478 printf( " %u-%u", ntohs( rtmp->rt_firstnet ),
1479 ntohs( rtmp->rt_lastnet ));
1481 printf( " %u", ntohs( rtmp->rt_firstnet ));
1483 if ( rtmp->rt_iprev == 0 && rtmp->rt_gate != 0 ) {