?? RIGHT := 110 ??
MODULE nam$network_configuration;
*copyc cmc$display_element_constants
*copyc nac$null_connection_id
*copyc osd$unique_name
*copyc nae$namve_conditions
*copyc nae$network_configuration
*copyc clt$display_control
*copyc nat$display_option
*copyc nat$network_descriptor
*copyc nlt$device_count
*copyc nlt$network_device
*copyc nlt$network_device_list
*copyc ost$name
*copyc pft$cycle_selector
*copyc pft$name
*copyc pft$password
*copyc pft$share_selections
*copyc pft$usage_selections
*copyc pmt$processor_attributes
*copyc jmv$executing_within_system_job
?? TITLE := 'XREFd PROCEDURES', EJECT ??
*copyc amp$return
*copyc clp$convert_integer_to_string
*copyc clp$horizontal_tab_display
*copyc clp$new_display_line
*copyc clp$pop_utility
*copyc clp$push_utility
*copyc clp$put_partial_display
*copyc clp$scan_command_file
*copyc cmp$clean_up_network_list
*copyc cmp$define_channel_network
*copyc cmp$define_host_network
*copyc cmp$define_network_access
*copyc cmp$define_network_connection
*copyc cmp$define_tcpip_host
*copyc cmp$validate_network_config
*copyc nap$system_id
*copyc nap$record_system_id
*copyc nlp$tm_define_tcpip_host
*copyc pfp$attach
*copyc pmp$generate_unique_name
*copyc pmp$get_pseudo_mainframe_id
*copyc osp$is_caller_system_privileged
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
?? TITLE := 'Global Variables', EJECT ??
*copyc cmv$network_descriptor_p
*copyc nav$host_subnet_id
*copyc nav$network_paged_heap
*copyc nlv$configured_network_devices
*copyc nlv$sm_devices
*copyc nlv$tm_host
*copyc nlv$tm_route_cache
*copyc oss$job_paged_literal
?? TITLE := '  [INLINE] set_system_id', EJECT ??

  PROCEDURE [INLINE] set_system_id;

{
{     The purpose of this request is to establish this  system's  CDCNET  system
{  identifier for subsequent retrieval via the NAP$SYSTEM_ID function.
{

    VAR
      mainframe_id: pmt$binary_mainframe_id,
      i: 0 .. 3,
      m: integer,
      serial_number: ^packed array [0 .. 3] of 0 .. 0f(16),
      system_identifier: ^nat$system_identifier,
      system_id: packed record
        prefix: 0 .. 0ffffff(16),
        system_type: 0 .. 3,
        cpu_0_model_number: 0 .. 0ff(16),
        cpu_0_serial_number: 0 .. 3fff(16),
      recend;

    system_id.prefix := 080025(16); {the XEROX-reserved prefix}
    system_id.system_type := 3; {NOS/VE system type}
    pmp$get_pseudo_mainframe_id (mainframe_id);
    system_id.cpu_0_model_number := mainframe_id.model_number;

{  The following code is dependent on mainframe.serial_number being in BCD format.  }

    serial_number := #LOC (mainframe_id.serial_number);
    system_id.cpu_0_serial_number := 0;
    m := 1;
    FOR i := UPPERVALUE (i) DOWNTO LOWERVALUE (i) DO
      system_id.cpu_0_serial_number :=
            system_id.cpu_0_serial_number + (serial_number^ [i] * m);
      m := m * 10;
    FOREND;
    system_identifier := #LOC (system_id);
    nap$record_system_id (system_identifier^);
  PROCEND set_system_id;

?? TITLE := 'NAP$ACTIVATE_NETWORK_CONFIG', EJECT ??
  PROCEDURE [XDCL] nap$activate_network_config
    (VAR status: ost$status);

{ The purpose of this procedure is to process the file containing the commands
{ to define networks. These commands define the networks connected directly to
{ the host mainframe.

{ WARNING:  Make sure that when this table is regenerated that it is placed in
{           the section oss$job_paged_literal.


{ table inc_command_table t=c s=local
{ command (define_host_network            ,defhn) cmp$define_host_network
{ command (define_network_connection      ,defnc) cmp$define_network_connection
{ command (define_tcpip_host              ,defth) cmp$define_tcpip_host
{ tablend
?? PUSH (LISTEXT := ON) ??

VAR
  inc_command_table: [STATIC, READ] ^clt$command_table :=
      ^inc_command_table_entries,

  inc_command_table_entries: [STATIC, READ] array [1 .. 6] of
      clt$command_table_entry := [
  {} ['DEFHN                          ', clc$abbreviation_entry,
        clc$normal_usage_entry, 1, clc$automatically_log, clc$linked_call,
        ^cmp$define_host_network],
  {} ['DEFINE_HOST_NETWORK            ', clc$nominal_entry,
        clc$normal_usage_entry, 1, clc$automatically_log, clc$linked_call,
        ^cmp$define_host_network],
  {} ['DEFINE_NETWORK_CONNECTION      ', clc$nominal_entry,
        clc$normal_usage_entry, 2, clc$automatically_log, clc$linked_call,
        ^cmp$define_network_connection],
  {} ['DEFINE_TCPIP_HOST              ', clc$nominal_entry,
        clc$normal_usage_entry, 3, clc$automatically_log, clc$linked_call,
        ^cmp$define_tcpip_host],
  {} ['DEFNC                          ', clc$abbreviation_entry,
        clc$normal_usage_entry, 2, clc$automatically_log, clc$linked_call,
        ^cmp$define_network_connection],
  {} ['DEFTH                          ', clc$abbreviation_entry,
        clc$normal_usage_entry, 3, clc$automatically_log, clc$linked_call,
        ^cmp$define_tcpip_host]];

?? POP ??

  VAR
    activate_network_utility: [STATIC, READ, OSS$JOB_PAGED_LITERAL] ost$name :=
      'ACTIVATE_NETWORK_CONFIGURATION',
    configuration_file_path: [STATIC, READ, OSS$JOB_PAGED_LITERAL]  array [1 .. 4] of pft$name :=
      ['$SYSTEM', '$SYSTEM', 'NETWORK', 'CONFIGURATION'],
    default_password: [STATIC, READ, OSS$JOB_PAGED_LITERAL] pft$password := '',
    highest_cycle: [STATIC, READ, OSS$JOB_PAGED_LITERAL] pft$cycle_selector := [pfc$highest_cycle],
    ignore_status: ost$status,
    share_selections: [STATIC, READ, OSS$JOB_PAGED_LITERAL] pft$share_selections := [],
    unique_name: ost$unique_name,
    usage_selections: [STATIC, READ, OSS$JOB_PAGED_LITERAL] pft$usage_selections := [pfc$read, pfc$execute];


{   Attach the $system.network.configuration file.

  pmp$generate_unique_name (unique_name, ignore_status);
  pfp$attach (unique_name.value, configuration_file_path, highest_cycle, default_password, usage_selections,
        share_selections, pfc$no_wait, status);
  IF NOT status.normal THEN
    RETURN;
  IFEND;

/activate_network_config/
  BEGIN

    clp$push_utility (activate_network_utility, clc$exclusive_command_search, inc_command_table, NIL, status);
    IF NOT status.normal THEN
      EXIT /activate_network_config/;
    IFEND;

    clp$scan_command_file (unique_name.value, activate_network_utility, '', status);
    IF NOT status.normal THEN
      EXIT /activate_network_config/;
    IFEND;

    clp$pop_utility (status);
    IF NOT status.normal THEN
      EXIT /activate_network_config/;
    IFEND;

    cmp$validate_network_config (cmv$network_descriptor_p, status);
    IF NOT status.normal THEN
      EXIT /activate_network_config/;
    IFEND;

    define_network_configuration (cmv$network_descriptor_p, status);

  END /activate_network_config/;

  cmp$clean_up_network_list (ignore_status);
  amp$return (unique_name.value, ignore_status);

PROCEND nap$activate_network_config;
?? TITLE := '   nap$display_network_config', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$display_network_config
    (    display_option: nat$display_option;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

{ The purpose of this procedure is to display the attributes of all the
{ directly connected networks.

    VAR
      field_column_number: integer,
      i: integer,
      int: integer,
      int_string: ost$string,
      network_device_list: ^nlt$network_device_list;

    status.normal := TRUE;

    IF (NOT jmv$executing_within_system_job) AND (NOT osp$is_caller_system_privileged()) THEN
      osp$set_status_abnormal('NA',nae$insufficient_privilege,
            'nap$display_network_config',status);
      RETURN;
    IFEND;

    IF nlv$configured_network_devices.network_device_list = NIL THEN
      osp$set_status_condition (nae$networks_not_activated, status);
      RETURN;
    IFEND;

    clp$new_display_line (display_control, 1, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, cmc$starting_subheader_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, cmc$msg_host_network, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    int := nav$host_subnet_id;
    clp$convert_integer_to_string (int, 10, TRUE, int_string, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, int_string.value, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    network_device_list := nlv$configured_network_devices.network_device_list;

    FOR i := LOWERBOUND (network_device_list^) TO UPPERBOUND (network_device_list^) DO
      clp$new_display_line (display_control, 1, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$horizontal_tab_display (display_control, cmc$starting_subheader_column, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, cmc$msg_connected_system, clc$no_trim, amc$continue,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, network_device_list^ [i].element, clc$trim, amc$terminate,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF network_device_list^ [i].kind = nac$ica_2 THEN
        clp$horizontal_tab_display (display_control, cmc$starting_subheader_column, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        clp$put_partial_display (display_control, cmc$msg_system_identifier, clc$no_trim, amc$continue,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        int := network_device_list^ [i].system_id;
        clp$convert_integer_to_string (int, 16, TRUE, int_string, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        clp$put_partial_display (display_control, int_string.value, clc$trim, amc$terminate, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;
    FOREND;

    IF nlv$tm_host.name_length > 0 THEN
      clp$new_display_line (display_control, 1, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$horizontal_tab_display (display_control, cmc$starting_subheader_column, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, cmc$msg_tcpip_host_name, clc$no_trim, amc$continue,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, nlv$tm_host.name (1, nlv$tm_host.name_length),
            clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$horizontal_tab_display (display_control, cmc$starting_subheader_column, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, cmc$msg_forward_search_range, clc$no_trim, amc$continue,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      int := nlv$tm_route_cache.forward_search_range;
      clp$convert_integer_to_string (int, 10, TRUE, int_string, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, int_string.value, clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

  PROCEND nap$display_network_config;
?? TITLE := '  define_network_configuration', EJECT ??

  PROCEDURE define_network_configuration (network_descriptor_list: ^nat$network_descriptor;
    VAR status: ost$status);

{   This procedure creates the network device list. The network device list
{  contains entries containing the attributes of the configured network devices,
{  and the host subnet identifier.

    VAR
      i: integer,
      network_descriptor: ^nat$network_descriptor,
      network_device_count: nlt$device_count,
      network_device_list: ^nlt$network_device_list,
      system_management_list: ^nlt$sm_device_list;

    status.normal := TRUE;
    IF nlv$configured_network_devices.network_device_list <> NIL THEN
      osp$set_status_condition (nae$networks_already_configured, status);
      RETURN;
    IFEND;

    IF network_descriptor_list = NIL THEN
      osp$set_status_condition (nae$empty_network_desc_list, status);
      RETURN;
    IFEND;

{ Count the number of network devices being configured.
    network_descriptor := network_descriptor_list;
    network_device_count := 0;
    REPEAT
      IF network_descriptor^.kind = nac$network_device THEN
        network_device_count := network_device_count + 1;
      IFEND;
      network_descriptor := network_descriptor^.next_descriptor;
    UNTIL network_descriptor = NIL;
    network_descriptor := network_descriptor_list;

{ Establish the CDCNET system identifier for this system.

    set_system_id;
    ALLOCATE network_device_list: [1 .. network_device_count] IN nav$network_paged_heap^;
    nlv$configured_network_devices.network_device_list := network_device_list;
    ALLOCATE system_management_list: [1 .. network_device_count] IN nav$network_paged_heap^;
    nlv$sm_devices.list := system_management_list;
    nlv$configured_network_devices.network_device_count := network_device_count;
    i := 1;
    REPEAT
      CASE network_descriptor^.kind OF
      = nac$network_device =

{ Define network device attributes.
      network_device_list^[i].device_id := i;
      network_device_list^[i].logical_unit := 0;
      network_device_list^[i].path_status := nlc$path_unavailable;
      network_device_list^[i].channel := network_descriptor^.access.channel;
      network_device_list^[i].channel_address := network_descriptor^.access.channel_address;
      network_device_list^[i].element := network_descriptor^.access.element;
      network_device_list^[i].driver_name := network_descriptor^.driver_name;
      network_device_list^[i].state := nlc$normal;
      network_device_list^[i].last_usage_data.bytes_transmitted := 0;
      network_device_list^[i].last_usage_data.bytes_received := 0;
      network_device_list^[i].reset_down_count_intervl := 0;
      network_device_list^[i].reset_down_count := 0;
      network_device_list^[i].reset_timestamp := 0;
      network_device_list^[i].task_waiting_for_state_change.index := 0;
      network_device_list^[i].maximum_pdu_size := 0;
      network_device_list^[i].kind := network_descriptor^.device_type;
      network_device_list^[i].system_id := network_descriptor^.system_identifier;

{ Define System Management attributes.
      system_management_list^[i].device_id := i;
      system_management_list^[i].state := nlc$sm_uninitialized;
      system_management_list^[i].connection_id := nac$null_connection_id;
      system_management_list^[i].network_address_length := 0;
      system_management_list^[i].network_address_prefix := NIL;
      system_management_list^[i].active_connection_count := 0;
      system_management_list^[i].subnet_list := NIL;
      system_management_list^[i].new_subnet_list := NIL;

      i := i + 1;

    = nac$host_subnet =
      nav$host_subnet_id := network_descriptor^.network;
    = nac$define_tcpip_host =
      nlp$tm_define_tcpip_host (network_descriptor^.tcpip.host_name^, network_descriptor^.
            tcpip.forward_search_range);
    ELSE
    CASEND;

      network_descriptor := network_descriptor^.next_descriptor;
    UNTIL network_descriptor = NIL;

  PROCEND define_network_configuration;
MODEND nam$network_configuration;

