// Copyright 2022 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package procfs

import (
	
	
	
	
	
	

	
)

// ProcNetstat models the content of /proc/<pid>/net/netstat.
type ProcNetstat struct {
	// The process ID.
	PID int
	TcpExt
	IpExt
}

type TcpExt struct { // nolint:revive
	SyncookiesSent            *float64
	SyncookiesRecv            *float64
	SyncookiesFailed          *float64
	EmbryonicRsts             *float64
	PruneCalled               *float64
	RcvPruned                 *float64
	OfoPruned                 *float64
	OutOfWindowIcmps          *float64
	LockDroppedIcmps          *float64
	ArpFilter                 *float64
	TW                        *float64
	TWRecycled                *float64
	TWKilled                  *float64
	PAWSActive                *float64
	PAWSEstab                 *float64
	DelayedACKs               *float64
	DelayedACKLocked          *float64
	DelayedACKLost            *float64
	ListenOverflows           *float64
	ListenDrops               *float64
	TCPHPHits                 *float64
	TCPPureAcks               *float64
	TCPHPAcks                 *float64
	TCPRenoRecovery           *float64
	TCPSackRecovery           *float64
	TCPSACKReneging           *float64
	TCPSACKReorder            *float64
	TCPRenoReorder            *float64
	TCPTSReorder              *float64
	TCPFullUndo               *float64
	TCPPartialUndo            *float64
	TCPDSACKUndo              *float64
	TCPLossUndo               *float64
	TCPLostRetransmit         *float64
	TCPRenoFailures           *float64
	TCPSackFailures           *float64
	TCPLossFailures           *float64
	TCPFastRetrans            *float64
	TCPSlowStartRetrans       *float64
	TCPTimeouts               *float64
	TCPLossProbes             *float64
	TCPLossProbeRecovery      *float64
	TCPRenoRecoveryFail       *float64
	TCPSackRecoveryFail       *float64
	TCPRcvCollapsed           *float64
	TCPDSACKOldSent           *float64
	TCPDSACKOfoSent           *float64
	TCPDSACKRecv              *float64
	TCPDSACKOfoRecv           *float64
	TCPAbortOnData            *float64
	TCPAbortOnClose           *float64
	TCPAbortOnMemory          *float64
	TCPAbortOnTimeout         *float64
	TCPAbortOnLinger          *float64
	TCPAbortFailed            *float64
	TCPMemoryPressures        *float64
	TCPMemoryPressuresChrono  *float64
	TCPSACKDiscard            *float64
	TCPDSACKIgnoredOld        *float64
	TCPDSACKIgnoredNoUndo     *float64
	TCPSpuriousRTOs           *float64
	TCPMD5NotFound            *float64
	TCPMD5Unexpected          *float64
	TCPMD5Failure             *float64
	TCPSackShifted            *float64
	TCPSackMerged             *float64
	TCPSackShiftFallback      *float64
	TCPBacklogDrop            *float64
	PFMemallocDrop            *float64
	TCPMinTTLDrop             *float64
	TCPDeferAcceptDrop        *float64
	IPReversePathFilter       *float64
	TCPTimeWaitOverflow       *float64
	TCPReqQFullDoCookies      *float64
	TCPReqQFullDrop           *float64
	TCPRetransFail            *float64
	TCPRcvCoalesce            *float64
	TCPRcvQDrop               *float64
	TCPOFOQueue               *float64
	TCPOFODrop                *float64
	TCPOFOMerge               *float64
	TCPChallengeACK           *float64
	TCPSYNChallenge           *float64
	TCPFastOpenActive         *float64
	TCPFastOpenActiveFail     *float64
	TCPFastOpenPassive        *float64
	TCPFastOpenPassiveFail    *float64
	TCPFastOpenListenOverflow *float64
	TCPFastOpenCookieReqd     *float64
	TCPFastOpenBlackhole      *float64
	TCPSpuriousRtxHostQueues  *float64
	BusyPollRxPackets         *float64
	TCPAutoCorking            *float64
	TCPFromZeroWindowAdv      *float64
	TCPToZeroWindowAdv        *float64
	TCPWantZeroWindowAdv      *float64
	TCPSynRetrans             *float64
	TCPOrigDataSent           *float64
	TCPHystartTrainDetect     *float64
	TCPHystartTrainCwnd       *float64
	TCPHystartDelayDetect     *float64
	TCPHystartDelayCwnd       *float64
	TCPACKSkippedSynRecv      *float64
	TCPACKSkippedPAWS         *float64
	TCPACKSkippedSeq          *float64
	TCPACKSkippedFinWait2     *float64
	TCPACKSkippedTimeWait     *float64
	TCPACKSkippedChallenge    *float64
	TCPWinProbe               *float64
	TCPKeepAlive              *float64
	TCPMTUPFail               *float64
	TCPMTUPSuccess            *float64
	TCPWqueueTooBig           *float64
}

type IpExt struct { // nolint:revive
	InNoRoutes      *float64
	InTruncatedPkts *float64
	InMcastPkts     *float64
	OutMcastPkts    *float64
	InBcastPkts     *float64
	OutBcastPkts    *float64
	InOctets        *float64
	OutOctets       *float64
	InMcastOctets   *float64
	OutMcastOctets  *float64
	InBcastOctets   *float64
	OutBcastOctets  *float64
	InCsumErrors    *float64
	InNoECTPkts     *float64
	InECT1Pkts      *float64
	InECT0Pkts      *float64
	InCEPkts        *float64
	ReasmOverlaps   *float64
}

func ( Proc) () (ProcNetstat, error) {
	 := .path("net/netstat")
	,  := util.ReadFileNoStat()
	if  != nil {
		return ProcNetstat{PID: .PID}, 
	}
	,  := parseProcNetstat(bytes.NewReader(), )
	.PID = .PID
	return , 
}

// parseProcNetstat parses the metrics from proc/<pid>/net/netstat file
// and returns a ProcNetstat structure.
func parseProcNetstat( io.Reader,  string) (ProcNetstat, error) {
	var (
		     = bufio.NewScanner()
		 = ProcNetstat{}
	)

	for .Scan() {
		 := strings.Split(.Text(), " ")
		.Scan()
		 := strings.Split(.Text(), " ")
		// Remove trailing :.
		 := strings.TrimSuffix([0], ":")
		if len() != len() {
			return , fmt.Errorf("%w: mismatch field count mismatch in %s: %s",
				ErrFileParse, , )
		}
		for  := 1;  < len(); ++ {
			,  := strconv.ParseFloat([], 64)
			if  != nil {
				return , 
			}
			 := []

			switch  {
			case "TcpExt":
				switch  {
				case "SyncookiesSent":
					.SyncookiesSent = &
				case "SyncookiesRecv":
					.SyncookiesRecv = &
				case "SyncookiesFailed":
					.SyncookiesFailed = &
				case "EmbryonicRsts":
					.EmbryonicRsts = &
				case "PruneCalled":
					.PruneCalled = &
				case "RcvPruned":
					.RcvPruned = &
				case "OfoPruned":
					.OfoPruned = &
				case "OutOfWindowIcmps":
					.OutOfWindowIcmps = &
				case "LockDroppedIcmps":
					.LockDroppedIcmps = &
				case "ArpFilter":
					.ArpFilter = &
				case "TW":
					.TW = &
				case "TWRecycled":
					.TWRecycled = &
				case "TWKilled":
					.TWKilled = &
				case "PAWSActive":
					.PAWSActive = &
				case "PAWSEstab":
					.PAWSEstab = &
				case "DelayedACKs":
					.DelayedACKs = &
				case "DelayedACKLocked":
					.DelayedACKLocked = &
				case "DelayedACKLost":
					.DelayedACKLost = &
				case "ListenOverflows":
					.ListenOverflows = &
				case "ListenDrops":
					.ListenDrops = &
				case "TCPHPHits":
					.TCPHPHits = &
				case "TCPPureAcks":
					.TCPPureAcks = &
				case "TCPHPAcks":
					.TCPHPAcks = &
				case "TCPRenoRecovery":
					.TCPRenoRecovery = &
				case "TCPSackRecovery":
					.TCPSackRecovery = &
				case "TCPSACKReneging":
					.TCPSACKReneging = &
				case "TCPSACKReorder":
					.TCPSACKReorder = &
				case "TCPRenoReorder":
					.TCPRenoReorder = &
				case "TCPTSReorder":
					.TCPTSReorder = &
				case "TCPFullUndo":
					.TCPFullUndo = &
				case "TCPPartialUndo":
					.TCPPartialUndo = &
				case "TCPDSACKUndo":
					.TCPDSACKUndo = &
				case "TCPLossUndo":
					.TCPLossUndo = &
				case "TCPLostRetransmit":
					.TCPLostRetransmit = &
				case "TCPRenoFailures":
					.TCPRenoFailures = &
				case "TCPSackFailures":
					.TCPSackFailures = &
				case "TCPLossFailures":
					.TCPLossFailures = &
				case "TCPFastRetrans":
					.TCPFastRetrans = &
				case "TCPSlowStartRetrans":
					.TCPSlowStartRetrans = &
				case "TCPTimeouts":
					.TCPTimeouts = &
				case "TCPLossProbes":
					.TCPLossProbes = &
				case "TCPLossProbeRecovery":
					.TCPLossProbeRecovery = &
				case "TCPRenoRecoveryFail":
					.TCPRenoRecoveryFail = &
				case "TCPSackRecoveryFail":
					.TCPSackRecoveryFail = &
				case "TCPRcvCollapsed":
					.TCPRcvCollapsed = &
				case "TCPDSACKOldSent":
					.TCPDSACKOldSent = &
				case "TCPDSACKOfoSent":
					.TCPDSACKOfoSent = &
				case "TCPDSACKRecv":
					.TCPDSACKRecv = &
				case "TCPDSACKOfoRecv":
					.TCPDSACKOfoRecv = &
				case "TCPAbortOnData":
					.TCPAbortOnData = &
				case "TCPAbortOnClose":
					.TCPAbortOnClose = &
				case "TCPDeferAcceptDrop":
					.TCPDeferAcceptDrop = &
				case "IPReversePathFilter":
					.IPReversePathFilter = &
				case "TCPTimeWaitOverflow":
					.TCPTimeWaitOverflow = &
				case "TCPReqQFullDoCookies":
					.TCPReqQFullDoCookies = &
				case "TCPReqQFullDrop":
					.TCPReqQFullDrop = &
				case "TCPRetransFail":
					.TCPRetransFail = &
				case "TCPRcvCoalesce":
					.TCPRcvCoalesce = &
				case "TCPRcvQDrop":
					.TCPRcvQDrop = &
				case "TCPOFOQueue":
					.TCPOFOQueue = &
				case "TCPOFODrop":
					.TCPOFODrop = &
				case "TCPOFOMerge":
					.TCPOFOMerge = &
				case "TCPChallengeACK":
					.TCPChallengeACK = &
				case "TCPSYNChallenge":
					.TCPSYNChallenge = &
				case "TCPFastOpenActive":
					.TCPFastOpenActive = &
				case "TCPFastOpenActiveFail":
					.TCPFastOpenActiveFail = &
				case "TCPFastOpenPassive":
					.TCPFastOpenPassive = &
				case "TCPFastOpenPassiveFail":
					.TCPFastOpenPassiveFail = &
				case "TCPFastOpenListenOverflow":
					.TCPFastOpenListenOverflow = &
				case "TCPFastOpenCookieReqd":
					.TCPFastOpenCookieReqd = &
				case "TCPFastOpenBlackhole":
					.TCPFastOpenBlackhole = &
				case "TCPSpuriousRtxHostQueues":
					.TCPSpuriousRtxHostQueues = &
				case "BusyPollRxPackets":
					.BusyPollRxPackets = &
				case "TCPAutoCorking":
					.TCPAutoCorking = &
				case "TCPFromZeroWindowAdv":
					.TCPFromZeroWindowAdv = &
				case "TCPToZeroWindowAdv":
					.TCPToZeroWindowAdv = &
				case "TCPWantZeroWindowAdv":
					.TCPWantZeroWindowAdv = &
				case "TCPSynRetrans":
					.TCPSynRetrans = &
				case "TCPOrigDataSent":
					.TCPOrigDataSent = &
				case "TCPHystartTrainDetect":
					.TCPHystartTrainDetect = &
				case "TCPHystartTrainCwnd":
					.TCPHystartTrainCwnd = &
				case "TCPHystartDelayDetect":
					.TCPHystartDelayDetect = &
				case "TCPHystartDelayCwnd":
					.TCPHystartDelayCwnd = &
				case "TCPACKSkippedSynRecv":
					.TCPACKSkippedSynRecv = &
				case "TCPACKSkippedPAWS":
					.TCPACKSkippedPAWS = &
				case "TCPACKSkippedSeq":
					.TCPACKSkippedSeq = &
				case "TCPACKSkippedFinWait2":
					.TCPACKSkippedFinWait2 = &
				case "TCPACKSkippedTimeWait":
					.TCPACKSkippedTimeWait = &
				case "TCPACKSkippedChallenge":
					.TCPACKSkippedChallenge = &
				case "TCPWinProbe":
					.TCPWinProbe = &
				case "TCPKeepAlive":
					.TCPKeepAlive = &
				case "TCPMTUPFail":
					.TCPMTUPFail = &
				case "TCPMTUPSuccess":
					.TCPMTUPSuccess = &
				case "TCPWqueueTooBig":
					.TCPWqueueTooBig = &
				}
			case "IpExt":
				switch  {
				case "InNoRoutes":
					.InNoRoutes = &
				case "InTruncatedPkts":
					.InTruncatedPkts = &
				case "InMcastPkts":
					.InMcastPkts = &
				case "OutMcastPkts":
					.OutMcastPkts = &
				case "InBcastPkts":
					.InBcastPkts = &
				case "OutBcastPkts":
					.OutBcastPkts = &
				case "InOctets":
					.InOctets = &
				case "OutOctets":
					.OutOctets = &
				case "InMcastOctets":
					.InMcastOctets = &
				case "OutMcastOctets":
					.OutMcastOctets = &
				case "InBcastOctets":
					.InBcastOctets = &
				case "OutBcastOctets":
					.OutBcastOctets = &
				case "InCsumErrors":
					.InCsumErrors = &
				case "InNoECTPkts":
					.InNoECTPkts = &
				case "InECT1Pkts":
					.InECT1Pkts = &
				case "InECT0Pkts":
					.InECT0Pkts = &
				case "InCEPkts":
					.InCEPkts = &
				case "ReasmOverlaps":
					.ReasmOverlaps = &
				}
			}
		}
	}
	return , .Err()
}