1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZParseNotice function.
4 * Created by: Robert French
6 * $Id: ZParseNot.c 2344 2009-03-24 03:40:55Z kcr $
8 * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file
14 static const char rcsid_ZParseNotice_c[] =
15 "$Zephyr: /mit/zephyr/src/lib/RCS/ZParseNotice.c,v 1.22 91/03/29 03:34:46 raeburn Exp $";
20 /* Skip to the next NUL-terminated field in the packet. */
25 while (ptr < end && *ptr != '\0')
33 ZParseNotice(char *buffer,
39 int maj, numfields, i;
43 /* Note: This definition of BAD eliminates lint and compiler
44 * complains about the "while (0)", but require that the macro not
45 * be used as the "then" part of an "if" statement that also has
48 #define BAD_PACKET {lineno=__LINE__;goto badpkt;}
49 /* This one gets lint/compiler complaints. */
50 /*#define BAD do{lineno=__LINE__;goto badpkt;}while(0)*/
52 #define BAD_PACKET goto badpkt
55 (void) memset((char *)notice, 0, sizeof(ZNotice_t));
60 notice->z_packet = buffer;
62 notice->z_version = ptr;
63 if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1))
65 ptr += sizeof(ZVERSIONHDR) - 1;
68 Z_debug ("ZParseNotice: null version string");
73 if (maj != ZVERSIONMAJOR)
75 ptr = next_field(ptr, end);
77 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
80 notice->z_num_hdr_fields = numfields;
81 ptr = next_field(ptr, end);
84 numfields -= 2; /* numfields, version, and checksum */
90 Z_debug ("ZParseNotice: bad packet from %s/%d (line %d)",
91 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
92 notice->z_port, lineno);
97 Z_debug ("ZParseNotice: bad packet from %s/%d",
98 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
105 if (numfields && ptr < end) {
106 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
108 notice->z_kind = (ZNotice_Kind_t)temp;
110 ptr = next_field(ptr, end);
115 if (numfields && ptr < end) {
116 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid,
117 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
119 notice->z_time.tv_sec = ntohl((u_long) notice->z_uid.tv.tv_sec);
120 notice->z_time.tv_usec = ntohl((u_long) notice->z_uid.tv.tv_usec);
122 ptr = next_field(ptr, end);
127 if (numfields && ptr < end) {
128 if (ZReadAscii16(ptr, end-ptr, ¬ice->z_port) == ZERR_BADFIELD)
130 notice->z_port = htons(notice->z_port);
132 ptr = next_field(ptr, end);
137 if (numfields && ptr < end) {
138 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
140 notice->z_auth = temp;
142 ptr = next_field(ptr, end);
146 notice->z_checked_auth = ZAUTH_UNSET;
148 if (numfields && ptr < end) {
149 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
151 notice->z_authent_len = temp;
153 ptr = next_field(ptr, end);
158 if (numfields && ptr < end) {
159 notice->z_ascii_authent = ptr;
161 ptr = next_field(ptr, end);
166 if (numfields && ptr < end) {
167 notice->z_class = ptr;
169 ptr = next_field(ptr, end);
172 notice->z_class = "";
174 if (numfields && ptr < end) {
175 notice->z_class_inst = ptr;
177 ptr = next_field(ptr, end);
180 notice->z_class_inst = "";
182 if (numfields && ptr < end) {
183 notice->z_opcode = ptr;
185 ptr = next_field(ptr, end);
188 notice->z_opcode = "";
190 if (numfields && ptr < end) {
191 notice->z_sender = ptr;
193 ptr = next_field(ptr, end);
196 notice->z_sender = "";
198 if (numfields && ptr < end) {
199 notice->z_recipient = ptr;
201 ptr = next_field(ptr, end);
204 notice->z_recipient = "";
206 if (numfields && ptr < end) {
207 notice->z_default_format = ptr;
209 ptr = next_field(ptr, end);
212 notice->z_default_format = "";
214 if (numfields && ptr < end) {
215 notice->z_ascii_checksum = ptr;
217 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
218 notice->z_checksum = 0;
220 notice->z_checksum = temp;
223 ptr = next_field (ptr, end);
227 notice->z_ascii_checksum = "";
228 notice->z_checksum = 0;
231 if (numfields && ptr < end) {
232 notice->z_multinotice = ptr;
234 ptr = next_field(ptr, end);
237 notice->z_multinotice = "";
239 if (numfields && ptr < end) {
240 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid,
241 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
243 notice->z_time.tv_sec = ntohl((u_long) notice->z_multiuid.tv.tv_sec);
244 notice->z_time.tv_usec = ntohl((u_long) notice->z_multiuid.tv.tv_usec);
246 ptr = next_field(ptr, end);
249 notice->z_multiuid = notice->z_uid;
251 if (numfields && ptr < end) {
252 /* we will take it on faith that ipv6 addresses are longer than ipv4
254 unsigned char addrbuf[sizeof(notice->z_sender_sockaddr.ip6.sin6_addr)];
257 /* because we're paranoid about naughtily misformated packets */
258 if (memchr(ptr, '\0', end - ptr) == NULL)
262 if (ZReadZcode((unsigned char *)ptr, addrbuf,
263 sizeof(addrbuf), &len) == ZERR_BADFIELD)
266 len = sizeof(notice->z_sender_sockaddr.ip4.sin_addr);
267 if (ZReadAscii(ptr, end - ptr, (unsigned char *)addrbuf,
268 len) == ZERR_BADFIELD)
272 if (len == sizeof(notice->z_sender_sockaddr.ip6.sin6_addr)) {
273 notice->z_sender_sockaddr.ip6.sin6_family = AF_INET6;
274 memcpy(¬ice->z_sender_sockaddr.ip6.sin6_addr, addrbuf, len);
275 } else if (len == sizeof(notice->z_sender_sockaddr.ip4.sin_addr)) {
276 notice->z_sender_sockaddr.ip4.sin_family = AF_INET;
277 memcpy(¬ice->z_sender_sockaddr.ip4.sin_addr, addrbuf, len);
282 ptr = next_field(ptr, end);
284 memset(¬ice->z_sender_sockaddr, 0,
285 sizeof notice->z_sender_sockaddr);
286 notice->z_sender_sockaddr.ip4.sin_family = AF_INET;
287 notice->z_sender_sockaddr.ip4.sin_addr = notice->z_uid.zuid_addr;
290 if (numfields && ptr < end) {
291 if (ZReadAscii16(ptr, end-ptr, ¬ice->z_charset) == ZERR_BADFIELD)
293 notice->z_charset = htons(notice->z_charset);
296 ptr = next_field(ptr, end);
298 notice->z_charset = ZCHARSET_UNKNOWN;
300 for (i=0;ptr < end && i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) {
301 notice->z_other_fields[i] = ptr;
302 ptr = next_field(ptr, end);
304 notice->z_num_other_fields = i;
306 for (i=0;ptr < end && numfields;numfields--)
307 ptr = next_field(ptr, end);
309 if (numfields || *(ptr - 1) != '\0')
312 notice->z_message = (caddr_t) ptr;
313 notice->z_message_len = len-(ptr-buffer);