Merge branch 'master' of git://cadel.mutabah.net/acess2
[tpg/acess2.git] / Usermode / Applications / ip_src / addr.c
1 /*
2  * Acess2 ip command
3  * - By John Hodge (thePowersGang)
4  * 
5  * addr.c
6  * - `ip addr` sub command
7  */
8 #include "common.h"
9
10 // === PROTOTYPES ===
11  int    Addr_main(int argc, char *argv[]);
12  int    AddInterface(const char *Device, int Type);
13  int    SetAddress(int IFNum, const void *Address, int SubnetSize);
14 void    DumpInterfaces(void);
15 void    DumpInterface(const char *Name);
16 void    DumpRoute(const char *Name);
17
18 // === CODE ===
19 int Addr_main(int argc, char *argv[])
20 {
21          int    ret;
22         if( argc <= 1 )
23         {
24                 // No action
25                 DumpInterfaces();
26         }
27         else if( strcmp(argv[1], "add") == 0 )
28         {
29                 uint8_t addr[16];
30                  int    type, subnet_size;
31
32                 // Check argument counts
33                 if( argc - 2 < 2 ) {
34                         fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n",
35                                 argv[0], argc-2);
36                         PrintUsage(argv[0]);
37                         return -1;
38                 }
39
40                 // Parse IP Address
41                 type = ParseIPAddress(argv[3], addr, &subnet_size);
42                 if(type == 0) {
43                         fprintf(stderr, "'%s' cannot be parsed as an IP address\n", argv[3]);
44                         return -1;
45                 }
46         
47                 // Fun
48                 ret = AddInterface( argv[2], type );
49                 if(ret < 0)     return ret;
50                 ret = SetAddress( ret, addr, subnet_size );
51                 return ret;
52         }
53         // Delete an interface
54         else if( strcmp(argv[1], "del") == 0 )
55         {
56                 if( argc - 2 < 1 ) {
57                         fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]);
58                         PrintUsage(argv[0]);
59                         return -1;
60                 }
61         }
62         else
63         {
64                 // Show named iface?
65                 DumpInterface(argv[1]);
66         }
67         return 0;
68 }
69
70 /**
71  * \brief Create a new interface using the passed device
72  * \param Device        Network device to bind to
73  */
74 int AddInterface(const char *Device, int Type)
75 {
76          int    dp, ret;
77         
78         dp = _SysOpen(IPSTACK_ROOT, OPENFLAG_READ);
79         struct {
80                 const char *Dev;
81                 const char *Name;
82                  int    Type;
83         } ifinfo;
84         ifinfo.Dev = Device;
85         ifinfo.Name = "";
86         ifinfo.Type = Type;
87         ret = _SysIOCtl(dp, 4, &ifinfo);
88         _SysClose(dp);
89         
90         if( ret < 0 ) {
91                 fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
92                 return -1;
93         }
94         
95         printf("-- Added '"IPSTACK_ROOT"/%i' using device %s\n", ret, Device);
96         
97         return ret;
98 }
99
100 /**
101  * \brief Set the address on an interface from a textual IP address
102  */
103 int SetAddress(int IFNum, const void *Address, int SubnetSize)
104 {
105         char    path[sizeof(IPSTACK_ROOT)+1+5+1];       // ip000
106          int    fd;
107         
108         // Open file
109         sprintf(path, IPSTACK_ROOT"/%i", IFNum);
110         fd = _SysOpen(path, OPENFLAG_READ);
111         if( fd == -1 ) {
112                 fprintf(stderr, "Unable to open '%s'\n", path);
113                 return -1;
114         }
115         
116         // Set Address
117         _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_address"), (void*)Address);
118         
119         // Set Subnet
120         _SysIOCtl(fd, _SysIOCtl(fd, 3, "getset_subnet"), &SubnetSize);
121         
122         _SysClose(fd);
123         
124         // Dump!
125         //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 );
126         
127         return 0;
128 }
129
130 /**
131  * \brief Dump all interfaces
132  */
133 void DumpInterfaces(void)
134 {
135          int    dp;
136         char    filename[FILENAME_MAX+1];
137         
138         dp = _SysOpen(IPSTACK_ROOT, OPENFLAG_READ);
139         
140         while( _SysReadDir(dp, filename) )
141         {
142                 if(filename[0] == '.')  continue;
143                 DumpInterface(filename);
144         }
145         
146         _SysClose(dp);
147 }
148
149 /**
150  * \brief Dump an interface
151  */
152 void DumpInterface(const char *Name)
153 {
154          int    fd;
155          int    type;
156         char    path[sizeof(IPSTACK_ROOT)+1+FILENAME_MAX+1] = IPSTACK_ROOT"/";
157         
158         strcat(path, Name);
159         
160         fd = _SysOpen(path, OPENFLAG_READ);
161         if(fd == -1) {
162                 fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t", Name, path);
163                 return ;
164         }
165         
166         type = _SysIOCtl(fd, 4, NULL);
167         
168         // Ignore -1 values
169         if( type == -1 ) {
170                 return ;
171         }
172         
173         printf("%s:\t", Name);
174         {
175                  int    call_num = _SysIOCtl(fd, 3, "get_device");
176                  int    len = _SysIOCtl(fd, call_num, NULL);
177                 char    *buf = malloc(len+1);
178                 _SysIOCtl(fd, call_num, buf);
179                 printf("'%s'\n", buf);
180                 free(buf);
181         }
182         printf("\t");
183         // Get the address type
184         switch(type)
185         {
186         case 0: // Disabled/Unset
187                 printf("DISABLED\n");
188                 break;
189         case 4: // IPv4
190                 {
191                 uint8_t ip[4];
192                  int    subnet;
193                 printf("IPv4\t");
194                 _SysIOCtl(fd, 5, ip);   // Get IP Address
195                 subnet = _SysIOCtl(fd, 7, NULL);        // Get Subnet Bits
196                 printf("%i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
197                 }
198                 break;
199         case 6: // IPv6
200                 {
201                 uint16_t        ip[8];
202                  int    subnet;
203                 printf("IPv6\t");
204                 _SysIOCtl(fd, 5, ip);   // Get IP Address
205                 subnet = _SysIOCtl(fd, 7, NULL);        // Get Subnet Bits
206                 printf("%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
207                         ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]),
208                         ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]),
209                         subnet);
210                 }
211                 break;
212         default:        // Unknow
213                 printf("UNKNOWN (%i)\n", type);
214                 break;
215         }
216                         
217         _SysClose(fd);
218 }
219

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