simple code (DDNS)

Stefan Puiu stefan.puiu at gmail.com
Thu Mar 9 12:00:21 UTC 2006


Hope you don't mind that I bring this on-list again, but after all, I
think the discussion is on-topic for bind-users.

On 3/7/06, Roman Mashak <romez777 at gmail.com> wrote:
> What's the benefit of using low-level functions? As far as I
> understood, 'res_mkupdrec()', 'res_update()' and similar are only
> wrappers to lower layer.

Depends on what you want to do. If you want to do simple updates, you
probably don't need to go low-level. If you want more control on the
update process, then you might go use res_mkupdrec(),
res_nsendsigned() etc.

We had this scenario where the server to update was always the same,
so it didn't make sense to go through the whole procedure - finding
the zone cut, finding nameservers etc.


>
> >
> > Now, you can only imagine what will happen when res_findzonecut() is
> > passed an empty string as the owner name - what zone can it determine
> > from that? I wouldn't be surprised if it justs returns an error.
> Actually I went through this simple code with debugger (stepping into
> 'libbind' library) and nothing bad happened :) (a little revised code
> attached here works correct). Perhaps, I missed something

Well, the new code looks like it might work, since you supplied the
domain name when calling dns_update() for the delete operation. It
really depends on what you want to do - if deletion and then addition
is the procedure you found appropriate for your setup, then OK. You
also might want to look into prerequisites - you can specify that the
record will be added only if it doesn't exist already, for example.


Also, I would use strncpy() for copying argv[1] in str in the code below.

>
> >
> > The second update will also be invalid, since you can't have a domain
> > name as the rdata in an A record.
> >
> > You could try to watch the traffic with a sniffer - however, probably
> > the first call to dns_update() won't generate any, if it has any input
> > checking.
> >
> According to documentation (standard etc.) to register names in DynDNS
> zone, we first should delete those names, that's why I pass DELETE
> opcode, and next - ADD.
>
> #include <stdlib.h>
> #include <string.h>
> #include <netinet/in.h>
> #include <res_update.h>
>
> #define DYN_TTL 3600
>
> /* DNS functions */
> int dns_update(const char *r_dname, int r_opcode, short int r_type,
>                            unsigned int r_ttl, int r_size, /*unsigned*/ char *r_data)
> {
>         int                     r_section = S_UPDATE;
>         short int       r_class = C_IN;
>         ns_updrec       *rrecp;
>
>         /* fill in update record */
>         if ( !(rrecp = res_mkupdrec(r_section, r_dname, r_class, r_type, r_ttl)) ||
>                   (r_size > 0 && !(rrecp->r_data = (u_char *)malloc(r_size))) )
>                 return -1;
>
>         rrecp->r_opcode = r_opcode;
>         rrecp->r_size = r_size;
>         if (r_size > 0)
>                 strcpy((char *)rrecp->r_data, r_data);
>
> #if !defined(BIND821) && !defined(__FreeBSD__)
>         rrecp->r_link.prev = NULL;
>         rrecp->r_link.next = NULL;
> #else
>         rrecp->r_prev = NULL;
>         rrecp->r_next = NULL;
> #endif
>
>         /* fail if updated 0 zones */
>         if (res_update(rrecp) == 0)
>                 return -1;
>
>         if (rrecp->r_size)
>                 free(rrecp->r_data);
>
>         free(rrecp);
>
>         return 0;
> }
>
> int main(int argc, char *argv[])
> {
>         char str[128];
>
>         if (argc < 2) {
>                 fprintf(stderr, "usage: %s <host> <ipaddr>\n", argv[0]);
>                 return -1;
>         }
>
>         sprintf(str, "%s", argv[1]);
>
>         if (dns_update(str, DELETE, T_A, 0, 0, "") < 0)
>                 return -1;
>         if (dns_update(str, ADD, T_A, DYN_TTL, strlen(argv[2]), argv[2]) < 0)
>                 return -1;
>
>         return 0;
> }
>
> --
> Roman
>



More information about the bind-users mailing list