Skip to content

Instantly share code, notes, and snippets.

@dgv
Created March 12, 2026 01:51
Show Gist options
  • Select an option

  • Save dgv/4d719bcb3cfaccba00991426b7f340d9 to your computer and use it in GitHub Desktop.

Select an option

Save dgv/4d719bcb3cfaccba00991426b7f340d9 to your computer and use it in GitHub Desktop.
zig lookup ip geolocation using mmdb
const std = @import("std");
const maxminddb = @import("maxminddb");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "ip66",
.root_module = b.createModule(.{
.root_source_file = b.path("ip66.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "maxminddb", .module = b.dependency("maxminddb", .{
.target = target,
.optimize = optimize,
}).module("maxminddb") },
},
}),
});
b.installArtifact(exe);
const run_step = b.step("run", "Run the app");
const run_cmd = b.addRunArtifact(exe);
run_step.dependOn(&run_cmd.step);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
}
.{
.name = .ip66,
.version = "0.0.0",
.fingerprint = 0x753d0b29c8b6370b, // Changing this has security and trust implications.
.minimum_zig_version = "0.15.2",
.dependencies = .{
.maxminddb = .{
.url = "git+https://github.com/marselester/maxminddb.zig.git#2a37156657c0120018b42d713989a7310d36ea01",
.hash = "maxminddb-0.4.0-HBInuoqSAQDRb-e1HR4prZrBRIEG_MxALBGB3gQl_7fJ",
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"ip66.zig",
},
}
//
// download free IP geolocation db form ip66.dev
// curl -LO https://downloads.ip66.dev/db/ip66.mmdb
//
// zig build run -- 4.228.31.150
// or
// zig build run -- 2001:1284:f514:35c6:3e40:c82e:d5d8:969e
//
const std = @import("std");
const maxminddb = @import("maxminddb");
const db_path = "ip66.mmdb";
// We expect a DB file not larger than 1 GB.
const max_db_size: usize = 1024 * 1024 * 1024;
pub fn main() !void {
var gpa: std.heap.DebugAllocator(.{}) = .init;
const allocator = gpa.allocator();
defer _ = gpa.detectLeaks();
var db = try maxminddb.Reader.open(allocator, db_path, max_db_size);
defer db.close(allocator);
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len != 2) {
std.debug.print("must provide an IP address\n", .{});
return;
}
const ip = try std.net.Address.parseIp(args[1], 0);
const city = try db.lookup(allocator, maxminddb.geoip2.City, ip, .{}) orelse return;
defer city.deinit();
for (city.value.country.names.?.entries) |e| {
std.debug.print("{s} = {s}\n", .{ e.key, e.value });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment