2 #include <sys/socket.h>
3 #include <netinet/in.h>
18 void con(char *name, int type, void *arg)
20 printf("conflicting name detected %s for type %d\n",name,type);
35 // create multicast 224.0.0.251:5353 socket
38 int s, flag = 1, ittl = 255;
39 struct sockaddr_in in;
43 bzero(&in, sizeof(in));
44 in.sin_family = AF_INET;
45 in.sin_port = htons(5353);
46 in.sin_addr.s_addr = 0;
48 if((s = socket(AF_INET,SOCK_DGRAM,0)) < 0) return 0;
50 setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char*)&flag, sizeof(flag));
52 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag));
53 if(bind(s,(struct sockaddr*)&in,sizeof(in))) { close(s); return 0; }
55 mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
56 mc.imr_interface.s_addr = htonl(INADDR_ANY);
57 setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mc, sizeof(mc));
58 setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
59 setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ittl, sizeof(ittl));
61 flag = fcntl(s, F_GETFL, 0);
63 fcntl(s, F_SETFL, flag);
68 int main(int argc, char *argv[])
74 unsigned short int port;
76 int bsize, ssize = sizeof(struct sockaddr_in);
77 unsigned char buf[MAX_PACKET_LEN];
78 struct sockaddr_in from, to;
81 unsigned char *packet, hlocal[256], nlocal[256];
85 if(argc < 4) { printf("usage: mhttp 'unique name' 12.34.56.78 80 '/optionalpath'\n"); return -1; }
87 ip = inet_addr(argv[2]);
89 printf("Announcing .local site named '%s' to %s:%d and extra path '%s'\n",argv[1],argv[2],port,argv[4]);
96 _d = d = mdnsd_new(1,1000);
97 if((s = msock()) == 0) { printf("can't create socket: %s\n",strerror(errno)); return 1; }
99 sprintf(hlocal,"%s._http._tcp.local.",argv[1]);
100 sprintf(nlocal,"http-%s.local.",argv[1]);
101 r = mdnsd_shared(d,"_http._tcp.local.",QTYPE_PTR,120);
102 mdnsd_set_host(d,r,hlocal);
103 r = mdnsd_unique(d,hlocal,QTYPE_SRV,600,con,0);
104 mdnsd_set_srv(d,r,0,0,port,nlocal);
105 r = mdnsd_unique(d,nlocal,QTYPE_A,600,con,0);
106 mdnsd_set_raw(d,r,(unsigned char *)&ip,4);
107 r = mdnsd_unique(d,nlocal,QTYPE_A,600,con,0);
109 mdnsd_set_raw(d,r,(unsigned char *)&ip,4);
110 r = mdnsd_unique(d,hlocal,16,600,con,0);
112 if(argc == 5 && argv[4] && strlen(argv[4]) > 0) xht_set(h,"path",argv[4]);
113 packet = sd2txt(h, &len);
115 mdnsd_set_raw(d,r,packet,len);
122 fds[0].events = POLLIN;
125 fds[1].events = POLLIN;
127 poll (fds, 2, tv->tv_sec * 1000 + tv->tv_usec / 1000);
129 // only used when we wake-up from a signal, shutting down
130 if (fds[0].revents) read(_zzz[0],buf,MAX_PACKET_LEN);
134 while((bsize = recvfrom(s,buf,MAX_PACKET_LEN,0,(struct sockaddr*)&from,&ssize)) > 0)
136 bzero(&m,sizeof(struct message));
137 message_parse(&m,buf);
138 mdnsd_in(d,&m,(unsigned long int)from.sin_addr.s_addr,from.sin_port);
140 if(bsize < 0 && errno != EAGAIN) { printf("can't read from socket %d: %s\n",errno,strerror(errno)); return 1; }
142 while(mdnsd_out(d,&m,&ip,&port))
144 bzero(&to, sizeof(to));
145 to.sin_family = AF_INET;
147 to.sin_addr.s_addr = ip;
148 if(sendto(s,message_packet(&m),message_packet_len(&m),0,(struct sockaddr *)&to,sizeof(struct sockaddr_in)) != message_packet_len(&m)) { printf("can't write to socket: %s\n",strerror(errno)); return 1; }