Patch #: 16 Type: update Priority: medium Modification: add features from UAR 1.1 Modification: Improved zone list handling Modification: NBP registration of interface names, ie: "munnari-ie0:UAR@*" Modification: add support for DEC FDDI (ULTRIX & Digital UNIX) Modification: add time server and 'tardis' time client Modification: add support for NetBSD 1.0 Modification: bug fix for large zone list per network Submitted: David Hornsby Submitted: Tom King Reported: Peter Leppik Reported: "James F. Tau" Archived: munnari.OZ.AU mac/cap.patches/uar.1.0.patch16 Application: 'cd uar; patch -p < uar.1.0.patch16' WARNING: WARNING: Note the change to signal handling indicated in the README WARNING: *** Makefile.orig Wed Mar 22 00:27:27 1995 --- Makefile Mon Sep 25 08:42:54 1995 *************** *** 1,19 **** # ! # UNIX AppleTalk Router # - # Copyright (c) 1992, The University of Melbourne # djh@munnari.OZ.AU # # ! # CFLAG settings for various supported hosts # # The defines for specific packet filters are ! # -DSNITPF SUN NIT PF (default) ! # -DUPFILT ULTRIX PF (default) # -DBPFILT BERKELEY PF # -DENETPF ENET PF # # For Sony NEWS OS4.2 or later to allow use of EtherTalk Phase 2 # CFLAGS=-Dsony_phaseII # LFLAGS= --- 1,26 ---- # ! # UAR - UNIX AppleTalk Router ! # ! # Copyright (c) 1992-1995, The University of Melbourne # # djh@munnari.OZ.AU # # ! # Specific CFLAG settings for various supported hosts. NB: A number of ! # supported hosts do not require special flags and are not listed below. # # The defines for specific packet filters are ! # ! # -DSNITPF SUN NIT PF (SunOS default) ! # -DUPFILT ULTRIX PF (ULTRIX default) # -DBPFILT BERKELEY PF # -DENETPF ENET PF # + # To enable FDDI support under ULTRIX or Digital UNIX (OSF/1), add + # -DUPFILT_FDDI + # + # # For Sony NEWS OS4.2 or later to allow use of EtherTalk Phase 2 # CFLAGS=-Dsony_phaseII # LFLAGS= *************** *** 29,39 **** # LFLAGS= # LIBS=-lsocket -lnsl # - # For DEC Aplha OSF/1, Phase 1 or Phase 2 - # CFLAGS= - # LFLAGS= - # LIBS=pfopen.o - # # For 386BSD, FreeBSD 1.0, Phase 1 only # CFLAGS=-D__386BSD__ # LFLAGS= --- 36,41 ---- *************** *** 45,50 **** --- 47,57 ---- # LFLAGS= # LIBS= # + # For NetBSD 1.0 + # CFLAGS= + # LFLAGS= + # LIBS=-lcrypt + # # For BSDI BSD/386, Phase 1 or Phase 2 # CFLAGS= # LFLAGS= *************** *** 97,103 **** rm -rf *.o core uar tar: ! tar -cvf uar.tar Makefile README uar.1l \ ! ForceDDPCheckSum.hqx IPTnnl.1.0.sit.hqx \ ! uar.h aarp.c cap.c ddp.c nbp.c \ ! pf.c rtmp.c stats.c uar.c zip.c tnnl.c uar.conf --- 104,110 ---- rm -rf *.o core uar tar: ! tar -cvf uar.tar Makefile README uar.1l ForceDDPCheckSum.hqx \ ! IPTnnl.1.0.sit.hqx Tardis.1.6.sit.hqx uar.conf \ ! uar.h aarp.c cap.c ddp.c nbp.c pf.c rtmp.c \ ! stats.c uar.c zip.c tnnl.c *** README.orig Sat Mar 25 00:42:59 1995 --- README Mon Sep 25 08:43:10 1995 *************** *** 4,26 **** The University of Melbourne djh@munnari.OZ.AU October, 1993 ! version 1.0.15 UAR is a 'UNIX AppleTalk Router' supporting Phase 1 or Phase 2 AppleTalk routing between multiple ethernet interfaces on a UNIX workstation. UAR ! also supports CAP services and simple AppleTalk packet tunneling over an ! IP internet. Note: CAP with UAR provides a similar functionality to CAP in Native EtherTalk mode, but on a wider variety of host types. UAR currently supports Phase 1 and Phase 2 EtherTalk networks connected to SUN SunOS/Solaris, DEC ULTRIX/Alpha, SGI IRIX, Sony NEWS 4.2, HP-UX ! 8.07, IBM RS6000 AIX, Linux 1.1.74, BSDI BSD/386 1.1 and FreeBSD 2.0 ! workstations, and Phase 1 only on Sony NEWS pre-4.2 and 386BSD/FreeBSD ! 1.0 workstations. NOTICE --- 4,29 ---- The University of Melbourne djh@munnari.OZ.AU October, 1993 ! version 1.0.16 UAR is a 'UNIX AppleTalk Router' supporting Phase 1 or Phase 2 AppleTalk routing between multiple ethernet interfaces on a UNIX workstation. UAR ! also supports CAP services (Columbia AppleTalk Package), AppleTalk time ! service, and simple AppleTalk packet tunneling over an IP internet. Note: CAP with UAR provides a similar functionality to CAP in Native EtherTalk mode, but on a wider variety of host types. UAR currently supports Phase 1 and Phase 2 EtherTalk networks connected to SUN SunOS/Solaris, DEC ULTRIX/Alpha, SGI IRIX, Sony NEWS 4.2, HP-UX ! 8.07, IBM RS6000 AIX, Linux 1.1.74, BSDI BSD/386 1.1, NetBSD 1.0 and ! FreeBSD 2.0 workstations, and Phase 1 only on Sony NEWS pre-4.2 and ! 386BSD/FreeBSD 1.0 workstations. ! ! Note: UAR supports AppleTalk over FDDI for ULTRIX & Digital UNIX. ! Refer to the "Notes for DEC FDDI" section below. NOTICE *************** *** 42,59 **** on a small number of UNIX hosts within a single organisation at no cost (please note the distribution and reuse restrictions listed above). Sites may, however, elect to pay a nominal/negotiable shareware or site license fee. Payment of this fee entitles the site to inclusion on a mailing list for notification of updates and bugfixes, higher priority attention for problem reports and, most importantly, encourages further development on this and other packages. ! UAR shareware version 1.1 supports ! * ARNS services for Async ATalk2 and IPRemote clients ! * CAP services on other than the default zone ! * NBP registration of EtherTalk interfaces ! * more efficient ZONE list handling The regular mail address for corresponence or payments is --- 45,63 ---- on a small number of UNIX hosts within a single organisation at no cost (please note the distribution and reuse restrictions listed above). + + SHAREWARE + Sites may, however, elect to pay a nominal/negotiable shareware or site license fee. Payment of this fee entitles the site to inclusion on a mailing list for notification of updates and bugfixes, higher priority attention for problem reports and, most importantly, encourages further development on this and other packages. ! In addition to the freeware features, UAR shareware version 1.1 supports ! * ARNS services for Async ATalk2 and IPRemote clients ! * NBP filtering of Objects, Types or Zones The regular mail address for corresponence or payments is *************** *** 74,85 **** Please report any problems via email to uar@munnari.OZ.AU CONFIGURATION The router is configured from a configuration file, if no file is provided the router will glean the necessary information from other routers on the ! network (ie: it acts as a non-seed router). The default configuration file ! name is /usr/local/lib/cap/uar.conf. An example file: # configuration file for UAR # --- 78,96 ---- Please report any problems via email to uar@munnari.OZ.AU + MORE INFORMATION + + http://www.cs.mu.OZ.AU/appletalk/atalk.html + + CONFIGURATION The router is configured from a configuration file, if no file is provided the router will glean the necessary information from other routers on the ! network (ie: it acts as a non-seed router). You can also run UAR with one ! or more non-seed interfaces by simply leaving the interface configuration ! data out of the configuration file. The default configuration file name ! is /usr/local/lib/cap/uar.conf. An example file: # configuration file for UAR # *************** *** 99,104 **** --- 110,116 ---- network 83.4 zone "unimelb-CompSci" zonelist "unimelb-CompSci" + timesrvr mulga phase 2 cap off *************** *** 131,136 **** --- 143,150 ---- -d number bit positions in print debugging messages for various subsystems. For details see uar.h. + -f uar.conf use "uar.conf" as the configuration file. + -l logfile use "logfile" for logging output. -1 | -2 use either Phase 1 or Phase 2 (default is 2). *************** *** 141,152 **** services are specified in the configuration file. Use -C only for non-seed routers (no config file). one or more ethernet interface names as listed by ! 'netstat -i' or the special interface name "tnnl", ! must match those listed in uar.conf. EG: ! uar -d 3967 -l logfile -2 ie0 ie1 CAP --- 155,189 ---- services are specified in the configuration file. Use -C only for non-seed routers (no config file). + -t server attach a timeserver to the first interface. Use -t + only for non-seed routers (no config file). + + -v print the UAR version number and exit. + + -z name the local cable zonename where CAP services appear. + Use -z only for non-seed routers (no config file). + one or more ethernet interface names as listed by ! 'netstat -i' or the special interface name "tnnl". ! Interface names that match those listed in uar.conf ! are 'seed' interfaces, others are 'non-seed'. EG: ! uar -d 3967 -l logfile -2 ie0 ie1 tnnl ! ! ! TIME SERVER ! ! UAR can provide a current time service to Macintoshes using the 'tardis' ! Chooser extension. You can enable timeserving on one or more interfaces ! (but only one is necessary) by adding a uar.conf entry of the form ! ! timesrvr "timeServer" ! ! to the selected interface. "timeServer" is the name to appear in the ! Chooser of the client Macintosh. Macintosh time is set from the selected ! server when the Mac is booted, by the user from the Chooser or daily at ! a specified time. CAP *************** *** 218,224 **** A Macintosh using the IPTnnl adev (a Network Control Panel client) can also be connected to a UAR tunnel, or used to connect to other IPTnnl equipped Macintoshes. For more details, refer to the 'IPTnnl userDoc' file which is ! available via FTP from munnari.OZ.AU in the file iptnnladev.1.0.sit.hqx.Z Each UAR host or IPTnnl Macintosh participating in IP tunneling must contain identical network, zone, peer and phase entries and each must have a unique --- 255,261 ---- A Macintosh using the IPTnnl adev (a Network Control Panel client) can also be connected to a UAR tunnel, or used to connect to other IPTnnl equipped Macintoshes. For more details, refer to the 'IPTnnl userDoc' file which is ! available via FTP from munnari.OZ.AU as the file iptnnladev.1.0.sit.hqx.Z Each UAR host or IPTnnl Macintosh participating in IP tunneling must contain identical network, zone, peer and phase entries and each must have a unique *************** *** 243,250 **** STATISTICS ! UAR can be requested to dump the AARP, RTMP, ZONE and statistics tables ! by sending signals to the UAR process. The signals are --- 280,287 ---- STATISTICS ! UAR versions 1.0.15 and below can be requested to dump the AARP, RTMP, ! ZONE and statistics tables by sending signals to the UAR process. The signals are *************** *** 256,261 **** --- 293,305 ---- eg: kill -QUIT + IMPORTANT: + + The function of signals changed in UAR versions 1.0.16 and 1.1. The + signal QUIT dumps the AARP, RTMP, NBP, ZONE and statistics tables. In + version 1.1, HUP causes the ARNS IP filter file to be re-read. USR1 + and USR2 are currently ignored. + The location of the dump and log files may be changed by editing the file uar.h or defining a new path in the Makefile. *************** *** 333,353 **** You MUST manually set the define for LIBS=pfopen.o in the Makefile and copy /usr/lib/examples/packetfilter/pfopen.c to the UAR directory. ---------------------- Notes for HP-UX users: If you receive the message "/dev/lan0: device busy" then you may need to upgrade your operating system to HP-UX 9.04 or greater. ! ----------------------- ! Notes for 386BSD users: You must install the Berkeley Packet Filter on your system and define -D__386BSD__ in the CFLAGS= line in the Makefile. At this stage, 386BSD supports only Phase 1 EtherTalk due to limitations in multicast support in the 386BSD ethernet driver. ! ----------------------- Notes for FreeBSD 2.0 users: You must define -DFreeBSD in the CFLAGS= line in the Makefile. There --- 377,405 ---- You MUST manually set the define for LIBS=pfopen.o in the Makefile and copy /usr/lib/examples/packetfilter/pfopen.c to the UAR directory. + ------------------- + Notes for DEC FDDI: + + UAR supports FDDI interfaces under DEC ULTRIX and Digital UNIX (tested + with the "fta" interface under OSF/1 3.2). You must define UPFILT_FDDI + in the Makefile to enable the FDDI code. When used in this mode, you + may mix FDDI and ethernet interfaces in the UAR interface argument list. + ---------------------- Notes for HP-UX users: If you receive the message "/dev/lan0: device busy" then you may need to upgrade your operating system to HP-UX 9.04 or greater. ! --------------------------------------- ! Notes for 386BSD and FreeBSD 1.0 users: You must install the Berkeley Packet Filter on your system and define -D__386BSD__ in the CFLAGS= line in the Makefile. At this stage, 386BSD supports only Phase 1 EtherTalk due to limitations in multicast support in the 386BSD ethernet driver. ! --------------------------- Notes for FreeBSD 2.0 users: You must define -DFreeBSD in the CFLAGS= line in the Makefile. There *************** *** 357,362 **** --- 409,419 ---- -------------------------- (edited ARNS version, as of July '93 UAR is untested on Sony NEWS) + + Yasuaki Honda + Sony Computer Science Laboratory Inc. + honda@csl.sony.co.jp + Notes for Sony NEWS users: You may know that recently Sony Corp. released NEWS-OS4.2 which supports *************** *** 423,429 **** % uar -l logfile -2 -i /dev/ether0 Then uar will speak phase 2. - - Yasuaki Honda - Sony Computer Science Laboratory Inc. - honda@csl.sony.co.jp --- 480,482 ---- *** Tardis.1.6.sit.hqx.orig Mon Sep 25 09:15:31 1995 --- Tardis.1.6.sit.hqx Fri Sep 22 16:44:38 1995 *************** *** 0 **** --- 1,201 ---- + (This file must be converted with BinHex 4.0) + :$R4KFQ4TFbia,MBZFfPd!&0*9#&6593K!!!!!#5`!!!!!'p`8dP8)3!"!!!NX(* + -BA8"!!!!!!!!!!)!"R4KFQ4TFbB!!!"3)hT!JX''3),"N!"!JX'J,5d!!bdY,5d + Y,5dY!&!MN!!!6@Xk!�[!1m!48!'`!"!!!!8#1U8N4&9P406%3K!+DE@8+RM$L + K!!!bT!!!!!!!!#3U!!!!!)VA!!!!!!!!!!$Vh`!!"!J)!-D+J#m1!K#3!)HJ`iF + 3)dBd3#H-($*TjY!53&!+N5*@U$4K3L4%`"m#N!!ip0!ZS%H3!#**QJ5!8UA%QkB + fC4%#83DTQd#$#Ke+Y+M4Sd8,N!!"!q*$+K!aFZ53!!'LLTXdGXV)QC1'6Ki3Emb + !D&+'MCJhGH5i+H2#LC9rfT!!R!Z!)BQlIq"#D@L""#i)2!*-JGV`J`Fm%($qr3$ + J4&F!'dMFr)1AbJi%&rrZ)5"i4J%)bGS'J`QS+mZM&cbF&+&bT6!!3+P!QIJ#BX% + C#(!![0#pS$%!Ebm@T"S&j3N'AJ!5C1!$`)A!j3#U,)6H"-!!k%8!%)$1"%!"k&3 + !')!Z"m!"k'3!))!q*lPTe%5N@*(bJN'U8,0VRa(L'iS2!'hB!-)5S+3`)#K+"2I + $!ERYPNSU9Cc'3'6rH0-B!8SSmB8C$!5ALL5I`5@D"!FQFD!+(Si5BQJE-1%1"S$ + mii`6AMK4KeX"b48!!LMJ%3!(-1!3J$4)!1-F'!k!F%!jJ#K"bfCQ%!$$!@!S--8 + KF(`!bb&YU*1BLa$%L!q00Z))`'IU&IL#F`b)i)Ck)N6K4#4S)J#+#Q6HD%@1jhb + !!`)iL#H!)fISN!$&%kJP-B36)rcJR!+a0A8'#,Z"!%5")%$a!J+1UKH'3-`-am3 + h()cT"3KIB2')%p#i&N!Ub)$"$JNmD+HH#6bN-3BE1+#3!1ZZ02b&!#QCJS!'!"C + NbX#a"*cC"LK4)L(%-83FqX)!R8)+LJJIR!'%Y6`SbQLfNAjJKJ%[[$S+'+DNZjX + *C`D"UDDF#J$#%20ZfLN#R`BJc($$MIB2(G*D5`#jfjS,bk(CUZ+"T!$m!m0ZZqh + lU3"XU&+#`%4-JFBEGb6K4"*8J#$'9e#%83FEBfNeKPB!$2%'((R)NFBCD0!"93i + ih0"#9$R!!)!9@R(eKKYJL3A$$#r)F--,3323!Ki*%2!22d[FK8m)c940)6fSZ"' + C2kDJmND3!!QS-!i@#J!"33L`8)h#'3c!i))rXK!!"!!Sa!"-fQLcX(EEEmHGJ!Y + R'"!$2qSP`!))1+3YJhK"R#Q,'rl3dSB&D+ZJ0ppqT`d(!U%r(VN+,3$aM`LTrf1 + #!@q#m!m+X*rTHJr-SI!2#$B',S0c#+K"`1ql3a0%kB1l(8,S,R5Hr0ZKSc"ffAf + S)"NrA&GGTK9NbqARTrq`B-+E#YMeM`3S,')!*33"NJ0cc4+3!&X+HaZ3!!*c)*` + *J!,e&H&1pfTB#",d!!!G8%J%VKQ!%%k"#RB3J(d"!84pN!!3`*33d!-(G08#'`J + q,SbU9$4#&4G@"Bf(j)phh$1&ph"`+&8-S#PQJ-#DpQHaL+&K0!"!"3Q!m#Pr8!) + %5X#8&)`&!"@!BJ6JfP8Gk0!T"k##!5#3!%))[P"%%,J#!,JCRR-F!)aJ)!!B!(K + !$2BQ2`#%S(iK`*rq&##%BhNJ"T@$#R-')J)i!S!%jN2I&4@`[[DpceCPT*pilUH + rr(P'!K5E%1C3-8!!X+#4dT1-#&"aJGb%3J3LN!$##&5#)J@SJJ!p&-3(6B@U*l` + $!!aJP3R2j*EZp3N(RqU(00$N'5M!!!@SP!%Z%3#*)-LJ9JMSJHT!-!h*J1#ACiU + %,c'$JQN!S3G"Q0dYpkG,mI35Q5"3*[&-i%aSZZk!-r6N"hV)J&''m!XMC"8F-## + %-d3"'9Gl`4X+#!!523%8CjUR$@$`#J"J!#`!N!#"+3(J!am!3TAQF3"6R,+cU96 + P+PRC5PHq%TD@Q38YDQ',QHS6SFB83"FD-J-91UU,!Y!MT%SJD3(i%9)JJ+"@hV& + "+$`J24!`i!`bU)p[E+!%)'$K#@C``!`4S&2(-+)iB+!!53NJ!KM8kKr!q%,Li+# + !aF!+"%`!a3G3F,dmZH8IQY!4"VLU(L&JaKYQr3F[dUS*da3'(Nl44AjX3b)#'@J + +3lL,0q!J!P#ii%4Z03`!8L&AfY$e3(I0UeVjkPI!2Z+Y(L$XA-p39dcKp5kDB1a + I#B3L49D)3VbJN!!Q'M-!)d#R!!"i"(5DjBJ8G+HAl!!!29+J%NUmMb-!`-3I"k+ + *##'"$3#3!%0Z2X!Baj!!!`BI+**ccL!P+XP!#F$PK"X-i04pm!--*[!YF1Ra!aB + !J"0`#-"L*JKF#j98!XK9,J#B1b8`##!h,S,42acKe6d"3%FmHK-#EXX6-`5"(3+ + BV8V3)!6[FJ-kqH['I`0-@`#3!11r!$"$Jp%"RB'`Bl8!D%F'h[3!!,a$Z`!!aR# + ,'`!rq1!$8`+6Q1Vl$f5)p3Kh33CC%5#%#33f'#!JE!ZqF,8cr20kQ,THTN5`"$M + !S,&!9J%%*S!%32a(#NF)cS9N-D!K!*JH@NJ#%SkK*,m'3@XJ`)8!'2$PIq$$bJ' + @3K,J3)$'`M4L`,JL!c)!K!"253Y!b-(Ha$'r[8N$$J*)C'2q!B(r$*3"BS%$!f$ + "#J#i)A(9I895&d`2aH+$cBh&$$j!SB-8[bK'[-L6*aK(P5F-34m"%%3)NP"2)H" + b!rLX*JB'5T8[L1!,-JL%39RP9!"FB$3")%1[-3"X,[3k!m#Q3UrVJ80@p*SH1#4 + &VqH"3dld'KmiT%5[li&$4[6D(MJN4+rl!3Bqp(SIB,"$Vr8""L2AkVTUF1T!`#$ + X@[N$$&k3!,F!`)!&H3m!$&,SpEf"X'i`G2UTB+$"Z-(3[(H$!3AR"N06H6"[)08 + U(f$JA+f`$3&p9dRH!3#$P#Mq`RNUMJrrU)Fr`F!8NmF!jICBZE)4lJ5"J`%*e`D + $%(U0F4jX'`clG$J-&Uk#L*1Ji"li0JeU93!`X%$TY6+!a+&Z(M"Ji0B5q!#UaJJ + !$5JK!&%#"3(F5`S#l$SD@0Ik&f,!%`kmr"rAm#IA[3lf0SpG!'8r1`&FJ!8S3#' + IfK%"(KD!!4Gm`JQT@!LU&X-UZ3"#a"`)J`D'(3B+p*S#BA$!U!B3J"GF!B[HB"` + %E!5#1`3N0a#!J"3!)B*jJL!Dr35"Affd+5(-%`'3!"-!0KJ3ShriRQj+!-3CF!q + %$a`V!mP"PBf3!-,mjM[rqG!Rb0kEi(F3l$d)9)"#rU,2rHjhAbi!!-1Trp'fFaL + "(r!#344)S(d%R%%!)T!!K"'q%AcQ(K%-jKL9!4L6&LcL3!#4X!B+J&X2-!84*J" + b%!!I8$N%B#2Y0'MN)!4!S!6Q)J-5m(m"+$qIm(!3)#6l3)!'q!Ebi`P@0fS""3+ + QTJqlXfUYpQVi4'Xr3%CPSJ[rS!F25)1dS#%aU"dcf(8["`$jd(9L"i0NG'Vqi!j + A%!dfFQZ$TJ3Q@'T[&h-Bi!64))&'#!e+%!%a*"GJ!!Jhq!qqJ&bM%J!'d&-cq!m + D%!5Ra!",0`rJ)!-BF!C')!YB)!C#)!*3-!9"F!B8N!"P3L!%&"!"e"!$)"!!J`J + #!Q!&!L!0`J!'k!"3"!!"f5#*P*J0DNB(,l3Ea#F"%5#*8a"XqQ!!J%!3)M!&3Q! + 'l("V!e9SJN#&P+)GP'8T3K!%%J!")JF"k#!38C!!$2qJ$d)`HR9J#(!J!f-`"h4 + 3(Jja!1cQ!!)""8%`"%X!$`%4!)d!!(M!'0a$$A*a!"M!!X$M!Q`b2PJ8AV$`*R& + )Bfr#!F$Q$AV"&rj!$Am4')0K0ehh13k`"J,"#`b`0`A`*J&!#p"!F$XJ(Nk`$`6 + "M))!!)f'$`'J#J(J!'EP$fMP#[kJ$B%&9i5&!V4a8b5593C#"ANPNCU&9AGb'4, + CC$T`AjKMAJI!8hIM$6pe"J,""EkeNMp3!!fLNKAj!JIJ'P53!!VR3)%b'3!q%&l + %Y5BlfC1e`J9!#@`UF*&aK3*A-%-8N!!+"e!IUD!+&aPCZL#9(R+9pU%+`+D5rd! + 6K[%"iF9iZQ!!D!#9'AN&&$*BB*Q9FIP@D#N!DQN!eI*BKX'98KQA9SQ9BKN3Y(# + 4"[#@AbQB113*,d838'8)#5J,J'!'2Q!DE'C9ZD#40N8h**N#,d!"U"!&*2Q8Tj% + DUp%DY3)EXQ&BG"0H&0-E*D8$aB%+8!!'f[GQMbN(!L#CCL!%Z10lrS!0lm%$F&N + %6Z!DUMPC'S"B"k)%)("C`3PSM88J*X*CGK1F4E)E[Z%"2r8ClcJB3T!!M[%&$[i + !$1Fd8"6!+Pp&!IL9NkQ`"i(e'K5#!BRK)(bJQ6He%&a!)D"*"r@"#R1!PB'!P@Q + !P493(jG*P[j!)IT!)GU3!!U0J+$BSU!-5L(U!+&F)"RFd!@5!3jD!"Tf!aI3`"` + 2)%`9NKMPZ$pQJ!!KbJe&!JBGKaNZ#JbrXcp)%!c5!!L&@!A2T$VNB!8pqJrS%+, + DF!9"+JiKkJe!DU,Q3#&)qLMCU4ZTj"LqF'J4NKL,35(+N!!+F##8mrl#PIb# + 8!S%$F'!!j4LQCQ!#ZA!Ac#!@@#N#6NU2#K#P448!H)#9)h"SB%!,B+S-&')-&1) + 2UG!Nh3)+EIS2aQ!'QK#LrM!&3,!'NV#2eZ%'M"#3!$!`N!!'8*!!"+%!rd!)RhT + I+%Sqja+Hqj0a[eQ@#Y#L2'UL2aUNk$#R8!S-JUB,!1!2I"Sa2U!%j0-'%@-$j#J + CbQ!'%F-#3Z!+r`"ZE%!KmT!!#R)3)@[b$r,JS+M3#N*T"G#+'I)3VID!#S&!J@C + J"%k+#Y+''I63UMiDS[3J"E!kVU63!j*"$fB'Vp+DV1S+#4SU6$C+Uf5T$Vk"$X8 + 4)DN`"q$+#+2K$ki3V'TkUk53!+hrS)f5m5mXF'+*+JaQJ!)-F!6LB3BLi,$#%+h + 8N!!+(N#QrS!(NE%rF%!'fZNB3S"8#N"99K8VYqS&d3UD!@SISZ31BI)2U93MH[) + 2kS"I2V"&-bDJ"#UK@5SC3AXpA`1K##THr8SKr%!Kl1#dQ-%2'HYl8C)ElK9H6@C + 9Bl"P22Ne[N%"-`3"j&SF+[B2iX"Lm,#0'$#d!1!!iSJ!jJ-2-*Y$LT!!PMPd#-' + "#U13!,ArF!EUGJ"&%JL-``#eXQ@+&Jc')!)()!Nk'J$PN!!)1DS$!@!3#d%&3,! + BQNX!4VSBU$!*5'!-,i!Z8bS!4N#1&""$ac%G`$83!J!G3Y0j$)!+K)!%aI!#"9" + 8m-HkVSXFXaZldm%FYIZIK$#Hrm!0,"DdFi%"iXJ!jZ1[YLS$rh%'(AXD#i!+DS! + $R`#YflX'18"&!K!K#j)YGkS%92!%m48M&Z+cAa@Vjc!!Bq8M3#)N4')N!0!"c*% + !Nm'rcI%2m3$!95#Y!0`%rc!2!&`%rd!2!-`%+3I!9*!!V!!X"jN"`'4JCJ!m"rq + !FADJ*%cL**Ya"Lbc*)"J!R5`'8T#")"3+e0J"2U""FqT"*!!F!B"KdX%`!j!X"N + "-AbCdJ*3m!rX!!B'm*a!,-4+J+cXJ&-JJ"RX)!F5!!f"d$U2k$B3!!ZB!3pQ`!% + 1'kZ5JEF!3&c%j4ZlfLe5)R9@JL9D`L@#!&m[!JcrJ!he&4"eSLCXiLC`)LGdSPp + hNLF!e5DhKhSBJ!4ZN`%*!SX1F-J'`&bN`!-`#JU1c!#+c&bQi-J#)!SmS!$6q!& + l!`'PY)EUq4E1J))am#E-L!'PM%TGPm6UF4Y$N!#,(&!RF'!"ARBAcL"fqMTkAR" + V8,!U5QKIi$)&9+"*#)2($#!%%5!T)Q!TQ3)$'&#MlQF"XJ!%BL!"ZD'(L3-"'"! + 0`!!'pT!!HZ`kHkIb"Eh-+T!!q)SdGJDTi!kS8KcQ["X%%)Y!-)ZeH)Zj'!#lf)Z + rD#2#5)c'L)`%X3$HN!!H!d!)$c%j0N"2rb%%Ke-&69!%6%!&&p%HcSG$%S"$&)" + $&S"$a"B3'Y")3*!!F3-8!'S!Sb00JR@U"`'J"b)h3!+!!1!($1fd+5q3!!!!*3& + 1!!PLq!d$!!!ra5-#XE%%m!*r`JrE)k6J"lhkeBjp`3ra+"JE!!F1F%NRS")8!!, + Z&a$SJ#!JJ)m8J#PHM3,DPjm!3!h[ih[D)358)!6!C3"pYMpA#V88JJk0F3#'N!! + $NK&c#-!!ER!!%F-1kpX'+9@DC[!'E%!'&$)QZS!!@,JK!U*T2,aH,'#q2$#+U&% + 'H%!(EM"L[k8HRDd!(N81'M*9!#")#S$AbDSH`eQFajQDX6&C4-#F"1+F8b!#6)! + &L5#GQ`8+eANR+!TFmGa8hN8!KjZi1!!)-$$F45)($$!-e!!*J5!#!&!1L#$&HUC + i3,B"TJS"m48ai("1lJ`0L"!Imr%%8'#F"'%Qf`hH6m!UL8$H8J!&D[E3!D(HEk, + ,lGcHd+!)m#h-f&F&"PMIEc'ejq"2G8Y@NV`+!0#k"V$GB1!$6(de6cf2hU8"Rl1 + (#2!j)h!'#Q8"`A'Rc1#b(ckP!)!)a4%Lr!#HpphG$FcHV,))m$d%l6h-l#[JI1* + 2-kB%MFEJ$[ii`%8"*U"p#e#Up`d'XIcMG`)#5'iL5$i#Edd"fmhLT%61q[hHmL% + &3m!%6c!&fB'09`1h-iBQNS`+#hiZF$!*`1BCE`*&a`,N3QlQD"i3pJ"K(-!A9`- + $%+"H5(!%3R!%!R!)D(dQec00+8'M21"l`J!%Z3%$!H!)6A))C[i2113,#1$AkqA + @NKi39(B%$!!&!I!CZ(F%+!S&Ei$Te5D`P+!$(i!D-8%%U2%59L"PMN%(YA*SE#! + rNQi(Uid%aSQFXB'INp+C*1QF4b!#9+$E*'NL@G9C@BQ9X(#6UB!*5Q!%)[J$KkN + *)(!%0r"h"*!!lD1qYH&hG!G"h-#!Z+KN!mJplX[Gh0-!hG*0h9*m!h[cAJ#J[(6 + YXiC3"bNE"R43"ZRp&ZiJ&r3E[8UJi!aqjMMN#Pfpi'*Y8h#qQ,qY(@BHIJ(45hI + Ke')'49GECZk3!!V'%+,f!![!*3!VUUk`3!A$apEL`E9L!&hL`9aFL`@ScJ1VcJ1 + YrZSI%HXNVJ@'YSDhRKJ*0jbU`4Uq[TVk`3#!pTU0%3$H8"c@(Ze+F!69IJ#TS!Q + lYI,erXB9NLH+3!C[!!9DN3C[J"&Mm1rR!lFUi"`3i)fS9,IQ!`Kq!!#!@2$l)j- + !J!bjd6SJd!)3E!)pJ)m)m!mUS*XY%%e%N!#U%J1Q&$"L5bm0)483Q!!"l!N)l+T + H0J80Kp!k*T!!pkTcq#MRHc#Jq)c['!Lb)@,"!*K[+DNA$9H0qSHJqXLK!e*!!C, + IC*@[[jHIqDTM!Lf!MjlUqEkAq)r!Rk-I!&S38L#3!2ZU$`'XVraZ%rZcArZ8$`6 + UaIQl)`)-)!fC(deq$rL#hr[lm`qH,a!5NfkmJ+`dB!CLS![)LJ0Q`!9+F!KRN!! + XVVrmc9rrcep!X`qY$2!$"`(6NJ'Rf5T8J&cdaMpi"RcSFm3!-k!"c"GQ%)!!`!k + X,c$!!2KI+VJ%Z@%#ZJ!,H!Q3!!XB1$UB!3C)!FN!!m$Ila0pBDbi!!")-0SL"Kl + i%Lq#22Q$2*%)RJ!F+!0Zi!QN"5PJ"'bFS%X6RZQ1kCFi-5IU'*k!Ak+-P1NAI`) + +!S#q!QhMM!U3!*!!Vc,+RN!)-'Ae**8a!'6KDVT1&p4ZC)i$J!)&S+mN!"j$!$+ + !c%fKAIB&"JTS3cYI!!+S(61A!%3"bj%I#F!82,L$mX[q!4q3!!X23+QT"`5R!jb + $"@"l%N!)%!"Sa3-+ff'M%(bJ-3J!6A"L1%36mi14lIhi##83caVJBqPG"Z!$U,h + k%"ab!bSB!6f!LR3d"m-!$%%E#!2&D$qd`RlA"Z"!S@L&F%!1P!%cJ&0D)@E6E'G + !"E6#-A#-f!$fDS9KS!fiJ6T`"M4!+raRG)#bi%+e%!h*)-Ta"LXR)'3@UD%k*P8 + 4'%9QJ!6d!$bJ!,$!2m!%iHNIJ"F"d$Td3CN""+2$$[i(-m!'k"8Yq!H@316d!!C + Q#Fj8kb!&C8BIf$P3m!k0M$a%*8G!4Yb'U'F'F%"M`LeajQUB!@-P'F!,0i3,V3- + @[%04F!$QSGG"9YUJ-q!!C'8*6!")V"*qS"S3-BBS!&*L$p"B'##q`)0r3!E1dbN + C2I[0#)J-)Q!%f0G(N!!#"%%*!!C(X!BQcJSF"8C!6[@D6h!+M-!X3!DhiGDJ#Z4 + 5dd!"*0K"$DJ13+*H%`$N&"%E!"0J!3L!JG"V))!i!!+3!%S)B)&hFM9NJ2#+4kj + J"U!FIl!3'!!Z+8X*B$mSJ9f#013L@K-!3R&3V)'P-8F@JP"F!#*!$C!!!,Qi%"D + #N4-#DD!ZiK+1J!$F!!3B2Sba@H`E!m!BHjS!J)cDJ3%%LV(i!Yb!!ZK!RBGG6B# + pF3!#)e&d!)"#1b$'a$%"#Z0H``-ri"m-#M&J!'TM8%X!(8J!H)!JS)+f!$)K!,! + !"&`"AX32T%!3Q!'93`%S!3bd"M$!"3S!(fJJ2!!'-"$!MQF!$0aJ!K`,[pB!CJ" + JJ!"c5bJ1!([3"SJ!D(3!b)3(Y*0mjY5H3!`JKeM!Rm4$-"!1Bm#aS!()JL-b`"" + `,,4!38JM48$0,!%!`!(#Ladm&c2J@&L!Z693p!!)5!+hKJXm!4r!#p3")D"#CU) + aj4#QD!3fKBJ%"Dd!+FD#Em$KQKJU#3@Yi!b+!%5!ABJM!!JkkL!+L!!f)3X`3H* + 3!MlbSYQ$8h-QTJ%dS%)bdJ[e+#`#hNL)8e%(8J!-Z)1)3Y(#cbXF!mFL)*!!J6Q + 3!!IQJ"dJ#)JJ&lk"XKF3*)%CJ!0DN5"iJMK!"T)I38!(Dd!-Y-PTT!(i(4[!4`* + "#,5"0T!!*J8#'C!!!mP`q`3!4-!'!+@[%JL)3#+%&c!J#!52!%KB")!"4-Bkd-S + NJ+38!&m5!83*GNA%1K!$Q!9F!"!)M(C6%)5%&K!B9J$e#)NA`#NMKK)3MGUKmjb + "2a%S#-"X$"C23"k-)J!`$di!$,J!,J!*l+-2%)FX`$lk!A%)!Ka,(-$KKL@c4!" + Fb`%XbTHe'H(![k&h!J19i%EGk!MFJ-9""555"1!HQ,)+"N"6&*%$J4BJJR04*EK + @%B-T(1&J1B2J1"ce!E+3!&-5)!lG+QNJ#b+-2BJ%b3#V(5aC!"E&)KNk!!5J!## + !"!!!FX0d"%"V`!*Faq`B4VLM3&K4mBJE3!"F3L9Z&5'!PD4aFkK+"K!,YU"!S"X + QF`#d!3)!UES@aEXh6J9F0N9a+5*4`5-iPd)#!DM,cK#I,)$0E!S(+b8&K#%3FRE + P!aJ!-F!&f!!FN!!d"836J)9T`!h3J6F`"p!!#+!#DD!0P)&l`3E5!!kN!bkJ!D3 + #S%%9V!*@+"S6*@PBP,13!"E@!N'`!6@!#U#"V@NfU@6DV#KNiD+dc6,3!*lQ')L + D8l0UAXfXZ6@(30ImQP""D4)%!4$S''5V)`J"3&b-!)G`')b!&#J#2C!!)"`'JR! + !B"e%)!++"`E%!"N`!fK!$E!"0`!(")h4@6T2CqTFRD66G+*1e5Nk3B$SM*fZNhD + b6YRj1QpRkjbGUj-JK!$EZ6Yc*qcmREfcH!*2d5NmL5IZA*l+-hNqcq6C2+9!'CJ + $@L%VY-R#*JG!3"h!RLEM+p#"ZAN[2JE9e!V1)5"8!!S`"FT#'5#')#!-$%kYf6l + P3%34Q[XM!E421N!(SZBCQ!2*J#!N!!5`2qHR[`X)!a4VDNdQm!BZ`Z*8!*SX)&L + 0XZ33*%"Mc!h)!!!3JJ#!(X1,"p#J!H"0",@(%!$!L1)j#A34!2`"#MU+4Y%[m!H + M#"3)!"F+3eq$$AfK-933M#*AS!Y'N5T3"6ZdK`+!(aT%BkJ`-+*&G)J#83$!3h0 + S%L@L6&5)JJ)G'N9pk"*YSJ"JLJ+#!H"l`!%*0D%$`)[5K"5k3J1#laP&Cc4Lr!- + dZNE9+"YpSfidMUE41GT'k5JFYD0bY)lUd6Zk4r2S&ZfL%Y6l1*rJ*dLK#M#!Bp! + Rq#R548T"M3)MID50FbMm!cp!55ZT*EfNM93S6&*)ZNMp3#B0#TY8&iM588T+DC! + !*bd+Qj56"Vp65K3Qk59pTCAdN`+&9+T+0bNUpD5B0*I+dTZ`56fTlm'PUp5@YP* + JDNT$D5rGT4,KQ2j5@JT-EkNa*DE(e*Rk8Q8D6BHT+ifPel5C@P0-QNf&U53&TXY + dQQV6ErT-bbNV*DILP*Pk8df+5beT0KfRl&5GTY0c'NmpD6'eTp88R3E6HBT-)d) + [GDHk9*VZdi%U81rT2c#S!M@F%Y4Y#P!"DMpe#,98P8B%h2*m(X"$G3Mhi!j)SeQ + k5$FU4,#SM&3LC03l3&*,UNI&U)cd(Ta8JR!2q!%cH+N[9D9'K(Z3!&*ADN!BU5@ + 9T0T8!%"6&kP-K3MhB+3+eCdD9$-$63fU4,@P"P9qJ&4RkP&pUNQ9U5V9RrS3LUT + 9TDSBGD6q!j++99QU9Z@U5G@S'Y@SZP5E+P"pUQ29UA*9X1T8aDTCVDT69DU'eDZ + D90IU(HLU0a@Y[Y@X+PAPDPZPUfVeVV,9Kk"+9bS3++%(!"iJ!!5`!0$"BRd!q!! + ")!)&J!SN+f@eV*9eXQE@$m!2%#XmJ+bJ&4q%eY%U@NXVDH@XddJL(&)6bNY$UMq + &TEYdNTC5HZUBB+XrKD5[PC*HdpMU"h3",[@Y[&@haY,A#Pal+fdeSl&dZ%)%fIT + EMf[%5+kkPEJfeq$D6SpV,Ad)Zp)mQ"k(!&)c+8leU2IJT4i$m'T5(92`)kmC&E` + HJhX`APQUB&@[l"@pDP5@ZPlEkdepVr3e[VVAp"S3ZQXN*3%8Vc[)JJ!`#@,P#(8 + )J1!"9)5,N!!43!$fj*rqXdVqKjl'AE')'3%!)J#e2!3,+Ydq3!!J!-#!)`5#$8Z + '`PJ!Q"`3JEKX`5-3!("!RE'K#i%4#!"'m'%"J#))!#dJ!0b##"!!m)NJ'!J40#! + )!'JJ!)!!*J!!*U$')J)F'`"`3BfpX6Rf&MaC*RX,K1`f@!KA9J"Nf5ZlI`"!0bK + ,J)!#"!390!#U3"@)!"&J(PJ(4)!)IUJ+HJh-#!$8Jl*8"Hj"3&!&FrBe6%J!X!r + q!3'S"e8J#R3L08X!*+XL8!@[S-qq"[3)!1c"2`J!p3!+f0N!S!"HJD0p$@+@crk + $-RYQ)d!m@,0Y9K8S@N!3CbpY&9!j3r65!J),#J$`39Q#!%(S0GK,pH"UAm-$'!L + !B0B'J(F!CQ-Y))LJV[D8e&T!`'KTDN-#"#SR!!5!1JYQpf`rm,1!9Y"#J&05D"( + "SAd&chE4"J4A'`$d!5T3X`'J!Rb"BCYTRbfR4E-YB3#`f4qDEBRYYRfd3"6F,YY + KZfIp!E30Y*fS*96EDfY[Ad1ArE+[B3,J@Pf,$b+)Vr@e!PI@6U1#qaS1EJ64XPJ + fiN,FLAYP23"(`!(JJ(%-J!(J#$#Za[d4F3!B'+4"iA%A!XF0BabK#%!!M8X!cY[ + +Y3i$3!3S!K$`F51"bQ8F!S!!4!%!B(%"`-fe$J6!#raFcL-!CZl)YEN[0qIZh*i + lG(AZd2f`4RFK1)+IUh4jEXTpZ32!k@,G(4&e!4$9eEP@eqGLADhlF5&!ed@k1"I + XpYb5Zh%lEXDe$N3Tj)jFYiYc6bl&PEKE0SX#J%&!3CPX#`!!X!!!h!!!d!X#3!E + JX6i@b$U%)9YNMq`($Ea#Sr$QMm!lH!X[mU'mK0I`#YPaX"!iV`$J["UJ``J*!"! + "!J,SE"Clil!5!(Xj!"KY!+#,'F#[%B'"8(S"!"ZJL`-Jp3D!)04kTa&Gr!!E!!! + !JA(J2SJ[&CJ(K!!,M)0(J!F+'Ki!"`k!#*5$5-!VS`'[M"%m9`-!J"a3HL-!"3! + #4B!#%!%b3!5J`1aGK"!J!K3"#a!&!J!&D,m4J#jk!1eE!$jY",J!`#$m%J!L3!5 + F`2QY!R#P#0!$([Yq!d$mcEiqPrD+f5*!!rB[%3J#raH,T!!#3)#M33#)!Eqh!`! + !(!!2J%%$Q!$!J!K-!f*!"'D!*`#Ga)!+I&B)3!mkc$ai!J!!'J#$m*!!!'),jjP + 'M+-'@iFik`"`,ZI&*hbAqh!!!I!I,)$))"N%34F-[Fm6%)b"-i*'"%%D`$H#i!f + S*%&3"ip6cV'fDI3Cr@ph%!J1`(*L6MSTc$6*0$)"C6Kr')!6H`5FJ"6i`J(!&F, + #,"N!*)%EN!!$a(!DH3,*1Be8JDlJ&G2)&[aK!#N3K)'ZQ!168b!iJd-F+!5#0MM + %K$J!Q!-LS18dPN#3!!G%J'6!BAm!"44&H!J!!N#6PB#!m(FL`LK5!(qR!'6*J," + 4D4mU)5!1iHpkJ,p$!Dk43`J![ZH%'%M#ZM[14#M!VVRi6&aCc5NlHM%)#!H8XaM + RMa!`%$3RF8%"bpKNXQ,L3SM-5(M3R"p83*L4KU!j$8!`$J'HJ()@J'mm$#MR"&h + 'h)"bFY&H(!,8!H98Sm[BcQT1H)aKQ`8a$XBL)-J#!'Q%MeNY+eE''"DAh10H2!+ + mbd$1(lib'3IM&%#)rr&#YX81Z4HV!1D!B)1a3UM)[AJfBC%$L%-)"-'i"Fa + D",S"(eT%QfJ0c54,Y#fCNL(D5Ti$,INNEdN%3!4fSFTJ!h4J$M5JC&J'#)!@1"T + P!%Qa!!!: + *** aarp.c.orig Mon Aug 22 18:51:29 1994 --- aarp.c Mon Sep 25 09:16:42 1995 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.1 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.2 $ * */ *************** *** 73,78 **** --- 73,79 ---- void aarp_ifnode_inuse(), aarp_mnode_inuse(); void aarp_respond(), aarp_dequeue(); void aarp_insert(), aarp_glean(); + void dumppacket(); incr(uarAARPPacketsIn); *************** *** 134,144 **** && iflist[ifn].state == ADDR_PENDING) aarp_ifnode_inuse(ifn); if (iflist[ifn].mnode[pd.dstNode].state == MNODE_PENDING) ! aarp_mnode_inuse(ifn, pd.dstNode); } /* we are required to "age out" this entry */ if ((aarp = aarp_find(pd.dstNet, pd.dstNode)) != AARPNULL) ! aarp_delete(aarp); /* fall through */ case AARPReq: /* defend address if one of ours */ --- 135,145 ---- && iflist[ifn].state == ADDR_PENDING) aarp_ifnode_inuse(ifn); if (iflist[ifn].mnode[pd.dstNode].state == MNODE_PENDING) ! aarp_mnode_inuse(ifn, pd.dstNode); } /* we are required to "age out" this entry */ if ((aarp = aarp_find(pd.dstNet, pd.dstNode)) != AARPNULL) ! (void)aarp_delete(aarp); /* fall through */ case AARPReq: /* defend address if one of ours */ *************** *** 158,171 **** && iflist[ifn].state == ADDR_PENDING) aarp_ifnode_inuse(ifn); if (iflist[ifn].mnode[pd.srcNode].state == MNODE_PENDING) ! aarp_mnode_inuse(ifn, pd.srcNode); } /* response to probe or request */ aarp_dequeue(pd.srcNet, pd.srcNode); if (new = ((aarp = aarp_find(pd.srcNet, pd.srcNode)) == AARPNULL)) if ((aarp = aarp_new()) == AARPNULL) ! drop(uarMemoryError); aarp->net = pd.srcNet; aarp->node = pd.srcNode; --- 159,172 ---- && iflist[ifn].state == ADDR_PENDING) aarp_ifnode_inuse(ifn); if (iflist[ifn].mnode[pd.srcNode].state == MNODE_PENDING) ! aarp_mnode_inuse(ifn, pd.srcNode); } /* response to probe or request */ aarp_dequeue(pd.srcNet, pd.srcNode); if (new = ((aarp = aarp_find(pd.srcNet, pd.srcNode)) == AARPNULL)) if ((aarp = aarp_new()) == AARPNULL) ! drop(uarMemoryError); aarp->net = pd.srcNet; aarp->node = pd.srcNode; *************** *** 225,258 **** int ifn; u_char node; { ! void aarp_enqueue(); ! switch (iflist[ifn].mnode[node].client) { ! case MNODE_CAP: ! if (iflist[ifn].mnode[node].state == MNODE_PENDING) { ! iflist[ifn].mnode[node].state = MNODE_UNUSED; ! iflist[ifn].mnode[node].client = MNODE_UNUSED; ! } ! /* ! * pick another node number ! * (on the same net) ! * ! */ ! for ( ; ; ) { ! if (--node == 0) ! return; ! if (iflist[ifn].mnode[node].state == MNODE_UNUSED ! && iflist[ifn].node != node) ! break; ! } ! iflist[ifn].mnode[node].state = MNODE_PENDING; ! iflist[ifn].mnode[node].client = MNODE_CAP; ! aarp_enqueue(ifn, iflist[ifn].net, node, AARPProbe); ! break; ! default: break; } return; } --- 226,258 ---- int ifn; u_char node; { ! u_char client; ! void log(), aarp_enqueue(); ! client = iflist[ifn].mnode[node].client; ! ! iflist[ifn].mnode[node].state = MNODE_UNUSED; ! iflist[ifn].mnode[node].client = MNODE_UNUSED; ! ! /* ! * pick another node number ! * (on the same net) ! * ! */ ! for ( ; ; ) { ! if (--node == 0) { ! log("OOPS: no more free multinodes, continuing."); ! return; ! } ! if (iflist[ifn].mnode[node].state == MNODE_UNUSED ! && iflist[ifn].node != node) break; } + iflist[ifn].mnode[node].state = MNODE_PENDING; + iflist[ifn].mnode[node].client = client; + aarp_enqueue(ifn, iflist[ifn].net, node, AARPProbe); + return; } *************** *** 346,353 **** struct pd *pd; u_char *addr; { - register u_char *pkt; u_char buf[128]; switch (iflist[ifn].phase) { case PHASE1: --- 346,354 ---- struct pd *pd; u_char *addr; { u_char buf[128]; + register u_char *pkt; + void aarp_write(); switch (iflist[ifn].phase) { case PHASE1: *************** *** 405,414 **** u_short function; { register u_char *pkt; u_short srcNet; ! u_char srcNode; ! u_char buf[128]; ! u_char *addr; srcNet = (function == AARPProbe) ? dstNet : iflist[ifn].net; srcNode = (function == AARPProbe) ? dstNode : iflist[ifn].node; --- 406,414 ---- u_short function; { register u_char *pkt; + u_char srcNode, buf[128], *addr; u_short srcNet; ! void aarp_write(); srcNet = (function == AARPProbe) ? dstNet : iflist[ifn].net; srcNode = (function == AARPProbe) ? dstNode : iflist[ifn].node; *************** *** 463,477 **** * */ ! int aarp_write(ifn, buf, function) int ifn; u_char *buf; u_short function; { int fd; ! short cc, len; register u_char *pkt; switch (iflist[ifn].phase) { case PHASE1: --- 463,478 ---- * */ ! void aarp_write(ifn, buf, function) int ifn; u_char *buf; u_short function; { int fd; ! short len; register u_char *pkt; + void dumppacket(); switch (iflist[ifn].phase) { case PHASE1: *************** *** 524,533 **** fd = (iflist[ifn].aarpfd >= 0) ? iflist[ifn].aarpfd : iflist[ifn].etfd; ! if ((cc = write_eth(fd, buf, len)) != len) if (debug) perror("write_eth()"); ! return(cc); } /* --- 525,534 ---- fd = (iflist[ifn].aarpfd >= 0) ? iflist[ifn].aarpfd : iflist[ifn].etfd; ! if (write_eth(fd, buf, len) != len) if (debug) perror("write_eth()"); ! return; } /* *************** *** 538,548 **** void aarp_process() { - int i; u_char node; struct aarpq *p, *q, *t; void aarp_lookup(), aarp_enqueue(); ! void log(), zone_getnetinfo(), cap_start(); p = aarpQueue; q = AARPQNULL; --- 539,550 ---- void aarp_process() { u_char node; + int ifn, client; struct aarpq *p, *q, *t; void aarp_lookup(), aarp_enqueue(); ! void zone_getnetinfo(), cap_start(); ! void uar_register(), log(); p = aarpQueue; q = AARPQNULL; *************** *** 555,574 **** if (iflist[p->intfc].state == ADDR_VALID) { if (p->count-- > 0) { aarp_lookup(p->intfc, p->net, p->node, p->function); ! } else { /* probe unchallenged or no response to request */ ! if (p->function == AARPProbe && iflist[p->intfc].net == p->net && iflist[p->intfc].mnode[p->node].state == MNODE_PENDING) { ! /* multinode probe, start service */ iflist[p->intfc].mnode[p->node].state = MNODE_VALID; switch (iflist[p->intfc].mnode[p->node].client) { ! case MNODE_CAP: ! cap_start(p->intfc, p->node); ! break; ! default: ! break; } } ! /* dequeue the request */ if (q == AARPQNULL) aarpQueue = p->next; else --- 557,587 ---- if (iflist[p->intfc].state == ADDR_VALID) { if (p->count-- > 0) { aarp_lookup(p->intfc, p->net, p->node, p->function); ! } else { ! /* ! * probe unchallenged or no response to request ! * ! */ ! if (p->function == AARPProbe ! && iflist[p->intfc].net == p->net && iflist[p->intfc].mnode[p->node].state == MNODE_PENDING) { ! /* ! * multinode probe, start service ! * ! */ iflist[p->intfc].mnode[p->node].state = MNODE_VALID; switch (iflist[p->intfc].mnode[p->node].client) { ! case MNODE_CAP: ! cap_start(p->intfc, p->node); ! break; ! default: ! break; } } ! /* ! * dequeue the request ! * ! */ if (q == AARPQNULL) aarpQueue = p->next; else *************** *** 585,618 **** /* * probe for interface addresses ! * start multinode probes when interface address valid * */ ! for (i = 0; i < numintfc; i++) { ! if (iflist[i].state == ADDR_PENDING) { ! if (iflist[i].count > 0) { ! aarp_lookup(i, iflist[i].net, iflist[i].node, AARPProbe); ! iflist[i].count--; ! } else { /* adopt this address */ ! iflist[i].mnode[iflist[i].node].state = MNODE_ROUTER; ! iflist[i].state = ADDR_VALID; ! if (iflist[i].phase == PHASE2) ! zone_getnetinfo(i); ! /* check for multinode clients */ ! if (iflist[i].clients & MNODE_CAP) { ! node = iflist[i].node; ! for ( ; ; ) { ! if (--node == 0) { ! log("OOPS: no more free multinodes, continuing."); ! break; ! } ! if (iflist[i].mnode[node].state == MNODE_UNUSED) { ! iflist[i].mnode[node].state = MNODE_PENDING; ! iflist[i].mnode[node].client = MNODE_CAP; ! aarp_enqueue(i, iflist[i].net, node, AARPProbe); ! break; ! } ! } } } } --- 598,643 ---- /* * probe for interface addresses ! * start probes for multinodes when interface address valid * */ ! for (ifn = 0; ifn < numintfc; ifn++) { ! if (iflist[ifn].state == ADDR_PENDING) { ! if (iflist[ifn].count-- > 0) { ! aarp_lookup(ifn, iflist[ifn].net, iflist[ifn].node, AARPProbe); ! } else { ! /* ! * adopt this address, register NBP name ! * ! */ ! iflist[ifn].state = ADDR_VALID; ! if (iflist[ifn].phase == PHASE2) ! zone_getnetinfo(ifn); ! uar_register(ifn); ! /* ! * (re)start multinode clients ! * ! */ ! bzero((char *)iflist[ifn].mnode, sizeof(iflist[ifn].mnode)); ! iflist[ifn].mnode[iflist[ifn].node].state = MNODE_ROUTER; ! if (iflist[ifn].clients) { ! node = iflist[ifn].node; ! client = MNODE_MIN; ! for ( ; ; ) { ! if (--node == 0) { ! log("OOPS: no more free multinodes, continuing."); ! break; ! } ! if (iflist[ifn].clients & client) { ! if (iflist[ifn].mnode[node].state == MNODE_UNUSED) { ! iflist[ifn].mnode[node].state = MNODE_PENDING; ! iflist[ifn].mnode[node].client = (u_char)client; ! aarp_enqueue(ifn, iflist[ifn].net, node, AARPProbe); ! } else continue; ! } else node++; ! if ((client <<= 1) > MNODE_MAX) ! break; ! } } } } *************** *** 810,829 **** aarp_free(aarp); return(next); - } - - /* - * AARP dump signal handler - * - */ - - void - aarp_dump_sig() - { - aarp_do_dump = 1; - (void)signal(SIGQUIT, aarp_dump_sig); - - return; } /* --- 835,840 ---- *** ddp.c.orig Mon Aug 22 18:49:12 1994 --- ddp.c Mon Sep 25 09:17:00 1995 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.3 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.4 $ * */ *************** *** 30,35 **** --- 30,36 ---- extern struct iflist iflist[]; extern struct RDS RDS[]; extern char *stats_msg[]; + extern struct timeval tn; extern u_char buf[]; /* *************** *** 175,183 **** --- 176,186 ---- register u_char *pkt, *addr, *ethType; struct rtmp *rtmp, *rtmp_route(); u_short cksum, chkSum(); + void dumppacket(); void aarp_glean(); int ddp_for_gw(); int ddp_for_mn(); + int ddp_is_gw(); void ddp_route(); void ddp_gw(); void ddp_mn(); *************** *** 255,261 **** pd.data = pkt+13; if (checksum && cksum) if (cksum != chkSum(pkt+4, pktlen-4)) ! drop(ddpChecksumErrors); break; default: drop(uarBadLapType); --- 258,264 ---- pd.data = pkt+13; if (checksum && cksum) if (cksum != chkSum(pkt+4, pktlen-4)) ! drop(ddpChecksumErrors); break; default: drop(uarBadLapType); *************** *** 271,278 **** * check if we can see our own transmissions * */ ! if (pd.srcNet == iflist[ifn].net ! && pd.srcNode == iflist[ifn].node) drop(uarIgnoreSelfSend); /* --- 274,280 ---- * check if we can see our own transmissions * */ ! if (ddp_is_gw(ifn, pd.srcNet, pd.srcNode)) drop(uarIgnoreSelfSend); /* *************** *** 289,296 **** */ /* ! * packet aimed at gateway or ifn is ! * non-extended and short DDP packet * */ if (ddp_for_gw(ifn, pd.dstNet, pd.dstNode)) { --- 291,297 ---- */ /* ! * packet aimed at gateway ? * */ if (ddp_for_gw(ifn, pd.dstNet, pd.dstNode)) { *************** *** 300,306 **** } /* ! * check if packet for multinode client on ifn * */ if (ddp_for_mn(ifn, pd.dstNet, pd.dstNode)) { --- 301,307 ---- } /* ! * packet for EtherTalk multinode client on ifn ? * */ if (ddp_for_mn(ifn, pd.dstNet, pd.dstNode)) { *************** *** 358,364 **** } /* ! * check if packet for gw interface rtmp->intfc * */ if (ddp_for_gw(rtmp->intfc, pd.dstNet, pd.dstNode)) { --- 359,365 ---- } /* ! * packet for gw on interface rtmp->intfc ? * */ if (ddp_for_gw(rtmp->intfc, pd.dstNet, pd.dstNode)) { *************** *** 368,374 **** } /* ! * check if packet for multinode client on rtmp->intfc * */ if (ddp_for_mn(rtmp->intfc, pd.dstNet, pd.dstNode)) { --- 369,375 ---- } /* ! * check if packet for EtherTalk multinode client on rtmp->intfc * */ if (ddp_for_mn(rtmp->intfc, pd.dstNet, pd.dstNode)) { *************** *** 433,438 **** --- 434,476 ---- } /* + * return true if valid interface node + * + */ + + int + ddp_is_gw(ifn, net, node) + int ifn; + u_short net; + u_char node; + { + if (iflist[ifn].net == net) + if (iflist[ifn].node == node + && iflist[ifn].state == ADDR_VALID) + return(1); + + return(0); + } + + /* + * return true if valid multinode node + * + */ + + int + ddp_is_mn(ifn, net, node) + int ifn; + u_short net; + u_char node; + { + if (iflist[ifn].net == net) + if (iflist[ifn].mnode[node].state == MNODE_VALID) + return(1); + + return(0); + } + + /* * check if nets match according to the DDP rules * Net A matches net B if A==B or A==0 or B==0 * *************** *** 460,465 **** --- 498,504 ---- void echo(), nbp(); void rtmpr(), rtmpd(); void zip(), zip_atp(); + void timesrvr_atp(); incr(ddpInLocalDatagrams); *************** *** 490,495 **** --- 529,538 ---- zip_atp(ifn, pd); break; } + if (pd->dstSkt == TMLDSKT) { + timesrvr_atp(ifn, pd); + break; + } /* fall thro' */ case ADSP: case SNMP: *************** *** 502,508 **** } /* ! * packet destined for multinode clients on interface 'ifn' * */ --- 545,551 ---- } /* ! * packet destined for EtherTalk multinode clients on interface 'ifn' * */ *************** *** 512,517 **** --- 555,561 ---- struct pd *pd; { int i; + void cap_route(); incr(uarMNodePacketsIn); *************** *** 522,532 **** for (i = 1; i < MAXNODES-1; i++) { if (iflist[ifn].mnode[i].state == MNODE_VALID) { switch (iflist[ifn].mnode[i].client) { ! case MNODE_CAP: ! cap_route(ifn, pd); ! break; ! default: ! break; } } } --- 566,576 ---- for (i = 1; i < MAXNODES-1; i++) { if (iflist[ifn].mnode[i].state == MNODE_VALID) { switch (iflist[ifn].mnode[i].client) { ! case MNODE_CAP: ! cap_route(ifn, pd); ! break; ! default: ! break; } } } *************** *** 611,616 **** --- 655,782 ---- } /* + * handle timeserver requests + * + */ + + #define isleap(yr) ((yr) % 4 == 0 && ((yr) % 100 != 0 || (yr) % 400 == 0)) + + void + timesrvr_atp(ifn, pd) + int ifn; + struct pd *pd; + { + short len; + time_t now; + u_char *pkt; + struct pd opd; + u_int mact, diff, usrbytes; + struct tm gmt, local, *localtime(), *gmtime(); + struct rtmp *rtmp_route(); + void dumppacket(); + void ddp_route(); + + if (iflist[ifn].if_timesrvr[0] == '\0') + drop(uarNoSocketHandler); + + pkt = pd->data; + len = pd->dataLen; + + if (len == 0) + drop(ddpTooShortErrors); + + if (len > MAXDDPLEN) + drop(ddpTooLongErrors); + + if (pkt[0] == TREL) + return; + + if (pkt[0] != (TREQ|XO) || pkt[1] != 0x01) + drop(uarBadPacketHdr); + + if (debug & TMLDDEBUG) { + fprintf(stderr, "TMLD: %-5s Receive Timelord Request\n", + iflist[ifn].if_name); + if (debug & PKTDEBUG) + dumppacket(pd->data, pd->dataLen); + } + + usrbytes = (pkt[4] << 24) | (pkt[5] << 16) | (pkt[6] << 8) | pkt[7]; + + switch (usrbytes) { + case TMLDGETTIME: + now = (time_t)tn.tv_sec; + gmt = *gmtime((time_t *)&now); + local = *localtime((time_t *)&now); + diff = gmt.tm_year - local.tm_year; + diff *= 365; + if (gmt.tm_year > local.tm_year) { + if (isleap(local.tm_year)) + diff++; + } else { + if (local.tm_year > gmt.tm_year) { + if (isleap(gmt.tm_year)) + diff--; + } + } + diff += gmt.tm_yday - local.tm_yday; + diff *= 24; + diff += gmt.tm_hour - local.tm_hour; + diff *= 60; + diff += gmt.tm_min - local.tm_min; + diff *= 60; + diff += gmt.tm_sec - local.tm_sec; + mact = now - diff + TMLDOFFSET; + pkt[8] = (mact >> 24) & 0xff; + pkt[9] = (mact >> 16) & 0xff; + pkt[10] = (mact >> 8) & 0xff; + pkt[11] = (mact & 0xff); + usrbytes = TMLDENONE; + len = 12; + break; + default: + strcpycp("Bad Request", (char *)(pkt+8)); + usrbytes = TMLDENOPERM; + len = 8+pkt[8]; + break; + } + + pkt[0] = TRESP | EOM; + pkt[1] = 0x00; + + pkt[4] = (usrbytes >> 24) & 0xff; + pkt[5] = (usrbytes >> 16) & 0xff; + pkt[6] = (usrbytes >> 8) & 0xff; + pkt[7] = (usrbytes & 0xff); + + opd.lapType = LDDP; + opd.ddpType = ATP; + opd.dstNet = pd->srcNet; + opd.srcNet = iflist[ifn].net; + opd.dstNode = pd->srcNode; + opd.srcNode = iflist[ifn].node; + opd.dstSkt = pd->srcSkt; + opd.srcSkt = TMLDSKT; + opd.dataLen = len; + opd.data = pkt; + opd.addr = NULL; + opd.hop = 0; + + if (debug & TMLDDEBUG) { + fprintf(stderr, "TMLD: %-5s Sending Timelord Reply %s", + iflist[ifn].if_name, ctime(&now)); + if (debug & PKTDEBUG) + dumppacket(opd.data, opd.dataLen); + } + + incr(ddpOutRequests); + + ddp_route(ifn, &opd, rtmp_route(opd.dstNet)); + + return; + } + + /* * send packet via route specified in rtmp entry * ('ifn' is the entry or originating port for the packet) * *************** *** 623,636 **** struct rtmp *rtmp; { short len; - u_char dstNode; u_short dstNet; u_short cksum, chkSum(); u_char *addr, *pkt, *hdr; struct aarp *aarp, *aarp_find(); struct rtmp rtmpn; int ddp_for_mn(); void aarp_enqueue(); void ddp_mn(); /* --- 789,804 ---- struct rtmp *rtmp; { short len; u_short dstNet; + u_char dstNode; u_short cksum, chkSum(); u_char *addr, *pkt, *hdr; struct aarp *aarp, *aarp_find(); struct rtmp rtmpn; int ddp_for_mn(); + int nbp_filter(); void aarp_enqueue(); + void dumppacket(); void ddp_mn(); /* *************** *** 685,691 **** dstNet = pd->dstNet; /* ! * check if packet for multinode client on rtmp->intfc * */ if (ddp_for_mn(rtmp->intfc, dstNet, pd->dstNode)) { --- 853,859 ---- dstNet = pd->dstNet; /* ! * check if packet for EtherTalk multinode client on rtmp->intfc * */ if (ddp_for_mn(rtmp->intfc, dstNet, pd->dstNode)) { *** nbp.c.orig Sun Oct 24 19:08:00 1993 --- nbp.c Mon Sep 25 09:18:05 1995 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.1 $ * */ *************** *** 27,34 **** --- 27,57 ---- extern u_long uar_stats[]; extern u_long pkts_dropped; extern struct iflist iflist[]; + extern struct timeval tn; extern char *stats_msg[]; + int nbpOutID; + int nbp_do_dump = 0; + + struct nbpq *nbpQueue; + struct nbptyp *nbpCache; + + /* + * Initialize NBP data structures + * + */ + + void + nbp_initialize() + { + nbpQueue = NBPQNULL; + nbpCache = NBPTYPNULL; + + nbpOutID = 1; + + return; + } + /* * process an incoming NBP packet * *************** *** 40,48 **** struct pd *pd; { short len; char *nbp_type(); ! u_char *pkt, function; ! void nbp_brreq(), nbp_fwdreq(); pkt = pd->data; len = pd->dataLen; --- 63,72 ---- struct pd *pd; { short len; + u_char *pkt; char *nbp_type(); ! void nbp_brreq(), nbp_lkupreq(); ! void nbp_fwdreq(), nbp_lkupreply(); pkt = pd->data; len = pd->dataLen; *************** *** 60,79 **** if (pd->dstSkt != NBP) drop(uarNoSocketHandler); ! function = pkt[0] >> 4; ! ! switch (function) { case NBPBRRQ: incr(nbpInBroadcastRequests); nbp_brreq(ifn, pd); break; case NBPLKUPREQ: incr(nbpInLookUpRequests); ! drop(nbpInErrors); break; case NBPLKUPREPLY: incr(nbpInLookUpReplies); ! drop(nbpInErrors); break; case NBPFWDREQ: incr(nbpInForwardRequests); --- 84,101 ---- if (pd->dstSkt != NBP) drop(uarNoSocketHandler); ! switch (pkt[0] >> 4) { case NBPBRRQ: incr(nbpInBroadcastRequests); nbp_brreq(ifn, pd); break; case NBPLKUPREQ: incr(nbpInLookUpRequests); ! nbp_lkupreq(ifn, pd); break; case NBPLKUPREPLY: incr(nbpInLookUpReplies); ! nbp_lkupreply(ifn, pd); break; case NBPFWDREQ: incr(nbpInForwardRequests); *************** *** 95,100 **** --- 117,124 ---- * BrRq into one Forward Request (FwdReq) packet for each network * that contains nodes in the target zone of the lookup request. * + * Inside AppleTalk, 2nd Edition, page 7-10 + * */ void *************** *** 103,135 **** struct pd *pd; { short len, tuples, zlen; ! u_char *pkt, *ent, *obj, *typ, *zon, *zone_mcast(); struct rtmp *rtmp, *rtmp_route(); struct zone *zone, *zone_find(); struct zit *zit; struct net *net; u_short srcNet; void nbp_send(); pkt = pd->data; len = pd->dataLen; ! tuples = pkt[0] & 0x0f; ! ! if (tuples != 1) drop(nbpInErrors); ! ent = pkt+2; ! obj = ent+5; typ = obj+*obj+1; zon = typ+*typ+1; ! if (zon > pkt+len) drop(nbpInErrors); zone = ZONENULL; ! if ((zon[0] == 1 && zon[1] == '*') || zon[0] == 0) { srcNet = (ent[0] << 8) | ent[1]; if ((rtmp = rtmp_route(srcNet)) == RTMPNULL) --- 127,163 ---- struct pd *pd; { short len, tuples, zlen; ! u_char *addr, *zone_mcast(); ! u_char *pkt, *ent, *obj, *typ, *zon; struct rtmp *rtmp, *rtmp_route(); struct zone *zone, *zone_find(); struct zit *zit; struct net *net; u_short srcNet; void nbp_send(); + int nbp_invalid(); + int nbp_match_tuple(); + void nbp_add_lookup(); + void dumppacket(); pkt = pd->data; len = pd->dataLen; ! if ((tuples = pkt[0] & 0x0f) != 0x01) ! /* not a single tuple */ drop(nbpInErrors); ! ent = pkt+NBPHDRSIZ; ! obj = ent+ENTHDRSIZ; typ = obj+*obj+1; zon = typ+*typ+1; ! if (nbp_invalid(obj, typ, zon, pkt, len)) drop(nbpInErrors); zone = ZONENULL; ! if (zon[0] == 0x00 || (zon[0] == 0x01 && zon[1] == '*')) { srcNet = (ent[0] << 8) | ent[1]; if ((rtmp = rtmp_route(srcNet)) == RTMPNULL) *************** *** 157,170 **** if ((zone = zone_find(zon, zlen)) == ZONENULL) drop(uarNoDefaultZone); net = zone->nets; while (net != NETNULL) { if ((rtmp = rtmp_route(net->net_lo)) != RTMPNULL) { if (rtmp->dist == 0 || iflist[rtmp->intfc].phase == PHASE1) { pkt[0] = (NBPLKUPREQ << 4) | tuples; ! if (iflist[rtmp->intfc].phase == PHASE2) ! pd->addr = zone_mcast(zon, zlen); pd->dstNode = BCAST; } else { /* Phase 2, not local */ pkt[0] = (NBPFWDREQ << 4) | tuples; --- 185,203 ---- if ((zone = zone_find(zon, zlen)) == ZONENULL) drop(uarNoDefaultZone); + pd->srcNet = iflist[ifn].net; + pd->srcNode = iflist[ifn].node; + pd->srcSkt = NBP; + pd->dstSkt = NBP; + + addr = zone_mcast(zon, zlen); net = zone->nets; while (net != NETNULL) { if ((rtmp = rtmp_route(net->net_lo)) != RTMPNULL) { if (rtmp->dist == 0 || iflist[rtmp->intfc].phase == PHASE1) { pkt[0] = (NBPLKUPREQ << 4) | tuples; ! pd->addr = (iflist[rtmp->intfc].phase == PHASE2) ? addr : NULL; pd->dstNode = BCAST; } else { /* Phase 2, not local */ pkt[0] = (NBPFWDREQ << 4) | tuples; *************** *** 188,193 **** --- 221,228 ---- * broadcasts it to the NIS in all nodes in the target zone on the * destination network. * + * Inside AppleTalk, 2nd Edition, page 7-10 + * */ void *************** *** 198,203 **** --- 233,241 ---- short len, tuples, zlen; u_char *pkt, *ent, *obj, *typ, *zon, *zone_mcast(); struct rtmp *rtmp, *rtmp_route(); + int nbp_invalid(); + void nbp_add_lookup(); + void dumppacket(); void nbp_send(); pkt = pd->data; *************** *** 209,228 **** if (pd->dstNode != 0x00) drop(nbpInErrors); ! tuples = pkt[0] & 0x0f; ! ! if (tuples != 1) drop(nbpInErrors); ! ent = pkt+2; ! obj = ent+5; typ = obj+*obj+1; zon = typ+*typ+1; ! if (zon > pkt+len) drop(nbpInErrors); ! if ((zon[0] == 1 && zon[1] == '*') || zon[0] == 0) drop(nbpInErrors); if ((rtmp = rtmp_route(pd->dstNet)) == RTMPNULL) --- 247,265 ---- if (pd->dstNode != 0x00) drop(nbpInErrors); ! if ((tuples = pkt[0] & 0x0f) != 0x01) ! /* not a single tuple */ drop(nbpInErrors); ! ent = pkt+NBPHDRSIZ; ! obj = ent+ENTHDRSIZ; typ = obj+*obj+1; zon = typ+*typ+1; ! if (nbp_invalid(obj, typ, zon, pkt, len)) drop(nbpInErrors); ! if (zon[0] == 0x00 || (zon[0] == 0x01 && zon[1] == '*')) drop(nbpInErrors); if ((rtmp = rtmp_route(pd->dstNet)) == RTMPNULL) *************** *** 236,276 **** pd->dstNode = BCAST; } nbp_send(ifn, pd, rtmp); return; } /* ! * send the NBP packet, possibly to a multicast zone address * */ void ! nbp_send(ifn, pd, rtmp) int ifn; struct pd *pd; - struct rtmp *rtmp; { ! u_char *pkt; ! char *nbp_type();; pkt = pd->data; ! pd->lapType = LDDP; ! pd->hop = 0; /* ! * sending NBP packets with the DDP header containing ! * the router source address is absolutely correct but ! * may break lookups to IMAGEWRITERS, do we care ... ? * */ ! pd->srcNet = iflist[rtmp->intfc].net; ! pd->srcNode = iflist[rtmp->intfc].node; if (debug & NBPDEBUG) { fprintf(stderr, " NBP: %-5s Sending %s to %3d.%-3d %3d", ! iflist[rtmp->intfc].if_name, nbp_type(pkt[0]), pd->dstNet >> 8, pd->dstNet & 0xff, pd->dstNode); if (pd->addr != NULL) fprintf(stderr, " %02x:%02x:%02x:%02x:%02x:%02x", --- 273,604 ---- pd->dstNode = BCAST; } + pd->srcNet = iflist[ifn].net; + pd->srcNode = iflist[ifn].node; + pd->srcSkt = NBP; + pd->dstSkt = NBP; + nbp_send(ifn, pd, rtmp); return; } /* ! * process an incoming NBP lookup reply ! * (to our NBP registration attempt) * */ void ! nbp_lkupreply(ifn, pd) int ifn; struct pd *pd; { ! register u_char *ent, *obj, *typ, *zon, *nxt; ! u_char object[NBPSTR], type[NBPSTR], zone[NBPSTR]; ! u_char *pkt, nbpID; ! short len, tuples; ! int nbp_invalid(); ! void nbp_dequeue(); ! void strcpypc(); pkt = pd->data; ! len = pd->dataLen; ! ! tuples = pkt[0] & 0x0f; ! nbpID = pkt[1]; ! ! ent = pkt+NBPHDRSIZ; ! ! while (tuples-- > 0) { ! ! obj = ent+ENTHDRSIZ; ! typ = obj+*obj+1; ! zon = typ+*typ+1; ! nxt = zon+*zon+1; ! ! if (nbp_invalid(obj, typ, zon, pkt, len)) ! drop(nbpInErrors); ! ! strcpypc((char *)obj, (char *)object); ! strcpypc((char *)typ, (char *)type); ! strcpypc((char *)zon, (char *)zone); ! ! if (debug & NBPDEBUG) ! fprintf(stderr, " NBP: %-5s Reply tuple %s:%s@%s\n", ! iflist[ifn].if_name, object, type, zone); ! ! /* ! * "soft" dequeue of NBP lookup ! * (ie: modify object and try again) ! * ! */ ! nbp_dequeue(ent, zon-ent, nbpID, 0); ! ! ent = nxt; ! } ! ! return; ! } ! ! /* ! * process an incoming NBP lookup packet ! * ! */ ! ! void ! nbp_lkupreq(ifn, pd) ! int ifn; ! struct pd *pd; ! { ! short len; ! register u_char *pkt, *ent, *obj, *typ, *zon, nbpID; ! u_char object[NBPSTR], type[NBPSTR], zone[NBPSTR]; ! int scmp, objWild, typWild, strcmpci(), nbp_wild(); ! int nbp_match(), nbp_zonmatch(), nbp_invalid(); ! int ddp_is_gw(), ddp_is_mn(); ! struct nbpobj *r, *s, *t; ! struct nbptyp *p, *q; ! u_short entNet; ! u_char entNode; ! void nbp_reply(); ! void strcpypc(); ! ! if (nbpCache == NBPTYPNULL) ! /* no entries */ ! return; ! ! pkt = pd->data; ! len = pd->dataLen; ! ! if ((pkt[0] & 0x0f) != 0x01) ! /* not a single tuple */ ! drop(nbpInErrors); ! ! nbpID = pkt[1]; ! ! ent = pkt+NBPHDRSIZ; ! obj = ent+ENTHDRSIZ; ! typ = obj+*obj+1; ! zon = typ+*typ+1; ! ! if (nbp_invalid(obj, typ, zon, pkt, len)) ! drop(nbpInErrors); ! ! strcpypc((char *)obj, (char *)object); ! strcpypc((char *)typ, (char *)type); ! strcpypc((char *)zon, (char *)zone); ! ! if (debug & NBPDEBUG) ! fprintf(stderr, " NBP: %-5s Look Up for %s:%s@%s\n", ! iflist[ifn].if_name, object, type, zone); ! ! objWild = nbp_wild(object); /* wild card ? */ ! typWild = nbp_wild(type); /* wild card ? */ ! ! p = nbpCache; ! q = NBPTYPNULL; /* ! * search cache for matching entries, if there are wild ! * cards in object or type, search is effectively linear * */ ! while (p != NBPTYPNULL) { ! loop: scmp = -1; ! if (!typWild) { ! if ((scmp = strcmpci(p->nbptyp+1, type)) < 0) { ! q = p; ! p = p->next; ! continue; ! } ! if (scmp > 0) ! break; ! } ! if (scmp == 0 || nbp_match(type, p->nbptyp+1)) { ! /* ! * found the NBP type, now look for object ! * ! */ ! r = p->list; ! s = NBPOBJNULL; ! ! while (r != NBPOBJNULL) { ! scmp = -1; ! if (!objWild) { ! if ((scmp = strcmpci(r->nbpobj+1, object)) < 0) { ! s = r; ! r = r->next; ! continue; ! } ! if (scmp > 0) ! break; ! } ! if (scmp == 0 || nbp_match(object, r->nbpobj+1)) { ! /* ! * check to see if the entry is valid for the interface ! * ! */ ! entNet = (r->nbpent[0] << 8) | r->nbpent[1]; ! entNode = r->nbpent[2]; ! if (!((ddp_is_gw(r->intfc, entNet, entNode)) ! || (ddp_is_mn(r->intfc, entNet, entNode))) ! || (r->when != 0 && tn.tv_sec > r->when+NBPCACHETIMEOUT)) { ! /* ! * not connected/expired, delete NBP cache entry ! * ! */ ! if (debug & NBPDEBUG) ! fprintf(stderr," NBP: %-5s expired, deleting %s:%s@%s\n", ! iflist[r->intfc].if_name, r->nbpobj+1, ! p->nbptyp+1, r->zone+1); ! ! if (s == NBPOBJNULL) ! p->list = r->next; ! else ! s->next = r->next; ! t = r->next; ! free((char *)r); ! r = t; ! ! if (p->list == NBPOBJNULL) { ! /* ! * no objects left for this type ! * ! */ ! if (debug & NBPDEBUG) ! fprintf(stderr," NBP: %-5s empty, deleting type %s\n", ! iflist[ifn].if_name, p->nbptyp+1); ! ! if (q == NBPTYPNULL) ! nbpCache = p->next; ! else ! q->next = p->next; ! free((char *)p); ! ! /* ! * start again ! * ! */ ! q = NBPTYPNULL; ! ! if ((p = nbpCache) == NBPTYPNULL) ! return; ! ! goto loop; ! } ! continue; ! } ! /* ! * send a single packet NBP reply per match ! * ! */ ! if (nbp_zonmatch(zone, r->zone+1)) ! nbp_reply(ifn, ent, r->nbpent, p->nbptyp, r->zone, nbpID); ! } ! s = r; ! r = r->next; ! } ! } ! q = p; ! p = p->next; ! } ! ! return; ! } ! ! /* ! * reply to the originator of the NBP request ! * (address in req) with the NBP data in rep. ! * ! */ ! ! void ! nbp_reply(ifn, req, rep, typ, zon, nbpID) ! int ifn; ! u_char *req, *rep, *typ, *zon, nbpID; ! { ! short len, nbp_pack(); ! u_char *pkt, *obj, buf[160]; ! struct rtmp *rtmp_route(); ! struct pd opd; ! int nbp_invalid(); ! void nbp_send(); ! ! /* ! * drop if request from same net/node ! * ! */ ! if (req[0] == rep[0] ! && req[1] == rep[1] ! && req[2] == rep[2]) ! return; ! ! obj = rep+ENTHDRSIZ; ! ! if (nbp_invalid(obj, typ, zon, (u_char *)NULL, 0)) ! return; ! ! len = 0; ! ! opd.lapType = LDDP; ! opd.ddpType = NBP; ! opd.dstNet = (req[0] << 8) | req[1]; ! opd.srcNet = (rep[0] << 8) | rep[1]; ! opd.dstNode = req[2]; ! opd.srcNode = rep[2]; ! opd.dstSkt = req[3]; ! opd.srcSkt = NBP; ! opd.data = buf+HDRSIZ+LDDPHDRSIZ; ! opd.dataLen = len; ! opd.addr = NULL; ! opd.hop = 0; ! ! pkt = opd.data; ! ! pkt[0] = (NBPLKUPREPLY << 4) | 0x01; /* LkUp Reply */ ! pkt[1] = nbpID; /* lookup ID */ ! ! len += NBPHDRSIZ; ! pkt += NBPHDRSIZ; ! ! bcopy((char *)rep, (char *)pkt, ENTHDRSIZ); ! ! pkt += ENTHDRSIZ; ! len += ENTHDRSIZ; ! ! len += nbp_pack(pkt, obj, typ, zon); ! ! opd.dataLen = len; ! ! nbp_send(ifn, &opd, rtmp_route(opd.dstNet)); ! ! return; ! } ! ! /* ! * send an NBP packet, possibly to a multicast zone address ! * ! */ ! ! void ! nbp_send(ifn, pd, rtmp) ! int ifn; ! struct pd *pd; ! struct rtmp *rtmp; ! { ! char *nbp_type(); ! int intfc, ddp_for_gw(); ! void ddp_gw(), ddp_route(); ! ! pd->lapType = LDDP; ! pd->hop = 0; ! ! intfc = (rtmp == NULL) ? ifn : rtmp->intfc; if (debug & NBPDEBUG) { fprintf(stderr, " NBP: %-5s Sending %s to %3d.%-3d %3d", ! iflist[intfc].if_name, nbp_type(pd->data[0]), pd->dstNet >> 8, pd->dstNet & 0xff, pd->dstNode); if (pd->addr != NULL) fprintf(stderr, " %02x:%02x:%02x:%02x:%02x:%02x", *************** *** 279,284 **** --- 607,625 ---- fprintf(stderr, "\n"); } + /* + * also send a copy of LKUPs and LKUPREPLYs to gw + * + */ + if ((pd->data[0] >> 4) == NBPLKUPREQ + || (pd->data[0] >> 4) == NBPLKUPREPLY) { + if (ddp_for_gw(intfc, pd->dstNet, pd->dstNode)) { + ddp_gw(intfc, pd); + if (pd->dstNode != BCAST) + return; + } + } + incr(ddpOutRequests); ddp_route(ifn, pd, rtmp); *************** *** 313,316 **** --- 654,1626 ---- } return("Unknown"); + } + + /* + * the NBP process + * + * send NBP LKUPs for pending NBP registrations + * (use our node in entity so we get any responses) + * + */ + + void + nbp_process() + { + short zlen; + u_char skt, nod, *zon; + struct nbpq *p, *q, *t; + struct zone *zone, *zone_default(); + void nbp_brreq(), nbp_insert(); + + p = nbpQueue; + q = NBPQNULL; + + while (p != NBPQNULL) { + if (iflist[p->intfc].state == ADDR_VALID) { + if (p->zonlen != 0) { /* have default zone */ + if (p->timer > 0 && ++p->period >= p->timer) { + p->period = 0; + if (p->count-- > 0) { + /* send an NBP lookup */ + nod = p->opd.data[4]; + p->opd.data[4] = iflist[p->intfc].node; + skt = p->opd.data[5]; + p->opd.data[5] = NBP; + nbp_brreq(p->intfc, &p->opd); + p->opd.dataLen = p->dataLen; + p->opd.data[4] = nod; + p->opd.data[5] = skt; + } else { + /* finished, add NBP data to cache (no timeout) */ + nbp_insert(p->intfc, p->opd.data, p->dataLen, 1); + /* dequeue the request */ + if (q == NBPQNULL) + nbpQueue = p->next; + else + q->next = p->next; + t = p->next; + free((char *)p); + p = t; + continue; + } + } + } else { /* try to find out the default zone */ + if ((zone = zone_default(p->intfc)) != ZONENULL) { + if ((zlen = zone->name[0]) <= MAXNBP) { + p->zonlen = zlen+1; + zon = p->opd.data + p->dataLen; + bcopy((char *)zone->name, (char *)zon, p->zonlen); + p->dataLen += p->zonlen; + p->opd.dataLen = p->dataLen; + continue; + } + } + } + } + q = p; + p = p->next; + } + + return; + } + + /* + * register an NBP entity + * + */ + + void + nbp_register(ifn, obj, typ, zon, addr, count, timer) + int ifn; + u_char *obj, *typ, *zon; + struct ataddr *addr; + short count, timer; + { + short len, nbp_pack(); + u_char *pkt, data[160]; + u_char object[NBPSTR], type[NBPSTR], zone[NBPSTR]; + int nbp_invalid(), nbp_wild(); + void nbp_enqueue(), strcpypc(); + + if (nbp_invalid(obj, typ, zon, (u_char *)NULL, 0)) + return; + + strcpypc((char *)obj, (char *)object); + strcpypc((char *)typ, (char *)type); + strcpypc((char *)zon, (char *)zone); + + if (nbp_wild(object)) + return; + + if (nbp_wild(type)) + return; + + if (!(zone[0] == 0x00 || (zone[0] == '*' && zone[1] == 0x00))) + return; + + if (debug & NBPDEBUG) + fprintf(stderr, " NBP: %-5s Registering %s:%s@%s\n", + iflist[ifn].if_name, object, type, zone); + + data[0] = (NBPBRRQ << 4) | 0x01; + data[1] = (nbpOutID++) & 0xff; + data[2] = addr->net >> 8; + data[3] = addr->net & 0xff; + data[4] = addr->node; + data[5] = addr->skt; + data[6] = 0x01; + + pkt = data+NBPHDRSIZ+ENTHDRSIZ; + len = NBPHDRSIZ+ENTHDRSIZ; + + len += nbp_pack(pkt, obj, typ, (u_char *)NULL); /* no zone */ + + nbp_enqueue(ifn, data, len, count, timer); + + return; + } + + /* + * mark a node's NBP cache entry for deletion + * + */ + + void + nbp_delete(ifn, net, node, skt) + int ifn; + u_short net; + u_char node, skt; + { + register struct nbptyp *p; + register struct nbpobj *r; + + p = nbpCache; + + while (p != NBPTYPNULL) { + r = p->list; + while (r != NBPOBJNULL) { + if (ifn == r->intfc + && node == r->nbpent[2] + && (skt == r->nbpent[3] || skt == 0x00) + && net == ((r->nbpent[0] << 8) | r->nbpent[1])) { + r->when = 1; + } + r = r->next; + } + p = p->next; + } + + return; + } + + /* + * queue an NBP lookup for the NBP process + * + */ + + void + nbp_enqueue(ifn, data, len, count, timer) + int ifn; + u_char *data; + short len, count, timer; + { + short siz; + u_char *ent; + struct nbpq *nbpq; + + if (len > (sizeof(nbpq->data)-HDRSIZ-LDDPHDRSIZ)) + return; + + nbpq = nbpQueue; + + /* + * check if ent/obj/typ already queued + * + */ + while (nbpq != NBPQNULL) { + ent = nbpq->opd.data+NBPHDRSIZ; + siz = nbpq->dataLen-nbpq->zonlen; + if (len == siz) { + if (bcmp((char *)(data+NBPHDRSIZ), (char *)ent, siz-NBPHDRSIZ) == 0) + /* same ent/obj/typ, ignore */ + return; + if (bcmp((char *)(data+NBPHDRSIZ+ENTHDRSIZ), + (char *)(ent+ENTHDRSIZ), siz-NBPHDRSIZ-ENTHDRSIZ) == 0) { + /* same obj/typ, update ent, reset timer */ + bcopy((char *)(data+NBPHDRSIZ), (char *)ent, ENTHDRSIZ); + nbpq->timer = timer; + nbpq->count = count; + return; + } + } + nbpq = nbpq->next; + } + + /* + * create a new queue element + * + */ + if ((nbpq = (struct nbpq *)malloc(sizeof(struct nbpq))) == NBPQNULL) { + incr(uarMemoryError); + return; + } + + nbpq->intfc = ifn; + nbpq->dataLen = len; + nbpq->timer = timer; + nbpq->count = count; + nbpq->period = 0; + nbpq->zonlen = 0; + nbpq->modifier = NULL; + + nbpq->opd.lapType = LDDP; + nbpq->opd.ddpType = NBP; + nbpq->opd.dstNet = iflist[ifn].net; + nbpq->opd.srcNet = (data[2] << 8) | data[3]; + nbpq->opd.dstNode = iflist[ifn].node; + nbpq->opd.srcNode = data[4]; + nbpq->opd.dstSkt = NBP; + nbpq->opd.srcSkt = NBP; + nbpq->opd.data = nbpq->data+HDRSIZ+LDDPHDRSIZ; + nbpq->opd.dataLen = len; + nbpq->opd.addr = NULL; + nbpq->opd.hop = 0; + + bcopy((char *)data, (char *)nbpq->opd.data, (int)len); + + /* + * queue it + * + */ + nbpq->next = nbpQueue; + nbpQueue = nbpq; + + return; + } + + /* + * dequeue pending NBP registration + * + * if a "hard" dequeue, remove an NBP lookup from the + * queue otherwise modify object and reset counters. + * + * (data and len include entity, object and type) + * + */ + + void + nbp_dequeue(data, len, nbpID, hard) + u_char *data; + short len; + u_char nbpID; + int hard; + { + short siz, off; + u_char *qobj, *obj; + struct nbpq *p, *q, *t; + int nbp_modify(); + + p = nbpQueue; + q = NBPQNULL; + + off = NBPHDRSIZ+ENTHDRSIZ; + siz = len-ENTHDRSIZ; + obj = data+ENTHDRSIZ; + + while (p != NBPQNULL) { + if (p->opd.data[1] == nbpID + && (p->dataLen-p->zonlen-off) == siz) { + /* same NBP ID and obj/typ length */ + qobj = p->opd.data+off; /* get queued object */ + if (bcmp((char *)qobj, (char *)obj, siz) == 0) { + /* found same obj/typ fields */ + if (!hard) + hard = nbp_modify(p); + if (hard) { + /* dequeue request */ + if (q == NBPQNULL) + nbpQueue = p->next; + else + q->next = p->next; + t = p->next; + free((char *)p); + p = t; + continue; + } + } + } + q = p; + p = p->next; + } + + return; + } + + /* + * modify NBP object for retry + * + */ + + int + nbp_modify(p) + struct nbpq *p; + { + u_char *obj, *typ, *zon; + + p->count = 8; + p->timer = 5; + p->period = 0; + + obj = p->opd.data+NBPHDRSIZ+ENTHDRSIZ; + + /* + * add or increment object modifier + * (trailing -N where N is 0-9, A-Z) + * + */ + if (p->modifier == NULL) { + typ = obj+*obj+1; + zon = typ+*typ+1; + if (*obj < (MAXNBP-2)) + bcopy((char *)typ, (char *)(typ+2), (int)(*typ+*zon+2)); + else + typ -= 2; + typ[0] = '-'; + typ[1] = '0'; + p->modifier = typ+1; + if (*obj < (MAXNBP-2)) { + p->opd.dataLen += 2; + p->dataLen += 2; + *obj += 2; + } + } else { + *p->modifier++; + if (*p->modifier > '9' + && *p->modifier < 'A') + *p->modifier = 'A'; + } + + return(*p->modifier > 'Z'); + } + + /* + * insert NBP tuple(s) into the NBP cache + * + * The NBP cache is a linked list sorted by NBP type. Each cache + * node contains a pointer to a linked list ordered by NBP object. + * + */ + + void + nbp_insert(ifn, pkt, len, perm) + int ifn; + u_char *pkt; + short len; + int perm; + { + register struct nbpobj *r, *s, *t; + register struct nbptyp *m, *p, *q; + register u_char *ent, *obj, *typ, *zon, *nxt; + u_char object[NBPSTR], type[NBPSTR], zone[NBPSTR]; + int scmp, tuples, strcmpci(), nbp_invalid(); + struct zone *z, *zone_default(); + struct nbpobj *newTuple(); + struct nbptyp *newCache(); + void strcpypc(); + + tuples = pkt[0] & 0x0f; + + ent = pkt+NBPHDRSIZ; + + while (tuples-- > 0) { + obj = ent+ENTHDRSIZ; + typ = obj+*obj+1; + zon = typ+*typ+1; + nxt = zon+*zon+1; + + if (nbp_invalid(obj, typ, zon, pkt, len)) + return; + + /* + * don't store "null" zone names if default known + * + */ + if (zon[0] == 0x00 || (zon[0] == 0x01 && zon[1] == '*')) + if ((z = zone_default(ifn)) != NULL) + zon = z->name; + + strcpypc((char *)obj, (char *)object); + strcpypc((char *)typ, (char *)type); + strcpypc((char *)zon, (char *)zone); + + if (debug & NBPDEBUG) + fprintf(stderr, " NBP: %-5s inserting tuple %s:%s@%s\n", + iflist[ifn].if_name, object, type, zone); + + /* + * create initial list entry + * + */ + if (nbpCache == NBPTYPNULL) { + if (debug & NBPDEBUG) + fprintf(stderr, " NBP: initialising cache\n"); + if ((r = newTuple(ifn,ent,obj,zon,NBPOBJNULL,perm)) == NBPOBJNULL) + return; + if ((nbpCache = newCache(typ, r, NBPTYPNULL)) == NBPTYPNULL) + free((char *)r); + return; + } + + p = nbpCache; + q = NBPTYPNULL; + + while (p != NBPTYPNULL) { + if ((scmp = strcmpci(p->nbptyp+1, type)) < 0) { + q = p; + p = p->next; + continue; + } + if (scmp > 0) + break; + if (scmp == 0) { + /* + * found NBP type + * + */ + r = p->list; + s = NBPOBJNULL; + + while (r != NBPOBJNULL) { + if ((scmp = strcmpci(r->nbpobj+1, object)) < 0) { + s = r; + r = r->next; + continue; + } + if (scmp > 0) + break; + if (scmp == 0) { + /* + * found NBP object + * + */ + if (debug & NBPDEBUG) + fprintf(stderr, " NBP: updating %s:%s@%s\n", + object, type, zone); + bcopy((char *)ent, (char *)r->nbpent, ENTHDRSIZ); + r->when = (perm) ? 0 : tn.tv_sec; + r->intfc = ifn; + goto next; + } + } + /* + * object not found, insert it + * + */ + if ((t = newTuple(ifn, ent, obj, zon, r, perm)) == NBPOBJNULL) + return; + + if (s == NBPOBJNULL) + p->list = t; + else + s->next = t; + + return; + } + } + + /* + * type isn't in cache list, create a new entry + * + */ + if ((r = newTuple(ifn,ent,obj,zon,NBPOBJNULL,perm)) == NBPOBJNULL) + return; + + if ((m = newCache(typ, r, p)) == NBPTYPNULL) { + free((char *)r); + return; + } + + /* + * link it into cache + * + */ + if (q == NBPTYPNULL) + nbpCache = m; + else + q->next = m; + + /* + * get next tuple + * + */ + next: ent = nxt; + } + + return; + } + + /* + * create a new tuple (NBP tuple without a type field) + * (make the object field null terminated for convenience) + * + */ + + struct nbpobj * + newTuple(ifn, ent, obj, zon, next, perm) + int ifn; + register u_char *ent, *obj, *zon; + struct nbpobj *next; + int perm; + { + register struct nbpobj *t; + + if ((t = (struct nbpobj *)malloc(sizeof(*t))) == NBPOBJNULL) + return(NBPOBJNULL); + + bcopy((char *)ent, (char *)t->nbpent, ENTHDRSIZ); + bcopy((char *)obj, (char *)t->nbpobj, (int)(*obj+1)); + bcopy((char *)zon, (char *)t->zone, (int)(*zon+1)); + t->nbpobj[*obj+1] = '\0'; + t->zone[*zon+1] = '\0'; + t->when = (perm) ? 0 : tn.tv_sec; + t->intfc = ifn; + t->next = next; + + return(t); + } + + /* + * create a new cache entry (a list of ordered objects with NBP type) + * (make the type field null terminated for convenience) + * + */ + + struct nbptyp * + newCache(typ, tuple, next) + register u_char *typ; + struct nbpobj *tuple; + struct nbptyp *next; + { + register struct nbptyp *c; + + if ((c = (struct nbptyp *)malloc(sizeof(*c))) == NBPTYPNULL) + return(NBPTYPNULL); + + bcopy((char *)typ, (char *)c->nbptyp, (int)(*typ+1)); + c->nbptyp[*typ+1] = '\0'; + c->list = tuple; + c->next = next; + + return(c); + } + + /* + * dump the NBP cache + * + */ + + void + nbp_dump() + { + int i, j, count; + char entity[100]; + FILE *r, *fopen(); + struct nbptyp *nbptyp; + struct nbpobj *nbpobj; + extern int numintfc; + + if ((r = fopen(DUMP_NBP, "w+")) == NULL) { + incr(uarBadDumpFile); + return; + } + + fprintf(r, "UAR NBP Cache:\n\n"); + fprintf(r, " net node skt enum ifc NBP entity\n"); + + count = 0; + nbptyp = nbpCache; + + while (nbptyp != NBPTYPNULL) { + nbpobj = nbptyp->list; + while (nbpobj != NBPOBJNULL) { + sprintf(entity, "%s:%s@%s", nbpobj->nbpobj+1, + nbptyp->nbptyp+1, nbpobj->zone+1); + fprintf(r, "%3d.%-3d %3d %3d %3d %2d%c %s\n", + nbpobj->nbpent[0], nbpobj->nbpent[1], + nbpobj->nbpent[2], nbpobj->nbpent[3], + nbpobj->nbpent[4], nbpobj->intfc, + (nbpobj->when == 0) ? '*' : ' ', + entity); + count++; + nbpobj = nbpobj->next; + } + nbptyp = nbptyp->next; + } + fprintf(r, "\n\n%d NBP entries\n", count); + + (void)fclose(r); + + if (debug & NBPDEBUG) + fprintf(stderr, " NBP: dumped NBP cache, %d entries\n", count); + + return; + } + + /* + * pack object, type and zone (if any) into contiguous data + * + */ + + short + nbp_pack(pkt, obj, typ, zon) + register u_char *pkt, *obj, *typ, *zon; + { + register int i; + register short len; + + len = 0; + + i = *obj+1; + bcopy((char *)obj, (char *)pkt, i); + pkt += i; + len += i; + + i = *typ+1; + bcopy((char *)typ, (char *)pkt, i); + pkt += i; + len += i; + + if (zon == NULL) + return(len); + + i = *zon+1; + bcopy((char *)zon, (char *)pkt, i); + pkt += i; + len += i; + + return(len); + } + + /* + * check (pascal) object, type and zone strings for sanity + * + */ + + int + nbp_invalid(obj, typ, zon, pkt, len) + register u_char *obj, *typ, *zon, *pkt; + register short len; + { + if (*obj > MAXNBP) + return(1); + + if (*typ > MAXNBP) + return(1); + + if (*zon > MAXNBP) + return(1); + + if (pkt == NULL) + return(0); + + if ((zon+*zon+1) > pkt+len) + return(1); + + return(0); + } + + /* + * check for NBP obj/typ wildcards in string + * + */ + + int + nbp_wild(str) + register u_char *str; + { + if (str[0] == nbpEquals && str[1] == 0x00) + return(1); + + if (index((char *)str, nbpApprox)) + return(1); + + return(0); + } + + /* + * NBP object/type match + * (taking wildcards in "pat" into account) + * + */ + + int + nbp_match(pat, thing) + register u_char *pat, *thing; + { + register u_char *p; + register short pl, tl, hl; + int strcmpci(), strncmpci(); + + if ((pat[0] == nbpEquals || pat[0] == nbpApprox) && pat[1] == 0x00) + return(1); + + if (p = (u_char *)index((char *)pat, nbpApprox)) { + if ((hl = p - pat) + && strncmpci(pat, thing, hl) != 0) + return(0); + + pl = strlen((char *)pat) - 1; + tl = strlen((char *)thing); + + if (tl < pl) + return(0); + + if (hl < pl + && strcmpci((p+1), thing+(tl-(pl-hl))) != 0) + return(0); + + return(1); + } + + if (strcmpci(pat, thing) != 0) + return(0); + + return(1); + } + + /* + * check for matching zone names + * + */ + + int + nbp_zonmatch(zonea, zoneb) + register u_char *zonea, *zoneb; + { + int strcmpci(); + + if (zonea[0] == 0x00 || (zonea[0] == '*' && zonea[1] == 0x00)) + return(1); /* match anything */ + + if (strcmpci(zonea, zoneb) == 0) + return(1); + + return(0); + } + + /* + * copy a pascal str to a C string + * + */ + + void + strcpypc(str, string) + register char *str, *string; + { + register int len; + + if ((len = *str) > MAXNBP) + len = MAXNBP; + + bcopy(str+1, string, len); + + string[len] = '\0'; + + return; + } + + /* + * copy a C str to a pascal string + * + */ + + void + strcpycp(str, string) + register char *str, *string; + { + register int len; + + if ((len = strlen(str)) > MAXNBP) + len = MAXNBP; + + bcopy(str, string+1, len); + + string[0] = len; + + return; + } + + /* + * case insensitive version of strcmp() + * + */ + + int + strcmpci(s, t) + register u_char *s, *t; + { + register u_char c, d; + u_char mactolower(); + + if (debug & NBPDEBUG) + fprintf(stderr, " NBP: comparing :%s: to :%s:\n", + (char *)s, (char *)t); + + for ( ; ; ) { + c = mactolower(*s++); + d = mactolower(*t++); + if (c != d) + return(c-d); + if (c == '\0') + return(0); + } + } + + /* + * case insensitive version of strncmp() + * + */ + + int + strncmpci(s, t, n) + register u_char *s, *t; + register int n; + { + register u_char c, d; + u_char mactolower(); + + for ( ; n > 0 ; n--) { + c = mactolower(*s++); + d = mactolower(*t++); + if (c != d) + return(c-d); + if (c == '\0') + return(0); + } + + return(0); + } + + /* + * map Macintosh uppercase characters to lowercase + * (Inside AppleTalk, 2nd Edition, Appendix D) + * + */ + + u_char + mactolower(c) + register u_char c; + { + if (!(c & 0x80)) { + if (isupper((int)c)) + return(tolower((int)c)); + else + return(c); + } + + switch (c) { + case 0xcb: + return(0x88); + break; + case 0x80: + return(0x8a); + break; + case 0xcc: + return(0x8b); + break; + case 0x81: + return(0x8c); + break; + case 0x82: + return(0x8d); + break; + case 0x83: + return(0x8e); + break; + case 0x84: + return(0x96); + break; + case 0x85: + return(0x9a); + break; + case 0xcd: + return(0x9b); + break; + case 0x86: + return(0x9f); + break; + case 0xae: + return(0xbe); + break; + case 0xaf: + return(0xbf); + break; + case 0xce: + return(0xcf); + break; + } + return(c); + } + + /* + * map Macintosh lowercase characters to uppercase + * (Inside AppleTalk, 2nd Edition, Appendix D) + * + * + */ + + u_char + mactoupper(c) + register u_char c; + { + if (!(c & 0x80)) { + if (islower((int)c)) + return(toupper((int)c)); + else + return(c); + } + + switch (c) { + case 0x88: + return(0xcb); + break; + case 0x8a: + return(0x80); + break; + case 0x8b: + return(0xcc); + break; + case 0x8c: + return(0x81); + break; + case 0x8d: + return(0x82); + break; + case 0x8e: + return(0x83); + break; + case 0x96: + return(0x84); + break; + case 0x9a: + return(0x85); + break; + case 0x9b: + return(0xcd); + break; + case 0x9f: + return(0x86); + break; + case 0xbe: + return(0xae); + break; + case 0xbf: + return(0xaf); + break; + case 0xcf: + return(0xce); + break; + } + return(c); } *** pf.c.orig Sat Dec 17 17:20:14 1994 --- pf.c Mon Sep 25 07:29:00 1995 *************** *** 1,11 **** /* * General Purpose AppleTalk Packet Filter Interface * ! * Copyright (c) 1992, The University of Melbourne. ! * All Rights Reserved. Permission to redistribute ! * or use any part of this software for any purpose ! * other than as originally shipped must be obtained ! * in writing from the copyright owner. * * This software is supplied "as is" without express * or implied warranty. --- 1,10 ---- /* * General Purpose AppleTalk Packet Filter Interface * ! * Copyright (c) 1992-1995, The University of Melbourne. ! * All Rights Reserved. Permission to redistribute or ! * use any part of this software for any purpose must ! * be obtained in writing from the copyright owner. * * This software is supplied "as is" without express * or implied warranty. *************** *** 16,21 **** --- 15,21 ---- * SunOS Network InterFace Tap (SNITPF) * DEC ULTRIX Packet Filter (UPFILT) * DEC OSF/Alpha Packet Filter (UPFILT) + * DEC Packet Filter via FDDI (UPFILT_FDDI) * Stanford Ethernet Packet Filter (ENETPF) * Solaris STREAMS Data Link Provider Interface (DLPIPF) * SGI IRIX SNOOP PF for promisc, DRAIN PF for non-promisc *************** *** 26,32 **** * Linux SOCK_PACKET * * $Author: djh $ ! * $Revision: 1.18 $ * */ --- 26,32 ---- * Linux SOCK_PACKET * * $Author: djh $ ! * $Revision: 1.20 $ * */ *************** *** 64,73 **** --- 64,81 ---- #define AIXETH #endif AIX + #ifdef BPFILT + #define NEEDSYSSTROPTS + #endif BPFILT + #ifdef __386BSD__ #define BPFILT #endif __386BSD__ + #ifdef __NetBSD__ + #define BPFILT + #endif __NetBSD__ + #ifdef FreeBSD #define BPFILT #endif FreeBSD *************** *** 116,128 **** #ifdef BPFILT #include #include ! #if (!(defined(bsdi) || defined(FreeBSD) || defined(__386BSD__))) #include ! #endif /* bsdi || FreeBSD || __386BSD__ */ #endif BPFILT #ifdef UPFILT #include #endif UPFILT #ifdef DLPIPF --- 124,140 ---- #ifdef BPFILT #include #include ! #ifdef NEEDSYSSTROPTS #include ! #endif NEEDSYSSTROPTS #endif BPFILT #ifdef UPFILT #include + #ifdef UPFILT_FDDI + #include + #include + #endif UPFILT_FDDI #endif UPFILT #ifdef DLPIPF *************** *** 167,175 **** --- 179,193 ---- #include #endif SOLARIS + #ifdef __NetBSD__ + #include + #include + #endif __NetBSD__ + #ifdef bsdi #include #include + #include #endif bsdi #ifdef linux *************** *** 245,254 **** --- 263,278 ---- #undef USE_SADDMULTI #endif __386BSD__ + #ifdef __NetBSD__ + #define USE_SIOCGIFCONF + #undef USE_GIFADDR + #endif __NetBSD__ + #ifdef FreeBSD #endif FreeBSD #ifdef bsdi + #define USE_SIOCGIFCONF #undef USE_GIFADDR #endif bsdi *************** *** 262,268 **** */ #define READBUFSIZ 4096 ! #define NUMRDS 32 struct RDS { u_short dataLen; --- 286,292 ---- */ #define READBUFSIZ 4096 ! #define NUMRDS 32 struct RDS { u_short dataLen; *************** *** 287,292 **** --- 311,323 ---- u_int pf_bufsize = READBUFSIZ; #endif BPFILT + #ifdef UPFILT + #ifdef UPFILT_FDDI + int ethtyp[32]; + int onfddi[32]; + #endif UPFILT_FDDI + #endif UPFILT + #ifdef linux struct socklist { struct sockaddr sa; *************** *** 356,361 **** --- 387,403 ---- perror(interface); return(-1); } + #ifdef UPFILT_FDDI + { struct endevp devParams; + + if (ioctl(s, EIOCDEVP, &devParams) < 0) { + perror(interface); + return(-1); + } + onfddi[s] = (devParams.end_dev_type == ENDT_FDDI); + ethtyp[s] = typ; + } + #endif UPFILT_FDDI #endif UPFILT *************** *** 744,752 **** #define s_offset(structp, element) (&(((structp)0)->element)) bzero((char *)&pf, sizeof(pf)); pf.Pf_Priority = 128; ! offset = ((int)s_offset(struct ether_header *, ether_type))/sizeof(u_short); ! if (typ == 2) /* EtherTalk Phase 2 */ ! offset += 4; /* shorts: 2 bytes length + 6 bytes of 802.2 and SNAP */ *fwp++ = ENF_PUSHWORD + offset; *fwp++ = ENF_PUSHLIT | ENF_EQ; *fwp++ = htons(prot); --- 786,807 ---- #define s_offset(structp, element) (&(((structp)0)->element)) bzero((char *)&pf, sizeof(pf)); pf.Pf_Priority = 128; ! #ifdef UPFILT_FDDI ! if (onfddi[s]) { ! /* ! * fddi is always 802 format so have ! * if_fddi header then if_llc header ! * ! */ ! offset = (sizeof(struct fddi_header) + ! (int)s_offset(struct llc *, llc_un.type_snap.ether_type))/sizeof(u_short); ! } else ! #endif UPFILT_FDDI ! { ! offset = ((int)s_offset(struct ether_header *, ether_type))/sizeof(u_short); ! if (typ == 2) /* EtherTalk Phase 2 */ ! offset += 4; /* shorts: 2 bytes length + 6 bytes of 802.2 and SNAP */ ! } *fwp++ = ENF_PUSHWORD + offset; *fwp++ = ENF_PUSHLIT | ENF_EQ; *fwp++ = htons(prot); *************** *** 984,998 **** u_char *addr; { - #ifdef bsdi - return(get_eth_addr(s, interface, addr)); - #endif bsdi - - #ifdef USE_GIFADDR { struct sockaddr *sa; strcpy(ifr.ifr_name, interface); if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { perror("SIOCGIFADDR"); return(-1); --- 1039,1049 ---- u_char *addr; { #ifdef USE_GIFADDR { struct sockaddr *sa; strcpy(ifr.ifr_name, interface); + ifr.ifr_addr.sa_family = AF_UNSPEC; if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { perror("SIOCGIFADDR"); return(-1); *************** *** 1007,1012 **** --- 1058,1108 ---- #endif USE_GIFADDR + #ifdef USE_SIOCGIFCONF + { int len, sock; + struct ifconf ifconf; + struct sockaddr_dl *sadl; + struct ifreq ifrbuf[32], *ifra, *ifrb; + + strcpy(ifr.ifr_name, interface); + ifconf.ifc_len = sizeof(ifrbuf); + ifconf.ifc_buf = (caddr_t)ifrbuf; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("SOCK_DGRAM"); + return(-1); + } + if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) { + perror("SIOCGIFCONF"); + close(sock); + return(-1); + } + close(sock); + ifra = ifrbuf; + ifrb = (struct ifreq *)((char *)ifra + ifconf.ifc_len); + while (ifra < ifrb) { + if (strcmp(ifr.ifr_name, ifra->ifr_name) == 0) { + if (ifra->ifr_addr.sa_family == AF_LINK) { + sadl = (struct sockaddr_dl *)&ifra->ifr_addr; + if (sadl->sdl_type == IFT_ETHER) { + bcopy((char *)LLADDR(sadl), (char *)addr, 6); + return(0); + } + #ifdef bsdi + if (sadl->sdl_alen == 0) /* no addr, try other method */ + return(get_eth_addr(s, interface, addr)); + #endif bsdi + } + } + if ((len = ifra->ifr_addr.sa_len+sizeof(ifra->ifr_name)) < sizeof(*ifra)) + len = sizeof(*ifra); + ifra = (struct ifreq *)((char *)ifra + len); + } + } + return(-1); + #endif USE_SIOCGIFCONF + + #ifdef USE_ENET { struct endevp endev; *************** *** 1510,1515 **** --- 1606,1660 ---- #endif linux + #ifdef UPFILT + #ifdef UPFILT_FDDI + if (onfddi[fd]) { + struct fddi_header fddibit; + struct iovec fdiov[3]; + struct llc llcbit; + int off; + + RDS[0].dataLen = 0; + + /* + * use readv to get the data we want. Based on + * protocol type we need to preserve a length and + * sap data in the input buffer + * + */ + off = (ethtyp[fd] == 2) ? 22 : 14; + fdiov[0].iov_base = (caddr_t)&fddibit; + fdiov[0].iov_len = sizeof(struct fddi_header); + fdiov[1].iov_base = (caddr_t)&llcbit; + fdiov[1].iov_len = sizeof(struct llc); + fdiov[2].iov_base = (caddr_t)(buf+off); + fdiov[2].iov_len = len-off; + + if ((cc = readv(fd, fdiov, 3)) <= 0) + return(cc); + + bcopy((char *)fddibit.fddi_dhost, (char *)buf, 12); /* addresses */ + cc = cc - fdiov[0].iov_len - fdiov[1].iov_len + off;/* eth length */ + + if (ethtyp[fd] == 2) { + bcopy((char *)&llcbit, (char *)(buf+14), 8); /* SAP */ + buf[12] = (cc >> 8) & 0xff; /* len */ + buf[13] = (cc & 0xff); + } else { /* type */ + buf[12] = (llcbit.llc_un.type_snap.ether_type >> 8) & 0xff; + buf[13] = (llcbit.llc_un.type_snap.ether_type & 0xff); + } + + RDS[0].dataLen = cc; + RDS[0].dataPtr = buf; + RDS[1].dataLen = 0; + + return(cc); + } + #endif UPFILT_FDDI + #endif UPFILT + + #if (!(defined(BPFILT) || defined(sgi) || defined(hpux) || defined(linux))) RDS[0].dataLen = 0; *************** *** 1525,1530 **** --- 1670,1676 ---- return(cc); #endif /* BPFILT || sgi || hpux */ + } /* *************** *** 1555,1560 **** --- 1701,1707 ---- #ifdef USE_WRITEV struct iovec iov[2]; + #ifdef FreeBSD_SWAP_BUG u_char swap; *************** *** 1563,1574 **** --- 1710,1762 ---- buf[13] = swap; #endif FreeBSD_SWAP_BUG + + #ifdef UPFILT + #ifdef UPFILT_FDDI + if (onfddi[fd]) { + int off, tot; + struct llc llcbit; + struct iovec fdiov[3]; + struct fddi_header fddibit; + unsigned char sapSnap[6] = { LLC_SNAP_LSAP, LLC_SNAP_LSAP, + LLC_UI, '\0', '\0', '\0' }; + + fddibit.fddi_fc = FDDIFC_LLC_ASYNC; /* frame control */ + bcopy(buf, fddibit.fddi_dhost, 12); /* mac addresses */ + + if (ethtyp[fd] == 2) { + bcopy((char *)(buf+14), (char *)&llcbit, 8); /* SAP */ + off = 22; + } else { + bcopy(sapSnap, (char *)&llcbit.llc_dsap, 6); /* sap snap */ + llcbit.llc_un.type_snap.ether_type = (buf[12] << 8) | buf[13]; + off = 14; + } + + fdiov[0].iov_base = (caddr_t)&fddibit; + fdiov[0].iov_len = sizeof(struct fddi_header); + fdiov[1].iov_base = (caddr_t)&llcbit; + fdiov[1].iov_len = sizeof(struct llc); + fdiov[2].iov_base = (caddr_t)(buf+off); + fdiov[2].iov_len = len-off; + + tot = len-off+sizeof(struct fddi_header)+sizeof(struct llc); + + if (writev(fd, fdiov, 3) == tot) + return(len); + + } + #endif UPFILT_FDDI + #endif UPFILT + iov[0].iov_base = (caddr_t)buf; iov[0].iov_len = 14; iov[1].iov_base = (caddr_t)buf+14; iov[1].iov_len = len-14; + if (writev(fd, iov, 2) == len) return(len); + #endif USE_WRITEV *** rtmp.c.orig Wed Nov 2 12:13:24 1994 --- rtmp.c Mon Sep 25 09:18:21 1995 *************** *** 15,33 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.4 $ * */ #include "uar.h" extern int debug; extern u_long uar_stats[]; extern u_long pkts_dropped; extern struct iflist iflist[]; extern char *stats_msg[]; int rtmp_do_dump = 0; struct rtmp *rtmpMRU; struct rtmp *rtmpTab[RTMPTABSIZ]; --- 15,37 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.5 $ * */ #include "uar.h" extern int debug; + extern int numintfc; extern u_long uar_stats[]; extern u_long pkts_dropped; extern struct iflist iflist[]; + extern struct timeval tn; extern char *stats_msg[]; + time_t rtmpModTime; int rtmp_do_dump = 0; + struct rtmp *rtmpMRU; struct rtmp *rtmpTab[RTMPTABSIZ]; *************** *** 43,53 **** rtmpMRU = RTMPNULL; - incr(uarRTMPRoutes); - for (i = 0; i < RTMPTABSIZ; i++) rtmpTab[i] = RTMPNULL; return; } --- 47,57 ---- rtmpMRU = RTMPNULL; for (i = 0; i < RTMPTABSIZ; i++) rtmpTab[i] = RTMPNULL; + rtmpModTime = tn.tv_sec; + return; } *************** *** 76,82 **** fprintf(stderr, " \"%s\"\n", znam); } ! rtmp_intfc(ifn, net_lo, net_hi, NULL); zlen = strlen((char *)znam); if ((zone = zone_find(znam, zlen)) == ZONENULL) { --- 80,86 ---- fprintf(stderr, " \"%s\"\n", znam); } ! rtmp_intfc(ifn, net_lo, net_hi, (struct pd *)NULL); zlen = strlen((char *)znam); if ((zone = zone_find(znam, zlen)) == ZONENULL) { *************** *** 119,136 **** int new; char message[80]; struct rtmp *rtmp, *rtmp_find(), *rtmp_new(); ! void cleanup(), rtmp_insert(); if ((iflist[ifn].net_lo == 0 && iflist[ifn].net_hi == 0) || (iflist[ifn].net_lo == 0 && iflist[ifn].net_hi == P2ENDSTUP)) { iflist[ifn].net = net_lo; iflist[ifn].net_lo = net_lo; iflist[ifn].net_hi = net_hi; ! if (iflist[ifn].phase == PHASE2) { ! /* need to re-probe for new address */ ! iflist[ifn].state = ADDR_PENDING; ! iflist[ifn].count = AARPCount; ! } if (new = ((rtmp = rtmp_find(net_lo, net_hi)) == RTMPNULL)) if ((rtmp = rtmp_new()) == RTMPNULL) --- 123,143 ---- int new; char message[80]; struct rtmp *rtmp, *rtmp_find(), *rtmp_new(); ! void cleanup(), rtmp_insert(), log(); ! extern char hostname[]; if ((iflist[ifn].net_lo == 0 && iflist[ifn].net_hi == 0) || (iflist[ifn].net_lo == 0 && iflist[ifn].net_hi == P2ENDSTUP)) { iflist[ifn].net = net_lo; iflist[ifn].net_lo = net_lo; iflist[ifn].net_hi = net_hi; ! /* ! * need to re-probe for new address ! * and restart interface multinodes ! * ! */ ! iflist[ifn].state = ADDR_PENDING; ! iflist[ifn].count = AARPCount; if (new = ((rtmp = rtmp_find(net_lo, net_hi)) == RTMPNULL)) if ((rtmp = rtmp_new()) == RTMPNULL) *************** *** 150,162 **** if (iflist[ifn].phase == PHASE2) rtmp->flags |= RTMP_EXTENDED; if (new) { rtmp_insert(rtmp); if (debug & RTMPDEBUG) fprintf(stderr, "RTMP: %-5s INIT %3d.%-3d-%3d.%-3d\n", iflist[ifn].if_name, ! rtmp->net_lo >> 8, rtmp->net_lo & 0xff, ! rtmp->net_hi >> 8, rtmp->net_hi & 0xff); } return; --- 157,171 ---- if (iflist[ifn].phase == PHASE2) rtmp->flags |= RTMP_EXTENDED; + rtmpModTime = tn.tv_sec; + if (new) { rtmp_insert(rtmp); if (debug & RTMPDEBUG) fprintf(stderr, "RTMP: %-5s INIT %3d.%-3d-%3d.%-3d\n", iflist[ifn].if_name, ! rtmp->net_lo >> 8, rtmp->net_lo & 0xff, ! rtmp->net_hi >> 8, rtmp->net_hi & 0xff); } return; *************** *** 277,308 **** rtmp->rnet = rnet; rtmp->rnode = rnode; rtmp->state = RTMP_GOOD; } else { if (rtmp->dist >= dist+1 && dist < 15) { /* replace entry */ ! if (rtmp->dist == dist+1) ! incr(rtmpNextIREqualChanges); ! else ! incr(rtmpNextIRLessChanges); rtmp->dist = dist+1; rtmp->intfc = ifn; rtmp->rnet = rnet; rtmp->rnode = rnode; rtmp->state = RTMP_GOOD; } else { ! if (rtmp->rnet == rnet ! && rtmp->rnode == rnode ! && rtmp->intfc == ifn) { ! /* net further away now */ ! if (dist != 31) { ! rtmp->dist = dist+1; ! if (rtmp->dist < 16) ! rtmp->state = RTMP_GOOD; ! else ! rtmp_delete(rtmp); ! } else ! rtmp->state = RTMP_BAD1; ! } } } } else { --- 286,320 ---- rtmp->rnet = rnet; rtmp->rnode = rnode; rtmp->state = RTMP_GOOD; + rtmpModTime = tn.tv_sec; } else { if (rtmp->dist >= dist+1 && dist < 15) { /* replace entry */ ! if (rtmp->dist == dist+1) ! incr(rtmpNextIREqualChanges); ! else ! incr(rtmpNextIRLessChanges); rtmp->dist = dist+1; rtmp->intfc = ifn; rtmp->rnet = rnet; rtmp->rnode = rnode; rtmp->state = RTMP_GOOD; + rtmpModTime = tn.tv_sec; } else { ! if (rtmp->rnet == rnet ! && rtmp->rnode == rnode ! && rtmp->intfc == ifn) { ! /* net further away now */ ! rtmpModTime = tn.tv_sec; ! if (dist != 31) { ! rtmp->dist = dist+1; ! if (rtmp->dist < 16) ! rtmp->state = RTMP_GOOD; ! else ! (void)rtmp_delete(rtmp); ! } else ! rtmp->state = RTMP_BAD1; ! } } } } else { *************** *** 349,355 **** u_char buf[64]; struct pd opd; struct rtmp *rtmp_route(); ! void rtmp_send(); pkt = pd->data; len = pd->dataLen; --- 361,367 ---- u_char buf[64]; struct pd opd; struct rtmp *rtmp_route(); ! void ddp_route(), rtmp_send(); pkt = pd->data; len = pd->dataLen; *************** *** 438,448 **** rtmp_process() { int i; - extern int numintfc; void rtmp_send(); ! for (i = 0; i < numintfc; i++) ! rtmp_send(i, NULL, 1); return; } --- 450,463 ---- rtmp_process() { int i; void rtmp_send(); ! for (i = 0; i < numintfc; i++) { ! if (iflist[i].rtmps != NULL) ! (*(iflist[i].rtmps))(i, (struct pd *)NULL, 1); ! else ! rtmp_send(i, (struct pd *)NULL, 1); ! } return; } *************** *** 574,579 **** --- 589,595 ---- struct pd *pd; { struct rtmp *rtmp_route(); + void ddp_route(); if (debug & RTMPDEBUG) fprintf(stderr, "RTMP: %-5s Sending RTMP data\n", *************** *** 717,722 **** --- 733,740 ---- else q->next = rtmp; + rtmpModTime = tn.tv_sec; + return; } *************** *** 757,762 **** --- 775,782 ---- rtmp_free(rtmp); + rtmpModTime = tn.tv_sec; + return(next); } *************** *** 779,798 **** } /* - * RTMP sump signal handler - * - */ - - void - rtmp_dump_sig() - { - rtmp_do_dump = 1; - (void)signal(SIGHUP, rtmp_dump_sig); - - return; - } - - /* * dump RTMP table * */ --- 799,804 ---- *************** *** 814,820 **** } fprintf(r, "UAR RTMP Table:\n\n"); ! fprintf(r, "low high dst ifc brNet Nd State Zone\n"); for (i = 0, count = 0; i < RTMPTABSIZ; i++) { rtmp = rtmpTab[i]; --- 820,826 ---- } fprintf(r, "UAR RTMP Table:\n\n"); ! fprintf(r, "low high dst ifc brNet Nd State Zone\n"); for (i = 0, count = 0; i < RTMPTABSIZ; i++) { rtmp = rtmpTab[i]; *************** *** 828,834 **** zit = rtmp->zitlist; while (zit != ZITNULL) { if (znum > 0) ! fprintf(r, "%42s", ""); fprintf(r, " %s\n", zit->zone->name+1); zit = zit->next; znum++; --- 834,840 ---- zit = rtmp->zitlist; while (zit != ZITNULL) { if (znum > 0) ! fprintf(r, "%42s", ""); fprintf(r, " %s\n", zit->zone->name+1); zit = zit->next; znum++; *** stats.c.orig Sun Oct 24 19:08:22 1993 --- stats.c Mon Sep 25 09:17:12 1995 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.1 $ * */ *************** *** 99,104 **** --- 99,106 ---- "TNNL packets transmitted", "TNNL packets not for me, dropped", "TNNL packets from bogus source addr", + "", /* ZONE Routes */ + "", /* ZONE Searches */ "" }; *************** *** 119,138 **** } /* - * stats dump signal handler - * - */ - - void - stats_dump_sig() - { - stats_do_dump = 1; - (void)signal(SIGUSR2, stats_dump_sig); - - return; - } - - /* * dump the statistics * */ --- 121,126 ---- *************** *** 154,163 **** --- 142,159 ---- if (*stats_msg[i] != '\0') fprintf(r, "%10d %s\n", uar_stats[i], stats_msg[i]); + if (uar_stats[uarRTMPRoutes] == 0) + uar_stats[uarRTMPRoutes] = 1; + + if (uar_stats[uarZONEFinds] == 0) + uar_stats[uarZONEFinds] = 1; + fprintf(r, "\n"); fprintf(r, "%10d packets dropped\n", pkts_dropped); fprintf(r, "%10.2f average RTMP searches per route request\n", (float)uar_stats[uarRTMPSearches]/(float)uar_stats[uarRTMPRoutes]); + fprintf(r, "%10.2f average ZONE searches per ZONE lookup\n", + (float)uar_stats[uarZONESearches]/(float)uar_stats[uarZONEFinds]); fprintf(r, "\n\n"); (void)fclose(r); *** uar.c.orig Sat Dec 17 17:50:08 1994 --- uar.c Mon Sep 25 09:17:54 1995 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.6 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.7 $ * */ *************** *** 39,44 **** --- 39,45 ---- char *interface = NULL; /* Network interface */ char *progname = NULL; /* Saved argv[0] */ char *thisZone = NULL; /* server zone name */ + char *timesrvr = NULL; /* time server name */ char *linep; /* line pointer for configure() */ u_char baddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* broadcast */ *************** *** 50,61 **** --- 51,64 ---- struct iflist iflist[MAXIF]; /* interface list */ u_char buf[BUFSIZE]; /* receive buffer */ + char hostname[MAXHOST]; /* machine name */ main(argc, argv) int argc; char *argv[]; { + char *p; int c, i; fd_set fdset; int nfds, res; *************** *** 63,77 **** extern char *optarg; extern int optind, opterr; void cap_initialize(), readcap(); void readeth(), readaarp(), readdev(); void configure(), process(), cleanup(); ! void aarp_initialize(), aarp_dump_sig(); ! void stats_initialize(), stats_dump_sig(); ! void rtmp_initialize(), rtmp_dump_sig(), rtmp_seed(); ! void zip_initialize(), zip_multicast(), zone_dump_sig(); void usage(), log(); int write_eth(); int init_eth(); opterr = 0; progname = *argv; --- 66,83 ---- extern char *optarg; extern int optind, opterr; void cap_initialize(), readcap(); + void rtmp_initialize(), rtmp_seed(); + void zip_initialize(), zip_multicast(); + void aarp_initialize(), nbp_initialize(), stats_initialize(); void readeth(), readaarp(), readdev(); void configure(), process(), cleanup(); ! void uar_dump_sig(); void usage(), log(); + void strcpycp(); int write_eth(); int init_eth(); + long strtol(); + void exit(); opterr = 0; progname = *argv; *************** *** 83,88 **** --- 89,95 ---- stats_initialize(); aarp_initialize(); rtmp_initialize(); + nbp_initialize(); zip_initialize(); /* *************** *** 91,109 **** */ (void)signal(SIGINT, cleanup); (void)signal(SIGTERM, cleanup); ! (void)signal(SIGHUP, rtmp_dump_sig); ! (void)signal(SIGQUIT, aarp_dump_sig); ! (void)signal(SIGUSR1, zone_dump_sig); ! (void)signal(SIGUSR2, stats_dump_sig); /* * process command line options * */ ! while ((c = getopt(argc, argv, "d:f:l:z:c12C")) != -1) { switch (c) { case 'd': ! debug = strtol(optarg, NULL, 0); break; case 'f': conffile = optarg; --- 98,116 ---- */ (void)signal(SIGINT, cleanup); (void)signal(SIGTERM, cleanup); ! (void)signal(SIGQUIT, uar_dump_sig); ! (void)signal(SIGHUP, SIG_IGN); ! (void)signal(SIGUSR1, SIG_IGN); ! (void)signal(SIGUSR2, SIG_IGN); /* * process command line options * */ ! while ((c = getopt(argc, argv, "d:f:l:t:z:c12Cv")) != -1) { switch (c) { case 'd': ! debug = (int)strtol(optarg, (char **)NULL, 0); break; case 'f': conffile = optarg; *************** *** 111,116 **** --- 118,130 ---- case 'l': logfile = optarg; break; + case 't': + timesrvr = optarg; + break; + case 'v': + fprintf(stderr, "UAR 1.0.16 September 1995\n"); + exit(0); + break; case 'z': thisZone = optarg; break; *************** *** 142,148 **** #endif /* sony_phaseII */ #endif /* sony_news */ ! gettimeofday(&tn, NULL); log("UAR starting"); --- 156,172 ---- #endif /* sony_phaseII */ #endif /* sony_news */ ! /* ! * find host name ! * ! */ ! hostname[0] = '\0'; ! if (gethostname(hostname, MAXHOST) == 0) { ! if ((p = (char *)index(hostname, '.')) != NULL) ! *p = '\0'; /* kill host domain names */ ! } ! ! (void)gettimeofday(&tn, (struct timezone *)NULL); log("UAR starting"); *************** *** 162,167 **** --- 186,192 ---- iflist[numintfc].phase = phase; iflist[numintfc].count = AARPCount; iflist[numintfc].if_name = argv[optind]; + iflist[numintfc].if_timesrvr[0] = '\0'; iflist[numintfc].defzone = ZONENULL; iflist[numintfc].ourzone = ZONENULL; iflist[numintfc].clients = 0; *************** *** 169,181 **** iflist[numintfc].write = write_eth; iflist[numintfc].reade = readeth; iflist[numintfc].reada = readaarp; bzero((char *)iflist[numintfc].eaddr, sizeof(iflist[numintfc].eaddr)); ! for (i = 0; i < MAXNODES; i++) { ! iflist[numintfc].mnode[i].client = MNODE_UNUSED; ! iflist[numintfc].mnode[i].state = MNODE_UNUSED; ! iflist[numintfc].mnode[i].addr = 0; ! } } if (numintfc == 0) { --- 194,210 ---- iflist[numintfc].write = write_eth; iflist[numintfc].reade = readeth; iflist[numintfc].reada = readaarp; + iflist[numintfc].rtmps = NULL; bzero((char *)iflist[numintfc].eaddr, sizeof(iflist[numintfc].eaddr)); ! iflist[numintfc].if_nbpname[1] = '\0'; ! p = (char *)iflist[numintfc].if_nbpname; ! strncat(p+1, hostname, 25); ! strncat(p+1, "-", 1); ! strncat(p+1, iflist[numintfc].if_name, 5); ! p[0] = (char)strlen(p+1); ! bzero((char *)iflist[numintfc].mnode, ! sizeof(iflist[numintfc].mnode)); } if (numintfc == 0) { *************** *** 250,255 **** --- 279,292 ---- * */ iflist[i].hint = iflist[i].node; + + /* + * timeserver required ? + * + */ + if (i == 0 && timesrvr != NULL + && iflist[0].if_timesrvr[0] == '\0') + strcpycp(timesrvr, iflist[0].if_timesrvr); } if (debug) *************** *** 319,325 **** to.tv_usec = 200000; /* 200 ms */ if ((res = select(nfds, &fdset, (fd_set *)0, (fd_set *)0, &to))>=0){ ! gettimeofday(&tn, NULL); for (i = 0; i < numintfc; i++) { if (iflist[i].etfd >= 0) if (FD_ISSET(iflist[i].etfd, &fdset)) --- 356,362 ---- to.tv_usec = 200000; /* 200 ms */ if ((res = select(nfds, &fdset, (fd_set *)0, (fd_set *)0, &to))>=0){ ! (void)gettimeofday(&tn, (struct timezone *)NULL); for (i = 0; i < numintfc; i++) { if (iflist[i].etfd >= 0) if (FD_ISSET(iflist[i].etfd, &fdset)) *************** *** 343,350 **** void usage() { ! fprintf(stderr, "usage: %s [-d flags] [-f uar.conf] [-c]\n", progname); ! fprintf(stderr, "\t[-C] [-l logfile] [-z zone] [-1] [-2] interfaces\n"); return; } --- 380,388 ---- void usage() { ! fprintf(stderr, "usage: %s [-d flags] [-f uar.conf]\n", progname); ! fprintf(stderr, "\t[-c] [-C] [-l logfile] [-t timeserver]\n"); ! fprintf(stderr, "\t[-z zone] [-1] [-2] interfaces\n"); return; } *************** *** 379,392 **** --- 417,433 ---- { static int rtmpValTimer = 0; static int rtmpTimer = 0; + static int nbpTimer = 0; static int zipTimer = 0; extern int rtmp_do_dump; + extern int nbp_do_dump; extern int aarp_do_dump; extern int zone_do_dump; extern int stats_do_dump; void rtmp_process(), rtmp_timer(); void aarp_process(), aarp_dump(); void zip_process(), zone_dump(); + void nbp_process(), nbp_dump(); void rtmp_dump(), stats_dump(); /* *************** *** 418,427 **** } /* * ZIP process * */ ! if (zipTimer++ >= ZIPTimer) { zipTimer = 0; zip_process(); } --- 459,477 ---- } /* + * NBP process + * + */ + if (nbpTimer++ >= NBPTimer) { + nbpTimer = 0; + nbp_process(); + } + + /* * ZIP process * */ ! if (zipTimer++ >= ZIPTimer) { zipTimer = 0; zip_process(); } *************** *** 440,445 **** --- 490,499 ---- rtmp_do_dump = 0; rtmp_dump(); } + if (nbp_do_dump) { + nbp_do_dump = 0; + nbp_dump(); + } if (aarp_do_dump) { aarp_do_dump = 0; aarp_dump(); *************** *** 457,467 **** } /* * display packet content in hex and ascii * */ ! int dumppacket(pkt, len) u_char *pkt; int len; --- 511,546 ---- } /* + * UAR dump signal handler + * + */ + + void + uar_dump_sig() + { + extern int rtmp_do_dump; + extern int nbp_do_dump; + extern int aarp_do_dump; + extern int zone_do_dump; + extern int stats_do_dump; + + rtmp_do_dump = 1; + nbp_do_dump = 1; + aarp_do_dump = 1; + zone_do_dump = 1; + stats_do_dump = 1; + + (void)signal(SIGQUIT, uar_dump_sig); + + return; + } + + /* * display packet content in hex and ascii * */ ! void dumppacket(pkt, len) u_char *pkt; int len; *************** *** 484,490 **** } } ! return(1); } /* --- 563,569 ---- } } ! return; } /* *************** *** 496,502 **** cleanup() { int i; ! void log(), zip_multicast(); for (i = 0; i < numintfc; i++) { if (iflist[i].itype == ITYPE_ETHERTALK) { --- 575,582 ---- cleanup() { int i; ! void log(), exit(); ! void zip_multicast(); for (i = 0; i < numintfc; i++) { if (iflist[i].itype == ITYPE_ETHERTALK) { *************** *** 556,561 **** --- 636,677 ---- } /* + * register NBP name of interface + * and any optional NBP services + * + */ + + void + uar_register(ifn) + { + struct ataddr ataddr; + void nbp_register(); + + ataddr.net = iflist[ifn].net; + ataddr.node = iflist[ifn].node; + ataddr.skt = AEP; + + /* + * interface name + * + */ + nbp_register(ifn, iflist[ifn].if_nbpname, + NBPTYPE, NBPZONE, &ataddr, 8, 5); + + /* + * Time server, if specified + * + */ + if (iflist[ifn].if_timesrvr[0] != '\0') { + ataddr.skt = TMLDSKT; + nbp_register(ifn, iflist[ifn].if_timesrvr, + TMLDTYPE, NBPZONE, &ataddr, 8, 5); + } + + return; + } + + /* * read the UAR configuration file * */ *************** *** 569,578 **** FILE *r, *fopen(); int ifn, phase, zlen, zones; u_short net, net_lo, net_hi, atnetshort(); ! char interface[64], name[64], value[64], line[256], znam[34], *p; struct zone *zone, *zonelist[258], *zone_make(); void cap_initialize(); void do_config(); void getfield(); if ((r = fopen(filename, "r")) == NULL) { --- 685,697 ---- FILE *r, *fopen(); int ifn, phase, zlen, zones; u_short net, net_lo, net_hi, atnetshort(); ! char interface[64], name[64], value[64], line[256], znam[NBPSTR], *p; struct zone *zone, *zonelist[258], *zone_make(); + unsigned long inet_addr(); void cap_initialize(); + void log(), exit(); void do_config(); + void strcpycp(); void getfield(); if ((r = fopen(filename, "r")) == NULL) { *************** *** 640,646 **** * */ if (strcmp(name, "zone") == 0) { ! if ((zlen = strlen(value)) > 32) { fprintf(stderr, " UAR: Zonename \"%s\" too long (%d)\n", value, zlen); exit(1); --- 759,765 ---- * */ if (strcmp(name, "zone") == 0) { ! if ((zlen = strlen(value)) > MAXNBP) { fprintf(stderr, " UAR: Zonename \"%s\" too long (%d)\n", value, zlen); exit(1); *************** *** 695,703 **** continue; } if (strcmp(name, "cap") == 0) { if (strcmp(interface, "tnnl") == 0) { ! fprintf(stderr, " UAR: cannot attach CAP to tnnl interface\n"); exit(1); } if (strcmp(value, "on") == 0) --- 814,828 ---- continue; } + if (strcmp(name, "timesrvr") == 0) { + strcpycp(value, iflist[ifn].if_timesrvr); + continue; + } + if (strcmp(name, "cap") == 0) { if (strcmp(interface, "tnnl") == 0) { ! fprintf(stderr, " UAR: cannot attach CAP to %s interface\n", ! interface); exit(1); } if (strcmp(value, "on") == 0) *************** *** 772,777 **** --- 897,903 ---- void tnnl_read(); int tnnl_write(); int tnnl_open(); + void exit(); if (net_lo != 0 && net_hi != 0 && znam[0] != '\0') { if (net_lo > net_hi) { *************** *** 784,790 **** iflist[ifn].if_name); exit(1); } ! rtmp_seed(ifn, net_lo, net_hi, znam); if (net != 0) { if (net >= net_lo && net <= net_hi) iflist[ifn].net = net; --- 910,916 ---- iflist[ifn].if_name); exit(1); } ! rtmp_seed(ifn, net_lo, net_hi, (u_char *)znam); if (net != 0) { if (net >= net_lo && net <= net_hi) iflist[ifn].net = net; *************** *** 800,806 **** iflist[ifn].if_name); exit(1); } ! rtmp_seed(ifn, net, net, znam); } if (zonelist[0] != ZONENULL) { --- 926,932 ---- iflist[ifn].if_name); exit(1); } ! rtmp_seed(ifn, net, net, (u_char *)znam); } if (zonelist[0] != ZONENULL) { *************** *** 830,835 **** --- 956,962 ---- iflist[ifn].write = NULL; iflist[ifn].reade = NULL; iflist[ifn].reada = NULL; + iflist[ifn].rtmps = NULL; } if (strcmp(iflist[ifn].if_name, "tnnl") == 0) { iflist[ifn].itype = ITYPE_TNNL; *************** *** 838,843 **** --- 965,971 ---- iflist[ifn].write = tnnl_write; iflist[ifn].reade = tnnl_read; iflist[ifn].reada = NULL; + iflist[ifn].rtmps = NULL; } return; *************** *** 886,891 **** --- 1014,1020 ---- while (*lp == ' ' || *lp == '\t') lp++; /* skip spaces/tabs */ + if (*lp == 0 || *lp == '#') { *cp = 0; return; *************** *** 928,935 **** if (*lp && *lp != ' ' && *lp != '\t' && *lp != '#') { fprintf(stderr, "garbage after string: %s", str); ! while (*lp && *lp != ' ' && ! *lp != '\t' && *lp != '#') lp++; } } --- 1057,1063 ---- if (*lp && *lp != ' ' && *lp != '\t' && *lp != '#') { fprintf(stderr, "garbage after string: %s", str); ! while (*lp && *lp != ' ' && *lp != '\t' && *lp != '#') lp++; } } *** uar.conf.orig Tue Oct 26 18:10:13 1993 --- uar.conf Fri Sep 22 15:05:21 1995 *************** *** 1,4 **** --- 1,6 ---- # + # uar.conf + # # sample configuration file for UAR # # The configuration file contains pairs of entries. *************** *** 13,24 **** # zonename - zone for interface services, ie: CAP # node - node number hint for this interface # phase { 1 | 2 } - AppleTalk Phase for this interface ! # peer - Node #/IP address mapping for tunnel # cap { on | off } - CAP services bound to this interface # # UAR is started with one or more interface names as arguments, these are # compared with the contents of the configuration file. If the interface # names match, the associated configuration is applied to that interface. # # A configuration entry must minimally contain the interface name, network # number information and zone name. The "network" field is optional if both --- 15,32 ---- # zonename - zone for interface services, ie: CAP # node - node number hint for this interface # phase { 1 | 2 } - AppleTalk Phase for this interface ! # timesrvr - AppleTalk time service enabled ! # peer - TNNL Node #/IP address mapping # cap { on | off } - CAP services bound to this interface # # UAR is started with one or more interface names as arguments, these are # compared with the contents of the configuration file. If the interface # names match, the associated configuration is applied to that interface. + # Interface names are as listed in the 'netstat -i' command. + # + # Note: To run UAR with a mixture of seed and non-seed interfaces, + # simply list all interfaces in the command line, but only enter + # configuration data for the seeded interfaces in the uar.conf file. # # A configuration entry must minimally contain the interface name, network # number information and zone name. The "network" field is optional if both *************** *** 36,49 **** # must be Phase 1 compatible, ie: non-extended network numbers and one # zone name per network number. # ! # CAP services may be bound to any one of the Ethernet interfaces by ! # specifying "cap on". CAP should be compiled for UAB, see also README. # # The special interface name "tnnl" can be used to connect two or more # EtherTalk networks via a simple IP tunnel. A tunnel has an assigned # AppleTalk network number and each host a unique node number. A "peer" # entry is used to map node numbers and IP addresses of hosts connected # to the tunnel. See also README. # interface le0 node 253 --- 44,64 ---- # must be Phase 1 compatible, ie: non-extended network numbers and one # zone name per network number. # ! # AppleTalk time service can be enabled on one or more interfaces (but only ! # one is necessary) using the "timesrvr" entry. The server name is specified ! # by the argument. Macintoshes use the Chooser extension 'tardis' to get ! # time from the selected server. ! # ! # CAP services may be bound to any ONE of the Ethernet interfaces by ! # specifying "cap on". CAP should be configured for UAR (or for UAB, ! # see also README). CAP services will be visible to all UAR interfaces. # # The special interface name "tnnl" can be used to connect two or more # EtherTalk networks via a simple IP tunnel. A tunnel has an assigned # AppleTalk network number and each host a unique node number. A "peer" # entry is used to map node numbers and IP addresses of hosts connected # to the tunnel. See also README. + # # interface le0 node 253 *** uar.h.orig Mon Mar 20 23:15:47 1995 --- uar.h Mon Sep 25 09:17:25 1995 *************** *** 15,26 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.6 $ * */ #include #include #include #include #include --- 15,27 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.7 $ * */ #include #include + #include #include #include #include *************** *** 65,85 **** #define MAXIF 10 /* maximum number of interfaces */ #define MAXNODES 256 /* maxm. nodes per interface */ #define SKTBUFSIZ 32768 /* SO_RCVBUF buffer size */ #define HDRSIZ 24 /* room for Phase 2 header */ #define BUFSIZE 4096+HDRSIZ /* main receive buffer size */ #define INFOTimer 5 /* server ZIP/Info proc (1 sec) */ #define RTMPTimer 50 /* RTMP sendRTMP timer (10 sec) */ #define RTMPValTimer 100 /* RTMP validity timer (20 sec) */ - #define NBPTimer 600 /* server NBP process (120 sec) */ #define ZIPTimer RTMPTimer /* server ZIP process (10 sec) */ - #define TICKLETimer 300 /* srvr TICKLE process (60 sec) */ #define AARPCount 10 /* # aarp packets to send */ - #define IDLECount 5 /* # tickles before disconnect */ - #define IDLETime 300 /* connection IDLE time (5 min) */ #define NBPCACHETIMEOUT 300 /* lives in local cache (5 min) */ #define ADDMULTI 0 --- 66,87 ---- #define MAXIF 10 /* maximum number of interfaces */ #define MAXNODES 256 /* maxm. nodes per interface */ + #define MAXHOST 64 /* maximum host name length */ #define SKTBUFSIZ 32768 /* SO_RCVBUF buffer size */ #define HDRSIZ 24 /* room for Phase 2 header */ #define BUFSIZE 4096+HDRSIZ /* main receive buffer size */ + #define NBPSTR 34 /* NBP string lengths */ + #define MAXNBP 32 + #define MAXDDPLEN 586 #define INFOTimer 5 /* server ZIP/Info proc (1 sec) */ + #define NBPTimer 5 /* server NBP process (1 sec) */ #define RTMPTimer 50 /* RTMP sendRTMP timer (10 sec) */ #define RTMPValTimer 100 /* RTMP validity timer (20 sec) */ #define ZIPTimer RTMPTimer /* server ZIP process (10 sec) */ #define AARPCount 10 /* # aarp packets to send */ #define NBPCACHETIMEOUT 300 /* lives in local cache (5 min) */ #define ADDMULTI 0 *************** *** 91,99 **** #define SDDPHDRSIZ 5 #define LDDPHDRSIZ 13 #define ZIPQHDRSIZ 2 #define ZIPATPHDRSIZ 8 - #define MAXDDPLEN 586 #define CAP_PORT 903 #define TNNL_PORT 9115 --- 93,102 ---- #define SDDPHDRSIZ 5 #define LDDPHDRSIZ 13 + #define NBPHDRSIZ 2 + #define ENTHDRSIZ 5 #define ZIPQHDRSIZ 2 #define ZIPATPHDRSIZ 8 #define CAP_PORT 903 #define TNNL_PORT 9115 *************** *** 111,121 **** #define NBPFWDREQ 0x04 /* NBP forward request */ #define nbpEquals '=' ! #define nbpWild 0xc5 - #define NBPTYPE "\014RemoteClient" #define ECHOMSG "[Are You There ?]" #define NETINFOZONE "UAR GetNetInfo Zone" #define PHASE1 0x01 #define PHASE2 0x02 --- 114,127 ---- #define NBPFWDREQ 0x04 /* NBP forward request */ #define nbpEquals '=' ! #define nbpApprox 0xc5 #define ECHOMSG "[Are You There ?]" #define NETINFOZONE "UAR GetNetInfo Zone" + #define TMLDTYPE "\010Timelord" + #define NBPTYPE "\003UAR" + #define NBPZONE "\001*" + #define TMLDSKT 253 #define PHASE1 0x01 #define PHASE2 0x02 *************** *** 128,134 **** #define RTMP 0x01 #define NBP 0x02 #define ATP 0x03 ! #define AEP 0x04 #define RTMPR 0x05 #define ZIP 0x06 #define ADSP 0x07 --- 134,140 ---- #define RTMP 0x01 #define NBP 0x02 #define ATP 0x03 ! #define AEP 0x04 #define RTMPR 0x05 #define ZIP 0x06 #define ADSP 0x07 *************** *** 168,173 **** --- 174,184 ---- #define MAXZIPQUERY 255 #define MAXZIPREPLYLEN 550 + #define TMLDOFFSET 0x7c25b080 /* Mac Time 00:00:00 GMT Jan 1, 1970 */ + #define TMLDGETTIME 0 + #define TMLDENOPERM 10 + #define TMLDENONE 12 + #define UAR_CONF 1 #define UAR_CONF_REQ 1 #define UAR_CONF_DATA 2 *************** *** 187,205 **** #define CAPDEBUG 0x0400 #define ARNSDEBUG 0x0800 #define TNNLDEBUG 0x1000 /* structure defns */ /* ! * multinode/tunnel support * */ struct mnode { u_char client; #define MNODE_CAP 0x01 ! #define MNODE_ARNS 0x02 ! #define MNODE_TNNL 0x03 u_char state; #define MNODE_UNUSED 0 #define MNODE_ROUTER 1 --- 198,217 ---- #define CAPDEBUG 0x0400 #define ARNSDEBUG 0x0800 #define TNNLDEBUG 0x1000 + #define TMLDDEBUG 0x2000 /* structure defns */ /* ! * multinode/special interface support * */ struct mnode { u_char client; #define MNODE_CAP 0x01 ! #define MNODE_ARNS 0x80 ! #define MNODE_TNNL 0x81 u_char state; #define MNODE_UNUSED 0 #define MNODE_ROUTER 1 *************** *** 208,213 **** --- 220,228 ---- u_long addr; }; + #define MNODE_MIN MNODE_CAP + #define MNODE_MAX MNODE_CAP + /* * structure per interface * *************** *** 232,245 **** short count; u_char eaddr[6]; char *if_name; struct zone *defzone; /* default zone for interface */ struct zone *ourzone; /* default zone for services */ ! struct mnode mnode[256]; /* multinodes for interface */ int clients; /* services supported on ifc */ int (*iopen)(); /* interface open routine */ int (*write)(); /* interface write routine */ void (*reade)(); /* ethertalk read routine */ void (*reada)(); /* aarp read routine */ }; /* --- 247,306 ---- short count; u_char eaddr[6]; char *if_name; + char *if_nbpname[NBPSTR]; /* NBP name for UAR interface */ + char *if_timesrvr[NBPSTR]; /* NBP name for Time Server */ struct zone *defzone; /* default zone for interface */ struct zone *ourzone; /* default zone for services */ ! struct mnode mnode[MAXNODES]; /* multinodes for interface */ int clients; /* services supported on ifc */ int (*iopen)(); /* interface open routine */ int (*write)(); /* interface write routine */ void (*reade)(); /* ethertalk read routine */ void (*reada)(); /* aarp read routine */ + void (*rtmps)(); /* rtmp send routine */ + }; + + /* + * packet descriptor + * + */ + + struct pd { + u_char lapType; + u_char ddpType; + u_short dstNet; + u_short srcNet; + u_char dstNode; + u_char srcNode; + u_char dstSkt; + u_char srcSkt; + short dataLen; + u_char *data; + u_char *addr; + short hop; + }; + + /* + * Read Data Structure + * + */ + + #define NUMRDS 32 + + struct RDS { + u_short dataLen; + u_char *dataPtr; + }; + + /* + * AppleTalk address + * + */ + + struct ataddr { + u_short net; + u_char node; + u_char skt; }; /* *************** *** 259,265 **** */ struct zone { ! u_char name[34]; /* zone name entry (pascal str) */ struct net *nets; /* list of nets for this zone */ struct zone *next; /* next in linked list */ }; --- 320,326 ---- */ struct zone { ! u_char name[NBPSTR]; /* zone name entry (pascal str) */ struct net *nets; /* list of nets for this zone */ struct zone *next; /* next in linked list */ }; *************** *** 275,280 **** --- 336,384 ---- }; /* + * NBP queue + * + */ + + struct nbpq { + int intfc; + short count; + short timer; + short period; + short zonlen; + struct pd opd; + u_char data[160]; + short dataLen; + u_char *modifier; + struct nbpq *next; + }; + + /* + * NBP entity list ordered by objects + * + */ + + struct nbpobj { + u_char nbpent[ENTHDRSIZ]; + u_char nbpobj[NBPSTR]; + u_char zone[NBPSTR]; + time_t when; + int intfc; + struct nbpobj *next; + }; + + /* + * NBP cache is a list sorted by type + * + */ + + struct nbptyp { + u_char nbptyp[NBPSTR]; + struct nbpobj *list; + struct nbptyp *next; + }; + + /* * RTMP table * */ *************** *** 322,392 **** }; /* - * packet descriptor - * - */ - - struct pd { - u_char lapType; - u_char ddpType; - u_short dstNet; - u_short srcNet; - u_char dstNode; - u_char srcNode; - u_char dstSkt; - u_char srcSkt; - short dataLen; - u_char *data; - u_char *addr; - short hop; - }; - - /* - * Read Data Structure - * - */ - - #define NUMRDS 32 - - struct RDS { - u_short dataLen; - u_char *dataPtr; - }; - - /* - * entity list ordered by NBP objects - * - */ - - struct cacheTuple { - u_short entNet; - u_char entNode; - u_char entSkt; - u_char entEnum; - char nbpObj[34]; - time_t when; - struct cacheTuple *next; - }; - - /* - * the NBP cache is a list sorted by NBP type - * - */ - - struct cacheEntry { - char nbpType[34]; - struct cacheTuple *list; - struct cacheEntry *next; - }; - - /* * statistics collection * */ #define incr(x) uar_stats[x]++ ! #define decr(x) uar_stats[x]-- ! #define drop(x) \ { \ if (debug) fprintf(stderr, "DROP: %s\n", stats_msg[x]); \ uar_stats[x]++; \ --- 426,438 ---- }; /* * statistics collection * */ #define incr(x) uar_stats[x]++ ! #define decr(x) uar_stats[x]-- ! #define drop(x) \ { \ if (debug) fprintf(stderr, "DROP: %s\n", stats_msg[x]); \ uar_stats[x]++; \ *************** *** 478,484 **** #define uarTNNLNotForMe 69 #define uarTNNLBogusSrc 70 ! #define maxCounters 71 /* * AppleTalk MIB Counters (per interface) --- 524,533 ---- #define uarTNNLNotForMe 69 #define uarTNNLBogusSrc 70 ! #define uarZONEFinds 71 ! #define uarZONESearches 72 ! ! #define maxCounters 73 /* * AppleTalk MIB Counters (per interface) *************** *** 493,521 **** #define ZITNULL (struct zit *)NULL #define NETNULL (struct net *)NULL - #define ZONENULL (struct zone *)NULL #define RTMPNULL (struct rtmp *)NULL #define AARPNULL (struct aarp *)NULL #define AARPQNULL (struct aarpq *)NULL /* * strings * */ ! #define ETH_THIS_NET "thisNet" ! #define ETH_THIS_NODE "thisNode" ! #define ETH_THIS_ZONE "thisZone" ! #define ETH_BRIDGE_NET "bridgeNet" ! #define ETH_BRIDGE_NODE "bridgeNode" ! #define ETH_BRIDGE_IP "bridgeIP" ! #define ETH_NIS_NET "nisNet" ! #define ETH_NIS_NODE "nisNode" ! #define ETH_ASYNC_NET "asyncNet" ! #define ETH_ASYNC_ZONE "asyncZone" ! #define ETH_INTERFACE "interface" ! #define ETH_NET_START "netRangeStart" ! #define ETH_NET_END "netRangeEnd" #ifndef ETH_DATABASE #define ETH_DATABASE "/etc/etalk.local" --- 542,573 ---- #define ZITNULL (struct zit *)NULL #define NETNULL (struct net *)NULL #define RTMPNULL (struct rtmp *)NULL + #define ZONENULL (struct zone *)NULL #define AARPNULL (struct aarp *)NULL #define AARPQNULL (struct aarpq *)NULL + #define NBPQNULL (struct nbpq *)NULL + #define NBPOBJNULL (struct nbpobj *)NULL + #define NBPTYPNULL (struct nbptyp *)NULL /* * strings * */ ! #define ETH_THIS_NET "thisNet" ! #define ETH_THIS_NODE "thisNode" ! #define ETH_THIS_ZONE "thisZone" ! #define ETH_BRIDGE_NET "bridgeNet" ! #define ETH_BRIDGE_NODE "bridgeNode" ! #define ETH_BRIDGE_IP "bridgeIP" ! #define ETH_NIS_NET "nisNet" ! #define ETH_NIS_NODE "nisNode" ! #define ETH_ASYNC_NET "asyncNet" ! #define ETH_ASYNC_ZONE "asyncZone" ! #define ETH_INTERFACE "interface" ! #define ETH_NET_START "netRangeStart" ! #define ETH_NET_END "netRangeEnd" #ifndef ETH_DATABASE #define ETH_DATABASE "/etc/etalk.local" *************** *** 532,537 **** --- 584,593 ---- #ifndef DUMP_RTMP #define DUMP_RTMP "/usr/tmp/uar.rtmp" #endif /* DUMP_RTMP */ + + #ifndef DUMP_NBP + #define DUMP_NBP "/usr/tmp/uar.nbp" + #endif /* DUMP_NBP */ #ifndef DUMP_ZONE #define DUMP_ZONE "/usr/tmp/uar.zone" *** zip.c.orig Mon Sep 25 08:56:39 1995 --- zip.c Mon Sep 25 09:17:39 1995 *************** *** 15,21 **** * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.5 $ * */ --- 15,21 ---- * djh@munnari.OZ.AU * * $Author: djh $ ! * $Revision: 1.1.1.6 $ * */ *************** *** 29,34 **** --- 29,35 ---- int zone_do_dump = 0; + struct zone *zoneMRU; struct zone *zoneTab; /* Ordered zone list */ static u_char zbuf[632]; /* ZIP Query/Reply data */ *************** *** 41,47 **** /* * Initialize ZIP data structures * ! * zoneTab is an unsorted list of individual zone names. Each rtmpTab * entry has a linked list of pointers to each of the zoneTab zone * names applicable to that network. Each zoneTab entry also has a * linked list of all of the network numbers belonging to that zone. --- 42,48 ---- /* * Initialize ZIP data structures * ! * zoneTab is a sorted list of individual zone names. Each rtmpTab * entry has a linked list of pointers to each of the zoneTab zone * names applicable to that network. Each zoneTab entry also has a * linked list of all of the network numbers belonging to that zone. *************** *** 53,58 **** --- 54,60 ---- zip_initialize() { zoneTab = ZONENULL; + zoneMRU = ZONENULL; return; } *************** *** 149,154 **** --- 151,157 ---- u_char *pkt; struct pd opd; struct rtmp *rtmp_route(); + void ddp_route(); if (zintfc == -1) return; *************** *** 430,435 **** --- 433,439 ---- u_char *pkt; struct pd opd; struct rtmp *rtmp_route(); + void ddp_route(); if (zcount == 0) return; *************** *** 485,492 **** int ifn; struct pd *pd; { ! u_short net, zlen; ! short len, netcount; u_char *pkt, *data, *znam; struct rtmp *rtmp, *rtmp_route(); struct zone *zone, *zone_find(), *zone_new(); --- 489,496 ---- int ifn; struct pd *pd; { ! u_short net; ! short len, zlen, netcount; u_char *pkt, *data, *znam; struct rtmp *rtmp, *rtmp_route(); struct zone *zone, *zone_find(), *zone_new(); *************** *** 512,522 **** drop(uarNoSocketHandler); data = pkt+2; ! while (netcount > 0) { net = (data[0] << 8) | data[1]; zlen = data[2]; znam = data+3; if ((zone = zone_find(znam, zlen)) == ZONENULL) { if ((zone = zone_new()) != ZONENULL) { bcopy((char *)znam, (char *)(zone->name+1), zlen); --- 516,530 ---- drop(uarNoSocketHandler); data = pkt+2; + len -= 2; ! while (len > 0) { net = (data[0] << 8) | data[1]; zlen = data[2]; znam = data+3; + #define MAXZONELEN 32 + if (zlen > MAXZONELEN) + drop(zipInErrors); if ((zone = zone_find(znam, zlen)) == ZONENULL) { if ((zone = zone_new()) != ZONENULL) { bcopy((char *)znam, (char *)(zone->name+1), zlen); *************** *** 539,545 **** zone_rtmp_add(zone, rtmp); data += (zlen+3); ! netcount--; } return; --- 547,553 ---- zone_rtmp_add(zone, rtmp); data += (zlen+3); ! len -= (zlen+3); } return; *************** *** 573,579 **** if (rtmp->dist == 0 && iflist[rtmp->intfc].phase == PHASE2) { if (iflist[rtmp->intfc].etfd >= 0) { ! if ((zaddr = zone_mcast(zone->name+1, zone->name[0])) != NULL) { eth_addmulti(iflist[rtmp->intfc].etfd, iflist[rtmp->intfc].if_name, zaddr); if (debug & ZIPDEBUG) { --- 581,587 ---- if (rtmp->dist == 0 && iflist[rtmp->intfc].phase == PHASE2) { if (iflist[rtmp->intfc].etfd >= 0) { ! if ((zaddr = zone_mcast(zone->name+1,(short)zone->name[0]))!=NULL) { eth_addmulti(iflist[rtmp->intfc].etfd, iflist[rtmp->intfc].if_name, zaddr); if (debug & ZIPDEBUG) { *************** *** 581,587 **** iflist[rtmp->intfc].if_name); fprintf(stderr, " %02x:%02x:%02x:%02x:%02x:%02x \"%s\"\n", zaddr[0], zaddr[1], zaddr[2], zaddr[3], zaddr[4], zaddr[5], ! zone->name+1); } } } --- 589,595 ---- iflist[rtmp->intfc].if_name); fprintf(stderr, " %02x:%02x:%02x:%02x:%02x:%02x \"%s\"\n", zaddr[0], zaddr[1], zaddr[2], zaddr[3], zaddr[4], zaddr[5], ! zone->name+1); } } } *************** *** 629,650 **** zit = rtmp->zitlist; while (zit != ZITNULL) { ! zaddr = zone_mcast(zit->zone->name+1, zit->zone->name[0]); if (zaddr != NULL) { if (fn == ADDMULTI) { if (iflist[ifn].etfd >= 0) eth_addmulti(iflist[ifn].etfd, iflist[ifn].if_name, zaddr); ! } else { if (iflist[ifn].etfd >= 0) eth_delmulti(iflist[ifn].etfd, iflist[ifn].if_name, zaddr); } if (debug & ZIPDEBUG) { fprintf(stderr, " ZIP: %-5s %s Zone Multicast", iflist[rtmp->intfc].if_name, ! (fn == ADDMULTI) ? "Adding" : "Deleting"); fprintf(stderr, " %02x:%02x:%02x:%02x:%02x:%02x \"%s\"\n", zaddr[0], zaddr[1], zaddr[2], zaddr[3], zaddr[4], zaddr[5], ! zit->zone->name+1); } } zit = zit->next; --- 637,658 ---- zit = rtmp->zitlist; while (zit != ZITNULL) { ! zaddr = zone_mcast(zit->zone->name+1, (short)zit->zone->name[0]); if (zaddr != NULL) { if (fn == ADDMULTI) { if (iflist[ifn].etfd >= 0) eth_addmulti(iflist[ifn].etfd, iflist[ifn].if_name, zaddr); ! } else { /* DELMULTI */ if (iflist[ifn].etfd >= 0) eth_delmulti(iflist[ifn].etfd, iflist[ifn].if_name, zaddr); } if (debug & ZIPDEBUG) { fprintf(stderr, " ZIP: %-5s %s Zone Multicast", iflist[rtmp->intfc].if_name, ! (fn == ADDMULTI) ? "Adding" : "Deleting"); fprintf(stderr, " %02x:%02x:%02x:%02x:%02x:%02x \"%s\"\n", zaddr[0], zaddr[1], zaddr[2], zaddr[3], zaddr[4], zaddr[5], ! zit->zone->name+1); } } zit = zit->next; *************** *** 665,676 **** int ifn; struct pd *pd; { - u_char *pkt, *znam, *mcast, *zaddr, *zone_mcast(); short len, zlen, zvalid, zcount; ! struct rtmp *rtmp, *rtmp_find(); ! struct rtmp *rtmp_route(); struct zit *zit; struct pd opd; pkt = pd->data; len = pd->dataLen; --- 673,684 ---- int ifn; struct pd *pd; { short len, zlen, zvalid, zcount; ! u_char *pkt, *znam, *mcast, *zaddr, *zone_mcast(); ! struct rtmp *rtmp, *rtmp_find(), *rtmp_route(); struct zit *zit; struct pd opd; + void ddp_route(); pkt = pd->data; len = pd->dataLen; *************** *** 791,805 **** u_char *znam; short zlen; { ! u_char zone[34]; u_short i, chkSum(); static u_char zmcaddr[6]; if (zlen > sizeof(zone)) return(NULL); for (i = 0; i < zlen; i++) ! zone[i] = (u_char)zip_toupper(znam[i]); zmcaddr[0] = 0x09; zmcaddr[1] = 0x00; --- 799,814 ---- u_char *znam; short zlen; { ! u_char zone[NBPSTR]; u_short i, chkSum(); + u_char mactoupper(); static u_char zmcaddr[6]; if (zlen > sizeof(zone)) return(NULL); for (i = 0; i < zlen; i++) ! zone[i] = mactoupper(znam[i]); zmcaddr[0] = 0x09; zmcaddr[1] = 0x00; *************** *** 830,835 **** --- 839,845 ---- struct pd opd; u_char *pkt, buf[80]; struct rtmp *rtmp_route(); + void ddp_route(); pkt = buf+HDRSIZ+LDDPHDRSIZ; *************** *** 893,899 **** short len, zlen, mlen; u_char *pkt, *znam, *mcast; struct zone *zone, *zone_find(), *zone_new(); ! void zone_insert(), rtmp_intfc(); pkt = pd->data; len = pd->dataLen; --- 903,911 ---- short len, zlen, mlen; u_char *pkt, *znam, *mcast; struct zone *zone, *zone_find(), *zone_new(); ! void log(), cleanup(); ! void zone_insert(); ! void rtmp_intfc(); pkt = pd->data; len = pd->dataLen; *************** *** 1091,1096 **** --- 1103,1109 ---- struct rtmp *rtmp_route(); struct zone *zone, *zone_default(); struct pd opd; + void ddp_route(); if (idx != 0) drop(uarBadPacketHdr); *************** *** 1261,1266 **** --- 1274,1280 ---- u_char *pkt; struct pd opd; struct rtmp *rtmp_route(); + void ddp_route(); pkt = zbuf+HDRSIZ+LDDPHDRSIZ; *************** *** 1332,1338 **** } /* ! * find a zone in the zone table * */ --- 1346,1352 ---- } /* ! * find a zone in the (sorted) zone table * */ *************** *** 1341,1353 **** u_char *znam; short zlen; { struct zone *zone; ! zone = zoneTab; ! while (zone != ZONENULL) { if (zstrncmpci(zone->name+1, znam, zlen) == 0) return(zone); zone = zone->next; } --- 1355,1396 ---- u_char *znam; short zlen; { + int scmp, ifn; struct zone *zone; + extern int numintfc; ! incr(uarZONEFinds); ! /* ! * check if most-recently-used ! * ! */ ! if ((zone = zoneMRU) != ZONENULL) { ! incr(uarZONESearches); if (zstrncmpci(zone->name+1, znam, zlen) == 0) return(zone); + } + + /* + * check interface default zones + * + */ + for (ifn = 0; ifn < numintfc; ifn++) { + if ((zone = iflist[ifn].defzone) != ZONENULL) { + incr(uarZONESearches); + if (zstrncmpci(zone->name+1, znam, zlen) == 0) + return((zoneMRU = zone)); + } + } + + zone = zoneTab; + + while (zone != ZONENULL) { + incr(uarZONESearches); + if ((scmp = zstrncmpci(zone->name+1, znam, zlen)) == 0) + return((zoneMRU = zone)); + if (scmp > 0) + break; zone = zone->next; } *************** *** 1363,1370 **** zone_insert(zone) struct zone *zone; { ! zone->next = zoneTab; ! zoneTab = zone; return; } --- 1406,1430 ---- zone_insert(zone) struct zone *zone; { ! struct zone *p, *q; ! int zstrncmpci(); ! ! p = zoneTab; ! q = ZONENULL; ! ! while (p != ZONENULL) { ! if (zstrncmpci(p->name+1, zone->name+1, (short)*zone->name) > 0) ! break; ! q = p; ! p = p->next; ! } ! ! zone->next = p; ! ! if (q == ZONENULL) ! zoneTab = zone; ! else ! q->next = zone; return; } *************** *** 1382,1388 **** void zone_insert(), exit(); struct zone *zone, *zone_find(), *zone_new(); ! if ((zlen = strlen((char *)znam)) > 32) { fprintf(stderr, " UAR: Zonename \"%s\" too long (%d)\n", znam, zlen); exit(1); } --- 1442,1448 ---- void zone_insert(), exit(); struct zone *zone, *zone_find(), *zone_new(); ! if ((zlen = strlen((char *)znam)) > MAXNBP) { fprintf(stderr, " UAR: Zonename \"%s\" too long (%d)\n", znam, zlen); exit(1); } *************** *** 1444,1450 **** { short zlen; u_char *znam; ! static u_char name[34]; struct zone *zone, *zone_default(); name[0] = '\0'; --- 1504,1510 ---- { short zlen; u_char *znam; ! static u_char name[NBPSTR]; struct zone *zone, *zone_default(); name[0] = '\0'; *************** *** 1466,1485 **** } /* - * zone dump signal handler - * - */ - - void - zone_dump_sig() - { - zone_do_dump = 1; - (void)signal(SIGUSR1, zone_dump_sig); - - return; - } - - /* * dump the zone table * */ --- 1526,1531 ---- *************** *** 1507,1517 **** while (net != NETNULL) { if (net->net_lo == net->net_hi) fprintf(r, " %3d.%-3d ", ! net->net_lo >> 8, net->net_lo & 0xff); else fprintf(r, " %3d.%-3d - %3d.%-3d", ! net->net_lo >> 8, net->net_lo & 0xff, ! net->net_hi >> 8, net->net_hi & 0xff); net = net->next; if (net != NETNULL && (++lnum%0x04) == 0) fprintf(r, "\n%24s", ""); --- 1553,1563 ---- while (net != NETNULL) { if (net->net_lo == net->net_hi) fprintf(r, " %3d.%-3d ", ! net->net_lo >> 8, net->net_lo & 0xff); else fprintf(r, " %3d.%-3d - %3d.%-3d", ! net->net_lo >> 8, net->net_lo & 0xff, ! net->net_hi >> 8, net->net_hi & 0xff); net = net->next; if (net != NETNULL && (++lnum%0x04) == 0) fprintf(r, "\n%24s", ""); *************** *** 1550,1694 **** } /* ! * Case insensitive version of strcmp for zone names ! * (first arg is null terminated, second arg length n) * */ int zstrncmpci(s, t, n) ! register char *s, *t; ! register int n; { ! register int c, d; for ( ; n > 0 ; n--) { ! c = *s++; ! if (isascii(c)) { ! if (isupper(c)) ! c = tolower(c); ! } else ! c = zip_tolower(c); ! d = *t++; ! if (isascii(d)) { ! if (isupper(d)) ! d = tolower(d); ! } else ! d = zip_tolower(d); if (c != d) return(c-d); } - return((*s == '\0') ? 0 : *s); - } - - /* - * map uppercase to lowercase - * - */ ! int ! zip_tolower(c) ! int c; ! { ! if (!(c & 0x80)) ! return(tolower(c)); ! ! switch (c) { ! case 0xcb: ! return(0x88); ! break; ! case 0x80: ! return(0x8a); ! break; ! case 0xcc: ! return(0x8b); ! break; ! case 0x81: ! return(0x8c); ! break; ! case 0x82: ! return(0x8d); ! break; ! case 0x83: ! return(0x8e); ! break; ! case 0x84: ! return(0x96); ! break; ! case 0x85: ! return(0x9a); ! break; ! case 0xcd: ! return(0x9b); ! break; ! case 0x86: ! return(0x9f); ! break; ! case 0xae: ! return(0xbe); ! break; ! case 0xaf: ! return(0xbf); ! break; ! case 0xce: ! return(0xcf); ! break; ! } ! return(c); ! } ! ! /* ! * convert lowercase to uppercase ! * ! */ ! ! int ! zip_toupper(c) ! int c; ! { ! if (!(c & 0x80)) ! return(toupper(c)); ! ! switch (c) { ! case 0x88: ! return(0xcb); ! break; ! case 0x8a: ! return(0x80); ! break; ! case 0x8b: ! return(0xcc); ! break; ! case 0x8c: ! return(0x81); ! break; ! case 0x8d: ! return(0x82); ! break; ! case 0x8e: ! return(0x83); ! break; ! case 0x96: ! return(0x84); ! break; ! case 0x9a: ! return(0x85); ! break; ! case 0x9b: ! return(0xcd); ! break; ! case 0x9f: ! return(0x86); ! break; ! case 0xbe: ! return(0xae); ! break; ! case 0xbf: ! return(0xaf); ! break; ! case 0xcf: ! return(0xce); ! break; ! } ! return(c); } --- 1596,1622 ---- } /* ! * Case insensitive version of strncmp() for zone names ! * ! * (first arg is null terminated, second arg is of ! * length n and is NOT necessarily null terminated) * */ int zstrncmpci(s, t, n) ! register u_char *s, *t; ! register short n; { ! register u_char c, d; ! u_char mactolower(); for ( ; n > 0 ; n--) { ! c = mactolower(*s++); ! d = mactolower(*t++); if (c != d) return(c-d); } ! return((*s == '\0') ? 0 : *s); }