/* include sig_alrm */
#include "udpcksum.h"
#include <setjmp.h>
static sigjmp_buf jmpbuf;
static int canjump;
void
sig_alrm(int signo)
{
if (canjump == 0)
return;
siglongjmp(jmpbuf, 1);
}
/* end sig_alrm */
/*
* Build a DNS A query for "a.root-servers.net" and write it to
* the raw socket.
*/
/* include send_dns_query */
void
send_dns_query(void)
{
size_t nbytes;
char buf[sizeof(struct udpiphdr) + 100], *ptr;
short one;
ptr = buf + sizeof(struct udpiphdr);/* leave room for IP/UDP headers */
*((u_short *) ptr) = htons(1234); /* identification */
ptr += 2;
*((u_short *) ptr) = htons(0x0); /* flags */
ptr += 2;
*((u_short *) ptr) = htons(1); /* #questions */
ptr += 2;
*((u_short *) ptr) = 0; /* #answer RRs */
ptr += 2;
*((u_short *) ptr) = 0; /* #authority RRs */
ptr += 2;
*((u_short *) ptr) = 0; /* #additional RRs */
ptr += 2;
memcpy(ptr, "\001a\014root-servers\003net\000", 20);
ptr += 20;
one = htons(1);
memcpy(ptr, &one, 2); /* query type = A */
ptr += 2;
memcpy(ptr, &one, 2); /* query class = 1 (IP addr) */
ptr += 2;
nbytes = 36;
udp_write(buf, nbytes);
if (verbose)
printf("sent: %d bytes of data\n", nbytes);
}
/* end send_dns_query */
/* include test_udp */
void
test_udp(void)
{
volatile int nsent = 0, timeout = 3;
struct udpiphdr *ui;
Signal(SIGALRM, sig_alrm);
if (sigsetjmp(jmpbuf, 1)) {
if (nsent >= 3)
err_quit("no response");
printf("timeout\n");
timeout *= 2; /* exponential backoff: 3, 6, 12 */
}
canjump = 1; /* siglongjmp is now OK */
send_dns_query();
nsent++;
alarm(timeout);
ui = udp_read();
canjump = 0;
alarm(0);
if (ui->ui_sum == 0)
printf("UDP checksums off\n");
else
printf("UDP checksums on\n");
if (verbose)
printf("recevied UDP checksum = %x\n", ui->ui_sum);
}
/* end test_udp */
syntax highlighted by Code2HTML, v. 0.9.1