Blog

  • Teaching Networking with Python and Scapy: A Lot Less Cruft To Carry Around

    <aside>
    💡

    Scapy is the closest thing Python has to a packet workbench: you can build packets as data structures, send them, capture real traffic, and save the results as PCAP files for Wireshark.

    </aside>

    Networking can feel abstract at first. We draw headers as rows of boxes, memorize protocol numbers, and talk about packets moving through systems we cannot see. Scapy changes that. With a few lines of Python, an IP header stops being a diagram and becomes an object you can create, inspect, modify, and—when appropriate—put on the wire.

    That makes Scapy especially useful in an teaching networking courses. It is small enough to explore interactively, but powerful enough to create realistic traffic and packet captures. Better still, it produces PCAP files, giving Wireshark a natural role in the same workflow.

    What follows is not a complete Scapy tutorial. It is a short tour of the features I find most useful when introducing packets: building one, exchanging one, creating a trace, and capturing live traffic.

    <aside>
    ⚠️

    Generate or replay traffic only on networks you own or where you have explicit permission. A lab VM network or loopback interface is the safest place to experiment. Sniffing often requires elevated privileges on macOS and Linux.

    </aside>

    Getting Scapy running

    Scapy requires Python 3 and is easy to install with pip:

    python3 -m pip install scapy
    

    A quick version check confirms that the installation worked:

    python3 -c "from scapy.all import *; print(conf.version)"
    

    Wireshark is not required, but it completes the experience. Scapy is excellent for creating and manipulating packets; Wireshark is excellent for exploring them visually.

    Turning a header diagram into an object

    The first useful Scapy session does not need to send anything. In a Python REPL, create an IP packet carrying an ICMP message:

    from scapy.all import IP, ICMP
    
    p = IP(dst="8.8.8.8")/ICMP()
    print(p)
    

    The slash is Scapy’s layering operator. Here it places ICMP inside IP, much as an encapsulation diagram would. The difference is that this diagram is executable.

    Calling show() reveals the packet field by field:

    p.show()
    

    Individual values are available directly:

    p[IP].dst
    p[IP].ttl
    p[ICMP].type
    

    The packet can also become the bytes that would travel across a network:

    raw_bytes = bytes(p)
    len(raw_bytes)
    raw_bytes[:20]
    

    This is the moment when Scapy earns its place in the classroom. “The IP header” is no longer only a concept from a slide. It is structured data with fields, defaults, and a binary representation.

    A packet exchange in a few lines

    The smallest complete networking story is a request followed by a response. An ICMP echo provides exactly that:

    from scapy.all import IP, ICMP, sr1
    
    req = IP(dst="8.8.8.8")/ICMP()
    reply = sr1(req, timeout=2, verbose=False)
    
    if reply is None:
    	print("No reply")
    else:
    	print("Request:")
    	req.show()
    	print("Reply:")
    	reply.show()
    

    The sr1() function sends one packet and waits for one answer. In a controlled lab, I usually replace 8.8.8.8 with a gateway or server VM that belongs to the lab. The destination is less important than the symmetry: Scapy lets you place the request and response beside each other and see which fields correspond.

    A timeout is instructive, too. “No reply” does not necessarily mean the destination is offline. A firewall may block ICMP, a route may be missing, or the response may simply arrive too late. Even this tiny program opens the door to an important networking habit: observed behavior must be interpreted, not merely recorded.

    Building a trace before capturing one

    We often use “trace” to mean a time-ordered sequence of packets. Scapy can create such a sequence entirely offline, which is useful when every student should begin with the same artifact.

    Consider a set of UDP packets whose TTL values increase from one through five:

    from scapy.all import IP, UDP
    
    pkts = []
    for ttl in range(1, 6):
    	p = IP(dst="203.0.113.1", ttl=ttl)/UDP(dport=33434)
    	pkts.append(p)
    
    pkts[0].show()
    len(pkts)
    

    The destination address comes from a block reserved for documentation, so this code is best understood as packet construction rather than an invitation to transmit. Each packet is almost identical to the one before it; only the TTL changes. That small variation makes the sequence easy to reason about and connects naturally to a later discussion of traceroute.

    Now write the packets to a PCAP file:

    from scapy.all import wrpcap
    
    wrpcap("ttl-demo.pcap", pkts)
    print("Wrote ttl-demo.pcap")
    

    Opening ttl-demo.pcap in Wireshark reveals the same packets through a different lens. Scapy emphasizes construction and code; Wireshark emphasizes comparison and visual inspection. Moving between the two helps connect Python objects, protocol fields, and bytes on disk.

    This is one of my favorite ways to begin packet analysis. Everyone works from the same clean trace, and no one has to troubleshoot capture permissions before seeing something useful.

    Adding an application-layer protocol

    DNS makes the next step especially clear because it is familiar, structured, and layered above UDP and IP. Here is a DNS query for example.com:

    from scapy.all import IP, UDP, DNS, DNSQR, sr1
    
    q = IP(dst="8.8.8.8")/UDP(dport=53)/DNS(rd=1, qd=DNSQR(qname="example.com"))
    a = sr1(q, timeout=2, verbose=False)
    
    if a:
    	a.show()
    

    That single expression makes the protocol stack visible: IP contains UDP, and UDP carries DNS. If a reply arrives, Scapy parses the payload back into meaningful fields rather than leaving it as an unexplained string of bytes.

    For example, the query name is available as a[DNS].qd.qname. The DNS flags reveal whether recursion was requested and provided, while the answer section may contain A, AAAA, or CNAME records. At this point, layering becomes more than a diagram: each layer is both independent and connected to the others.

    Moving from generated packets to live traffic

    Once offline traces make sense, capturing live traffic feels like a natural next step. Scapy’s sniff() function can collect a fixed number of packets or stop after a timeout:

    from scapy.all import sniff
    
    pkts = sniff(count=20, timeout=10)
    print(len(pkts))
    

    An unrestricted capture can become noisy quickly. A Berkeley Packet Filter narrows the stream before Scapy processes it. This example listens only for DNS over UDP:

    pkts = sniff(count=50, timeout=15, filter="udp port 53")
    print(len(pkts))
    

    The result can be saved just like the trace we generated earlier:

    from scapy.all import wrpcap
    
    wrpcap("sniffed-dns.pcap", pkts)
    

    The distinction between these two PCAPs is useful. ttl-demo.pcap contains packets deliberately constructed in code. sniffed-dns.pcap records traffic observed on an interface. Both are packet traces, but they tell different kinds of stories.

    On macOS and Linux, live capture often requires elevated privileges. If Scapy reports a permission error, run the script with sudo in an appropriate lab environment or configure capture permissions according to local policy.

    Replaying a saved trace

    Scapy can also read packets from a PCAP and transmit them:

    from scapy.all import rdpcap, send
    
    pkts = rdpcap("ttl-demo.pcap")
    send(pkts, verbose=False)
    

    Replay is useful in a controlled environment when several people need to generate the same traffic pattern against a service they own. It also creates an opening for later discussions about timing, state, addresses, checksums, and why replayed traffic may not behave exactly like the original exchange.

    Because replay places packets back on the network, it deserves the same caution as any other transmission: use it only in an isolated or explicitly authorized environment.

    A small capture program worth keeping

    After experimenting in the REPL, it helps to put one useful task into a complete script. The following program captures UDP traffic for up to 30 seconds and saves the result:

    from scapy.all import sniff, wrpcap
    
    def main():
    	pkts = sniff(count=100, timeout=30, filter="udp")
    	wrpcap("capture.pcap", pkts)
    	print(f"Saved {len(pkts)} packets to capture.pcap")
    
    if __name__ == "__main__":
    	main()
    

    It is intentionally modest: one file, one job, and one artifact to inspect. From here, it is easy to change the filter, packet count, timeout, or output filename without hiding the networking ideas beneath a larger application.

    From diagrams to evidence

    Scapy occupies a useful middle ground. It is approachable enough for a first networking course, yet it exposes the same packet structures that appear in serious testing, troubleshooting, and research.

    The real value is not that Scapy makes it easy to send a ping or save a capture. It is that it shortens the distance between an idea and evidence. A header becomes an object. An object becomes bytes. A sequence of packets becomes a PCAP. That PCAP becomes something we can inspect, question, and explain.

    For someone learning networking, that progression is far more memorable than another page of acronyms.

    Selah.

  • Trust vs. Confidence in Higher Education Leadership (and Why One Can’t Fake the Other)

    Higher education leaders talk about “trust” the way institutions talk about “excellence”: as if repetition can make it real. But students, faculty, staff, alumni, legislators, donors, and the public judge leadership through two distinct ideas: trust and confidence.

    The difference matters. A university can restore confidence through competent performance yet fail to rebuild trust after people feel misled, dismissed, or used.

    Trust is not confidence

    Confidence: “I believe this will work.”

    Confidence rests on competence and predictability. It grows from evidence: sound decisions, reliable operations, measurable results, and promises kept.

    Trust: “I believe you will act fairly.”

    Trust rests on intent, integrity, and relationship. It grows when leaders tell the truth, treat people with dignity, share risk, and allow the institution’s mission to constrain their choices.

    The two often move together, but not always:

    • Confidence without trust: “They are capable, but I do not believe they are fair.”
    • Trust without confidence: “They mean well, but I am not sure they can deliver.”

    Universities need both. Where authority is distributed, expertise is specialized, and legitimacy is social, confidence produces compliance; trust produces commitment.

    Four kinds of leadership credibility

    High confidenceLow confidence
    High trustDurable legitimacy: people tolerate mistakes because they believe leaders are honest and capable.Goodwill under strain: people remain sympathetic, but patience fades when execution does not improve.
    Low trustEfficient but resented: short-term results come at the cost of long-term cynicism.Crisis: stakeholders assume the worst and resist nearly every decision.

    The political maneuvering of the past two years—roughly fall 2024 through fall 2026—makes these distinctions unusually clear. The question is not whether government should enforce civil-rights law or whether universities should be accountable. Both are necessary. The question is whether rules are applied consistently and through legitimate procedures—and whether leaders can protect students, scholarship, and institutional independence at the same time.

    Leadership under political leverage

    Political intervention in higher education did not begin in 2024, but it accelerated and became more routine.

    Florida expanded restrictions on the use of state and federal funds for DEI programs across its public system. The state Board of Education described its January 2024 rule as a permanent prohibition on public funding for DEI programs. Texas and other states pursued greater control over DEI, tenure, curriculum, and faculty governance. A 2026 scholarly overview reported that, by spring 2025, lawmakers in 29 states had introduced 134 anti-DEI bills; 19 had become law.

    Supporters describe these measures as an effort to reclaim public institutions from unaccountable bureaucracies and ideological conformity. Critics see partisan authorities displacing academic judgment. Either way, university leaders face the same credibility test. Quietly renaming offices or complying through euphemism may preserve operations, but it offers neither a principled defense nor an honest account of institutional constraints.

    <blockquote>When political authorities change the rules, leaders must distinguish among compliance, agreement, and advocacy.</blockquote>

    Federal pressure intensified in 2025. The Trump administration used research grants, contracts, accreditation, tax status, and authority over international students as leverage over universities. Administration officials said forceful action was necessary to combat antisemitism and unlawful discrimination. Universities and higher education associations argued that legitimate civil-rights enforcement had become entangled with demands for ideological and governance changes.

    This is where trust and confidence can pull in opposite directions. Concession may protect grants, laboratories, jobs, and students—evidence of competent stewardship. But unexplained concessions can weaken trust by suggesting that institutional principles are negotiable. Resistance may demonstrate integrity and independence, but it can also put people and programs at financial risk.

    The real test is not whether a leader settles or fights. It is whether the leader explains what is being protected, what is being conceded, who will bear the cost, and where the institution will draw the line next time.

    What trustworthy, confident leadership looks like

    Apply one standard

    Define harassment, disruption, and discrimination before a crisis. Apply those definitions regardless of the people, politics, or cause involved. Selective enforcement may produce order, but it destroys legitimacy.

    Separate compliance from endorsement

    Leaders should say plainly when the institution is obeying a law it opposed, challenging a demand it considers unlawful, or voluntarily correcting a failed policy. Claiming that every strategic choice was legally required may avoid criticism today, but it invites cynicism tomorrow.

    Keep boards from becoming shadow administrations

    Trustees should oversee mission, risk, and executive performance. They should not manage curricula or make policy in response to donors, headlines, or social media. When boards bypass shared governance, even defensible decisions begin to look political.

    Defend civil rights and academic freedom together

    These principles are not natural enemies. Universities lose credibility when they protect expression but ignore harassment—or invoke safety to suppress lawful dissent. Leaders must explain how both commitments operate in practice, especially when they collide.

    Make concessions visible

    Private deals invite speculation. When confidentiality is legally necessary, leaders can still disclose decision criteria, responsible authorities, review dates, and foreseeable costs. Transparency does not require revealing everything; it requires refusing to hide what can responsibly be shared.

    Build coalitions before the ultimatum

    A president acting alone is easy to isolate. Faculty, students, peer institutions, scientific organizations, alumni, and civic leaders can provide legitimacy that no press release can manufacture.

    How leaders lose both

    Trust erodes quickly when leaders:

    • Rewrite principles after discovering which position is politically safer.
    • Invoke “institutional neutrality” only for controversies they prefer to avoid.
    • Announce emergency policies without definitions, end dates, or appeals.
    • Present strategic concessions as unavoidable legal requirements.
    • Treat students and faculty as reputational liabilities rather than members of the institution.
    • Defend autonomy in public while allowing donors, trustees, legislators, or federal officials to exercise control in private.

    The deepest danger is not that universities may move left or right. It is that their communities may stop believing decisions are governed by stable rules. Once that happens, competent decisions look partisan, and principled decisions look performative.

    The bottom line

    Higher education does not run on hierarchy alone. It also depends on expertise, norms, and shared governance. Leaders cannot “message” their way into legitimacy.

    Confidence is earned by doing what you said you would do.

    Trust is earned by showing, repeatedly, that the institution’s values constrain your choices rather than decorate your speeches.

    Universities that build both can withstand political pressure, adapt to change, and remain institutions worth believing in.

    Selah.

  • Command-line Knowledge for MacOS: Preventing Sleep

    One of the things I love about what I do is that I discover some oddity that makes me say to myself: “Self, Why did you not know about that?” Today’s entry in that category is MacOS’s caffeinate command. It’s a command-line tool that prevents your Mac from sleeping for a period of time, or while a specific process is running. It is simple, reliable, and does not require installing anything.


    How caffeinate works

    macOS has several power management behaviors:

    • Display sleep: the screen turns off.
    • System sleep: the whole Mac goes to sleep.
    • Disk sleep: disks can spin down.
    • Idle sleep: sleep that happens because there is no activity.

    caffeinate creates a temporary “stay awake” assertion with the power management system. While the assertion is active, macOS will avoid the kind of sleep you told it to prevent.


    The simplest usage

    Start caffeinate in Terminal:

    caffeinate
    

    As long as that command is running, your Mac will be kept awake (until you stop it).

    To stop it, press:

    • Ctrl + C

    Common options (the ones you will actually use)

    You can tailor what gets prevented:

    • -d prevents display sleep
    • -i prevents idle system sleep
    • -m prevents disk sleep
    • -s prevents system sleep (particularly useful on AC power)

    Examples:

    # Keep the Mac awake, but let the display sleep
    caffeinate -i
    
    # Keep the display awake (presentation mode)
    caffeinate -d
    
    # Keep system awake (often best for long tasks)
    caffeinate -s
    
    # Keep everything you can awake
    caffeinate -dims
    

    Note: Some flags make more sense in certain situations (for example, -s is most relevant when the Mac is plugged in).


    Set a time limit with -t

    If you want “stay awake” behavior for a fixed amount of time, use -t with a number of seconds.

    # Stay awake for 1 hour
    caffeinate -i -t 3600
    

    A handy trick: if you think in minutes, multiply by 60.


    Tie it to a command (the best way for long jobs)

    Instead of manually starting and stopping caffeinate, you can run it while another command runs.

    # Keep the Mac awake while rsync runs
    caffeinate -i rsync -av ~/Source/ /Volumes/Backup/Source/
    

    When the rsync command finishes, caffeinate exits automatically.

    This pattern is great for:

    • Backups and file copies
    • Long builds
    • Data imports
    • Video exports
    • Large downloads

    Real-world recipes

    1) Keep your Mac awake while a large file downloads

    If you are using curl:

    caffeinate -i curl -LO "<https://example.com/bigfile.zip>"
    

    2) Prevent sleep during a presentation

    caffeinate -d
    

    Leave it running for the duration of the presentation, then Ctrl + C.

    3) Keep your Mac awake for a meeting, then stop automatically

    # 90 minutes
    caffeinate -i -t 5400
    

    Safety notes and gotchas


    • Preventing sleep can use more power and generate more heat, especially on laptops.
    • If you use caffeinate with no time limit, it will run until you stop it. If you forget, your Mac may stay awake all night.
    • If the goal is “do not lock my screen,” that is a different setting. caffeinate is about sleep behavior, not password prompts.

    Quick cheat sheet

    caffeinate              # keep awake until you stop it
    caffeinate -i           # prevent idle sleep
    caffeinate -d           # prevent display sleep
    caffeinate -i -t 600    # preventsleep for 10 minutes
    caffeinate -i <command> # keep awake while command runs
    

    Linux equivalent?

    Many Linux desktop environments use the caffeine utility, which includes a caffeinate binary in some distributions (like Debian/Ubuntu) that mimics the macOS syntax.

    Installation:

    • Ubuntu/Debian/Mint: sudo apt install caffeine
    • Arch Linux: sudo pacman -S caffeine-ng
    • Fedora: sudo dnf install caffeine-ng [1, 2]

    Syntax & Usage:

    • Prevent screen blanking while running a command: bash caffeinate COMMAND Use code with caution.
    • Toggle via GUI: Run caffeine or caffeine-indicator from your app menu to get a coffee cup icon in your taskbar, then click it to toggle idle-prevention on and off manually

    Closing thoughts

    If you work in Terminal even occasionally, caffeinate is one of those small tools that saves you from big annoyances. The best default is usually caffeinate -i, and the best habit is adding it in front of any command you expect to run for a long time.

  • The Canvas Security Breach: Cloud-Infrastructure As Single Point of Failure

    The recent breach and outage involving the Canvas learning management system should be a warning to every university administrator, faculty senate, IT office, and accreditor. This wasn’t just a cybersecurity incident. It was a stress test of how much higher education has outsourced its day-to-day functioning to centralized cloud infrastructure—and how brittle that dependence can be.

    Reports suggest data tied to as many as 275 million users may have been exposed, including names, emails, ID numbers, and messages between students and instructors. The disruption also hit at the worst possible moment: final exams. Students lost access to assignments, instructors couldn’t upload grades, and campuses scrambled to improvise workarounds.

    But the real lesson isn’t simply “Canvas got hacked.”

    It’s that higher education has consolidated core academic operations into a small number of cloud platforms that now act as infrastructural choke points.

    A handful of companies operate critical educational systems at planetary scale. Baylor University reports that Canvas alone supports roughly 41% of higher education institutions in North America. When one dominant vendor is compromised, thousands of campuses can feel it—immediately.

    That concentration has consequences. When a single provider hosts coursework, exams, communications, grading workflows, analytics, archives, identity integration, and student records for thousands of institutions at once, that provider becomes part of educational critical infrastructure. Yet many universities still treat these platforms as ordinary software subscriptions rather than systemic dependencies.

    The Canvas incident also exposes a strategic blind spot. Universities often justify cloud adoption as a financial or convenience decision: less maintenance, better uptime, easier scaling, automatic updates, smaller staffing needs. Those benefits are real. But institutions routinely underweight the risks of dependency concentration—especially the risk that a single failure can halt teaching itself.

    Higher education has spent years talking about “digital transformation” without taking “digital sovereignty” seriously.

    A university cannot claim resilient infrastructure if instruction becomes inaccessible whenever a third-party platform goes down. And it cannot fully claim academic independence when the basic mechanics of teaching and assessment depend on the operational stability of a small set of multinational vendors.

    This isn’t an argument for abandoning cloud services. That would be unrealistic—and sometimes counterproductive.

    It is an argument for designing for resilience.

    Institutions need layered architectures rather than single-platform dependency. They should maintain local contingency options for instructional continuity. Faculty should be supported in keeping offline-accessible course materials. Campuses should have fallback communication channels that don’t rely on the LMS. Critical assessment workflows should not exist exclusively inside cloud-managed ecosystems.

    Procurement also has to mature. Vendor selection can’t be driven only by features, usability, and subscription price. Institutions must evaluate systemic risk: exit strategies, interoperability, local recoverability, contractual guarantees, and the practical ability to keep teaching during an outage.

    Most importantly, universities need to stop treating cloud infrastructure as “someone else’s problem.”

    Educational platforms are no longer peripheral administrative tools. They sit under the intellectual and operational foundation of modern universities. When they fail, teaching fails. When they’re compromised, academic continuity is compromised.

    The Canvas breach exposed more than a security weakness. It exposed an architectural weakness in higher education itself.

    Universities built a globally centralized digital campus.

    Now they’re discovering what happens when the campus has only one front door.

    Selah.

  • Is anybody actually writing “Modern C++”?

    If you spend any time watching C++ conference talks, reading the standard, or skimming the Core Guidelines, you could be forgiven for thinking the industry quietly agreed to rewrite itself overnight. The code in those talks is elegant. Expressive. Composed of ranges, concepts,constexpr, value semantics, and a conspicuous absence of raw pointers.

    In college, though, C++ often shows up in a different outfit: data structures, intro systems, maybe compilers or graphics if you are lucky. It is taught as “the language you use to understand memory,” not “the language you use to write elegant libraries.” Students learn pointers early. They learn manual lifetime management. They learn to fear undefined behavior.

    Then you open a real codebase, written by a team that ships products for a living.

    And… yeah. Something is off.

    So let’s ask the uncomfortable question out loud: is anybody actually writing C++ the way C++20 suggests?

    The answer is yes. But not in the way most people mean.

    What “the C++20 Way” Even Is

    When people say “modern C++,” they rarely mean one feature. They mean a style that has emerged over the last decade: code that leans on value semantics and RAII, prefers standard algorithms over bespoke loops, uses strong types to make illegal states harder to represent, and pushes intent into the type system instead of into comments.

    In practice, “the C++20 way” usually looks like a handful of recurring moves. You see

    std::optional

    and

    std::variant

    where older code used sentinel values. You see

    enum class

    where older code used loosely-typed integers. You see concepts where older template code relied on SFINAE and error messages as a rite of passage. You see

    constexpr

    used to make compile-time decisions explicit rather than accidental.

    And, maybe most importantly, you see fewer macros, fewer raw owning pointers, and fewer surprise lifetime rules.

    None of this descended from on high with a standard release. It grew out of guidelines, talks, libraries, and hard-won experience. It is not “how C++ must be written.” It is how C++ can be written when everything goes right.

    Who’s Actually Writing C++ This Way?

    Some people really are writing the C++ from the talks. It is not imaginary. It is just concentrated in a few places.

    Library authors and C++ specialists

    If you work on standard library internals, Boost-like libraries, header-only abstractions, compilers, or tooling, this style is not aspirational. It is necessary.

    These teams spend all day living in templates. They are the reason concepts exist. They treat

    constexpr

    as a feature, not a punishment. Their code looks like the talks because they are the ones giving the talks.

    Greenfield, performance-heavy projects

    New subsystems and high-end projects are the next most likely place to find “conference C++.” Think simulation, robotics, finance, and HPC, where performance and correctness are non-negotiable and the codebase is not dragging decades of baggage.

    Even here, adoption is cautious. Smart pointers become the default, but they do not replace every custom allocator. Expressive types show up, but teams still measure every abstraction. Ranges do not replace every loop. Modules exist mostly in slide decks. Compile-time complexity is treated as a real cost.

    It is modern, but it is modern with a budget.

    Teaching environments

    Academia can produce the cleanest C++ precisely because it can ignore so many constraints. When you are not supporting four platforms, three compilers, and one vendor-patched standard library, you can teach the simpler story: avoid raw owning pointers, express intent in types, and let the compiler enforce invariants.

    Students often learn a cleaner C++ than they will see in their first job.

    That is not a bug. That is a north star.

    Who Mostly Isn’t Writing C++ This Way?

    If “conference C++” were the median, this essay would not exist. Most production C++ lives under constraints that talks rarely linger on.

    Legacy codebases

    Millions of lines of pre-C++11 code do not get magically modernized because a new standard dropped.

    Modernization is usually incremental and local. You modernize at boundaries, where it is safe. You introduce a new type here, replace a few ownership patterns there, move a subsystem toward a newer dialect when you can, and leave the rest alone unless you enjoy production outages.

    These teams live in a hybrid world: “modern where possible, old where required.” And that is often the correct choice.

    Cross-platform product teams

    If you support old compilers, niche platforms, embedded targets, or vendor-patched libraries, you cannot assume full C++20 support.

    So you end up writing C++17-ish core logic, adopting a few C++20 features where they help, and building careful fallbacks. This is not conservatism. It is survival.

    Game studios

    Games deserve special mention because they are often very modern, but almost never ideological.

    Game teams care about debuggability, build times, and predictable performance. They use RAII everywhere. They use smart pointers where they fit the engine’s ownership model. Exceptions are often banned. Heavy abstractions and ranges show up selectively, because the cost is paid by every developer who has to build, debug, and profile the game.

    Game C++ looks modern, but it does not look like a conference slide.

    And it should not.

    The Uncomfortable Truth

    The C++ standard does not describe how people do write code. It describes how people could write code if starting today, with no legacy constraints, excellent toolchains, uniform compiler support, and deeply trained developers.

    Real codebases are messier, older, and more political than that.

    What’s Actually Happening in Practice

    C++20 has not become doctrine. It has become a toolbox.

    Teams adopt what pays for itself. They take the features that reduce bugs. They take the features that clarify intent. They take the features that do not explode compile times, onboarding, or debugging.

    And they ignore the rest. Sometimes that is shortsighted. Often it is wise.

    This is not failure. It is engineering.

    A Hot Take Worth Saying Out Loud

    C++20 is not a style guide. It is a pressure gradient.

    New code drifts toward it. Old code resists it. Great engineers use it deliberately. Poor engineers misuse it and blame the language.

    The difference is not the standard.

    It is judgment.

    A Note for Educators

    If you teach C++ “the C++20 way,” you are doing the right thing, as long as you are honest about reality.

    Teach it as the ideal we aim for, not the average codebase someone will inherit. The students who understand that distinction tend to become better engineers faster, because they learn both the direction of travel and the constraints that slow it down.

    Final Thought

    The right question is not “Is anyone writing C++ like the standard suggests?”

    It is: “Which parts of modern C++ meaningfully improve this codebase?”

    That is the question professionals actually answer every day.

    And it is the real lesson C++20 teaches.

    Fair warning: I have strong opinions 😄

    Selah.

  • Command-line Knowledge for MacOS: Network Troubleshooting

    I am teaching a graduate-level class in computer communications and networking in this semester. One of the first things I do in that class is review the command-line tools you have available for network configuration and troubleshooting. Y’all know I’m an Apple person and I find that, like most command-line level stuff, Apple people are not very cognizant of the power you have with the command-line. So, I thought I’d share some of the notes from my class focused on macOS networking.

    macOS ships with a strong set of command-line networking tools. Many of them come from the BSD and POSIX tradition, and work almost exactly the same as they do on FreeBSD, OpenBSD, and Linux. On top of that, Apple adds a set of system configuration and diagnostics tools that integrate with macOS frameworks like System Configuration, NetworkExtension, and the Wi‑Fi stack.

    This post is organized in two parts:

    • Traditional BSD utilities you can expect on most Unix-like systems
    • Apple-specific tools that are especially useful on macOS

    Part 1: Traditional BSD utilities (the classics)

    These tools are generally stable, script-friendly, and easy to combine in pipelines.

    ping and ping6: basic reachability and latency

    Use ping to answer two questions:

    • Can I reach this host?
    • What is the latency and packet loss?

    Examples:

    ping -c 5 1.1.1.1
    ping -c 5 [example.com](<http://example.com>)
    

    Notes:

    • ICMP can be blocked by firewalls, so “no ping” does not always mean “no connectivity.”

    traceroute: path discovery (where packets go)

    traceroute shows the hop-by-hop path toward a destination.

    traceroute [example.com](<http://example.com>)
    

    Helpful options:

    • -n for numeric output (faster; avoids DNS lookups)
    • -w to adjust timeout

    ifconfig: interfaces, addresses, and link state

    On macOS, ifconfig is still the canonical interface tool.

    Show all interfaces:

    ifconfig
    

    Show one interface:

    ifconfig en0
    

    Common things to look for:

    • IPv4 address (inet)
    • IPv6 address (inet6)
    • MAC address (ether)
    • Status (status: active)

    Tip: on many Macs, Wi‑Fi is often en0 and Ethernet is often en1 or another en*, but it varies.


    netstat: sockets and routing info (legacy but handy)

    netstat can show listening ports, established connections, and routing tables.

    Show listening TCP sockets:

    netstat -anv | grep LISTEN
    

    Show routing table:

    netstat -rn
    

    macOS note: for some tasks, netstat is being superseded by tools like lsof, route, and Apple’s newer diagnostics tools, but it is still useful.


    route: view and modify the routing table

    View the current default route:

    route -n get default
    

    Show the route to a specific destination:

    route -n get 8.8.8.8
    

    Be cautious editing routes on a laptop. In most cases you want to inspect rather than change.


    arp: inspect the ARP cache (IPv4 LAN neighbor mapping)

    When troubleshooting local LAN issues (wrong gateway, duplicate IPs, suspicious devices), arp can help.

    arp -a
    

    nslookup, dig, and host: DNS troubleshooting

    DNS is often the source of “the internet is down” reports. These tools confirm what your resolver is doing.

    dig is the most informative:

    dig [example.com](<http://example.com>) A
    dig [example.com](<http://example.com>) AAAA
    dig +short [example.com](<http://example.com>)
    

    Check which DNS server is answering:

    dig [example.com](<http://example.com>) @1.1.1.1
    

    nc (netcat): quick TCP/UDP testing

    nc is great for testing whether a port is reachable.

    Test TCP connect:

    nc -vz [example.com](<http://example.com>) 443
    

    Listen on a port (for local testing):

    nc -l 9000
    

    tcpdump: packet capture (the gold standard)

    If you want to know what is actually on the wire, use tcpdump.

    Capture on Wi‑Fi (en0) and show DNS traffic:

    sudo tcpdump -i en0 -n port 53
    

    Capture HTTPS flow behavior:

    sudo tcpdump -i en0 -n tcp port 443
    

    Pro tips:

    • Always start with -n to avoid DNS lookups in your capture output.
    • Keep captures narrow (filter early) so you can read them.

    lsof: map ports back to processes

    When you see “something is listening on port 8080,” lsof answers “what process?”

    sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
    

    This is often the fastest way to diagnose conflicts with dev servers, proxies, or VPN clients.


    Part 2: Apple-specific tools (macOS superpowers)

    These tools understand macOS network services and configuration layers better than the classic Unix utilities.

    networksetup: manage network service settings

    networksetup is a friendly CLI wrapper for many settings you would otherwise click through in System Settings.

    List network services:

    networksetup -listallnetworkservices
    

    Show Wi‑Fi info for a service name:

    networksetup -getinfo "Wi-Fi"
    

    See DNS servers configured for a service:

    networksetup -getdnsservers "Wi-Fi"
    

    Set DNS servers (example):

    sudo networksetup -setdnsservers "Wi-Fi" 1.1.1.1 1.0.0.1
    

    Tip: macOS has multiple “network services” (Wi‑Fi, Ethernet adapters, Thunderbolt bridges, VPN interfaces). Troubleshooting often gets easier once you know which service you are actually using.


    scutil: System Configuration and name resolution details

    scutil is lower-level than networksetup and is extremely useful when configuration looks correct in the UI but behavior is still odd.

    Show current DNS resolver state (one of the best troubleshooting commands on macOS):

    scutil --dns
    

    Show proxy configuration:

    scutil --proxy
    

    Get the “primary” network interface/service in use:

    scutil --nwi
    

    ipconfig (macOS): DHCP and interface address details

    On macOS, ipconfig is not the Windows tool. It is a small utility mainly for DHCP and interface state.

    Get the IPv4 address of an interface:

    ipconfig getifaddr en0
    

    Renew DHCP lease:

    sudo ipconfig set en0 DHCP
    

    system_profiler: inventory network hardware (when names are confusing)

    If you are unsure what hardware exists (especially with docks/adapters), system_profiler can help.

    Wi‑Fi details:

    system_profiler SPAirPortDataType
    

    Network hardware list:

    system_profiler SPNetworkDataType
    

    log show: read macOS unified logs for networking clues

    When problems are intermittent, the system logs can expose DHCP renewals, Wi‑Fi roam events, and VPN behavior.

    Example (last hour, filtering for Wi‑Fi keywords):

    log show --last 1h --predicate 'eventMessage CONTAINS[c] "Wi-Fi"'
    

    This is powerful but can be noisy. Narrow your time window and predicate.


    Wi‑Fi diagnostics: airport

    Apple ships a Wi‑Fi utility called airport. It is not always on your PATH, so you typically run it via the full path.

    Show Wi‑Fi link status (SSID, RSSI, channel, rates):

    /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
    

    Scan for nearby networks:

    /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s
    

    If you troubleshoot Wi‑Fi often, airport -I is the quickest “is my signal bad?” check.


    dns-sd: browse and test Bonjour / mDNS service discovery

    macOS heavily uses Bonjour (mDNS) for printers, AirPlay, and peer discovery.

    Browse services of a type (example: AirPrint):

    dns-sd -B _ipp._tcp
    

    Resolve a service instance:

    dns-sd -L "Some Printer" _ipp._tcp local
    

    A practical troubleshooting flow (putting it together)

    When a Mac has “network issues,” a repeatable flow saves time:

    1. Link + IP
      • ifconfig en0
      • ipconfig getifaddr en0
    2. Default route
      • route -n get default
    3. DNS
      • scutil --dns
      • dig [example.com](<http://example.com>)
    4. Reachability and path
      • ping -c 5 1.1.1.1
      • traceroute [example.com](<http://example.com>)
    5. Ports and processes
      • nc -vz [example.com](<http://example.com>) 443
      • sudo lsof -nP -iTCP -sTCP:LISTEN
    6. Packet capture (when you must prove what’s happening)
      • sudo tcpdump -i en0 -n ...

    Closing thoughts

    The biggest shift on macOS is not that the Unix tools are missing. It is that the configuration and behavior often live in higher-level macOS systems (network services, DNS resolver stacks, Wi‑Fi frameworks, VPN profiles). Knowing when to reach for scutil and networksetup is what turns “I can’t reproduce it” into actionable information.

    If you only memorize three commands for macOS-specific diagnostics, make them:

    • scutil --dns
    • networksetup -listallnetworkservices
    • airport -I
  • The Future of On-Campus Courses in a Predominantly Online World

    For 25 years, higher education has wrestled with one question: If students can learn online, why come to campus?

    The answer: on-campus learning isn’t disappearing—it’s transforming to do what online cannot.

    Content Delivery Is Moving Online

    Online platforms and AI tutors have become the most efficient way to deliver information. Lectures, readings, and examples thrive in digital spaces where students can pause, rewind, and revisit.

    The campus is no longer the best place for one-way information transfer.

    On-campus courses will thrive by providing experiences that cannot be digitized:

    • Hands-on labs with specialized equipment
    • Design studios and maker spaces
    • Collaborative team-based work
    • In-person research with faculty
    • Real-time problem-solving under guidance

    The future classroom looks less like a lecture hall and more like a studio, lab, or incubator.

    The Campus’s Strongest Differentiator: People

    For most students, the real value of campus has never been the lecture—it’s been the people:

    • Belonging and connection
    • Clubs, teams, and organizations
    • Faculty mentorship
    • Friendships and peer networks
    • Leadership and service opportunities

    AI can personalize instruction, but it cannot replace human relationships.

    Athens State as a Use Case

    My employer, Athens State University, serves a geographically dispersed, working-adult population as a predominantly online institution. Yet the campus remains vital—not for lectures, but as a specialized space for high-impact, hands-on learning.

    Computing students come to campus for experiences that cannot be replicated online: cybersecurity labs, IoT and networking environments, undergraduate research, and deeply interactive experiences that complement flexible online programs.

    Hybridization Is the Default

    The false binary of “online vs. on-campus” is evaporating. What emerges is hybrid by design:

    • Lectures watched ahead of time
    • Class time for application, coaching, and creation
    • AI helps students practice and simulate
    • In-person meetings during critical learning phases
    • Flexibility during less critical weeks

    My CS 318 (Computer Science 2) course exemplifies this: lectures are asynchronous and recorded; class meetings are live-streamed for in-person or online attendance. A significant minority perform better with direct interaction. We use class time for structured programming labs, with plans to add code reviews and breakout activities.

    AI Raises the Bar

    AI tutoring makes it easy for students to master procedural content independently. This shifts the question:

    Why attend in person if an AI tutor can explain the content 24/7?

    The answer must be compelling. In-person courses must emphasize:

    • Creative synthesis and judgment under uncertainty
    • Real-time collaboration and improvisation
    • Peer critique and feedback cycles
    • Experiential learning with real consequences

    Campuses must deliver the parts of learning that require being alive, alert, and in the room.

    The Campus Becomes Professional Infrastructure

    In applied fields, the campus functions less as a place for listening and more as a place for doing professional work:

    • Running experiments
    • Configuring hardware, networks, and security systems
    • Building prototypes
    • Practicing industry-standard workflows
    • Working in labs and studios

    Future students might take 70% of their content online, but complete 100% of their professional practice in hybrid and in-person environments.

    Enrollment Economics Will Reinvent Campus

    As flexible online pathways become standard, institutions will restructure their physical spaces:

    • Fewer traditional lectures
    • More active learning classrooms and labs
    • More spaces for team projects
    • More tutoring and success centers
    • More events and community engagement

    Campuses evolve from information centers to creation and connection centers.

    Dreamscape Learn as an Example

    Dreamscape Learn (https://www.dreamscapelearn.com/) exemplifies this transformation. A collaboration between Hollywood storytellers and academic leaders, it brings cinematic-quality VR into higher education. Originally developed with Arizona State University, Dreamscape creates immersive, narrative-rich VR environments where students work together in shared virtual worlds.

    These VR labs turn complex subjects—biology, physics, environmental science—into interactive simulations requiring investigation, collaboration, and problem-solving. The campus becomes the gateway to high-impact, immersive learning that cannot be replicated online. VR laboratories become collaborative hubs where students form communities around exploratory challenges, demonstrating how physical spaces can offer deeply interactive, emotionally resonant learning that fuses storytelling, simulation, and teamwork.

    So What Is the Future?

    Not extinction. Transformation.

    Online education handles:

    • Content delivery
    • Self-paced mastery
    • Flexible pathways
    • Practice and basic tutoring (via AI)

    On-campus education focuses on:

    • Human connection
    • Judgment, creativity, and synthesis
    • Teamwork and communication
    • Studio, lab, and project-based learning
    • Identity development and mentorship

    The campus becomes a premium experience—not the default, but the valuable. Students show up not because they “have to,” but because something worth experiencing happens there.

    Conclusion: The Future University Is a Network

    The future of higher education is networked—a connected ecosystem where AI provides constant support, online platforms provide flexibility, the campus provides community and practice, faculty guide through mentorship and design, and students move fluidly between digital and physical experiences.

    In a world where almost anything can be learned online, on-campus courses will thrive by becoming deeply human, intensely interactive, and uniquely experiential.

    Three Key Insights

    1. Physical Affordances Matter—But Only if They’re Superior

    Labs, equipment, studios—things that cannot fit through a screen. But this only works if the equipment is meaningfully better than what students could access elsewhere. A basic computer lab isn’t defensible; a VR development lab or cyber range is.

    2. The Campus Becomes a Premium Tier

    Real-time collaboration, mentorship, peer learning. Even when only a minority perform better with direct interaction, those small percentages matter when competing on outcomes. The campus shifts from default tier for everyone to premium tier for students who need high-touch interaction.

    3. Human Social Capital Appreciates in an AI World

    In an AI-saturated world, human social capital becomes more valuable, not less. The network you build in college may be worth more than the skills you learn, especially as skills become commoditized by AI.

    Selah.

  • Online Education: Changes in Attitude, Changes in Modality

    For nearly three decades, online education has centered on one question: Is it better to teach online through real-time sessions or self-paced modules? The answer has shifted dramatically—and today’s research reveals a far more nuanced picture than early “either/or” debates suggested.

    When universities first moved courses online in the late 1990s and early 2000s, asynchronous instruction dominated. Limited bandwidth and early LMS platforms like Blackboard and WebCT made videoconferencing unreliable. Scholars such as Michael Moore—whose Transactional Distance Theory shaped early distance-ed thinking—emphasized that effective online learning required bridging the psychological gap between teacher and student through well-structured materials and meaningful dialogue, most of which happened via text-based, time-flexible tools.

    By the mid-2000s, research consistently found that asynchronous environments supported reflection, deeper discussion, and learner autonomy (Hrastinski, 2008). Asynchronous wasn’t just convenient—it was considered the gold standard for well-designed online education, especially for adult learners balancing work, family, and school.

    As broadband expanded and tools like Zoom, Adobe Connect, and Collaborate improved, synchronous online learning became more viable. Studies throughout the 2010s showed that live sessions boosted social presence, helped students maintain momentum, and let instructors respond to confusion in real time. Research also began suggesting that blended approaches—combining asynchronous materials with occasional synchronous meetings—could outperform either model alone.

    Still, attitudes remained cautious. Most fully online programs stuck with asynchronous delivery because it scaled well and met the needs of working adults. Synchronous formats were often seen as a nice addition, not a core design element.

    The Pandemic: Synchronous Goes Mainstream

    COVID-19 changed everything. Practically overnight, Zoom became the global classroom. For many students and instructors, synchronous online learning was their first experience with online education of any kind.

    Research from 2020–2022 revealed several key themes:

    • Students valued structure. Synchronous classes provided routine during a chaotic period.
    • Faculty found real-time teaching easier to manage than designing robust asynchronous modules on short notice.
    • Zoom fatigue was real, and bandwidth limitations, childcare demands, and time zone conflicts disproportionately affected lower-income and rural learners.
    • Students in hastily converted asynchronous courses often felt isolated or under-supported.

    Most importantly, the pandemic normalized synchronous online learning at an unprecedented scale. Many students—especially traditional undergrads—discovered they prefer some real-time interaction online.

    Post-Pandemic Research: Changes In Attitude

    As researchers have examined online learning beyond the “emergency remote” context, a clear pattern has emerged: neither synchronous nor asynchronous online education is inherently superior. Each offers distinct advantages.

    Asynchronous strengths:

    • Maximum flexibility
    • Self-paced, repeatable content
    • Deeper opportunities for reflective engagement

    Synchronous strengths:

    • Immediate feedback and clarification
    • Stronger sense of connection and accountability
    • Better fit for discussion-heavy or skills-based courses

    Recent meta-analyses find similar learning outcomes across both formats when courses are intentionally designed. Where differences appear, they relate more to student characteristics (e.g., work schedules, self-regulation skills) and course type than to modality.

    The most important post-COVID trend is the rise of “bichronous” online learning—a term coined by Martin, Sunley, and Turner (2020) to describe courses that intentionally blend both modes. Students complete core content asynchronously while engaging in targeted synchronous sessions for problem-solving, discussions, or community building. Recent studies show high satisfaction with these hybrids, especially when synchronous time is used strategically rather than habitually.

    Generative AI: Killer or Savior of On-line Education

    Generative AI is seen by some as the death of asynchronous online education—and by others as its savior. Asynchronous courses rely heavily on content, self-directed learning, and delayed interaction.

    The loudest criticism of this approach is that it makes students feel alone, unsupported, and disconnected. But chatbots integrated into the LMS—serving as first-line tutors and discussion thread guides—can provide real-time support in a non-real-time environment.

    At the same time, AI is disrupting assessment and causing concern among faculty over academic integrity. The tools make it easy for students to cheat by auto-generating essays, code, and short answers.

    The response has been a move toward more open-ended assessments—projects, reflections, case studies, and multimedia submissions—where AI becomes a tool rather than a shortcut. Faculty are also adopting process-based assignments like think-aloud activities, staged coding tasks, or version-controlled writing.

    On the flip side, AI makes life easier for instructional designers. Asynchronous courses require tight, highly structured, and carefully planned materials. Here, AI’s ability to rapidly generate and update content—while creating multiple versions of the same concept—lowers the barriers to quality design.

    We see AI not as the “killer” of asynchronous online education but as the “enabler” and “accelerator” of bichronous online education. Tools for text, image, and video generation create new opportunities.

    The Take-away

    For nearly three decades, the distinction between synchronous and asynchronous learning has shaped online education—from course design to student expectations. This evolution began in the bandwidth-limited era when asynchronous experiences defined quality online learning. It continued through the rise of robust synchronous platforms in the 2010s, then accelerated dramatically when the COVID-19 pandemic pushed real-time online instruction into the mainstream. Today, research shows that neither modality is inherently superior. Each offers unique strengths, and students increasingly prefer thoughtful blends that balance flexibility with meaningful interaction. The future lies in treating synchronicity as a design choice rather than a philosophical divide.

    AI amplifies this shift by transforming asynchronous learning itself. Intelligent tutors, adaptive feedback systems, dynamic content generation, and AI-integrated assessments reduce the isolation traditionally associated with self-paced courses while elevating personalization and rigor. At the same time, faculty must rethink assessment integrity and guide students in responsible AI use. Asynchronous education is no longer simply “anytime learning”—supported by AI, it’s becoming interactive, adaptive, and deeply student-centered. Together, these trends signal a future where online education is shaped not by the constraints of time, but by intentional design, learner support, and strategic use of new technologies.

    Selah.

  • Command Line Knowledge for MacOS: Dealing with Active Directory

    Well, we have to play nicely with all of the Windows stuff that is out in the world. In the enterprise, we have to accept that we are going to have to deal with Windows Networking, particularly authentication and authorization services provided by Active Directory.

    Apple has improved the integration with Windows Networking over the years but you still have to do a bunch of contortions to get a machine on the network. Note that the following is taken from multiple Apple support sites and some AI assistance.

    Joining a machine into an AD domain and configuring it for network authentication requires you to bind the machine to Domain through Directory Services and then configure authentication on the local machine to connect to the AI domain.


    1. Bind the Mac to the AD domain

    macOS includes the dsconfigad tool (Active Directory connector) which allows you to bind a Mac to an AD domain from Terminal. (Apple Support)

    Here’s a typical command (you’ll substitute your values):

    sudo dsconfigad -add DOMAIN.COM \
        -computer "Mac-Hostname" \
        -username "BindUser" \
        -password "BindPassword" \
        -ou "OU=Computers,DC=DOMAIN,DC=COM" \
        -force

    Explanation of parameters:

    • -add DOMAIN.COM → The AD domain you’re joining.
    • -computer "Mac-Hostname" → The name you want this Mac to appear in AD.
    • -username / -password → Credentials of an AD account with rights to bind computer objects.
    • -ou "…" → The organizational unit in AD where you want the computer object to reside.
    • -force → Optional, for example if it was already bound previously, etc.

    Other common flags you may want:

    sudo dsconfigad -domain DOMAIN.COM \
         -alldomains enable \
         -groups "Domain Admins,Enterprise Admins" \
         -packetsign require \
         -packetencrypt require

    This enables all domains in the forest, adds certain AD groups to the Mac’s “admin” group, and enables packet signing/encryption for LDAP/AD traffic. (Apple Support)


    2. Enable network users to log in at the login window

    Once the Mac is bound, you need to allow domain users (network accounts) to login at the macOS login window. There are GUI steps (System Preferences → Users & Groups → Login Options → “Allow network users to log in at login window”), but we can achieve this via command line/config defaults.

    Command-line approach

    You can use the defaults command to set a preference so that network users are allowed to login. Example:

    sudo defaults write /Library/Preferences/com.apple.loginwindow ENABLEDIRLOGIN -bool true

    This sets ENABLEDIRLOGIN to true, enabling directory (network/AD) users at login. (Note: this key has been used historically, though exact availability may vary across macOS versions.)

    Also ensure that the login window is set appropriately (e.g., “Name & Password” rather than “List of Users”). For example:

    sudo defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME -bool true

    Then you may want to restart the loginwindow or reboot:

    sudo killall loginwindow

    Mobile/local account caching and mobile user accounts

    This is a an important step that some sites wrongly suggest as optional. You really, really, really, really want to use dsconfigad to enable domain users to have mobile accounts. This will cache credentials locally and will permit users to login when offline from the enterprise network. Otherwise you won’t be able to login. We also strongly recommend that you do keep a separate local user for when things go wrong.

    Here’s how to enable mobile accounts in MacOS via dsconfigad:

    sudo dsconfigad -mobile enable -mobileconfirm disable -localhome enable

    (from the gist example) (Gist)


    3. Verification & Pitfalls

    • After binding you can check current settings:
    dsconfigad -show

    This will display the domain, computer account, OU, mobile account settings etc. (Gist)

    • Make sure DNS is correctly configured: the Mac must be able to resolve the domain controllers for your AD domain. Apple’s documentation emphasizes DNS/Kerberos/LDAP for AD integration. (Apple Support)
    • If users cannot login:
    • Check that “Allow network users to log in at login window” is indeed enabled (GUI or defaults).
    • If after login attempt the screen just sits/spins/shakes, it may be waiting on network/LDAP/Kerberos auth. Example case discussed in Apple forums. (Apple Support Community)
    • LocalAdmin vs domain group membership: If you want certain AD groups to be local admins (e.g., “Domain Admins”), you’ll include that in the binding via -groups flag. Otherwise domain user logins may succeed but the user may lack local rights.
    • For macOS versions and AD interactions: some behaviors may change from version to version (especially around caching or login window UI). Always test in your environment.

    CAVEAT: We admit to using AI tools to research and edit this post.

    Selah.

  • How Third-Party Course Content Is Destroying Higher Education

    Colleges and universities built their reputations on the quality of their teaching and the expertise of their faculty. A degree meant you had learned from scholars who designed, tested, and refined the very curriculum that carried the institution’s name. But in recent years, this foundation has been quietly eroded by the rise of third-party course content providers—companies that package “ready-to-teach” online courses for universities to rebrand as their own.

    At first, this outsourcing looked like convenience. Today, it’s corrosion.

    1. The Erosion of Academic Integrity

    When a university licenses pre-made courses, it gives away its most sacred academic function: curriculum design. Faculty once spent months shaping syllabi to fit local program outcomes, student needs, and institutional missions. Now, many are handed “turnkey” shells built by strangers—often containing outdated information, no local context, and little alignment with departmental standards.

    This undermines the authenticity of the university’s promise. Students think they are learning from that university’s faculty, but in truth they are completing a commodity course produced by a contractor. The result is a diploma that increasingly reflects a licensing relationship, not an educational experience.

    2. Faculty Deskilled, Then Replaced

    Third-party content de-skills faculty. Once instructors are told to “facilitate” someone else’s course rather than create their own, they cease to be educators and become content proctors. Their authority over learning design, assessment, and even grading can be stripped away through automated quizzes and publisher rubrics.

    Eventually, administrators notice that if a course can be taught by anyone following a script, it can also be taught by no one—or by the lowest-cost adjunct available. The business model’s logic leads inexorably to layoffs, consolidation, and the hollowing-out of the academic profession itself.

    3. Students Lose the Human Element

    Education is not the same as content delivery. Learning happens through mentorship, intellectual friction, and local context—when faculty connect a concept to a community, a region, or a student’s lived experience.

    Third-party vendors flatten that richness into generic modules designed to scale across thousands of institutions. A course on “Introduction to Business” becomes a cookie-cutter PowerPoint set with no awareness of the local economy, no discussion of regional industries, and no dialogue with students’ realities.

    Students sense this disconnect. Surveys repeatedly show that learners in pre-packaged online courses feel less engaged, less connected, and less confident in their instructors’ expertise.

    4. The Corporate Capture of the Curriculum

    Outsourcing curriculum means outsourcing values. Third-party content providers are not accountable to faculty senates or accrediting bodies in the same way universities are. Their incentives are commercial, not educational.

    When companies determine what students learn—and universities merely rent that content—the door opens for subtle corporate bias. Which case studies are used in a business course? Which programming languages are prioritized in a computer science module? Which health data examples are selected in a nursing simulation? Each of these choices embeds an ideology of the marketplace, not of the academy.

    5. The Path Forward: Reclaiming Academic Sovereignty

    Universities must rediscover what made them trusted in the first place: faculty governance, curricular integrity, and intellectual independence. That doesn’t mean rejecting all collaboration—it means controlling it.

    Partnerships with vendors can be tools, not replacements. Faculty should lead course design, adapting external materials where appropriate but ensuring that institutional mission and local expertise remain at the center. Accrediting agencies and state boards should require disclosure when third-party content exceeds a certain percentage of a degree program. Students have a right to know when their “university course” was written by someone who has never set foot on campus.

    If higher education fails to reclaim authorship of its own curriculum, it will become a branding service, not an intellectual community.

    Closing Thought

    The crisis is not about technology or convenience—it’s about ownership of knowledge. When universities surrender that ownership to third-party content companies, they trade centuries of academic tradition for a subscription plan. The result is an education that looks like college but feels like customer service.

    It’s time to take the curriculum back.

    Caveat: This post was edited with the assistance of AI research and editing tools but all opinions expressed are the opinions of the author.

    As always, solely the opinions of the author, your mileage may vary, standard disclaimers apply.

    Selah.