2 * FILE: $Header: /home/egg/src/RCS/genlib.c,v 1.6 1999/02/28 20:05:18 ghn Exp $
3 * PURPOSE: General library
9 * Revision 1.6 1999/02/28 20:05:18 ghn
10 * Version 5.1: Changed dquad2sockaddr interface to support ip/mm mask,
11 * created hl2dquad to translate host-long to dotted quad, and modified
12 * sockaddr2dquad to use this.
14 * Revision 1.5 1998/12/31 22:07:56 ghn
15 * Rev 5 code: includes multi-reg support, HTML, etc.
17 * Revision 1.4 1998/08/03 20:43:35 kelvin
18 * File byte-order independence.
20 * Revision 1.3 1998/08/01 18:51:25 ghn
21 * Added John's byte-order-independence changes.
23 * Revision 1.2 1998/08/01 17:07:29 ghn
24 * Casting fixes from John plus better parsing.
26 * Revision 1.1 1998/07/21 11:38:15 ghn
29 * Copyright 1998 - Greg Nelson
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/utsname.h>
41 uint32 getzulutime(struct timeval *ztv) {
45 gettimeofday(ztv, NULL);
48 gettimeofday(&ttv, NULL);
53 /* Get time difference (tv1-tv2) in msec. Only works if less than 24
55 int32 deltams(struct timeval *tv1, struct timeval *tv2) {
56 return (tv1->tv_sec - tv2->tv_sec) * 1000L +
57 (tv1->tv_usec - tv2->tv_usec) / 1000L;
60 /* Look up an EGG id. If we can't get it from environment, do a nutty
61 thing using CRC of uname block, which should be pretty unique. */
64 struct utsname utsname;
66 if ((idstr = getenv("EGGID")) != NULL) {
70 return BlockCRC16((byte *)(&utsname), sizeof(struct utsname));
74 char *Packetize(EggCarton *src) {
80 pktsize = (7 * sizeof(uint16)) + sizeof(trial) + /* Header */
81 sizeof(char) + /* ...including pad byte for trialsz */
82 (src->hdr.numrec * (sizeof(uint32) + /* Trial data */
83 src->hdr.samp_rec * sizeof(trial))) +
84 sizeof(uint32); /* CRC and terminator */
85 rbuf = pktP = (char *) malloc(pktsize);
87 /* Assemble header fields into data packet. */
89 pack16(src->hdr.type = DATA_PACKET);
90 pack16(src->hdr.pktsize = pktsize);
91 pack16(src->hdr.eggid);
92 pack16(src->hdr.samp_rec);
93 pack16(src->hdr.sec_rec);
94 pack16(src->hdr.rec_pkt);
95 pack8(0); /* Pad byte in case we want to expand trialsz */
96 pack8(src->hdr.trialsz);
97 pack16(src->hdr.numrec);
99 /* Append data records to packet. */
101 for (rec = 0; rec < src->hdr.numrec; rec++) {
102 pack32(src->records[rec].timestamp);
103 pack8s(&(src->records[rec].trials), src->hdr.samp_rec);
106 /* Get CRC, pack into base(32,32,64) notation, and add tag byte (0xFF) */
107 lbuf = BlockCRC16((byte *) rbuf, pktP - rbuf);
108 lbuf = ((lbuf & 0xF800) << 13) |
109 ((lbuf & 0x07C0) << 10) |
110 ((lbuf & 0x003F) << 8) |
114 if ((pktP - rbuf) != pktsize) {
115 fprintf(stderr, "Length mismatch assembling packet. Computed: %d, actually packed: %ld.\n",
116 pktsize, pktP - rbuf);
121 int32 Unpacketize(EggCarton *dst, char *src) {
125 uint32 lbuf, filecrc;
127 /* Unpack the portable header into a host-order and aligned
130 unpack16(dst->hdr.type);
131 unpack16(dst->hdr.pktsize);
132 unpack16(dst->hdr.eggid);
133 unpack16(dst->hdr.samp_rec);
134 unpack16(dst->hdr.sec_rec);
135 unpack16(dst->hdr.rec_pkt);
136 unpack8(pad); /* Pad in case we later grow trialsz */
137 unpack8(dst->hdr.trialsz);
138 unpack16(dst->hdr.numrec);
140 if (dst->hdr.type != DATA_PACKET) {
142 fprintf(stderr, "Invalid header type 0x%04X in packet read from file.\n", dst->hdr.type);
147 /* Unpack the data records from the file packet. */
149 for (rec = 0; rec < dst->hdr.numrec; rec++) {
150 unpack32(dst->records[rec].timestamp);
151 /* Assumes sizeof(trial) = 1 */
152 unpack8s(&(dst->records[rec].trials), dst->hdr.samp_rec);
155 /* Compute the CRC, reassemble into record terminator,
156 and compare with terminator in file. */
158 lbuf = BlockCRC16((byte *) src, pktP - src);
159 lbuf = ((lbuf & 0xF800) << 13) |
160 ((lbuf & 0x07C0) << 10) |
161 ((lbuf & 0x003F) << 8) |
166 if (lbuf != filecrc) {
168 fprintf(stderr, "Bad CRC in packet read from file. Read 0x%08X, computed 0x%08X.\n", filecrc, lbuf);
173 if (dst->hdr.pktsize != (pktP - src)) {
175 fprintf(stderr, "Length mismatch decoding packet. Header: %d, length decoded: %ld.\n",
176 dst->hdr.pktsize, pktP - src);
181 /* One final little tweak. Since we included a pad byte to allow
182 for growth in trialsz, hdr.pktsize will include it. Subtract
183 one to hide the existence of the pad in the file from the
184 caller. In all probability the caller isn't going to look at
185 pktsize, but you can't be too careful. */
192 void Parse(char *input, int *argc, char *argv[]) {
197 tp = strtok(input, " \t\n");
198 while (tp != NULL && *argc < MAX_PARSE) {
201 tp = strtok(NULL, " \t\n");
205 char *mallocpy(char *input) {
208 res = (char *)malloc(1+strlen(input));
209 if (res) strcpy(res, input);
213 void dquad2sockaddr(struct sockaddr_in *sinp, int16 *mask, char *dquad) {
218 loser = mallocpy(dquad);
220 tp = strtok(loser, ".");
221 for (qcount = 0, saddr = 0; qcount < 4 && tp != NULL; qcount++) {
222 saddr = (saddr << 8) | (atoi(tp) & 0xFF);
223 tp = strtok(NULL, ".");
227 strcpy(loser, dquad);
228 tp = strtok(loser, "/");
230 tp = strtok(NULL, "/");
231 if (tp) *mask = atoi(tp);
236 sinp->sin_family = AF_INET;
237 sinp->sin_port = 0; /* To be filled in later */
238 sinp->sin_addr.s_addr = htonl(saddr);
241 char *sockaddr2dquad(struct sockaddr_in *sinp) {
244 saddr = ntohl(sinp->sin_addr.s_addr);
245 return hl2dquad(saddr);
248 char *hl2dquad(uint32 addr) {
249 static char resout[16];
251 sprintf(resout, "%u.%u.%u.%u",
252 (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
253 (addr >> 8) & 0xFF, addr & 0xFF);