I Like It !
Monday, September 26, 2016
Sunday, September 18, 2016
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
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 #include42 #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 #include102 #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
Subscribe to:
Posts (Atom)