File: services.c

package info (click to toggle)
nessus-libraries 2.2.10-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,884 kB
  • ctags: 2,550
  • sloc: ansic: 21,402; sh: 8,231; makefile: 421; yacc: 234; lex: 203
file content (175 lines) | stat: -rw-r--r-- 3,963 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* 
 * Copyright (C) 2002 Michel Arboi
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * TCP/IP service functions (getservent enhancement)
 */ 

#define EXPORTING
#include <includes.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#ifndef MAP_FAILED
#define MAP_FAILED ((void*)-1)
#endif

#include "services.h"
#include "libnessus.h"

/* IMPORTANT ! Some options are defined in services.h */

static int
cmp_ns_svc(const void *v1,
	   const void *v2)
{
  const struct nessus_service * p1 = v1;
  const struct nessus_service * p2 = v2;
  
  if(v1 == NULL)
  	return 1;
  else if(v2 == NULL)
  	return -1;
  
  return p1->ns_port - p2->ns_port;
}

ExtFunc const char*
nessus_get_svc_name(int port, const char* proto)
{
  static struct nessus_service		*svc_db_ptr[2] = { NULL, NULL };
  static int				nb_svc[2];

  int			fd = -1, len, idx;
  struct stat		st;
  struct nessus_service	*pns, kns;
  struct servent	*svc;


  if (proto != NULL && strcmp(proto, "udp") == 0)
    idx = 1;
  else
    idx = 0;			/* default to TCP */

  if (svc_db_ptr[idx] == NULL)
    {
      if ((fd = open(idx ? NESSUS_SERVICES_UDP : NESSUS_SERVICES_TCP, O_RDONLY)) >= 0)
	{
	  if (fstat(fd, &st) < 0)
	    perror("fstat");
	  else
	    {
	      len = st.st_size;
	      nb_svc[idx] = len / sizeof(struct nessus_service);
	      if ((svc_db_ptr[idx] = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0))== MAP_FAILED )
		{
		perror("mmap");
		svc_db_ptr[idx] = NULL;
		}
	    }
	}
    }

  if (svc_db_ptr[idx] == NULL)
    {
      if (fd > 0)
	close(fd);
    }
  else
    {
      kns.ns_port = port;
      pns = bsearch(&kns, svc_db_ptr[idx], nb_svc[idx], sizeof(kns), cmp_ns_svc);
      if (pns != NULL)
	return pns->ns_name;
#ifdef NESSUS_SVC_READS_ETC_SERVICES
      else
	return "unknown";
#endif
    }

  setservent(1); /* Rewinds /etc/services and keep the file open */
  svc = getservbyport(htons((unsigned short) port), proto);
  if (svc == NULL)
    return "unknown";
  else
    return svc->s_name;
}


ExtFunc unsigned short * get_tcp_svcs(int * num)
{
  struct nessus_service * ns = NULL;
  int len, num_svc;
  unsigned short * ret;
  int fd, i;
  struct stat st;

  if ((fd = open(NESSUS_SERVICES_TCP, O_RDONLY)) >= 0)
	{
	  if (fstat(fd, &st) < 0)
	    perror("fstat");
	  else
	    {
	      len = st.st_size;
	      num_svc = len / sizeof(struct nessus_service);
	      if ((ns = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0))== MAP_FAILED ) {
		perror("mmap");
		ns = NULL;
	}
	    }
	}

  if (ns == NULL)
    {
	    struct servent  * ent;
	    int n = 0;
	    ret = emalloc(sizeof(unsigned short) * 65537);
	    endservent();
	    while ( (ent = getservent()) != NULL )
	    {
		    if(strcmp(ent->s_proto, "tcp") == 0 && ntohs(ent->s_port))
		    {
		    ret[n++] = ntohs(ent->s_port);
		    if(n >= 65537)break;
		    }
	    }
	    endservent();

	    if(num != NULL)
		    *num = n;

	    ret = erealloc(ret, sizeof(unsigned short) * (n+1)); 
	    ret[n] = 0;
	    return ret;
    }
  else
    {
	    ret = emalloc(sizeof(unsigned short) * (num_svc + 1));
	    for(i=0;i<num_svc;i++)
	    {
		    ret[i] = ns[i].ns_port;
 	    }
	    if(num != NULL)
		    *num = num_svc;

	    munmap(ns, len);
	    close(fd);
    }
 return ret;
}