usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / vlan / vconfig.c
blob5057cfd13ae41c5fff7457130a1d1d3d546d519f
1 //
2 //Copyright (C) 2001 Ben Greear
3 //
4 //This program is free software; you can redistribute it and/or
5 //modify it under the terms of the GNU Library General Public License
6 //as published by the Free Software Foundation; either version 2
7 //of the License, or (at your option) any later version.
8 //
9 //This program is distributed in the hope that it will be useful,
10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 //GNU General Public License for more details.
14 //You should have received a copy of the GNU Library General Public License
15 //along with this program; if not, write to the Free Software
16 //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 // To contact the Author, Ben Greear: greearb@candelatech.com
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <strings.h>
28 #include <sys/ioctl.h>
29 #include <linux/if_vlan.h>
30 #include <linux/sockios.h>
31 #include <string.h>
32 #include <sys/socket.h>
33 #include <sys/types.h>
36 #define MAX_HOSTNAME 256
39 static char* usage =
40 "\n"
41 "Usage: add [interface-name] [vlan_id]\n"
42 " rem [vlan-name]\n"
43 " set_flag [interface-name] [flag-num] [0 | 1]\n"
44 " set_egress_map [vlan-name] [skb_priority] [vlan_qos]\n"
45 " set_ingress_map [vlan-name] [skb_priority] [vlan_qos]\n"
46 " set_name_type [name-type]\n"
47 "\n"
48 "* The [interface-name] is the name of the ethernet card that hosts\n"
49 " the VLAN you are talking about.\n"
50 "* The vlan_id is the identifier (0-4095) of the VLAN you are operating on.\n"
51 "* skb_priority is the priority in the socket buffer (sk_buff).\n"
52 "* vlan_qos is the 3 bit priority in the VLAN header\n"
53 "* name-type: VLAN_PLUS_VID (vlan0005), VLAN_PLUS_VID_NO_PAD (vlan5),\n"
54 " DEV_PLUS_VID (eth0.0005), DEV_PLUS_VID_NO_PAD (eth0.5)\n"
55 "* bind-type: PER_DEVICE # Allows vlan 5 on eth0 and eth1 to be unique.\n"
56 " PER_KERNEL # Forces vlan 5 to be unique across all devices.\n"
57 "* FLAGS: 1 REORDER_HDR When this is set, the VLAN device will move the\n"
58 " ethernet header around to make it look exactly like a real\n"
59 " ethernet device. This may help programs such as DHCPd which\n"
60 " read the raw ethernet packet and make assumptions about the\n"
61 " location of bytes. If you don't need it, don't turn it on, because\n"
62 " there will be at least a small performance degradation. Default\n"
63 " is OFF.\n";
65 void show_usage() {
66 fprintf(stdout,usage);
69 int hex_to_bytes(char* bytes, int bytes_length, char* hex_str) {
70 int hlen;
71 int i;
73 int j = 0;
74 char hex[3];
75 char* stop; /* not used for any real purpose */
77 hlen = strlen(hex_str);
79 hex[2] = 0;
81 for (i = 0; i<hlen; i++) {
83 hex[0] = hex_str[i];
84 i++;
85 if (i >= hlen) {
86 return j; /* done */
89 hex[1] = hex_str[i];
90 bytes[j++] = (char)strtoul(hex, &stop, 16);
92 return j;
96 int main(int argc, char** argv) {
97 int fd;
98 struct vlan_ioctl_args if_request;
100 char* cmd = NULL;
101 char* if_name = NULL;
102 unsigned int vid = 0;
103 unsigned int skb_priority;
104 unsigned short vlan_qos;
105 unsigned int nm_type = VLAN_NAME_TYPE_PLUS_VID;
107 char* conf_file_name = "/proc/net/vlan/config";
109 memset(&if_request, 0, sizeof(struct vlan_ioctl_args));
111 if ((argc < 3) || (argc > 5)) {
112 fprintf(stdout,"Expecting argc to be 3-5, inclusive. Was: %d\n",argc);
114 show_usage();
115 exit(1);
117 else {
118 cmd = argv[1];
120 if (strcasecmp(cmd, "set_name_type") == 0) {
121 if (strcasecmp(argv[2], "VLAN_PLUS_VID") == 0) {
122 nm_type = VLAN_NAME_TYPE_PLUS_VID;
124 else if (strcasecmp(argv[2], "VLAN_PLUS_VID_NO_PAD") == 0) {
125 nm_type = VLAN_NAME_TYPE_PLUS_VID_NO_PAD;
127 else if (strcasecmp(argv[2], "DEV_PLUS_VID") == 0) {
128 nm_type = VLAN_NAME_TYPE_RAW_PLUS_VID;
130 else if (strcasecmp(argv[2], "DEV_PLUS_VID_NO_PAD") == 0) {
131 nm_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
133 else {
134 // MATHIEU
135 //cerr << "Invalid name type.\n";
136 fprintf(stderr,"Invalid name type.\n");
138 show_usage();
139 exit(1);
141 if_request.u.name_type = nm_type;
143 else {
144 if_name = argv[2];
145 if (strlen(if_name) > 15) {
146 // MATHIEU
147 //cerr << "ERROR: if_name must be 15 characters or less." << endl;
148 fprintf(stderr,"ERROR: if_name must be 15 characters or less.\n");
149 exit(1);
151 strcpy(if_request.device1, if_name);
154 if (argc == 4) {
155 vid = atoi(argv[3]);
156 if_request.u.VID = vid;
159 if (argc == 5) {
160 skb_priority = atoi(argv[3]);
161 vlan_qos = atoi(argv[4]);
162 if_request.u.skb_priority = skb_priority;
163 if_request.vlan_qos = vlan_qos;
167 // Open up the /proc/vlan/config
168 if ((fd = open(conf_file_name, O_RDONLY)) < 0) {
169 // MATHIEU
170 //cerr << "ERROR: Could not open /proc/vlan/config.\n";
171 fprintf(stderr,"WARNING: Could not open /proc/net/vlan/config. Maybe you need to load the 8021q module, or maybe you are not using PROCFS??\n");
174 else {
175 close(fd);
178 /* We use sockets now, instead of the file descriptor */
179 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
180 fprintf(stderr, "FATAL: Couldn't open a socket..go figure!\n");
181 exit(2);
184 /* add */
185 if (strcasecmp(cmd, "add") == 0) {
186 if_request.cmd = ADD_VLAN_CMD;
187 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
188 fprintf(stderr,"ERROR: trying to add VLAN #%u to IF -:%s:- error: %s\n",
189 vid, if_name, strerror(errno));
190 exit(3);
192 else {
193 fprintf(stdout,"Added VLAN with VID == %u to IF -:%s:-\n",
194 vid, if_name);
195 if (vid == 1) {
196 fprintf(stdout, "WARNING: VLAN 1 does not work with many switches,\nconsider another number if you have problems.\n");
199 }//if
200 else if (strcasecmp(cmd, "rem") == 0) {
201 if_request.cmd = DEL_VLAN_CMD;
202 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
203 fprintf(stderr,"ERROR: trying to remove VLAN -:%s:- error: %s\n",
204 if_name, strerror(errno));
205 exit(4);
207 else {
208 fprintf(stdout,"Removed VLAN -:%s:-\n", if_name);
210 }//if
211 else if (strcasecmp(cmd, "set_egress_map") == 0) {
212 if_request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD;
213 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
214 fprintf(stderr,"ERROR: trying to set egress map on device -:%s:- error: %s\n",
215 if_name, strerror(errno));
216 exit(5);
218 else {
219 fprintf(stdout,"Set egress mapping on device -:%s:- "
220 "Should be visible in /proc/net/vlan/%s\n",
221 if_name, if_name);
224 else if (strcasecmp(cmd, "set_ingress_map") == 0) {
225 if_request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD;
226 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
227 fprintf(stderr,"ERROR: trying to set ingress map on device -:%s:- error: %s\n",
228 if_name, strerror(errno));
229 exit(6);
231 else {
232 fprintf(stdout,"Set ingress mapping on device -:%s:- "
233 "Should be visible in /proc/net/vlan/%s\n",
234 if_name, if_name);
237 else if (strcasecmp(cmd, "set_flag") == 0) {
238 if_request.cmd = SET_VLAN_FLAG_CMD;
239 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
240 fprintf(stderr,"ERROR: trying to set flag on device -:%s:- error: %s\n",
241 if_name, strerror(errno));
242 exit(7);
244 else {
245 fprintf(stdout,"Set flag on device -:%s:- "
246 "Should be visible in /proc/net/vlan/%s\n",
247 if_name, if_name);
250 else if (strcasecmp(cmd, "set_name_type") == 0) {
251 if_request.cmd = SET_VLAN_NAME_TYPE_CMD;
252 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
253 fprintf(stderr,"ERROR: trying to set name type for VLAN subsystem, error: %s\n",
254 strerror(errno));
255 exit(8);
257 else {
258 fprintf(stdout,"Set name-type for VLAN subsystem."
259 " Should be visible in /proc/net/vlan/config\n");
262 else {
263 fprintf(stderr, "Unknown command -:%s:-\n", cmd);
265 show_usage();
266 exit(5);
269 return 0;
270 }/* main */