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[] = {
33 // get sockaddr, IPv4 or IPv6:
34 static void *get_in_addr(struct sockaddr *sa)
36 if (sa->sa_family == AF_INET) {
37 return &(((struct sockaddr_in*)sa)->sin_addr);
40 return &(((struct sockaddr_in6*)sa)->sin6_addr);
43 static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
45 unsigned char *p = buf;
47 memcpy(&packet->magic[0], p, sizeof(packet->magic));
48 p += sizeof(packet->magic);
56 memcpy(&packet->event_id, p, sizeof(packet->event_id));
57 p += sizeof(packet->event_id);
58 packet->event_id = ntohl(packet->event_id);
60 memcpy(&packet->datalen, p, sizeof(packet->datalen));
61 p += sizeof(packet->datalen);
62 packet->datalen = ntohs(packet->datalen);
64 memcpy(&packet->data[0], p, packet->datalen);
73 struct addrinfo hints, *servinfo, *p;
76 struct sockaddr_storage their_addr;
79 char s[INET6_ADDRSTRLEN];
82 memset(&hints, 0, sizeof hints);
83 hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
84 hints.ai_socktype = SOCK_DGRAM;
86 if ((rv = getaddrinfo(NULL, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
87 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
91 // loop through all the results and bind to the first we can
92 for(p = servinfo; p != NULL; p = p->ai_next) {
93 if ((sockfd = socket(p->ai_family, p->ai_socktype,
94 p->ai_protocol)) == -1) {
95 perror("listener: socket");
99 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
101 perror("listener: bind");
109 fprintf(stderr, "listener: failed to bind socket\n");
113 freeaddrinfo(servinfo);
115 printf("listener: waiting to recvfrom...\n");
117 addr_len = sizeof their_addr;
119 struct fce_packet packet;
121 if ((numbytes = recvfrom(sockfd,
125 (struct sockaddr *)&their_addr,
131 unpack_fce_packet(buf, &packet);
133 if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) {
135 switch (packet.mode) {
137 printf("FCE Start\n");
140 case FCE_CONN_BROKEN:
141 printf("Broken FCE connection\n");
145 printf("ID: %" PRIu32 ", Event: %s, Path: %s\n",
146 packet.event_id, fce_ev_names[packet.mode], packet.data);