udpserv04.lc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "unpifi.h"## 1 ##src/advio/udpserv04.c##
  2. void mydg_echo(int, SA *, socklen_t);## 2 ##src/advio/udpserv04.c##
  3. int## 3 ##src/advio/udpserv04.c##
  4. main(int argc, char **argv)## 4 ##src/advio/udpserv04.c##
  5. {## 5 ##src/advio/udpserv04.c##
  6. int sockfd, family, port;## 6 ##src/advio/udpserv04.c##
  7. const int on = 1;## 7 ##src/advio/udpserv04.c##
  8. pid_t pid;## 8 ##src/advio/udpserv04.c##
  9. socklen_t salen;## 9 ##src/advio/udpserv04.c##
  10. struct sockaddr *sa, *wild;## 10 ##src/advio/udpserv04.c##
  11. struct ifi_info *ifi, *ifihead;## 11 ##src/advio/udpserv04.c##
  12. if (argc == 2)## 12 ##src/advio/udpserv04.c##
  13. sockfd = Udp_client(NULL, argv[1], (void **) &sa, &salen);## 13 ##src/advio/udpserv04.c##
  14. else if (argc == 3)## 14 ##src/advio/udpserv04.c##
  15. sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 15 ##src/advio/udpserv04.c##
  16. else## 16 ##src/advio/udpserv04.c##
  17. err_quit("usage: udpserv04 [ <host> ] <service or port>");## 17 ##src/advio/udpserv04.c##
  18. family = sa->sa_family;## 18 ##src/advio/udpserv04.c##
  19. port = sock_get_port(sa, salen);## 19 ##src/advio/udpserv04.c##
  20. Close(sockfd); /* we just want family, port, salen */## 20 ##src/advio/udpserv04.c##
  21. for (ifihead = ifi = Get_ifi_info(family, 1);## 21 ##src/advio/udpserv04.c##
  22. ifi != NULL; ifi = ifi->ifi_next) {## 22 ##src/advio/udpserv04.c##
  23. /* 4bind unicast address */## 23 ##src/advio/udpserv04.c##
  24. sockfd = Socket(family, SOCK_DGRAM, 0);## 24 ##src/advio/udpserv04.c##
  25. Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 25 ##src/advio/udpserv04.c##
  26. sock_set_port(ifi->ifi_addr, salen, port);## 26 ##src/advio/udpserv04.c##
  27. Bind(sockfd, ifi->ifi_addr, salen);## 27 ##src/advio/udpserv04.c##
  28. printf("bound %s\n", Sock_ntop(ifi->ifi_addr, salen));## 28 ##src/advio/udpserv04.c##
  29. if ((pid = Fork()) == 0) { /* child */## 29 ##src/advio/udpserv04.c##
  30. mydg_echo(sockfd, ifi->ifi_addr, salen);## 30 ##src/advio/udpserv04.c##
  31. exit(0); /* never executed */## 31 ##src/advio/udpserv04.c##
  32. }## 32 ##src/advio/udpserv04.c##
  33. if (ifi->ifi_flags & IFF_BROADCAST) {## 33 ##src/advio/udpserv04.c##
  34. /* 4try to bind broadcast address */## 34 ##src/advio/udpserv04.c##
  35. sockfd = Socket(family, SOCK_DGRAM, 0);## 35 ##src/advio/udpserv04.c##
  36. Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 36 ##src/advio/udpserv04.c##
  37. sock_set_port(ifi->ifi_brdaddr, salen, port);## 37 ##src/advio/udpserv04.c##
  38. if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) {## 38 ##src/advio/udpserv04.c##
  39. if (errno == EADDRINUSE) {## 39 ##src/advio/udpserv04.c##
  40. printf("EADDRINUSE: %s\n",## 40 ##src/advio/udpserv04.c##
  41. Sock_ntop(ifi->ifi_brdaddr, salen));## 41 ##src/advio/udpserv04.c##
  42. Close(sockfd);## 42 ##src/advio/udpserv04.c##
  43. continue;## 43 ##src/advio/udpserv04.c##
  44. } else## 44 ##src/advio/udpserv04.c##
  45. err_sys("bind error for %s",## 45 ##src/advio/udpserv04.c##
  46. Sock_ntop(ifi->ifi_brdaddr, salen));## 46 ##src/advio/udpserv04.c##
  47. }## 47 ##src/advio/udpserv04.c##
  48. printf("bound %s\n", Sock_ntop(ifi->ifi_brdaddr, salen));## 48 ##src/advio/udpserv04.c##
  49. if ((pid = Fork()) == 0) { /* child */## 49 ##src/advio/udpserv04.c##
  50. mydg_echo(sockfd, ifi->ifi_brdaddr, salen);## 50 ##src/advio/udpserv04.c##
  51. exit(0); /* never executed */## 51 ##src/advio/udpserv04.c##
  52. }## 52 ##src/advio/udpserv04.c##
  53. }## 53 ##src/advio/udpserv04.c##
  54. }## 54 ##src/advio/udpserv04.c##
  55. /* 4bind wildcard address */## 55 ##src/advio/udpserv04.c##
  56. sockfd = Socket(family, SOCK_DGRAM, 0);## 56 ##src/advio/udpserv04.c##
  57. Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 57 ##src/advio/udpserv04.c##
  58. wild = Malloc(salen);## 58 ##src/advio/udpserv04.c##
  59. memcpy(wild, sa, salen); /* copy family and port */## 59 ##src/advio/udpserv04.c##
  60. sock_set_wild(wild, salen);## 60 ##src/advio/udpserv04.c##
  61. Bind(sockfd, wild, salen);## 61 ##src/advio/udpserv04.c##
  62. printf("bound %s\n", Sock_ntop(wild, salen));## 62 ##src/advio/udpserv04.c##
  63. if ((pid = Fork()) == 0) { /* child */## 63 ##src/advio/udpserv04.c##
  64. mydg_echo(sockfd, wild, salen);## 64 ##src/advio/udpserv04.c##
  65. exit(0); /* never executed */## 65 ##src/advio/udpserv04.c##
  66. }## 66 ##src/advio/udpserv04.c##
  67. exit(0);## 67 ##src/advio/udpserv04.c##
  68. }## 68 ##src/advio/udpserv04.c##
  69. void## 69 ##src/advio/udpserv04.c##
  70. mydg_echo(int sockfd, SA *myaddr, socklen_t salen)## 70 ##src/advio/udpserv04.c##
  71. {## 71 ##src/advio/udpserv04.c##
  72. int n;## 72 ##src/advio/udpserv04.c##
  73. char mesg[MAXLINE];## 73 ##src/advio/udpserv04.c##
  74. socklen_t len;## 74 ##src/advio/udpserv04.c##
  75. struct sockaddr *cli;## 75 ##src/advio/udpserv04.c##
  76. cli = Malloc(salen);## 76 ##src/advio/udpserv04.c##
  77. for (;;) {## 77 ##src/advio/udpserv04.c##
  78. len = salen;## 78 ##src/advio/udpserv04.c##
  79. n = Recvfrom(sockfd, mesg, MAXLINE, 0, cli, &len);## 79 ##src/advio/udpserv04.c##
  80. printf("child %d, datagram from %s", getpid(), Sock_ntop(cli, len));## 80 ##src/advio/udpserv04.c##
  81. printf(", to %s\n", Sock_ntop(myaddr, salen));## 81 ##src/advio/udpserv04.c##
  82. Sendto(sockfd, mesg, n, 0, cli, len);## 82 ##src/advio/udpserv04.c##
  83. }## 83 ##src/advio/udpserv04.c##
  84. }## 84 ##src/advio/udpserv04.c##