JwaIpTypes.pas
上传用户:davidchvip
上传日期:2009-07-28
资源大小:1749k
文件大小:15k
源码类别:

Windows编程

开发平台:

Delphi

  1. {******************************************************************************}
  2. {                                                                       }
  3. { Internet Protocol Helper API interface Unit for Object Pascal                }
  4. {                                                                       }
  5. { Portions created by Microsoft are Copyright (C) 1995-2001 Microsoft          }
  6. { Corporation. All Rights Reserved.                                            }
  7. {                 }
  8. { The original file is: iptypes.h, released July 2000. The original Pascal     }
  9. { code is: IpTypes.pas, released September 2000. The initial developer of the  }
  10. { Pascal code is Marcel van Brakel (brakelm@chello.nl).                        }
  11. {                                                                              }
  12. { Portions created by Marcel van Brakel are Copyright (C) 1999-2001            }
  13. { Marcel van Brakel. All Rights Reserved.                                      }
  14. {                 }
  15. { Contributor(s): John C. Penman (jcp@craiglockhart.com)                       }
  16. {                 Vladimir Vassiliev (voldemarv@hotpop.com)                    }
  17. {                 }
  18. { Obtained through: Joint Endeavour of Delphi Innovators (Project JEDI)        }
  19. {                }
  20. { You may retrieve the latest version of this file at the Project JEDI home    }
  21. { page, located at http://delphi-jedi.org or my personal homepage located at   }
  22. { http://members.chello.nl/m.vanbrakel2                                        }
  23. {                }
  24. { The contents of this file are used with permission, subject to the Mozilla   }
  25. { Public License Version 1.1 (the "License"); you may not use this file except }
  26. { in compliance with the License. You may obtain a copy of the License at      }
  27. { http://www.mozilla.org/MPL/MPL-1.1.html                                      }
  28. {                                                                              }
  29. { Software distributed under the License is distributed on an "AS IS" basis,   }
  30. { WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for }
  31. { the specific language governing rights and limitations under the License.    }
  32. {                                                                              }
  33. { Alternatively, the contents of this file may be used under the terms of the  }
  34. { GNU Lesser General Public License (the  "LGPL License"), in which case the   }
  35. { provisions of the LGPL License are applicable instead of those above.        }
  36. { If you wish to allow use of your version of this file only under the terms   }
  37. { of the LGPL License and not to allow others to use your version of this file }
  38. { under the MPL, indicate your decision by deleting  the provisions above and  }
  39. { replace  them with the notice and other provisions required by the LGPL      }
  40. { License.  If you do not delete the provisions above, a recipient may use     }
  41. { your version of this file under either the MPL or the LGPL License.          }
  42. {                 }
  43. { For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
  44. {                 }
  45. {******************************************************************************}
  46. unit JwaIpTypes;
  47. {$WEAKPACKAGEUNIT}
  48. {$HPPEMIT ''}
  49. {$HPPEMIT '#include "iptypes.h"'}
  50. {$HPPEMIT ''}
  51. {$I WINDEFINES.INC}
  52. interface
  53. uses
  54.   JwaWinsock2, JwaWinType;
  55. type
  56.   // #include <time.h>  // TODO
  57.   time_t = Longint;
  58.   {$EXTERNALSYM time_t}
  59. // Definitions and structures used by getnetworkparams and getadaptersinfo apis
  60. const
  61.   MAX_ADAPTER_DESCRIPTION_LENGTH = 128; // arb.
  62.   {$EXTERNALSYM MAX_ADAPTER_DESCRIPTION_LENGTH}
  63.   MAX_ADAPTER_NAME_LENGTH        = 256; // arb.
  64.   {$EXTERNALSYM MAX_ADAPTER_NAME_LENGTH}
  65.   MAX_ADAPTER_ADDRESS_LENGTH     = 8; // arb.
  66.   {$EXTERNALSYM MAX_ADAPTER_ADDRESS_LENGTH}
  67.   DEFAULT_MINIMUM_ENTITIES       = 32; // arb.
  68.   {$EXTERNALSYM DEFAULT_MINIMUM_ENTITIES}
  69.   MAX_HOSTNAME_LEN               = 128; // arb.
  70.   {$EXTERNALSYM MAX_HOSTNAME_LEN}
  71.   MAX_DOMAIN_NAME_LEN            = 128; // arb.
  72.   {$EXTERNALSYM MAX_DOMAIN_NAME_LEN}
  73.   MAX_SCOPE_ID_LEN               = 256; // arb.
  74.   {$EXTERNALSYM MAX_SCOPE_ID_LEN}
  75. //
  76. // types
  77. //
  78. // Node Type
  79.   BROADCAST_NODETYPE    = 1;
  80.   {$EXTERNALSYM BROADCAST_NODETYPE}
  81.   PEER_TO_PEER_NODETYPE = 2;
  82.   {$EXTERNALSYM PEER_TO_PEER_NODETYPE}
  83.   MIXED_NODETYPE        = 4;
  84.   {$EXTERNALSYM MIXED_NODETYPE}
  85.   HYBRID_NODETYPE       = 8;
  86.   {$EXTERNALSYM HYBRID_NODETYPE}
  87. //
  88. // IP_ADDRESS_STRING - store an IP address as a dotted decimal string
  89. //
  90. type
  91.   PIP_MASK_STRING = ^IP_MASK_STRING;
  92.   {$EXTERNALSYM PIP_MASK_STRING}
  93.   IP_ADDRESS_STRING = record
  94.     S: array [0..15] of Char;
  95.   end;
  96.   {$EXTERNALSYM IP_ADDRESS_STRING}
  97.   PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
  98.   {$EXTERNALSYM PIP_ADDRESS_STRING}
  99.   IP_MASK_STRING = IP_ADDRESS_STRING;
  100.   {$EXTERNALSYM IP_MASK_STRING}
  101.   TIpAddressString = IP_ADDRESS_STRING;
  102.   PIpAddressString = PIP_MASK_STRING;
  103. //
  104. // IP_ADDR_STRING - store an IP address with its corresponding subnet mask,
  105. // both as dotted decimal strings
  106. //
  107.   PIP_ADDR_STRING = ^IP_ADDR_STRING;
  108.   {$EXTERNALSYM PIP_ADDR_STRING}
  109.   _IP_ADDR_STRING = record
  110.     Next: PIP_ADDR_STRING;
  111.     IpAddress: IP_ADDRESS_STRING;
  112.     IpMask: IP_MASK_STRING;
  113.     Context: DWORD;
  114.   end;
  115.   {$EXTERNALSYM _IP_ADDR_STRING}
  116.   IP_ADDR_STRING = _IP_ADDR_STRING;
  117.   {$EXTERNALSYM IP_ADDR_STRING}
  118.   TIpAddrString = IP_ADDR_STRING;
  119.   PIpAddrString = PIP_ADDR_STRING;
  120. //
  121. // ADAPTER_INFO - per-adapter information. All IP addresses are stored as
  122. // strings
  123. //
  124.   PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
  125.   {$EXTERNALSYM PIP_ADAPTER_INFO}
  126.   _IP_ADAPTER_INFO = record
  127.     Next: PIP_ADAPTER_INFO;
  128.     ComboIndex: DWORD;
  129.     AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of Char;
  130.     Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char;
  131.     AddressLength: UINT;
  132.     Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
  133.     Index: DWORD;
  134.     Type_: UINT;
  135.     DhcpEnabled: UINT;
  136.     CurrentIpAddress: PIP_ADDR_STRING;
  137.     IpAddressList: IP_ADDR_STRING;
  138.     GatewayList: IP_ADDR_STRING;
  139.     DhcpServer: IP_ADDR_STRING;
  140.     HaveWins: BOOL;
  141.     PrimaryWinsServer: IP_ADDR_STRING;
  142.     SecondaryWinsServer: IP_ADDR_STRING;
  143.     LeaseObtained: time_t;
  144.     LeaseExpires: time_t;
  145.   end;
  146.   {$EXTERNALSYM _IP_ADAPTER_INFO}
  147.   IP_ADAPTER_INFO = _IP_ADAPTER_INFO;
  148.   {$EXTERNALSYM IP_ADAPTER_INFO}
  149.   TIpAdapterInfo = IP_ADAPTER_INFO;
  150.   PIpAdapterInfo = PIP_ADAPTER_INFO;
  151. //
  152. // The following types require Winsock2.
  153. //
  154.   IP_PREFIX_ORIGIN = (
  155.     IpPrefixOriginOther,
  156.     IpPrefixOriginManual,
  157.     IpPrefixOriginWellKnown,
  158.     IpPrefixOriginDhcp,
  159.     IpPrefixOriginRouterAdvertisement);
  160.   {$EXTERNALSYM IP_PREFIX_ORIGIN}
  161.   TIpPrefixOrigin = IP_PREFIX_ORIGIN;
  162.   IP_SUFFIX_ORIGIN = (
  163.     IpSuffixOriginOther,
  164.     IpSuffixOriginManual,
  165.     IpSuffixOriginWellKnown,
  166.     IpSuffixOriginDhcp,
  167.     IpSuffixOriginLinkLayerAddress,
  168.     IpSuffixOriginRandom);
  169.   {$EXTERNALSYM IP_SUFFIX_ORIGIN}
  170.   TIpSuffixOrigin = IP_SUFFIX_ORIGIN;
  171.   IP_DAD_STATE = (
  172.     IpDadStateInvalid,
  173.     IpDadStateTentative,
  174.     IpDadStateDuplicate,
  175.     IpDadStateDeprecated,
  176.     IpDadStatePreferred);
  177.   {$EXTERNALSYM IP_DAD_STATE}
  178.   TIpDadState = IP_DAD_STATE;
  179.   PIP_ADAPTER_UNICAST_ADDRESS = ^_IP_ADAPTER_UNICAST_ADDRESS;
  180.   {$EXTERNALSYM PIP_ADAPTER_UNICAST_ADDRESS}
  181.   _IP_ADAPTER_UNICAST_ADDRESS = record
  182.     Union: record
  183.       case Integer of
  184.         0: (
  185.           Alignment: ULONGLONG);
  186.         1: (
  187.           Length: ULONG;
  188.           Flags: DWORD);
  189.     end;
  190.     Next: PIP_ADAPTER_UNICAST_ADDRESS;
  191.     Address: SOCKET_ADDRESS;
  192.     PrefixOrigin: IP_PREFIX_ORIGIN;
  193.     SuffixOrigin: IP_SUFFIX_ORIGIN;
  194.     DadState: IP_DAD_STATE;
  195.     ValidLifetime: ULONG;
  196.     PreferredLifetime: ULONG;
  197.     LeaseLifetime: ULONG;
  198.   end;
  199.   {$EXTERNALSYM _IP_ADAPTER_UNICAST_ADDRESS}
  200.   IP_ADAPTER_UNICAST_ADDRESS = _IP_ADAPTER_UNICAST_ADDRESS;
  201.   {$EXTERNALSYM IP_ADAPTER_UNICAST_ADDRESS}
  202.   TIpAdapterUnicastAddress = IP_ADAPTER_UNICAST_ADDRESS;
  203.   PIpAdapterUnicastAddress = PIP_ADAPTER_UNICAST_ADDRESS;
  204.   PIP_ADAPTER_ANYCAST_ADDRESS = ^_IP_ADAPTER_ANYCAST_ADDRESS;
  205.   {$EXTERNALSYM PIP_ADAPTER_ANYCAST_ADDRESS}
  206.   _IP_ADAPTER_ANYCAST_ADDRESS = record
  207.     Union: record
  208.       case Integer of
  209.         0: (
  210.           Alignment: ULONGLONG);
  211.         1: (
  212.           Length: ULONG;
  213.           Flags: DWORD);
  214.     end;
  215.     Next: PIP_ADAPTER_ANYCAST_ADDRESS;
  216.     Address: SOCKET_ADDRESS;
  217.   end;
  218.   {$EXTERNALSYM _IP_ADAPTER_ANYCAST_ADDRESS}
  219.   IP_ADAPTER_ANYCAST_ADDRESS = _IP_ADAPTER_ANYCAST_ADDRESS;
  220.   {$EXTERNALSYM IP_ADAPTER_ANYCAST_ADDRESS}
  221.   TIpAdapterAnycaseAddress = IP_ADAPTER_ANYCAST_ADDRESS;
  222.   PIpAdapterAnycaseAddress = PIP_ADAPTER_ANYCAST_ADDRESS;
  223.   PIP_ADAPTER_MULTICAST_ADDRESS = ^_IP_ADAPTER_MULTICAST_ADDRESS;
  224.   {$EXTERNALSYM PIP_ADAPTER_MULTICAST_ADDRESS}
  225.   _IP_ADAPTER_MULTICAST_ADDRESS = record
  226.     Union: record
  227.       case Integer of
  228.         0: (
  229.           Alignment: ULONGLONG);
  230.         1: (
  231.           Length: ULONG;
  232.           Flags: DWORD);
  233.     end;
  234.     Next: PIP_ADAPTER_MULTICAST_ADDRESS;
  235.     Address: SOCKET_ADDRESS;
  236.   end;
  237.   {$EXTERNALSYM _IP_ADAPTER_MULTICAST_ADDRESS}
  238.   IP_ADAPTER_MULTICAST_ADDRESS = _IP_ADAPTER_MULTICAST_ADDRESS;
  239.   TIpAdapterMulticastAddress = IP_ADAPTER_MULTICAST_ADDRESS;
  240.   PIpAdapterMulticastAddress = PIP_ADAPTER_MULTICAST_ADDRESS;  
  241. //
  242. // Per-address Flags
  243. //
  244. const
  245.   IP_ADAPTER_ADDRESS_DNS_ELIGIBLE = $01;
  246.   {$EXTERNALSYM IP_ADAPTER_ADDRESS_DNS_ELIGIBLE}
  247.   IP_ADAPTER_ADDRESS_TRANSIENT    = $02;
  248.   {$EXTERNALSYM IP_ADAPTER_ADDRESS_TRANSIENT}
  249. type
  250.   PIP_ADAPTER_DNS_SERVER_ADDRESS = ^_IP_ADAPTER_DNS_SERVER_ADDRESS;
  251.   {$EXTERNALSYM PIP_ADAPTER_DNS_SERVER_ADDRESS}
  252.   _IP_ADAPTER_DNS_SERVER_ADDRESS = record
  253.     Union: record
  254.       case Integer of
  255.         0: (
  256.           Alignment: ULONGLONG);
  257.         1: (
  258.           Length: ULONG;
  259.           Reserved: DWORD);
  260.     end;
  261.     Next: PIP_ADAPTER_DNS_SERVER_ADDRESS;
  262.     Address: SOCKET_ADDRESS;
  263.   end;
  264.   {$EXTERNALSYM _IP_ADAPTER_DNS_SERVER_ADDRESS}
  265.   IP_ADAPTER_DNS_SERVER_ADDRESS = _IP_ADAPTER_DNS_SERVER_ADDRESS;
  266.   {$EXTERNALSYM IP_ADAPTER_DNS_SERVER_ADDRESS}
  267.   TIpAdapterDnsServerAddress = IP_ADAPTER_DNS_SERVER_ADDRESS;
  268.   PIpAdapterDnsServerAddress = PIP_ADAPTER_DNS_SERVER_ADDRESS;  
  269.   PIP_ADAPTER_PREFIX = ^IP_ADAPTER_PREFIX;
  270.   {$EXTERNALSYM PIP_ADAPTER_PREFIX}
  271.   _IP_ADAPTER_PREFIX = record
  272.     Union: record
  273.     case Integer of
  274.       0: (
  275.         Alignment: ULONGLONG);
  276.       1: (
  277.         Length: ULONG;
  278.         Flags: DWORD);
  279.     end;
  280.     Next: PIP_ADAPTER_PREFIX;
  281.     Address: SOCKET_ADDRESS;
  282.     PrefixLength: ULONG;
  283.   end;
  284.   {$EXTERNALSYM _IP_ADAPTER_PREFIX}
  285.   IP_ADAPTER_PREFIX = _IP_ADAPTER_PREFIX;
  286.   {$EXTERNALSYM IP_ADAPTER_PREFIX}
  287.   TIpAdapterPrefix = IP_ADAPTER_PREFIX;
  288.   PIpAdapterPrefix = PIP_ADAPTER_PREFIX;
  289. //
  290. // Per-adapter Flags
  291. //
  292. const
  293.   IP_ADAPTER_DDNS_ENABLED            = $01;
  294.   {$EXTERNALSYM IP_ADAPTER_DDNS_ENABLED}
  295.   IP_ADAPTER_REGISTER_ADAPTER_SUFFIX = $02;
  296.   {$EXTERNALSYM IP_ADAPTER_REGISTER_ADAPTER_SUFFIX}
  297.   IP_ADAPTER_DHCP_ENABLED            = $04;
  298.   {$EXTERNALSYM IP_ADAPTER_DHCP_ENABLED}
  299.   IP_ADAPTER_RECEIVE_ONLY            = $08;
  300.   {$EXTERNALSYM IP_ADAPTER_RECEIVE_ONLY}
  301.   IP_ADAPTER_NO_MULTICAST            = $10;
  302.   {$EXTERNALSYM IP_ADAPTER_NO_MULTICAST}
  303.   IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG = $20;
  304.   {$EXTERNALSYM IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG}
  305. //
  306. // OperStatus values from RFC 2863
  307. //
  308. type
  309.   IF_OPER_STATUS = (
  310.     IfOperStatusUp,
  311.     IfOperStatusDown,
  312.     IfOperStatusTesting,
  313.     IfOperStatusUnknown,
  314.     IfOperStatusDormant,
  315.     IfOperStatusNotPresent,
  316.     IfOperStatusLowerLayerDown);
  317.   {$EXTERNALSYM IF_OPER_STATUS}
  318.   TIfOperStatus = IF_OPER_STATUS;
  319. //
  320. // Scope levels from RFC 2373 used with ZoneIndices array.
  321. //
  322. const
  323.   ScopeLevelInterface    = 1;
  324.   {$EXTERNALSYM ScopeLevelInterface}
  325.   ScopeLevelLink         = 2;
  326.   {$EXTERNALSYM ScopeLevelLink}
  327.   ScopeLevelSubnet       = 3;
  328.   {$EXTERNALSYM ScopeLevelSubnet}
  329.   ScopeLevelAdmin        = 4;
  330.   {$EXTERNALSYM ScopeLevelAdmin}
  331.   ScopeLevelSite         = 5;
  332.   {$EXTERNALSYM ScopeLevelSite}
  333.   ScopeLevelOrganization = 8;
  334.   {$EXTERNALSYM ScopeLevelOrganization}
  335.   ScopeLevelGlobal       = 14;
  336.   {$EXTERNALSYM ScopeLevelGlobal}
  337. type
  338.   SCOPE_LEVEL = DWORD;
  339.   {$EXTERNALSYM SCOPE_LEVEL}
  340.   TScopeLevel = SCOPE_LEVEL;
  341.   PIP_ADAPTER_ADDRESSES = ^_IP_ADAPTER_ADDRESSES;
  342.   {$EXTERNALSYM PIP_ADAPTER_ADDRESSES}
  343.   _IP_ADAPTER_ADDRESSES = record
  344.     Union: record
  345.       case Integer of
  346.         0: (
  347.           Alignment: ULONGLONG);
  348.         1: (
  349.           Length: ULONG;
  350.           IfIndex: DWORD);
  351.     end;
  352.     Next: PIP_ADAPTER_ADDRESSES;
  353.     AdapterName: PCHAR;
  354.     FirstUnicastAddress: PIP_ADAPTER_UNICAST_ADDRESS;
  355.     FirstAnycastAddress: PIP_ADAPTER_ANYCAST_ADDRESS;
  356.     FirstMulticastAddress: PIP_ADAPTER_MULTICAST_ADDRESS;
  357.     FirstDnsServerAddress: PIP_ADAPTER_DNS_SERVER_ADDRESS;
  358.     DnsSuffix: PWCHAR;
  359.     Description: PWCHAR;
  360.     FriendlyName: PWCHAR;
  361.     PhysicalAddress: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
  362.     PhysicalAddressLength: DWORD;
  363.     Flags: DWORD;
  364.     Mtu: DWORD;
  365.     IfType: DWORD;
  366.     OperStatus: IF_OPER_STATUS;
  367.     Ipv6IfIndex: DWORD;
  368.     ZoneIndices: array [0..15] of DWORD;
  369.     FirstPrefix: PIP_ADAPTER_PREFIX;
  370.   end;
  371.   {$EXTERNALSYM _IP_ADAPTER_ADDRESSES}
  372.   IP_ADAPTER_ADDRESSES = _IP_ADAPTER_ADDRESSES;
  373.   {$EXTERNALSYM IP_ADAPTER_ADDRESSES}
  374.   TIpAdapterAddresses = IP_ADAPTER_ADDRESSES;
  375.   PIpAdapterAddresses = PIP_ADAPTER_ADDRESSES;  
  376. //
  377. // Flags used as argument to GetAdaptersAddresses().
  378. // "SKIP" flags are added when the default is to include the information.
  379. // "INCLUDE" flags are added when the default is to skip the information.
  380. //
  381. const
  382.   GAA_FLAG_SKIP_UNICAST     = $0001;
  383.   {$EXTERNALSYM GAA_FLAG_SKIP_UNICAST}
  384.   GAA_FLAG_SKIP_ANYCAST     = $0002;
  385.   {$EXTERNALSYM GAA_FLAG_SKIP_ANYCAST}
  386.   GAA_FLAG_SKIP_MULTICAST   = $0004;
  387.   {$EXTERNALSYM GAA_FLAG_SKIP_MULTICAST}
  388.   GAA_FLAG_SKIP_DNS_SERVER  = $0008;
  389.   {$EXTERNALSYM GAA_FLAG_SKIP_DNS_SERVER}
  390.   GAA_FLAG_INCLUDE_PREFIX   = $0010;
  391.   {$EXTERNALSYM GAA_FLAG_INCLUDE_PREFIX}
  392.   GAA_FLAG_SKIP_FRIENDLY_NAME = $0020;
  393.   {$EXTERNALSYM GAA_FLAG_SKIP_FRIENDLY_NAME}
  394. //
  395. // IP_PER_ADAPTER_INFO - per-adapter IP information such as DNS server list.
  396. //
  397. type
  398.   PIP_PER_ADAPTER_INFO = ^IP_PER_ADAPTER_INFO;
  399.   {$EXTERNALSYM PIP_PER_ADAPTER_INFO}
  400.   _IP_PER_ADAPTER_INFO = record
  401.     AutoconfigEnabled: UINT;
  402.     AutoconfigActive: UINT;
  403.     CurrentDnsServer: PIP_ADDR_STRING;
  404.     DnsServerList: IP_ADDR_STRING;
  405.   end;
  406.   {$EXTERNALSYM _IP_PER_ADAPTER_INFO}
  407.   IP_PER_ADAPTER_INFO = _IP_PER_ADAPTER_INFO;
  408.   {$EXTERNALSYM IP_PER_ADAPTER_INFO}
  409.   TIpPerAdapterInfo = IP_PER_ADAPTER_INFO;
  410.   PIpPerAdapterInfo = PIP_PER_ADAPTER_INFO;
  411. //
  412. // FIXED_INFO - the set of IP-related information which does not depend on DHCP
  413. //
  414.   PFIXED_INFO = ^FIXED_INFO;
  415.   {$EXTERNALSYM PFIXED_INFO}
  416.   FIXED_INFO = record
  417.     HostName: array [0..MAX_HOSTNAME_LEN + 3] of Char;
  418.     DomainName: array[0..MAX_DOMAIN_NAME_LEN + 3] of Char;
  419.     CurrentDnsServer: PIP_ADDR_STRING;
  420.     DnsServerList: IP_ADDR_STRING;
  421.     NodeType: UINT;
  422.     ScopeId: array [0..MAX_SCOPE_ID_LEN + 3] of Char;
  423.     EnableRouting: UINT;
  424.     EnableProxy: UINT;
  425.     EnableDns: UINT;
  426.   end;
  427.   {$EXTERNALSYM FIXED_INFO}
  428.   TFixedInfo = FIXED_INFO;
  429.   PFixedInfo = PFIXED_INFO;
  430. implementation
  431. end.