3 #endif /* HAVE_CONFIG_H */
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
16 #include <sys/types.h>
17 #include <sys/param.h>
19 #include <atalk/fce_api.h>
20 #include <atalk/util.h>
22 #define MAXBUFLEN 1024
24 static char *fce_ev_names[] = {
37 static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
39 unsigned char *p = buf;
44 memcpy(&packet->fcep_magic[0], p, sizeof(packet->fcep_magic));
45 p += sizeof(packet->fcep_magic);
47 packet->fcep_version = *p++;
49 if (packet->fcep_version > 1)
50 packet->fcep_options = *p++;
52 packet->fcep_event = *p++;
54 if (packet->fcep_version > 1)
58 if (packet->fcep_version > 1)
62 memcpy(&packet->fcep_event_id, p, sizeof(packet->fcep_event_id));
63 p += sizeof(packet->fcep_event_id);
64 packet->fcep_event_id = ntohl(packet->fcep_event_id);
66 if (packet->fcep_options & FCE_EV_INFO_PID) {
67 memcpy(&packet->fcep_pid, p, sizeof(packet->fcep_pid));
68 packet->fcep_pid = hton64(packet->fcep_pid);
69 p += sizeof(packet->fcep_pid);
72 if (packet->fcep_options & FCE_EV_INFO_USER) {
73 memcpy(&packet->fcep_userlen, p, sizeof(packet->fcep_userlen));
74 packet->fcep_userlen = ntohs(packet->fcep_userlen);
75 p += sizeof(packet->fcep_userlen);
77 memcpy(&packet->fcep_user[0], p, packet->fcep_userlen);
78 packet->fcep_user[packet->fcep_userlen] = 0; /* 0 terminate strings */
79 p += packet->fcep_userlen;
83 memcpy(&packet->fcep_pathlen1, p, sizeof(packet->fcep_pathlen1));
84 p += sizeof(packet->fcep_pathlen1);
85 packet->fcep_pathlen1 = ntohs(packet->fcep_pathlen1);
87 memcpy(&packet->fcep_path1[0], p, packet->fcep_pathlen1);
88 packet->fcep_path1[packet->fcep_pathlen1] = 0; /* 0 terminate strings */
89 p += packet->fcep_pathlen1;
91 if (packet->fcep_options & FCE_EV_INFO_SRCPATH) {
92 memcpy(&packet->fcep_pathlen2, p, sizeof(packet->fcep_pathlen2));
93 p += sizeof(packet->fcep_pathlen2);
94 packet->fcep_pathlen2 = ntohs(packet->fcep_pathlen2);
95 memcpy(&packet->fcep_path2[0], p, packet->fcep_pathlen2);
96 packet->fcep_path2[packet->fcep_pathlen2] = 0; /* 0 terminate strings */
97 p += packet->fcep_pathlen2;
103 int main(int argc, char **argv)
106 struct addrinfo hints, *servinfo, *p;
108 struct sockaddr_storage their_addr;
111 char s[INET6_ADDRSTRLEN];
112 char *host = "localhost";
114 while ((c = getopt(argc, argv, "h:")) != -1) {
117 host = strdup(optarg);
122 memset(&hints, 0, sizeof hints);
123 hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
124 hints.ai_socktype = SOCK_DGRAM;
126 if ((rv = getaddrinfo(host, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
127 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
131 // loop through all the results and bind to the first we can
132 for(p = servinfo; p != NULL; p = p->ai_next) {
133 if ((sockfd = socket(p->ai_family, p->ai_socktype,
134 p->ai_protocol)) == -1) {
135 perror("listener: socket");
139 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
141 perror("listener: bind");
149 fprintf(stderr, "listener: failed to bind socket\n");
153 freeaddrinfo(servinfo);
155 printf("listener: waiting to recvfrom...\n");
157 addr_len = sizeof their_addr;
159 struct fce_packet packet;
161 if ((numbytes = recvfrom(sockfd,
165 (struct sockaddr *)&their_addr,
171 unpack_fce_packet((unsigned char *)buf, &packet);
173 if (memcmp(packet.fcep_magic, FCE_PACKET_MAGIC, sizeof(packet.fcep_magic)) == 0) {
175 switch (packet.fcep_event) {
177 printf("FCE Start\n");
180 case FCE_CONN_BROKEN:
181 printf("Broken FCE connection\n");
185 printf("ID: %" PRIu32 ", Event: %s", packet.fcep_event_id, fce_ev_names[packet.fcep_event]);
186 if (packet.fcep_options & FCE_EV_INFO_PID)
187 printf(", pid: %" PRId64, packet.fcep_pid);
188 if (packet.fcep_options & FCE_EV_INFO_USER)
189 printf(", user: %s", packet.fcep_user);
191 if (packet.fcep_options & FCE_EV_INFO_SRCPATH)
192 printf(", source: %s", packet.fcep_path2);
194 printf(", Path: %s\n", packet.fcep_path1);