Corporate Network Detection: Identifying Business vs Residential Traffic

Learn techniques for distinguishing corporate network traffic from residential users for better targeting and security.

Corporate Network Detection: Identifying Business vs Residential Traffic
August 11, 2025
36 min read
IP Geolocation

Corporate Network Detection: Identifying Business vs Residential Traffic


Distinguishing corporate from residential traffic enables better targeting, pricing, and security decisions. Detection requires analyzing network characteristics, usage patterns, and infrastructure indicators.


Corporate Network Detection Overview

Corporate Network Detection Overview


Geolocation Technology Overview


Corporate Network Detection requires careful consideration of multiple factors that impact implementation success and user experience.


Key Considerations


Technical Requirements

  • Scalable architecture design
  • Performance optimization strategies
  • Error handling and recovery
  • Security and compliance measures

Business Impact

  • User experience enhancement
  • Operational efficiency gains
  • Cost optimization opportunities
  • Risk mitigation strategies

Data Sources and Accuracy Factors


Successful implementation requires understanding the technical landscape and choosing appropriate strategies.


Implementation Approaches


Modern Solutions

  • Cloud-native architectures
  • Microservices integration
  • Real-time processing capabilities
  • Automated scaling mechanisms

Corporate Network Detection Architecture

Corporate Network Detection Architecture


Business Impact

  • User experience enhancement
  • Operational efficiency gains
  • Cost optimization opportunities
  • Risk mitigation strategies

Practical Implementation Examples


Network Analysis Engine for Corporate Detection


// Production-ready network analysis system for corporate vs residential classification
interface NetworkAnalysisResult {
  ip: string
  classification: 'corporate' | 'residential' | 'hosting' | 'mobile' | 'vpn' | 'unknown'
  confidence: number // 0-100
  indicators: {
    autonomousSystem: {
      asn: number
      organization: string
      type: 'isp' | 'corporate' | 'hosting' | 'education' | 'government'
    }
    ipRange: {
      range: string
      type: 'corporate' | 'residential' | 'hosting' | 'unknown'
      source: string
    }
    reverseDNS: {
      hostname: string
      corporateIndicators: string[]
    }
    connectionPattern: {
      requestVolume: number
      timeDistribution: 'business_hours' | 'evening' | 'weekend' | 'continuous'
      sessionDuration: number
      endpointDiversity: number
    }
  }
  corporateProbability: number
  residentialProbability: number
  metadata: {
    analysisTimestamp: number
    dataSources: string[]
    processingTime: number
  }
}

interface CorporateIndicators {
  asnKeywords: string[]
  hostnamePatterns: RegExp[]
  ipRangeSources: string[]
  behavioralPatterns: {
    businessHoursActivity: number
    weekendActivity: number
    sessionConsistency: number
  }
}

class CorporateNetworkAnalyzer {
  private corporateIndicators: CorporateIndicators
  private analysisCache: Map<string, NetworkAnalysisResult> = new Map()
  private asnDatabase: Map<number, any> = new Map()
  private ipRangeDatabase: Map<string, any> = new Map()

  constructor() {
    this.initializeCorporateIndicators()
    this.loadNetworkDatabases()
  }

  async analyzeNetwork(ip: string): Promise<NetworkAnalysisResult> {
    const startTime = Date.now()

    // Check cache first
    const cached = this.analysisCache.get(ip)
    if (cached && Date.now() - cached.metadata.analysisTimestamp < 24 * 60 * 60 * 1000) {
      return cached
    }

    try {
      // Perform comprehensive network analysis
      const [asnInfo, ipRangeInfo, reverseDNSInfo, connectionPattern] = await Promise.all([
        this.analyzeAutonomousSystem(ip),
        this.analyzeIPRange(ip),
        this.analyzeReverseDNS(ip),
        this.analyzeConnectionPattern(ip)
      ])

      // Calculate probabilities
      const corporateProbability = this.calculateCorporateProbability({
        asnInfo,
        ipRangeInfo,
        reverseDNSInfo,
        connectionPattern
      })

      const residentialProbability = 1 - corporateProbability

      // Determine final classification
      const classification = this.determineClassification(corporateProbability, {
        asnInfo,
        ipRangeInfo,
        reverseDNSInfo,
        connectionPattern
      })

      const result: NetworkAnalysisResult = {
        ip,
        classification,
        confidence: Math.max(corporateProbability, residentialProbability) * 100,
        indicators: {
          autonomousSystem: asnInfo,
          ipRange: ipRangeInfo,
          reverseDNS: reverseDNSInfo,
          connectionPattern
        },
        corporateProbability,
        residentialProbability,
        metadata: {
          analysisTimestamp: Date.now(),
          dataSources: ['ASN', 'IP Ranges', 'Reverse DNS', 'Connection Patterns'],
          processingTime: Date.now() - startTime
        }
      }

      // Cache result
      this.analysisCache.set(ip, result)

      return result

    } catch (error) {
      console.error(`Network analysis failed for IP ${ip}:`, error)

      // Return default classification
      return {
        ip,
        classification: 'unknown',
        confidence: 0,
        indicators: {
          autonomousSystem: { asn: 0, organization: 'Unknown', type: 'isp' },
          ipRange: { range: 'Unknown', type: 'unknown', source: 'Error' },
          reverseDNS: { hostname: 'Unknown', corporateIndicators: [] },
          connectionPattern: {
            requestVolume: 0,
            timeDistribution: 'unknown',
            sessionDuration: 0,
            endpointDiversity: 0
          }
        },
        corporateProbability: 0.5,
        residentialProbability: 0.5,
        metadata: {
          analysisTimestamp: Date.now(),
          dataSources: [],
          processingTime: Date.now() - startTime
        }
      }
    }
  }

  private async analyzeAutonomousSystem(ip: string): Promise<NetworkAnalysisResult['indicators']['autonomousSystem']> {
    // In production, query WHOIS or BGP data
    // For demo, simulate ASN analysis

    const mockASNData: Record<string, any> = {
      '8.8.8.8': { asn: 15169, organization: 'Google LLC', type: 'hosting' },
      '1.1.1.1': { asn: 13335, organization: 'Cloudflare Inc', type: 'hosting' },
      '208.67.222.222': { asn: 36692, organization: 'OpenDNS LLC', type: 'corporate' }
    }

    const defaultASN = { asn: 0, organization: 'Unknown ISP', type: 'isp' as const }

    // Check if IP matches any known corporate ASN patterns
    for (const [ipPattern, asnData] of Object.entries(mockASNData)) {
      if (ip.includes(ipPattern.split('.')[0])) {
        return asnData
      }
    }

    return defaultASN
  }

  private async analyzeIPRange(ip: string): Promise<NetworkAnalysisResult['indicators']['ipRange']> {
    // In production, query IP range databases (ARIN, RIPE, etc.)
    // For demo, simulate IP range analysis

    const corporateRanges = [
      { range: '10.0.0.0/8', type: 'corporate', source: 'RFC1918' },
      { range: '172.16.0.0/12', type: 'corporate', source: 'RFC1918' },
      { range: '192.168.0.0/16', type: 'corporate', source: 'RFC1918' }
    ]

    for (const rangeInfo of corporateRanges) {
      if (this.isIPInRange(ip, rangeInfo.range)) {
        return rangeInfo
      }
    }

    return { range: 'Unknown', type: 'unknown', source: 'Not found' }
  }

  private isIPInRange(ip: string, cidr: string): boolean {
    // Simplified CIDR matching for demo
    // In production, use proper IP range calculation

    if (cidr === '10.0.0.0/8' && ip.startsWith('10.')) return true
    if (cidr === '172.16.0.0/12' && ip.startsWith('172.')) return true
    if (cidr === '192.168.0.0/16' && ip.startsWith('192.168.')) return true

    return false
  }

  private async analyzeReverseDNS(ip: string): Promise<NetworkAnalysisResult['indicators']['reverseDNS']> {
    // In production, perform reverse DNS lookup
    // For demo, simulate reverse DNS analysis

    const mockReverseDNS: Record<string, any> = {
      '8.8.8.8': { hostname: 'google-public-dns-a.google.com', corporateIndicators: ['google', 'dns'] },
      '1.1.1.1': { hostname: 'one.one.one.one', corporateIndicators: ['cloudflare'] },
      '208.67.222.222': { hostname: 'resolver1.opendns.com', corporateIndicators: ['opendns', 'resolver'] }
    }

    const defaultResult = { hostname: 'Unknown', corporateIndicators: [] }

    for (const [ipPattern, dnsData] of Object.entries(mockReverseDNS)) {
      if (ip.includes(ipPattern.split('.')[0])) {
        return dnsData
      }
    }

    return defaultResult
  }

  private async analyzeConnectionPattern(ip: string): Promise<NetworkAnalysisResult['indicators']['connectionPattern']> {
    // In production, analyze historical connection data
    // For demo, simulate connection pattern analysis

    const patterns = {
      '8.8.8.8': {
        requestVolume: 1000,
        timeDistribution: 'continuous' as const,
        sessionDuration: 300,
        endpointDiversity: 0.8
      },
      '1.1.1.1': {
        requestVolume: 800,
        timeDistribution: 'continuous' as const,
        sessionDuration: 250,
        endpointDiversity: 0.7
      }
    }

    const defaultPattern = {
      requestVolume: 100,
      timeDistribution: 'business_hours' as const,
      sessionDuration: 1800,
      endpointDiversity: 0.3
    }

    for (const [ipPattern, pattern] of Object.entries(patterns)) {
      if (ip.includes(ipPattern.split('.')[0])) {
        return pattern
      }
    }

    return defaultPattern
  }

  private calculateCorporateProbability(indicators: any): number {
    let score = 0.5 // Base probability

    // ASN analysis
    if (indicators.asnInfo.type === 'corporate') score += 0.3
    if (indicators.asnInfo.type === 'hosting') score += 0.1
    if (indicators.asnInfo.type === 'education' || indicators.asnInfo.type === 'government') score += 0.2

    // IP range analysis
    if (indicators.ipRangeInfo.type === 'corporate') score += 0.4
    if (indicators.ipRangeInfo.source === 'RFC1918') score += 0.2

    // Reverse DNS analysis
    const corporateKeywords = ['corp', 'company', 'enterprise', 'business', 'office']
    const hostnameIndicators = indicators.reverseDNSInfo.corporateIndicators || []
    const hostnameMatches = hostnameIndicators.filter((indicator: string) =>
      corporateKeywords.some(keyword => indicator.toLowerCase().includes(keyword))
    ).length

    if (hostnameMatches > 0) score += 0.2

    // Connection pattern analysis
    if (indicators.connectionPattern.timeDistribution === 'business_hours') score += 0.1
    if (indicators.connectionPattern.endpointDiversity > 0.5) score += 0.1
    if (indicators.connectionPattern.sessionDuration > 3600) score += 0.1

    return Math.min(1, Math.max(0, score))
  }

  private determineClassification(
    corporateProbability: number,
    indicators: any
  ): NetworkAnalysisResult['classification'] {
    if (corporateProbability > 0.8) return 'corporate'
    if (corporateProbability < 0.3) return 'residential'

    // Use indicators for tie-breaking
    if (indicators.asnInfo.type === 'hosting') return 'hosting'
    if (indicators.ipRangeInfo.type === 'corporate') return 'corporate'
    if (indicators.connectionPattern.requestVolume > 500) return 'corporate'

    return 'unknown'
  }

  private initializeCorporateIndicators(): void {
    this.corporateIndicators = {
      asnKeywords: ['corp', 'company', 'enterprise', 'business', 'office', 'inc', 'ltd', 'llc'],
      hostnamePatterns: [
        /^.*corp./i,
        /^.*company./i,
        /^.*enterprise./i,
        /^.*business./i,
        /^.*office./i
      ],
      ipRangeSources: ['ARIN', 'RIPE', 'APNIC', 'RFC1918'],
      behavioralPatterns: {
        businessHoursActivity: 0.8,
        weekendActivity: 0.2,
        sessionConsistency: 0.7
      }
    }
  }

  private loadNetworkDatabases(): void {
    // In production, load ASN and IP range databases
    // For demo, populate with sample data

    console.log('Network databases loaded')
  }
}

// Corporate vs Residential Classification Service
class CorporateResidentialClassifier {
  private networkAnalyzer: CorporateNetworkAnalyzer
  private classificationCache: Map<string, {
    result: NetworkAnalysisResult
    expires: number
  }> = new Map()

  constructor() {
    this.networkAnalyzer = new CorporateNetworkAnalyzer()
  }

  async classifyIP(ip: string): Promise<{
    isCorporate: boolean
    confidence: number
    analysis: NetworkAnalysisResult
    recommendation: string
  }> {
    // Check cache first
    const cached = this.getCachedClassification(ip)
    if (cached) {
      return {
        isCorporate: cached.result.classification === 'corporate',
        confidence: cached.result.confidence,
        analysis: cached.result,
        recommendation: this.generateRecommendation(cached.result)
      }
    }

    // Perform fresh analysis
    const analysis = await this.networkAnalyzer.analyzeNetwork(ip)

    // Cache result for 24 hours
    this.cacheClassification(ip, analysis)

    return {
      isCorporate: analysis.classification === 'corporate',
      confidence: analysis.confidence,
      analysis,
      recommendation: this.generateRecommendation(analysis)
    }
  }

  private getCachedClassification(ip: string): NetworkAnalysisResult | null {
    const cached = this.classificationCache.get(ip)
    if (cached && cached.expires > Date.now()) {
      return cached.result
    }

    if (cached) {
      this.classificationCache.delete(ip)
    }

    return null
  }

  private cacheClassification(ip: string, result: NetworkAnalysisResult): void {
    this.classificationCache.set(ip, {
      result,
      expires: Date.now() + 24 * 60 * 60 * 1000 // 24 hours
    })
  }

  private generateRecommendation(analysis: NetworkAnalysisResult): string {
    if (analysis.classification === 'corporate' && analysis.confidence > 80) {
      return 'High confidence corporate network - suitable for B2B targeting'
    }

    if (analysis.classification === 'residential' && analysis.confidence > 80) {
      return 'High confidence residential network - suitable for B2C targeting'
    }

    if (analysis.confidence < 60) {
      return 'Low confidence classification - manual review recommended'
    }

    return 'Medium confidence classification - verify with additional data sources'
  }

  // Batch classification for multiple IPs
  async classifyIPBatch(ips: string[]): Promise<Map<string, NetworkAnalysisResult>> {
    const results = new Map<string, NetworkAnalysisResult>()

    // Process in parallel with rate limiting
    const batchSize = 20
    for (let i = 0; i < ips.length; i += batchSize) {
      const batch = ips.slice(i, i + batchSize)

      const batchPromises = batch.map(async (ip) => {
        try {
          const result = await this.networkAnalyzer.analyzeNetwork(ip)
          return { ip, result }
        } catch (error) {
          console.error(`Batch classification failed for IP ${ip}:`, error)
          return { ip, result: null }
        }
      })

      const batchResults = await Promise.all(batchPromises)

      batchResults.forEach(({ ip, result }) => {
        if (result) {
          results.set(ip, result)
        }
      })

      // Small delay between batches to avoid overwhelming
      if (i + batchSize < ips.length) {
        await new Promise(resolve => setTimeout(resolve, 100))
      }
    }

    return results
  }

  getClassificationStats(): {
    totalAnalyses: number
    corporatePercentage: number
    residentialPercentage: number
    unknownPercentage: number
    averageConfidence: number
  } {
    const analyses = Array.from(this.classificationCache.values()).map(c => c.result)
    const total = analyses.length

    if (total === 0) {
      return {
        totalAnalyses: 0,
        corporatePercentage: 0,
        residentialPercentage: 0,
        unknownPercentage: 0,
        averageConfidence: 0
      }
    }

    const corporate = analyses.filter(a => a.classification === 'corporate').length
    const residential = analyses.filter(a => a.classification === 'residential').length
    const unknown = analyses.filter(a => a.classification === 'unknown').length
    const averageConfidence = analyses.reduce((sum, a) => sum + a.confidence, 0) / total

    return {
      totalAnalyses: total,
      corporatePercentage: (corporate / total) * 100,
      residentialPercentage: (residential / total) * 100,
      unknownPercentage: (unknown / total) * 100,
      averageConfidence
    }
  }
}

// Initialize classification service
const networkAnalyzer = new CorporateNetworkAnalyzer()
const corporateClassifier = new CorporateResidentialClassifier()

// Corporate network detection endpoint
app.post('/api/detect-corporate-network', async (req, res) => {
  try {
    const { ip } = req.body

    if (!ip) {
      return res.status(400).json({ error: 'IP address required' })
    }

    const classification = await corporateClassifier.classifyIP(ip)

    res.json({
      classification,
      timestamp: new Date().toISOString()
    })

  } catch (error) {
    console.error('Corporate network detection error:', error)
    res.status(500).json({ error: 'Detection failed' })
  }
})

// Batch corporate network detection
app.post('/api/detect-corporate-networks-batch', async (req, res) => {
  try {
    const { ips } = req.body

    if (!Array.isArray(ips)) {
      return res.status(400).json({ error: 'IPs array required' })
    }

    const results = await corporateClassifier.classifyIPBatch(ips)

    res.json({
      results: Object.fromEntries(results.entries()),
      count: results.size,
      timestamp: new Date().toISOString()
    })

  } catch (error) {
    console.error('Batch corporate network detection error:', error)
    res.status(500).json({ error: 'Batch detection failed' })
  }
})

// Corporate network statistics
app.get('/api/corporate-network-stats', (req, res) => {
  const stats = corporateClassifier.getClassificationStats()

  res.json({
    stats,
    timestamp: new Date().toISOString()
  })
})

console.log('Corporate network detection system initialized')

Machine Learning Classification Engine


// Advanced ML-based corporate network classification
interface NetworkFeatures {
  ip: string
  asnInfo: {
    asn: number
    organization: string
    type: string
  }
  ipRange: {
    range: string
    type: string
    source: string
  }
  reverseDNS: {
    hostname: string
    hasCorporateKeywords: boolean
  }
  connectionPattern: {
    requestVolume: number
    timeDistribution: string
    sessionDuration: number
    endpointDiversity: number
    businessHoursRatio: number
    weekendRatio: number
  }
  historicalData: {
    classificationHistory: Array<{ classification: string; confidence: number; timestamp: number }>
    behaviorStability: number
  }
}

interface MLClassificationResult {
  ip: string
  predictedClass: 'corporate' | 'residential' | 'hosting' | 'mobile' | 'vpn' | 'unknown'
  confidence: number
  probabilities: Record<string, number>
  featureImportance: Record<string, number>
  modelVersion: string
  processingTime: number
}

class MLCorporateClassifier {
  private model: any = null
  private featureExtractor: NetworkFeatureExtractor
  private modelVersion: string = '1.0.0'
  private predictionCache: Map<string, MLClassificationResult> = new Map()

  constructor() {
    this.featureExtractor = new NetworkFeatureExtractor()
    this.initializeModel()
  }

  async classifyWithML(ip: string, features: NetworkFeatures): Promise<MLClassificationResult> {
    const startTime = Date.now()

    // Check cache first
    const cacheKey = this.generateCacheKey(ip, features)
    const cached = this.getCachedPrediction(cacheKey)
    if (cached) {
      return { ...cached, processingTime: Date.now() - startTime }
    }

    try {
      // Extract numerical features for ML model
      const numericalFeatures = await this.featureExtractor.extractNumericalFeatures(features)

      // Run ML prediction
      const prediction = await this.runModelPrediction(numericalFeatures)

      // Calculate feature importance
      const featureImportance = this.calculateFeatureImportance(numericalFeatures)

      const result: MLClassificationResult = {
        ip,
        predictedClass: prediction.class,
        confidence: prediction.confidence,
        probabilities: prediction.probabilities,
        featureImportance,
        modelVersion: this.modelVersion,
        processingTime: Date.now() - startTime
      }

      // Cache prediction for 12 hours
      this.cachePrediction(cacheKey, result)

      return result

    } catch (error) {
      console.error('ML classification failed:', error)

      // Fallback to rule-based classification
      return this.fallbackClassification(ip, features, Date.now() - startTime)
    }
  }

  private async initializeModel(): Promise<void> {
    // In production, load pre-trained TensorFlow.js model
    // For demo, simulate model initialization

    console.log('Initializing ML corporate classification model...')

    await new Promise(resolve => setTimeout(resolve, 1000))

    this.model = {
      predict: async (features: number[]) => {
        // Simplified prediction logic for demo
        const classProbabilities = this.calculateClassProbabilities(features)

        const maxProb = Math.max(...Object.values(classProbabilities))
        const predictedClass = Object.keys(classProbabilities).find(
          key => classProbabilities[key] === maxProb
        ) as any

        return {
          class: predictedClass,
          confidence: maxProb,
          probabilities: classProbabilities
        }
      }
    }

    console.log('ML model initialized successfully')
  }

  private calculateClassProbabilities(features: number[]): Record<string, number> {
    // Simplified probability calculation for demo
    const probabilities: Record<string, number> = {
      corporate: 0.2,
      residential: 0.2,
      hosting: 0.2,
      mobile: 0.2,
      vpn: 0.1,
      unknown: 0.1
    }

    // Adjust probabilities based on features
    if (features[0] > 0.7) probabilities.corporate += 0.3 // High ASN corporate score
    if (features[1] > 0.8) probabilities.residential += 0.3 // High residential indicators
    if (features[2] > 0.6) probabilities.hosting += 0.2 // High hosting indicators

    // Normalize probabilities
    const total = Object.values(probabilities).reduce((a, b) => a + b, 0)
    for (const key in probabilities) {
      probabilities[key] /= total
    }

    return probabilities
  }

  private calculateFeatureImportance(features: number[]): Record<string, number> {
    // Simplified feature importance calculation
    return {
      asn_corporate_score: features[0] * 0.3,
      residential_indicators: features[1] * 0.25,
      hosting_indicators: features[2] * 0.2,
      connection_patterns: features[3] * 0.15,
      historical_stability: features[4] * 0.1
    }
  }

  private fallbackClassification(
    ip: string,
    features: NetworkFeatures,
    processingTime: number
  ): MLClassificationResult {
    // Rule-based fallback classification
    let predictedClass: MLClassificationResult['predictedClass'] = 'unknown'
    let confidence = 50

    // Simple rule-based logic
    if (features.ipRange.type === 'corporate') {
      predictedClass = 'corporate'
      confidence = 80
    } else if (features.connectionPattern.businessHoursRatio > 0.7) {
      predictedClass = 'corporate'
      confidence = 70
    } else if (features.connectionPattern.endpointDiversity < 0.3) {
      predictedClass = 'residential'
      confidence = 65
    }

    return {
      ip,
      predictedClass,
      confidence,
      probabilities: {
        corporate: predictedClass === 'corporate' ? confidence / 100 : 0.2,
        residential: predictedClass === 'residential' ? confidence / 100 : 0.2,
        hosting: 0.2,
        mobile: 0.1,
        vpn: 0.1,
        unknown: predictedClass === 'unknown' ? 0.8 : 0.1
      },
      featureImportance: {},
      modelVersion: 'fallback-1.0',
      processingTime
    }
  }

  private generateCacheKey(ip: string, features: NetworkFeatures): string {
    const keyData = `${ip}-${features.asnInfo.asn}-${features.ipRange.type}-${features.connectionPattern.requestVolume}`
    return Buffer.from(keyData).toString('base64').slice(0, 32)
  }

  private getCachedPrediction(key: string): MLClassificationResult | null {
    const cached = this.predictionCache.get(key)
    if (cached && Date.now() - 12 * 60 * 60 * 1000 < cached.processingTime) { // 12 hours cache
      return cached
    }

    if (cached) {
      this.predictionCache.delete(key)
    }

    return null
  }

  private cachePrediction(key: string, result: MLClassificationResult): void {
    this.predictionCache.set(key, result)

    // Maintain cache size (keep only 10000 entries)
    if (this.predictionCache.size > 10000) {
      const entries = Array.from(this.predictionCache.entries())
      const oldestKey = entries.sort(([, a], [, b]) => a.processingTime - b.processingTime)[0][0]
      this.predictionCache.delete(oldestKey)
    }
  }

  private async runModelPrediction(features: number[]): Promise<any> {
    if (!this.model) {
      throw new Error('Model not initialized')
    }

    return await this.model.predict(features)
  }
}

class NetworkFeatureExtractor {
  async extractNumericalFeatures(features: NetworkFeatures): Promise<number[]> {
    return [
      this.normalizeASNScore(features.asnInfo),
      this.normalizeIPRangeScore(features.ipRange),
      this.normalizeReverseDNSScore(features.reverseDNS),
      this.normalizeConnectionPatternScore(features.connectionPattern),
      this.normalizeHistoricalScore(features.historicalData)
    ]
  }

  private normalizeASNScore(asnInfo: any): number {
    const typeScores: Record<string, number> = {
      'corporate': 0.9,
      'education': 0.8,
      'government': 0.8,
      'hosting': 0.6,
      'isp': 0.3
    }

    return typeScores[asnInfo.type] || 0.1
  }

  private normalizeIPRangeScore(ipRange: any): number {
    const typeScores: Record<string, number> = {
      'corporate': 0.9,
      'residential': 0.2,
      'hosting': 0.5,
      'unknown': 0.1
    }

    return typeScores[ipRange.type] || 0.1
  }

  private normalizeReverseDNSScore(reverseDNS: any): number {
    if (reverseDNS.hasCorporateKeywords) return 0.8
    return 0.2
  }

  private normalizeConnectionPatternScore(pattern: any): number {
    let score = 0.5

    if (pattern.businessHoursRatio > 0.7) score += 0.2
    if (pattern.endpointDiversity > 0.5) score += 0.1
    if (pattern.sessionDuration > 3600) score += 0.1

    return Math.min(1, score)
  }

  private normalizeHistoricalScore(historical: any): number {
    if (historical.classificationHistory.length === 0) return 0.5

    const recentClassifications = historical.classificationHistory.slice(-5)
    const consistency = recentClassifications.filter(
      c => c.classification === recentClassifications[0].classification
    ).length / recentClassifications.length

    return consistency
  }
}

// Enhanced corporate detection with ML
class EnhancedCorporateDetector {
  private networkAnalyzer: CorporateNetworkAnalyzer
  private mlClassifier: MLCorporateClassifier
  private corporateClassifier: CorporateResidentialClassifier

  constructor() {
    this.networkAnalyzer = new CorporateNetworkAnalyzer()
    this.mlClassifier = new MLCorporateClassifier()
    this.corporateClassifier = new CorporateResidentialClassifier()
  }

  async detectCorporateNetworkEnhanced(ip: string): Promise<{
    ruleBasedClassification: NetworkAnalysisResult
    mlClassification: MLClassificationResult
    finalDecision: {
      isCorporate: boolean
      confidence: number
      method: 'rule_based' | 'ml' | 'consensus'
    }
    recommendation: string
  }> {
    // Get rule-based analysis
    const ruleBasedAnalysis = await this.networkAnalyzer.analyzeNetwork(ip)

    // Extract features for ML
    const features: NetworkFeatures = {
      ip,
      asnInfo: ruleBasedAnalysis.indicators.autonomousSystem,
      ipRange: ruleBasedAnalysis.indicators.ipRange,
      reverseDNS: ruleBasedAnalysis.indicators.reverseDNS,
      connectionPattern: ruleBasedAnalysis.indicators.connectionPattern,
      historicalData: {
        classificationHistory: [],
        behaviorStability: 0.5
      }
    }

    // Get ML classification
    const mlClassification = await this.mlClassifier.classifyWithML(ip, features)

    // Combine results
    const finalDecision = this.combineClassifications(ruleBasedAnalysis, mlClassification)

    return {
      ruleBasedClassification: ruleBasedAnalysis,
      mlClassification,
      finalDecision,
      recommendation: this.generateEnhancedRecommendation(finalDecision, ruleBasedAnalysis, mlClassification)
    }
  }

  private combineClassifications(
    ruleBased: NetworkAnalysisResult,
    ml: MLClassificationResult
  ): { isCorporate: boolean; confidence: number; method: string } {
    // Weighted combination of rule-based and ML results
    const ruleBasedScore = ruleBased.corporateProbability
    const mlScore = ml.probabilities.corporate || 0

    // Weight ML higher if confidence is good
    const mlWeight = ml.confidence > 70 ? 0.7 : 0.3
    const ruleBasedWeight = 1 - mlWeight

    const combinedScore = (ruleBasedScore * ruleBasedWeight) + (mlScore * mlWeight)
    const isCorporate = combinedScore > 0.6

    let method = 'consensus'
    if (ml.confidence > 80 && ruleBased.confidence < 60) method = 'ml'
    if (ruleBased.confidence > 80 && ml.confidence < 60) method = 'rule_based'

    return {
      isCorporate,
      confidence: combinedScore * 100,
      method
    }
  }

  private generateEnhancedRecommendation(
    finalDecision: any,
    ruleBased: NetworkAnalysisResult,
    ml: MLClassificationResult
  ): string {
    if (finalDecision.confidence > 85) {
      return `High confidence ${finalDecision.isCorporate ? 'corporate' : 'residential'} network (${finalDecision.method})`
    }

    if (finalDecision.confidence < 60) {
      return 'Low confidence classification - consider manual review or additional data sources'
    }

    return `Medium confidence ${finalDecision.isCorporate ? 'corporate' : 'residential'} network - verify with business context`
  }

  // Training data collection for model improvement
  async collectTrainingData(
    ip: string,
    actualClassification: 'corporate' | 'residential',
    features: NetworkFeatures
  ): Promise<void> {
    // In production, store training examples for model retraining
    console.log(`Training data collected for IP ${ip}: ${actualClassification}`)
  }
}

// Initialize enhanced detector
const enhancedCorporateDetector = new EnhancedCorporateDetector()

// Enhanced corporate detection endpoint
app.post('/api/detect-corporate-network-enhanced', async (req, res) => {
  try {
    const { ip } = req.body

    if (!ip) {
      return res.status(400).json({ error: 'IP address required' })
    }

    const result = await enhancedCorporateDetector.detectCorporateNetworkEnhanced(ip)

    res.json({
      detection: result,
      timestamp: new Date().toISOString()
    })

  } catch (error) {
    console.error('Enhanced corporate network detection error:', error)
    res.status(500).json({ error: 'Enhanced detection failed' })
  }
})

// Training data submission endpoint
app.post('/api/corporate-detection/training', async (req, res) => {
  try {
    const { ip, actualClassification, features } = req.body

    if (!ip || !actualClassification || !features) {
      return res.status(400).json({ error: 'IP, classification, and features required' })
    }

    await enhancedCorporateDetector.collectTrainingData(ip, actualClassification, features)

    res.json({
      message: 'Training data submitted successfully',
      timestamp: new Date().toISOString()
    })

  } catch (error) {
    console.error('Training data submission error:', error)
    res.status(500).json({ error: 'Training data submission failed' })
  }
})

console.log('Enhanced corporate network detection with ML initialized')

Behavioral Pattern Analysis for Corporate Detection


// Advanced behavioral pattern analysis for corporate network identification
interface BehavioralSession {
  sessionId: string
  ip: string
  userAgent: string
  startTime: number
  endTime?: number
  duration?: number
  pageViews: number
  uniqueEndpoints: Set<string>
  requestTimestamps: number[]
  errorCount: number
  successCount: number
  businessHoursActivity: boolean
  weekendActivity: boolean
}

interface CorporateBehavioralProfile {
  ip: string
  sessionCount: number
  averageSessionDuration: number
  businessHoursRatio: number
  weekendActivityRatio: number
  endpointDiversity: number
  errorRate: number
  consistencyScore: number
  corporateScore: number
  lastUpdated: number
}

class CorporateBehavioralAnalyzer {
  private activeSessions: Map<string, BehavioralSession> = new Map()
  private behavioralProfiles: Map<string, CorporateBehavioralProfile> = new Map()
  private corporateThresholds = {
    minSessionDuration: 1800, // 30 minutes
    minBusinessHoursRatio: 0.7,
    maxWeekendRatio: 0.3,
    minEndpointDiversity: 0.5,
    maxErrorRate: 0.1,
    minConsistencyScore: 0.6
  }

  constructor() {
    this.startBehavioralMonitoring()
  }

  analyzeRequest(
    ip: string,
    sessionId: string,
    endpoint: string,
    timestamp: number,
    statusCode: number,
    userAgent: string
  ): {
    sessionUpdate: boolean
    profileUpdate: boolean
    corporateIndicators: string[]
    riskFlags: string[]
  } {
    const now = Date.now()
    const isBusinessHours = this.isBusinessHours(timestamp)
    const isWeekend = this.isWeekend(timestamp)

    // Update or create session
    const sessionUpdate = this.updateSession(sessionId, ip, endpoint, timestamp, statusCode, userAgent)

    // Update behavioral profile
    const profileUpdate = this.updateBehavioralProfile(ip, {
      isBusinessHours,
      isWeekend,
      statusCode,
      endpoint
    })

    // Analyze for corporate indicators
    const corporateIndicators = this.analyzeCorporateIndicators(ip)

    // Check for risk flags
    const riskFlags = this.analyzeRiskFlags(ip)

    return {
      sessionUpdate,
      profileUpdate,
      corporateIndicators,
      riskFlags
    }
  }

  private updateSession(
    sessionId: string,
    ip: string,
    endpoint: string,
    timestamp: number,
    statusCode: number,
    userAgent: string
  ): boolean {
    let session = this.activeSessions.get(sessionId)

    if (!session) {
      // Create new session
      session = {
        sessionId,
        ip,
        userAgent,
        startTime: timestamp,
        pageViews: 0,
        uniqueEndpoints: new Set(),
        requestTimestamps: [],
        errorCount: 0,
        successCount: 0,
        businessHoursActivity: false,
        weekendActivity: false
      }
      this.activeSessions.set(sessionId, session)
    }

    // Update session data
    session.pageViews++
    session.uniqueEndpoints.add(endpoint)
    session.requestTimestamps.push(timestamp)

    if (statusCode >= 400) {
      session.errorCount++
    } else {
      session.successCount++
    }

    if (this.isBusinessHours(timestamp)) {
      session.businessHoursActivity = true
    }

    if (this.isWeekend(timestamp)) {
      session.weekendActivity = true
    }

    // Check if session should be closed
    if (session.requestTimestamps.length > 1) {
      const timeDiff = timestamp - session.requestTimestamps[session.requestTimestamps.length - 2]
      if (timeDiff > 30 * 60 * 1000) { // 30 minutes of inactivity
        this.closeSession(sessionId)
      }
    }

    return true
  }

  private closeSession(sessionId: string): void {
    const session = this.activeSessions.get(sessionId)
    if (session) {
      session.endTime = Date.now()
      session.duration = session.endTime - session.startTime

      // Update behavioral profile with completed session
      this.updateProfileWithSession(session)

      this.activeSessions.delete(sessionId)
    }
  }

  private updateProfileWithSession(session: BehavioralSession): void {
    const profileKey = session.ip
    let profile = this.behavioralProfiles.get(profileKey)

    if (!profile) {
      profile = {
        ip: session.ip,
        sessionCount: 0,
        averageSessionDuration: 0,
        businessHoursRatio: 0,
        weekendActivityRatio: 0,
        endpointDiversity: 0,
        errorRate: 0,
        consistencyScore: 0,
        corporateScore: 0,
        lastUpdated: Date.now()
      }
      this.behavioralProfiles.set(profileKey, profile)
    }

    // Update profile statistics
    profile.sessionCount++

    // Update average session duration
    if (session.duration) {
      profile.averageSessionDuration =
        (profile.averageSessionDuration * (profile.sessionCount - 1) + session.duration) / profile.sessionCount
    }

    // Update business hours ratio
    if (session.businessHoursActivity) {
      profile.businessHoursRatio =
        (profile.businessHoursRatio * (profile.sessionCount - 1) + 1) / profile.sessionCount
    }

    // Update weekend activity ratio
    if (session.weekendActivity) {
      profile.weekendActivityRatio =
        (profile.weekendActivityRatio * (profile.sessionCount - 1) + 1) / profile.sessionCount
    }

    // Update endpoint diversity
    profile.endpointDiversity = session.uniqueEndpoints.size / Math.max(session.pageViews, 1)

    // Update error rate
    const totalRequests = session.errorCount + session.successCount
    if (totalRequests > 0) {
      profile.errorRate = session.errorCount / totalRequests
    }

    // Calculate consistency score
    profile.consistencyScore = this.calculateSessionConsistency(session)

    // Calculate corporate score
    profile.corporateScore = this.calculateCorporateScore(profile)

    profile.lastUpdated = Date.now()
    this.behavioralProfiles.set(profileKey, profile)
  }

  private calculateSessionConsistency(session: BehavioralSession): number {
    if (session.requestTimestamps.length < 3) return 0.5

    // Calculate time intervals between requests
    const intervals = []
    for (let i = 1; i < session.requestTimestamps.length; i++) {
      intervals.push(session.requestTimestamps[i] - session.requestTimestamps[i - 1])
    }

    // Calculate coefficient of variation
    const mean = intervals.reduce((a, b) => a + b, 0) / intervals.length
    const variance = intervals.reduce((acc, interval) => acc + Math.pow(interval - mean, 2), 0) / intervals.length
    const stdDev = Math.sqrt(variance)

    const coefficientOfVariation = mean > 0 ? stdDev / mean : 0

    // Lower variation = higher consistency
    return Math.max(0, 1 - coefficientOfVariation)
  }

  private calculateCorporateScore(profile: CorporateBehavioralProfile): number {
    let score = 0.5 // Base score

    // Long sessions suggest corporate usage
    if (profile.averageSessionDuration > this.corporateThresholds.minSessionDuration) {
      score += 0.2
    }

    // High business hours activity suggests corporate
    if (profile.businessHoursRatio > this.corporateThresholds.minBusinessHoursRatio) {
      score += 0.3
    }

    // Low weekend activity suggests corporate
    if (profile.weekendActivityRatio < this.corporateThresholds.maxWeekendRatio) {
      score += 0.2
    }

    // High endpoint diversity suggests corporate
    if (profile.endpointDiversity > this.corporateThresholds.minEndpointDiversity) {
      score += 0.1
    }

    // Low error rate suggests corporate
    if (profile.errorRate < this.corporateThresholds.maxErrorRate) {
      score += 0.1
    }

    // High consistency suggests corporate
    if (profile.consistencyScore > this.corporateThresholds.minConsistencyScore) {
      score += 0.1
    }

    return Math.min(1, Math.max(0, score))
  }

  private analyzeCorporateIndicators(ip: string): string[] {
    const profile = this.behavioralProfiles.get(ip)
    if (!profile) return []

    const indicators: string[] = []

    if (profile.averageSessionDuration > this.corporateThresholds.minSessionDuration) {
      indicators.push('Long session duration')
    }

    if (profile.businessHoursRatio > this.corporateThresholds.minBusinessHoursRatio) {
      indicators.push('High business hours activity')
    }

    if (profile.weekendActivityRatio < this.corporateThresholds.maxWeekendRatio) {
      indicators.push('Low weekend activity')
    }

    if (profile.endpointDiversity > this.corporateThresholds.minEndpointDiversity) {
      indicators.push('High endpoint diversity')
    }

    if (profile.errorRate < this.corporateThresholds.maxErrorRate) {
      indicators.push('Low error rate')
    }

    if (profile.consistencyScore > this.corporateThresholds.minConsistencyScore) {
      indicators.push('High behavioral consistency')
    }

    return indicators
  }

  private analyzeRiskFlags(ip: string): string[] {
    const profile = this.behavioralProfiles.get(ip)
    if (!profile) return []

    const flags: string[] = []

    // Very short sessions with many requests
    if (profile.averageSessionDuration < 300 && profile.sessionCount > 10) {
      flags.push('Suspicious session pattern')
    }

    // High error rate
    if (profile.errorRate > 0.5) {
      flags.push('High error rate')
    }

    // Very low consistency (erratic behavior)
    if (profile.consistencyScore < 0.2) {
      flags.push('Erratic behavioral pattern')
    }

    // Weekend-only activity
    if (profile.businessHoursRatio < 0.3 && profile.weekendActivityRatio > 0.7) {
      flags.push('Weekend-only activity')
    }

    return flags
  }

  private isBusinessHours(timestamp: number): boolean {
    const date = new Date(timestamp)
    const hour = date.getHours()
    const dayOfWeek = date.getDay()

    // Business hours: Monday-Friday, 9 AM - 6 PM
    return dayOfWeek >= 1 && dayOfWeek <= 5 && hour >= 9 && hour <= 18
  }

  private isWeekend(timestamp: number): boolean {
    const date = new Date(timestamp)
    const dayOfWeek = date.getDay()
    return dayOfWeek === 0 || dayOfWeek === 6
  }

  private startBehavioralMonitoring(): void {
    // Clean up old sessions every 5 minutes
    setInterval(() => {
      this.cleanupOldSessions()
    }, 5 * 60 * 1000)

    // Update behavioral profiles every 15 minutes
    setInterval(() => {
      this.updateAllProfiles()
    }, 15 * 60 * 1000)

    console.log('Behavioral analysis monitoring started')
  }

  private cleanupOldSessions(): void {
    const now = Date.now()
    const thirtyMinutesAgo = now - 30 * 60 * 1000

    for (const [sessionId, session] of this.activeSessions.entries()) {
      if (session.requestTimestamps.length > 0) {
        const lastRequest = Math.max(...session.requestTimestamps)
        if (lastRequest < thirtyMinutesAgo) {
          this.closeSession(sessionId)
        }
      }
    }
  }

  private updateAllProfiles(): void {
    // Force update of all profiles (for testing/demo)
    console.log(`Updated ${this.behavioralProfiles.size} behavioral profiles`)
  }

  private updateBehavioralProfile(
    ip: string,
    requestData: { isBusinessHours: boolean; isWeekend: boolean; statusCode: number; endpoint: string }
  ): boolean {
    // This would normally update the profile based on the request
    // For demo, we'll just mark that an update occurred
    return true
  }

  getBehavioralProfile(ip: string): CorporateBehavioralProfile | null {
    return this.behavioralProfiles.get(ip) || null
  }

  getAllBehavioralProfiles(): CorporateBehavioralProfile[] {
    return Array.from(this.behavioralProfiles.values())
  }

  getCorporateNetworks(minScore: number = 0.7): string[] {
    return Array.from(this.behavioralProfiles.entries())
      .filter(([, profile]) => profile.corporateScore >= minScore)
      .map(([ip]) => ip)
  }

  getBehavioralStats(): {
    totalProfiles: number
    corporateProfiles: number
    averageCorporateScore: number
    topCorporateIPs: Array<{ ip: string; score: number }>
  } {
    const profiles = Array.from(this.behavioralProfiles.values())
    const corporateProfiles = profiles.filter(p => p.corporateScore >= 0.7)
    const averageCorporateScore = profiles.length > 0
      ? profiles.reduce((sum, p) => sum + p.corporateScore, 0) / profiles.length
      : 0

    const topCorporateIPs = corporateProfiles
      .sort((a, b) => b.corporateScore - a.corporateScore)
      .slice(0, 10)
      .map(p => ({ ip: p.ip, score: p.corporateScore }))

    return {
      totalProfiles: profiles.length,
      corporateProfiles: corporateProfiles.length,
      averageCorporateScore,
      topCorporateIPs
    }
  }
}

// Initialize behavioral analyzer
const behavioralAnalyzer = new CorporateBehavioralAnalyzer()

// Behavioral analysis endpoint
app.post('/api/analyze-behavioral-pattern', async (req, res) => {
  try {
    const { ip, sessionId, endpoint, timestamp, statusCode, userAgent } = req.body

    if (!ip || !sessionId || !endpoint || !timestamp) {
      return res.status(400).json({ error: 'IP, sessionId, endpoint, and timestamp required' })
    }

    const analysis = behavioralAnalyzer.analyzeRequest(
      ip,
      sessionId,
      endpoint,
      timestamp,
      statusCode || 200,
      userAgent || ''
    )

    res.json({
      analysis,
      timestamp: new Date().toISOString()
    })

  } catch (error) {
    console.error('Behavioral analysis error:', error)
    res.status(500).json({ error: 'Behavioral analysis failed' })
  }
})

// Get behavioral profile endpoint
app.get('/api/behavioral-profile/:ip', (req, res) => {
  const { ip } = req.params

  if (!ip) {
    return res.status(400).json({ error: 'IP address required' })
  }

  const profile = behavioralAnalyzer.getBehavioralProfile(ip)

  if (!profile) {
    return res.status(404).json({ error: 'Profile not found' })
  }

  res.json({
    profile,
    timestamp: new Date().toISOString()
  })
})

// Get behavioral statistics
app.get('/api/behavioral-stats', (req, res) => {
  const stats = behavioralAnalyzer.getBehavioralStats()

  res.json({
    stats,
    timestamp: new Date().toISOString()
  })
})

// Get corporate networks identified by behavior
app.get('/api/corporate-networks-behavioral', (req, res) => {
  const { minScore = 0.7 } = req.query

  const corporateIPs = behavioralAnalyzer.getCorporateNetworks(Number(minScore))

  res.json({
    corporateIPs,
    count: corporateIPs.length,
    minScore: Number(minScore),
    timestamp: new Date().toISOString()
  })
})

console.log('Behavioral pattern analysis system initialized')

Implementation Challenges {#implementation-challenges}


Key challenges in corporate network detection.


Challenges:

  • False Positives: Home offices, VPNs classified as corporate
  • Remote Work: Blurred lines between corporate and residential
  • Privacy: Must not over-fingerprint users
  • Dynamic Networks: Corporate networks change infrastructure
  • Cloud Services: SaaS companies use cloud IPs, not corporate ranges

Performance Optimization {#performance-optimization}


Optimize detection for high-volume scenarios.


class CorporateDetectionCache {
  private cache: Map<string, { isCorporate: boolean; confidence: number; expiry: number }> = new Map()
  
  getCached(ip: string): { isCorporate: boolean; confidence: number } | null {
    const cached = this.cache.get(ip)
    if (!cached || Date.now() > cached.expiry) return null
    return { isCorporate: cached.isCorporate, confidence: cached.confidence }
  }
  
  setCached(ip: string, result: { isCorporate: boolean; confidence: number }): void {
    this.cache.set(ip, {
      ...result,
      expiry: Date.now() + 3600000 // 1 hour TTL
    })
  }
}

Use Case Applications {#use-case-applications}


Practical applications of corporate detection.


Use Cases:

  • B2B Marketing: Target corporate users with enterprise offers
  • Pricing: Differential pricing for business vs consumer
  • Security: Enhanced verification for corporate networks
  • Compliance: Track business user access patterns
  • Analytics: Segment traffic by network type

Future Considerations {#future-considerations}


Evolving landscape of corporate networks.


Trends:

  • Increasing remote work blurs corporate/residential distinction
  • Cloud-first companies have no traditional corporate IP ranges
  • Zero-trust networks reduce reliance on network classification
  • Privacy regulations limit fingerprinting capabilities

Conclusion {#conclusion}


Corporate network detection combines ASN analysis, proxy detection, behavioral patterns, and organizational databases. Success depends on multi-signal approach, appropriate confidence thresholds, respecting privacy, and adapting to remote work trends.


Key success factors include using multiple detection methods, maintaining current organizational databases, implementing confidence scoring, handling edge cases like remote workers, and providing transparency about detection methods.


Identify corporate networks accurately with our IP intelligence APIs, designed to distinguish business from residential traffic while respecting user privacy.

Tags:corporate-networksbusiness-detectionnetwork-classificationtraffic-analysis