Tomato 1.28
[tomato.git] / release / src / router / vlan / vconfig.c
blob797411a9c8efca848fe9f99f5460d3a7d892b55c
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 =
41 Usage: add [interface-name] [vlan_id]
42 rem [vlan-name]
43 set_flag [interface-name] [flag-num] [0 | 1]
44 set_egress_map [vlan-name] [skb_priority] [vlan_qos]
45 set_ingress_map [vlan-name] [skb_priority] [vlan_qos]
46 set_name_type [name-type]
48 * The [interface-name] is the name of the ethernet card that hosts
49 the VLAN you are talking about.
50 * The vlan_id is the identifier (0-4095) of the VLAN you are operating on.
51 * skb_priority is the priority in the socket buffer (sk_buff).
52 * vlan_qos is the 3 bit priority in the VLAN header
53 * name-type: VLAN_PLUS_VID (vlan0005), VLAN_PLUS_VID_NO_PAD (vlan5),
54 DEV_PLUS_VID (eth0.0005), DEV_PLUS_VID_NO_PAD (eth0.5)
55 * bind-type: PER_DEVICE # Allows vlan 5 on eth0 and eth1 to be unique.
56 PER_KERNEL # Forces vlan 5 to be unique across all devices.
57 * FLAGS: 1 REORDER_HDR When this is set, the VLAN device will move the
58 ethernet header around to make it look exactly like a real
59 ethernet device. This may help programs such as DHCPd which
60 read the raw ethernet packet and make assumptions about the
61 location of bytes. If you don't need it, don't turn it on, because
62 there will be at least a small performance degradation. Default
63 is OFF.
66 void show_usage() {
67 fprintf(stdout,usage);
70 int hex_to_bytes(char* bytes, int bytes_length, char* hex_str) {
71 int hlen;
72 int i;
74 int j = 0;
75 char hex[3];
76 char* stop; /* not used for any real purpose */
78 hlen = strlen(hex_str);
80 hex[2] = 0;
82 for (i = 0; i<hlen; i++) {
84 hex[0] = hex_str[i];
85 i++;
86 if (i >= hlen) {
87 return j; /* done */
90 hex[1] = hex_str[i];
91 bytes[j++] = (char)strtoul(hex, &stop, 16);
93 return j;
97 int main(int argc, char** argv) {
98 int fd;
99 struct vlan_ioctl_args if_request;
101 char* cmd = NULL;
102 char* if_name = NULL;
103 unsigned int vid = 0;
104 unsigned int skb_priority;
105 unsigned short vlan_qos;
106 unsigned int nm_type = VLAN_NAME_TYPE_PLUS_VID;
108 char* conf_file_name = "/proc/net/vlan/config";
110 memset(&if_request, 0, sizeof(struct vlan_ioctl_args));
112 if ((argc < 3) || (argc > 5)) {
113 fprintf(stdout,"Expecting argc to be 3-5, inclusive. Was: %d\n",argc);
115 show_usage();
116 exit(1);
118 else {
119 cmd = argv[1];
121 if (strcasecmp(cmd, "set_name_type") == 0) {
122 if (strcasecmp(argv[2], "VLAN_PLUS_VID") == 0) {
123 nm_type = VLAN_NAME_TYPE_PLUS_VID;
125 else if (strcasecmp(argv[2], "VLAN_PLUS_VID_NO_PAD") == 0) {
126 nm_type = VLAN_NAME_TYPE_PLUS_VID_NO_PAD;
128 else if (strcasecmp(argv[2], "DEV_PLUS_VID") == 0) {
129 nm_type = VLAN_NAME_TYPE_RAW_PLUS_VID;
131 else if (strcasecmp(argv[2], "DEV_PLUS_VID_NO_PAD") == 0) {
132 nm_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
134 else {
135 // MATHIEU
136 //cerr << "Invalid name type.\n";
137 fprintf(stderr,"Invalid name type.\n");
139 show_usage();
140 exit(1);
142 if_request.u.name_type = nm_type;
144 else {
145 if_name = argv[2];
146 if (strlen(if_name) > 15) {
147 // MATHIEU
148 //cerr << "ERROR: if_name must be 15 characters or less." << endl;
149 fprintf(stderr,"ERROR: if_name must be 15 characters or less.\n");
151 exit(1);
153 strcpy(if_request.device1, if_name);
156 if (argc == 4) {
157 vid = atoi(argv[3]);
158 if_request.u.VID = vid;
161 if (argc == 5) {
162 skb_priority = atoi(argv[3]);
163 vlan_qos = atoi(argv[4]);
164 if_request.u.skb_priority = skb_priority;
165 if_request.vlan_qos = vlan_qos;
169 // Open up the /proc/vlan/config
170 if ((fd = open(conf_file_name, O_RDONLY)) < 0) {
171 // MATHIEU
172 //cerr << "ERROR: Could not open /proc/vlan/config.\n";
173 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");
176 else {
177 close(fd);
180 /* We use sockets now, instead of the file descriptor */
181 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
182 fprintf(stderr, "FATAL: Couldn't open a socket..go figure!\n");
183 exit(2);
186 /* add */
187 if (strcasecmp(cmd, "add") == 0) {
188 if_request.cmd = ADD_VLAN_CMD;
189 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
190 fprintf(stderr,"ERROR: trying to add VLAN #%u to IF -:%s:- error: %s\n",
191 vid, if_name, strerror(errno));
193 }//if
194 else if (strcasecmp(cmd, "rem") == 0) {
195 if_request.cmd = DEL_VLAN_CMD;
196 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
197 fprintf(stderr,"ERROR: trying to remove VLAN -:%s:- error: %s\n",
198 if_name, strerror(errno));
200 }//if
201 else if (strcasecmp(cmd, "set_egress_map") == 0) {
202 if_request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD;
203 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
204 fprintf(stderr,"ERROR: trying to set egress map on device -:%s:- error: %s\n",
205 if_name, strerror(errno));
208 else if (strcasecmp(cmd, "set_ingress_map") == 0) {
209 if_request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD;
210 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
211 fprintf(stderr,"ERROR: trying to set ingress map on device -:%s:- error: %s\n",
212 if_name, strerror(errno));
215 else if (strcasecmp(cmd, "set_flag") == 0) {
216 if_request.cmd = SET_VLAN_FLAG_CMD;
217 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
218 fprintf(stderr,"ERROR: trying to set flag on device -:%s:- error: %s\n",
219 if_name, strerror(errno));
222 else if (strcasecmp(cmd, "set_name_type") == 0) {
223 if_request.cmd = SET_VLAN_NAME_TYPE_CMD;
224 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) {
225 fprintf(stderr,"ERROR: trying to set name type for VLAN subsystem, error: %s\n",
226 strerror(errno));
229 else {
230 fprintf(stderr, "Unknown command -:%s:-\n", cmd);
232 show_usage();
233 exit(5);
236 return 0;
237 }/* main */