int errno; typedef /*signed*/ char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef int int32_t; typedef unsigned int uint32_t; struct timespec {long tv_sec, tv_nsec;}; #define SI_LOAD_SHIFT 16 struct sysinfo { long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ unsigned short pad; /* explicit padding for m68k */ unsigned long totalhigh; /* Total high memory size */ unsigned long freehigh; /* Available high memory size */ unsigned int mem_unit; /* Memory unit size in bytes */ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */ }; #include "../proto/xmon-proto-1.h" #define htonl(a) ((((a) & 0xFF000000)>>24) | (((a) & 0xFF0000)>>8) | (((a) & 0xFF00)<<8) | (((a) & 0xFF)<<24)) #define htons(a) ((((a) & 0xFF00)>>8) | (((a) & 0xFF)<<8)) #define SYS_SENDTO 11 /* sys_sendto(2) */ #define SYS_RECVFROM 12 /* sys_recvfrom(2) */ #define __NR_socketcall 102 #define __NR_sysinfo 116 #define __NR_nanosleep 162 #define ECONNREFUSED 111 /* Connection refused */ #define NULL ((void *)0) #define __syscall_return(type, res) \ do { \ if ((unsigned long)(res) >= (unsigned long)(-125)) { \ errno = -(res); \ res = -1; \ } \ return (type) (res); \ } while (0) #define _syscall1mem(type,name,type1,arg1) \ type name(type1 arg1) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)) \ : "memory" ); \ __syscall_return(type,__res); \ } #define _syscall2mem(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)) \ : "memory" ); \ __syscall_return(type,__res); \ } #define _syscall2(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)) \ ); \ __syscall_return(type,__res); \ } static inline _syscall1mem(int,sysinfo,struct sysinfo *,info) static inline _syscall2mem(int,socketcall,int,call,unsigned long *,args) static inline _syscall2(int,nanosleep,struct timespec *,rqtp, struct timespec *,rmtp) typedef unsigned short sa_family_t; struct sockaddr { sa_family_t sa_family; /* address family, AF_xxx */ char sa_data[14]; /* 14 bytes of protocol address */ }; static inline int recvfrom(int fd, void *msg, int len, unsigned int flags, const struct sockaddr *from, int *fromlen) { unsigned long buf[6]; buf[0]=fd; buf[1]=(unsigned long)msg; buf[2]=len; buf[3]=flags; buf[4]=(unsigned long)from; buf[5]=(unsigned long)fromlen; return socketcall(SYS_RECVFROM, buf); } static inline int sendto(int fd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen) { unsigned long buf[6]; buf[0]=fd; buf[1]=(unsigned long)msg; buf[2]=len; buf[3]=flags; buf[4]=(unsigned long)to; buf[5]=tolen; return socketcall(SYS_SENDTO, buf); } int main(void) { struct sockaddr from; struct request request; struct reply xmsysinfo; struct reply xmerr; int bytes, fromlen; struct timespec delay={0, 100000000}; xmerr.status=htonl(XM_STATUS_ERR); xmerr.magic=htonl(XM_MAGIC); xmerr.calltype=htonl(XM_REPLY); xmsysinfo.status=htonl(XM_STATUS_OK); xmsysinfo.opcode=htonl(XM_OP_SYSINFO); xmsysinfo.magic=htonl(XM_MAGIC); xmsysinfo.calltype=htonl(XM_REPLY); xmsysinfo.t.sysinfo.flags=htonl(XM_SYSINFO_ALLFLAGS); again: fromlen=sizeof(from); nanosleep(&delay, NULL); bytes=recvfrom(0, &request, sizeof(request), 0, &from, &fromlen); if (bytes==-1 && errno!=ECONNREFUSED) return 1; if (bytes<20) goto again; if (request.magic!=htonl(XM_MAGIC)) goto again; if (request.calltype!=htonl(XM_REQUEST)) goto again; if (request.version!=htonl(XM_VERSION)) { xmerr.t.err.reason=htonl(XM_ERR_WRONGVER); goto senderr; } if (request.opcode==htonl(XM_OP_SYSINFO)) { struct sysinfo info; xmerr.t.err.reason=htonl(XM_ERR_FAULT); if (sysinfo(&info)) goto senderr; xmsysinfo.xid=request.xid; xmsysinfo.t.sysinfo.uptime=htonl(info.uptime); xmsysinfo.t.sysinfo.loads[0]=htonl(info.loads[0]); xmsysinfo.t.sysinfo.loads[1]=htonl(info.loads[1]); xmsysinfo.t.sysinfo.loads[2]=htonl(info.loads[2]); xmsysinfo.t.sysinfo.totalram=htonl(info.totalram); xmsysinfo.t.sysinfo.freeram=htonl(info.freeram); xmsysinfo.t.sysinfo.sharedram=htonl(info.sharedram); xmsysinfo.t.sysinfo.bufferram=htonl(info.bufferram); xmsysinfo.t.sysinfo.totalswap=htonl(info.totalswap); xmsysinfo.t.sysinfo.freeswap=htonl(info.freeswap); xmsysinfo.t.sysinfo.procs=htonl(info.procs); sendto(0, &xmsysinfo, 20+sizeof(struct reply_sysinfo), 0, &from, fromlen); goto again; } xmerr.t.err.reason=htonl(XM_ERR_UNKNOWNOP); senderr: xmerr.xid=request.xid; xmerr.opcode=request.opcode; sendto(0, &xmerr, 20+sizeof(struct reply_err), 0, &from, fromlen); goto again; }