Retire MINIX irdpd(8)

Change-Id: Id11c6db9db5da18346d993cb9c3faa4313ed3ed4
This commit is contained in:
David van Moolenbroek 2017-02-14 18:38:28 +00:00
parent f130137a5e
commit 9cf227216d
10 changed files with 6 additions and 770 deletions

View File

@ -388,7 +388,7 @@
./usr/bin/install minix-base
./usr/bin/ipcrm minix-base
./usr/bin/ipcs minix-base
./usr/bin/irdpd minix-base
./usr/bin/irdpd minix-base obsolete
./usr/bin/isodir minix-base
./usr/bin/isoinfo minix-base
./usr/bin/isoread minix-base

View File

@ -305,7 +305,7 @@
./usr/libdata/debug/usr/bin/install.debug minix-debug debug
./usr/libdata/debug/usr/bin/ipcrm.debug minix-debug debug
./usr/libdata/debug/usr/bin/ipcs.debug minix-debug debug
./usr/libdata/debug/usr/bin/irdpd.debug minix-debug debug
./usr/libdata/debug/usr/bin/irdpd.debug minix-debug debug,obsolete
./usr/libdata/debug/usr/bin/isoread.debug minix-debug debug
./usr/libdata/debug/usr/bin/join.debug minix-debug debug
./usr/libdata/debug/usr/bin/jot.debug minix-debug debug

View File

@ -3406,7 +3406,7 @@
./usr/man/man8/init.8 minix-man
./usr/man/man8/installboot_nbsd.8 minix-man
./usr/man/man8/intr.8 minix-man
./usr/man/man8/irdpd.8 minix-man
./usr/man/man8/irdpd.8 minix-man obsolete
./usr/man/man8/link.8 minix-man
./usr/man/man8/loadramdisk.8 minix-man
./usr/man/man8/makefs.8 minix-man

View File

@ -8,8 +8,7 @@
CPPFLAGS.fslib.c+= -I${NETBSDSRCDIR}/minix/fs
CPPFLAGS.fsversion.c+= -I${NETBSDSRCDIR}/minix/fs
SRCS+= fsversion.c gcov.c itoa.c \
oneC_sum.c read_tsc_64.c fslib.c
SRCS+= fsversion.c gcov.c itoa.c read_tsc_64.c fslib.c
.endif # defined(__MINIX)
.PATH: ${ARCHDIR}/gen ${.CURDIR}/gen

View File

@ -12,7 +12,7 @@ SUBDIR= at backup \
fix format fsck.mfs \
gcov-pull \
ifdef \
intr irdpd isoread \
intr isoread \
loadkeys loadramdisk logger look lp \
lpd lspci mail MAKEDEV \
minix-service mount mt netconf \

View File

@ -1,4 +0,0 @@
PROG= irdpd
MAN= irdpd.8
.include <bsd.prog.mk>

View File

@ -1,74 +0,0 @@
.TH IRDPD 8
.SH NAME
irdpd \- internet router discovery protocol daemon
.SH SYNOPSIS
.B irdpd
.RB [ \-bd ]
.RB [ \-U
.IR udp-device ]
.RB [ \-I
.IR ip-device ]
.RB [ \-o
.IR priority-offset ]
.SH DESCRIPTION
.B Irdpd
looks for routers. This should be a simple task, but some routers are hard
to find because they do not implement the router discovery protocol. This
daemon collects information that routers do send out and makes it available.
.PP
At startup
.B irdpd
sends out several router solicitation broadcasts. A good router should
respond to this with a router advertisement.
.PP
If a router advertisement arrives then no more solicitations are sent. The
TCP/IP server has filled its routing table with the info from the
advertisement, so it now has at least one router. If the advertisement is
sent by a genuine router (the sender is in the table) then the
.B irdpd
daemon goes dormant for the time the advert is valid. Routers send new
adverts periodically, keeping the daemon silent.
.PP
Otherwise
.B irdpd
will listen for RIP (Router Information Protocol) packets. These packets
are sent between routers to exchange routing information.
.B Irdpd
uses this information to build a routing table.
.PP
Every now and then a router advertisement is sent to the local host to give
it router information build from the RIP packets.
.SH OPTIONS
.TP
.B \-b
Broadcast advertisements instead of sending them to the local host only.
This may be used to keep (non-Minix) hosts alive on a net without adverts.
.TP
.B \-d
Debug mode, tell where info is coming from and where it is sent. Debugging
can also be turned on at runtime by sending signal
.B SIGUSR1
or turned off with
.BR SIGUSR2 .
.TP
.BI \-o " priority-offset
Offset used to make the gateway's preferences collected from RIP packets look
worse than those found in genuine router adverts. By default
.BR -1024 .
.SH "SEE ALSO"
.BR inet (8),
.BR boot (8),
.BR dhcpd (8),
.BR inetd (8),
.BR nonamed (8).
.SH BUGS
This daemon has gone out of favour thanks to
.BR dhcpd ,
that also does router solicitations among other things.
.PP
Under standard MINIX 3 this daemon can't listen to both IRDP and RIP
at the same time, so it starts out with IRDP. It switches over to RIP
if it can't find a router, or if it threatens to lose its router. It
does not switch back.
.SH AUTHOR
Kees J. Bot (kjb@cs.vu.nl)

View File

@ -1,624 +0,0 @@
/* irdpd 1.10 - Internet router discovery protocol daemon.
* Author: Kees J. Bot
* 28 May 1994
* Activily solicitate or passively look for routers.
* Based heavily on its forerunners, the irdp_sol and rip2icmp daemons by
* Philip Homburg.
*/
#define nil 0
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/asynchio.h>
#include <net/hton.h>
#include <net/netlib.h>
#include <net/gen/in.h>
#include <net/gen/ip_hdr.h>
#include <net/gen/icmp.h>
#include <net/gen/icmp_hdr.h>
#include <net/gen/ip_io.h>
#include <net/gen/inet.h>
#include <netdb.h>
#include <net/gen/oneCsum.h>
#include <net/gen/socket.h>
#include <net/gen/udp.h>
#include <net/gen/udp_hdr.h>
#include <net/gen/udp_io.h>
#include <arpa/inet.h>
#define MAX_SOLICITATIONS 3 /* # router solicitations. */
#define SOLICITATION_INTERVAL 3 /* Secs between solicitate retries. */
#define DEST_TO (10*60) /* 10 minutes */
#define NEW_ROUTE (5*60) /* 5 minutes */
#define DANGER (2*60) /* Nearing a advert timeout? */
#define DEAD_TO (24L*60*60) /* 24 hours */
#define DEAD_PREF 0x80000000L /* From RFC 1256 */
#define MaxAdvertisementInterval (DEST_TO/2) /* Chosen to jive with RIP */
#define AdvertisementLifetime DEST_TO
#define PRIO_OFF_DEF -1024
#define RIP_REPLY 2
/* It's now or never. */
#define IMMEDIATELY ((time_t) ((time_t) -1 < 0 ? LONG_MIN : 0))
#define NEVER ((time_t) ((time_t) -1 < 0 ? LONG_MAX : ULONG_MAX))
#if !__minix_vmd
/* Standard Minix needs to choose between router discovery and RIP info. */
int do_rdisc= 1;
int do_rip= 0;
#else
/* VMD Minix can do both at once. */
#define do_rdisc 1
#define do_rip 1
#endif
int rip_fd; /* For incoming RIP packet. */
int irdp_fd; /* Receive or transmit IRDP packets. */
char *udp_device; /* UDP device to use. */
char *ip_device; /* IP device to use. */
int priority_offset; /* Offset to make my routes less preferred. */
int bcast= 0; /* Broadcast adverts to all. */
int debug= 0;
char rip_buf[8192]; /* Incoming RIP packet buffer. */
char irdp_buf[1024]; /* IRDP buffer. */
typedef struct routeinfo
{
u8_t command;
u8_t version;
u16_t zero1;
struct routedata {
u16_t family;
u16_t zero2;
u32_t ip_addr;
u32_t zero3, zero4;
u32_t metric;
} data[1];
} routeinfo_t;
typedef struct table
{
ipaddr_t tab_gw;
i32_t tab_pref;
time_t tab_time;
} table_t;
table_t *table; /* Collected table of routing info. */
size_t table_size;
int sol_retries= MAX_SOLICITATIONS;
time_t next_sol= IMMEDIATELY;
time_t next_advert= NEVER;
time_t router_advert_valid= IMMEDIATELY;
time_t now;
void report(const char *label)
/* irdpd: /dev/hd0: Device went up in flames */
{
fprintf(stderr, "irdpd: %s: %s\n", label, strerror(errno));
}
void fatal(const char *label)
/* irdpd: /dev/house: Taking this with it */
{
report(label);
exit(1);
}
#if DEBUG
char *addr2name(ipaddr_t host)
/* Translate an IP address to a printable name. */
{
struct hostent *hostent;
hostent= gethostbyaddr((char *) &host, sizeof(host), AF_INET);
return hostent == nil ? inet_ntoa(host) : hostent->h_name;
}
#else
#define addr2name(host) inet_ntoa(*(struct in_addr *)&(host))
#endif
void print_table(void)
/* Show the collected routing table. */
{
int i;
table_t *ptab;
struct tm *tm;
for (i= 0, ptab= table; i < table_size; i++, ptab++) {
if (ptab->tab_time < now - DEAD_TO) continue;
tm= localtime(&ptab->tab_time);
printf("%-40s %6ld %02d:%02d:%02d\n",
addr2name(ptab->tab_gw),
(long) ptab->tab_pref,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
}
void advertize(ipaddr_t host)
/* Send a router advert to a host. */
{
char *buf, *data;
ip_hdr_t *ip_hdr;
icmp_hdr_t *icmp_hdr;
int i;
table_t *ptab;
buf= malloc(sizeof(*ip_hdr) + offsetof(icmp_hdr_t, ih_dun.uhd_data)
+ table_size * (sizeof(ipaddr_t) + sizeof(u32_t)));
if (buf == nil) fatal("heap error");
ip_hdr= (ip_hdr_t *) buf;
icmp_hdr= (icmp_hdr_t *) (ip_hdr + 1);
ip_hdr->ih_vers_ihl= 0x45;
ip_hdr->ih_dst= host;
icmp_hdr->ih_type= ICMP_TYPE_ROUTER_ADVER;
icmp_hdr->ih_code= 0;
icmp_hdr->ih_hun.ihh_ram.iram_na= 0;
icmp_hdr->ih_hun.ihh_ram.iram_aes= 2;
icmp_hdr->ih_hun.ihh_ram.iram_lt= htons(AdvertisementLifetime);
data= (char *) icmp_hdr->ih_dun.uhd_data;
/* Collect gateway entries from the table. */
for (i= 0, ptab= table; i < table_size; i++, ptab++) {
if (ptab->tab_time < now - DEAD_TO) continue;
icmp_hdr->ih_hun.ihh_ram.iram_na++;
if (ptab->tab_time < now - DEST_TO) ptab->tab_pref= DEAD_PREF;
* (ipaddr_t *) data= ptab->tab_gw;
data+= sizeof(ipaddr_t);
* (i32_t *) data= htonl(ptab->tab_pref);
data+= sizeof(i32_t);
}
icmp_hdr->ih_chksum= 0;
icmp_hdr->ih_chksum= ~oneC_sum(0, icmp_hdr, data - (char *) icmp_hdr);
if (icmp_hdr->ih_hun.ihh_ram.iram_na > 0) {
/* Send routing info. */
if (debug) {
printf("Routing table send to %s:\n", addr2name(host));
print_table();
}
if (write(irdp_fd, buf, data - buf) < 0) {
(errno == EIO ? fatal : report)(ip_device);
}
}
free(buf);
}
void time_functions(void)
/* Perform time dependend functions: router solicitation, router advert. */
{
if (now >= next_sol) {
char buf[sizeof(ip_hdr_t) + 8];
ip_hdr_t *ip_hdr;
icmp_hdr_t *icmp_hdr;
if (sol_retries == 0) {
/* Stop soliciting. */
next_sol= NEVER;
#if !__minix_vmd
/* Switch to RIP if no router responded. */
if (table_size == 0) {
do_rip= 1;
do_rdisc= 0;
}
#endif
return;
}
/* Broadcast a router solicitation to find a router. */
ip_hdr= (ip_hdr_t *) buf;
icmp_hdr= (icmp_hdr_t *) (ip_hdr + 1);
ip_hdr->ih_vers_ihl= 0x45;
ip_hdr->ih_dst= htonl(0xFFFFFFFFL);
icmp_hdr->ih_type= ICMP_TYPE_ROUTE_SOL;
icmp_hdr->ih_code= 0;
icmp_hdr->ih_chksum= 0;
icmp_hdr->ih_hun.ihh_unused= 0;
icmp_hdr->ih_chksum= ~oneC_sum(0, icmp_hdr, 8);
if (debug) printf("Broadcasting router solicitation\n");
if (write(irdp_fd, buf, sizeof(buf)) < 0)
fatal("sending router solicitation failed");
/* Schedule the next packet. */
next_sol= now + SOLICITATION_INTERVAL;
sol_retries--;
}
if (now >= next_advert) {
/* Advertize routes to the local host (normally), or
* broadcast them (to keep bad hosts up.)
*/
advertize(bcast ? htonl(0xFFFFFFFFL) : htonl(0x7F000001L));
next_advert= now + MaxAdvertisementInterval;
#if !__minix_vmd
/* Make sure we are listening to RIP now. */
do_rip= 1;
do_rdisc= 0;
#endif
}
}
void add_gateway(ipaddr_t host, i32_t pref)
/* Add a router with given address and preference to the routing table. */
{
table_t *oldest, *ptab;
int i;
/* Look for the host, or select the oldest entry. */
oldest= nil;
for (i= 0, ptab= table; i < table_size; i++, ptab++) {
if (ptab->tab_gw == host) break;
if (oldest == nil || ptab->tab_time < oldest->tab_time)
oldest= ptab;
}
/* Don't evict the oldest if it is still valid. */
if (oldest != nil && oldest->tab_time >= now - DEST_TO) oldest= nil;
/* Expand the table? */
if (i == table_size && oldest == nil) {
table_size++;
table= realloc(table, table_size * sizeof(*table));
if (table == nil) fatal("heap error");
oldest= &table[table_size - 1];
}
if (oldest != nil) {
ptab= oldest;
ptab->tab_gw= host;
ptab->tab_pref= DEAD_PREF;
}
/* Replace an entry if the new one looks more promising. */
if (pref >= ptab->tab_pref || ptab->tab_time <= now - NEW_ROUTE) {
ptab->tab_pref= pref;
ptab->tab_time= now;
}
}
void rip_incoming(ssize_t n)
/* Use a RIP packet to add to the router table. (RIP packets are really for
* between routers, but often it is the only information around.)
*/
{
udp_io_hdr_t *udp_io_hdr;
u32_t default_dist;
i32_t pref;
routeinfo_t *routeinfo;
struct routedata *data, *end;
/* We don't care about RIP packets when there are router adverts. */
if (now + MaxAdvertisementInterval < router_advert_valid) return;
udp_io_hdr= (udp_io_hdr_t *) rip_buf;
if (udp_io_hdr->uih_data_len != n - sizeof(*udp_io_hdr)) {
if (debug) printf("Bad sized route packet (discarded)\n");
return;
}
routeinfo= (routeinfo_t *) (rip_buf + sizeof(*udp_io_hdr)
+ udp_io_hdr->uih_ip_opt_len);
if (routeinfo->command != RIP_REPLY) {
if (debug) {
printf("RIP-%d packet command %d ignored\n",
routeinfo->version, routeinfo->command);
}
return;
}
/* Look for a default route, the route to the gateway. */
end= (struct routedata *) (rip_buf + n);
default_dist= (u32_t) -1;
for (data= routeinfo->data; data < end; data++) {
if (ntohs(data->family) != AF_INET || data->ip_addr != 0)
continue;
default_dist= ntohl(data->metric);
if (default_dist >= 256) {
if (debug) {
printf("Strange metric %lu\n",
(unsigned long) default_dist);
}
}
}
pref= default_dist >= 256 ? 1 : 512 - default_dist;
pref+= priority_offset;
/* Add the gateway to the table with the calculated preference. */
add_gateway(udp_io_hdr->uih_src_addr, pref);
if (debug) {
printf("Routing table after RIP-%d packet from %s:\n",
routeinfo->version,
addr2name(udp_io_hdr->uih_src_addr));
print_table();
}
/* Start advertizing. */
if (next_advert == NEVER) next_advert= IMMEDIATELY;
}
void irdp_incoming(ssize_t n)
/* Look for router solicitations and router advertisements. The solicitations
* are probably from other irdpd daemons, we answer them if we do not expect
* a real router to answer. The advertisements cause this daemon to shut up.
*/
{
ip_hdr_t *ip_hdr;
icmp_hdr_t *icmp_hdr;
int ip_hdr_len;
char *data;
int i;
int router;
ipaddr_t addr;
i32_t pref;
time_t valid;
ip_hdr= (ip_hdr_t *) irdp_buf;
ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;
if (n < ip_hdr_len + 8) {
if (debug) printf("Bad sized ICMP (discarded)\n");
return;
}
icmp_hdr= (icmp_hdr_t *)(irdp_buf + ip_hdr_len);
/* Did I send this myself? */
if (ip_hdr->ih_src == ip_hdr->ih_dst) return;
if ((htonl(ip_hdr->ih_src) & 0xFF000000L) == 0x7F000000L) return;
if (icmp_hdr->ih_type != ICMP_TYPE_ROUTER_ADVER) return;
/* Incoming router advertisement, the kind of packet the TCP/IP task
* is very happy with. No need to solicit further.
*/
sol_retries= 0;
/* Add router info to our table. Also see if the packet really came
* from a router. If so then we can go dormant for the lifetime of
* the ICMP.
*/
router= 0;
data= (char *) icmp_hdr->ih_dun.uhd_data;
for (i= 0; i < icmp_hdr->ih_hun.ihh_ram.iram_na; i++) {
addr= * (ipaddr_t *) data;
data+= sizeof(ipaddr_t);
pref= htonl(* (i32_t *) data);
data+= sizeof(i32_t);
if (addr == ip_hdr->ih_src) {
/* The sender is in the routing table! */
router= 1;
}
add_gateway(addr, pref);
}
valid= now + ntohs(icmp_hdr->ih_hun.ihh_ram.iram_lt);
if (router) router_advert_valid= valid;
/* Restart advertizing close to the timeout of the advert. (No more
* irdpd adverts if the router stays alive.)
*/
if (router || next_advert > valid - DANGER)
next_advert= valid - DANGER;
if (debug) {
printf("Routing table after advert received from %s:\n",
addr2name(ip_hdr->ih_src));
print_table();
if (router) {
struct tm *tm= localtime(&router_advert_valid);
printf(
"This router advert is valid until %02d:%02d:%02d\n",
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
}
}
void sig_handler(int sig)
/* A signal changes the debug level. */
{
switch (sig) {
case SIGUSR1: debug++; break;
case SIGUSR2: debug= 0; break;
}
}
void usage(void)
{
fprintf(stderr,
"Usage: irdpd [-bd] [-U udp-device] [-I ip-device] [-o priority-offset]\n");
exit(1);
}
int main(int argc, char **argv)
{
int i;
struct servent *service;
udpport_t route_port;
nwio_udpopt_t udpopt;
nwio_ipopt_t ipopt;
asynchio_t asyn;
time_t timeout;
struct timeval tv;
struct sigaction sa;
char *offset_arg, *offset_end;
long arg;
udp_device= ip_device= nil;
offset_arg= nil;
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
char *p= argv[i] + 1;
if (p[0] == '-' && p[1] == 0) { i++; break; }
while (*p != 0) {
switch (*p++) {
case 'U':
if (udp_device != nil) usage();
if (*p == 0) {
if (++i == argc) usage();
p= argv[i];
}
udp_device= p;
p= "";
break;
case 'I':
if (ip_device != nil) usage();
if (*p == 0) {
if (++i == argc) usage();
p= argv[i];
}
ip_device= p;
p= "";
break;
case 'o':
if (offset_arg != nil) usage();
if (*p == 0) {
if (++i == argc) usage();
p= argv[i];
}
offset_arg= p;
p= "";
break;
case 'b':
bcast= 1;
break;
case 's':
/*obsolete*/
break;
case 'd':
debug= 1;
break;
default:
usage();
}
}
}
if (i != argc) usage();
/* Debug level signals. */
sa.sa_handler= sig_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags= 0;
sigaction(SIGUSR1, &sa, nil);
sigaction(SIGUSR2, &sa, nil);
if (udp_device == nil && (udp_device= getenv("UDP_DEVICE")) == nil)
udp_device= UDP_DEVICE;
if (ip_device == nil && (ip_device= getenv("IP_DEVICE")) == nil)
ip_device= IP_DEVICE;
if (offset_arg == nil) {
priority_offset= PRIO_OFF_DEF;
} else {
arg= strtol(offset_arg, &offset_end, 0);
if (*offset_end != 0 || (priority_offset= arg) != arg) usage();
}
if ((service= getservbyname("route", "udp")) == nil) {
fprintf(stderr,
"irdpd: unable to look up the port number for the 'route' service\n");
exit(1);
}
route_port= (udpport_t) service->s_port;
if ((rip_fd= open(udp_device, O_RDWR)) < 0) fatal(udp_device);
udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SET | NWUO_DI_LOC
| NWUO_EN_BROAD | NWUO_RP_SET | NWUO_RA_ANY | NWUO_RWDATALL
| NWUO_DI_IPOPT;
udpopt.nwuo_locport= route_port;
udpopt.nwuo_remport= route_port;
if (ioctl(rip_fd, NWIOSUDPOPT, &udpopt) < 0)
fatal("setting UDP options failed");
if ((irdp_fd= open(ip_device, O_RDWR)) < 0) fatal(ip_device);
ipopt.nwio_flags= NWIO_COPY | NWIO_EN_LOC | NWIO_EN_BROAD
| NWIO_REMANY | NWIO_PROTOSPEC
| NWIO_HDR_O_SPEC | NWIO_RWDATALL;
ipopt.nwio_tos= 0;
ipopt.nwio_ttl= 1;
ipopt.nwio_df= 0;
ipopt.nwio_hdropt.iho_opt_siz= 0;
ipopt.nwio_rem= htonl(0xFFFFFFFFL);
ipopt.nwio_proto= IPPROTO_ICMP;
if (ioctl(irdp_fd, NWIOSIPOPT, &ipopt) < 0)
fatal("can't configure ICMP channel");
asyn_init(&asyn);
while (1) {
ssize_t r;
if (do_rip) {
/* Try a RIP read. */
r= asyn_read(&asyn, rip_fd, rip_buf, sizeof(rip_buf));
if (r < 0) {
if (errno == EIO) fatal(udp_device);
if (errno != EINPROGRESS) report(udp_device);
} else {
now= time(nil);
rip_incoming(r);
}
}
if (do_rdisc) {
/* Try an IRDP read. */
r= asyn_read(&asyn, irdp_fd, irdp_buf,
sizeof(irdp_buf));
if (r < 0) {
if (errno == EIO) fatal(ip_device);
if (errno != EINPROGRESS) report(ip_device);
} else {
now= time(nil);
irdp_incoming(r);
}
}
fflush(stdout);
/* Compute the next wakeup call. */
timeout= next_sol < next_advert ? next_sol : next_advert;
/* Wait for a RIP or IRDP packet or a timeout. */
tv.tv_sec= timeout;
tv.tv_usec= 0;
if (asyn_wait(&asyn, 0, timeout == NEVER ? nil : &tv) < 0) {
/* Timeout? */
if (errno != EINTR && errno != EAGAIN)
fatal("asyn_wait()");
now= time(nil);
time_functions();
}
}
}

View File

@ -1,61 +0,0 @@
/* oneC_sum() - One complement's checksum Author: Kees J. Bot
* 8 May 1995
* See RFC 1071, "Computing the Internet checksum"
*/
#include <sys/types.h>
#include <net/gen/oneCsum.h>
u16_t oneC_sum(u16_t prev, void *data, size_t size)
{
u8_t *dptr;
size_t n;
u16_t word;
u32_t sum;
int swap= 0;
sum= prev;
dptr= data;
n= size;
swap= ((size_t) dptr & 1);
if (swap) {
sum= ((sum & 0xFF) << 8) | ((sum & 0xFF00) >> 8);
if (n > 0) {
((u8_t *) &word)[0]= 0;
((u8_t *) &word)[1]= dptr[0];
sum+= (u32_t) word;
dptr+= 1;
n-= 1;
}
}
while (n >= 8) {
sum+= (u32_t) ((u16_t *) dptr)[0]
+ (u32_t) ((u16_t *) dptr)[1]
+ (u32_t) ((u16_t *) dptr)[2]
+ (u32_t) ((u16_t *) dptr)[3];
dptr+= 8;
n-= 8;
}
while (n >= 2) {
sum+= (u32_t) ((u16_t *) dptr)[0];
dptr+= 2;
n-= 2;
}
if (n > 0) {
((u8_t *) &word)[0]= dptr[0];
((u8_t *) &word)[1]= 0;
sum+= (u32_t) word;
}
sum= (sum & 0xFFFF) + (sum >> 16);
if (sum > 0xFFFF) sum++;
if (swap) {
sum= ((sum & 0xFF) << 8) | ((sum & 0xFF00) >> 8);
}
return sum;
}

View File

@ -217,7 +217,7 @@ CPPFLAGS.tolower_.c+= -I${LIBCDIR}/locale
CPPFLAGS.toupper_.c+= -I${LIBCDIR}/locale
.for f in \
read_tsc_64.o fslib.o itoa.o oneC_sum.o
read_tsc_64.o fslib.o itoa.o
${f} ${f:C/\.o/.bc/}: ${LIBMINIXCDIR}/gen/${f:C/\.o/.c/}
${f} ${f:C/\.o/.go/}: ${LIBMINIXCDIR}/gen/${f:C/\.o/.c/}
OBJS+= ${f}