@@ -95,6 +95,154 @@ unsigned int daemons(const in_port_t server_port)
9595
9696 return nbcnx ;
9797}
98+
99+ #ifndef IN_PURE_MRTGINFO
100+ static unsigned int count_perip (in_port_t server_port ,
101+ const struct sockaddr_storage * peer ,
102+ const char * const file )
103+ {
104+ int f ;
105+ int r ;
106+ int c ;
107+ int b = 0 ;
108+ int e = 0 ;
109+ unsigned int d = 0U ;
110+ char buf [2049 ];
111+ unsigned char peer_bytes [16 ];
112+ size_t peer_len ;
113+ int is_ipv6 = (STORAGE_FAMILY (* peer ) == AF_INET6 );
114+
115+ if (is_ipv6 ) {
116+ memcpy (peer_bytes , & STORAGE_SIN_ADDR6_CONST (* peer ), 16 );
117+ peer_len = 16 ;
118+ } else {
119+ memcpy (peer_bytes , & STORAGE_SIN_ADDR_CONST (* peer ), 4 );
120+ peer_len = 4 ;
121+ }
122+
123+ if ((f = open (file , O_RDONLY )) == -1 ) {
124+ return 0 ;
125+ }
126+ buf [2048 ] = 0 ;
127+
128+ for (;;) {
129+ while ((r = (int ) read (f , buf + e , (size_t ) (2048U - e )))
130+ < (ssize_t ) 0 && errno == EINTR );
131+ if (r <= (ssize_t ) 0 ) {
132+ break ;
133+ }
134+ e += r ;
135+
136+ c = b ;
137+ while (c < e && buf [c ] != '\n' ) {
138+ c ++ ;
139+ }
140+ while (c < e ) {
141+ buf [c ++ ] = 0 ;
142+ while (b < c && buf [b ] != ':' && buf [b ] != '\n' ) {
143+ b ++ ;
144+ }
145+ if (b < c && buf [b ] == ':' ) {
146+ b ++ ;
147+ while (b < e && buf [b ] != ':' ) {
148+ b ++ ;
149+ }
150+ b ++ ;
151+ if (strtoul (buf + b , NULL , 16 ) ==
152+ (unsigned long ) server_port ) {
153+ while (b < e && buf [b ] != ' ' ) {
154+ b ++ ;
155+ }
156+ if (buf [b ] == ' ' ) {
157+ unsigned char remote_bytes [16 ];
158+ char * hex_start = buf + b + 1 ;
159+ char * colon ;
160+ size_t hex_len ;
161+ size_t i ;
162+ int match = 1 ;
163+
164+ colon = strchr (hex_start , ':' );
165+ if (colon != NULL ) {
166+ hex_len = (size_t )(colon - hex_start );
167+ if ((hex_len == 8 && peer_len == 4 ) ||
168+ (hex_len == 32 && peer_len == 16 )) {
169+ for (i = 0 ; i < peer_len ; i ++ ) {
170+ unsigned int byte_val ;
171+ char hex_byte [3 ];
172+ hex_byte [0 ] = hex_start [i * 2 ];
173+ hex_byte [1 ] = hex_start [i * 2 + 1 ];
174+ hex_byte [2 ] = 0 ;
175+ byte_val = (unsigned int ) strtoul (hex_byte , NULL , 16 );
176+ remote_bytes [i ] = (unsigned char ) byte_val ;
177+ }
178+ if (peer_len == 4 ) {
179+ unsigned char swapped [4 ];
180+ swapped [0 ] = remote_bytes [3 ];
181+ swapped [1 ] = remote_bytes [2 ];
182+ swapped [2 ] = remote_bytes [1 ];
183+ swapped [3 ] = remote_bytes [0 ];
184+ memcpy (remote_bytes , swapped , 4 );
185+ } else {
186+ unsigned char swapped [16 ];
187+ for (i = 0 ; i < 4 ; i ++ ) {
188+ swapped [i * 4 + 0 ] = remote_bytes [i * 4 + 3 ];
189+ swapped [i * 4 + 1 ] = remote_bytes [i * 4 + 2 ];
190+ swapped [i * 4 + 2 ] = remote_bytes [i * 4 + 1 ];
191+ swapped [i * 4 + 3 ] = remote_bytes [i * 4 + 0 ];
192+ }
193+ memcpy (remote_bytes , swapped , 16 );
194+ }
195+ for (i = 0 ; i < peer_len ; i ++ ) {
196+ if (remote_bytes [i ] != peer_bytes [i ]) {
197+ match = 0 ;
198+ break ;
199+ }
200+ }
201+ if (match ) {
202+ while (b < e && buf [b ] != ' ' ) {
203+ b ++ ;
204+ }
205+ b ++ ;
206+ if (strtoul (buf + b , NULL , 16 ) == TCP_STATE_CNX ) {
207+ d ++ ;
208+ }
209+ }
210+ }
211+ }
212+ }
213+ }
214+ }
215+ b = c ;
216+ while (c < e && buf [c ] != '\n' ) {
217+ c ++ ;
218+ }
219+ }
220+ if (e > b ) {
221+ (void ) memmove (buf , buf + b , (size_t ) (e - b ));
222+ }
223+ e -= b ;
224+ b = 0 ;
225+ }
226+ close (f );
227+
228+ return d ;
229+ }
230+
231+ unsigned int daemons_perip (const in_port_t server_port ,
232+ const struct sockaddr_storage * peer )
233+ {
234+ unsigned int nbcnx ;
235+
236+ if (STORAGE_FAMILY (* peer ) == AF_INET6 ) {
237+ nbcnx = count_perip (server_port , peer , "/proc/net/tcp6" );
238+ } else {
239+ nbcnx = count_perip (server_port , peer , "/proc/net/tcp" );
240+ }
241+
242+ return nbcnx ;
243+ }
244+ #endif
245+
98246#else
99247extern signed char v6ready ;
100248#endif
0 commit comments