]> arthur.barton.de Git - netatalk.git/blob - bin/misc/fce.c
0 terminate packet data
[netatalk.git] / bin / misc / fce.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif /* HAVE_CONFIG_H */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <netdb.h>
15 #include <inttypes.h>
16 #include <sys/types.h>
17 #include <sys/param.h>
18
19 #include <atalk/fce_api.h>
20 #include <atalk/util.h>
21
22 #define MAXBUFLEN 1024
23
24 static char *fce_ev_names[] = {
25     "",
26     "FCE_FILE_MODIFY",
27     "FCE_FILE_DELETE",
28     "FCE_DIR_DELETE",
29     "FCE_FILE_CREATE",
30     "FCE_DIR_CREATE"
31 };
32
33 // get sockaddr, IPv4 or IPv6:
34 static void *get_in_addr(struct sockaddr *sa)
35 {
36     if (sa->sa_family == AF_INET) {
37         return &(((struct sockaddr_in*)sa)->sin_addr);
38     }
39
40     return &(((struct sockaddr_in6*)sa)->sin6_addr);
41 }
42
43 static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
44 {
45     unsigned char *p = buf;
46
47     memcpy(&packet->magic[0], p, sizeof(packet->magic));
48     p += sizeof(packet->magic);
49
50     packet->version = *p;
51     p++;
52
53     packet->mode = *p;
54     p++;
55
56     memcpy(&packet->event_id, p, sizeof(packet->event_id));
57     p += sizeof(packet->event_id);
58     packet->event_id = ntohl(packet->event_id);
59
60     memcpy(&packet->datalen, p, sizeof(packet->datalen));
61     p += sizeof(packet->datalen);
62     packet->datalen = ntohs(packet->datalen);
63
64     memcpy(&packet->data[0], p, packet->datalen);
65     packet->data[packet->datalen] = 0; /* 0 terminate strings */
66     p += packet->datalen;
67
68     return 0;
69 }
70
71 int main(void)
72 {
73     int sockfd;
74     struct addrinfo hints, *servinfo, *p;
75     int rv;
76     int numbytes;
77     struct sockaddr_storage their_addr;
78     char buf[MAXBUFLEN];
79     socklen_t addr_len;
80     char s[INET6_ADDRSTRLEN];
81     uint64_t tmsize;
82
83     memset(&hints, 0, sizeof hints);
84     hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
85     hints.ai_socktype = SOCK_DGRAM;
86
87     if ((rv = getaddrinfo(NULL, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
88         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
89         return 1;
90     }
91
92     // loop through all the results and bind to the first we can
93     for(p = servinfo; p != NULL; p = p->ai_next) {
94         if ((sockfd = socket(p->ai_family, p->ai_socktype,
95                              p->ai_protocol)) == -1) {
96             perror("listener: socket");
97             continue;
98         }
99
100         if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
101             close(sockfd);
102             perror("listener: bind");
103             continue;
104         }
105
106         break;
107     }
108
109     if (p == NULL) {
110         fprintf(stderr, "listener: failed to bind socket\n");
111         return 2;
112     }
113
114     freeaddrinfo(servinfo);
115
116     printf("listener: waiting to recvfrom...\n");
117
118     addr_len = sizeof their_addr;
119
120     struct fce_packet packet;
121     while (1) {
122         if ((numbytes = recvfrom(sockfd,
123                                  buf,
124                                  MAXBUFLEN - 1,
125                                  0,
126                                  (struct sockaddr *)&their_addr,
127                                  &addr_len)) == -1) {
128             perror("recvfrom");
129             exit(1);
130         }
131
132         unpack_fce_packet(buf, &packet);
133
134         if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) {
135
136             switch (packet.mode) {
137             case FCE_CONN_START:
138                 printf("FCE Start\n");
139                 break;
140
141             case FCE_CONN_BROKEN:
142                 printf("Broken FCE connection\n");
143                 break;
144
145             default:
146                 printf("ID: %" PRIu32 ", Event: %s, Path: %s\n",
147                        packet.event_id, fce_ev_names[packet.mode], packet.data);
148                 break;
149             }
150         }
151     }
152
153     close(sockfd);
154     return 0;
155 }