summaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-29 21:55:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-29 21:55:22 +0000
commit2e723237c932f117a74ddaab66277d1a9bb29cc5 (patch)
tree348228a359338dc71e6949547380bcb316cf5f16 /networking
parent53f83d68fb0e7a12b819f91e21bb85917de6e09a (diff)
downloadbusybox-w32-2e723237c932f117a74ddaab66277d1a9bb29cc5.tar.gz
busybox-w32-2e723237c932f117a74ddaab66277d1a9bb29cc5.tar.bz2
busybox-w32-2e723237c932f117a74ddaab66277d1a9bb29cc5.zip
traceroute: move data off bss. small code optimizations.
function old new delta traceroute_main 4358 4397 +39 verbose 13 9 -4 useicmp 4 - -4 nflag 4 - -4 split_suffices 40 24 -16 route 16 - -16 dumpleases_main 392 357 -35 gwlist 36 - -36 whereto 128 - -128 wherefrom 128 - -128 packet 512 - -512 ------------------------------------------------------------------------------ (add/remove: 0/7 grow/shrink: 1/3 up/down: 39/-883) Total: -844 bytes
Diffstat (limited to 'networking')
-rw-r--r--networking/traceroute.c203
1 files changed, 109 insertions, 94 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c
index fd4c20e6d..552903655 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -284,11 +284,6 @@ struct IFADDRLIST {
284}; 284};
285 285
286 286
287static const char route[] = "/proc/net/route";
288
289/* last inbound (icmp) packet */
290static unsigned char packet[512] ATTRIBUTE_ALIGNED(32);
291
292static struct ip *outip; /* last output (udp) packet */ 287static struct ip *outip; /* last output (udp) packet */
293static struct udphdr *outudp; /* last output (udp) packet */ 288static struct udphdr *outudp; /* last output (udp) packet */
294static struct outdata *outdata; /* last output (udp) packet */ 289static struct outdata *outdata; /* last output (udp) packet */
@@ -297,18 +292,9 @@ static struct outdata *outdata; /* last output (udp) packet */
297static struct icmp *outicmp; /* last output (icmp) packet */ 292static struct icmp *outicmp; /* last output (icmp) packet */
298#endif 293#endif
299 294
300#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
301/* Maximum number of gateways (include room for one noop) */
302#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(uint32_t)))
303/* loose source route gateway list (including room for final destination) */
304static uint32_t gwlist[NGATEWAYS + 1];
305#endif
306
307static int s; /* receive (icmp) socket file descriptor */ 295static int s; /* receive (icmp) socket file descriptor */
308static int sndsock; /* send (udp/icmp) socket file descriptor */ 296static int sndsock; /* send (udp/icmp) socket file descriptor */
309 297
310static struct sockaddr_storage whereto; /* Who to try to reach */
311static struct sockaddr_storage wherefrom; /* Who we are */
312static int packlen; /* total length of packet */ 298static int packlen; /* total length of packet */
313static int minpacket; /* min ip packet size */ 299static int minpacket; /* min ip packet size */
314static int maxpacket = 32 * 1024; /* max ip packet size */ 300static int maxpacket = 32 * 1024; /* max ip packet size */
@@ -320,7 +306,6 @@ static uint16_t ident;
320static uint16_t port = 32768 + 666; /* start udp dest port # for probe packets */ 306static uint16_t port = 32768 + 666; /* start udp dest port # for probe packets */
321 307
322static int waittime = 5; /* time to wait for response (in seconds) */ 308static int waittime = 5; /* time to wait for response (in seconds) */
323static int nflag; /* print addresses numerically */
324static int doipcksum = 1; /* calculate ip checksums by default */ 309static int doipcksum = 1; /* calculate ip checksums by default */
325 310
326#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 311#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
@@ -329,12 +314,56 @@ static int optlen; /* length of ip options */
329#define optlen 0 314#define optlen 0
330#endif 315#endif
331 316
317
318/* Keep in sync with getopt32 call! */
319#define OPT_DONT_FRAGMNT (1<<0) /* F */
320#define OPT_USE_ICMP (1<<1) /* I */
321#define OPT_TTL_FLAG (1<<2) /* l */
322#define OPT_ADDR_NUM (1<<3) /* n */
323#define OPT_BYPASS_ROUTE (1<<4) /* r */
324#define OPT_DEBUG (1<<5) /* d */
325#define OPT_VERBOSE (1<<6) /* v */
326#define OPT_IP_CHKSUM (1<<7) /* x */
327#define OPT_TOS (1<<8) /* t */
328#define OPT_DEVICE (1<<9) /* i */
329#define OPT_MAX_TTL (1<<10) /* m */
330#define OPT_PORT (1<<11) /* p */
331#define OPT_NPROBES (1<<12) /* q */
332#define OPT_SOURCE (1<<13) /* s */
333#define OPT_WAITTIME (1<<14) /* w */
334#define OPT_PAUSE_MS (1<<15) /* z */
335#define OPT_FIRST_TTL (1<<16) /* f */
336
332#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP 337#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP
333static int useicmp; /* use icmp echo instead of udp packets */ 338/* use icmp echo instead of udp packets */
339#define useicmp (option_mask32 & OPT_USE_ICMP)
334#endif 340#endif
335#if ENABLE_FEATURE_TRACEROUTE_VERBOSE 341#if ENABLE_FEATURE_TRACEROUTE_VERBOSE
336static int verbose; 342#define verbose (option_mask32 & OPT_VERBOSE)
337#endif 343#endif
344#define nflag (option_mask32 & OPT_ADDR_NUM)
345
346
347struct globals {
348 /* last inbound (icmp) packet */
349 unsigned char packet[512];
350 struct sockaddr_storage whereto; /* Who to try to reach */
351 struct sockaddr_storage wherefrom; /* Who we are */
352#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
353 /* Maximum number of gateways (include room for one noop) */
354#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(uint32_t)))
355 /* loose source route gateway list (including room for final destination) */
356 uint32_t gwlist[NGATEWAYS + 1];
357#endif
358};
359
360#define G (*ptr_to_globals)
361
362#define packet (G.packet )
363#define whereto (G.whereto )
364#define wherefrom (G.wherefrom)
365#define gwlist (G.gwlist )
366
338 367
339/* 368/*
340 * Return the interface list 369 * Return the interface list
@@ -453,7 +482,7 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
453 struct IFADDRLIST *al; 482 struct IFADDRLIST *al;
454 char buf[256], tdevice[256], device[256]; 483 char buf[256], tdevice[256], device[256];
455 484
456 f = xfopen(route, "r"); 485 f = xfopen("/proc/net/route", "r");
457 486
458 /* Find the appropriate interface */ 487 /* Find the appropriate interface */
459 n = 0; 488 n = 0;
@@ -892,37 +921,40 @@ int traceroute_main(int argc, char *argv[])
892 int code, n; 921 int code, n;
893 unsigned char *outp; 922 unsigned char *outp;
894 uint32_t *ap; 923 uint32_t *ap;
895 struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom; 924 struct sockaddr_in *from;
896 struct sockaddr_in *to = (struct sockaddr_in *)&whereto; 925 struct sockaddr_in *to;
897 struct hostinfo *hi; 926 struct hostinfo *hi;
898 int ttl, probe, i; 927 int ttl, probe, i;
899 int seq = 0; 928 int seq = 0;
900 int tos = 0; 929 int tos = 0;
901 char *tos_str = NULL; 930 char *tos_str;
902 char *source = NULL; 931 char *source;
903 unsigned long op; 932 unsigned op;
904
905#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 933#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
906 int lsrr = 0; 934 int lsrr = 0;
907#endif 935#endif
908 uint16_t off = 0; 936 uint16_t off = 0;
909 struct IFADDRLIST *al; 937 struct IFADDRLIST *al;
910 char *device = NULL; 938 char *device;
911 int max_ttl = 30; 939 int max_ttl = 30;
912 char *max_ttl_str = NULL; 940 char *max_ttl_str;
913 char *port_str = NULL; 941 char *port_str;
914 int nprobes = 3; 942 int nprobes = 3;
915 char *nprobes_str = NULL; 943 char *nprobes_str;
916 char *waittime_str = NULL; 944 char *waittime_str;
917 unsigned pausemsecs = 0; 945 unsigned pausemsecs = 0;
918 char *pausemsecs_str = NULL; 946 char *pausemsecs_str;
919 int first_ttl = 1; 947 int first_ttl = 1;
920 char *first_ttl_str = NULL; 948 char *first_ttl_str;
921#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 949#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
922 llist_t *sourse_route_list = NULL; 950 llist_t *sourse_route_list = NULL;
923#endif 951#endif
924 952
925 opterr = 0; 953 PTR_TO_GLOBALS = xzalloc(sizeof(G));
954 from = (struct sockaddr_in *)&wherefrom;
955 to = (struct sockaddr_in *)&whereto;
956
957 //opterr = 0;
926#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 958#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
927 opt_complementary = "x-x:g::"; 959 opt_complementary = "x-x:g::";
928#else 960#else
@@ -930,65 +962,51 @@ int traceroute_main(int argc, char *argv[])
930#endif 962#endif
931 963
932 op = getopt32(argc, argv, "FIlnrdvxt:i:m:p:q:s:w:z:f:" 964 op = getopt32(argc, argv, "FIlnrdvxt:i:m:p:q:s:w:z:f:"
933#define USAGE_OP_DONT_FRAGMNT (1<<0) /* F */
934#define USAGE_OP_USE_ICMP (1<<1) /* I */
935#define USAGE_OP_TTL_FLAG (1<<2) /* l */
936#define USAGE_OP_ADDR_NUM (1<<3) /* n */
937#define USAGE_OP_BYPASS_ROUTE (1<<4) /* r */
938#define USAGE_OP_DEBUG (1<<5) /* d */
939#define USAGE_OP_VERBOSE (1<<6) /* v */
940#define USAGE_OP_IP_CHKSUM (1<<7) /* x */
941
942#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 965#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
943 "g:" 966 "g:"
944#endif 967#endif
945 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str, 968 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
946 &source, &waittime_str, &pausemsecs_str, &first_ttl_str 969 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str
947#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 970#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
948 , &sourse_route_list 971 , &sourse_route_list
949#endif 972#endif
950 ); 973 );
951 974
952 if (op & USAGE_OP_DONT_FRAGMNT) 975 if (op & OPT_DONT_FRAGMNT)
953 off = IP_DF; 976 off = IP_DF;
954#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP 977 if (op & OPT_IP_CHKSUM) {
955 useicmp = op & USAGE_OP_USE_ICMP;
956#endif
957 nflag = op & USAGE_OP_ADDR_NUM;
958#if ENABLE_FEATURE_TRACEROUTE_VERBOSE
959 verbose = op & USAGE_OP_VERBOSE;
960#endif
961 if (op & USAGE_OP_IP_CHKSUM) {
962 doipcksum = 0; 978 doipcksum = 0;
963 bb_error_msg("warning: ip checksums disabled"); 979 bb_error_msg("warning: ip checksums disabled");
964 } 980 }
965 if (tos_str) 981 if (op & OPT_TOS)
966 tos = xatoul_range(tos_str, 0, 255); 982 tos = xatou_range(tos_str, 0, 255);
967 if (max_ttl_str) 983 if (op & OPT_MAX_TTL)
968 max_ttl = xatoul_range(max_ttl_str, 1, 255); 984 max_ttl = xatou_range(max_ttl_str, 1, 255);
969 if (port_str) 985 if (op & OPT_PORT)
970 port = xatou16(port_str); 986 port = xatou16(port_str);
971 if (nprobes_str) 987 if (op & OPT_NPROBES)
972 nprobes = xatoul_range(nprobes_str, 1, INT_MAX); 988 nprobes = xatou_range(nprobes_str, 1, INT_MAX);
973 if (source) { 989 if (op & OPT_SOURCE) {
974 /* 990 /*
975 * set the ip source address of the outbound 991 * set the ip source address of the outbound
976 * probe (e.g., on a multi-homed host). 992 * probe (e.g., on a multi-homed host).
977 */ 993 */
978 if (getuid()) bb_error_msg_and_die("-s %s: permission denied", source); 994 if (getuid())
995 bb_error_msg_and_die("-s %s: permission denied", source);
979 } 996 }
980 if (waittime_str) 997 if (op & OPT_WAITTIME)
981 waittime = xatoul_range(waittime_str, 2, 24 * 60 * 60); 998 waittime = xatou_range(waittime_str, 2, 24 * 60 * 60);
982 if (pausemsecs_str) 999 if (op & OPT_PAUSE_MS)
983 pausemsecs = xatoul_range(pausemsecs_str, 0, 60 * 60 * 1000); 1000 pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
984 if (first_ttl_str) 1001 if (op & OPT_FIRST_TTL)
985 first_ttl = xatoul_range(first_ttl_str, 1, 255); 1002 first_ttl = xatou_range(first_ttl_str, 1, 255);
986 1003
987#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE 1004#if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE
988 if (sourse_route_list) { 1005 if (sourse_route_list) {
989 llist_t *l_sr; 1006 llist_t *l_sr;
990 1007
991 for (l_sr = sourse_route_list; l_sr; ) { 1008 l_sr = sourse_route_list;
1009 while (l_sr) {
992 if (lsrr >= NGATEWAYS) 1010 if (lsrr >= NGATEWAYS)
993 bb_error_msg_and_die("no more than %d gateways", NGATEWAYS); 1011 bb_error_msg_and_die("no more than %d gateways", NGATEWAYS);
994 getaddr(gwlist + lsrr, l_sr->data); 1012 getaddr(gwlist + lsrr, l_sr->data);
@@ -1046,11 +1064,11 @@ int traceroute_main(int argc, char *argv[])
1046 s = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 1064 s = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
1047 1065
1048#if TRACEROUTE_SO_DEBUG 1066#if TRACEROUTE_SO_DEBUG
1049 if (op & USAGE_OP_DEBUG) 1067 if (op & OPT_DEBUG)
1050 setsockopt(s, SOL_SOCKET, SO_DEBUG, 1068 setsockopt(s, SOL_SOCKET, SO_DEBUG,
1051 &const_int_1, sizeof(const_int_1)); 1069 &const_int_1, sizeof(const_int_1));
1052#endif 1070#endif
1053 if (op & USAGE_OP_BYPASS_ROUTE) 1071 if (op & OPT_BYPASS_ROUTE)
1054 setsockopt(s, SOL_SOCKET, SO_DONTROUTE, 1072 setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
1055 &const_int_1, sizeof(const_int_1)); 1073 &const_int_1, sizeof(const_int_1));
1056 1074
@@ -1102,11 +1120,11 @@ int traceroute_main(int argc, char *argv[])
1102#endif 1120#endif
1103#endif 1121#endif
1104#if TRACEROUTE_SO_DEBUG 1122#if TRACEROUTE_SO_DEBUG
1105 if (op & USAGE_OP_DEBUG) 1123 if (op & OPT_DEBUG)
1106 setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, 1124 setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
1107 &const_int_1, sizeof(const_int_1)); 1125 &const_int_1, sizeof(const_int_1));
1108#endif 1126#endif
1109 if (op & USAGE_OP_BYPASS_ROUTE) 1127 if (op & OPT_BYPASS_ROUTE)
1110 setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, 1128 setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
1111 &const_int_1, sizeof(const_int_1)); 1129 &const_int_1, sizeof(const_int_1));
1112 1130
@@ -1147,22 +1165,21 @@ int traceroute_main(int argc, char *argv[])
1147 n = ifaddrlist(&al); 1165 n = ifaddrlist(&al);
1148 1166
1149 /* Look for a specific device */ 1167 /* Look for a specific device */
1150 if (device != NULL) { 1168 if (op & OPT_DEVICE) {
1151 for (i = n; i > 0; --i, ++al) 1169 for (i = n; i > 0; --i, ++al)
1152 if (strcmp(device, al->device) == 0) 1170 if (strcmp(device, al->device) == 0)
1153 break; 1171 goto found_dev;
1154 if (i <= 0) { 1172 bb_error_msg_and_die("can't find interface %s", device);
1155 bb_error_msg_and_die("can't find interface %s", device);
1156 }
1157 } 1173 }
1174 found_dev:
1158 1175
1159 /* Determine our source address */ 1176 /* Determine our source address */
1160 if (source == NULL) { 1177 if (!(op & OPT_SOURCE)) {
1161 /* 1178 /*
1162 * If a device was specified, use the interface address. 1179 * If a device was specified, use the interface address.
1163 * Otherwise, try to determine our source address. 1180 * Otherwise, try to determine our source address.
1164 */ 1181 */
1165 if (device != NULL) 1182 if (op & OPT_DEVICE)
1166 setsin(from, al->addr); 1183 setsin(from, al->addr);
1167 findsaddr(to, from); 1184 findsaddr(to, from);
1168 } else { 1185 } else {
@@ -1175,21 +1192,19 @@ int traceroute_main(int argc, char *argv[])
1175 * Otherwise, use the first address (and warn if 1192 * Otherwise, use the first address (and warn if
1176 * there are more than one). 1193 * there are more than one).
1177 */ 1194 */
1178 if (device != NULL) { 1195 if (op & OPT_DEVICE) {
1179 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap) 1196 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
1180 if (*ap == al->addr) 1197 if (*ap == al->addr)
1181 break; 1198 goto found_dev2;
1182 if (i <= 0) { 1199 bb_error_msg_and_die("%s is not on interface %s",
1183 bb_error_msg_and_die( 1200 source, device);
1184 "%s is not on interface %s", 1201 found_dev2:
1185 source, device);
1186 }
1187 setsin(from, *ap); 1202 setsin(from, *ap);
1188 } else { 1203 } else {
1189 setsin(from, hi->addrs[0]); 1204 setsin(from, hi->addrs[0]);
1190 if (hi->n > 1) 1205 if (hi->n > 1)
1191 bb_error_msg( 1206 bb_error_msg(
1192 "Warning: %s has multiple addresses; using %s", 1207 "warning: %s has multiple addresses; using %s",
1193 source, inet_ntoa(from->sin_addr)); 1208 source, inet_ntoa(from->sin_addr));
1194 } 1209 }
1195 freehostinfo(hi); 1210 freehostinfo(hi);
@@ -1200,11 +1215,11 @@ int traceroute_main(int argc, char *argv[])
1200 xbind(sndsock, (struct sockaddr *)from, sizeof(*from)); 1215 xbind(sndsock, (struct sockaddr *)from, sizeof(*from));
1201#endif 1216#endif
1202 1217
1203 fprintf(stderr, "traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr)); 1218 printf("traceroute to %s (%s)", hostname, inet_ntoa(to->sin_addr));
1204 if (source) 1219 if (op & OPT_SOURCE)
1205 fprintf(stderr, " from %s", source); 1220 printf(" from %s", source);
1206 fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen); 1221 printf(", %d hops max, %d byte packets\n", max_ttl, packlen);
1207 (void)fflush(stderr); 1222 fflush(stdout);
1208 1223
1209 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { 1224 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
1210 uint32_t lastaddr = 0; 1225 uint32_t lastaddr = 0;
@@ -1239,7 +1254,7 @@ int traceroute_main(int argc, char *argv[])
1239 } 1254 }
1240 printf(" %.3f ms", deltaT(&t1, &t2)); 1255 printf(" %.3f ms", deltaT(&t1, &t2));
1241 ip = (struct ip *)packet; 1256 ip = (struct ip *)packet;
1242 if (op & USAGE_OP_TTL_FLAG) 1257 if (op & OPT_TTL_FLAG)
1243 printf(" (%d)", ip->ip_ttl); 1258 printf(" (%d)", ip->ip_ttl);
1244 if (i == -2) { 1259 if (i == -2) {
1245 if (ip->ip_ttl <= 1) 1260 if (ip->ip_ttl <= 1)