1 /* brpvc.c -- client for managing RFC2684 bridge-encapsulation VCs.
3 written by Chuck Musser <chuckie@well.com>
6 #include <stdio.h> /* printf, read, write, etc. */
7 #include <stdlib.h> /* malloc, exit, etc. */
8 #include <unistd.h> /* getopt, atoi */
9 #include <errno.h> /* system errors */
10 #include <sys/un.h> /* unix domain sockets */
11 #include <sys/types.h> /* u_int32_t, etc. */
12 #include <pwd.h> /* getpwuid, etc. */
14 #include "atm.h" /* general ATM stuff */
15 #include "atmbr2684.h" /* ATM bridging structs */
23 extern int optind, opterr, optopt;
25 void clean_exit (char *str)
34 int unix_connect(void)
38 struct sockaddr_un addr;
40 if( (fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
41 clean_exit("Can't create client socket");
43 bzero(&addr, sizeof(addr));
44 addr.sun_family = AF_LOCAL;
45 strncpy(addr.sun_path, BRPVC_SOCKPATH, sizeof(addr.sun_path) -1);
47 if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)))
48 clean_exit("Can't connect to server");
50 bzero(&msg, sizeof(msg));
53 if( send(fd, &msg, sizeof(msg), 0) < 0 )
54 clean_exit("Can't send HELLO message");
56 if( recv(fd, &msg, sizeof(msg), 0) <= 0 )
57 clean_exit("Can't receive receive OK response from server");
62 void usage(int exitval)
64 printf("usage: bctl -a -v <[intf].vpi.vci> -i <nas #> [-c count] [-g group name]\n");
65 printf(" bctl -d -v <[intf].vpi.vci> -i <nas #> [-c count] [-g group name]\n");
66 printf(" bctl -d -d group name\n");
67 printf(" bctl -l [-d group name]\n");
74 int pvc2684ctl_main (int argc, char **argv)
76 int main (int argc, char **argv)
79 int optchar, action = 0, count = 1, starting_nas_idx = -1,
80 t2a_err, srv_fd, nbytes, header = 0;
82 char name[MAX_GROUPNAME_LEN] = {};
83 struct be_msg smsg, rmsg;
84 struct be_memstat rstatmsg;
85 struct sockaddr_atmpvc vc;
88 int encap=BR2684_ENCAPS_LLC, proto_filter=0, mode=0;
89 unsigned short vlan_id=-1;
91 bzero(&vc, sizeof(vc));
94 optchar = getopt(argc, argv, "Madli:v:c:g:erft:");
102 srv_fd = unix_connect();
103 smsg.msgtype = MEM_STATS;
105 if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
106 clean_exit("Can't send MEM_STAT message");
108 nbytes = recv(srv_fd, &rstatmsg, sizeof(rstatmsg), 0);
110 clean_exit("connection closed waiting for MEM_STAT response\n");
112 clean_exit("Can't receive MEM_STAT response");
114 printf("VC mallocs: %d\nVC frees: %d\nGroup mallocs: %d\nGroup frees:%d\n",
115 rstatmsg.vc_mallocs,rstatmsg.vc_frees,
116 rstatmsg.group_mallocs,rstatmsg.group_frees);
129 starting_nas_idx = strtol(optarg, &endptr, 10);
130 if(*endptr || starting_nas_idx < 0) {
131 printf("Invalid interface index specified\n");
138 if((t2a_err = (text2atm(optarg, (struct sockaddr *)&vc, sizeof(vc), T2A_PVC)))) {
139 printf ("can't parse \"%s\".\n", optarg);
145 retval = sscanf(optarg, "%d.%d.%d", num, num+1, num+2);
146 starting_nas_idx = OFFSET*num[1]+num[2];
151 count = strtol(optarg, &endptr, 10);
152 if(*endptr || count <= 0) {
153 printf("Invalid count specified\n");
160 encap=BR2684_ENCAPS_VC;
165 proto_filter = FILTER_PPPOE;
172 // brcm add vlan id flag
174 vlan_id = atoi(optarg);
178 strncpy(name,optarg,MAX_GROUPNAME_LEN);
185 printf ("getopt returned char %c\n", optchar);
190 for(; hasname>0; hasname--) {
191 if(name[hasname] != '\0') break;
199 if(vc.sap_family == AF_ATMPVC) {
201 if(starting_nas_idx < 0) {
203 /* If you specify a PVC, you must specify an interface too */
204 printf("No interface specified. Use the -i option.\n");
208 } else if(action == 'a') {
210 /* If this is an ADD, you need to specify the PVC. */
211 printf("No VC specified. Use the -v option.\n");
214 } else if (!hasname) {
216 /* If it's not an ADD, it must be a DELETE. You need at least a name. */
217 printf("No VC or VC group name specified. Use the -v or -g options.\n");
222 /* If we're here, no VC was specified, it's a DELETE and a group
223 name was specified. Send a DELETE_GROUP message and exit.
226 bzero(&rmsg, sizeof(rmsg));
227 srv_fd = unix_connect();
228 smsg.msgtype = DELETE_GROUP;
229 strncpy(smsg.name,name,MAX_GROUPNAME_LEN);
231 if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
232 clean_exit("Can't send DELETE_GROUP message");
234 nbytes = recv(srv_fd, &rmsg, sizeof(rmsg), 0);
236 clean_exit("connection closed waiting for DELETE_GROUP response\n");
238 clean_exit("Can't receive response to DELETE_GROUP message");
240 if(rmsg.msgtype == GROUP_NOT_FOUND)
241 printf("group \"%s\" doesn't exist\n", name);
246 smsg.msgtype = (action == 'a' ? ADD : DELETE);
247 smsg.nas_idx = starting_nas_idx;
249 strncpy(smsg.name,name,MAX_GROUPNAME_LEN);
252 smsg.proto_filter = proto_filter;
254 smsg.vlan_id = vlan_id;
256 bzero(&rmsg, sizeof(rmsg));
257 srv_fd = unix_connect();
261 if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
262 clean_exit("Can't send ADD or DELETE message");
264 nbytes = recv(srv_fd, &rmsg, sizeof(rmsg), 0);
266 clean_exit("connection closed waiting for ADD or DELETE response\n");
268 clean_exit("Can't receive response to ADD or DELETE message");
270 switch(rmsg.msgtype) {
274 printf("No VC %d/%d on nas%d\n",
275 smsg.pvc.sap_addr.vpi,
276 smsg.pvc.sap_addr.vci,
282 pw = getpwuid(rmsg.uid);
283 printf("Can't delete VC %d/%d on nas%d. owner is %s\n",
284 smsg.pvc.sap_addr.vpi,
285 smsg.pvc.sap_addr.vci,
292 printf("Interface nas%d already in use\n", smsg.nas_idx);
295 case INTERFACE_FAILED:
297 printf("Interface nas%d couldn't be created\n", smsg.nas_idx);
302 printf("Server can't allocate memory\n");
311 printf("Weird error: %d\n", rmsg.msgtype);
315 smsg.pvc.sap_addr.vci++;
317 } while(--count > 0);
323 srv_fd = unix_connect();
324 smsg.msgtype = (strlen(name) ? LIST_GROUP : LIST_ALL );
325 strncpy(smsg.name,name,MAX_GROUPNAME_LEN);
327 if( send(srv_fd, &smsg, sizeof(smsg), 0) < 0 )
328 clean_exit("Can't send LIST_GROUP or LIST_ALL message");
333 nbytes = recv(srv_fd, &rmsg, sizeof(rmsg), 0);
335 clean_exit("connection closed waiting for LIST_GROUP or LIST_ALL response\n");
337 clean_exit("Can't receive response to LIST_GROUP or LIST_ALL message");
339 if(rmsg.msgtype == GROUP_NOT_FOUND) {
341 printf("Group %s not found\n", name);
343 printf("No VCs defined\n");
347 printf("\nVC interface mode vlan_id\n");
348 printf("-- --------- ------ ----------\n");
349 // printf("\nVC interface group owner\n");
350 // printf("-- --------- ------ -----\n");
354 if(rmsg.msgtype == OK) {
355 printf("%2d/%4d nas%-6d %-16s %d (X%02X)\n",
356 rmsg.pvc.sap_addr.vpi,
357 rmsg.pvc.sap_addr.vci,
359 rmsg.mode? "Routing": "Bridging",
360 rmsg.vlan_id, rmsg.vlan_id
363 } while(rmsg.msgtype != LIST_END);
370 printf("No command specified. Use -a, -d, or -l\n");