Whois Queries¶
The apnic-skills SDK provides comprehensive Whois query capabilities against the APNIC Whois server (whois.apnic.net:43). Whois is the traditional TCP-based protocol for querying registration data for IP addresses, ASNs, and other Internet resources.
sequenceDiagram
participant Client as SDK Client
participant SDK as apnic-skills
participant Whois as whois.apnic.net:43
Client->>SDK: QueryWhoisIP(ctx, "1.1.1.1")
SDK->>SDK: Apply rate limit + jitter
SDK->>Whois: TCP connect (port 43)
Whois-->>SDK: Connection established
SDK->>Whois: "1.1.1.1\r\n"
Whois-->>SDK: Raw Whois response
SDK->>SDK: ParseWhoisResponse()
SDK-->>Client: *WhoisInfo Methods¶
| Method | Description |
|---|---|
QueryWhois(ctx, query) | Perform a raw Whois query and return the response text |
QueryWhoisIP(ctx, ip) | Query Whois for an IP address and return parsed result |
QueryWhoisASN(ctx, asn) | Query Whois for an ASN (pass 13335, not "AS13335") |
QueryWhoisWithFlags(ctx, query, flags) | Query with flags like "B" (brief), "r" (no recursion) |
ParseWhoisResponse(response) | Parse raw Whois text into structured WhoisInfo |
WhoisInfo Structure¶
type WhoisInfo struct {
Network string // Network range (e.g., "1.1.1.0 - 1.1.1.255")
CIDR []string // CIDR blocks (e.g., ["1.1.1.0/24"])
Country string // ISO 3166 country code
OrgName string // Organization name
Parent string // Parent allocation
Created time.Time // Registration date
LastUpdated time.Time // Last modification date
}
Query Flow¶
flowchart TB
subgraph Query["Whois Query"]
Connect["TCP Connect<br/>whois.apnic.net:43"]
Send["Send Query<br/>query + CRLF"]
Read["Read Response<br/>until EOF"]
end
subgraph Parse["Response Parsing"]
Scan["Scan Lines"]
Skip["Skip Comments<br/>% and #"]
Extract["Extract Fields<br/>key: value"]
Build["Build WhoisInfo"]
end
subgraph RateLimit["Anti-Scraping"]
Bucket["Token Bucket<br/>rate limiting"]
Jitter["Random Jitter<br/>200-800ms"]
end
RateLimit --> Connect --> Send --> Read --> Scan --> Skip --> Extract --> Build Examples¶
IP Address Whois Query¶
package main
import (
"context"
"fmt"
"log"
"time"
apnic "github.com/cyberspacesec/apnic-skills"
)
func main() {
client := apnic.NewClient(
apnic.WithWhoisTimeout(15 * time.Second),
)
ctx := context.Background()
// Query IP Whois
info, err := client.QueryWhoisIP(ctx, "1.1.1.1")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Network: %s\n", info.Network)
fmt.Printf("CIDR: %v\n", info.CIDR)
fmt.Printf("Country: %s\n", info.Country)
fmt.Printf("Organization: %s\n", info.OrgName)
fmt.Printf("Created: %s\n", info.Created.Format("2006-01-02"))
fmt.Printf("Last Updated: %s\n", info.LastUpdated.Format("2006-01-02"))
}
ASN Whois Query¶
package main
import (
"context"
"fmt"
"log"
apnic "github.com/cyberspacesec/apnic-skills"
)
func main() {
client := apnic.NewClient()
ctx := context.Background()
// Query ASN Whois (pass numeric ASN, not "AS13335")
info, err := client.QueryWhoisASN(ctx, 13335)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Organization: %s\n", info.OrgName)
fmt.Printf("Country: %s\n", info.Country)
}
Raw Whois Query with Flags¶
package main
import (
"context"
"fmt"
"log"
apnic "github.com/cyberspacesec/apnic-skills"
)
func main() {
client := apnic.NewClient()
ctx := context.Background()
// Raw query with flags
// "B" = brief output, "r" = no recursion, "l" = one level less specific
raw, err := client.QueryWhoisWithFlags(ctx, "8.8.8.8", "B")
if err != nil {
log.Fatal(err)
}
fmt.Println("Raw Whois Response:")
fmt.Println(raw)
// Parse manually if needed
info := apnic.ParseWhoisResponse(raw)
fmt.Printf("Network: %s\n", info.Network)
}
Custom Whois Server¶
package main
import (
apnic "github.com/cyberspacesec/apnic-skills"
)
func main() {
client := apnic.NewClient(
apnic.WithWhoisServer("whois.apnic.net:43"),
apnic.WithWhoisTimeout(30 * apnic.Second),
)
// ... use client
}
Anti-Scraping Integration¶
Whois queries inherit the SDK's anti-scraping mechanisms:
- Rate Limiting: Token bucket algorithm limits request frequency
- Random Jitter: 200-800ms delay between requests (configurable)
- Context Support: Respects context cancellation and deadlines
// Configure jitter range
client := apnic.NewClient(
apnic.WithJitter(100*time.Millisecond, 500*time.Millisecond),
apnic.WithRateLimit(1.0), // 1 request per second max
)
Common Whois Flags¶
| Flag | Description |
|---|---|
B | Brief output (less verbose) |
r | Disable recursion (no referral to other registries) |
l | Show one level less specific |
L | Show all levels less specific |
m | Show one level more specific |
M | Show all levels more specific |