]> git.sur5r.net Git - ngadmin/blob - spy/src/spy.c
Cli: switch to filename completion after terminal commands
[ngadmin] / spy / src / spy.c
1
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <poll.h>
5 #include <signal.h>
6 #include <arpa/inet.h>
7
8 #include <nsdp/protocol.h>
9 #include <nsdp/attr.h>
10 #include <nsdp/net.h>
11
12
13 static const char* code_str (unsigned char code)
14 {
15         switch (code) {
16         
17         case CODE_READ_REQ:
18                 return "read request";
19         
20         case CODE_READ_REP:
21                 return "read reply";
22         
23         case CODE_WRITE_REQ:
24                 return "write request";
25         
26         case CODE_WRITE_REP:
27                 return "write reply";
28         
29         default:
30                 return "unknown";
31         }
32 }
33
34
35 static const char* error_str (unsigned char err)
36 {
37         switch (err) {
38         
39         case 0:
40                 return "none";
41         
42         case ERROR_READONLY:
43                 return "read only";
44         
45         case ERROR_INVALID_VALUE:
46                 return "invalid value";
47         
48         case ERROR_DENIED:
49                 return "access denied";
50         
51         default:
52                 return "unknown";
53         }
54 }
55
56
57 static void print_packet (const List *attr, const struct nsdp_cmd *nc)
58 {
59         const ListNode *ln;
60         const struct attr *at;
61         
62         
63         printf("---------------------------------\n");
64         printf("code = %s (%u)\n", code_str(nc->code), nc->code);
65         printf("error = %s (%u)\n", error_str(nc->error), nc->error);
66         if (nc->attr_error != 0)
67                 printf("erroneous attribute = %04X\n", nc->attr_error);
68         printf("source address = %s:%u\n", inet_ntoa(nc->remote_addr.sin_addr), ntohs(nc->remote_addr.sin_port));
69         printf("client MAC = %s\n", ether_ntoa(&nc->client_mac));
70         printf("switch MAC = %s\n", ether_ntoa(&nc->switch_mac));
71         printf("sequence number = %u\n\n", nc->seqnum);
72         printf("received %d attribute(s)\n", attr->count);
73         
74         for (ln = attr->first; ln != NULL; ln = ln->next) {
75                 at = ln->data;
76                 printf("received attribute code = %04X, length = %d\n", at->attr, at->size);
77         }
78         
79         printf("---------------------------------\n\n");
80 }
81
82
83 static void handler (int sig)
84 {
85         (void)sig;
86         printf("interrupt\n");
87 }
88
89
90 int main (void)
91 {
92         int err = 0, sw_sock = -1, cl_sock = -1;
93         List *attr;
94         struct nsdp_cmd nc;
95         struct sockaddr_in sw_local, cl_local;
96         struct pollfd fds[2];
97         struct sigaction sa;
98         
99         
100         sw_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
101         if (sw_sock < 0) {
102                 perror("socket");
103                 err = 1;
104                 goto end;
105         };
106         
107         cl_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
108         if (cl_sock < 0) {
109                 perror("socket");
110                 err = 1;
111                 goto end;
112         };
113         
114         
115         memset(&sw_local, 0, sizeof(struct sockaddr_in));
116         sw_local.sin_family = AF_INET;
117         sw_local.sin_addr.s_addr = htonl(INADDR_ANY);
118         sw_local.sin_port = htons(SWITCH_PORT);
119         
120         cl_local = sw_local;
121         cl_local.sin_port = htons(CLIENT_PORT);
122         
123         if (bind(sw_sock, (struct sockaddr*)&sw_local, sizeof(struct sockaddr_in)) < 0) {
124                 perror("bind");
125                 err = 2;
126                 goto end;
127         }
128         
129         if (bind(cl_sock, (struct sockaddr*)&cl_local, sizeof(struct sockaddr_in)) < 0) {
130                 perror("bind");
131                 err = 2;
132                 goto end;
133         }
134         
135         fds[0].fd = sw_sock;
136         fds[0].events = POLLIN;
137         fds[0].revents = 0;
138         fds[1].fd = cl_sock;
139         fds[1].events = POLLIN;
140         fds[1].revents = 0;
141         
142         memset(&sa, 0, sizeof(struct sigaction));
143         sa.sa_handler = handler;
144         sigaction(SIGINT, &sa, NULL);
145         sigaction(SIGTERM, &sa, NULL);
146         
147         attr = createEmptyList();
148         
149         while (1) {
150                 err = poll(fds, 2, -1);
151                 if (err < 0) {
152                         perror("poll");
153                         break;
154                 } else if (err == 0) {
155                         continue;
156                 }
157                 
158                 memset(&nc, 0, sizeof(struct nsdp_cmd));
159                 nc.remote_addr.sin_family = AF_INET;
160                 
161                 if (fds[0].revents & POLLIN) {
162                         nc.remote_addr.sin_port = htons(CLIENT_PORT);
163                         err = recvNsdpPacket(sw_sock, &nc, attr, NULL);
164                 } else {
165                         nc.remote_addr.sin_port = htons(SWITCH_PORT);
166                         err = recvNsdpPacket(cl_sock, &nc, attr, NULL);
167                 }
168                 
169                 if (err < 0)
170                         continue;
171                 
172                 print_packet(attr, &nc);
173                 
174                 clearList(attr, (void(*)(void*))freeAttr);
175         }
176         
177         destroyList(attr, (void(*)(void*))freeAttr);
178         
179 end:
180         close(sw_sock);
181         close(cl_sock);
182         
183         return err;
184 }
185