with Vms;
with System;

package Ip_Tcp_Defs is

    type Bit_16 is new System.Unsigned_Word;
    type Bit_32 is new System.Unsigned_Longword;

    subtype Byte_8 is System.Unsigned_Byte_Array (0 .. 7);
    subtype Byte_4 is System.Unsigned_Byte_Array (0 .. 3);
    subtype Byte_2 is System.Unsigned_Byte_Array (0 .. 1);

    The_Device : constant Vms.Device_Name_Type := "INET0:";

    Ss_Normal : constant := 1;  -- VMS status code

    package Vms_Function is
        -- VMS function codes

        subtype Code is Vms.Function_Code_Type;

        Io_Send : constant Code := Vms.Io_Writevblk;
        Io_Receive : constant Code := Vms.Io_Readvblk;

        Ios_Fcode : constant Integer := 6;
        Multiplier : constant Code := Vms."**" (2, Ios_Fcode);

        function "+" (Left, Right : Code) return Code renames Vms."+";
        function "*" (Left, Right : Code) return Code renames Vms."*";

        Io_Socket : constant Code := Vms.Io_Access + (Multiplier * 0);
        Io_Bind : constant Code := Vms.Io_Access + (Multiplier * 1);
        Io_Listen : constant Code := Vms.Io_Access + (Multiplier * 2);
        Io_Accept : constant Code := Vms.Io_Access + (Multiplier * 3);
        Io_Connect : constant Code := Vms.Io_Access + (Multiplier * 4);
        Io_Setsockopt : constant Code := Vms.Io_Access + (Multiplier * 5);
        Io_Getsockopt : constant Code := Vms.Io_Access + (Multiplier * 6);
        Io_Ioctl : constant Code := Vms.Io_Access + (Multiplier * 8);
        Io_Accept_Wait : constant Code := Vms.Io_Access + (Multiplier * 10);
        Io_Network_Pty : constant Code := Vms.Io_Access + (Multiplier * 11);
        Io_Shutdown : constant Code := Vms.Io_Access + (Multiplier * 12);
        Io_Getsockname : constant Code := Vms.Io_Access + (Multiplier * 13);
    end Vms_Function;

    package Unix_Error is
        -- Error codes defined by Unix.

        subtype Number is System.Unsigned_Word;

        function Decode (Status : Vms.Iosb_Type) return Number;
        function Decode (Status : Vms.Cond_Value_Type) return Number;

        Eperm : constant := 1;  -- Not owner
        Enoent : constant := 2;  -- No such file or directory
        Esrch : constant := 3;  -- No such process
        Eintr : constant := 4;  -- Interrupted system call
        Eio : constant := 5;  -- I/O error
        Enxio : constant := 6;  -- No such device or address
        E2big : constant := 7;  -- Arg list too long
        Enoexec : constant := 8;  -- Exec format error
        Ebadf : constant := 9;  -- Bad file number
        Echild : constant := 10;  -- No children
        Eagain : constant := 11;  -- No more processes
        Enomem : constant := 12;  -- Not enough core
        Eacces : constant := 13;  -- Permission denied
        Efault : constant := 14;  -- Bad address
        Enotblk : constant := 15;  -- Block device required
        Ebusy : constant := 16;  -- Mount device busy
        Eexist : constant := 17;  -- File exists
        Exdev : constant := 18;  -- Cross-device link
        Enodev : constant := 19;  -- No such device
        Enotdir : constant := 20;  -- Not a directory
        Eisdir : constant := 21;  -- Is a directory
        Einval : constant := 22;  -- Invalid argument
        Enfile : constant := 23;  -- File table overflow
        Emfile : constant := 24;  -- Too many open files
        Enotty : constant := 25;  -- Not a typewriter
        Etxtbsy : constant := 26;  -- Text file busy
        Efbig : constant := 27;  -- File too large
        Enospc : constant := 28;  -- No space left on device
        Espipe : constant := 29;  -- Illegal seek
        Erofs : constant := 30;  -- Read-only file system
        Emlink : constant := 31;  -- Too many links
        Epipe : constant := 32;  -- Broken pipe

        -- math software
        Edom : constant := 33;  -- Argument too large
        Erange : constant := 34;  -- Result too large

        -- non-blocking and interrupt i/o
        Ewouldblock : constant := 35;  -- Operation would block
        Einprogress : constant := 36;  -- Operation now in progress
        Ealready : constant := 37;  -- Operation already in progress


        -- ipc/network software

        -- argument errors
        Enotsock : constant := 38;  -- Socket operation on non-socket
        Edestaddrreq : constant := 39;  -- Destination address required
        Emsgsize : constant := 40;  -- Message too long
        Eprototype : constant := 41;  -- Protocol wrong type for socket
        Enoprotoopt : constant := 42;  -- Protocol not available
        Eprotonosupport : constant := 43;  -- Protocol not supported
        Esocktnosupport : constant := 44;  -- Socket type not supported
        Eopnotsupp : constant := 45;  -- Operation not supported on socket
        Epfnosupport : constant := 46;  -- Protocol family not supported
        Eafnosupport : constant :=
           47;  -- Address family not supported by protocol family
        Eaddrinuse : constant := 48;  -- Address already in use
        Eaddrnotavail : constant := 49;  -- Can't assign requested address

        -- operational errors
        Enetdown : constant := 50;  -- Network is down
        Enetunreach : constant := 51;  -- Network is unreachable
        Enetreset : constant := 52;  -- Network dropped connection on reset
        Econnaborted : constant := 53;  -- Software caused connection abort
        Econnreset : constant := 54;  -- Connection reset by peer
        Enobufs : constant := 55;  -- No buffer space available
        Eisconn : constant := 56;  -- Socket is already connected
        Enotconn : constant := 57;  -- Socket is not connected
        Eshutdown : constant := 58;  -- Can't send after socket shutdown
        Etoomanyrefs : constant := 59;  -- Too many references: can't splice
        Etimedout : constant := 60;  -- Connection timed out
        Econnrefused : constant := 61;  -- Connection refused
        Eloop : constant := 62;  -- Too many levels of symbolic links
        Enametoolong : constant := 63;  -- File name too long

        -- should be rearranged
        Ehostdown : constant := 64;  -- Host is down
        Ehostunreach : constant := 65;  -- No route to host
        Enotempty : constant := 66;  -- Directory not empty

        -- quotas & mush
        Eproclim : constant := 67;  -- Too many processes
        Eusers : constant := 68;  -- Too many users
        Edquot : constant := 69;  -- Disc quota exceeded
    end Unix_Error;


    Sol_Socket : constant := 16#FFFF#;
    Somaxconn : constant := 5;
    Sock_Stream : constant := 1;
    Sock_Dgram : constant := 2;

    subtype Option_Flags_Type is Integer;

    So_Debug : constant Option_Flags_Type := 16#01#;
    So_Acceptconn : constant Option_Flags_Type := 16#02#;
    So_Reuseaddr : constant Option_Flags_Type := 16#04#;
    So_Keepalive : constant Option_Flags_Type := 16#08#;

    subtype Address_Family_Type is Bit_16;

    Af_Inet : constant Address_Family_Type := 2;

    type Internet_Address is new Byte_4;
    Null_Internet_Address : constant Internet_Address := (others => 0);

    type Port_Number is new Byte_2;
    Null_Port_Number : constant Port_Number := (others => 0);

    type Sin_Addr_Type is
        record
            S_Addr : Internet_Address := Null_Internet_Address;
        end record;

    type Sockaddr_In is
        record
            Sin_Family : Address_Family_Type;
            Sin_Port : Port_Number := Null_Port_Number;
            Sin_Addr : Sin_Addr_Type;
            Sin_Zero : Byte_8 := (others => 0);
        end record;

    type Io_Accept_Return_Type is
        record
            Addr_Size : Bit_32;
            Foreign_Addr : Sockaddr_In;
        end record;

end Ip_Tcp_Defs;