I Like It !

Friday, September 16, 2016

The Executable Code of MBR

7C3E FA            CLI               ; Disable maskable Interrupts
7C3F 33C0          XOR    AX,AX        ; Zero-out the Accumulator and set
7C41 8ED0          MOV    SS,AX        ;  Stack Segment register to ZERO.
7C43 BC007C        MOV    SP,7C00         ; Stack Pointer top now 0000:7C00
7C46 16            PUSH    SS           ;|
7C47 07            POP    ES           ;|Makes sure Extra Segment = ZERO.
7C48 BB7800        MOV    BX,0078      ; 0078h ---> BX
7C4B 36C537        LDS    SI,SS:[BX]   ; SS is still zero...
                                     ; Load Far Pointer from [SS:0078]
                                     ; into DS:SI  (usually 0000:0522).
7C4E 1E            PUSH    DS
7C4F 56            PUSH    SI
7C50 16            PUSH    SS
7C51 53            PUSH    BX

; The following four instructions will overwrite 11 code bytes starting at 7C3Eh:
7C52 BF3E7C        MOV    DI,7C3E      ; Will overwrite some code bytes!
7C55 B90B00        MOV    CX,000B      ; Copy CX (0Bh = 11) bytes from ...
7C58 FC            CLD               ; Clear Direction Flag (df=0).
7C59 F3A4          REP    MOVSB        ; ... DS:SI to ES:DI (0000:7C3E) and
                                     ; following; DI increases to 7C49.
7C5B 06            PUSH    ES
7C5C 1F            POP     DS        ; Data Segment set to ZERO.
7C5D C645FE0F      MOV     BYTE PTR [DI-02],0F  ; 0Fh ---> [7C47].
7C61 8B0E187C      MOV     CX,[7C18]            ; Copy SPT ([7C18]) into CX
7C65 884DF9        MOV     [DI-07],CL           ; Sectors/Track --> [7C42].

; The next two instructions set the Diskette Parameters Table SEG:OFF vector
; at [0:0078] from the original vector of 0000:0522 to our 0000:7C3E address,
; so any DPT look-ups will access the data created here instead:

7C68 894702        MOV     [BX+02],AX           ; 0000 --> [0:007A]
7C6B C7073E7C      MOV     WORD PTR [BX],7C3E   ; 7C3E --> [0:0078]

7C6F FB            STI               ; Enable maskable Interrupts
                                     ; after the next instruction.
;---------------------------------------------------------------------------
; INT 13 - DISK - RESET DISK SYSTEM
;    AH = 00h
;    DL = drive (if bit 7 is set both hard disks and floppy disks reset)
; Return: AH = status (see #00234)
;    CF clear if successful (returned AH=00h)
;    CF set on error
;---------------------------------------------------------------------------
7C70 CD13          INT     13
7C72 7279          JC       7CED          ; If CF set, there's a disk error,
                                         ; so jump to Error Msg. routine!

7C74 33C0          XOR     AX,AX
7C76 3906137C      CMP     [7C13],AX
7C7A 7408          JZ      7C84
7C7C 8B0E137C      MOV     CX,[7C13]        ; [7C13] = Total Sectors
                                            ; 960h = 2400 sectors.
7C80 890E207C      MOV     [7C20],CX
7C84 A0107C        MOV     AL,[7C10]        ; FAT12 F.S. has two FATs
7C87 F726167C      MUL     WORD PTR [7C16]  ; of 7 sectors each, plus...
7C8B 03061C7C      ADD     AX,[7C1C]
7C8F 13161E7C      ADC     DX,[7C1E]
7C93 03060E7C      ADD     AX,[7C0E]        ; 1 Rsrvd sector (VBR itself)
7C97 83D200        ADC     DX,+00
7C9A A3507C        MOV     [7C50],AX
7C9D 8916527C      MOV     [7C52],DX
7CA1 A3497C        MOV     [7C49],AX
7CA4 89164B7C      MOV     [7C4B],DX

7CA8 B82000        MOV     AX,0020          ; 20h = 32 bytes per Dir entry
7CAB F726117C      MUL     WORD PTR [7C11]  ; [7C11] is number of possible
                                            ; Root Directory entries (224).
;    So, AX now contains (32 x 224 = 7,168) more used system area in bytes.

7CAF 8B1E0B7C      MOV     BX,[7C0B]        ; [7C0B] is 512 bytes per sector.
7CB3 03C3          ADD     AX,BX            ; Add 1 more sector in bytes.
7CB5 48            DEC     AX               ; Subtract 1 byte.
7CB6 F7F3          DIV     BX               ; Divide by 512 to get sectors.
7CB8 0106497C      ADD     [7C49],AX
7CBC 83164B7C00    ADC     WORD PTR [7C4B],+00
7CC1 BB0005        MOV     BX,0500          ; 500h = 1,280
7CC4 8B16527C      MOV     DX,[7C52]
7CC8 A1507C        MOV     AX,[7C50]
7CCB E89200        CALL    7D60

7CCE 721D          JB      7CED
7CD0 B001          MOV     AL,01
7CD2 E8AC00        CALL    7D81             ; -> Read Sectors

7CD5 7216          JB      7CED
7CD7 8BFB          MOV     DI,BX
7CD9 B90B00        MOV     CX,000B          ; 11 characters per file name.
7CDC BEE67D        MOV     SI,7DE6          ; Points to IO.SYS
7CDF F3            REPZ
7CE0 A6            CMPSB                    ; Compare  "IO.SYS"  name  to
                          ; first file name in Root Directory of diskette.
7CE1 750A          JNZ     7CED             ; If not identical, there's a
                                   ; disk error or it's not a System disk!

; Now we check if "MSDOS.SYS" is the second file in the Root Directory:
7CE3 8D7F20        LEA     DI,[BX+20]       ; Points to MSDOS.SYS
7CE6 B90B00        MOV     CX,000B
7CE9 F3            REPZ
7CEA A6            CMPSB
7CEB 7418          JZ      7D05

7CED BE9E7D        MOV     SI,7D9E          ; Points to Error Message
7CF0 E85F00        CALL    7D52             ; Display Character String
7CF3 33C0          XOR     AX,AX
7CF5 CD16          INT     16               ; Get Keystroke from Keyboard

7CF7 5E            POP     SI
7CF8 1F            POP     DS
7CF9 8F04          POP     [SI]
7CFB 8F4402        POP     [SI+02]
7CFE CD19          INT     19               ; If a key was pressed, then
                                            ;   Start over again with
                                            ;   System BOOTSTRAP LOADER.

7D00 58            POP     AX
7D01 58            POP     AX
7D02 58            POP     AX
7D03 EBE8          JMP     7CED


7D05 8B471A        MOV     AX,[BX+1A]
7D08 48            DEC     AX
7D09 48            DEC     AX
7D0A 8A1E0D7C      MOV     BL,[7C0D]
7D0E 32FF          XOR     BH,BH
7D10 F7E3          MUL     BX
7D12 0306497C      ADD     AX,[7C49]
7D16 13164B7C      ADC     DX,[7C4B]
7D1A BB0007        MOV     BX,0700
7D1D B90300        MOV     CX,0003
7D20 50            PUSH    AX
7D21 52            PUSH    DX
7D22 51            PUSH    CX
7D23 E83A00        CALL    7D60
7D26 72D8          JB      7D00
7D28 B001          MOV     AL,01
7D2A E85400        CALL    7D81                ; -> Read Sectors
7D2D 59            POP     CX
7D2E 5A            POP     DX
7D2F 58            POP     AX
7D30 72BB          JB      7CED
7D32 050100        ADD     AX,0001
7D35 83D200        ADC     DX,+00
7D38 031E0B7C      ADD     BX,[7C0B]
7D3C E2E2          LOOP    7D20

7D3E 8A2E157C      MOV     CH,[7C15]
7D42 8A16247C      MOV     DL,[7C24]
7D46 8B1E497C      MOV     BX,[7C49]
7D4A A14B7C        MOV     AX,[7C4B]
7D4D EA00007000    JMP     FAR PTR 0070:0000   ; Same as jumping to
                                               ;  0000:0700 (start DOS).

SUBROUTINES
; Display Zero-terminated Character String

7D52 AC            LODSB
7D53 0AC0          OR      AL,AL
7D55 7429          JZ      7D80           ; -> RETurn from Subroutine.
7D57 B40E          MOV     AH,0E          ; Video Function 0Eh
7D59 BB0700        MOV     BX,0007        ;  Page 0, Mode 7...
7D5C CD10          INT     10             ;  of INT 10. 'Tele-
                                          ;  type Output' AL =
                                          ; character to write.

7D5E EBF2          JMP     7D52           ; Loop until done.

;====================================================================

7D60 3B16187C      CMP     DX,[7C18]
7D64 7319          JNB     7D7F
7D66 F736187C      DIV     WORD PTR [7C18]
7D6A FEC2          INC     DL
7D6C 88164F7C      MOV     [7C4F],DL
7D70 33D2          XOR     DX,DX
7D72 F7361A7C      DIV     WORD PTR [7C1A]
7D76 8816257C      MOV     [7C25],DL
7D7A A34D7C        MOV     [7C4D],AX
7D7D F8            CLC                      ; Clear Carry Flag (CF=0)
7D7E C3            RET
7D7F F9            STC                      ;   Set Carry Flag (CF=1)
7D80 C3            RET

; READ SECTORS INTO MEMORY

7D81 B402          MOV     AH,02            ; Function 02 of INT 13
7D83 8B164D7C      MOV     DX,[7C4D]
7D87 B106          MOV     CL,06
7D89 D2E6          SHL     DH,CL
7D8B 0A364F7C      OR      DH,[7C4F]
7D8F 8BCA          MOV     CX,DX
7D91 86E9          XCHG    CH,CL
7D93 8A16247C      MOV     DL,[7C24]
7D97 8A36257C      MOV     DH,[7C25]
7D9B CD13          INT     13

7D9D C3            RET

tcp_impl.h

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or http://www.opensolaris.org/os/licensing.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 /*
   22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   23  */
   24 
   25 #ifndef _INET_TCP_IMPL_H
   26 #define _INET_TCP_IMPL_H
   27 
   28 /*
   29  * TCP implementation private declarations.  These interfaces are
   30  * used to build the IP module and are not meant to be accessed
   31  * by any modules except IP itself.  They are undocumented and are
   32  * subject to change without notice.
   33  */
   34 
   35 #ifdef  __cplusplus
   36 extern "C" {
   37 #endif
   38 
   39 #ifdef _KERNEL
   40 
   41 #include 
   42 #include      /* For LBOLT_FASTPATH{,64} */
   43 #include 
   44 #include 
   45 #include 
   46 
   47 #define TCP_MOD_ID      5105
   48 
   49 extern struct qinit     tcp_sock_winit;
   50 extern struct qinit     tcp_winit;
   51 
   52 extern sock_downcalls_t sock_tcp_downcalls;
   53 
   54 /*
   55  * Bind hash list size and has function.  It has to be a power of 2 for
   56  * hashing.
   57  */
   58 #define TCP_BIND_FANOUT_SIZE    512
   59 #define TCP_BIND_HASH(lport) (ntohs(lport) & (TCP_BIND_FANOUT_SIZE - 1))
   60 
   61 /*
   62  * This implementation follows the 4.3BSD interpretation of the urgent
   63  * pointer and not RFC 1122. Switching to RFC 1122 behavior would cause
   64  * incompatible changes in protocols like telnet and rlogin.
   65  */
   66 #define TCP_OLD_URP_INTERPRETATION      1
   67 
   68 /* TCP option length */
   69 #define TCPOPT_NOP_LEN          1
   70 #define TCPOPT_MAXSEG_LEN       4
   71 #define TCPOPT_WS_LEN           3
   72 #define TCPOPT_REAL_WS_LEN      (TCPOPT_WS_LEN+1)
   73 #define TCPOPT_TSTAMP_LEN       10
   74 #define TCPOPT_REAL_TS_LEN      (TCPOPT_TSTAMP_LEN+2)
   75 #define TCPOPT_SACK_OK_LEN      2
   76 #define TCPOPT_REAL_SACK_OK_LEN (TCPOPT_SACK_OK_LEN+2)
   77 #define TCPOPT_REAL_SACK_LEN    4
   78 #define TCPOPT_MAX_SACK_LEN     36
   79 #define TCPOPT_HEADER_LEN       2
   80 
   81 /* Round up the value to the nearest mss. */
   82 #define MSS_ROUNDUP(value, mss)         ((((value) - 1) / (mss) + 1) * (mss))
   83 
   84 /*
   85  * Was this tcp created via socket() interface?
   86  */
   87 #define TCP_IS_SOCKET(tcp)      ((tcp)->tcp_issocket)
   88 
   89 /*
   90  * Is this tcp not attached to any upper client?
   91  */
   92 #define TCP_IS_DETACHED(tcp)    ((tcp)->tcp_detached)
   93 
   94 /* TCP timers related data strucutres.  Refer to tcp_timers.c. */
   95 typedef struct tcp_timer_s {
   96         conn_t  *connp;
   97         void    (*tcpt_proc)(void *);
   98         callout_id_t   tcpt_tid;
   99 } tcp_timer_t;
  100 
  101 extern kmem_cache_t *tcp_timercache;
  102 
  103 /*
  104  * Macro for starting various timers.  Retransmission timer has its own macro,
  105  * TCP_TIMER_RESTART().  tim is in millisec.
  106  */
  107 #define TCP_TIMER(tcp, f, tim)          \
  108         tcp_timeout(tcp->tcp_connp, f, tim)
  109 #define TCP_TIMER_CANCEL(tcp, id)       \
  110         tcp_timeout_cancel(tcp->tcp_connp, id)
  111 
  112 /*
  113  * To restart the TCP retransmission timer.  intvl is in millisec.
  114  */
  115 #define TCP_TIMER_RESTART(tcp, intvl) {                                 \
  116         if ((tcp)->tcp_timer_tid != 0)                                  \
  117                 (void) TCP_TIMER_CANCEL((tcp), (tcp)->tcp_timer_tid);   \
  118         (tcp)->tcp_timer_tid = TCP_TIMER((tcp), tcp_timer, (intvl));    \
  119 }
  120 
  121 /*
  122  * For scalability, we must not run a timer for every TCP connection
  123  * in TIME_WAIT state.  To see why, consider (for time wait interval of
  124  * 1 minutes):
  125  *      10,000 connections/sec * 60 seconds/time wait = 600,000 active conn's
  126  *
  127  * This list is ordered by time, so you need only delete from the head
  128  * until you get to entries which aren't old enough to delete yet.
  129  * The list consists of only the detached TIME_WAIT connections.
  130  *
  131  * When a tcp_t enters TIME_WAIT state, a timer is started (timeout is
  132  * tcps_time_wait_interval).  When the tcp_t is detached (upper layer closes
  133  * the end point), it is moved to the time wait list and another timer is
  134  * started (expiry time is set at tcp_time_wait_expire, which is
  135  * also calculated using tcps_time_wait_interval).  This means that the
  136  * TIME_WAIT state can be extended (up to doubled) if the tcp_t doesn't
  137  * become detached for a long time.
  138  *
  139  * The list manipulations (including tcp_time_wait_next/prev)
  140  * are protected by the tcp_time_wait_lock. The content of the
  141  * detached TIME_WAIT connections is protected by the normal perimeters.
  142  *
  143  * This list is per squeue and squeues are shared across the tcp_stack_t's.
  144  * Things on tcp_time_wait_head remain associated with the tcp_stack_t
  145  * and conn_netstack.
  146  * The tcp_t's that are added to tcp_free_list are disassociated and
  147  * have NULL tcp_tcps and conn_netstack pointers.
  148  */
  149 typedef struct tcp_squeue_priv_s {
  150         kmutex_t        tcp_time_wait_lock;
  151         callout_id_t    tcp_time_wait_tid;
  152         tcp_t           *tcp_time_wait_head;
  153         tcp_t           *tcp_time_wait_tail;
  154         tcp_t           *tcp_free_list;
  155         uint_t          tcp_free_list_cnt;
  156 #ifdef DEBUG
  157         /*
  158          * For debugging purpose, true when tcp_time_wait_collector() is
  159          * running.
  160          */
  161         boolean_t       tcp_time_wait_running;
  162 #endif
  163 } tcp_squeue_priv_t;
  164 
  165 /*
  166  * Parameters for TCP Initial Send Sequence number (ISS) generation.  When
  167  * tcp_strong_iss is set to 1, which is the default, the ISS is calculated
  168  * by adding three components: a time component which grows by 1 every 4096
  169  * nanoseconds (versus every 4 microseconds suggested by RFC 793, page 27);
  170  * a per-connection component which grows by 125000 for every new connection;
  171  * and an "extra" component that grows by a random amount centered
  172  * approximately on 64000.  This causes the ISS generator to cycle every
  173  * 4.89 hours if no TCP connections are made, and faster if connections are
  174  * made.
  175  *
  176  * When tcp_strong_iss is set to 0, ISS is calculated by adding two
  177  * components: a time component which grows by 250000 every second; and
  178  * a per-connection component which grows by 125000 for every new connections.
  179  *
  180  * A third method, when tcp_strong_iss is set to 2, for generating ISS is
  181  * prescribed by Steve Bellovin.  This involves adding time, the 125000 per
  182  * connection, and a one-way hash (MD5) of the connection ID , a "truly" random (per RFC 1750) number, and a console-entered
  184  * password.
  185  */
  186 #define ISS_INCR        250000
  187 #define ISS_NSEC_SHT    12
  188 
  189 /* Macros for timestamp comparisons */
  190 #define TSTMP_GEQ(a, b) ((int32_t)((a)-(b)) >= 0)
  191 #define TSTMP_LT(a, b)  ((int32_t)((a)-(b)) < 0)
  192 
  193 /*
  194  * Initialize cwnd according to RFC 3390.  def_max_init_cwnd is
  195  * either tcp_slow_start_initial or tcp_slow_start_after idle
  196  * depending on the caller.  If the upper layer has not used the
  197  * TCP_INIT_CWND option to change the initial cwnd, tcp_init_cwnd
  198  * should be 0 and we use the formula in RFC 3390 to set tcp_cwnd.
  199  * If the upper layer has changed set the tcp_init_cwnd, just use
  200  * it to calculate the tcp_cwnd.
  201  */
  202 #define TCP_SET_INIT_CWND(tcp, mss, def_max_init_cwnd)                  \
  203 {                                                                       \
  204         if ((tcp)->tcp_init_cwnd == 0) {                                \
  205                 (tcp)->tcp_cwnd = MIN(def_max_init_cwnd * (mss),        \
  206                     MIN(4 * (mss), MAX(2 * (mss), 4380 / (mss) * (mss)))); \
  207         } else {                                                        \
  208                 (tcp)->tcp_cwnd = (tcp)->tcp_init_cwnd * (mss);         \
  209         }                                                               \
  210         tcp->tcp_cwnd_cnt = 0;                                          \
  211 }
  212 
  213 /*
  214  * Set ECN capable transport (ECT) code point in IP header.
  215  *
  216  * Note that there are 2 ECT code points '01' and '10', which are called
  217  * ECT(1) and ECT(0) respectively.  Here we follow the original ECT code
  218  * point ECT(0) for TCP as described in RFC 2481.
  219  */
  220 #define TCP_SET_ECT(tcp, iph) \
  221         if ((tcp)->tcp_connp->conn_ipversion == IPV4_VERSION) { \
  222                 /* We need to clear the code point first. */ \
  223                 ((ipha_t *)(iph))->ipha_type_of_service &= 0xFC; \
  224                 ((ipha_t *)(iph))->ipha_type_of_service |= IPH_ECN_ECT0; \
  225         } else { \
  226                 ((ip6_t *)(iph))->ip6_vcf &= htonl(0xFFCFFFFF); \
  227                 ((ip6_t *)(iph))->ip6_vcf |= htonl(IPH_ECN_ECT0 << 20); \
  228         }
  229 
  230 /*
  231  * Set tcp_rto with boundary checking.
  232  */
  233 #define TCP_SET_RTO(tcp, rto) \
  234         if ((rto) < (tcp)->tcp_rto_min)                 \
  235                 (tcp)->tcp_rto = (tcp)->tcp_rto_min;    \
  236         else if ((rto) > (tcp)->tcp_rto_max)            \
  237                 (tcp)->tcp_rto = (tcp)->tcp_rto_max;    \
  238         else                                            \
  239                 (tcp)->tcp_rto = (rto);
  240 
  241 /*
  242  * TCP options struct returned from tcp_parse_options.
  243  */
  244 typedef struct tcp_opt_s {
  245         uint32_t        tcp_opt_mss;
  246         uint32_t        tcp_opt_wscale;
  247         uint32_t        tcp_opt_ts_val;
  248         uint32_t        tcp_opt_ts_ecr;
  249         tcp_t           *tcp;
  250 } tcp_opt_t;
  251 
  252 /*
  253  * Write-side flow-control is implemented via the per instance STREAMS
  254  * write-side Q by explicitly setting QFULL to stop the flow of mblk_t(s)
  255  * and clearing QFULL and calling qbackenable() to restart the flow based
  256  * on the number of TCP unsent bytes (i.e. those not on the wire waiting
  257  * for a remote ACK).
  258  *
  259  * This is different than a standard STREAMS kmod which when using the
  260  * STREAMS Q the framework would automatictly flow-control based on the
  261  * defined hiwat/lowat values as mblk_t's are enqueued/dequeued.
  262  *
  263  * As of FireEngine TCP write-side flow-control needs to take into account
  264  * both the unsent tcp_xmit list bytes but also any squeue_t enqueued bytes
  265  * (i.e. from tcp_wput() -> tcp_output()).
  266  *
  267  * This is accomplished by adding a new tcp_t fields, tcp_squeue_bytes, to
  268  * count the number of bytes enqueued by tcp_wput() and the number of bytes
  269  * dequeued and processed by tcp_output().
  270  *
  271  * So, the total number of bytes unsent is (squeue_bytes + unsent) with all
  272  * flow-control uses of unsent replaced with the macro TCP_UNSENT_BYTES.
  273  */
  274 extern void     tcp_clrqfull(tcp_t *);
  275 extern void     tcp_setqfull(tcp_t *);
  276 
  277 #define TCP_UNSENT_BYTES(tcp) \
  278         ((tcp)->tcp_squeue_bytes + (tcp)->tcp_unsent)
  279 
  280 /*
  281  * Linked list struct to store listener connection limit configuration per
  282  * IP stack.  The list is stored at tcps_listener_conf in tcp_stack_t.
  283  *
  284  * tl_port: the listener port of this limit configuration
  285  * tl_ratio: the maximum amount of memory consumed by all concurrent TCP
  286  *           connections created by a listener does not exceed 1/tl_ratio
  287  *           of the total system memory.  Note that this is only an
  288  *           approximation.
  289  * tl_link: linked list struct
  290  */
  291 typedef struct tcp_listener_s {
  292         in_port_t       tl_port;
  293         uint32_t        tl_ratio;
  294         list_node_t     tl_link;
  295 } tcp_listener_t;
  296 
  297 /*
  298  * If there is a limit set on the number of connections allowed per each
  299  * listener, the following struct is used to store that counter.  It keeps
  300  * the number of TCP connection created by a listener.  Note that this needs
  301  * to be separated from the listener since the listener can go away before
  302  * all the connections are gone.
  303  *
  304  * When the struct is allocated, tlc_cnt is set to 1.  When a new connection
  305  * is created by the listener, tlc_cnt is incremented by 1.  When a connection
  306  * created by the listener goes away, tlc_count is decremented by 1.  When the
  307  * listener itself goes away, tlc_cnt is decremented  by one.  The last
  308  * connection (or the listener) which decrements tlc_cnt to zero frees the
  309  * struct.
  310  *
  311  * tlc_max is the maximum number of concurrent TCP connections created from a
  312  * listner.  It is calculated when the tcp_listen_cnt_t is allocated.
  313  *
  314  * tlc_report_time stores the time when cmn_err() is called to report that the
  315  * max has been exceeeded.  Report is done at most once every
  316  * TCP_TLC_REPORT_INTERVAL mins for a listener.
  317  *
  318  * tlc_drop stores the number of connection attempt dropped because the
  319  * limit has reached.
  320  */
  321 typedef struct tcp_listen_cnt_s {
  322         uint32_t        tlc_max;
  323         uint32_t        tlc_cnt;
  324         int64_t         tlc_report_time;
  325         uint32_t        tlc_drop;
  326 } tcp_listen_cnt_t;
  327 
  328 #define TCP_TLC_REPORT_INTERVAL (30 * MINUTES)
  329 
  330 #define TCP_DECR_LISTEN_CNT(tcp)                                        \
  331 {                                                                       \
  332         ASSERT((tcp)->tcp_listen_cnt->tlc_cnt > 0);                     \
  333         if (atomic_add_32_nv(&(tcp)->tcp_listen_cnt->tlc_cnt, -1) == 0) \
  334                 kmem_free((tcp)->tcp_listen_cnt, sizeof (tcp_listen_cnt_t)); \
  335         (tcp)->tcp_listen_cnt = NULL;                                   \
  336 }
  337 
  338 /* Increment and decrement the number of connections in tcp_stack_t. */
  339 #define TCPS_CONN_INC(tcps)                                             \
  340         atomic_inc_64(                                                  \
  341             (uint64_t *)&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_conn_cnt)
  342 
  343 #define TCPS_CONN_DEC(tcps)                                             \
  344         atomic_dec_64(                                                  \
  345             (uint64_t *)&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_conn_cnt)
  346 
  347 /*
  348  * When the system is under memory pressure, stack variable tcps_reclaim is
  349  * true, we shorten the connection timeout abort interval to tcp_early_abort
  350  * seconds.  Defined in tcp.c.
  351  */
  352 extern uint32_t tcp_early_abort;
  353 
  354 /*
  355  * To reach to an eager in Q0 which can be dropped due to an incoming
  356  * new SYN request when Q0 is full, a new doubly linked list is
  357  * introduced. This list allows to select an eager from Q0 in O(1) time.
  358  * This is needed to avoid spending too much time walking through the
  359  * long list of eagers in Q0 when tcp_drop_q0() is called. Each member of
  360  * this new list has to be a member of Q0.
  361  * This list is headed by listener's tcp_t. When the list is empty,
  362  * both the pointers - tcp_eager_next_drop_q0 and tcp_eager_prev_drop_q0,
  363  * of listener's tcp_t point to listener's tcp_t itself.
  364  *
  365  * Given an eager in Q0 and a listener, MAKE_DROPPABLE() puts the eager
  366  * in the list. MAKE_UNDROPPABLE() takes the eager out of the list.
  367  * These macros do not affect the eager's membership to Q0.
  368  */
  369 #define MAKE_DROPPABLE(listener, eager)                                 \
  370         if ((eager)->tcp_eager_next_drop_q0 == NULL) {                  \
  371                 (listener)->tcp_eager_next_drop_q0->tcp_eager_prev_drop_q0\
  372                     = (eager);                                          \
  373                 (eager)->tcp_eager_prev_drop_q0 = (listener);           \
  374                 (eager)->tcp_eager_next_drop_q0 =                       \
  375                     (listener)->tcp_eager_next_drop_q0;                 \
  376                 (listener)->tcp_eager_next_drop_q0 = (eager);           \
  377         }
  378 
  379 #define MAKE_UNDROPPABLE(eager)                                         \
  380         if ((eager)->tcp_eager_next_drop_q0 != NULL) {                  \
  381                 (eager)->tcp_eager_next_drop_q0->tcp_eager_prev_drop_q0 \
  382                     = (eager)->tcp_eager_prev_drop_q0;                  \
  383                 (eager)->tcp_eager_prev_drop_q0->tcp_eager_next_drop_q0 \
  384                     = (eager)->tcp_eager_next_drop_q0;                  \
  385                 (eager)->tcp_eager_prev_drop_q0 = NULL;                 \
  386                 (eager)->tcp_eager_next_drop_q0 = NULL;                 \
  387         }
  388 
  389 /*
  390  * The format argument to pass to tcp_display().
  391  * DISP_PORT_ONLY means that the returned string has only port info.
  392  * DISP_ADDR_AND_PORT means that the returned string also contains the
  393  * remote and local IP address.
  394  */
  395 #define DISP_PORT_ONLY          1
  396 #define DISP_ADDR_AND_PORT      2
  397 
  398 #define IP_ADDR_CACHE_SIZE      2048
  399 #define IP_ADDR_CACHE_HASH(faddr)                                       \
  400         (ntohl(faddr) & (IP_ADDR_CACHE_SIZE -1))
  401 
  402 /* TCP cwnd burst factor. */
  403 #define TCP_CWND_INFINITE       65535
  404 #define TCP_CWND_SS             3
  405 #define TCP_CWND_NORMAL         5
  406 
  407 /*
  408  * TCP reassembly macros.  We hide starting and ending sequence numbers in
  409  * b_next and b_prev of messages on the reassembly queue.  The messages are
  410  * chained using b_cont.  These macros are used in tcp_reass() so we don't
  411  * have to see the ugly casts and assignments.
  412  */
  413 #define TCP_REASS_SEQ(mp)               ((uint32_t)(uintptr_t)((mp)->b_next))
  414 #define TCP_REASS_SET_SEQ(mp, u)        ((mp)->b_next = \
  415                                         (mblk_t *)(uintptr_t)(u))
  416 #define TCP_REASS_END(mp)               ((uint32_t)(uintptr_t)((mp)->b_prev))
  417 #define TCP_REASS_SET_END(mp, u)        ((mp)->b_prev = \
  418                                         (mblk_t *)(uintptr_t)(u))
  419 
  420 #define tcps_time_wait_interval         tcps_propinfo_tbl[0].prop_cur_uval
  421 #define tcps_conn_req_max_q             tcps_propinfo_tbl[1].prop_cur_uval
  422 #define tcps_conn_req_max_q0            tcps_propinfo_tbl[2].prop_cur_uval
  423 #define tcps_conn_req_min               tcps_propinfo_tbl[3].prop_cur_uval
  424 #define tcps_conn_grace_period          tcps_propinfo_tbl[4].prop_cur_uval
  425 #define tcps_cwnd_max_                  tcps_propinfo_tbl[5].prop_cur_uval
  426 #define tcps_dbg                        tcps_propinfo_tbl[6].prop_cur_uval
  427 #define tcps_smallest_nonpriv_port      tcps_propinfo_tbl[7].prop_cur_uval
  428 #define tcps_ip_abort_cinterval         tcps_propinfo_tbl[8].prop_cur_uval
  429 #define tcps_ip_abort_linterval         tcps_propinfo_tbl[9].prop_cur_uval
  430 #define tcps_ip_abort_interval          tcps_propinfo_tbl[10].prop_cur_uval
  431 #define tcps_ip_notify_cinterval        tcps_propinfo_tbl[11].prop_cur_uval
  432 #define tcps_ip_notify_interval         tcps_propinfo_tbl[12].prop_cur_uval
  433 #define tcps_ipv4_ttl                   tcps_propinfo_tbl[13].prop_cur_uval
  434 #define tcps_keepalive_interval_high    tcps_propinfo_tbl[14].prop_max_uval
  435 #define tcps_keepalive_interval         tcps_propinfo_tbl[14].prop_cur_uval
  436 #define tcps_keepalive_interval_low     tcps_propinfo_tbl[14].prop_min_uval
  437 #define tcps_maxpsz_multiplier          tcps_propinfo_tbl[15].prop_cur_uval
  438 #define tcps_mss_def_ipv4               tcps_propinfo_tbl[16].prop_cur_uval
  439 #define tcps_mss_max_ipv4               tcps_propinfo_tbl[17].prop_cur_uval
  440 #define tcps_mss_min                    tcps_propinfo_tbl[18].prop_cur_uval
  441 #define tcps_naglim_def                 tcps_propinfo_tbl[19].prop_cur_uval
  442 #define tcps_rexmit_interval_initial_high       \
  443                                         tcps_propinfo_tbl[20].prop_max_uval
  444 #define tcps_rexmit_interval_initial    tcps_propinfo_tbl[20].prop_cur_uval
  445 #define tcps_rexmit_interval_initial_low        \
  446                                         tcps_propinfo_tbl[20].prop_min_uval
  447 #define tcps_rexmit_interval_max_high   tcps_propinfo_tbl[21].prop_max_uval
  448 #define tcps_rexmit_interval_max        tcps_propinfo_tbl[21].prop_cur_uval
  449 #define tcps_rexmit_interval_max_low    tcps_propinfo_tbl[21].prop_min_uval
  450 #define tcps_rexmit_interval_min_high   tcps_propinfo_tbl[22].prop_max_uval
  451 #define tcps_rexmit_interval_min        tcps_propinfo_tbl[22].prop_cur_uval
  452 #define tcps_rexmit_interval_min_low    tcps_propinfo_tbl[22].prop_min_uval
  453 #define tcps_deferred_ack_interval      tcps_propinfo_tbl[23].prop_cur_uval
  454 #define tcps_snd_lowat_fraction         tcps_propinfo_tbl[24].prop_cur_uval
  455 #define tcps_dupack_fast_retransmit     tcps_propinfo_tbl[25].prop_cur_uval
  456 #define tcps_ignore_path_mtu            tcps_propinfo_tbl[26].prop_cur_bval
  457 #define tcps_smallest_anon_port         tcps_propinfo_tbl[27].prop_cur_uval
  458 #define tcps_largest_anon_port          tcps_propinfo_tbl[28].prop_cur_uval
  459 #define tcps_xmit_hiwat                 tcps_propinfo_tbl[29].prop_cur_uval
  460 #define tcps_xmit_lowat                 tcps_propinfo_tbl[30].prop_cur_uval
  461 #define tcps_recv_hiwat                 tcps_propinfo_tbl[31].prop_cur_uval
  462 #define tcps_recv_hiwat_minmss          tcps_propinfo_tbl[32].prop_cur_uval
  463 #define tcps_fin_wait_2_flush_interval_high     \
  464                                         tcps_propinfo_tbl[33].prop_max_uval
  465 #define tcps_fin_wait_2_flush_interval  tcps_propinfo_tbl[33].prop_cur_uval
  466 #define tcps_fin_wait_2_flush_interval_low      \
  467                                         tcps_propinfo_tbl[33].prop_min_uval
  468 #define tcps_max_buf                    tcps_propinfo_tbl[34].prop_cur_uval
  469 #define tcps_strong_iss                 tcps_propinfo_tbl[35].prop_cur_uval
  470 #define tcps_rtt_updates                tcps_propinfo_tbl[36].prop_cur_uval
  471 #define tcps_wscale_always              tcps_propinfo_tbl[37].prop_cur_bval
  472 #define tcps_tstamp_always              tcps_propinfo_tbl[38].prop_cur_bval
  473 #define tcps_tstamp_if_wscale           tcps_propinfo_tbl[39].prop_cur_bval
  474 #define tcps_rexmit_interval_extra      tcps_propinfo_tbl[40].prop_cur_uval
  475 #define tcps_deferred_acks_max          tcps_propinfo_tbl[41].prop_cur_uval
  476 #define tcps_slow_start_after_idle      tcps_propinfo_tbl[42].prop_cur_uval
  477 #define tcps_slow_start_initial         tcps_propinfo_tbl[43].prop_cur_uval
  478 #define tcps_sack_permitted             tcps_propinfo_tbl[44].prop_cur_uval
  479 #define tcps_ipv6_hoplimit              tcps_propinfo_tbl[45].prop_cur_uval
  480 #define tcps_mss_def_ipv6               tcps_propinfo_tbl[46].prop_cur_uval
  481 #define tcps_mss_max_ipv6               tcps_propinfo_tbl[47].prop_cur_uval
  482 #define tcps_rev_src_routes             tcps_propinfo_tbl[48].prop_cur_bval
  483 #define tcps_local_dack_interval        tcps_propinfo_tbl[49].prop_cur_uval
  484 #define tcps_local_dacks_max            tcps_propinfo_tbl[50].prop_cur_uval
  485 #define tcps_ecn_permitted              tcps_propinfo_tbl[51].prop_cur_uval
  486 #define tcps_rst_sent_rate_enabled      tcps_propinfo_tbl[52].prop_cur_bval
  487 #define tcps_rst_sent_rate              tcps_propinfo_tbl[53].prop_cur_uval
  488 #define tcps_push_timer_interval        tcps_propinfo_tbl[54].prop_cur_uval
  489 #define tcps_use_smss_as_mss_opt        tcps_propinfo_tbl[55].prop_cur_bval
  490 #define tcps_keepalive_abort_interval_high \
  491                                         tcps_propinfo_tbl[56].prop_max_uval
  492 #define tcps_keepalive_abort_interval \
  493                                         tcps_propinfo_tbl[56].prop_cur_uval
  494 #define tcps_keepalive_abort_interval_low \
  495                                         tcps_propinfo_tbl[56].prop_min_uval
  496 #define tcps_wroff_xtra                 tcps_propinfo_tbl[57].prop_cur_uval
  497 #define tcps_dev_flow_ctl               tcps_propinfo_tbl[58].prop_cur_bval
  498 #define tcps_reass_timeout              tcps_propinfo_tbl[59].prop_cur_uval
  499 
  500 extern struct qinit tcp_rinitv4, tcp_rinitv6;
  501 extern boolean_t do_tcp_fusion;
  502 
  503 /*
  504  * Object to represent database of options to search passed to
  505  * {sock,tpi}optcom_req() interface routine to take care of option
  506  * management and associated methods.
  507  */
  508 extern optdb_obj_t      tcp_opt_obj;
  509 extern uint_t           tcp_max_optsize;
  510 
  511 extern int tcp_squeue_flag;
  512 
  513 extern uint_t tcp_free_list_max_cnt;
  514 
  515 /*
  516  * Functions in tcp.c.
  517  */
  518 extern void     tcp_acceptor_hash_insert(t_uscalar_t, tcp_t *);
  519 extern tcp_t    *tcp_acceptor_hash_lookup(t_uscalar_t, tcp_stack_t *);
  520 extern void     tcp_acceptor_hash_remove(tcp_t *);
  521 extern mblk_t   *tcp_ack_mp(tcp_t *);
  522 extern int      tcp_build_hdrs(tcp_t *);
  523 extern void     tcp_cleanup(tcp_t *);
  524 extern int      tcp_clean_death(tcp_t *, int);
  525 extern void     tcp_clean_death_wrapper(void *, mblk_t *, void *,
  526                     ip_recv_attr_t *);
  527 extern void     tcp_close_common(conn_t *, int);
  528 extern void     tcp_close_detached(tcp_t *);
  529 extern void     tcp_close_mpp(mblk_t **);
  530 extern void     tcp_closei_local(tcp_t *);
  531 extern sock_lower_handle_t tcp_create(int, int, int, sock_downcalls_t **,
  532                     uint_t *, int *, int, cred_t *);
  533 extern conn_t   *tcp_create_common(cred_t *, boolean_t, boolean_t, int *);
  534 extern void     tcp_disconnect(tcp_t *, mblk_t *);
  535 extern char     *tcp_display(tcp_t *, char *, char);
  536 extern int      tcp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
  537                     boolean_t);
  538 extern int      tcp_do_connect(conn_t *, const struct sockaddr *, socklen_t,
  539                     cred_t *, pid_t);
  540 extern int      tcp_do_listen(conn_t *, struct sockaddr *, socklen_t, int,
  541                     cred_t *, boolean_t);
  542 extern int      tcp_do_unbind(conn_t *);
  543 extern boolean_t        tcp_eager_blowoff(tcp_t *, t_scalar_t);
  544 extern void     tcp_eager_cleanup(tcp_t *, boolean_t);
  545 extern void     tcp_eager_kill(void *, mblk_t *, void *, ip_recv_attr_t *);
  546 extern void     tcp_eager_unlink(tcp_t *);
  547 extern int      tcp_getpeername(sock_lower_handle_t, struct sockaddr *,
  548                     socklen_t *, cred_t *);
  549 extern int      tcp_getsockname(sock_lower_handle_t, struct sockaddr *,
  550                     socklen_t *, cred_t *);
  551 extern void     tcp_init_values(tcp_t *, tcp_t *);
  552 extern void     tcp_ipsec_cleanup(tcp_t *);
  553 extern int      tcp_maxpsz_set(tcp_t *, boolean_t);
  554 extern void     tcp_mss_set(tcp_t *, uint32_t);
  555 extern void     tcp_reinput(conn_t *, mblk_t *, ip_recv_attr_t *, ip_stack_t *);
  556 extern void     tcp_rsrv(queue_t *);
  557 extern uint_t   tcp_rwnd_reopen(tcp_t *);
  558 extern int      tcp_rwnd_set(tcp_t *, uint32_t);
  559 extern int      tcp_set_destination(tcp_t *);
  560 extern void     tcp_set_ws_value(tcp_t *);
  561 extern void     tcp_stop_lingering(tcp_t *);
  562 extern void     tcp_update_pmtu(tcp_t *, boolean_t);
  563 extern mblk_t   *tcp_zcopy_backoff(tcp_t *, mblk_t *, boolean_t);
  564 extern boolean_t        tcp_zcopy_check(tcp_t *);
  565 extern void     tcp_zcopy_notify(tcp_t *);
  566 extern void     tcp_get_proto_props(tcp_t *, struct sock_proto_props *);
  567 
  568 /*
  569  * Bind related functions in tcp_bind.c
  570  */
  571 extern int      tcp_bind_check(conn_t *, struct sockaddr *, socklen_t,
  572                     cred_t *, boolean_t);
  573 extern void     tcp_bind_hash_insert(tf_t *, tcp_t *, int);
  574 extern void     tcp_bind_hash_remove(tcp_t *);
  575 extern in_port_t        tcp_bindi(tcp_t *, in_port_t, const in6_addr_t *,
  576                             int, boolean_t, boolean_t, boolean_t);
  577 extern in_port_t        tcp_update_next_port(in_port_t, const tcp_t *,
  578                             boolean_t);
  579 
  580 /*
  581  * Fusion related functions in tcp_fusion.c.
  582  */
  583 extern void     tcp_fuse(tcp_t *, uchar_t *, tcpha_t *);
  584 extern void     tcp_unfuse(tcp_t *);
  585 extern boolean_t tcp_fuse_output(tcp_t *, mblk_t *, uint32_t);
  586 extern void     tcp_fuse_output_urg(tcp_t *, mblk_t *);
  587 extern boolean_t tcp_fuse_rcv_drain(queue_t *, tcp_t *, mblk_t **);
  588 extern size_t   tcp_fuse_set_rcv_hiwat(tcp_t *, size_t);
  589 extern int      tcp_fuse_maxpsz(tcp_t *);
  590 extern void     tcp_fuse_backenable(tcp_t *);
  591 extern void     tcp_iss_key_init(uint8_t *, int, tcp_stack_t *);
  592 
  593 /*
  594  * Output related functions in tcp_output.c.
  595  */
  596 extern void     tcp_close_output(void *, mblk_t *, void *, ip_recv_attr_t *);
  597 extern void     tcp_output(void *, mblk_t *, void *, ip_recv_attr_t *);
  598 extern void     tcp_output_urgent(void *, mblk_t *, void *, ip_recv_attr_t *);
  599 extern void     tcp_rexmit_after_error(tcp_t *);
  600 extern void     tcp_sack_rexmit(tcp_t *, uint_t *);
  601 extern void     tcp_send_data(tcp_t *, mblk_t *);
  602 extern void     tcp_send_synack(void *, mblk_t *, void *, ip_recv_attr_t *);
  603 extern void     tcp_shutdown_output(void *, mblk_t *, void *, ip_recv_attr_t *);
  604 extern void     tcp_ss_rexmit(tcp_t *);
  605 extern void     tcp_update_xmit_tail(tcp_t *, uint32_t);
  606 extern void     tcp_wput(queue_t *, mblk_t *);
  607 extern void     tcp_wput_data(tcp_t *, mblk_t *, boolean_t);
  608 extern void     tcp_wput_sock(queue_t *, mblk_t *);
  609 extern void     tcp_wput_fallback(queue_t *, mblk_t *);
  610 extern void     tcp_xmit_ctl(char *, tcp_t *, uint32_t, uint32_t, int);
  611 extern void     tcp_xmit_listeners_reset(mblk_t *, ip_recv_attr_t *,
  612                     ip_stack_t *i, conn_t *);
  613 extern mblk_t   *tcp_xmit_mp(tcp_t *, mblk_t *, int32_t, int32_t *,
  614                     mblk_t **, uint32_t, boolean_t, uint32_t *, boolean_t);
  615 
  616 /*
  617  * Input related functions in tcp_input.c.
  618  */
  619 extern void     tcp_icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
  620 extern void     tcp_input_data(void *, mblk_t *, void *, ip_recv_attr_t *);
  621 extern void     tcp_input_listener_unbound(void *, mblk_t *, void *,
  622                     ip_recv_attr_t *);
  623 extern boolean_t        tcp_paws_check(tcp_t *, tcpha_t *, tcp_opt_t *);
  624 extern uint_t   tcp_rcv_drain(tcp_t *);
  625 extern void     tcp_rcv_enqueue(tcp_t *, mblk_t *, uint_t, cred_t *);
  626 extern boolean_t        tcp_verifyicmp(conn_t *, void *, icmph_t *, icmp6_t *,
  627                             ip_recv_attr_t *);
  628 
  629 /*
  630  * Kernel socket related functions in tcp_socket.c.
  631  */
  632 extern int      tcp_fallback(sock_lower_handle_t, queue_t *, boolean_t,
  633                     so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
  634 extern boolean_t tcp_newconn_notify(tcp_t *, ip_recv_attr_t *);
  635 
  636 /*
  637  * Timer related functions in tcp_timers.c.
  638  */
  639 extern void     tcp_ack_timer(void *);
  640 extern void     tcp_close_linger_timeout(void *);
  641 extern void     tcp_keepalive_timer(void *);
  642 extern void     tcp_push_timer(void *);
  643 extern void     tcp_reass_timer(void *);
  644 extern mblk_t   *tcp_timermp_alloc(int);
  645 extern void     tcp_timermp_free(tcp_t *);
  646 extern timeout_id_t tcp_timeout(conn_t *, void (*)(void *), hrtime_t);
  647 extern clock_t  tcp_timeout_cancel(conn_t *, timeout_id_t);
  648 extern void     tcp_timer(void *arg);
  649 extern void     tcp_timers_stop(tcp_t *);
  650 
  651 /*
  652  * TCP TPI related functions in tcp_tpi.c.
  653  */
  654 extern void     tcp_addr_req(tcp_t *, mblk_t *);
  655 extern void     tcp_capability_req(tcp_t *, mblk_t *);
  656 extern boolean_t        tcp_conn_con(tcp_t *, uchar_t *, mblk_t *,
  657                             mblk_t **, ip_recv_attr_t *);
  658 extern void     tcp_err_ack(tcp_t *, mblk_t *, int, int);
  659 extern void     tcp_err_ack_prim(tcp_t *, mblk_t *, int, int, int);
  660 extern void     tcp_info_req(tcp_t *, mblk_t *);
  661 extern void     tcp_send_conn_ind(void *, mblk_t *, void *);
  662 extern void     tcp_send_pending(void *, mblk_t *, void *, ip_recv_attr_t *);
  663 extern void     tcp_tpi_accept(queue_t *, mblk_t *);
  664 extern void     tcp_tpi_bind(tcp_t *, mblk_t *);
  665 extern int      tcp_tpi_close(queue_t *, int);
  666 extern int      tcp_tpi_close_accept(queue_t *);
  667 extern void     tcp_tpi_connect(tcp_t *, mblk_t *);
  668 extern int      tcp_tpi_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
  669 extern int      tcp_tpi_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *,
  670                     uint_t *, uchar_t *, void *, cred_t *);
  671 extern void     tcp_tpi_unbind(tcp_t *, mblk_t *);
  672 extern void     tcp_tli_accept(tcp_t *, mblk_t *);
  673 extern void     tcp_use_pure_tpi(tcp_t *);
  674 extern void     tcp_do_capability_ack(tcp_t *, struct T_capability_ack *,
  675                     t_uscalar_t);
  676 
  677 /*
  678  * TCP option processing related functions in tcp_opt_data.c
  679  */
  680 extern int      tcp_opt_default(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
  681 extern int      tcp_opt_get(conn_t *, int, int, uchar_t *);
  682 extern int      tcp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *,
  683                     uint_t *, uchar_t *, void *, cred_t *);
  684 
  685 /*
  686  * TCP time wait processing related functions in tcp_time_wait.c.
  687  */
  688 extern void             tcp_time_wait_append(tcp_t *);
  689 extern void             tcp_time_wait_collector(void *);
  690 extern boolean_t        tcp_time_wait_remove(tcp_t *, tcp_squeue_priv_t *);
  691 extern void             tcp_time_wait_processing(tcp_t *, mblk_t *, uint32_t,
  692                             uint32_t, int, tcpha_t *, ip_recv_attr_t *);
  693 
  694 /*
  695  * Misc functions in tcp_misc.c.
  696  */
  697 extern uint32_t tcp_find_listener_conf(tcp_stack_t *, in_port_t);
  698 extern void     tcp_ioctl_abort_conn(queue_t *, mblk_t *);
  699 extern void     tcp_listener_conf_cleanup(tcp_stack_t *);
  700 extern void     tcp_stack_cpu_add(tcp_stack_t *, processorid_t);
  701 
  702 #endif  /* _KERNEL */
  703 
  704 #ifdef  __cplusplus
  705 }
  706 #endif
  707 
  708 #endif  /* _INET_TCP_IMPL_H */

Minix/kernel/system.c

  1 static char rcsid[] = "$Id";
  2 
  3 /* This task handles the interface between file system and kernel as well as
  4  * between memory manager and kernel.  System services are obtained by sending
  5  * sys_task() a message specifying what is needed.  To make life easier for
  6  * MM and FS, a library is provided with routines whose names are of the
  7  * form sys_xxx, e.g. sys_xit sends the SYS_XIT message to sys_task.  The
  8  * message types and parameters are:
  9  *
 10  *   SYS_FORK    informs kernel that a process has forked
 11  *   SYS_NEWMAP  allows MM to set up a process memory map
 12  *   SYS_GETMAP  allows MM to get a process' memory map
 13  *   SYS_EXEC    sets program counter and stack pointer after EXEC
 14  *   SYS_XIT     informs kernel that a process has exited
 15  *   SYS_GETSP   caller wants to read out some process' stack pointer
 16  *   SYS_TIMES   caller wants to get accounting times for a process
 17  *   SYS_ABORT   MM or FS cannot go on; abort MINIX
 18  *   SYS_FRESH   start with a fresh process image during EXEC (68000 & SPARC only)
 19  *   SYS_SENDSIG send a signal to a process (POSIX style)
 20  *   SYS_SIGRETURN complete POSIX-style signalling
 21  *   SYS_KILL    cause a signal to be sent via MM
 22  *   SYS_ENDSIG  finish up after SYS_KILL-type signal
 23  *   SYS_COPY    request a block of data to be copied between processes
 24  *   SYS_VCOPY   request a series of data blocks to be copied between procs
 25  *   SYS_GBOOT   copies the boot parameters to a process
 26  *   SYS_MEM     returns the next free chunk of physical memory
 27  *   SYS_UMAP    compute the physical address for a given virtual address
 28  *   SYS_TRACE   request a trace operation
 29  *
 30  * Message types and parameters:
 31  *
 32  *    m_type       PROC1     PROC2      PID     MEM_PTR
 33  * ------------------------------------------------------
 34  * | SYS_FORK   | parent  |  child  |   pid   |         |
 35  * |------------+---------+---------+---------+---------|
 36  * | SYS_NEWMAP | proc nr |         |         | map ptr |
 37  * |------------+---------+---------+---------+---------|
 38  * | SYS_EXEC   | proc nr | traced  | new sp  |         |
 39  * |------------+---------+---------+---------+---------|
 40  * | SYS_XIT    | parent  | exitee  |         |         |
 41  * |------------+---------+---------+---------+---------|
 42  * | SYS_GETSP  | proc nr |         |         |         |
 43  * |------------+---------+---------+---------+---------|
 44  * | SYS_TIMES  | proc nr |         | buf ptr |         |
 45  * |------------+---------+---------+---------+---------|
 46  * | SYS_ABORT  |         |         |         |         |
 47  * |------------+---------+---------+---------+---------|
 48  * | SYS_FRESH  | proc nr | data_cl |         |         |
 49  * |------------+---------+---------+---------+---------|
 50  * | SYS_GBOOT  | proc nr |         |         | bootptr |
 51  * |------------+---------+---------+---------+---------|
 52  * | SYS_GETMAP | proc nr |         |         | map ptr |
 53  * ------------------------------------------------------
 54  *
 55  *    m_type          m1_i1     m1_i2     m1_i3       m1_p1
 56  * ----------------+---------+---------+---------+--------------
 57  * | SYS_VCOPY     |  src p  |  dst p  | vec siz | vc addr     |
 58  * |---------------+---------+---------+---------+-------------|
 59  * | SYS_SENDSIG   | proc nr |         |         | smp         |
 60  * |---------------+---------+---------+---------+-------------|
 61  * | SYS_SIGRETURN | proc nr |         |         | scp         |
 62  * |---------------+---------+---------+---------+-------------|
 63  * | SYS_ENDSIG    | proc nr |         |         |             |
 64  * -------------------------------------------------------------
 65  *
 66  *    m_type       m2_i1     m2_i2     m2_l1     m2_l2
 67  * ------------------------------------------------------
 68  * | SYS_TRACE  | proc_nr | request |  addr   |  data   |
 69  * ------------------------------------------------------
 70  *
 71  *
 72  *    m_type       m6_i1     m6_i2     m6_i3     m6_f1
 73  * ------------------------------------------------------
 74  * | SYS_KILL   | proc_nr  |  sig    |         |         |
 75  * ------------------------------------------------------
 76  *
 77  *
 78  *    m_type      m5_c1   m5_i1    m5_l1   m5_c2   m5_i2    m5_l2   m5_l3
 79  * --------------------------------------------------------------------------
 80  * | SYS_COPY   |src seg|src proc|src vir|dst seg|dst proc|dst vir| byte ct |
 81  * --------------------------------------------------------------------------
 82  * | SYS_UMAP   |  seg  |proc nr |vir adr|       |        |       | byte ct |
 83  * --------------------------------------------------------------------------
 84  *
 85  *
 86  *    m_type      m1_i1      m1_i2      m1_i3
 87  * |------------+----------+----------+----------
 88  * | SYS_MEM    | mem base | mem size | tot mem |
 89  * ----------------------------------------------
 90  *
 91  * In addition to the main sys_task() entry point, there are 5 other minor
 92  * entry points:
 93  *   cause_sig: take action to cause a signal to occur, sooner or later
 94  *   inform:    tell MM about pending signals
 95  *   numap:     umap D segment starting from process number instead of pointer
 96  *   umap:      compute the physical address for a given virtual address
 97  *   alloc_segments: allocate segments for 8088 or higher processor
 98  */
 99 
100 #include "kernel.h"
101 #include 
102 #include 
103 #include 
104 #include 
105 #include 
106 #include 
107 #include 
108 #include "proc.h"
109 #if (CHIP == INTEL)
110 #include "protect.h"
111 #endif
112 #if (MACHINE == SUN)
113 #include "logging.h"
114 #endif
115 
116 /* PSW masks. */
117 #define IF_MASK 0x00000200
118 #define IOPL_MASK 0x003000
119 
120 PRIVATE message m;
121 #if (MACHINE != SUN)
122 PRIVATE char sig_stuff[SIG_PUSH_BYTES]; /* used to send signals to processes */
123 #endif
124 
125 FORWARD _PROTOTYPE( int do_abort, (message *m_ptr) );
126 FORWARD _PROTOTYPE( int do_copy, (message *m_ptr) );
127 FORWARD _PROTOTYPE( int do_exec, (message *m_ptr) );
128 FORWARD _PROTOTYPE( int do_fork, (message *m_ptr) );
129 FORWARD _PROTOTYPE( int do_gboot, (message *m_ptr) );
130 FORWARD _PROTOTYPE( int do_getsp, (message *m_ptr) );
131 FORWARD _PROTOTYPE( int do_kill, (message *m_ptr) );
132 FORWARD _PROTOTYPE( int do_mem, (message *m_ptr) );
133 FORWARD _PROTOTYPE( int do_newmap, (message *m_ptr) );
134 FORWARD _PROTOTYPE( int do_sendsig, (message *m_ptr) );
135 FORWARD _PROTOTYPE( int do_sigreturn, (message *m_ptr) );
136 FORWARD _PROTOTYPE( int do_endsig, (message *m_ptr) );
137 FORWARD _PROTOTYPE( int do_times, (message *m_ptr) );
138 FORWARD _PROTOTYPE( int do_trace, (message *m_ptr) );
139 FORWARD _PROTOTYPE( int do_umap, (message *m_ptr) );
140 FORWARD _PROTOTYPE( int do_xit, (message *m_ptr) );
141 FORWARD _PROTOTYPE( int do_vcopy, (message *m_ptr) );
142 FORWARD _PROTOTYPE( int do_getmap, (message *m_ptr) );
143 
144 #if (SHADOWING == 1)
145 FORWARD _PROTOTYPE( int do_fresh, (message *m_ptr) );
146 #endif
147 
148