"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/tftp.c" between
dnsmasq-2.81.tar.xz and dnsmasq-2.82.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

tftp.c  (dnsmasq-2.81.tar.xz):tftp.c  (dnsmasq-2.82.tar.xz)
skipping to change at line 64 skipping to change at line 64
struct tftp_transfer *transfer = NULL, **up; struct tftp_transfer *transfer = NULL, **up;
int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */ int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
int mtuflag = IP_PMTUDISC_DONT; int mtuflag = IP_PMTUDISC_DONT;
#endif #endif
char namebuff[IF_NAMESIZE]; char namebuff[IF_NAMESIZE];
char *name = NULL; char *name = NULL;
char *prefix = daemon->tftp_prefix; char *prefix = daemon->tftp_prefix;
struct tftp_prefix *pref; struct tftp_prefix *pref;
union all_addr addra; union all_addr addra;
int family = listen->addr.sa.sa_family;
/* Can always get recvd interface for IPv6 */ /* Can always get recvd interface for IPv6 */
int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6; int check_dest = !option_bool(OPT_NOWILD) || family == AF_INET6;
union { union {
struct cmsghdr align; /* this ensures alignment */ struct cmsghdr align; /* this ensures alignment */
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
#elif defined(HAVE_SOLARIS_NETWORK) #elif defined(HAVE_SOLARIS_NETWORK)
char control[CMSG_SPACE(sizeof(struct in_addr)) + char control[CMSG_SPACE(sizeof(struct in_addr)) +
CMSG_SPACE(sizeof(unsigned int))]; CMSG_SPACE(sizeof(unsigned int))];
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF) #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
char control[CMSG_SPACE(sizeof(struct in_addr)) + char control[CMSG_SPACE(sizeof(struct in_addr)) +
skipping to change at line 124 skipping to change at line 125
return; return;
} }
} }
else else
{ {
struct cmsghdr *cmptr; struct cmsghdr *cmptr;
if (msg.msg_controllen < sizeof(struct cmsghdr)) if (msg.msg_controllen < sizeof(struct cmsghdr))
return; return;
addr.sa.sa_family = listen->family; addr.sa.sa_family = family;
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
if (listen->family == AF_INET) if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) ) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) )
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO) if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{ {
union { union {
unsigned char *c; unsigned char *c;
struct in_pktinfo *p; struct in_pktinfo *p;
} p; } p;
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
addr.in.sin_addr = p.p->ipi_spec_dst; addr.in.sin_addr = p.p->ipi_spec_dst;
if_index = p.p->ipi_ifindex; if_index = p.p->ipi_ifindex;
} }
#elif defined(HAVE_SOLARIS_NETWORK) #elif defined(HAVE_SOLARIS_NETWORK)
if (listen->family == AF_INET) if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) ) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) )
{ {
union { union {
unsigned char *c; unsigned char *c;
struct in_addr *a; struct in_addr *a;
unsigned int *i; unsigned int *i;
} p; } p;
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDST ADDR) if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDST ADDR)
addr.in.sin_addr = *(p.a); addr.in.sin_addr = *(p.a);
else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RE CVIF) else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RE CVIF)
if_index = *(p.i); if_index = *(p.i);
} }
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF) #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
if (listen->family == AF_INET) if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) ) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) )
{ {
union { union {
unsigned char *c; unsigned char *c;
struct in_addr *a; struct in_addr *a;
struct sockaddr_dl *s; struct sockaddr_dl *s;
} p; } p;
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDST ADDR) if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDST ADDR)
addr.in.sin_addr = *(p.a); addr.in.sin_addr = *(p.a);
else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RE CVIF) else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RE CVIF)
if_index = p.s->sdl_index; if_index = p.s->sdl_index;
} }
#endif #endif
if (listen->family == AF_INET6) if (family == AF_INET6)
{ {
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmp tr)) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmp tr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon- >v6pktinfo) if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon- >v6pktinfo)
{ {
union { union {
unsigned char *c; unsigned char *c;
struct in6_pktinfo *p; struct in6_pktinfo *p;
} p; } p;
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
skipping to change at line 197 skipping to change at line 198
} }
} }
if (!indextoname(listen->tftpfd, if_index, namebuff)) if (!indextoname(listen->tftpfd, if_index, namebuff))
return; return;
name = namebuff; name = namebuff;
addra.addr4 = addr.in.sin_addr; addra.addr4 = addr.in.sin_addr;
if (listen->family == AF_INET6) if (family == AF_INET6)
addra.addr6 = addr.in6.sin6_addr; addra.addr6 = addr.in6.sin6_addr;
if (daemon->tftp_interfaces) if (daemon->tftp_interfaces)
{ {
/* dedicated tftp interface list */ /* dedicated tftp interface list */
for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next) for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, name)) if (tmp->name && wildcard_match(tmp->name, name))
break; break;
if (!tmp) if (!tmp)
return; return;
} }
else else
{ {
/* Do the same as DHCP */ /* Do the same as DHCP */
if (!iface_check(listen->family, &addra, name, NULL)) if (!iface_check(family, &addra, name, NULL))
{ {
if (!option_bool(OPT_CLEVERBIND)) if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces(0); enumerate_interfaces(0);
if (!loopback_exception(listen->tftpfd, listen->family, &addra, nam if (!loopback_exception(listen->tftpfd, family, &addra, name) &&
e) && !label_exception(if_index, family, &addra))
!label_exception(if_index, listen->family, &addra))
return; return;
} }
#ifdef HAVE_DHCP #ifdef HAVE_DHCP
/* allowed interfaces are the same as for DHCP */ /* allowed interfaces are the same as for DHCP */
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, name)) if (tmp->name && wildcard_match(tmp->name, name))
return; return;
#endif #endif
} }
skipping to change at line 284 skipping to change at line 285
} }
if (name) if (name)
{ {
/* check for per-interface prefix */ /* check for per-interface prefix */
for (pref = daemon->if_prefix; pref; pref = pref->next) for (pref = daemon->if_prefix; pref; pref = pref->next)
if (strcmp(pref->interface, name) == 0) if (strcmp(pref->interface, name) == 0)
prefix = pref->prefix; prefix = pref->prefix;
} }
if (listen->family == AF_INET) if (family == AF_INET)
{ {
addr.in.sin_port = htons(port); addr.in.sin_port = htons(port);
#ifdef HAVE_SOCKADDR_SA_LEN #ifdef HAVE_SOCKADDR_SA_LEN
addr.in.sin_len = sizeof(addr.in); addr.in.sin_len = sizeof(addr.in);
#endif #endif
} }
else else
{ {
addr.in6.sin6_port = htons(port); addr.in6.sin6_port = htons(port);
addr.in6.sin6_flowinfo = 0; addr.in6.sin6_flowinfo = 0;
skipping to change at line 307 skipping to change at line 308
addr.in6.sin6_len = sizeof(addr.in6); addr.in6.sin6_len = sizeof(addr.in6);
#endif #endif
} }
/* May reuse struct transfer from abandoned transfer in single port mode. */ /* May reuse struct transfer from abandoned transfer in single port mode. */
if (!transfer && !(transfer = whine_malloc(sizeof(struct tftp_transfer)))) if (!transfer && !(transfer = whine_malloc(sizeof(struct tftp_transfer))))
return; return;
if (option_bool(OPT_SINGLE_PORT)) if (option_bool(OPT_SINGLE_PORT))
transfer->sockfd = listen->tftpfd; transfer->sockfd = listen->tftpfd;
else if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1) else if ((transfer->sockfd = socket(family, SOCK_DGRAM, 0)) == -1)
{ {
free(transfer); free(transfer);
return; return;
} }
transfer->peer = peer; transfer->peer = peer;
transfer->source = addra; transfer->source = addra;
transfer->if_index = if_index; transfer->if_index = if_index;
transfer->timeout = now + 2; transfer->timeout = now + 2;
transfer->backoff = 1; transfer->backoff = 1;
transfer->block = 1; transfer->block = 1;
transfer->blocksize = 512; transfer->blocksize = 512;
transfer->offset = 0; transfer->offset = 0;
transfer->file = NULL; transfer->file = NULL;
transfer->opt_blocksize = transfer->opt_transize = 0; transfer->opt_blocksize = transfer->opt_transize = 0;
transfer->netascii = transfer->carrylf = 0; transfer->netascii = transfer->carrylf = 0;
prettyprint_addr(&peer, daemon->addrbuff); (void)prettyprint_addr(&peer, daemon->addrbuff);
/* if we have a nailed-down range, iterate until we find a free one. */ /* if we have a nailed-down range, iterate until we find a free one. */
while (!option_bool(OPT_SINGLE_PORT)) while (!option_bool(OPT_SINGLE_PORT))
{ {
if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 || if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, siz eof(mtuflag)) == -1 || setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, siz eof(mtuflag)) == -1 ||
#endif #endif
!fix_fd(transfer->sockfd)) !fix_fd(transfer->sockfd))
{ {
if (errno == EADDRINUSE && daemon->start_tftp_port != 0) if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
{ {
if (++port <= daemon->end_tftp_port) if (++port <= daemon->end_tftp_port)
{ {
if (listen->family == AF_INET) if (family == AF_INET)
addr.in.sin_port = htons(port); addr.in.sin_port = htons(port);
else else
addr.in6.sin6_port = htons(port); addr.in6.sin6_port = htons(port);
continue; continue;
} }
my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP")) ; my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP")) ;
} }
free_transfer(transfer); free_transfer(transfer);
return; return;
skipping to change at line 378 skipping to change at line 379
if (strcasecmp(mode, "netascii") == 0) if (strcasecmp(mode, "netascii") == 0)
transfer->netascii = 1; transfer->netascii = 1;
while ((opt = next(&p, end))) while ((opt = next(&p, end)))
{ {
if (strcasecmp(opt, "blksize") == 0) if (strcasecmp(opt, "blksize") == 0)
{ {
if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK)) if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
{ {
/* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */ /* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
int overhead = (listen->family == AF_INET) ? 32 : 52; int overhead = (family == AF_INET) ? 32 : 52;
transfer->blocksize = atoi(opt); transfer->blocksize = atoi(opt);
if (transfer->blocksize < 1) if (transfer->blocksize < 1)
transfer->blocksize = 1; transfer->blocksize = 1;
if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4) if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4; transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
if (mtu != 0 && transfer->blocksize > (unsigned)mtu - overhead) if (mtu != 0 && transfer->blocksize > (unsigned)mtu - overhead)
transfer->blocksize = (unsigned)mtu - overhead; transfer->blocksize = (unsigned)mtu - overhead;
transfer->opt_blocksize = 1; transfer->opt_blocksize = 1;
transfer->block = 0; transfer->block = 0;
} }
skipping to change at line 627 skipping to change at line 628
} }
if (len != 0) if (len != 0)
send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), daemon->pa cket, len, send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), daemon->pa cket, len,
&transfer->peer, &transfer->source, transfer->if_index); &transfer->peer, &transfer->source, transfer->if_index);
if (endcon || len == 0) if (endcon || len == 0)
{ {
strcpy(daemon->namebuff, transfer->file->filename); strcpy(daemon->namebuff, transfer->file->filename);
sanitise(daemon->namebuff); sanitise(daemon->namebuff);
prettyprint_addr(&transfer->peer, daemon->addrbuff); (void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff); my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
/* unlink */ /* unlink */
*up = tmp; *up = tmp;
if (endcon) if (endcon)
free_transfer(transfer); free_transfer(transfer);
else else
{ {
/* put on queue to be sent to script and deleted */ /* put on queue to be sent to script and deleted */
transfer->next = daemon->tftp_done_trans; transfer->next = daemon->tftp_done_trans;
daemon->tftp_done_trans = transfer; daemon->tftp_done_trans = transfer;
skipping to change at line 670 skipping to change at line 671
transfer->backoff = 0; transfer->backoff = 0;
if (transfer->block++ != 0) if (transfer->block++ != 0)
transfer->offset += transfer->blocksize - transfer->expansion; transfer->offset += transfer->blocksize - transfer->expansion;
} }
else if (ntohs(mess->op) == OP_ERR) else if (ntohs(mess->op) == OP_ERR)
{ {
char *p = daemon->packet + sizeof(struct ack); char *p = daemon->packet + sizeof(struct ack);
char *end = daemon->packet + len; char *end = daemon->packet + len;
char *err = next(&p, end); char *err = next(&p, end);
prettyprint_addr(&transfer->peer, daemon->addrbuff); (void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
/* Sanitise error message */ /* Sanitise error message */
if (!err) if (!err)
err = ""; err = "";
else else
sanitise(err); sanitise(err);
my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"), my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
(int)ntohs(mess->block), err, (int)ntohs(mess->block), err,
daemon->addrbuff); daemon->addrbuff);
 End of changes. 17 change blocks. 
18 lines changed or deleted 18 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)