1 /* RFC2136 DNS inform - necessary for Win2k3 DNS servers */
15 [1] "request format error",
16 [2] "internal server error",
17 [3] "domain name does not exist",
18 [4] "request not supported",
19 [5] "permission denied",
20 [6] "domain name already exists",
21 [7] "resource record already exists",
22 [8] "resource record does not exist",
23 [9] "server not authoritative",
24 [10] "domain name not in zone",
27 static uchar loopbacknet[IPaddrlen] = {
33 static uchar loopbackmask[IPaddrlen] = {
34 0xff, 0xff, 0xff, 0xff,
35 0xff, 0xff, 0xff, 0xff,
36 0xff, 0xff, 0xff, 0xff,
39 static uchar loopback6[IPaddrlen] = {
49 fprint(2, "usage: %s [-x netmtpt]\n", argv0);
54 ding(void *, char *msg)
56 if(strstr(msg, "alarm") != nil)
88 pmem(uchar **p, void *v, int len)
95 pname(uchar **p, char *s)
101 while(*s && *s != '.')
111 main(int argc, char *argv[])
113 static char *query[] = { "dom", "dnsdomain", "ns", "inform" };
114 char *sysname, *dnsdomain, *dom, *inform, *ns, net[32];
117 uchar *p, buf[4096], mynet[IPaddrlen];
124 fmtinstall('I', eipfmt);
125 fmtinstall('V', eipfmt);
126 setnetmtpt(net, sizeof net, nil);
138 setnetmtpt(net, sizeof net, EARGF(usage()));
147 if((sysname = getenv("sysname")) == nil)
148 sysfatal("$sysname not set");
150 if((db = ndbopen(nil)) == nil)
151 sysfatal("can't open ndb: %r");
152 tt = ndbipinfo(db, "sys", sysname, query, nelem(query));
153 for(t = tt; t; t = t->entry){
154 if(strcmp(t->attr, "ns") == 0)
156 else if(strcmp(t->attr, "dom") == 0)
158 else if(strcmp(t->attr, "dnsdomain") == 0)
160 else if(strcmp(t->attr, "inform") == 0)
170 sysfatal("no relevant ns=");
172 sysfatal("no relevant dom=");
174 sysfatal("no relevant dnsdomain=");
177 print("ns=%s\n", ns);
178 print("dnsdomain=%s\n", dnsdomain);
179 print("dom=%s\n", dom);
182 if((fd = dial(netmkaddr(ns, "udp", "dns"), 0, 0, 0)) < 0)
183 sysfatal("can't dial %s: %r", ns);
185 txid = time(nil) + getpid();
188 p16(&p, txid); /* ID */
189 p16(&p, 5<<11); /* flags */
190 p16(&p, 1); /* # Zones */
191 p16(&p, 0); /* # prerequisites */
192 p16(&p, 2); /* # updates */
193 p16(&p, 0); /* # additionals */
195 pname(&p, dnsdomain); /* zone */
196 p16(&p, Tsoa); /* zone type */
197 p16(&p, Cin); /* zone class */
199 /* delete old name */
200 pname(&p, dom); /* name */
201 p16(&p, Ta); /* type: v4 addr */
202 p16(&p, Call); /* class */
203 p32(&p, 0); /* TTL */
204 p16(&p, 0); /* data len */
206 pname(&p, dom); /* name */
207 p16(&p, Taaaa); /* type: v6 addr */
208 p16(&p, Call); /* class */
209 p32(&p, 0); /* TTL */
210 p16(&p, 0); /* data len */
212 for(ifc = readipifc(net, nil, -1); ifc != nil; ifc = ifc->next){
213 for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
215 if(ipcmp(lifc->ip, IPnoaddr) == 0)
219 if(ipcmp(lifc->ip, loopback6) == 0)
223 maskip(lifc->ip, loopbackmask, mynet);
224 if(ipcmp(mynet, loopbacknet) == 0)
228 print("ip=%I\n", lifc->ip);
230 /* add new A record */
231 pname(&p, dom); /* name */
232 p16(&p, isv4(lifc->ip)?Ta:Taaaa);
233 p16(&p, Cin); /* class */
234 p32(&p, 60*60*25); /* TTL (25 hours) */
236 p16(&p, IPv4addrlen);
237 pmem(&p, lifc->ip+IPv4off, IPv4addrlen);
240 pmem(&p, lifc->ip, IPaddrlen);
246 if(write(fd, buf, len) != len)
247 sysfatal("write failed: %r");
252 if(read(fd, buf, sizeof buf) < 0)
255 }while(g16(&p) != txid);
259 if(err != 0 && err != 7) /* err==7 is just a "yes, I know" warning */
260 if(err < nelem(errmsgs))
261 sysfatal("%s", errmsgs[err]);
263 sysfatal("unknown dns server error %d", err);