2 #include <sys/socket.h>
3 #include <netinet/in.h>
12 void con(char *name, int type, void *arg)
14 printf("conflicting name detected %s for type %d\n",name,type);
29 // create multicast 224.0.0.251:5353 socket
32 int s, flag = 1, ittl = 255;
33 struct sockaddr_in in;
37 bzero(&in, sizeof(in));
38 in.sin_family = AF_INET;
39 in.sin_port = htons(5353);
40 in.sin_addr.s_addr = 0;
42 if((s = socket(AF_INET,SOCK_DGRAM,0)) < 0) return 0;
44 setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char*)&flag, sizeof(flag));
46 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag));
47 if(bind(s,(struct sockaddr*)&in,sizeof(in))) { close(s); return 0; }
49 mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
50 mc.imr_interface.s_addr = htonl(INADDR_ANY);
51 setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mc, sizeof(mc));
52 setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
53 setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ittl, sizeof(ittl));
55 flag = fcntl(s, F_GETFL, 0);
57 fcntl(s, F_SETFL, flag);
62 int main(int argc, char *argv[])
68 unsigned short int port;
70 int bsize, ssize = sizeof(struct sockaddr_in);
71 unsigned char buf[MAX_PACKET_LEN];
72 struct sockaddr_in from, to;
75 unsigned char *packet, hlocal[256], nlocal[256];
79 if(argc < 4) { printf("usage: mhttp 'unique name' 12.34.56.78 80 '/optionalpath'\n"); return; }
81 ip = inet_addr(argv[2]);
83 printf("Announcing .local site named '%s' to %s:%d and extra path '%s'\n",argv[1],inet_ntoa(ip),port,argv[4]);
90 _d = d = mdnsd_new(1,1000);
91 if((s = msock()) == 0) { printf("can't create socket: %s\n",strerror(errno)); return 1; }
93 sprintf(hlocal,"%s._http._tcp.local.",argv[1]);
94 sprintf(nlocal,"http-%s.local.",argv[1]);
95 r = mdnsd_shared(d,"_http._tcp.local.",QTYPE_PTR,120);
96 mdnsd_set_host(d,r,hlocal);
97 r = mdnsd_unique(d,hlocal,QTYPE_SRV,600,con,0);
98 mdnsd_set_srv(d,r,0,0,port,nlocal);
99 r = mdnsd_unique(d,nlocal,QTYPE_A,600,con,0);
100 mdnsd_set_raw(d,r,(unsigned char *)&ip,4);
101 r = mdnsd_unique(d,hlocal,16,600,con,0);
103 if(argc == 5 && argv[4] && strlen(argv[4]) > 0) xht_set(h,"path",argv[4]);
104 packet = sd2txt(h, &len);
106 mdnsd_set_raw(d,r,packet,len);
113 FD_SET(_zzz[0],&fds);
115 select(s+1,&fds,0,0,tv);
117 // only used when we wake-up from a signal, shutting down
118 if(FD_ISSET(_zzz[0],&fds)) read(_zzz[0],buf,MAX_PACKET_LEN);
122 while((bsize = recvfrom(s,buf,MAX_PACKET_LEN,0,(struct sockaddr*)&from,&ssize)) > 0)
124 bzero(&m,sizeof(struct message));
125 message_parse(&m,buf);
126 mdnsd_in(d,&m,(unsigned long int)from.sin_addr.s_addr,from.sin_port);
128 if(bsize < 0 && errno != EAGAIN) { printf("can't read from socket %d: %s\n",errno,strerror(errno)); return 1; }
130 while(mdnsd_out(d,&m,&ip,&port))
132 bzero(&to, sizeof(to));
133 to.sin_family = AF_INET;
135 to.sin_addr.s_addr = ip;
136 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; }