Cleaning up some debug, fixing cosmetic bugs in usermode apps
[tpg/acess2.git] / Usermode / Applications / ifconfig_src / main.c
1 /*
2  * Acess2 IFCONFIG command
3  */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <acess/sys.h>
8
9 // === CONSTANTS ===
10 #define FILENAME_MAX    255
11 #define IPSTACK_ROOT    "/Devices/ip"
12
13 // === PROTOTYPES ===
14 void    PrintUsage(const char *ProgName);
15 void    DumpInterfaces(void);
16 void    DumpInterface(const char *Name);
17  int    AddInterface(const char *Device);
18  int    DoAutoConfig(const char *Device);
19
20 // === CODE ===
21 /**
22  * \brief Program entrypoint
23  */
24 int main(int argc, char *argv[])
25 {
26         // No args, dump interfaces
27         if(argc == 1) {
28                 DumpInterfaces();
29                 return 0;
30         }
31         
32         // Add a new interface
33         if( strcmp(argv[1], "add") == 0 ) {
34                 if( argc < 4 ) {
35                         fprintf(stderr, "ERROR: %s add require two arguments, %i passed\n", argv[0], argc-2);
36                         PrintUsage(argv[0]);
37                         return 0;
38                 }
39                 // TODO: Also set the IP address as the usage says it does
40                 return AddInterface( argv[2] );
41         }
42         
43         // Autoconfigure an interface
44         // NOTE: Debugging hack (see the function for more details)
45         if( strcmp(argv[1], "autoconf") == 0 ) {
46                 DoAutoConfig(argv[2]);
47                 return 0;
48         }
49         
50         // Print usage instructions
51         PrintUsage(argv[0]);
52         
53         return 0;
54 }
55
56 /**
57  * \brief Print usage instructions
58  */
59 void PrintUsage(const char *ProgName)
60 {
61         fprintf(stderr, "Usage:\n");
62         fprintf(stderr, "    %s add <device> <ip>/<prefix>\n", ProgName);
63         fprintf(stderr, "        Add a new interface listening on <device> with the specified\n");
64         fprintf(stderr, "        address.\n");
65         fprintf(stderr, "    %s del <interface>\n", ProgName);
66         fprintf(stderr, "    %s set <interface> <option> <value>\n", ProgName);
67         fprintf(stderr, "        Set an option on an interface, a list of valid options follows\n");
68         fprintf(stderr, "        gw      IPv4 default gateway\n");
69         fprintf(stderr, "    %s [<interface>]\n", ProgName);
70         fprintf(stderr, "        Print the current interfaces (or only <interface> if passed)\n");
71         fprintf(stderr, "\n");
72         fprintf(stderr, "A note on Acess's IP Stack:\n");
73         fprintf(stderr, "    Each interface corresponds to only one IP address (either IPv4\n");
74         fprintf(stderr, "    or IPv6). A network device can have multiple interfaces bound\n");
75         fprintf(stderr, "    to it, allowing multiple addresses for one network connection\n");
76         fprintf(stderr, "\n");
77 }
78
79 /**
80  * \brief Dump all interfaces
81  */
82 void DumpInterfaces(void)
83 {
84          int    dp;
85         char    filename[FILENAME_MAX+1];
86         
87         dp = open(IPSTACK_ROOT, OPENFLAG_READ);
88         
89         while( readdir(dp, filename) )
90         {
91                 if(filename[0] == '.')  continue;
92                 DumpInterface(filename);
93         }
94         
95         close(dp);
96 }
97
98 /**
99  * \brief Dump an interface
100  */
101 void DumpInterface(const char *Name)
102 {
103          int    fd;
104          int    type;
105         char    path[sizeof(IPSTACK_ROOT)+1+FILENAME_MAX+1] = IPSTACK_ROOT"/";
106         
107         strcat(path, Name);
108         
109         fd = open(path, OPENFLAG_READ);
110         if(fd == -1) {
111                 printf("%s:\tUnable to open ('%s')\n", Name, path);
112                 return ;
113         }
114         
115         type = ioctl(fd, 4, NULL);
116         
117         printf("%s:\t", Name);
118         {
119                  int    call_num = ioctl(fd, 3, "get_device");
120                  int    len = ioctl(fd, call_num, NULL);
121                 char    *buf = malloc(len+1);
122                 ioctl(fd, call_num, buf);
123                 printf("'%s'\t", buf);
124                 free(buf);
125         }
126         // Get the address type
127         switch(type)
128         {
129         case 0: // Disabled/Unset
130                 printf("DISABLED\n");
131                 break;
132         case 4: // IPv4
133                 {
134                 uint8_t ip[4];
135                  int    subnet;
136                 printf("IPv4\n");
137                 ioctl(fd, 5, ip);       // Get IP Address
138                 subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
139                 printf("\tAddress: %i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
140                 ioctl(fd, 8, ip);       // Get Gateway
141                 printf("\tGateway: %i.%i.%i.%i\n", ip[0], ip[1], ip[2], ip[3]);
142                 }
143                 break;
144         case 6: // IPv6
145                 {
146                 uint16_t        ip[8];
147                  int    subnet;
148                 printf("IPv6\n");
149                 ioctl(fd, 5, ip);       // Get IP Address
150                 subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
151                 printf("\t%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
152                         ip[0], ip[1], ip[2], ip[3],
153                         ip[4], ip[5], ip[6], ip[7],
154                         subnet);
155                 }
156                 break;
157         default:        // Unknow
158                 printf("UNKNOWN (%i)\n", type);
159                 break;
160         }
161         printf("\n");
162                         
163         close(fd);
164 }
165
166 /**
167  * \brief Create a new interface using the passed device
168  * \param Device        Network device to bind to
169  */
170 int AddInterface(const char *Device)
171 {
172          int    dp, ret;
173         
174         dp = open(IPSTACK_ROOT, OPENFLAG_READ);
175         ret = ioctl(dp, 4, (void*)Device);
176         printf("AddInterface: ret = 0x%x = %i\n", ret, ret);
177         close(dp);
178         
179         if( ret < 0 ) {
180                 fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
181                 return -1;
182         }
183         
184         printf("-- Added '"IPSTACK_ROOT"/%i' using device %s\n", ret, Device);
185         
186         return ret;
187 }
188
189 /**
190  * \note Debugging HACK!
191  * \brief Autoconfigure the specified device to 10.0.2.55/8 using
192  *        10.0.2.1 as the gateway.
193  */
194 int DoAutoConfig(const char *Device)
195 {
196          int    tmp, fd;
197         char    path[sizeof(IPSTACK_ROOT)+5+1]; // ip000
198         uint8_t addr[4] = {10,0,2,55};
199         uint8_t gw[4] = {10,0,2,1};
200          int    subnet = 8;
201         
202         tmp = AddInterface(Device);
203         if( tmp < 0 )   return tmp;
204         
205         sprintf(path, IPSTACK_ROOT"/%i", tmp);
206         
207         fd = open(path, OPENFLAG_READ);
208         if( fd == -1 ) {
209                 fprintf(stderr, "Unable to open '%s'\n", path);
210                 return -1;
211         }
212         
213         tmp = 4;        // IPv4
214         tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
215         if( tmp != 4 ) {
216                 fprintf(stderr, "Error in setting address type (got %i, expected 4)\n", tmp);
217                 return -1;
218         }
219         // Set Address
220         ioctl(fd, ioctl(fd, 3, "set_address"), addr);
221         // Set Subnet
222         ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
223         // Set Gateway
224         ioctl(fd, ioctl(fd, 3, "set_gateway"), gw);
225         
226         close(fd);
227         
228         printf("Set address to %i.%i.%i.%i/%i (GW: %i.%i.%i.%i)\n",
229                 addr[0], addr[1], addr[2], addr[3],
230                 subnet,
231                 gw[0], gw[1], gw[2], gw[3]);
232         
233         return 0;
234 }

UCC git Repository :: git.ucc.asn.au