--- l2_sockmon.c 2001/09/06 14:31:33 1.2
+++ l2_sockmon.c 2001/09/06 19:29:14 1.3
@@ -36,7 +36,7 @@
#define BACKLOG 1024 /* max # pending connections */
#define BUFFSIZ 256 /* max string size */
-char *strcasedup(const char *pszIn)
+char *strlowerdup(const char *pszIn)
{
int i = 0;
char *pszTemp = NULL;
@@ -88,22 +88,39 @@
int myserver(int iFamily, int iProtocol, int iPort)
{
- struct sockaddr_in laddr, faddr;
- int iSock, iNewsock, iSockopt, iProtofam;
+ char pszBuf[BUFFSIZ];
+ struct sockaddr_in laddr4, faddr4, caddr4;
+ struct sockaddr_in6 laddr6, faddr6, caddr6;
+ int iSock, iNewsock;
+ int iSockopt, iProtofam;
+ int iTrans, cc;
socklen_t faddrlen;
/* ASSERT(iPort);*/
/* Set up an IPv4 TCP socket to listen on for connections. */
- laddr.sin_family = iFamily;
- laddr.sin_port = iPort;
- laddr.sin_addr.s_addr = INADDR_ANY;
+ if (iFamily == AF_INET6)
+ {
+ laddr6.sin6_family = AF_INET6;
+ laddr6.sin6_flowinfo = 0;
+ laddr6.sin6_port = iPort;
+ laddr6.sin6_addr = in6addr_any; /* Structure assignment */
+ }
+ else if (iFamily == AF_INET)
+ {
+ laddr4.sin_family = AF_INET;
+ laddr4.sin_port = iPort;
+ laddr4.sin_addr.s_addr = INADDR_ANY;
+ }
+ else
+ return -1; /* Not IPv4 or IPv6 */
- iProtofam = (iFamily == AF_INET) ? PF_INET : PF_INET6;
- iSock = socket(iProtofam, SOCK_STREAM, iProtocol);
+ iProtofam = (iFamily == AF_INET) ? PF_INET : PF_INET6;
+ iTrans = (iProtocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
+ iSock = socket(iProtofam, iTrans, iProtocol);
if (iSock == -1) {
perror("socket");
- return (-1);
+ return -1;
}
/* Tell the system to allow local addresses to be reused. */
@@ -112,54 +129,148 @@
sizeof (iSockopt)) == -1) {
perror("setsockopt(SO_REUSEADDR)");
(void) close(iSock);
- return (-1);
+ return -1;
}
- if (bind(iSock, (struct sockaddr *)&laddr, sizeof (laddr)) == -1) {
- perror("bind"); /* Bad bind */
- (void) close(iSock);
- return (-1);
+
+ if (iFamily == AF_INET6) {
+ if (bind(iSock, (struct sockaddr *)&laddr6, sizeof (laddr6)) == -1) {
+ perror("bind"); /* Bad bind */
+ (void) close(iSock);
+ return -1;
+ }
+ }
+ else if (iFamily == AF_INET) {
+ if (bind(iSock, (struct sockaddr *)&laddr4, sizeof (laddr4)) == -1) {
+ perror("bind"); /* Bad bind */
+ (void) close(iSock);
+ return -1;
+ }
+ }
+
+ if (iProtocol == IPPROTO_UDP) {
+ if (iFamily == AF_INET6) {
+ for (;;) { /* Receive messages */
+ faddrlen = sizeof(caddr6);
+ memset(pszBuf, 0x0, BUFFSIZ); /* Init the buffer */
+ cc = recvfrom(iSock, pszBuf, BUFFSIZ, 0, (struct sockaddr *)\
+ &caddr6, &faddrlen);
+
+ if (cc == -1) {
+ perror("recvfrom");
+ exit(1);
+ }
+
+ if (cc == 0) {
+ /* EOF */
+ (void) close(iSock);
+ (void) printf("Connection closed\n");
+ return;
+ }
+
+ if (cc != BUFFSIZ) {
+ pszBuf[cc + 1] = '\0';
+ (void) printf("Read: %s", pszBuf);
+
+ if (write(iSock, pszBuf, cc) == -1) {
+ perror("write");
+ exit(1);
+ }
+ }
+ else
+ return -1;
+ }
+ }
+ else if (iFamily == AF_INET) {
+ for (;;) { /* Receive messages */
+ faddrlen = sizeof(caddr4);
+ memset(pszBuf, 0x0, BUFFSIZ); /* Init the buffer */
+ cc = recvfrom(iSock, pszBuf, BUFFSIZ, 0, (struct sockaddr *)\
+ &caddr4, &faddrlen);
+
+ if (cc == -1) {
+ perror("recvfrom");
+ exit(1);
+ }
+
+ if (cc == 0) {
+ /* EOF */
+ (void) close(iSock);
+ (void) printf("Connection closed\n");
+ return;
+ }
+
+ if (cc != BUFFSIZ) {
+ pszBuf[cc + 1] = '\0';
+ (void) printf("Read: %s", pszBuf);
+
+ if (write(iSock, pszBuf, cc) == -1) {
+ perror("write");
+ exit(1);
+ }
+ }
+ else
+ return -1;
+ }
}
-fprintf(stderr, "Listening on %d or 0x%x\n", iPort, iPort);
- if (listen(iSock, BACKLOG) == -1) {
- perror("listen"); /* Listen just blew up */
- (void) close(iSock);
- return (-1);
}
- /* Wait for a connection request. */
- for (;;) {
- faddrlen = sizeof (faddr);
- iNewsock = accept(iSock, (struct sockaddr *)&faddr, &faddrlen);
- if (iNewsock == -1) {
- if (errno != EINTR && errno != ECONNABORTED) {
- perror("accept");
+ else if (iProtocol == IPPROTO_TCP) { /* Only try to listen if we have TCP */
+ if (listen(iSock, BACKLOG) == -1) {
+ perror("listen"); /* Listen just blew up */
+ (void) close(iSock);
+ return -1;
+ }
+
+ /* Wait for a connection request */
+ if (iFamily == AF_INET6) {
+ for (;;) {
+ faddrlen = sizeof (faddr6);
+ iNewsock = accept(iSock, (struct sockaddr *)&faddr6, &faddrlen);
+ if (iNewsock == -1) {
+ if (errno != EINTR && errno != ECONNABORTED) {
+ perror("accept");
+ }
+ continue;
+ }
+ (void) printf("Connection from %s/%d\n",\
+ inet_ntop(faddr6.sin6_addr), ntohs(faddr6.sin6_port));
+ dowork(iNewsock); /* do some sockwork */
+ }
+ }
+ else if (iFamily == AF_INET) {
+ for (;;) {
+ faddrlen = sizeof (faddr4);
+ iNewsock = accept(iSock, (struct sockaddr *)&faddr4, &faddrlen);
+ if (iNewsock == -1) {
+ if (errno != EINTR && errno != ECONNABORTED) {
+ perror("accept");
+ }
+ continue;
+ }
+ (void) printf("Connection from %s/%d\n",\
+ inet_ntop(faddr4.sin_addr), ntohs(faddr4.sin_port));
+ dowork(iNewsock); /* do some sockwork */
}
- continue;
}
- (void) printf("Connection from %s/%d\n", inet_ntoa(faddr.sin_addr), ntohs(faddr.sin_port));
- dowork(iNewsock); /* do some sockwork */
+ /* NOTREACHED */
}
- /*NOTREACHED*/
+ else
+ return -1; /* We are being asked to serve other than TCP or UDP */
}
int main(int argc, char *argv[])
{
- char *pszArgv = NULL;
- int iFamily = -1;
- int iNetproto = -1;
- int iNetport = 0;
+ int iFam = -1;
+ int iProto = -1;
+ int iPort = 0;
- if (argc < 2) {
- (void) fprintf(stderr, "Usage: %s [IPv6] [UDP] <Port>\n", argv[0]);
+ if (argc != 4) {
+ (void) fprintf(stderr, "Usage: %s <IPv4-or-IPv6> <TCP-or-UDP> <Port>\n", argv[0]);
exit(1); /* Dink donk if the user doesn't know how to use this */
}
- if ((pszArgv = strcasedup(*argv)) == NULL)
- return -1;
-
- iFamily = (strstr(pszArgv, "ipv6")) ? AF_INET6 : AF_INET;
- iNetproto = (strstr(pszArgv, "udp")) ? IPPROTO_UDP : IPPROTO_TCP;
- iNetport = htons(atoi(argv[argc - 1]));
+ iFam = (!strcmp(argv[1], "IPv6")) ? AF_INET6 : AF_INET;
+ iProto = (!strcmp(argv[2], "UDP")) ? IPPROTO_UDP : IPPROTO_TCP;
+ iPort = htons(atoi(argv[3]));
- free (pszArgv);
- return myserver(iFamily, iNetproto, iNetport);
+ return myserver(iFam, iProto, iPort);
}
|