Removed submodules

This commit is contained in:
2026-05-31 14:34:00 -04:00
commit 46c36b11da
352 changed files with 14792 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
# Ignore all compiled files regardless of location
**/*.o
# But not the private.o
!tests/private.o
# Ignore executables for this project
net
testsuite
# Ignore test outputs
tests/ckstyle
tests/itests.txt
tests/outputs
tests/style.txt
tests/valgrind
tests/utests.txt
**/.nfs*
**/.vscode
+52
View File
@@ -0,0 +1,52 @@
#
# Simple Makefile
# Mike Lam, James Madison University, August 2016
#
# This makefile builds a simple application that contains a main module
# (specified by the EXE variable) and a predefined list of additional modules
# (specified by the MODS variable). If there are any external library
# dependencies (e.g., the math library, "-lm"), list them in the LIBS variable.
# If there are any precompiled object files, list them in the OBJS variable.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=net
MODS=client.o
OBJS=
LIBS=-lm
default: $(EXE)
test: $(EXE)
make -C tests test
# compiler/linker settings
CC=gcc
#CFLAGS=-g -O0 -Wall --std=gnu99 -pedantic
CFLAGS=-g -O0 -Wall --std=gnu99 -pedantic
LDFLAGS=-g -O0 -pthread
# build targets
$(EXE): main.o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(EXE) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -f $(EXE) main.o $(MODS)
make -C tests clean
.PHONY: default clean
+108
View File
@@ -0,0 +1,108 @@
#include <arpa/inet.h>
#include <assert.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "client.h"
#define BUFFER_MAX_SIZE 4096
/* Given a struct with server information, return a dynamically allocated
string of the IP address in dotted decimal or colon hexadecimal notation.
Consult Chapter 4, as well as /usr/include/netdb.h and
/usr/include/arpa/inet.h as needed. Use inet_ntop() to get the formatted
string based on the address's ai_addr field.
*/
char *
addr_string (struct addrinfo *server)
{
// Return safely in case server is NULL:
if (server == NULL)
return strdup ("no address information");
size_t addrlen
= server->ai_family == AF_INET6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN;
char *buffer = calloc (addrlen, sizeof (char));
void *addr;
if (server->ai_family == AF_INET)
addr = &((struct sockaddr_in *)server->ai_addr)->sin_addr;
else
addr = &((struct sockaddr_in6 *)server->ai_addr)->sin6_addr;
inet_ntop (server->ai_family, addr, buffer, addrlen);
return buffer;
}
/* Given the server address info, return a dynamically allocated string with
its transport-layer protocol, IP version, and IP address. For instance,
querying jmu.edu over TCP/IPv4 should return:
"TCP IPv4 134.126.10.50"
Use addr_string() to get the formatted address string, concatenate it to
the string to return, then free the result from addr_string(). If the
passed server parameter is NULL, use strdup() to return a dynamically
allocated copy of "no address information".
NOTE: When distinguishing TCP and UDP, you should be checking the
server->ai_socktype field, not server->ai_protocol. The test cases do not
set the server->ai_protocol, which is sometimes not used in practice.
*/
char *
serv_string (struct addrinfo *server)
{
// Return safely in case server is NULL:
if (server == NULL)
return strdup ("no address information");
size_t addrlen
= server->ai_family == AF_INET6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN;
char *buffer = calloc (10 + addrlen, sizeof (char));
char *proto = server->ai_socktype == SOCK_STREAM ? "TCP" : "UDP";
char *ipver = server->ai_family == AF_INET ? "IPv4" : "IPv6";
char *addr = addr_string (server);
snprintf (buffer, 10 + addrlen, "%s %s %s", proto, ipver, addr);
free (addr);
return buffer;
}
/* Given a hostname string, use getaddrinfo() to query DNS for the specified
protocol parameters. Boolean values indicate whether or not to use IPv6
(as opposed to IPv4) or TCP (as opposed to UDP). For this lab, the protocol
will only be "http", though it could be others in a more complete
implementation. Return the pointer to the linked list of server results.
*/
struct addrinfo *
get_server_list (const char *hostname, const char *proto, bool tcp, bool ipv6)
{
struct addrinfo hints = { 0 };
struct addrinfo *server_list = NULL;
hints.ai_family = ipv6 ? AF_INET6 : AF_INET;
if (tcp)
{
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
}
else
{
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
}
getaddrinfo (hostname, proto, &hints, &server_list);
return server_list;
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef __client_h__
#define __client_h__
#include <netdb.h>
#include <stdbool.h>
char *addr_string (struct addrinfo *);
char *serv_string (struct addrinfo *);
struct addrinfo *get_server_list (const char *, const char *, bool, bool);
char *web (const char *, char *, const char *, char **, bool);
#endif
+106
View File
@@ -0,0 +1,106 @@
/*
* CS 361: Template project driver
*
* Name:
*/
#include <assert.h>
#include <getopt.h>
#include <inttypes.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "client.h"
int cmdline (int, char **, char **, bool *, short int *);
void
usage (void)
{
printf ("Usage: net [options] domain\n");
printf (" Options are:\n");
printf (" -6 Use IPv6 addresses\n");
printf (" -p P Lookup address for application protocol P\n");
}
int
main (int argc, char **argv)
{
char *protocol = "http";
bool ipv6 = false;
short int port = 0;
if (cmdline (argc, argv, &protocol, &ipv6, &port) < 0)
{
usage ();
return EXIT_FAILURE;
}
char *domain = argv[optind];
// MINIMUM requirements:
// Get the server list for the specified domain and protocol
// Given this command-line:
// ./net -p http www.jmu.edu
// Print the following output:
// www.jmu.edu http: TCP IPv4 134.126.10.50
// The requested transport-layer protocol should be based on the
// requested application-layer protocol. TCP is default, but use
// UDP for protocols "53", "67", "dns", or "dhcp".
bool tcp = true;
char *udpProtocols[] = { "53", "67", "dns", "dhcp" };
for (size_t i = 0; i < 4; i++)
{
if (strcmp (protocol, udpProtocols[i]) == 0)
{
tcp = false;
break;
}
}
struct addrinfo *server = get_server_list (domain, protocol, tcp, ipv6);
char *server_string = serv_string (server);
printf ("%s %s: %s\n", domain, protocol, server_string);
free (server);
free (server_string);
return EXIT_SUCCESS;
}
/* DO NOT MODIFY THIS FUNCTION */
int
cmdline (int argc, char **argv, char **protocol, bool *ipv6, short int *port)
{
int option;
while ((option = getopt (argc, argv, "p:6sh")) != -1)
{
switch (option)
{
// Change this to merge -p and -o as same flag
case 'p':
*protocol = optarg;
break;
case '6':
*ipv6 = true;
break;
case 'h':
return -1;
break;
default:
return -1;
}
}
if (optind != argc - 1)
return -1;
return 0;
}
+86
View File
@@ -0,0 +1,86 @@
#
# Simple Test Makefile
# Mike Lam, James Madison University, August 2016
#
# This version of the Makefile includes support for building a test suite. The
# recommended framework is Check (http://check.sourceforge.net/). To build and
# run the test suite, execute the "test" target. The test suite must be located
# in a module called "testsuite". The MODS, LIBS, and OBJS variables work as
# they do in the main Makefile.
#
# To change the default build target (which executes when you just type
# "make"), change the right-hand side of the definition of the "default"
# target.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=../net
TEST=testsuite
MODS=public.o
OBJS=../client.o private.o
LIBS=
UTESTOUT=utests.txt
ITESTOUT=itests.txt
SCHECKOUT=style.txt
default: $(TEST)
$(EXE):
make -C ../
test: utest itest style
@echo "========================================"
utest: $(EXE) $(TEST)
@echo "========================================"
@echo " UNIT TESTS"
@./$(TEST) 2>/dev/null >$(UTESTOUT)
@cat $(UTESTOUT) | sed -n -e '/Checks/,$$p' | sed -e 's/^private.*:[EF]://g'
itest: $(EXE)
@echo "========================================"
@echo " INTEGRATION TESTS"
@./integration.sh | tee $(ITESTOUT)
style: $(EXE)
@echo "========================================"
@echo " CODING STYLE CHECK"
@./style.sh 2>/dev/null >$(SCHECKOUT)
@cat $(SCHECKOUT)
# compiler/linker settings
CC=gcc
CFLAGS=-g -O0 -Wall --std=gnu99 -pedantic
LDFLAGS=-g -O0
CFLAGS=
LIBS+=-lcheck -lm -lpthread
ifeq ($(shell uname -s),Linux)
LIBS+=-lrt -lsubunit
endif
# build targets
$(TEST): $(TEST).o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(TEST) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -rf $(TEST) $(TEST).o $(MODS) $(UTESTOUT) $(ITESTOUT) $(SCHECKOUT) outputs valgrind ckstyle
.PHONY: default clean test unittest inttest
@@ -0,0 +1 @@
6aa4050ebd7cf3e2973480a61c8f3e10abae0b8b
@@ -0,0 +1 @@
1954727e95f02e160a1ca5747b42de74ba7a73bb
@@ -0,0 +1 @@
9e5b32bfdef634ce9687b592ef6ab66dd2359d3e
@@ -0,0 +1 @@
16f74b0708234d24ac814851071de4a4f8d3893a
@@ -0,0 +1 @@
c0a296ad55ce3db887a3fbfa529ec4b3dc407e4a
@@ -0,0 +1 @@
fb304af0dc2a1fd9029541d8e653995755bc8b2c
+1
View File
@@ -0,0 +1 @@
ns3.jmu.edu 53: UDP IPv4 134.126.115.46
@@ -0,0 +1 @@
ns3.jmu.edu 53: UDP IPv6 ::ffff:134.126.115.46
@@ -0,0 +1 @@
ns3.jmu.edu 53: no address information
@@ -0,0 +1 @@
localhost http: TCP IPv4 127.0.0.1
@@ -0,0 +1 @@
localhost http: TCP IPv6 ::1
@@ -0,0 +1 @@
w3.cs.jmu.edu http: TCP IPv4 134.126.20.33
@@ -0,0 +1 @@
w3.cs.jmu.edu http: TCP IPv6 ::ffff:134.126.20.33
@@ -0,0 +1 @@
w3.cs.jmu.edu http: no address information
+75
View File
@@ -0,0 +1,75 @@
#!/bin/bash
EXE="../net"
function run_test {
# parameters
TAG=$1
ARGS=$2
# file paths
OUTPUT=outputs/$TAG.txt
DIFF=outputs/$TAG.diff
EXPECT=expected/$TAG.txt
VALGRND=valgrind/$TAG.txt
# print tag format
PTAG=$(printf '%-30s' "$TAG")
# check for expected text that needs to be fixed
if [ ! -z "$(egrep "<<<<.*>>>>" "$EXPECT")" ] ; then
echo "$PTAG FAIL ($EXPECT not correct)"
return
fi
# compare the file
SHAOUT=$(shasum "$EXPECT" | awk '{print $1}')
SHAEXP=$(cat "expected/.$TAG.sha")
if [ "$SHAOUT" != "$SHAEXP" ] ; then
echo "$PTAG FAIL (expected file is not correct)"
return
fi
# run test and compare output to the expected version
$EXE $ARGS 2>/dev/null >"$OUTPUT"
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
if [ -s "$DIFF" ]; then
# try alternative solution (if it exists)
EXPECT=expected/$TAG-2.txt
if [ -e "$EXPECT" ]; then
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
if [ -s "$DIFF" ]; then
echo "$PTAG FAIL (see $DIFF for details)"
else
echo "$PTAG pass"
fi
else
echo "$PTAG FAIL (see $DIFF for details)"
fi
else
echo "$PTAG pass"
fi
# run valgrind
valgrind $EXE $ARGS &>$VALGRND
}
# initialize output folders
mkdir -p outputs
mkdir -p valgrind
rm -f outputs/* valgrind/*
# run individual tests
source itests.include
# check for memory leaks
LEAK=`cat valgrind/*.txt | grep 'definitely lost' | grep -v ' 0 bytes in 0 blocks'`
if [ -z "$LEAK" ]; then
echo "No memory leak found."
else
echo "Memory leak(s) found. See files listed below for details."
grep 'definitely lost' valgrind/*.txt | grep -v ' 0 bytes in 0 blocks' | sed -e 's/:.*$//g' | sed -e 's/^/ - /g'
fi
+14
View File
@@ -0,0 +1,14 @@
# list of integration tests
# format: run_test <TAG> <ARGS>
# <TAG> used as the root for all filenames (i.e., "expected/$TAG.txt")
# <ARGS> command-line arguments to test
run_test INTEG_localhost_ipv4 "localhost"
run_test INTEG_localhost_ipv6 "-6 localhost"
run_test INTEG_w3_ipv6 "-6 w3.cs.jmu.edu"
run_test INTEG_w3_ipv4 "w3.cs.jmu.edu"
run_test INTEG_53_ns3 "-p 53 ns3.jmu.edu"
run_test INTEG_53_ns3_ipv6 "-6 -p 53 ns3.jmu.edu"
#run_test EXTRA_youtube_H "-w / youtube.com"
#run_test EXTRA_w3_index_H "-w /index.html w3.cs.jmu.edu"
#run_test EXTRA_nope_H "-w /nope.html example.com"
Binary file not shown.
+100
View File
@@ -0,0 +1,100 @@
#include <arpa/inet.h>
#include <assert.h>
#include <check.h>
#include <fcntl.h>
#include <inttypes.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "../client.h"
START_TEST (UNIT_addr_string_localhost_v4)
{
printf ("======================================\n");
printf ("PUBLIC\n");
printf (" UNIT addr string localhost v4\n");
printf (" Convert 32-bit integer address for localhost\n");
printf (" into dotted-decimal 127.0.0.1 string format.\n\n");
struct sockaddr_in address;
memset (&address, 0, sizeof (address));
address.sin_addr.s_addr = htonl (0x7f000001);
struct addrinfo server;
server.ai_family = AF_INET;
server.ai_addr = (struct sockaddr *) &address;
char *ipv4 = addr_string (&server);
printf (" IPv4 address for localhost is '%s'\n", ipv4);
printf ("\n");
ck_assert_str_eq (ipv4, "127.0.0.1");
free (ipv4);
}
END_TEST
START_TEST (UNIT_get_server_list_localhost)
{
printf ("======================================\n");
printf ("PUBLIC\n");
printf (" UNIT get server list localhost\n");
printf (" Use getaddrinfo() to gather information about localhost\n");
printf (" for the HTTP protocol with IPv4. Requires network access\n");
printf (" to get information from DNS.\n\n");
struct addrinfo *server =
get_server_list ("localhost", "http", true, false);
struct sockaddr_in *addr4 = (struct sockaddr_in *) server->ai_addr;
uint32_t address = ntohl (addr4->sin_addr.s_addr);
printf (" IPv4 address for localhost is 0x%08" PRIx32 "\n", address);
printf ("\n");
ck_assert_int_eq (address, 0x7f000001);
freeaddrinfo (server);
}
END_TEST
START_TEST (UNIT_serv_string_localhost)
{
printf ("======================================\n");
printf ("PUBLIC\n");
printf (" UNIT serv string localhost\n");
printf (" Converts a struct addrinfo into a string that contains\n");
printf (" the transport-layer protocol, IP version, and IP address\n");
printf (" in the appropriate format.\n\n");
struct sockaddr_in address;
memset (&address, 0, sizeof (address));
address.sin_addr.s_addr = htonl (0x7f000001);
struct addrinfo server;
server.ai_family = AF_INET;
server.ai_addr = (struct sockaddr *) &address;
server.ai_socktype = SOCK_STREAM;
char *serv_info = serv_string (&server);
printf (" Server information for localhost: '%s'\n", serv_info);
printf ("\n");
ck_assert_str_eq (serv_info, "TCP IPv4 127.0.0.1");
free (serv_info);
}
END_TEST
void public_tests (Suite *s)
{
TCase *tc_public = tcase_create ("Public");
tcase_add_test (tc_public, UNIT_addr_string_localhost_v4);
tcase_add_test (tc_public, UNIT_get_server_list_localhost);
tcase_add_test (tc_public, UNIT_serv_string_localhost);
suite_add_tcase (s, tc_public);
}
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
STYLE="gnu"
IGNORE=()
FAIL=0
function comp_file {
SRC=$1
SRC_NAME=$2
# file paths
FORMAT=ckstyle/${SRC_NAME}.$STYLE
DIFF=ckstyle/${SRC_NAME}.diff
# run clang-format and compare results
clang-format --style=$STYLE $source > $FORMAT
diff -u $SRC $FORMAT >$DIFF
PTAG=$(printf '%-30s' "$SRC_NAME")
if [ -s $DIFF ]; then
echo "$PTAG FAIL (see $DIFF for details)"
FAIL=1
else
echo "$PTAG pass"
rm $DIFF
fi
rm $FORMAT
}
mkdir -p ckstyle
rm -f ckstyle/*
for source in $(ls ../*.c ../*.h) ; do
SKIP=0
src=$(basename $source)
for ignore in ${IGNORE[*]} ; do
if [ "$src" = "$ignore" ] ; then
SKIP=1
fi
done
if [ $SKIP = 0 ] ; then
comp_file $source $src
fi
done
if [ $FAIL != 0 ] ; then
echo "Code that does not adhere to GNU standards will not be accepted."
echo "You must fix these files before submission."
else
echo "Code correctly adheres to required style."
fi
+34
View File
@@ -0,0 +1,34 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <time.h>
#include <check.h>
extern void public_tests (Suite *s);
extern void private_tests (Suite *s);
Suite * test_suite (void)
{
Suite *s = suite_create ("Default");
public_tests (s);
private_tests (s);
return s;
}
void run_testsuite ()
{
Suite *s = test_suite ();
SRunner *sr = srunner_create (s);
srunner_run_all (sr, CK_NORMAL);
srunner_free (sr);
}
int main (void)
{
srand((unsigned)time(NULL));
run_testsuite ();
return EXIT_SUCCESS;
}