Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Portage & Programming
  • Search

[Solved] How do you receive ICMP messages in a C program

Problems with emerge or ebuilds? Have a basic programming question about C, PHP, Perl, BASH or something else?
Post Reply
Advanced search
7 posts • Page 1 of 1
Author
Message
TJNII
l33t
l33t
User avatar
Posts: 648
Joined: Sun Nov 09, 2003 3:16 am
Location: for(;;);

[Solved] How do you receive ICMP messages in a C program

  • Quote

Post by TJNII » Wed Dec 30, 2009 3:45 am

When writing a network application in C, how do you receive ICMP packets? If my application sends a packet that triggers an ICMP response, how do I recieve and parse it? Since ICMP is part of IP, I would expect the kernel to parse it and pass me a code somehow, but how? I'd like to know the method that doesn't require raw sockets.

The backstory:
I'm building a embedded, network attached device. It has no display, and I've tried to be as standards compliant as possible. If the device doesn't like a packet and there is an ICMP response for it, it uses the ICMP response. I'd like the partner application running on the PC to catch and log it, since the device doesn't have the recourses for a log.
Last edited by TJNII on Thu Dec 31, 2009 11:12 pm, edited 1 time in total.
Top
patrikas
Tux's lil' helper
Tux's lil' helper
Posts: 106
Joined: Sat Nov 28, 2009 3:35 pm

  • Quote

Post by patrikas » Wed Dec 30, 2009 9:03 am

A question, why avoiding raw sockets ? It's a standart way of doing this, because ICMP is not originally meant to be used for communications in application level and it's actually an integral part of IP protocol. I'd just simply do:

Code: Select all

rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
Then read(2) it and evaluate using structures defined in */include/netinet/ip.h and */include/netinet/ip_icmp.h".
Top
Hu
Administrator
Administrator
Posts: 24403
Joined: Tue Mar 06, 2007 5:38 am

  • Quote

Post by Hu » Wed Dec 30, 2009 5:27 pm

What type of packet are you sending? If you are sending ICMP, like ping would, then consult the ping source for a reference. If you are sending normal TCP or UDP traffic and expecting ICMP responses for exceptional errors, such as sending UDP to a closed port, then you should be able to get the error back as a failure on your next read of the socket. Try echo | strace socat udp4:ip:port - where ip:port points to a machine which is up, but not providing UDP service on that port. Compare the strace output with a tcpdump collected at the same time.

[Edit: fixed mistake in use of forum code.]
Last edited by Hu on Wed Dec 30, 2009 10:46 pm, edited 1 time in total.
Top
TJNII
l33t
l33t
User avatar
Posts: 648
Joined: Sun Nov 09, 2003 3:16 am
Location: for(;;);

  • Quote

Post by TJNII » Wed Dec 30, 2009 6:36 pm

Hu wrote:If you are sending normal TCP or UDP traffic and expecting ICMP responses for exceptional errors
This is exactly what I am doing. I plan to preform normal communications using UDP. I want to know of ICMP responses as they signify something is very wrong or I have a bug in my firmware.
Hu wrote:You should be able to get the error back as a failure on your next read of the socket.
This is what I expected, but the man page doesn't show the returned errnos as being very verbose. I'm probably just not looking in the right place for documentation. I suppose the distilled version of this question would be "What does the kernel do with ICMP error responses and how does my program check for errors it caused?"
Hu wrote:Try echo | strace socat udp4:ip:port - where ip:port points to a machine which is up, but not providing UDP service on that port. Compare the strace output with a tcpdump collected at the same time.

.....yea, but there are a couple things I don't like about going that route. The main one is I'd really like to find some documentation on the proper error codes returned. I don't want to take the old "suck it and see" approach for this project. I can if I must, I'd prefer not to. Also, I plan to write my applications in C, so I'd expect to catch the problem through errno on a failed read. Will the strace output give me the errnos?

patrikas wrote:A question, why avoiding raw sockets ?

Well, for two reasons. First, I don't believe I should have to. In this situation an ICMP response will signify some kind of major error or bug. I have no problems with my program failing because it received an ICMP response. I just want to know how I can receive the details of the message, or at least what the specific message was so I can debug. Secondly, and this may be an incorrect assumption on my part, since raw sockets happen below the TCP/UDP layer they should receive all IP traffic for the system. I would expect this to be a security risk and as such require some elevated privileges. I don't want to need elevated privileges, and I don't want to have to preform the packet filtering myself.
Top
patrikas
Tux's lil' helper
Tux's lil' helper
Posts: 106
Joined: Sat Nov 28, 2009 3:35 pm

  • Quote

Post by patrikas » Wed Dec 30, 2009 8:37 pm

Well, if you want to receive ICMP packets for a particular datagram socket you need to use IP_RECVERR socket option, then when socket operation triggers an error you should call recvmsg(2) with MSG_ERRQUEUE flag. See "man 7 ip" and search for IP_RECVERR.

No, raw socket will receive only packets or errors matching protocol number, which is IPPROTO_ICMP
Top
Hu
Administrator
Administrator
Posts: 24403
Joined: Tue Mar 06, 2007 5:38 am

  • Quote

Post by Hu » Wed Dec 30, 2009 10:47 pm

TJNII wrote:Also, I plan to write my applications in C, so I'd expect to catch the problem through errno on a failed read. Will the strace output give me the errnos?
Yes. It provides the decoded error code, so you even get the symbolic name.
Top
TJNII
l33t
l33t
User avatar
Posts: 648
Joined: Sun Nov 09, 2003 3:16 am
Location: for(;;);

  • Quote

Post by TJNII » Thu Dec 31, 2009 11:12 pm

patrikas wrote:Well, if you want to receive ICMP packets for a particular datagram socket you need to use IP_RECVERR socket option, then when socket operation triggers an error you should call recvmsg(2) with MSG_ERRQUEUE flag. See "man 7 ip" and search for IP_RECVERR.
This is what I was looking for, thanks.
Top
Post Reply

7 posts • Page 1 of 1

Return to “Portage & Programming”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy

 

 

magic