git.ucc.asn.au
/
tpg
/
acess2.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
560e973
)
IPStack / ifconfig - Routing changes
author
John Hodge
<
[email protected]
>
Tue, 25 Jan 2011 13:41:13 +0000
(21:41 +0800)
committer
John Hodge
<
[email protected]
>
Tue, 25 Jan 2011 13:41:13 +0000
(21:41 +0800)
- Implemented implicit routes in interface.c/routing.c
> Implicit routes are routes that are constructed on the fly from
an interface.
- Vastly improved the route support in ifconfig
- (Misc) Added some missing syscalls to Usermode/acess/sys.h
Modules/IPStack/interface.c
patch
|
blob
|
history
Modules/IPStack/ipstack.h
patch
|
blob
|
history
Modules/IPStack/routing.c
patch
|
blob
|
history
Usermode/Applications/ifconfig_src/main.c
patch
|
blob
|
history
Usermode/Libraries/libnet.so_src/net.h
patch
|
blob
|
history
Usermode/include/acess/sys.h
patch
|
blob
|
history
diff --git
a/Modules/IPStack/interface.c
b/Modules/IPStack/interface.c
index
50d4c22
..
fc79e9e
100644
(file)
--- a/
Modules/IPStack/interface.c
+++ b/
Modules/IPStack/interface.c
@@
-251,7
+251,7
@@
tInterface *IPStack_AddInterface(const char *Device, const char *Name)
iface = malloc(
sizeof(tInterface)
+ nameLen + 1
- + IPStack_GetAddressSize(-1)
+ + IPStack_GetAddressSize(-1)
*3 // Address, Route->Network, Route->NextHop
);
if(!iface) {
LEAVE('n');
@@
-261,6
+261,8
@@
tInterface *IPStack_AddInterface(const char *Device, const char *Name)
iface->Next = NULL;
iface->Type = 0; // Unset type
iface->Address = iface->Name + nameLen + 1; // Address
+ iface->Route.Network = iface->Address + IPStack_GetAddressSize(-1);
+ iface->Route.NextHop = iface->Route.Network + IPStack_GetAddressSize(-1);
// Create Node
iface->Node.ImplPtr = iface;
diff --git
a/Modules/IPStack/ipstack.h
b/Modules/IPStack/ipstack.h
index
e6ded4b
..
b0dff23
100644
(file)
--- a/
Modules/IPStack/ipstack.h
+++ b/
Modules/IPStack/ipstack.h
@@
-38,21
+38,6
@@
struct sMacAddr {
Uint8 B[6];
} __attribute__((packed));
-struct sInterface {
- struct sInterface *Next; //!< Next interface in list
-
- tVFS_Node Node; //!< Node to use the interface
-
- tAdapter *Adapter; //!< Adapter the interface is associated with
- int TimeoutDelay; //!< Time in miliseconds before a packet times out
- int Type; //!< Interface type, see ::eInterfaceTypes
-
- void *Address; //!< IP address (stored after the Name)
- int SubnetBits; //!< Number of bits that denote the address network
-
- char Name[];
-};
-
/**
* \brief Route definition structure
*/
@@
-69,6
+54,23
@@
typedef struct sRoute {
int Metric; //!< Route priority
} tRoute;
+struct sInterface {
+ struct sInterface *Next; //!< Next interface in list
+
+ tVFS_Node Node; //!< Node to use the interface
+
+ tAdapter *Adapter; //!< Adapter the interface is associated with
+ int TimeoutDelay; //!< Time in miliseconds before a packet times out
+ int Type; //!< Interface type, see ::eInterfaceTypes
+
+ void *Address; //!< IP address (stored after the Name)
+ int SubnetBits; //!< Number of bits that denote the address network
+
+ tRoute Route; //!< Interface route
+
+ char Name[];
+};
+
/**
* \brief Represents a network adapter
*/
diff --git
a/Modules/IPStack/routing.c
b/Modules/IPStack/routing.c
index
53d5c88
..
26817b6
100644
(file)
--- a/
Modules/IPStack/routing.c
+++ b/
Modules/IPStack/routing.c
@@
-251,6
+251,8
@@
tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
{
tRoute *rt;
tRoute *best = NULL;
+ tInterface *iface;
+ int addrSize;
ENTER("iAddressType pInterface sAddress",
AddressType, Interface, IPStack_PrintAddress(AddressType, Address));
@@
-261,6
+263,10
@@
tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
return NULL;
}
+ // Get address size
+ addrSize = IPStack_GetAddressSize(AddressType);
+
+ // Check against explicit routes
for( rt = gIP_Routes; rt; rt = rt->Next )
{
// Check interface
@@
-290,6
+296,56
@@
tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
best = rt;
}
+ // Check against implicit routes
+ if( !best && !Interface )
+ {
+ for( iface = gIP_Interfaces; iface; iface = iface->Next )
+ {
+ if( Interface && iface != Interface ) continue;
+ if( iface->Type != AddressType ) continue;
+
+
+ // Check if the address matches
+ if( !IPStack_CompareAddress(AddressType, iface->Address, Address, iface->SubnetBits) )
+ continue;
+
+ if( best ) {
+ // More direct routes are preferred
+ if( best->SubnetBits > rt->SubnetBits ) {
+ LOG("Skipped - less direct (%i < %i)", rt->SubnetBits, best->SubnetBits);
+ continue;
+ }
+ // If equally direct, choose the best metric
+ if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) {
+ LOG("Skipped - higher metric (%i > %i)", rt->Metric, best->Metric);
+ continue;
+ }
+ }
+
+ rt = &iface->Route;
+ memcpy(rt->Network, iface->Address, addrSize);
+ memset(rt->NextHop, 0, addrSize);
+ rt->Metric = DEFAUTL_METRIC;
+ rt->SubnetBits = iface->SubnetBits;
+
+ best = rt;
+ }
+ }
+ if( !best && Interface )
+ {
+ rt = &Interface->Route;
+ // Make sure route is up to date
+ memcpy(rt->Network, iface->Address, addrSize);
+ memset(rt->NextHop, 0, addrSize);
+ rt->Metric = DEFAUTL_METRIC;
+ rt->SubnetBits = iface->SubnetBits;
+
+ if( IPStack_CompareAddress(AddressType, rt->Network, Address, rt->SubnetBits) )
+ {
+ best = rt;
+ }
+ }
+
LEAVE('p', best);
return best;
}
diff --git
a/Usermode/Applications/ifconfig_src/main.c
b/Usermode/Applications/ifconfig_src/main.c
index
3a45530
..
9aa9d72
100644
(file)
--- a/
Usermode/Applications/ifconfig_src/main.c
+++ b/
Usermode/Applications/ifconfig_src/main.c
@@
-11,6
+11,7
@@
// === CONSTANTS ===
#define FILENAME_MAX 255
#define IPSTACK_ROOT "/Devices/ip"
+#define DEFAULT_METRIC 30
// TODO: Move this to a header
#define ntohs(v) (((v&0xFF)<<8)|((v>>8)&0xFF))
@@
-22,10
+23,10
@@
void DumpRoutes(void);
void DumpInterface(const char *Name);
void DumpRoute(const char *Name);
int AddInterface(const char *Device);
-void AddRoute(const char *Interface,
void *Dest, int MaskBits
, void *NextHop);
+void AddRoute(const char *Interface,
int AddressType, void *Dest, int MaskBits, int Metric
, void *NextHop);
int DoAutoConfig(const char *Device);
int SetAddress(int IFNum, const char *Address);
- int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits);
+ int ParseIPAddres
s
(const char *Address, uint8_t *Dest, int *SubnetBits);
// === CODE ===
/**
@@
-41,13
+42,93
@@
int main(int argc, char *argv[])
return 0;
}
- if( strcmp(argv[1], "routes") == 0 ) {
- DumpRoutes();
+ // Routes
+ if( strcmp(argv[1], "route") == 0 )
+ {
+ // Add new route
+ if( strcmp(argv[2], "add") == 0 )
+ {
+ uint8_t dest[16] = {0};
+ uint8_t nextHop[16] = {0};
+ int addrType, subnetBits = -1;
+ int nextHopType, nextHopBits=-1;
+ char *ifaceName;
+ int metric = DEFAULT_METRIC;
+ // Usage:
+ // ifconfig route add <host>[/<prefix>] <interface> [<metric>]
+ // ifconfig route add <host>[/<prefix>] <next hop> [<metric>]
+ if( argc - 3 < 2 ) {
+ fprintf(stderr, "ERROR: '%s route add' takes at least two arguments, %i passed\n",
+ argv[0], argc-3);
+ PrintUsage(argv[0]);
+ return -1;
+ }
+
+ if( argc - 3 > 3 ) {
+ fprintf(stderr, "ERROR: '%s route add' takes at most three arguments, %i passed\n",
+ argv[0], argc-3);
+ PrintUsage(argv[0]);
+ return -1;
+ }
+
+ // Destination IP
+ addrType = ParseIPAddress(argv[3], dest, &subnetBits);
+ if( subnetBits == -1 ) {
+ subnetBits = Net_GetAddressSize(addrType)*8;
+ }
+ // Interface Name / Next Hop
+ if( (nextHopType = ParseIPAddress(argv[4], nextHop, &nextHopBits)) == 0 )
+ {
+ // Interface name
+ ifaceName = argv[4];
+ }
+ else
+ {
+ // Next Hop
+ // - Check if it's the same type as the network/destination
+ if( nextHopType != addrType ) {
+ fprintf(stderr, "ERROR: Address type mismatch\n");
+ return -1;
+ }
+ // - Make sure there's no mask
+ if( nextHopBits != -1 ) {
+ fprintf(stderr, "Error: Next hop cannot be masked\n");
+ return -1;
+ }
+ }
+
+ // Metric
+ if( argc - 3 >= 3 )
+ {
+ metric = atoi(argv[5]);
+ if( metric == 0 && argv[5][0] != '0' ) {
+ fprintf(stderr, "ERROR: Metric should be a number\n");
+ return -1;
+ }
+ }
+
+ // Make the route!
+ AddRoute(ifaceName, addrType, dest, subnetBits, metric, nextHop);
+
+ return 0;
+ }
+ // Delete a route
+ else if( strcmp(argv[2], "del") == 0 )
+ {
+ // Usage:
+ // ifconfig route del <routenum>
+ // ifconfig route del <host>[/<prefix>]
+ }
+ else
+ {
+ // List routes
+ DumpRoutes();
+ }
return 0;
}
-
// Add a new interface
- if( strcmp(argv[1], "add") == 0 ) {
+ else if( strcmp(argv[1], "add") == 0 )
+ {
if( argc < 4 ) {
fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2);
PrintUsage(argv[0]);
@@
-59,9
+140,9
@@
int main(int argc, char *argv[])
ret = SetAddress( ret, argv[3] );
return ret;
}
-
// Delete an interface
- if( strcmp(argv[1], "del") == 0 ) {
+ else if( strcmp(argv[1], "del") == 0 )
+ {
if( argc < 3 ) {
fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]);
PrintUsage(argv[0]);
@@
-69,16
+150,21
@@
int main(int argc, char *argv[])
}
// TODO:
}
-
// Autoconfigure an interface
// NOTE: Debugging hack (see the function for more details)
- if( strcmp(argv[1], "autoconf") == 0 ) {
+ else if( strcmp(argv[1], "autoconf") == 0 )
+ {
DoAutoConfig(argv[2]);
return 0;
}
+ else if( strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 )
+ {
+ PrintUsage(argv[0]);
+ return 0;
+ }
- //
Print usage instructions
-
PrintUsage(argv[0
]);
+ //
Dump a named interface
+
DumpInterface(argv[1
]);
return 0;
}
@@
-93,12
+179,18
@@
void PrintUsage(const char *ProgName)
fprintf(stderr, " Add a new interface listening on <device> with the specified\n");
fprintf(stderr, " address.\n");
fprintf(stderr, " %s del <interface>\n", ProgName);
- fprintf(stderr, " %s set <interface> <option> <value>\n", ProgName);
- fprintf(stderr, " Set an option on an interface, a list of valid options follows\n");
- fprintf(stderr, " gw IPv4 default gateway\n");
+ fprintf(stderr, " Delete an interface\n");
fprintf(stderr, " %s [<interface>]\n", ProgName);
fprintf(stderr, " Print the current interfaces (or only <interface> if passed)\n");
fprintf(stderr, "\n");
+ fprintf(stderr, " %s routes\n", ProgName);
+ fprintf(stderr, " Print the routing tables\n");
+ fprintf(stderr, " %s routes add <host>[/<prefix>] [<nexthop> OR <iface>] [<metric>]\n", ProgName);
+ fprintf(stderr, " Add a new route\n");
+ fprintf(stderr, " %s routes del <host>[/<prefix>]\n", ProgName);
+ fprintf(stderr, " %s routes del <routenum>\n", ProgName);
+ fprintf(stderr, " Add a new route\n");
+ fprintf(stderr, "\n");
fprintf(stderr, "A note on Acess's IP Stack:\n");
fprintf(stderr, " Each interface corresponds to only one IP address (either IPv4\n");
fprintf(stderr, " or IPv6). A network device can have multiple interfaces bound\n");
@@
-157,7
+249,7
@@
void DumpInterface(const char *Name)
fd = open(path, OPENFLAG_READ);
if(fd == -1) {
-
printf("%s:\tUnable to open ('%s')\n
", Name, path);
+
fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t
", Name, path);
return ;
}
@@
-315,11
+407,51
@@
int AddInterface(const char *Device)
return ret;
}
-void AddRoute(const char *Interface,
void *Dest, int MaskBits
, void *NextHop)
+void AddRoute(const char *Interface,
int AddressType, void *Dest, int MaskBits, int Metric
, void *NextHop)
{
int fd;
int num;
char tmp[sizeof(IPSTACK_ROOT"/routes/") + 5]; // enough for 4 digits
+ char *ifaceToFree = NULL;
+
+ // Get interface name
+ if( !Interface )
+ {
+ if( !NextHop ) {
+ fprintf(stderr,
+ "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
+ "Only one should be NULL\n"
+ );
+ return ;
+ }
+
+ // Query for the interface name
+ Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
+ }
+ // Check address type (if the interface was passed)
+ // - If we got the interface name, then it should be correct
+ else
+ {
+ char ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
+
+ // Open interface
+ strcpy(ifacePath, IPSTACK_ROOT"/");
+ strcat(ifacePath, Interface);
+ fd = open(ifacePath, 0);
+ if( fd == -1 ) {
+ fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
+ return ;
+ }
+ // Get and check type
+ num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
+ if( num != AddressType ) {
+ fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
+ AddressType, num);
+ return ;
+ }
+
+ close(fd);
+ }
// Create route
fd = open(IPSTACK_ROOT"/routes", 0);
@@
-331,11
+463,16
@@
void AddRoute(const char *Interface, void *Dest, int MaskBits, void *NextHop)
fd = open(tmp, 0);
ioctl(fd, ioctl(fd, 3, "set_network"), Dest);
- ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
+ if( NextHop )
+ ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), &MaskBits);
+ ioctl(fd, ioctl(fd, 3, "getset_metric"), &Metric);
close(fd);
+ // Check if the interface name was allocated by us
+ if( ifaceToFree )
+ free(ifaceToFree);
}
/**
@@
-376,8
+513,8
@@
int DoAutoConfig(const char *Device)
// Set routes
{
uint8_t net[4] = {0,0,0,0};
- AddRoute(path + sizeof(IPSTACK_ROOT),
addr, subnet, net);
// This interface
- AddRoute(path + sizeof(IPSTACK_ROOT),
net, 0, gw);
// Gateway
+ AddRoute(path + sizeof(IPSTACK_ROOT),
4, addr, subnet, DEFAULT_METRIC, net);
// This interface
+ AddRoute(path + sizeof(IPSTACK_ROOT),
4, net, 0, DEFAULT_METRIC, gw);
// Gateway
}
close(fd);
@@
-401,7
+538,7
@@
int SetAddress(int IFNum, const char *Address)
int tmp, fd, subnet;
// Parse IP Address
- type = ParseIPAddres(Address, addr, &subnet);
+ type = ParseIPAddres
s
(Address, addr, &subnet);
if(type == 0) {
fprintf(stderr, "'%s' cannot be parsed as an IP address\n", Address);
return -1;
@@
-440,7
+577,7
@@
int SetAddress(int IFNum, const char *Address)
* \brief Parse an IP Address
* \return 0 for unknown, 4 for IPv4 and 6 for IPv6
*/
-int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits)
+int ParseIPAddres
s
(const char *Address, uint8_t *Dest, int *SubnetBits)
{
const char *p = Address;
@@
-485,7
+622,7
@@
int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits)
if(val > 32) {
printf("Notice: Subnet size >32 (%i)\n", val);
}
- *SubnetBits = val;
+
if(SubnetBits)
*SubnetBits = val;
}
if(Address[i] != '\0') {
//printf("EOS != '\\0', '%c'\n", Address[i]);
@@
-560,7
+697,7
@@
int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits)
if(val > 128) {
printf("Notice: Subnet size >128 (%i)\n", val);
}
- *SubnetBits = val;
+
if(SubnetBits)
*SubnetBits = val;
}
for( j = 0; j < split; j ++ )
diff --git
a/Usermode/Libraries/libnet.so_src/net.h
b/Usermode/Libraries/libnet.so_src/net.h
index
f45646f
..
fcd213f
100644
(file)
--- a/
Usermode/Libraries/libnet.so_src/net.h
+++ b/
Usermode/Libraries/libnet.so_src/net.h
@@
-21,6
+21,13
@@
extern int Net_ParseAddress(const char *String, void *Addr);
*/
extern const char *Net_PrintAddress(int AddressType, void *Address);
+/**
+ * \brief Get the size in bytes of an address type
+ * \param AddressType Address type returned by Net_ParseAddress
+ * \return Size of an address in bytes
+ */
+extern int Net_GetAddressSize(int AddressType);
+
/**
* \brief Get the interface required to reach \a Addr
* \param AddrType Addresss Family (4: IPv4, 6: IPv6)
diff --git
a/Usermode/include/acess/sys.h
b/Usermode/include/acess/sys.h
index
368524a
..
ba58ffe
100644
(file)
--- a/
Usermode/include/acess/sys.h
+++ b/
Usermode/include/acess/sys.h
@@
-66,6
+66,7
@@
extern void _SysDebug(const char *format, ...);
extern void _exit(int status) __attribute__((noreturn));
extern void sleep();
extern void yield();
+extern int kill(int pid, int sig);
extern void wait(int miliseconds);
extern int waittid(int id, int *status);
extern int clone(int flags, void *stack);
@@
-73,6
+74,8
@@
extern int execve(char *path, char **argv, char **envp);
extern int gettid();
extern int getpid();
extern int _SysSetFaultHandler(int (*Handler)(int));
+extern void SysSetName(const char *Name);
+//extern int SysGetName(const char *Name);
// --- Permissions ---
extern int getuid();
UCC
git Repository :: git.ucc.asn.au