1 /*======================================================================*
2 * Copyright (c) 2008, Yahoo! Inc. All rights reserved. *
4 * Licensed under the New BSD License (the "License"); you may not use *
5 * this file except in compliance with the License. Unless required *
6 * by applicable law or agreed to in writing, software distributed *
7 * under the License is distributed on an "AS IS" BASIS, WITHOUT *
8 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
9 * See the License for the specific language governing permissions and *
10 * limitations under the License. See accompanying LICENSE file. *
11 *======================================================================*/
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
28 #define ntohll(x) ( ( (uint64_t)(ntohl( (uint32_t)((x << 32) >> 32) )) << 32) | ntohl( ((uint32_t)(x >> 32)) ) )
30 void header_add(void* buf
, int count
, unsigned long long tm
, unsigned long addr
, unsigned short port
)
32 unsigned char* cp
= (unsigned char*)buf
;
34 marshal_short(cp
, count
); /* Size of message body. */
35 marshal_ulong_long(cp
, tm
); /* Now in msec. */
36 marshal_long(cp
, addr
); /* Sender IP address. */
37 marshal_short(cp
, port
); /* Sender port number. */
38 marshal_short(cp
, arg_site
); /* Site ID number */
39 /* TODO: should be perfectly alright, but un-QA'd marshal_long(cp, 0); */
43 int header_is_rotate (void* buf
)
45 return toknam_eq((unsigned char *)buf
+ HEADER_LENGTH
,
46 (unsigned char *)ROTATE_COMMAND
);
47 LOG_PROG("Command::Rotate message received.\n");
50 void header_fingerprint(void* buf
, struct packet_check
* pc
)
52 unsigned char* cp
= (unsigned char*)buf
;
54 unsigned long long tm
;
57 /* Extract the timestamp. */
58 unmarshal_short(cp
, length
);
59 unmarshal_ulong_long(cp
, tm
);
61 /* Add phony timestamp of zero. */
63 marshal_long_long(cp
, zero
);
66 /* pc->md5 = md5(); */
69 /////////////////////////////////////////////////////////////////////////////
70 // It's a small thing, but toknam_eq() is quicker than memcmp().
71 // * memcmp does a tremendous amount of setup before comparing the first
72 // character (it's designed to compare large strings efficently)
73 // * we don't care if greater-than or less-than, just equal or not
74 // * syntactically simpler (taking advantage of token's length byte)
75 int toknam_eq(const unsigned char* toknam
, const unsigned char* nam
)
77 unsigned char len
= *nam
+1 ;
78 while ( *toknam
++ == *nam
++ )
84 /////////////////////////////////////////////////////////////////////////////
86 void header_print (const char* buf
)
88 LOG_INF("header payload length: %u\n", header_payload_length(buf
));
89 LOG_INF("receipt time: %llu\n", header_receipt_time(buf
));
90 LOG_INF("now: %llu\n", time(NULL
)*1000L);
91 LOG_INF("sender IP text: %s\n", header_sender_ip_formatted(buf
));
92 LOG_INF("sender port: %u\n", header_sender_port(buf
));
93 LOG_INF("site id: %u\n", header_site_id(buf
));
96 static uint16_t header_uint16(const char* bytes
) {
97 return ntohs(*((uint16_t*) bytes
));
100 static uint32_t header_uint32(const char* bytes
) {
101 return ntohl(*((uint32_t*) bytes
));
104 static uint64_t header_uint64(const char* bytes
) {
105 return (((uint64_t)header_uint32(bytes
))<<32) | header_uint32(bytes
+4);
108 uint16_t header_payload_length(const char* header
)
110 return header_uint16(header
);
113 uint64_t header_receipt_time(const char* header
) {
114 return header_uint64(header
+RECEIPT_TIME_OFFSET
);
117 const char* header_sender_ip_formatted(const char* header
) {
118 struct in_addr addr
= { header_uint32(header
+SENDER_IP_OFFSET
) };
119 return inet_ntoa(addr
);
122 uint16_t header_sender_port(const char* header
) {
123 return header_uint16(header
+SENDER_PORT_OFFSET
);
126 uint16_t header_site_id(const char* header
) {
127 return header_uint16(header
+SITE_ID_OFFSET
);