code: func cipherSuiteScan(addr, hostname string) (grade Grade, output Output, err error) {
  	var cvList cipherVersionList
  	allCiphers := allCiphersIDs()
  
  	var vers uint16
  	for vers = tls.VersionTLS12; vers >= tls.VersionSSL30; vers-- {
  		ciphers := make([]uint16, len(allCiphers))
  		copy(ciphers, allCiphers)
  		for len(ciphers) > 0 {
  			var cipherIndex int
  			cipherIndex, _, _, err = sayHello(addr, hostname, ciphers, nil, vers, nil)
  			if err != nil {
  				if err == errHelloFailed {
  					err = nil
  					break
  				}
  				return
  			}
  			if vers == tls.VersionSSL30 {
  				grade = Warning
  			}
  			cipherID := ciphers[cipherIndex]
  
  			// If this is an EC cipher suite, do a second scan for curve support
  			var supportedCurves []tls.CurveID
  			if tls.CipherSuites[cipherID].EllipticCurve {
  				supportedCurves, err = doCurveScan(addr, hostname, vers, cipherID, ciphers)
  				if len(supportedCurves) == 0 {
  					err = errors.New("couldn't negotiate any curves")
  				}
  			}
  			for i, c := range cvList {
  				if cipherID == c.cipherID {
  					cvList[i].data = append(c.data, cipherDatum{vers, supportedCurves})
  					goto exists
  				}
  			}
  			cvList = append(cvList, cipherVersions{cipherID, []cipherDatum{{vers, supportedCurves}}})
  		exists:
  			ciphers = append(ciphers[:cipherIndex], ciphers[cipherIndex+1:]...)
  		}
  	}
  
  	if len(cvList) == 0 {
  		err = errors.New("couldn't negotiate any cipher suites")
  		return
  	}
  
  	if grade != Warning {
  		grade = Good
  	}
  
  	output = cvList
  	return
  }
docs: // cipherSuiteScan returns, by TLS Version, the sort list of cipher suites
  // supported by the host