Lines 115-121
Link Here
|
115 |
#endif |
115 |
#endif |
116 |
|
116 |
|
117 |
/* prototypes for statistics.c */ |
117 |
/* prototypes for statistics.c */ |
118 |
void parsesnmp(int, int, int); |
118 |
void parsesnmp(int, int, int, int); |
119 |
void inittab(void); |
119 |
void inittab(void); |
120 |
void parsesnmp6(int, int, int); |
120 |
void parsesnmp6(int, int, int); |
121 |
void inittab6(void); |
121 |
void inittab6(void); |
Lines 773-931
static int igmp_info(void)
Link Here
|
773 |
igmp_do_one, "igmp", "igmp6"); |
773 |
igmp_do_one, "igmp", "igmp6"); |
774 |
} |
774 |
} |
775 |
|
775 |
|
776 |
static int ip_parse_dots(uint32_t *addr, char const *src) { |
776 |
static const char *sctp_socket_state_str(int state) |
777 |
unsigned a, b, c, d; |
777 |
{ |
778 |
unsigned ret = 4-sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d); |
778 |
if(state>=0 && state<=10) |
779 |
*addr = htonl((a << 24)|(b << 16)|(c << 8)|d); |
779 |
return tcp_state[state]; |
780 |
return ret; |
780 |
else { |
781 |
} |
781 |
static char state_str_buf[64]; |
782 |
|
782 |
sprintf(state_str_buf,"UNKNOWN(%d)",state); |
783 |
static void print_ip_service(struct sockaddr_in *addr, char const *protname, |
783 |
return state_str_buf; |
784 |
char *buf, unsigned size) { |
|
|
785 |
struct aftype *ap; |
786 |
|
787 |
if(size == 0) return; |
788 |
|
789 |
/* print host */ |
790 |
if((ap = get_afntype(addr->sin_family)) == NULL) { |
791 |
fprintf(stderr, _("netstat: unsupported address family %d !\n"), |
792 |
addr->sin_family); |
793 |
return; |
794 |
} |
795 |
safe_strncpy(buf, ap->sprint((struct sockaddr*)addr, flag_not), size); |
796 |
|
797 |
/* print service */ |
798 |
if(flag_all || (flag_lst && !addr->sin_port) || (!flag_lst && addr->sin_port)) { |
799 |
char bfs[32]; |
800 |
|
801 |
snprintf(bfs, sizeof(bfs), "%s", |
802 |
get_sname(addr->sin_port, (char*)protname, flag_not & FLAG_NUM_PORT)); |
803 |
|
804 |
/* check if we must cut on host and/or service name */ |
805 |
{ |
806 |
unsigned const bufl = strlen(buf); |
807 |
unsigned const bfsl = strlen(bfs); |
808 |
|
809 |
if(bufl+bfsl+2 > size) { |
810 |
unsigned const half = (size-2)>>1; |
811 |
if(bufl > half) { |
812 |
if(bfsl > half) { |
813 |
buf[size-2-half] = '\0'; |
814 |
bfs[half+1] = '\0'; |
815 |
} |
816 |
else buf[size-2-bfsl] = '\0'; |
817 |
} |
818 |
else bfs[size-2-bufl] = '\0'; |
819 |
} |
820 |
} |
784 |
} |
821 |
strcat(buf, ":"); |
|
|
822 |
strcat(buf, bfs); |
823 |
} |
824 |
} |
785 |
} |
825 |
|
786 |
|
826 |
/* process single SCTP endpoint */ |
787 |
static struct aftype *process_sctp_addr_str(const char *addr_str, struct sockaddr *sa) |
827 |
static void sctp_do_ept(int lnr, char const *line, const char *prot) |
|
|
828 |
{ |
788 |
{ |
829 |
struct sockaddr_in laddr, raddr; |
789 |
if (strchr(addr_str,':')) { |
830 |
unsigned uid, inode; |
790 |
#if HAVE_AFINET6 |
|
|
791 |
extern struct aftype inet6_aftype; |
792 |
/* Demangle what the kernel gives us */ |
793 |
struct in6_addr in6; |
794 |
char addr6_str[INET6_ADDRSTRLEN]; |
795 |
unsigned u0,u1,u2,u3,u4,u5,u6,u7; |
796 |
sscanf(addr_str, "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X", |
797 |
&u0, &u1, &u2, &u3, &u4, &u5, &u6, &u7); |
798 |
in6.s6_addr16[0] = htons(u0); |
799 |
in6.s6_addr16[1] = htons(u1); |
800 |
in6.s6_addr16[2] = htons(u2); |
801 |
in6.s6_addr16[3] = htons(u3); |
802 |
in6.s6_addr16[4] = htons(u4); |
803 |
in6.s6_addr16[5] = htons(u5); |
804 |
in6.s6_addr16[6] = htons(u6); |
805 |
in6.s6_addr16[7] = htons(u7); |
806 |
|
807 |
inet_ntop(AF_INET6, &in6, addr6_str, sizeof(addr6_str)); |
808 |
inet6_aftype.input(1, addr6_str, sa); |
809 |
sa->sa_family = AF_INET6; |
810 |
#endif |
811 |
} else { |
812 |
((struct sockaddr_in*)sa)->sin_addr.s_addr = inet_addr(addr_str); |
813 |
sa->sa_family = AF_INET; |
814 |
} |
815 |
return get_afntype(sa->sa_family); |
816 |
} |
831 |
|
817 |
|
832 |
char l_addr[23], r_addr[23]; |
818 |
static void sctp_eps_do_one(int lnr, char *line, const char *proto) |
|
|
819 |
{ |
820 |
char buffer[1024]; |
821 |
int state, port; |
822 |
int uid; |
823 |
unsigned long inode; |
824 |
struct aftype *ap; |
825 |
#if HAVE_AFINET6 |
826 |
struct sockaddr_in6 localaddr; |
827 |
#else |
828 |
struct sockaddr_in localaddr; |
829 |
#endif |
830 |
const char *sst_str; |
831 |
const char *lport_str; |
832 |
const char *uid_str; |
833 |
const char *inode_str; |
834 |
char *laddrs_str; |
835 |
|
836 |
if(lnr == 0) { |
837 |
/* ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS */ |
838 |
return; |
839 |
} |
840 |
strtok(line," \t\n"); /*skip endpt*/ |
841 |
strtok(0," \t\n"); /*skip sock*/ |
842 |
strtok(0," \t\n"); /*skp sty*/ |
843 |
sst_str = strtok(0," \t\n"); |
844 |
strtok(0," \t\n"); /*skip hash bucket*/ |
845 |
lport_str=strtok(0," \t\n"); |
846 |
uid_str = strtok(0," \t\n"); |
847 |
inode_str = strtok(0," \t\n"); |
848 |
laddrs_str=strtok(0,"\t\n"); |
849 |
|
850 |
if (!sst_str || !lport_str || !uid_str || !inode_str) { |
851 |
fprintf(stderr, _("warning, got bogus sctp eps line.\n")); |
852 |
return; |
853 |
} |
854 |
state = atoi(sst_str); |
855 |
port = atoi(lport_str); |
856 |
uid = atoi(uid_str); |
857 |
inode = strtoul(inode_str,0,0); |
858 |
|
859 |
const char *this_local_addr; |
860 |
int first=1; |
861 |
char local_port[16]; |
862 |
snprintf(local_port, sizeof(local_port), "%s", |
863 |
get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT)); |
864 |
for(this_local_addr=strtok(laddrs_str," \t\n"); |
865 |
this_local_addr; |
866 |
this_local_addr=strtok(0," \t\n")) |
867 |
{ |
868 |
char local_addr[64]; |
869 |
ap = process_sctp_addr_str(this_local_addr, (struct sockaddr*)&localaddr); |
870 |
if(ap) |
871 |
safe_strncpy(local_addr, |
872 |
ap->sprint((struct sockaddr *) &localaddr, flag_not), |
873 |
sizeof(local_addr)); |
874 |
else |
875 |
sprintf(local_addr,_("unsupported address family %d"), ((struct sockaddr*)&localaddr)->sa_family); |
876 |
|
877 |
if(!first) printf("\n"); |
878 |
if(first) |
879 |
printf("sctp "); |
880 |
else |
881 |
printf(" "); |
882 |
sprintf(buffer,"%s:%s", local_addr, local_port); |
883 |
printf("%-47s", buffer); |
884 |
printf(" %-11s", first?sctp_socket_state_str(state):""); |
885 |
first = 0; |
886 |
} |
887 |
finish_this_one(uid,inode,""); |
888 |
} |
889 |
|
890 |
static void sctp_assoc_do_one(int lnr, char *line, const char *proto) |
891 |
{ |
892 |
char buffer[1024]; |
893 |
int state, lport,rport; |
894 |
int uid; |
895 |
unsigned rxqueue,txqueue; |
896 |
unsigned long inode; |
897 |
|
898 |
struct aftype *ap; |
899 |
#if HAVE_AFINET6 |
900 |
struct sockaddr_in6 localaddr,remoteaddr; |
901 |
#else |
902 |
struct sockaddr_in localaddr,remoteaddr; |
903 |
#endif |
904 |
const char *sst_str; |
905 |
const char *txqueue_str; |
906 |
const char *rxqueue_str; |
907 |
const char *lport_str,*rport_str; |
908 |
const char *uid_str; |
909 |
const char *inode_str; |
910 |
char *laddrs_str; |
911 |
char *raddrs_str; |
833 |
|
912 |
|
834 |
/* fill sockaddr_in structures */ |
913 |
if(lnr == 0) { |
835 |
{ |
914 |
/* ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT RPORT LADDRS <-> RADDRS */ |
836 |
unsigned lport; |
915 |
return; |
837 |
unsigned ate; |
916 |
} |
838 |
|
|
|
839 |
if(lnr == 0) return; |
840 |
if(sscanf(line, "%*X %*X %*u %*u %*u %u %u %u %n", |
841 |
&lport, &uid, &inode, &ate) < 3) goto err; |
842 |
|
843 |
/* decode IP address */ |
844 |
if(ip_parse_dots(&laddr.sin_addr.s_addr, line+ate)) goto err; |
845 |
raddr.sin_addr.s_addr = htonl(0); |
846 |
laddr.sin_family = raddr.sin_family = AF_INET; |
847 |
laddr.sin_port = htons(lport); |
848 |
raddr.sin_port = htons(0); |
849 |
} |
850 |
|
917 |
|
851 |
/* print IP:service to l_addr and r_addr */ |
918 |
strtok(line," \t\n"); /*skip assoc*/ |
852 |
print_ip_service(&laddr, prot, l_addr, sizeof(l_addr)); |
919 |
strtok(0," \t\n"); /*skip sock*/ |
853 |
print_ip_service(&raddr, prot, r_addr, sizeof(r_addr)); |
920 |
strtok(0," \t\n"); /*skp sty*/ |
854 |
|
921 |
sst_str = strtok(0," \t\n"); |
855 |
/* Print line */ |
922 |
strtok(0," \t\n"); |
856 |
printf("%-4s %6d %6d %-*s %-*s %-11s", |
923 |
strtok(0," \t\n"); /*skip hash bucket*/ |
857 |
prot, 0, 0, |
924 |
strtok(0," \t\n"); /*skip hash assoc-id*/ |
858 |
(int)netmax(23,strlen(l_addr)), l_addr, |
925 |
txqueue_str = strtok(0," \t\n"); |
859 |
(int)netmax(23,strlen(r_addr)), r_addr, |
926 |
rxqueue_str = strtok(0," \t\n"); |
860 |
_(tcp_state[TCP_LISTEN])); |
927 |
uid_str = strtok(0," \t\n"); |
861 |
finish_this_one(uid, inode, ""); |
928 |
inode_str = strtok(0," \t\n"); |
862 |
return; |
929 |
lport_str=strtok(0," \t\n"); |
863 |
err: |
930 |
rport_str=strtok(0," \t\n"); |
864 |
fprintf(stderr, "SCTP error in line: %d\n", lnr); |
931 |
laddrs_str = strtok(0,"<->\t\n"); |
865 |
} |
932 |
raddrs_str = strtok(0,"<->\t\n"); |
866 |
|
933 |
|
867 |
/* process single SCTP association */ |
934 |
if (!sst_str || !txqueue_str || !rxqueue_str || !uid_str || |
868 |
static void sctp_do_assoc(int lnr, char const *line, const char *prot) |
935 |
!inode_str || !lport_str || !rport_str) { |
869 |
{ |
936 |
fprintf(stderr, _("warning, got bogus sctp assoc line.\n")); |
870 |
struct sockaddr_in laddr, raddr; |
937 |
return; |
871 |
unsigned long rxq, txq; |
938 |
} |
872 |
unsigned uid, inode; |
939 |
|
873 |
|
940 |
state = atoi(sst_str); |
874 |
char l_addr[23], r_addr[23]; |
941 |
txqueue = atoi(txqueue_str); |
875 |
|
942 |
rxqueue = atoi(rxqueue_str); |
876 |
/* fill sockaddr_in structures */ |
943 |
uid = atoi(uid_str); |
877 |
{ |
944 |
inode = strtoul(inode_str,0,0); |
878 |
unsigned lport, rport; |
945 |
lport = atoi(lport_str); |
879 |
unsigned ate; |
946 |
rport = atoi(rport_str); |
880 |
char const *addr; |
947 |
|
881 |
|
948 |
/*print all addresses*/ |
882 |
if(lnr == 0) return; |
949 |
const char *this_local_addr; |
883 |
if(sscanf(line, "%*X %*X %*u %*u %*u %*u %*u %lu %lu %u %u %u %u %n", |
950 |
const char *this_remote_addr; |
884 |
&txq, &rxq, &uid, &inode, &lport, &rport, &ate) < 6) goto err; |
951 |
char *ss1,*ss2; |
885 |
|
952 |
int first=1; |
886 |
/* decode IP addresses */ |
953 |
char local_port[16]; |
887 |
addr = strchr(line+ate, '*'); |
954 |
char remote_port[16]; |
888 |
if(addr == 0) goto err; |
955 |
snprintf(local_port, sizeof(local_port), "%s", |
889 |
if(ip_parse_dots(&laddr.sin_addr.s_addr, ++addr)) goto err; |
956 |
get_sname(htons(lport), proto, |
890 |
addr = strchr(addr, '*'); |
957 |
flag_not & FLAG_NUM_PORT)); |
891 |
if(addr == 0) goto err; |
958 |
snprintf(remote_port, sizeof(remote_port), "%s", |
892 |
if(ip_parse_dots(&raddr.sin_addr.s_addr, ++addr)) goto err; |
959 |
get_sname(htons(rport), proto, |
893 |
|
960 |
flag_not & FLAG_NUM_PORT)); |
894 |
/* complete sockaddr_in structures */ |
961 |
|
895 |
laddr.sin_family = raddr.sin_family = AF_INET; |
962 |
this_local_addr=strtok_r(laddrs_str," \t\n",&ss1); |
896 |
laddr.sin_port = htons(lport); |
963 |
this_remote_addr=strtok_r(raddrs_str," \t\n",&ss2); |
897 |
raddr.sin_port = htons(rport); |
964 |
while(this_local_addr || this_remote_addr) { |
898 |
} |
965 |
char local_addr[64]; |
|
|
966 |
char remote_addr[64]; |
967 |
|
968 |
if(this_local_addr) { |
969 |
if (this_local_addr[0] == '*') { |
970 |
/* skip * */ |
971 |
this_local_addr++; |
972 |
} |
973 |
ap = process_sctp_addr_str(this_local_addr, (struct sockaddr*)&localaddr); |
974 |
if(ap) |
975 |
safe_strncpy(local_addr, |
976 |
ap->sprint((struct sockaddr *) &localaddr, flag_not), sizeof(local_addr)); |
977 |
else |
978 |
sprintf(local_addr,_("unsupported address family %d"), ((struct sockaddr*)&localaddr)->sa_family); |
979 |
} |
980 |
if(this_remote_addr) { |
981 |
if (this_remote_addr[0] == '*') { |
982 |
/* skip * */ |
983 |
this_remote_addr++; |
984 |
} |
985 |
ap = process_sctp_addr_str(this_remote_addr, (struct sockaddr*)&remoteaddr); |
986 |
if(ap) |
987 |
safe_strncpy(remote_addr, |
988 |
ap->sprint((struct sockaddr *) &remoteaddr, flag_not), sizeof(remote_addr)); |
989 |
else |
990 |
sprintf(remote_addr,_("unsupported address family %d"), ((struct sockaddr*)&remoteaddr)->sa_family); |
991 |
} |
899 |
|
992 |
|
900 |
/* print IP:service to l_addr and r_addr */ |
993 |
if(!first) printf("\n"); |
901 |
print_ip_service(&laddr, prot, l_addr, sizeof(l_addr)); |
994 |
if(first) |
902 |
print_ip_service(&raddr, prot, r_addr, sizeof(r_addr)); |
995 |
printf("sctp %6u %6u ", rxqueue, txqueue); |
903 |
|
996 |
else |
904 |
/* Print line */ |
997 |
printf(" "); |
905 |
printf("%-4s %6ld %6ld %-*s %-*s %-11s", |
998 |
if(this_local_addr) { |
906 |
prot, rxq, txq, |
999 |
if(first) |
907 |
(int)netmax(23,strlen(l_addr)), l_addr, |
1000 |
sprintf(buffer,"%s:%s", local_addr, local_port); |
908 |
(int)netmax(23,strlen(r_addr)), r_addr, |
1001 |
else |
909 |
_(tcp_state[TCP_ESTABLISHED])); |
1002 |
sprintf(buffer,"%s", local_addr); |
910 |
finish_this_one(uid, inode, ""); |
1003 |
printf("%-23s", buffer); |
911 |
return; |
1004 |
} else |
912 |
err: |
1005 |
printf("%-23s", ""); |
913 |
fprintf(stderr, "SCTP error in line: %d\n", lnr); |
1006 |
printf(" "); |
|
|
1007 |
if(this_remote_addr) { |
1008 |
if(first) |
1009 |
sprintf(buffer,"%s:%s", remote_addr, remote_port); |
1010 |
else |
1011 |
sprintf(buffer,"%s", remote_addr); |
1012 |
printf("%-23s", buffer); |
1013 |
} else |
1014 |
printf("%-23s", ""); |
1015 |
|
1016 |
printf(" %-11s", first?sctp_socket_state_str(state):""); |
1017 |
|
1018 |
first = 0; |
1019 |
this_local_addr=strtok_r(0," \t\n",&ss1); |
1020 |
this_remote_addr=strtok_r(0," \t\n",&ss2); |
1021 |
} |
1022 |
finish_this_one(uid,inode,""); |
914 |
} |
1023 |
} |
915 |
|
1024 |
|
916 |
static int sctp_info_epts(void) { |
1025 |
static int sctp_info_eps(void) |
|
|
1026 |
{ |
917 |
INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)", |
1027 |
INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)", |
918 |
sctp_do_ept, "sctp", "sctp6"); |
1028 |
sctp_eps_do_one, "sctp", "sctp6"); |
919 |
} |
1029 |
} |
920 |
|
1030 |
|
921 |
static int sctp_info_assocs(void) { |
1031 |
static int sctp_info_assocs(void) { |
922 |
INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)", |
1032 |
INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)", |
923 |
sctp_do_assoc, "sctp", "sctp6"); |
1033 |
sctp_assoc_do_one, "sctp", "sctp6"); |
924 |
} |
1034 |
} |
925 |
|
1035 |
|
926 |
static int sctp_info(void) { |
1036 |
static int sctp_info(void) { |
927 |
int res; |
1037 |
int res; |
928 |
res = sctp_info_epts(); |
1038 |
res = sctp_info_eps(); |
929 |
if(res) return res; |
1039 |
if(res) return res; |
930 |
return sctp_info_assocs(); |
1040 |
return sctp_info_assocs(); |
931 |
} |
1041 |
} |
Lines 2094-2100
int main
Link Here
|
2094 |
if (!strcmp(afname, "inet")) { |
2204 |
if (!strcmp(afname, "inet")) { |
2095 |
#if HAVE_AFINET |
2205 |
#if HAVE_AFINET |
2096 |
inittab(); |
2206 |
inittab(); |
2097 |
parsesnmp(flag_raw, flag_tcp, flag_udp); |
2207 |
parsesnmp(flag_raw, flag_tcp, flag_udp, flag_sctp); |
2098 |
#else |
2208 |
#else |
2099 |
ENOSUPP("netstat", "AF INET"); |
2209 |
ENOSUPP("netstat", "AF INET"); |
2100 |
#endif |
2210 |
#endif |