/*********************************************************/ /* ----------------------------------------------------- */ /* activate Firewall in OS/2 TCP/IP V 4.1 and up */ /* Functions: Filter ADD DELET MOVE VIEW */ /* A-Net GmbH Zumikon, www.anetgmbh.ch */ /* ----------------------------------------------------- */ /* Version 0.5 */ /* ----------------------------------------------------- */ /* */ /* IMPORTANT: Use at own risk !!! */ /* */ /*********************************************************/ /*********************************************************/ /* ----------------------------------------------------- */ /* test prerequisites (drivers, fwfiltrs.cnf, OS/2) */ /* ----------------------------------------------------- */ /*********************************************************/ /* -------------------------------------------------------------- */ /* seek boot drive an test, if fwfiltrs.cnf is present */ /* -------------------------------------------------------------- */ do forever os2c = strip(left(stream('c:\os2\cmd.exe','c','query exists'),1)) os2d = strip(left(stream('d:\os2\cmd.exe','c','query exists'),1)) os2e = strip(left(stream('e:\os2\cmd.exe','c','query exists'),1)) os2f = strip(left(stream('f:\os2\cmd.exe','c','query exists'),1)) /* multiple OS/2 installations? */ i = '0' if os2c <> '' then i = i + 1 if os2d <> '' then i = i + 1 if os2e <> '' then i = i + 1 if i == '1' then do /* only one OS/2 found */ letter = os2c||os2d||os2e||os2f say '' say 'OS/2 found on' letter':' leave end /* do */ if i > '1' then do forever say '' say 'Several OS/2 installations found on' os2c os2d os2e os2f say 'Please select desired drive letter: ' pull letter if letter = 'C' | letter = 'D' | letter = 'E' | letter = 'F' | letter = 'G' then leave say 'invalid selection' end /* do forever */ if i = '0' then do say '' say 'No OS/2 found on C: D: E: F:' say 'Installation aborted' pull . Exit end /* do */ end /* do forever */ /* OS/2 found, seek FilterFile */ filter = stream(letter':\mptn\etc\security\fwfiltrs.cnf','c','query exists') if filter = '' then do say '------------------------------------------------------' say 'no filter file found' say 'If TCP/IP V 4.1 or up is installed' say 'a new file ' letter':\mptn\etc\security\fwfiltrs.cnf can be created' say 'Shall we do that for You (y/n)?' pull answer if answer = 'N' then EXIT if answer = 'Y' then do '@echo off' 'md ' letter':\MPTN > nul' 'md ' letter':\MPTN\ETC > nul' 'md ' letter':\MPTN\ETC\SECURITY > nul' 'echo # OS/2 FirewallFilter (generated by A-Net GmbH) > ' letter':\mptn\etc\security\fwfiltrs.cnf' end /* if */ end /* do */ else say 'filter file ' letter':\mptn\etc\security\fwfiltrs.cnf found' /* seek Secure Interface, if not present create empty file */ fwsec = stream(letter':\mptn\etc\fwsecad.cnf','c','query exists') if fwsec = '' then do say '------------------------------------------------------' say 'no file with IP address of the secure interface found' say 'The file can be generated automatically? ' letter':\mptn\etc\fwsecad.cnf' say 'Shall we do that for You (y/n)?' pull answer if answer = 'N' then EXIT if answer = 'Y' then do '@echo off' 'echo 127.0.0.1 > ' letter':\mptn\etc\fwsecad.cnf' end /* if */ end /* do */ else say 'SecureAdapter File ' letter':\mptn\etc\fwsecad.cnf found' /* ------------------------------------------- */ /* importatnt variables with path an file name */ /* ------------------------------------------- */ drive = letter':\mptn\etc\security\' /* default filter directory */ infile = 'fwfiltrs.cnf' /* existing filter config file */ outfile = 'fwfiltrs.new' /* new filter config file */ configsys = letter':\config.sys' configsav = letter':\config.fw0' 'echo off' 'if exist ' drive||outfile ' erase ' drive||outfile say '' /* -------------------------------------------------- */ /* Test, if FWIP.SYS is loaded */ /* -------------------------------------------------- */ fwip = '0' do while lines(configsys)>0 line = translate(strip(linein(configsys))) if left(line,6)<> 'DEVICE' then iterate if pos('FWIP.SYS',line) >0 then fwip = '1' /* driver found */ end call stream configsys,'c','close' /* close file */ if fwip = '0' then do say '' say '------------------------------------------------------' say 'driver for OS/2 Firewall is not installed' say 'Should FWIP.SYS be added to config.sys (y/n)?' pull answer if answer = 'Y' then do if stream(letter':\MPTN\PROTOCOL\FWIP.SYS','c','query exists') = ''then do say '************************************************************' say 'FWIP.SYS driver not found, CONFIG.SYS unchanged ' say 'Are You shure that TCP/IP 4.1 or up is installed?' say 'The firewall will not be functioning like this!' say 'But You can still define filters,' say 'for another system.' say '************************************************************' say '' beep(450,50) end /* if */ else do 'copy ' configsys configsav /* save old CONFIG.SYS */ 'echo REM driver for OS/2 Firewall >>'letter':\CONFIG.SYS' 'echo DEVICE='letter':\MPTN\PROTOCOL\FWIP.SYS >>'letter':\CONFIG.SYS' say '' say 'Importatnt: New driver requires reboot!' say 'old ' configsys ' is saved as ' configsav say '' end /* else */ end /* do */ end /* do */ /******************************************************/ /* -------------------------------------------------- */ /* Select funtion ADD DELETE EDIT MOVE */ /* -------------------------------------------------- */ /******************************************************/ nextone: do forever say '' say '-------------------- select funktion --------------------' say 'Select a funkction:' say '1 = add new filter file' say '2 = remove old filter file' say '3 = move filter (processed from top down)' say '4 = view filter (with interpretation, without comment only lines)' say '5 = start/update firewall with these new rules' say '6 = exit program' say '---------------------------------------------------------' pull answer if answer > '0' & answer < 7 then leave /* valid entry? */ say '' say 'Select 1, 2, 3, 4, 5 or 6' beep(450,50) end /*do forever */ /* branch to selected function */ if answer = '1' then do todo = 'add' signal addfilter end /* if */ if answer = '2' then do todo = 'del' signal delfilter end /* if */ if answer = '3' then do todo = 'move' signal movefilter end /* if */ if answer = '4' then do todo = 'view' signal viewfilter end /* if */ if answer = '5' then do 'call cfgfilt -u -i' signal nextone end /* if */ if answer = '6' then NOP exit /******************************************************/ /* -------------------------------------------------- */ /* add filter */ /* -------------------------------------------------- */ /******************************************************/ addfilter: /* comment */ say 'Filter comment (for Your comfort): ' say '-----------------------------------' pull comment say '' /* action */ do forever say 'desired action:' say '---------------' say ' 1 = block (default)' say ' 2 = allow' pull action if action = '' then action = '1' say '' if action = '1' then leave if action = '2' then leave say '**********************' say 'Invalit option' action say '**********************' say '' beep(440,50) end /* do forever */ action = word('deny permit',action) /* convert number to command */ /* sourceip */ do forever say 'IP address of sender (empty: any sender address):' say '----------------------------------------------' pull sourceip say '' if sourceip == '' then sourceip = '0.0.0.0' parse var sourceip ip1 '.' ip2 '.' ip3 '.' ip4 ok = '1' if ip1 < '0' then ok = '0' if ip1 > '255' then ok = '0' if ip2 < '0' then ok = '0' if ip2 > '255' then ok = '0' if ip3 < '0' then ok = '0' if ip3 > '255' then ok = '0' if ip4 < '0' then ok = '0' if ip4 > '255' then ok = '0' if ok == '1' then leave say '*************************************************************************' say 'invalid IP address, must be 4 numbers between 0 and 255 separated with . ' say 'e.g. 10.2.45.0' say '*************************************************************************' say ' ' beep(440,50) end /* do forever */ /* sourcemask */ do forever say 'Subnetmask of sender (Select number from 1 to 9):' say '-------------------------------------------------------' say '1 = 0.0.0.0 (all addresses)' say '2 = 255.255.255.255 (single host)' say '3 = 255.255.255.0 typical class C subnet' say '4 = 255.255.0.0' say '5 = 255.0.0.0' say '6 = 255.255.255.128 subnet with 126 hosts max.' say '7 = 255.255.255.192 subnet with 62 hosts max.' say '8 = 255.255.255.224 subnet with 30 hosts max.' say '9 = 255.255.254.0 subnet with 1022 hosts max.' pull sourcemask say '' ok = '1' if sourcemask < '1' then ok = '0' if sourcemask > '9' then ok = '0' if ok == '1' then leave say '*******************************************************************' say 'invalid option, please select 1 to 9' say '*******************************************************************' say ' ' beep(440,50) end /* do forever */ select when sourcemask == '1' then sourcemask = '0.0.0.0' when sourcemask == '2' then sourcemask = '255.255.255.255' when sourcemask == '3' then sourcemask = '255.255.255.0' when sourcemask == '4' then sourcemask = '255.255.0.0' when sourcemask == '5' then sourcemask = '255.0.0.0' when sourcemask == '6' then sourcemask = '255.255.255.128' when sourcemask == '7' then sourcemask = '255.255.255.192' when sourcemask == '8' then sourcemask = '255.255.255.224' when sourcemask == '9' then sourcemask = '255.255.254.0' otherwise NOP end /* select */ /* destip */ do forever say 'Receivers IP address (empty: any address):' say '------------------------------------------' pull destip say '' if destip == '' then destip = '0.0.0.0' parse var destip ip1 '.' ip2 '.' ip3 '.' ip4 ok = '1' if ip1 < '0' then ok = '0' if ip1 > '255' then ok = '0' if ip2 < '0' then ok = '0' if ip2 > '255' then ok = '0' if ip3 < '0' then ok = '0' if ip3 > '255' then ok = '0' if ip4 < '0' then ok = '0' if ip4 > '255' then ok = '0' if ok == '1' then leave say '*******************************************************************' say 'invalid IP address, must be 4 numbers between 0 and 255 separated with . ' say 'e.g. 10.2.45.0' say '*******************************************************************' say ' ' beep(440,50) end /* do forever */ /* destmask */ do forever say 'Subnetmask of receiver (select number from 1 to 9):' say '---------------------------------------------------' say '1 = 0.0.0.0 (alle Adressen)' say '2 = 255.255.255.255 (einzelner Host)' say '3 = 255.255.255.0' say '4 = 255.255.0.0' say '5 = 255.0.0.0' say '6 = 255.255.255.128' say '7 = 255.255.255.192' say '8 = 255.255.255.224' say '9 = 255.255.254.0' pull destmask say '' ok = '1' if destmask < '1' then ok = '0' if destmask > '9' then ok = '0' if ok == '1' then leave say '*******************************************************************' say 'invalid option, select 1 to 9' say '*******************************************************************' say ' ' beep(440,50) end /* do forever */ select when destmask == '1' then destmask = '0.0.0.0' when destmask == '2' then destmask = '255.255.255.255' when destmask == '3' then destmask = '255.255.255.0' when destmask == '4' then destmask = '255.255.0.0' when destmask == '5' then destmask = '255.0.0.0' when destmask == '6' then destmask = '255.255.255.128' when destmask == '7' then destmask = '255.255.255.192' when destmask == '8' then destmask = '255.255.255.224' when destmask == '9' then destmask = '255.255.254.0' otherwise NOP end /* select */ /* protocol */ do forever say 'Select protocol: ' say '-----------------' say 'all, tcp, tcp/ack, udp, icmp, ospf, ipip, esp, ah' say '(ipip = IP in IP, esp = encapsulatin security, ah = authentication header)' parse pull protocol say '' ok = '0' if protocol = 'all' then ok = '1' if protocol = 'tcp' then ok = '1' if protocol = 'tcp/ack' then ok = '1' if protocol = 'udp' then ok = '1' if protocol = 'icmp' then ok = '1' if protocol = 'ospf' then ok = '1' if protocol = 'ipip' then ok = '1' if protocol = 'esp' then ok = '1' if protocol = 'ah' then ok = '1' if ok ='1' then leave say '************************' say 'invalid option ' protocol say '************************' say '' beep(440,50) end /* do forever */ /* srcopcode */ do forever say 'Select operand for sender port :' say '--------------------------------' say 'any (any port)' say 'eq (equal)' say 'gt (greater than)' say 'lt (lesser than)' say 'neq (not equal)' say 'ge (greater or equal)' say 'le (lesser or equal)' parse pull srcopcode say '' ok = '0' if srcopcode = 'any' then ok = '1' if srcopcode = 'eq' then ok = '1' if srcopcode = 'gt' then ok = '1' if srcopcode = 'lt' then ok = '1' if srcopcode = 'neq' then ok = '1' if srcopcode = 'ge' then ok = '1' if srcopcode = 'le' then ok = '1' if ok ='1' then leave say '**********************' say 'invalid option ' srcopcode say '**********************' say '' beep(440,50) end /* do forever */ /* srcport */ do forever if srcopcode == 'any' then do srcport = '0' leave end /* if*/ say 'Select sender port (1 to 65535): ' say '--------------------------------------' say '(21 = FTP File Transfer)' say '(23 = Telnet)' say '(25 = SMTP, sending Mail)' say '(37 = Time Server)' say '(53 = DNS, Domain Name Server)' say '(79 = Finger)' say '(80 = HTTP, Browser)' say '(110 = POP3, get Mail)' say '(139 = NetBios Session)' say '(161 = SNMP)' parse pull srcport say '' ok = '1' if srcport < '1' then ok = '0' if srcport > '65535' then ok = '0' if ok ='1' then leave say '**********************' say 'invalid option' srcport say '**********************' say '' beep(440,50) end /* do forever */ /* destopcode */ do forever say 'Select operand for receiver port: ' say '----------------------------------' say 'any (any port)' say 'eq (equal)' say 'gt (greater than)' say 'lt (lesser than)' say 'neq (not equal)' say 'ge (greater or equal)' say 'le (lesser or equal)' parse pull destopcode say '' ok = '0' if destopcode = 'any' then ok = '1' if destopcode = 'eq' then ok = '1' if destopcode = 'gt' then ok = '1' if destopcode = 'lt' then ok = '1' if destopcode = 'neq' then ok = '1' if destopcode = 'ge' then ok = '1' if destopcode = 'le' then ok = '1' if ok ='1' then leave say '**********************' say 'Invalid option ' destopcode say '**********************' say '' beep(440,50) end /* do forever */ /* destport */ do forever if destopcode == 'any' then do destport = '0' leave end /* if*/ say 'Empf„nger-Port eingeben (1 bis 65535): ' say '---------------------------------------' say '(21 = FTP File Transfer)' say '(23 = Telnet)' say '(25 = SMTP, sending mail)' say '(37 = Time Server)' say '(53 = DNS, Domain Name Service)' say '(79 = Finger)' say '(80 = HTTP, Browser)' say '(110 = POP3, get mail)' say '(139 = NetBios Session)' say '(161 = SNMP)' parse pull destport say '' ok = '1' if destport < '1' then ok = '0' if destport > '65535' then ok = '0' if ok ='1' then leave say '**********************' say 'Invalid option ' destport say '**********************' say '' beep(440,50) end /* do forever */ /* interface */ do forever say 'Select LAN adapter: ' say '----------------' say '1 = any LAN adapter (default) (= both)' say '2 = secure adapter, internal LAN (= secure)' say '3 = unsecure adapter, toward the Internet (= non-secure)' parse pull interface say '' if interface == '' then interface = '1' ok = '1' if interface < '1' then ok = '0' if interface > '3' then ok = '0' if ok == '1' then leave say '**********************' say 'Invalid option ' interface say '**********************' say '' beep(440,50) end /* do forever */ interface = word('both secure non-secure',interface) /* compute interface from number */ /* routing */ do forever say 'Select routing w„hlen: ' say '----------------------' say '1 or empty = all pakets (= both)' say '2 = only pakets to/from this PC (= local)' say '3 = only traversing pakets (= route)' parse pull routing say '' if routing == '' then routing = '1' ok = '1' if routing < '1' then ok = '0' if routing > '3' then ok = '0' if ok == '1' then leave say '**********************' say 'Invalid option ' routing say '**********************' say '' beep(440,50) end /* do forever */ routing = word('both local route',routing) /* compute parameter from number */ /* direction */ do forever say 'Select direction of pakets: ' say '----------------------------' say '1 or empty = incoming and outgoing pakets (= both)' say '2 = only incoming pakets (= inbound)' say '3 = only outgoing pakets (= outbound)' parse pull direction say '' if direction == '' then direction = '1' ok = '1' if direction < '1' then ok = '0' if direction > '3' then ok = '0' if ok == '1' then leave say '**********************' say 'Invalid option ' direction say '**********************' say '' beep(440,50) end /* do forever */ direction = word('both inbound outbound',direction) /* computer word from number */ /* log */ say 'Shall these pakets be logged? (y/n): ' say '------------------------------------' say 'empty = no' pull log say '' if log == 'Y' then log = 'l=yes' else log = 'l=no' /* fragment */ do forever say 'How to treat fragmented pakets? ' say '-------------------------------' say '1 or empty = apply to whole pakets and framgments' say '2 = appyl only to whole pakets' say '3 = appyl only to fragments and fragemnet headers' say '4 = apply only to fragment headers and whole pakets' pull fragment say '' if fragment == '' then fragment = '1' ok = '1' if fragment < '1' then ok = '0' if fragment > '4' then ok = '0' if ok == '1' then leave say '**********************' say 'Invalid option ' fragment say '**********************' say '' beep(440,50) end /* do forever */ fragment = word('f=yes f=no f=only f=headers',fragment) /* computer word from number */ /* tunnelid */ do forever say 'Tunnel-ID (only for VPN): ' say '(in case of VPN tunnel pakets must pass another filter' say '------------------------------------------------------' say 'empty = no tunnel ID (=default)' pull tunnelid say '' if tunnelid == '' then leave /* no VPN Definition */ if tunnelid > '0' & tunnelid < '1000000' then leave /* Id valid */ say '*****************************************' say 'Tunnel ID must be between 0 and 999999' say '*****************************************' beep(450,50) end /* do forever */ tunnelid = 't='tunnelid /* Show all entered parameters */ say '------------------------- Control display of new filter ------------------------' say 'Comment: ' comment say 'Action: ' action say 'Sender IP: ' sourceip ' Sender Mask: ' sourcemask say 'Receiver IP ' destip ' Receiver Mask: ' destmask say 'Protocol: ' protocol say 'SenderOPcode: ' srcopcode ' Sender Port: ' srcport say 'ReceiverOPcode: ' destopcode ' Receiver Port: ' destport say 'Adapter: ' interface say 'Routing: ' routing say 'Direction: ' direction say 'Log: ' log say 'Fragment: ' fragment say 'TunnelID: ' tunnelid say '-------------------------------------------------------------------------------' say '' do forever say 'Filter ok (y/n)?' pull neu if neu == 'N' then signal addfilter /* cancel and ask again */ if neu == 'Y' then leave say 'Please enter just y or n' end /* do forever */ /* new line in fwfiltrs.cnf will be: */ linenew = action sourceip sourcemask destip destmask protocol srcopcode srcport destopcode destport interface routing direction log fragment tunnelid '#' comment say '' /********************************************************************/ /* ---------------------------------------------------------------- */ /* change filter file */ /* insert, delete, move, depending on value of 'todo' */ /* ---------------------------------------------------------------- */ /********************************************************************/ delfilter: movefilter: /* -------------------------------------------------- */ /* read filter file */ /* -------------------------------------------------- */ /* read filter file line by line and display it */ say '' say '------------------------- current filter (short form of) -------------------------' inserted = '0' j = '0' /* page count */ do while lines(drive||infile) <> '0' do i = 1 to 10 /* line number on page */ line.i=linein(drive||infile) parse var line.i linesub '#' comment parse var line.i teil1 't=' tunnel ' ' teil2 if tunnel <> '' then tunnel = 't='tunnel linesub = substr(linesub,1,77) /* max. 77 caracters shown */ say 'Line:' j*10+i comment tunnel /* to avoid line wrap */ say ' 'linesub end /* do */ say '-------------------------------------------------------------- Page' j+1 '-------' do forever if inserted = '1' then leave /* new filter already inserted */ if todo = 'add' then say 'line number of new filter definition or w to continue' if todo = 'del' then say 'line number of filter to delete or w to continue' if todo = 'move' then say 'line number of filter to move or w to continue' if todo = 'edit' then say 'Zeilennummer des zu „ndernden Filters oder w fr weiter eingeben' pull zeile if zeile = 'W' then leave if zeile > j*10 & zeile < j*10+11 then leave say 'invalid line number ' beep(440,50) end /* do forever */ /* in case of move, ask for traget line number */ if todo = 'move' & zeile <> 'W' then do zeilefrom = zeile - 10 * j linemove = line.zeilefrom /* store the line to move */ do forever say 'Target line number for selected line?' pull zeilemove if zeilemove > j*10 & zeilemove < j*10+11 then leave say 'invalid line number ' beep(440,50) end /* do forever */ end /* do */ do i = 1 to 10 if i+j*10 = zeile & todo = 'add' then do call lineout drive||outfile,linenew /* add new line */ inserted = '1' end /* if */ if i+j*10 = zeilemove & todo = 'move' then do call lineout drive||outfile,linemove /* insert moved line */ inserted = '1' end /* if */ if i+j*10 = zeile & todo = 'del' then do line.i = '' /* delete line */ inserted = '1' end /* if */ if i+j*10 = zeile & todo = 'move' then do line.i = '' /* remove move line at old location */ inserted = '1' end /* if */ if line.i <> '' then do call lineout drive||outfile,line.i /* write preserved line */ end /* if */ end /* do i = */ j = j + 1 end /* while lines */ do i = 1 to 10 /* erase line array */ line.i = '' end /* do i= */ /* close files */ call stream drive||infile,'c','close' call stream drive||outfile,'c','close' /* copy new filter file and replace old */ 'copy ' drive||outfile drive||infile 'erase ' drive||outfile if todo = 'add' & zeile <> 'W' then say 'new filter insertetd at line ' zeile if todo = 'del' & zeile <> 'W' then say 'filter erased at line ' zeile if todo = 'edit' & zeile <> 'W' then say 'filter at line ' zeile 'changed' if zeile = 'W' then say 'no changes' /* return to funktion selection */ signal nextone /* -------------------------------------------------- */ /* End add/delet/move filter */ /* -------------------------------------------------- */ /******************************************************/ /* -------------------------------------------------- */ /* display interpreted filters */ /* -------------------------------------------------- */ /******************************************************/ viewfilter: /* read filter line by line, interpret and display */ i = '0' do while lines(drive||infile) line=linein(drive||infile) i = i + 1 if pos('#',line) = 1 then NOP /* omit commentary lines */ else do parse var line rest '#' comment comment = strip(comment) rest = strip(rest) /* remove blanks */ parse var line action ' ' rest if action == 'deny' then action = 'deny ' rest = strip(rest) /* remove blanks */ parse var rest sourceip ' ' rest rest = strip(rest) /* remove blanks */ parse var rest sourcemask ' ' rest rest = strip(rest) /* remove blanks */ parse var rest destip ' ' rest rest = strip(rest) /* remove blanks */ parse var rest destmask ' ' rest rest = strip(rest) /* remove blanks */ parse var rest protocol ' ' rest rest = strip(rest) /* remove blanks */ parse var rest srcopcode ' ' rest rest = strip(rest) /* remove blanks */ parse var rest srcport ' ' rest rest = strip(rest) /* remove blanks */ parse var rest destopcode ' ' rest rest = strip(rest) /* remove blanks */ parse var rest destport ' ' rest rest = strip(rest) /* remove blanks */ parse var rest interface ' ' rest rest = strip(rest) /* remove blanks */ parse var rest routing ' ' rest rest = strip(rest) /* remove blanks */ parse var rest direction ' ' rest rest = strip(rest) /* remove blanks */ parse var rest rest1 'l=' log ' ' rest2 log = 'l=' || strip(log) /* remove blanks */ if log == 'l=' then log = '' /* leave empty, if parameter is missing */ parse var rest rest1 'f=' fragment ' ' rest2 fragment = 'f=' || strip(fragment) if fragment == 'f=' then fragment = '' /* leave mepty, if parameter is missing */ parse var rest rest1 't=' tunnelid ' ' rest2 tunnelid = 't=' || strip(tunnelid) if tunnelid = 't=' then tunnelid = '' /* leave empty, if parameter is missing */ /* display read values, interpreted */ say '------------------------- Control display of filters' i '---------------------' say 'Comment: ' comment say 'Action: ' action say 'Sender IP: ' sourceip ' Sender Mask: ' sourcemask say 'Receiver IP ' destip ' Receiver Mask: ' destmask say 'Protocol: ' protocol say 'SenderOPcode: ' srcopcode ' Sender Port: ' srcport say 'ReceiverOPcode: ' destopcode ' Receiver Port: ' destport say 'Adapter: ' interface say 'Routing: ' routing say 'Direction: ' direction say 'Log: ' log say 'Fragment: ' fragment say 'Tunnel-ID: ' tunnelid say '-----------------------------------------------------------------------------' pull . end /* else do */ end /* do while */ /* close files */ call stream drive||infile,'c','close' /* Return to function selection */ signal nextone