10 #include <netinet/ether.h>
11 #include <sys/ioctl.h>
22 __attribute__((noreturn)) void handler (int sig) {
39 int main (int argc, char **argv) {
42 socklen_t slen=sizeof(struct sockaddr_in);
43 struct sockaddr_in local, client;
44 struct ether_addr localmac;
45 struct in_addr localip;
48 unsigned char ports=8;
57 printf("Usage: %s <interface>\n", argv[0]);
61 memset(&local, 0, sizeof(struct sockaddr_in));
62 local.sin_family=AF_INET;
64 local.sin_addr.s_addr=htonl(INADDR_ANY);
65 local.sin_port=htons(SWITCH_PORT);
67 memset(&ifr, 0, sizeof(struct ifreq));
68 strncpy(ifr.ifr_name, argv[1], IFNAMSIZ-1);
71 np.maxlen=sizeof(buffer);
73 if ( (sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))<0 ) {
75 } else if ( bind(sock, (struct sockaddr*)&local, sizeof(struct sockaddr_in))<0 ) {
80 if ( setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i))<0 ) {
81 perror("setsockopt(SO_BROADCAST)");
86 if ( setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &i, sizeof(i)) ) {
87 perror("setsockopt(IP_MULTICAST_LOOP)");
92 if ( ioctl(sock, SIOCGIFHWADDR, &ifr)<0 ) {
93 perror("ioctl(SIOCGIFHWADDR)");
95 memcpy(&localmac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
97 if ( ioctl(sock, SIOCGIFADDR, &ifr)<0 ) {
98 perror("ioctl(SIOCGIFADDR)");
100 localip=(*(struct sockaddr_in*)&ifr.ifr_addr).sin_addr;
103 printf("server: ip %s, mac %s\n", inet_ntoa(localip), ether_ntoa(&localmac));
105 signal(SIGINT, handler);
106 signal(SIGTERM, handler);
111 if ( (len=recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&client, &slen))<0 ) {
116 if ( len<(int)sizeof(struct ng_header) || ( memcmp(&np.nh->switch_mac, &nullMac, 6)!=0 && memcmp(&np.nh->switch_mac, &localmac, 6)!=0 ) ) {
120 printf("received %d bytes from %s: \n", len, inet_ntoa(client.sin_addr));
122 printf("code: %i\n", np.nh->code);
123 printf("client mac: %s\n", ether_ntoa((struct ether_addr*)np.nh->client_mac));
124 printf("seq num: %d\n", ntohl(np.nh->seqnum));
127 memcpy(np.nh->switch_mac, &localmac, ETH_ALEN);
130 l=extractPacketAttributes(&np);
135 switch ( np.nh->code ) {
139 for (ln=l->first; ln!=NULL; ln=ln->next) {
142 switch ( at->attr ) {
145 strcpy(np.ah->data, "NgEmu");
146 addPacketAttr(&np, ATTR_PRODUCT, strlen(np.ah->data), NULL);
150 addPacketShortAttr(&np, ATTR_UNK2, 0);
154 strcpy(np.ah->data, "netgear switch emulator");
155 addPacketAttr(&np, ATTR_NAME, strlen(np.ah->data), NULL);
159 memcpy(np.ah->data, &localmac, ETH_ALEN);
160 addPacketAttr(&np, ATTR_MAC, ETH_ALEN, NULL);
164 memset(np.ah->data, 0, 64);
165 addPacketAttr(&np, ATTR_UNK5, 64, NULL);
169 *(struct in_addr*)np.ah->data=localip;
170 addPacketAttr(&np, ATTR_IP, 4, NULL);
174 *(in_addr_t*)np.ah->data=inet_addr("255.255.255.0");
175 addPacketAttr(&np, ATTR_NETMASK, 4, NULL);
179 *(in_addr_t*)np.ah->data=inet_addr("192.168.0.16");
180 addPacketAttr(&np, ATTR_GATEWAY, 4, NULL);
184 addPacketShortAttr(&np, ATTR_DHCP, 1);
188 addPacketByteAttr(&np, ATTR_UNK12, 1);
192 strcpy(np.ah->data, "NgAdmin 0.0.1");
193 addPacketAttr(&np, ATTR_FIRM_VER, strlen(np.ah->data), NULL);
197 addPacketByteAttr(&np, ATTR_UNK15, 1);
200 case ATTR_PORTS_NUMBER:
201 addPacketByteAttr(&np, ATTR_PORTS_NUMBER, ports);
204 case ATTR_PORT_STATUS:
205 for (i=1; i<=ports; i++) {
208 case 0: np.ah->data[2]=0; np.ah->data[1]=0; break;
209 case 1: np.ah->data[2]=1; np.ah->data[1]=SPEED_10; break;
210 case 2: np.ah->data[2]=1; np.ah->data[1]=SPEED_100; break;
211 case 3: np.ah->data[2]=1; np.ah->data[1]=SPEED_1000;
213 addPacketAttr(&np, ATTR_PORT_STATUS, 3, NULL);
218 addPacketByteAttr(&np, ATTR_QOS_TYPE, QOS_PORT);
221 case ATTR_QOS_CONFIG:
222 for (i=1; i<=(int)ports; i++) {
224 np.ah->data[1]=(i&3)+1;
225 addPacketAttr(&np, ATTR_QOS_CONFIG, 2, NULL);
230 addPacketByteAttr(&np, 0x5400, 0);
234 case 0x1000: // System -> Monitoring -> Port Statistics
236 for (i=1; i<=(int)ports; i++) {
237 memset(np.ah->data, 0, len);
238 addPacketAttr(&np, 0x1000, len, NULL);
244 np.ah->data[0]=ports;
246 len=(ports>>3)+((ports&7)!=0);
247 *(unsigned int*)&np.ah->data[2]=0;
248 for (i=0; i<ports-1; i+=2) {
249 np.ah->data[2+(i>>3)] |= 1<<(7-(i&7)) ;
251 addPacketAttr(&np, ATTR_MIRROR, 2+len, NULL);
255 addPacketByteAttr(&np, ATTR_VLAN_TYPE, VLAN_DOT_ADV);
264 addPacketEmptyAttr(&np, at->attr);
270 np.nh->code=CODE_READ_REP;
271 len=getPacketTotalSize(&np);
276 np.nh->code=CODE_WRITE_REP;
280 printf("unkown code\n");
285 destroyList(l, (void(*)(void*))freeAttr);
287 client.sin_addr.s_addr=htonl(INADDR_BROADCAST);
288 client.sin_port=htons(CLIENT_PORT);
289 if ( sendto(sock, buffer, len, 0, (struct sockaddr*)&client, sizeof(struct sockaddr))<0 ) {